From 39348d532ed0a99dc2417df9d5ed2f6a3730201d Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Wed, 22 May 2024 12:23:14 +0100 Subject: [PATCH 001/124] docs(framework:skip) Update link for `run-simulation-from-cli` (#3382) --------- Co-authored-by: Daniel J. Beutel --- doc/source/conf.py | 1 + doc/source/how-to-upgrade-to-flower-next.rst | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 1c53a827dcf5..feb173c0efa8 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -248,6 +248,7 @@ def find_test_modules(package_path): "quickstart-mxnet": "index.html", "tutorial-quickstart-mxnet": "index.html", "example-mxnet-walk-through": "index.html", + "ref-api/flwr.simulation.run_simulation_from_cli.html": "index.html", } # -- Options for HTML output ------------------------------------------------- diff --git a/doc/source/how-to-upgrade-to-flower-next.rst b/doc/source/how-to-upgrade-to-flower-next.rst index 8c8f3c3f8fd7..44fad51546b6 100644 --- a/doc/source/how-to-upgrade-to-flower-next.rst +++ b/doc/source/how-to-upgrade-to-flower-next.rst @@ -22,21 +22,22 @@ Let's dive in! .. |startclient_link| replace:: ``start_client()`` .. |startserver_link| replace:: ``start_server()`` .. |startsim_link| replace:: ``start_simulation()`` -.. |runsimcli_link| replace:: ``flower-simulation`` .. |runsim_link| replace:: ``run_simulation()`` .. |flowernext_superlink_link| replace:: ``flower-superlink`` .. |flowernext_clientapp_link| replace:: ``flower-client-app`` .. |flowernext_serverapp_link| replace:: ``flower-server-app`` +.. |flower_simulation_link| replace:: ``flower-simulation`` .. _clientapp_link: ref-api/flwr.client.ClientApp.html .. _serverapp_link: ref-api/flwr.server.ServerApp.html .. _startclient_link: ref-api/flwr.client.start_client.html .. _startserver_link: ref-api/flwr.server.start_server.html .. _startsim_link: ref-api/flwr.simulation.start_simulation.html -.. _runsimcli_link: ref-api/flwr.simulation.run_simulation_from_cli.html .. _runsim_link: ref-api/flwr.simulation.run_simulation.html .. _flowernext_superlink_link: ref-api-cli.html#flower-superlink .. _flowernext_clientapp_link: ref-api-cli.html#flower-client-app .. _flowernext_serverapp_link: ref-api-cli.html#flower-server-app +.. _flower_simulation_link: ref-api-cli.html#flower-simulation + Install update -------------- @@ -228,7 +229,7 @@ Simulation in CLI ... ) -- Run |runsimcli_link|_ in CLI and point to the ``server_app`` / ``client_app`` object in the +- Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / ``client_app`` object in the code instead of executing the Python script. Here's an example (assuming the ``server_app`` and ``client_app`` objects are in a ``sim.py`` module): From b5b662f4b27698874518fa95723ff166cbf3a217 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Wed, 22 May 2024 15:33:01 +0200 Subject: [PATCH 002/124] refactor(framework:skip) Move simulation defaults to toml files in CLI (#3455) --- src/py/flwr/cli/build.py | 6 ++--- src/py/flwr/cli/config_utils.py | 24 +------------------ .../new/templates/app/pyproject.hf.toml.tpl | 6 +++++ .../new/templates/app/pyproject.mlx.toml.tpl | 6 +++++ .../templates/app/pyproject.numpy.toml.tpl | 6 +++++ .../templates/app/pyproject.pytorch.toml.tpl | 6 +++++ .../templates/app/pyproject.sklearn.toml.tpl | 6 +++++ .../app/pyproject.tensorflow.toml.tpl | 6 +++++ src/py/flwr/cli/run/run.py | 24 +++++++++++++++---- 9 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/py/flwr/cli/build.py b/src/py/flwr/cli/build.py index 37753e5b57b1..ca7ab8686c5c 100644 --- a/src/py/flwr/cli/build.py +++ b/src/py/flwr/cli/build.py @@ -24,7 +24,7 @@ import typer from typing_extensions import Annotated -from .config_utils import load_and_validate_with_defaults +from .config_utils import load_and_validate from .utils import is_valid_project_name @@ -67,9 +67,7 @@ def build( ) raise typer.Exit(code=1) - conf, errors, warnings = load_and_validate_with_defaults( - directory / "pyproject.toml" - ) + conf, errors, warnings = load_and_validate(directory / "pyproject.toml") if conf is None: typer.secho( "Project configuration could not be loaded.\npyproject.toml is invalid:\n" diff --git a/src/py/flwr/cli/config_utils.py b/src/py/flwr/cli/config_utils.py index bca35a51dde5..d943d87e3812 100644 --- a/src/py/flwr/cli/config_utils.py +++ b/src/py/flwr/cli/config_utils.py @@ -22,7 +22,7 @@ from flwr.common import object_ref -def load_and_validate_with_defaults( +def load_and_validate( path: Optional[Path] = None, ) -> Tuple[Optional[Dict[str, Any]], List[str], List[str]]: """Load and validate pyproject.toml as dict. @@ -47,14 +47,6 @@ def load_and_validate_with_defaults( if not is_valid: return (None, errors, warnings) - # Apply defaults - defaults = { - "flower": { - "engine": {"name": "simulation", "simulation": {"supernode": {"num": 2}}} - } - } - config = apply_defaults(config, defaults) - return (config, errors, warnings) @@ -129,17 +121,3 @@ def validate(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]: return False, [reason], [] return True, [], [] - - -def apply_defaults( - config: Dict[str, Any], - defaults: Dict[str, Any], -) -> Dict[str, Any]: - """Apply defaults to config.""" - for key in defaults: - if key in config: - if isinstance(config[key], dict) and isinstance(defaults[key], dict): - apply_defaults(config[key], defaults[key]) - else: - config[key] = defaults[key] - return config diff --git a/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl index 3bd980b2340e..6a235b7b15cf 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl @@ -29,3 +29,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl index 0f56dc7eacc5..321dfaab41cc 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl @@ -26,3 +26,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl index bbf8463054f4..6b1c40d12561 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl @@ -24,3 +24,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl index a41ce1a6a4c6..df404d178495 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl @@ -26,3 +26,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl index 25645f0cde1a..7ee655967c4a 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl @@ -25,3 +25,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl index 3968e3aa327b..f453bce668fa 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl @@ -25,3 +25,9 @@ publisher = "$username" [flower.components] serverapp = "$import_name.server:app" clientapp = "$import_name.client:app" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = 2 diff --git a/src/py/flwr/cli/run/run.py b/src/py/flwr/cli/run/run.py index 9c50c8cb1980..dbaf7feb3500 100644 --- a/src/py/flwr/cli/run/run.py +++ b/src/py/flwr/cli/run/run.py @@ -15,18 +15,32 @@ """Flower command line interface `run` command.""" import sys +from enum import Enum +from typing import Optional import typer +from typing_extensions import Annotated from flwr.cli import config_utils from flwr.simulation.run_simulation import _run_simulation -def run() -> None: +class Engine(str, Enum): + """Enum defining the engine to run on.""" + + SIMULATION = "simulation" + + +def run( + engine: Annotated[ + Optional[Engine], + typer.Option(case_sensitive=False, help="The ML framework to use"), + ] = None, +) -> None: """Run Flower project.""" typer.secho("Loading project configuration... ", fg=typer.colors.BLUE) - config, errors, warnings = config_utils.load_and_validate_with_defaults() + config, errors, warnings = config_utils.load_and_validate() if config is None: typer.secho( @@ -49,9 +63,11 @@ def run() -> None: server_app_ref = config["flower"]["components"]["serverapp"] client_app_ref = config["flower"]["components"]["clientapp"] - engine = config["flower"]["engine"]["name"] - if engine == "simulation": + if engine is None: + engine = config["flower"]["engine"]["name"] + + if engine == Engine.SIMULATION: num_supernodes = config["flower"]["engine"]["simulation"]["supernode"]["num"] typer.secho("Starting run... ", fg=typer.colors.BLUE) From bd4d7e0bc71c49343c46e832b8da9a6f21f70b83 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 22 May 2024 18:27:08 +0100 Subject: [PATCH 003/124] ci(framework:skip) Enable auto-formatting for E2E (#3473) --- dev/format.sh | 5 +++++ dev/test.sh | 6 +++--- e2e/bare-client-auth/client.py | 10 ++++++---- e2e/bare-client-auth/server.py | 3 ++- e2e/bare-https/client.py | 14 +++++++++----- e2e/bare-https/server.py | 2 +- e2e/bare/client.py | 2 +- e2e/bare/simulation.py | 24 +++++++++++++++++------- e2e/docker/client.py | 5 +++-- e2e/docker/server.py | 2 +- e2e/fastai/client.py | 4 ++-- e2e/fastai/simulation.py | 9 ++++++--- e2e/jax/client.py | 15 ++++++++------- e2e/jax/jax_training.py | 4 ++-- e2e/jax/simulation.py | 9 ++++++--- e2e/opacus/client.py | 24 +++++++++++++++--------- e2e/opacus/simulation.py | 9 ++++++--- e2e/pandas/client.py | 3 ++- e2e/pandas/server.py | 4 ++-- e2e/pandas/simulation.py | 4 ++-- e2e/pytorch-lightning/client.py | 9 +++++++-- e2e/pytorch-lightning/mnist.py | 12 +++++++----- e2e/pytorch-lightning/simulation.py | 9 ++++++--- e2e/pytorch/client.py | 28 +++++++++++++++++++++------- e2e/pytorch/simulation.py | 25 +++++++++++++++++-------- e2e/scikit-learn/client.py | 15 ++++++++++----- e2e/scikit-learn/simulation.py | 9 ++++++--- e2e/scikit-learn/utils.py | 14 +++++++------- e2e/server.py | 3 +-- e2e/strategies/client.py | 21 ++++++++++++++------- e2e/tabnet/client.py | 11 ++++++++--- e2e/tabnet/simulation.py | 9 ++++++--- e2e/tensorflow/client.py | 9 +++++++-- e2e/tensorflow/simulation.py | 9 ++++++--- 34 files changed, 222 insertions(+), 119 deletions(-) diff --git a/dev/format.sh b/dev/format.sh index 6b9cdaf5f44c..05248b5eed3d 100755 --- a/dev/format.sh +++ b/dev/format.sh @@ -16,6 +16,11 @@ find src/proto/flwr/proto -name *.proto | grep "\.proto" | xargs clang-format -i python -m black -q examples python -m docformatter -i -r examples +# E2E +python -m isort e2e +python -m black -q e2e +python -m docformatter -i -r e2e + # Notebooks python -m black --ipynb -q doc/source/*.ipynb KEYS="metadata.celltoolbar metadata.language_info metadata.toc metadata.notify_time metadata.varInspector metadata.accelerator metadata.vscode cell.metadata.id cell.metadata.heading_collapsed cell.metadata.hidden cell.metadata.code_folding cell.metadata.tags cell.metadata.init_cell cell.metadata.vscode cell.metadata.pycharm" diff --git a/dev/test.sh b/dev/test.sh index 1ed1b96edea1..7cabf35abf41 100755 --- a/dev/test.sh +++ b/dev/test.sh @@ -11,11 +11,11 @@ clang-format --Werror --dry-run src/proto/flwr/proto/* echo "- clang-format: done" echo "- isort: start" -python -m isort --check-only --skip src/py/flwr/proto src/py/flwr +python -m isort --check-only --skip src/py/flwr/proto src/py/flwr e2e echo "- isort: done" echo "- black: start" -python -m black --exclude "src\/py\/flwr\/proto" --check src/py/flwr examples +python -m black --exclude "src\/py\/flwr\/proto" --check src/py/flwr examples e2e echo "- black: done" echo "- init_py_check: start" @@ -23,7 +23,7 @@ python -m flwr_tool.init_py_check src/py/flwr src/py/flwr_tool echo "- init_py_check: done" echo "- docformatter: start" -python -m docformatter -c -r src/py/flwr -e src/py/flwr/proto +python -m docformatter -c -r src/py/flwr e2e -e src/py/flwr/proto echo "- docformatter: done" echo "- ruff: start" diff --git a/e2e/bare-client-auth/client.py b/e2e/bare-client-auth/client.py index a56ba5eca552..e82f17088bd9 100644 --- a/e2e/bare-client-auth/client.py +++ b/e2e/bare-client-auth/client.py @@ -1,11 +1,11 @@ -import flwr as fl import numpy as np -from pathlib import Path +import flwr as fl model_params = np.array([1]) objective = 5 + # Define Flower client class FlowerClient(fl.client.NumPyClient): def get_parameters(self, config): @@ -13,18 +13,20 @@ def get_parameters(self, config): def fit(self, parameters, config): model_params = parameters - model_params = [param * (objective/np.mean(param)) for param in model_params] + model_params = [param * (objective / np.mean(param)) for param in model_params] return model_params, 1, {} def evaluate(self, parameters, config): model_params = parameters - loss = min(np.abs(1 - np.mean(model_params)/objective), 1) + loss = min(np.abs(1 - np.mean(model_params) / objective), 1) accuracy = 1 - loss return loss, 1, {"accuracy": accuracy} + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) diff --git a/e2e/bare-client-auth/server.py b/e2e/bare-client-auth/server.py index 7e4f96e15fd9..e10d5ebc5760 100644 --- a/e2e/bare-client-auth/server.py +++ b/e2e/bare-client-auth/server.py @@ -1,6 +1,7 @@ -import flwr as fl from pathlib import Path +import flwr as fl + app = fl.server.ServerApp() diff --git a/e2e/bare-https/client.py b/e2e/bare-https/client.py index b4570b36512d..8f5c1412fd01 100644 --- a/e2e/bare-https/client.py +++ b/e2e/bare-https/client.py @@ -1,11 +1,13 @@ -import flwr as fl -import numpy as np from pathlib import Path +import numpy as np + +import flwr as fl model_params = np.array([1]) objective = 5 + # Define Flower client class FlowerClient(fl.client.NumPyClient): def get_parameters(self, config): @@ -13,18 +15,20 @@ def get_parameters(self, config): def fit(self, parameters, config): model_params = parameters - model_params = [param * (objective/np.mean(param)) for param in model_params] + model_params = [param * (objective / np.mean(param)) for param in model_params] return model_params, 1, {} def evaluate(self, parameters, config): model_params = parameters - loss = min(np.abs(1 - np.mean(model_params)/objective), 1) + loss = min(np.abs(1 - np.mean(model_params) / objective), 1) accuracy = 1 - loss return loss, 1, {"accuracy": accuracy} + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) @@ -32,7 +36,7 @@ def client_fn(cid): if __name__ == "__main__": # Start Flower client fl.client.start_client( - server_address="127.0.0.1:8080", + server_address="127.0.0.1:8080", client=FlowerClient().to_client(), root_certificates=Path("certificates/ca.crt").read_bytes(), insecure=False, diff --git a/e2e/bare-https/server.py b/e2e/bare-https/server.py index d85c0623e92c..e10d5ebc5760 100644 --- a/e2e/bare-https/server.py +++ b/e2e/bare-https/server.py @@ -1,6 +1,6 @@ -import flwr as fl from pathlib import Path +import flwr as fl app = fl.server.ServerApp() diff --git a/e2e/bare/client.py b/e2e/bare/client.py index 5f8642e27675..402d775ac3a9 100644 --- a/e2e/bare/client.py +++ b/e2e/bare/client.py @@ -1,8 +1,8 @@ from datetime import datetime -import flwr as fl import numpy as np +import flwr as fl from flwr.common import ConfigsRecord SUBSET_SIZE = 1000 diff --git a/e2e/bare/simulation.py b/e2e/bare/simulation.py index 3a90d90a0ae0..25868eb8e33f 100644 --- a/e2e/bare/simulation.py +++ b/e2e/bare/simulation.py @@ -1,11 +1,12 @@ from typing import List, Tuple + import numpy as np +from client import client_fn import flwr as fl from flwr.common import Metrics -from client import client_fn -STATE_VAR = 'timestamp' +STATE_VAR = "timestamp" # Define metric aggregation function @@ -14,18 +15,22 @@ def record_state_metrics(metrics: List[Tuple[int, Metrics]]) -> Metrics: states = [] for _, m in metrics: # split string and covert timestamps to float - states.append([float(tt) for tt in m[STATE_VAR].split(',')]) + states.append([float(tt) for tt in m[STATE_VAR].split(",")]) for client_state in states: if len(client_state) == 1: continue deltas = np.diff(client_state) - assert np.all(deltas > 0), f"Timestamps are not monotonically increasing: {client_state}" + assert np.all( + deltas > 0 + ), f"Timestamps are not monotonically increasing: {client_state}" return {STATE_VAR: states} -strategy = fl.server.strategy.FedAvg(evaluate_metrics_aggregation_fn=record_state_metrics) +strategy = fl.server.strategy.FedAvg( + evaluate_metrics_aggregation_fn=record_state_metrics +) hist = fl.simulation.start_simulation( client_fn=client_fn, @@ -34,8 +39,13 @@ def record_state_metrics(metrics: List[Tuple[int, Metrics]]) -> Metrics: strategy=strategy, ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) # The checks in record_state_metrics don't do anythinng if client's state has a single entry state_metrics_last_round = hist.metrics_distributed[STATE_VAR][-1] -assert len(state_metrics_last_round[1][0]) == 2*state_metrics_last_round[0], f"There should be twice as many entries in the client state as rounds" +assert ( + len(state_metrics_last_round[1][0]) == 2 * state_metrics_last_round[0] +), "There should be twice as many entries in the client state as rounds" diff --git a/e2e/docker/client.py b/e2e/docker/client.py index cea752ea5777..8451b810416b 100644 --- a/e2e/docker/client.py +++ b/e2e/docker/client.py @@ -1,14 +1,14 @@ import warnings from collections import OrderedDict -from flwr.client import NumPyClient, ClientApp -from flwr_datasets import FederatedDataset import torch import torch.nn as nn import torch.nn.functional as F +from flwr_datasets import FederatedDataset from torch.utils.data import DataLoader, Subset from torchvision.transforms import Compose, Normalize, ToTensor +from flwr.client import ClientApp, NumPyClient # ############################################################################# # 1. Regular PyTorch pipeline: nn.Module, train, test, and DataLoader @@ -19,6 +19,7 @@ SUBSET_SIZE = 1_000 + class Net(nn.Module): """Model (simple CNN adapted from 'PyTorch: A 60 Minute Blitz')""" diff --git a/e2e/docker/server.py b/e2e/docker/server.py index cb3490b75dca..61825f0a5df3 100644 --- a/e2e/docker/server.py +++ b/e2e/docker/server.py @@ -1,8 +1,8 @@ from typing import List, Tuple +from flwr.common import Metrics from flwr.server import ServerApp, ServerConfig from flwr.server.strategy import FedAvg -from flwr.common import Metrics # Define metric aggregation function diff --git a/e2e/fastai/client.py b/e2e/fastai/client.py index c4bfb89c2dde..1d98a1134941 100644 --- a/e2e/fastai/client.py +++ b/e2e/fastai/client.py @@ -1,11 +1,11 @@ import warnings from collections import OrderedDict -import flwr as fl import numpy as np import torch from fastai.vision.all import * +import flwr as fl warnings.filterwarnings("ignore", category=UserWarning) @@ -17,7 +17,7 @@ path, valid_pct=0.5, train="training", valid="testing", num_workers=0 ) -subset_size = 100 # Or whatever +subset_size = 100 # Or whatever selected_train = np.random.choice(dls.train_ds.items, subset_size, replace=False) selected_valid = np.random.choice(dls.valid_ds.items, subset_size, replace=False) # Swap in the subset for the whole thing (Note: this mutates dls, so re-initialize before full training!) diff --git a/e2e/fastai/simulation.py b/e2e/fastai/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/fastai/simulation.py +++ b/e2e/fastai/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/jax/client.py b/e2e/jax/client.py index a4e4d1f55117..347a005d923a 100644 --- a/e2e/jax/client.py +++ b/e2e/jax/client.py @@ -1,15 +1,12 @@ """Flower client example using JAX for linear regression.""" +from typing import Dict, List, Tuple -from typing import Dict, List, Tuple, Callable - -import flwr as fl -import numpy as np import jax -import jax.numpy as jnp - import jax_training +import numpy as np +import flwr as fl # Load data and determine model shape train_x, train_y, test_x, test_y = jax_training.load_data() @@ -50,13 +47,17 @@ def evaluate( ) return float(loss), num_examples, {"loss": float(loss)} + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) if __name__ == "__main__": # Start Flower client - fl.client.start_client(server_address="127.0.0.1:8080", client=FlowerClient().to_client()) + fl.client.start_client( + server_address="127.0.0.1:8080", client=FlowerClient().to_client() + ) diff --git a/e2e/jax/jax_training.py b/e2e/jax/jax_training.py index 2b523a08516e..f57db75d5963 100644 --- a/e2e/jax/jax_training.py +++ b/e2e/jax/jax_training.py @@ -7,13 +7,13 @@ please read the JAX documentation or the mentioned tutorial. """ +from typing import Callable, Dict, List, Tuple -from typing import Dict, List, Tuple, Callable import jax import jax.numpy as jnp +import numpy as np from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split -import numpy as np key = jax.random.PRNGKey(0) diff --git a/e2e/jax/simulation.py b/e2e/jax/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/jax/simulation.py +++ b/e2e/jax/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/opacus/client.py b/e2e/opacus/client.py index 00437a31233c..c9ebe319063a 100644 --- a/e2e/opacus/client.py +++ b/e2e/opacus/client.py @@ -11,7 +11,6 @@ import flwr as fl - # Define parameters. PARAMS = { "batch_size": 32, @@ -57,9 +56,7 @@ def train(net, trainloader, privacy_engine, optimizer, epochs): loss = criterion(net(images), labels) loss.backward() optimizer.step() - epsilon = privacy_engine.get_epsilon( - delta=PRIVACY_PARAMS["target_delta"] - ) + epsilon = privacy_engine.get_epsilon(delta=PRIVACY_PARAMS["target_delta"]) return epsilon @@ -76,22 +73,27 @@ def test(net, testloader): accuracy = correct / len(testloader.dataset) return loss, accuracy + def load_data(): transform = transforms.Compose( [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))] ) data = CIFAR10("./data", train=True, download=True, transform=transform) - split = math.floor(len(data)* 0.01 * PARAMS["train_split"]) + split = math.floor(len(data) * 0.01 * PARAMS["train_split"]) trainset = torch.utils.data.Subset(data, list(range(0, split))) - testset = torch.utils.data.Subset(data, list(range(split, math.floor(len(data) * 0.01)))) + testset = torch.utils.data.Subset( + data, list(range(split, math.floor(len(data) * 0.01))) + ) trainloader = DataLoader(trainset, PARAMS["batch_size"]) testloader = DataLoader(testset, PARAMS["batch_size"]) sample_rate = PARAMS["batch_size"] / len(trainset) return trainloader, testloader, sample_rate + model = Net() trainloader, testloader, sample_rate = load_data() + # Define Flower client. class FlowerClient(fl.client.NumPyClient): def __init__(self, model) -> None: @@ -118,7 +120,11 @@ def set_parameters(self, parameters): def fit(self, parameters, config): self.set_parameters(parameters) epsilon = train( - self.model, self.trainloader, self.privacy_engine, self.optimizer, PARAMS["local_epochs"] + self.model, + self.trainloader, + self.privacy_engine, + self.optimizer, + PARAMS["local_epochs"], ) print(f"epsilon = {epsilon:.2f}") return ( @@ -137,12 +143,12 @@ def client_fn(cid): model = Net() return FlowerClient(model).to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) if __name__ == "__main__": fl.client.start_client( - server_address="127.0.0.1:8080", - client=FlowerClient(model).to_client() + server_address="127.0.0.1:8080", client=FlowerClient(model).to_client() ) diff --git a/e2e/opacus/simulation.py b/e2e/opacus/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/opacus/simulation.py +++ b/e2e/opacus/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/pandas/client.py b/e2e/pandas/client.py index 0ecd75df3ae8..19e15f5a3b11 100644 --- a/e2e/pandas/client.py +++ b/e2e/pandas/client.py @@ -5,7 +5,6 @@ import flwr as fl - df = pd.read_csv("./data/client.csv") column_names = ["sepal length (cm)", "sepal width (cm)"] @@ -32,9 +31,11 @@ def fit( {}, ) + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) diff --git a/e2e/pandas/server.py b/e2e/pandas/server.py index 4c69ab3881d2..ef0e92a11ea2 100644 --- a/e2e/pandas/server.py +++ b/e2e/pandas/server.py @@ -1,7 +1,7 @@ -import flwr as fl - from strategy import FedAnalytics +import flwr as fl + app = fl.server.ServerApp() diff --git a/e2e/pandas/simulation.py b/e2e/pandas/simulation.py index b548b5ebb760..8160fb744229 100644 --- a/e2e/pandas/simulation.py +++ b/e2e/pandas/simulation.py @@ -1,8 +1,8 @@ -import flwr as fl - from client import client_fn from strategy import FedAnalytics +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, diff --git a/e2e/pytorch-lightning/client.py b/e2e/pytorch-lightning/client.py index fde550e31c08..fdd55b3dc344 100644 --- a/e2e/pytorch-lightning/client.py +++ b/e2e/pytorch-lightning/client.py @@ -1,9 +1,11 @@ -import flwr as fl +from collections import OrderedDict + import mnist import pytorch_lightning as pl -from collections import OrderedDict import torch +import flwr as fl + class FlowerClient(fl.client.NumPyClient): def __init__(self, model, train_loader, val_loader, test_loader): @@ -48,6 +50,7 @@ def _set_parameters(model, parameters): state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict}) model.load_state_dict(state_dict, strict=True) + def client_fn(cid): model = mnist.LitAutoEncoder() train_loader, val_loader, test_loader = mnist.load_data() @@ -55,10 +58,12 @@ def client_fn(cid): # Flower client return FlowerClient(model, train_loader, val_loader, test_loader).to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) + def main() -> None: # Model and data model = mnist.LitAutoEncoder() diff --git a/e2e/pytorch-lightning/mnist.py b/e2e/pytorch-lightning/mnist.py index 462087739474..b23efc50d1e4 100644 --- a/e2e/pytorch-lightning/mnist.py +++ b/e2e/pytorch-lightning/mnist.py @@ -3,14 +3,13 @@ Source: pytorchlightning.ai (2021/02/04) """ - +import pytorch_lightning as pl import torch from torch import nn from torch.nn import functional as F from torch.utils.data import DataLoader, Subset, random_split from torchvision import transforms from torchvision.datasets import MNIST -import pytorch_lightning as pl class LitAutoEncoder(pl.LightningModule): @@ -62,14 +61,18 @@ def _evaluate(self, batch, stage=None): def load_data(): # Training / validation set - trainset = MNIST("./data", train=True, download=True, transform=transforms.ToTensor()) + trainset = MNIST( + "./data", train=True, download=True, transform=transforms.ToTensor() + ) trainset = Subset(trainset, range(1000)) mnist_train, mnist_val = random_split(trainset, [800, 200]) train_loader = DataLoader(mnist_train, batch_size=32, shuffle=True, num_workers=0) val_loader = DataLoader(mnist_val, batch_size=32, shuffle=False, num_workers=0) # Test set - testset = MNIST("./data", train=False, download=True, transform=transforms.ToTensor()) + testset = MNIST( + "./data", train=False, download=True, transform=transforms.ToTensor() + ) testset = Subset(testset, range(10)) test_loader = DataLoader(testset, batch_size=32, shuffle=False, num_workers=0) @@ -78,7 +81,6 @@ def load_data(): def main() -> None: """Centralized training.""" - # Load data train_loader, val_loader, test_loader = load_data() diff --git a/e2e/pytorch-lightning/simulation.py b/e2e/pytorch-lightning/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/pytorch-lightning/simulation.py +++ b/e2e/pytorch-lightning/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/pytorch/client.py b/e2e/pytorch/client.py index 1fd07763148e..dbfbfed1ffa7 100644 --- a/e2e/pytorch/client.py +++ b/e2e/pytorch/client.py @@ -20,7 +20,7 @@ warnings.filterwarnings("ignore", category=UserWarning) DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") SUBSET_SIZE = 1000 -STATE_VAR = 'timestamp' +STATE_VAR = "timestamp" class Net(nn.Module): @@ -92,7 +92,7 @@ def load_data(): class FlowerClient(fl.client.NumPyClient): def get_parameters(self, config): return [val.cpu().numpy() for _, val in net.state_dict().items()] - + def _record_timestamp_to_state(self): """Record timestamp to client's state.""" t_stamp = datetime.now().timestamp() @@ -101,31 +101,45 @@ def _record_timestamp_to_state(self): value = self.context.state.configs_records[STATE_VAR][STATE_VAR] # type: ignore value += f",{t_stamp}" - self.context.state.configs_records[STATE_VAR] = ConfigsRecord({STATE_VAR: value}) - + self.context.state.configs_records[STATE_VAR] = ConfigsRecord( + {STATE_VAR: value} + ) + def _retrieve_timestamp_from_state(self): return self.context.state.configs_records[STATE_VAR][STATE_VAR] + def fit(self, parameters, config): set_parameters(net, parameters) train(net, trainloader, epochs=1) self._record_timestamp_to_state() - return self.get_parameters(config={}), len(trainloader.dataset), {STATE_VAR: self._retrieve_timestamp_from_state()} + return ( + self.get_parameters(config={}), + len(trainloader.dataset), + {STATE_VAR: self._retrieve_timestamp_from_state()}, + ) def evaluate(self, parameters, config): set_parameters(net, parameters) loss, accuracy = test(net, testloader) self._record_timestamp_to_state() - return loss, len(testloader.dataset), {"accuracy": accuracy, STATE_VAR: self._retrieve_timestamp_from_state()} + return ( + loss, + len(testloader.dataset), + {"accuracy": accuracy, STATE_VAR: self._retrieve_timestamp_from_state()}, + ) + def set_parameters(model, parameters): params_dict = zip(model.state_dict().keys(), parameters) state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict}) model.load_state_dict(state_dict, strict=True) - return + return + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) diff --git a/e2e/pytorch/simulation.py b/e2e/pytorch/simulation.py index a4c8d4642be2..25868eb8e33f 100644 --- a/e2e/pytorch/simulation.py +++ b/e2e/pytorch/simulation.py @@ -1,12 +1,12 @@ from typing import List, Tuple + import numpy as np +from client import client_fn import flwr as fl from flwr.common import Metrics - -from client import client_fn -STATE_VAR = 'timestamp' +STATE_VAR = "timestamp" # Define metric aggregation function @@ -15,18 +15,22 @@ def record_state_metrics(metrics: List[Tuple[int, Metrics]]) -> Metrics: states = [] for _, m in metrics: # split string and covert timestamps to float - states.append([float(tt) for tt in m[STATE_VAR].split(',')]) + states.append([float(tt) for tt in m[STATE_VAR].split(",")]) for client_state in states: if len(client_state) == 1: continue deltas = np.diff(client_state) - assert np.all(deltas > 0), f"Timestamps are not monotonically increasing: {client_state}" + assert np.all( + deltas > 0 + ), f"Timestamps are not monotonically increasing: {client_state}" return {STATE_VAR: states} -strategy = fl.server.strategy.FedAvg(evaluate_metrics_aggregation_fn=record_state_metrics) +strategy = fl.server.strategy.FedAvg( + evaluate_metrics_aggregation_fn=record_state_metrics +) hist = fl.simulation.start_simulation( client_fn=client_fn, @@ -35,8 +39,13 @@ def record_state_metrics(metrics: List[Tuple[int, Metrics]]) -> Metrics: strategy=strategy, ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) # The checks in record_state_metrics don't do anythinng if client's state has a single entry state_metrics_last_round = hist.metrics_distributed[STATE_VAR][-1] -assert len(state_metrics_last_round[1][0]) == 2*state_metrics_last_round[0], f"There should be twice as many entries in the client state as rounds" +assert ( + len(state_metrics_last_round[1][0]) == 2 * state_metrics_last_round[0] +), "There should be twice as many entries in the client state as rounds" diff --git a/e2e/scikit-learn/client.py b/e2e/scikit-learn/client.py index e073d3cb2748..b0691e75a79d 100644 --- a/e2e/scikit-learn/client.py +++ b/e2e/scikit-learn/client.py @@ -1,11 +1,11 @@ import warnings -import flwr as fl -import numpy as np +import numpy as np +import utils from sklearn.linear_model import LogisticRegression from sklearn.metrics import log_loss -import utils +import flwr as fl # Load MNIST dataset from https://www.openml.org/d/554 (X_train, y_train), (X_test, y_test) = utils.load_mnist() @@ -24,6 +24,7 @@ # Setting initial parameters, akin to model.compile for keras models utils.set_initial_params(model) + # Define Flower client class FlowerClient(fl.client.NumPyClient): def get_parameters(self, config): # type: ignore @@ -42,14 +43,18 @@ def evaluate(self, parameters, config): # type: ignore loss = log_loss(y_test, model.predict_proba(X_test)) accuracy = model.score(X_test, y_test) return loss, len(X_test), {"accuracy": accuracy} - + + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) if __name__ == "__main__": # Start Flower client - fl.client.start_client(server_address="0.0.0.0:8080", client=FlowerClient().to_client()) + fl.client.start_client( + server_address="0.0.0.0:8080", client=FlowerClient().to_client() + ) diff --git a/e2e/scikit-learn/simulation.py b/e2e/scikit-learn/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/scikit-learn/simulation.py +++ b/e2e/scikit-learn/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/scikit-learn/utils.py b/e2e/scikit-learn/utils.py index 2b8dcf8655ee..b7b202f7b760 100644 --- a/e2e/scikit-learn/utils.py +++ b/e2e/scikit-learn/utils.py @@ -1,7 +1,8 @@ -from typing import Tuple, Union, List +from typing import List, Tuple, Union + import numpy as np -from sklearn.linear_model import LogisticRegression import openml +from sklearn.linear_model import LogisticRegression XY = Tuple[np.ndarray, np.ndarray] Dataset = Tuple[XY, XY] @@ -34,12 +35,11 @@ def set_model_params( def set_initial_params(model: LogisticRegression): - """Sets initial parameters as zeros Required since model params are - uninitialized until model.fit is called. + """Sets initial parameters as zeros Required since model params are uninitialized + until model.fit is called. - But server asks for initial parameters from clients at launch. Refer - to sklearn.linear_model.LogisticRegression documentation for more - information. + But server asks for initial parameters from clients at launch. Refer to + sklearn.linear_model.LogisticRegression documentation for more information. """ n_classes = 10 # MNIST has 10 classes n_features = 784 # Number of features in dataset diff --git a/e2e/server.py b/e2e/server.py index 3b37ac4244e9..c678cd0a2446 100644 --- a/e2e/server.py +++ b/e2e/server.py @@ -1,6 +1,5 @@ import numpy as np - import flwr as fl STATE_VAR = "timestamp" @@ -77,4 +76,4 @@ def main(driver, context): state_metrics_last_round = hist.metrics_distributed[STATE_VAR][-1] assert ( len(state_metrics_last_round[1][0]) == 2 * state_metrics_last_round[0] - ), f"There should be twice as many entries in the client state as rounds" + ), "There should be twice as many entries in the client state as rounds" diff --git a/e2e/strategies/client.py b/e2e/strategies/client.py index 3b49f770dc6b..505340e013a5 100644 --- a/e2e/strategies/client.py +++ b/e2e/strategies/client.py @@ -1,19 +1,23 @@ import os -import flwr as fl import tensorflow as tf +import flwr as fl + SUBSET_SIZE = 1000 # Make TensorFlow log less verbose os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" + def get_model(): - model = tf.keras.models.Sequential([ - tf.keras.layers.Flatten(input_shape=(28, 28)), - tf.keras.layers.Dense(128, activation='relu'), - tf.keras.layers.Dense(10) - ]) + model = tf.keras.models.Sequential( + [ + tf.keras.layers.Flatten(input_shape=(28, 28)), + tf.keras.layers.Dense(128, activation="relu"), + tf.keras.layers.Dense(10), + ] + ) model.compile( optimizer=tf.keras.optimizers.Adam(0.001), loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), @@ -21,6 +25,7 @@ def get_model(): ) return model + model = get_model() (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data() x_train, y_train = x_train[:SUBSET_SIZE], y_train[:SUBSET_SIZE] @@ -54,4 +59,6 @@ def client_fn(cid): if __name__ == "__main__": # Start Flower client - fl.client.start_client(server_address="127.0.0.1:8080", client=FlowerClient().to_client()) + fl.client.start_client( + server_address="127.0.0.1:8080", client=FlowerClient().to_client() + ) diff --git a/e2e/tabnet/client.py b/e2e/tabnet/client.py index 0290ba4629de..1a7ecfd68f73 100644 --- a/e2e/tabnet/client.py +++ b/e2e/tabnet/client.py @@ -1,8 +1,10 @@ import os -import flwr as fl + +import tabnet import tensorflow as tf import tensorflow_datasets as tfds -import tabnet + +import flwr as fl train_size = 125 BATCH_SIZE = 50 @@ -81,10 +83,13 @@ def evaluate(self, parameters, config): def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) if __name__ == "__main__": # Start Flower client - fl.client.start_client(server_address="127.0.0.1:8080", client=FlowerClient().to_client()) + fl.client.start_client( + server_address="127.0.0.1:8080", client=FlowerClient().to_client() + ) diff --git a/e2e/tabnet/simulation.py b/e2e/tabnet/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/tabnet/simulation.py +++ b/e2e/tabnet/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) diff --git a/e2e/tensorflow/client.py b/e2e/tensorflow/client.py index 10ee91136241..779be0c3746d 100644 --- a/e2e/tensorflow/client.py +++ b/e2e/tensorflow/client.py @@ -1,8 +1,9 @@ import os -import flwr as fl import tensorflow as tf +import flwr as fl + SUBSET_SIZE = 1000 # Make TensorFlow log less verbose @@ -31,13 +32,17 @@ def evaluate(self, parameters, config): loss, accuracy = model.evaluate(x_test, y_test) return loss, len(x_test), {"accuracy": accuracy} + def client_fn(cid): return FlowerClient().to_client() + app = fl.client.ClientApp( client_fn=client_fn, ) if __name__ == "__main__": # Start Flower client - fl.client.start_client(server_address="127.0.0.1:8080", client=FlowerClient().to_client()) + fl.client.start_client( + server_address="127.0.0.1:8080", client=FlowerClient().to_client() + ) diff --git a/e2e/tensorflow/simulation.py b/e2e/tensorflow/simulation.py index 5f0e5334bd08..bf05a77cf32a 100644 --- a/e2e/tensorflow/simulation.py +++ b/e2e/tensorflow/simulation.py @@ -1,11 +1,14 @@ -import flwr as fl - from client import client_fn +import flwr as fl + hist = fl.simulation.start_simulation( client_fn=client_fn, num_clients=2, config=fl.server.ServerConfig(num_rounds=3), ) -assert hist.losses_distributed[-1][1] == 0 or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +assert ( + hist.losses_distributed[-1][1] == 0 + or (hist.losses_distributed[0][1] / hist.losses_distributed[-1][1]) >= 0.98 +) From 21272418f27de2ab8b30178f44724242f0704dc6 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 23 May 2024 09:31:07 +0100 Subject: [PATCH 004/124] fix (#3475) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 909cf890dccf..dabeb0a9eba9 100644 --- a/README.md +++ b/README.md @@ -150,7 +150,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples): - 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)) - [Comprehensive Flower+XGBoost](https://github.com/adap/flower/tree/main/examples/xgboost-comprehensive) - [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose) -- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplna-meier-fitter) +- [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter) - [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus) ## Community From f22cb84d32109ff7762462931d7e60aaf2b0604a Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 23 May 2024 11:37:10 +0200 Subject: [PATCH 005/124] fix(framework:skip) Use sqlite3 lib without dev headers (#3486) Signed-off-by: Robert Steiner --- src/docker/base/ubuntu/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 75152d00f8d6..6f2585d4570f 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -54,7 +54,7 @@ ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update \ && apt-get -y --no-install-recommends install \ - libsqlite3-dev \ + libsqlite3-0 \ && rm -rf /var/lib/apt/lists/* COPY --from=python /usr/local/bin/python /usr/local/bin/python From a754714865619fbaeb4a44a77956a473d2d49784 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 23 May 2024 12:08:53 +0200 Subject: [PATCH 006/124] ci(*:skip) Ignore dependabot PRs for title checks (#3495) --- .github/workflows/pr_check.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml index 47bb4b284136..6b3af429bb0d 100644 --- a/.github/workflows/pr_check.yml +++ b/.github/workflows/pr_check.yml @@ -14,6 +14,7 @@ jobs: pr_title_check: runs-on: ubuntu-22.04 name: Title format + if: ${{ github.actor != 'dependabot[bot]' }} steps: - uses: actions/checkout@v4 - name: Bootstrap From 14deafda25a74536d0d542492781ece20ce12178 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 23 May 2024 13:53:57 +0200 Subject: [PATCH 007/124] ci(*:skip) Upgrade pip and setuptools (#3496) --------- Signed-off-by: Robert Steiner Co-authored-by: Chong Shen Ng Co-authored-by: Taner Topal --- .devcontainer/Dockerfile | 4 ++-- .github/actions/bootstrap/action.yml | 6 +++--- dev/bootstrap.sh | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 03849995735d..ce4f8a1a5b8d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -29,8 +29,8 @@ RUN apt-get install -y curl wget gnupg python3 python-is-python3 python3-pip git build-essential tmux vim RUN python -m pip install \ - pip==23.3.1 \ - setuptools==68.2.2 \ + pip==24.0.0 \ + setuptools==69.5.1 \ poetry==1.7.1 USER $USERNAME diff --git a/.github/actions/bootstrap/action.yml b/.github/actions/bootstrap/action.yml index 8527f1f82307..bee90beffa7d 100644 --- a/.github/actions/bootstrap/action.yml +++ b/.github/actions/bootstrap/action.yml @@ -6,17 +6,17 @@ inputs: default: 3.8 pip-version: description: "Version of pip to be installed using pip" - default: 23.3.1 + default: 24.0.0 setuptools-version: description: "Version of setuptools to be installed using pip" - default: 68.2.2 + default: 69.5.1 poetry-version: description: "Version of poetry to be installed using pip" default: 1.7.1 poetry-skip: description: "Option to skip the poetry installation" required: false - default: 'false' + default: "false" outputs: python-version: description: "Version range or exact version of Python or PyPy" diff --git a/dev/bootstrap.sh b/dev/bootstrap.sh index b4bb82d73b51..154fe0f1cbaf 100755 --- a/dev/bootstrap.sh +++ b/dev/bootstrap.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e -cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../ +cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../ # Setup environment variables for development ./dev/setup-envs.sh @@ -9,8 +9,8 @@ cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../ ./dev/rm-caches.sh # Upgrade/install spcific versions of `pip`, `setuptools`, and `poetry` -python -m pip install -U pip==23.3.1 -python -m pip install -U setuptools==68.2.2 +python -m pip install -U pip==24.0.0 +python -m pip install -U setuptools==69.5.1 python -m pip install -U poetry==1.7.1 # Use `poetry` to install project dependencies From 97d1d4d6c65bbdcd8bc2ed2c6c65ae58af64d4a7 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 23 May 2024 14:30:46 +0200 Subject: [PATCH 008/124] ci(*:skip) Fix PR title check regex (#3497) --- .github/workflows/pr_check.yml | 1 - dev/changelog_config.toml | 2 +- dev/check_pr_title.py | 29 ++++++++++++++++------------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/.github/workflows/pr_check.yml b/.github/workflows/pr_check.yml index 6b3af429bb0d..47bb4b284136 100644 --- a/.github/workflows/pr_check.yml +++ b/.github/workflows/pr_check.yml @@ -14,7 +14,6 @@ jobs: pr_title_check: runs-on: ubuntu-22.04 name: Title format - if: ${{ github.actor != 'dependabot[bot]' }} steps: - uses: actions/checkout@v4 - name: Bootstrap diff --git a/dev/changelog_config.toml b/dev/changelog_config.toml index 892050cdb084..898f9bfdb221 100644 --- a/dev/changelog_config.toml +++ b/dev/changelog_config.toml @@ -7,7 +7,7 @@ project = ["framework", "baselines", "datasets", "examples"] scope = "skip" -pattern_template = "^({types})\\(({projects})(?::({scope}))?\\) ([A-Z][^\\.\\n]*(?:\\.(?=[^\\.\\n]))*[^\\.\\n]*)$" +pattern_template = "^({types})\\(({projects})(?::({scope}))?\\) ([A-Z][^\\n]*[^\\.\\n])$" allowed_verbs=[ "Abandon", diff --git a/dev/check_pr_title.py b/dev/check_pr_title.py index e2679b3e7226..33b7a4664e9f 100644 --- a/dev/check_pr_title.py +++ b/dev/check_pr_title.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""This module is used to check a given PR title format.""" +"""Used to check a given PR title format.""" import pathlib import re @@ -46,10 +46,13 @@ valid = True error = "it doesn't have the correct format" - if not match: + # This check is there to ignore dependabot PRs from title checks + if pr_title.startswith("chore"): + sys.exit(0) + elif not match: valid = False else: - if not match.group(4).split()[0] in allowed_verbs: + if match.group(4).split()[0] not in allowed_verbs: valid = False error = "the doesn't start with a verb in the imperative mood" elif match.group(2) == "*" and match.group(3) is None: @@ -58,16 +61,16 @@ if not valid: print( - f"PR title `{pr_title}` is invalid, {error}.\n\n" - "A PR title should be of the form:\n\n\t() " - f"\n\nOr, if the PR shouldn't appear in the changelog:\n\n\t" - f"(:skip) \n\nwith in [{types}],\n" - f" in [{'|'.join(config['project']) + '|*'}] (where '*' is used " - "when modifying multiple projects and should be used in " + f"PR title `{pr_title}` is invalid, {error}.\n\nA PR title should " + "be of the form:\n\n\t() \n\n" + f"Or, if the PR shouldn't appear in the changelog:\n\n\t" + f"(:skip) \n\nwith in [{types}],\n" + f" in [{'|'.join(config['project']) + '|*'}] " + "(where '*' is used when modifying multiple projects and should be used in " "conjunction with the ':skip' flag),\nand starting with " - "a capitalized verb in the imperative mood and without any punctuation at the end.\n\n" - "A valid example is:\n\n\t`feat(framework) Add flwr build CLI command`\n\n" - "Or, if the PR shouldn't appear in the changelog:\n\n\t" - "`feat(framework:skip) Add new option to build CLI`\n" + "a capitalized verb in the imperative mood and without any punctuation " + "at the end.\n\nA valid example is:\n\n\t`feat(framework) " + "Add flwr build CLI command`\n\nOr, if the PR shouldn't appear in " + "the changelog:\n\n\t`feat(framework:skip) Add new option to build CLI`\n" ) sys.exit(1) From 30e99983f7d777f504ce7f5bd828ca1310c8ac77 Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 23 May 2024 15:26:29 +0100 Subject: [PATCH 009/124] fix(*:skip) Exclude `setuptools` version from `pyproject.toml` (#3494) --------- Co-authored-by: Taner Topal Co-authored-by: Taner Topal --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 57ed4450cc52..adacd5d2b4e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,13 +73,13 @@ iterators = "^0.0.2" typer = { version = "^0.9.0", extras=["all"] } tomli = "^2.0.1" pathspec = "^0.12.1" +setuptools = "!=70.0.0" # Optional dependencies (Simulation Engine) ray = { version = "==2.6.3", optional = true, python = ">=3.8,<3.12" } # Optional dependencies (REST transport layer) requests = { version = "^2.31.0", optional = true } starlette = { version = "^0.31.0", optional = true } uvicorn = { version = "^0.23.0", extras = ["standard"], optional = true } -setuptools = "69.5.1" [tool.poetry.extras] simulation = ["ray", "pydantic"] From a43aa0d77a02997d251a0945e108f4c1a29de004 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Thu, 23 May 2024 17:17:33 +0100 Subject: [PATCH 010/124] ci(framework:skip) Add caching to speed up E2E CI tests (#3480) --- .github/workflows/e2e.yml | 20 +++++++++++++--- e2e/bare-client-auth/pyproject.toml | 21 +++++++++++------ e2e/bare-https/pyproject.toml | 21 +++++++++++------ e2e/bare/pyproject.toml | 21 +++++++++++------ e2e/fastai/pyproject.toml | 25 +++++++++++++------- e2e/jax/pyproject.toml | 31 ++++++++++++++---------- e2e/opacus/pyproject.toml | 27 +++++++++++++-------- e2e/pandas/pyproject.toml | 33 ++++++++++++++++---------- e2e/pytorch-lightning/pyproject.toml | 27 +++++++++++++-------- e2e/pytorch/pyproject.toml | 31 ++++++++++++++---------- e2e/scikit-learn/pyproject.toml | 29 +++++++++++++---------- e2e/tabnet/pyproject.toml | 35 +++++++++++++++++----------- e2e/tensorflow/pyproject.toml | 29 ++++++++++++++--------- 13 files changed, 224 insertions(+), 126 deletions(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 57802e598546..1802809bd2b0 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -118,12 +118,26 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Bootstrap - uses: ./.github/actions/bootstrap + - name: Set up Python + uses: actions/setup-python@v5 with: python-version: 3.8 + - name: Install build tools + run: | + python -m pip install -U pip==23.3.1 + shell: bash + # Using approach described here for Python location caching: + # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d + - name: Cache Python location + id: cache-python + uses: actions/cache@v4 + with: + path: ${{ env.pythonLocation }} + key: pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }}-${{ hashFiles('**/pyproject.toml') }} + restore-keys: | + pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }} - name: Install dependencies - run: python -m poetry install + run: python -m pip install --upgrade . - name: Install Flower wheel from artifact store if: ${{ github.repository == 'adap/flower' && !github.event.pull_request.head.repo.fork && github.actor != 'dependabot[bot]' }} run: | diff --git a/e2e/bare-client-auth/pyproject.toml b/e2e/bare-client-auth/pyproject.toml index 693fec815474..839f0779cc01 100644 --- a/e2e/bare-client-auth/pyproject.toml +++ b/e2e/bare-client-auth/pyproject.toml @@ -1,13 +1,20 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "bare_client_auth_test" version = "0.1.0" description = "Client-auth-enabled bare Federated Learning test with Flower" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr @ {root:parent:parent:uri}", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true } +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/bare-https/pyproject.toml b/e2e/bare-https/pyproject.toml index 3afb7b57a084..de8aa92cbd02 100644 --- a/e2e/bare-https/pyproject.toml +++ b/e2e/bare-https/pyproject.toml @@ -1,13 +1,20 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "bare_https_test" version = "0.1.0" description = "HTTPS-enabled bare Federated Learning test with Flower" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr @ {root:parent:parent:uri}", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true } +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/bare/pyproject.toml b/e2e/bare/pyproject.toml index 45ce7ea333af..ba8c1b2b2276 100644 --- a/e2e/bare/pyproject.toml +++ b/e2e/bare/pyproject.toml @@ -1,13 +1,20 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "bare_test" version = "0.1.0" description = "Bare Federated Learning test with Flower" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation,rest] @ {root:parent:parent:uri}", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation", "rest"] } +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/fastai/pyproject.toml b/e2e/fastai/pyproject.toml index feed31f6d202..53d3b7e7baf1 100644 --- a/e2e/fastai/pyproject.toml +++ b/e2e/fastai/pyproject.toml @@ -1,15 +1,22 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "quickstart-fastai" version = "0.1.0" description = "Fastai Federated Learning E2E test with Flower" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "fastai>=2.7.12,<3.0.0", + "torch>=2.0.0,!=2.0.1,<2.1.0", +] -[tool.poetry.dependencies] -python = ">=3.8,<3.10" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -fastai = "^2.7.12" -torch = ">=2.0.0, !=2.0.1, < 2.1.0" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/jax/pyproject.toml b/e2e/jax/pyproject.toml index 9a4af5dee59a..bb024ba14d23 100644 --- a/e2e/jax/pyproject.toml +++ b/e2e/jax/pyproject.toml @@ -1,17 +1,24 @@ -[tool.poetry] +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] name = "jax_example" version = "0.1.0" description = "JAX example training a linear regression model with federated learning" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "jax==0.4.13", + "jaxlib==0.4.13", + "scikit-learn>=1.1.1,<2.0.0", + "numpy>=1.21.4,<2.0.0", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -jax = "==0.4.13" -jaxlib = "==0.4.13" -scikit-learn = "^1.1.1" -numpy = "^1.21.4" +[tool.hatch.build.targets.wheel] +packages = ["."] -[build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/opacus/pyproject.toml b/e2e/opacus/pyproject.toml index ab4a727cc00b..8fd1056f43a3 100644 --- a/e2e/opacus/pyproject.toml +++ b/e2e/opacus/pyproject.toml @@ -1,16 +1,23 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "opacus_e2e" version = "0.1.0" description = "Opacus E2E testing" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "opacus>=1.4.0,<2.0.0", + "torch>=1.13.1,<2.0.0", + "torchvision>=0.14.0,<2.0.0", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -opacus = "^1.4.0" -torch = "^1.13.1" -torchvision = "^0.14.0" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/pandas/pyproject.toml b/e2e/pandas/pyproject.toml index 416dfeec3460..f8f8488a7006 100644 --- a/e2e/pandas/pyproject.toml +++ b/e2e/pandas/pyproject.toml @@ -1,17 +1,26 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] +[project] name = "quickstart-pandas" version = "0.1.0" -description = "Pandas Federated Analytics Quickstart with Flower" -authors = ["Ragy Haddad "] -maintainers = ["The Flower Authors "] +description = "Pandas E2E test with Flower" +authors = [ + { name = "Ragy Haddad", email = "ragy202@gmail.com" }, +] +maintainers = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "numpy>=1.21.0,<2.0.0", + "pandas>=2.0.0,<3.0.0", + "scikit-learn>=1.1.1,<2.0.0", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -numpy = "^1.21.0" -pandas = "^2.0.0" -scikit-learn = "^1.1.1" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/pytorch-lightning/pyproject.toml b/e2e/pytorch-lightning/pyproject.toml index 90d659813c28..8706ef098d8b 100644 --- a/e2e/pytorch-lightning/pyproject.toml +++ b/e2e/pytorch-lightning/pyproject.toml @@ -1,15 +1,22 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "quickstart-pytorch-lightning" +[project] +name = "quickstart-pytorch-lightning-test" version = "0.1.0" description = "Federated Learning E2E test with Flower and PyTorch Lightning" -authors = ["The Flower Authors "] +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "pytorch-lightning==2.2.4", + "torchvision==0.14.1", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -pytorch-lightning = "2.2.4" -torchvision = "0.14.1" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/pytorch/pyproject.toml b/e2e/pytorch/pyproject.toml index e538f1437df6..8c59c43d50df 100644 --- a/e2e/pytorch/pyproject.toml +++ b/e2e/pytorch/pyproject.toml @@ -1,16 +1,23 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "quickstart-pytorch" +[project] +name = "pytorch_e2e" version = "0.1.0" -description = "PyTorch Federated Learning Quickstart with Flower" -authors = ["The Flower Authors "] +description = "PyTorch Federated Learning E2E test with Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "torch>=1.12.0,<2.0.0", + "torchvision>=0.14.1,<0.15.0", + "tqdm>=4.63.0,<5.0.0", +] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -torch = "^1.12.0" -torchvision = "^0.14.1" -tqdm = "^4.63.0" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/scikit-learn/pyproject.toml b/e2e/scikit-learn/pyproject.toml index 50c07d31add7..caba2324d44f 100644 --- a/e2e/scikit-learn/pyproject.toml +++ b/e2e/scikit-learn/pyproject.toml @@ -1,18 +1,23 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "sklearn-mnist" +[project] +name = "sklearn-mnist-test" version = "0.1.0" -description = "Federated learning with scikit-learn and Flower" +description = "Federated learning E2E test with scikit-learn and Flower" authors = [ - "The Flower Authors ", - "Kaushik Amar Das ", + { name = "The Flower Authors", email = "hello@flower.ai" }, + { name = "Kaushik Amar Das", email = "kaushik.das@iiitg.ac.in"}, ] +dependencies = [ + "flwr[simulation,rest] @ {root:parent:parent:uri}", + "scikit-learn>=1.1.1,<2.0.0", + "openml>=0.14.0,<0.15.0" +] + +[tool.hatch.build.targets.wheel] +packages = ["."] -[tool.poetry.dependencies] -python = "^3.8" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -scikit-learn = "^1.1.1" -openml = "^0.14.0" +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/tabnet/pyproject.toml b/e2e/tabnet/pyproject.toml index b1abf382a24a..99379ddb607e 100644 --- a/e2e/tabnet/pyproject.toml +++ b/e2e/tabnet/pyproject.toml @@ -1,18 +1,25 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "quickstart-tabnet" +[project] +name = "quickstart-tabnet-test" version = "0.1.0" -description = "Tabnet Federated Learning Quickstart with Flower" -authors = ["The Flower Authors "] +description = "Tabnet Federated Learning E2E test with Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "tensorflow-cpu>=2.9.1,!=2.11.1; platform_machine == \"x86_64\"", + "tensorflow-macos>=2.9.1,!=2.11.1; sys_platform == \"darwin\" and platform_machine == \"arm64\"", + "tensorflow_datasets==4.9.2", + "tensorflow-io-gcs-filesystem<0.35.0", + "tabnet==0.1.6", +] -[tool.poetry.dependencies] -python = ">=3.8,<3.11" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -tensorflow-cpu = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "platform_machine == \"x86_64\"" } -tensorflow-macos = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "sys_platform == \"darwin\" and platform_machine == \"arm64\"" } -tensorflow_datasets = "4.9.2" -tensorflow-io-gcs-filesystem = "<0.35.0" -tabnet = "0.1.6" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true diff --git a/e2e/tensorflow/pyproject.toml b/e2e/tensorflow/pyproject.toml index a7dbfe2305db..4b035873223c 100644 --- a/e2e/tensorflow/pyproject.toml +++ b/e2e/tensorflow/pyproject.toml @@ -1,15 +1,22 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "quickstart-tensorflow" +[project] +name = "quickstart-tensorflow-test" version = "0.1.0" -description = "Keras Federated Learning Quickstart with Flower" -authors = ["The Flower Authors "] +description = "Keras Federated Learning E2E test with Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation] @ {root:parent:parent:uri}", + "tensorflow-cpu>=2.9.1,!=2.11.1", + "tensorflow-io-gcs-filesystem<0.35.0", +] -[tool.poetry.dependencies] -python = ">=3.8,<3.11" -flwr = { path = "../../", develop = true, extras = ["simulation"] } -tensorflow-cpu = "^2.9.1, !=2.11.1" -tensorflow-io-gcs-filesystem = "<0.35.0" +[tool.hatch.build.targets.wheel] +packages = ["."] + +[tool.hatch.metadata] +allow-direct-references = true From 117216739bbb6c847b48d6dc9d89be1aa8e7ea6b Mon Sep 17 00:00:00 2001 From: Javier Date: Thu, 23 May 2024 18:45:31 +0100 Subject: [PATCH 011/124] ci(framework) Add `FlowerNext` simulation E2E (#3363) Co-authored-by: Heng Pan Co-authored-by: Daniel J. Beutel --- .github/workflows/e2e.yml | 3 +++ e2e/pytorch/simulation_next.py | 14 ++++++++++++++ e2e/tensorflow/simulation_next.py | 14 ++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 e2e/pytorch/simulation_next.py create mode 100644 e2e/tensorflow/simulation_next.py diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 1802809bd2b0..18ca4e46d593 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -151,6 +151,9 @@ jobs: - name: Run virtual client test if: ${{ matrix.directory != 'bare-client-auth' }} run: python simulation.py + - name: Run simulation engine test + if: ${{ matrix.directory == 'pytorch' || matrix.directory == 'tensorflow'}} + run: python simulation_next.py - name: Run driver test if: ${{ matrix.directory != 'bare-client-auth' }} run: ./../test_driver.sh "${{ matrix.directory }}" diff --git a/e2e/pytorch/simulation_next.py b/e2e/pytorch/simulation_next.py new file mode 100644 index 000000000000..ba1719dfb75b --- /dev/null +++ b/e2e/pytorch/simulation_next.py @@ -0,0 +1,14 @@ +from client import app as client_app + +import flwr as fl + +# Define ServerAppp +server_app = fl.server.ServerApp( + config=fl.server.ServerConfig(num_rounds=3), +) + + +# Run with FlowerNext +fl.simulation.run_simulation( + server_app=server_app, client_app=client_app, num_supernodes=2 +) diff --git a/e2e/tensorflow/simulation_next.py b/e2e/tensorflow/simulation_next.py new file mode 100644 index 000000000000..ba1719dfb75b --- /dev/null +++ b/e2e/tensorflow/simulation_next.py @@ -0,0 +1,14 @@ +from client import app as client_app + +import flwr as fl + +# Define ServerAppp +server_app = fl.server.ServerApp( + config=fl.server.ServerConfig(num_rounds=3), +) + + +# Run with FlowerNext +fl.simulation.run_simulation( + server_app=server_app, client_app=client_app, num_supernodes=2 +) From 0c88e528902c3d9e49c5cf899c628140fc14c8fa Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 23 May 2024 22:53:31 +0200 Subject: [PATCH 012/124] ci(framework:skip) Switch to new base images (#3483) --------- Signed-off-by: Robert Steiner --- .github/workflows/_docker-build.yml | 1 + .github/workflows/docker-base.yml | 60 -------- .github/workflows/docker-images.yml | 75 ++++++++++ .github/workflows/docker-serverapp.yml | 52 ------- .github/workflows/docker-superlink.yml | 45 ------ .github/workflows/docker-supernode.yml | 52 ------- dev/build-docker-image-matrix.py | 182 +++++++++++++++++++++++++ src/docker/serverapp/Dockerfile | 16 +-- src/docker/superlink/Dockerfile | 16 +-- src/docker/supernode/Dockerfile | 12 +- 10 files changed, 264 insertions(+), 247 deletions(-) delete mode 100644 .github/workflows/docker-base.yml create mode 100644 .github/workflows/docker-images.yml delete mode 100644 .github/workflows/docker-serverapp.yml delete mode 100644 .github/workflows/docker-superlink.yml delete mode 100644 .github/workflows/docker-supernode.yml create mode 100644 dev/build-docker-image-matrix.py diff --git a/.github/workflows/_docker-build.yml b/.github/workflows/_docker-build.yml index 043b6139a79e..608158fc0a5a 100644 --- a/.github/workflows/_docker-build.yml +++ b/.github/workflows/_docker-build.yml @@ -88,6 +88,7 @@ jobs: id: build uses: docker/build-push-action@2cdde995de11925a030ce8070c3d77a52ffcf1c0 # v5.3.0 with: + pull: true platforms: ${{ matrix.platform.docker }} context: "{{defaultContext}}:${{ inputs.file-dir }}" build-args: ${{ inputs.build-args }} diff --git a/.github/workflows/docker-base.yml b/.github/workflows/docker-base.yml deleted file mode 100644 index f779043d9932..000000000000 --- a/.github/workflows/docker-base.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Build docker base image - -on: - workflow_dispatch: - inputs: - flwr-version: - description: "Version of Flower." - required: true - type: string - -permissions: - contents: read - -jobs: - parameters: - name: Collect build parameters - runs-on: ubuntu-22.04 - timeout-minutes: 10 - outputs: - pip-version: ${{ steps.versions.outputs.pip-version }} - setuptools-version: ${{ steps.versions.outputs.setuptools-version }} - - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - uses: ./.github/actions/bootstrap - id: bootstrap - - - id: versions - run: | - echo "pip-version=${{ steps.bootstrap.outputs.pip-version }}" >> "$GITHUB_OUTPUT" - echo "setuptools-version=${{ steps.bootstrap.outputs.setuptools-version }}" >> "$GITHUB_OUTPUT" - - build-base-images: - name: Build base images - uses: ./.github/workflows/_docker-build.yml - needs: parameters - strategy: - fail-fast: false - matrix: - python-version: ["3.8", "3.9", "3.10", "3.11"] - distro: - - name: ubuntu - version: "22.04" - - name: alpine - version: "3.19" - with: - namespace-repository: flwr/base - file-dir: src/docker/base/${{ matrix.distro.name }} - build-args: | - PYTHON_VERSION=${{ matrix.python-version }} - PIP_VERSION=${{ needs.parameters.outputs.pip-version }} - SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }} - DISTRO=${{ matrix.distro.name }} - DISTRO_VERSION=${{ matrix.distro.version }} - FLWR_VERSION=${{ github.event.inputs.flwr-version }} - tags: ${{ github.event.inputs.flwr-version }}-py${{ matrix.python-version }}-${{ matrix.distro.name }}${{ matrix.distro.version }} - secrets: - dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} - dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-images.yml b/.github/workflows/docker-images.yml new file mode 100644 index 000000000000..e341ae62e3f7 --- /dev/null +++ b/.github/workflows/docker-images.yml @@ -0,0 +1,75 @@ +name: Build docker images + +on: + workflow_dispatch: + inputs: + flwr-version: + description: "Version of Flower." + required: true + type: string + +permissions: + contents: read + +jobs: + parameters: + name: Collect build parameters + runs-on: ubuntu-22.04 + timeout-minutes: 10 + outputs: + pip-version: ${{ steps.versions.outputs.pip-version }} + setuptools-version: ${{ steps.versions.outputs.setuptools-version }} + matrix: ${{ steps.matrix.outputs.matrix }} + steps: + - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + + - uses: ./.github/actions/bootstrap + id: bootstrap + + - id: versions + run: | + echo "pip-version=${{ steps.bootstrap.outputs.pip-version }}" >> "$GITHUB_OUTPUT" + echo "setuptools-version=${{ steps.bootstrap.outputs.setuptools-version }}" >> "$GITHUB_OUTPUT" + + - id: matrix + run: | + python dev/build-docker-image-matrix.py --flwr-version ${{ github.event.inputs.flwr-version }} > matrix.json + echo "matrix=$(cat matrix.json)" >> $GITHUB_OUTPUT + + build-base-images: + name: Build base images + uses: ./.github/workflows/_docker-build.yml + needs: parameters + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.parameters.outputs.matrix).base }} + with: + namespace-repository: ${{ matrix.images.namespace_repository }} + file-dir: ${{ matrix.images.file_dir }} + build-args: | + PYTHON_VERSION=${{ matrix.images.python_version }} + PIP_VERSION=${{ needs.parameters.outputs.pip-version }} + SETUPTOOLS_VERSION=${{ needs.parameters.outputs.setuptools-version }} + DISTRO=${{ matrix.images.distro.name }} + DISTRO_VERSION=${{ matrix.images.distro.version }} + FLWR_VERSION=${{ matrix.images.flwr_version }} + tags: ${{ matrix.images.tag }} + secrets: + dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} + + build-binary-images: + name: Build binary images + uses: ./.github/workflows/_docker-build.yml + needs: [parameters, build-base-images] + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.parameters.outputs.matrix).binary }} + with: + namespace-repository: ${{ matrix.images.namespace_repository }} + file-dir: ${{ matrix.images.file_dir }} + build-args: BASE_IMAGE=${{ matrix.images.base_image }} + tags: ${{ matrix.images.tags }} + secrets: + dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-serverapp.yml b/.github/workflows/docker-serverapp.yml deleted file mode 100644 index 531ef079c641..000000000000 --- a/.github/workflows/docker-serverapp.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Build docker ServerApp image - -on: - workflow_dispatch: - inputs: - flwr-version: - description: "Version of Flower." - required: true - type: string - -permissions: - contents: read - -jobs: - build-serverapp-images: - name: Build images - uses: ./.github/workflows/_docker-build.yml - # run only on default branch when using it with workflow_dispatch - if: github.ref_name == github.event.repository.default_branch - strategy: - fail-fast: false - matrix: - image: [ - { - py-version: "3.8", - tags: "${{ github.event.inputs.flwr-version }}-py3.8-ubuntu22.04" - }, - { - py-version: "3.9", - tags: "${{ github.event.inputs.flwr-version }}-py3.9-ubuntu22.04" - }, - { - py-version: "3.10", - tags: "${{ github.event.inputs.flwr-version }}-py3.10-ubuntu22.04" - }, - { - py-version: "3.11", - # those are two tags -py3.11-py3.11-ubuntu22.04 and separated by a \n - tags: "${{ github.event.inputs.flwr-version }}-py3.11-ubuntu22.04\n${{ github.event.inputs.flwr-version }}" - }, - ] - with: - namespace-repository: flwr/serverapp - file-dir: src/docker/serverapp - build-args: | - FLWR_VERSION=${{ github.event.inputs.flwr-version }} - PYTHON_VERSION=${{ matrix.image.py-version }} - UBUNTU_VERSION=ubuntu22.04 - tags: ${{ matrix.image.tags }} - secrets: - dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} - dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/.github/workflows/docker-superlink.yml b/.github/workflows/docker-superlink.yml deleted file mode 100644 index b6a6b4114ba4..000000000000 --- a/.github/workflows/docker-superlink.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Build docker SuperLink image - -on: - workflow_dispatch: - inputs: - flwr-version: - description: "Version of Flower." - required: true - type: string - -permissions: - contents: read - -jobs: - build-superlink-images: - name: Build images - uses: ./.github/workflows/_docker-build.yml - # run only on default branch when using it with workflow_dispatch - if: github.ref_name == github.event.repository.default_branch - with: - namespace-repository: flwr/superlink - file-dir: src/docker/superlink - build-args: | - FLWR_VERSION=${{ github.event.inputs.flwr-version }} - PYTHON_VERSION=3.11 - UBUNTU_VERSION=ubuntu22.04 - tags: | - ${{ github.event.inputs.flwr-version }}-py3.11-ubuntu22.04 - ${{ github.event.inputs.flwr-version }} - secrets: - dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} - dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} - - summary: - name: Summary - runs-on: ubuntu-22.04 - needs: build-superlink-images - timeout-minutes: 10 - steps: - - run: | - echo "### Images" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - for IMAGE in $(echo ${{ toJson(needs.build-superlink-images.outputs.metadata) }} | jq -r '.tags[]' ); do - echo "- $IMAGE" >> $GITHUB_STEP_SUMMARY - done diff --git a/.github/workflows/docker-supernode.yml b/.github/workflows/docker-supernode.yml deleted file mode 100644 index 83b53764b794..000000000000 --- a/.github/workflows/docker-supernode.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Build docker SuperNode image - -on: - workflow_dispatch: - inputs: - flwr-version: - description: "Version of Flower." - required: true - type: string - -permissions: - contents: read - -jobs: - build-supernode-images: - name: Build images - uses: ./.github/workflows/_docker-build.yml - # run only on default branch when using it with workflow_dispatch - if: github.ref_name == github.event.repository.default_branch - strategy: - fail-fast: false - matrix: - image: [ - { - py-version: "3.8", - tags: "${{ github.event.inputs.flwr-version }}-py3.8-ubuntu22.04" - }, - { - py-version: "3.9", - tags: "${{ github.event.inputs.flwr-version }}-py3.9-ubuntu22.04" - }, - { - py-version: "3.10", - tags: "${{ github.event.inputs.flwr-version }}-py3.10-ubuntu22.04" - }, - { - py-version: "3.11", - # those are two tags -py3.11-py3.11-ubuntu22.04 and separated by a \n - tags: "${{ github.event.inputs.flwr-version }}-py3.11-ubuntu22.04\n${{ github.event.inputs.flwr-version }}" - }, - ] - with: - namespace-repository: flwr/supernode - file-dir: src/docker/supernode - build-args: | - FLWR_VERSION=${{ github.event.inputs.flwr-version }} - PYTHON_VERSION=${{ matrix.image.py-version }} - UBUNTU_VERSION=ubuntu22.04 - tags: ${{ matrix.image.tags }} - secrets: - dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} - dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} diff --git a/dev/build-docker-image-matrix.py b/dev/build-docker-image-matrix.py new file mode 100644 index 000000000000..5b9c63434bfb --- /dev/null +++ b/dev/build-docker-image-matrix.py @@ -0,0 +1,182 @@ +""" +Usage: python dev/build-docker-image-matrix.py --flwr-version +""" + +import argparse +from dataclasses import asdict, dataclass +from enum import Enum +import json +from typing import Any, Callable, Dict, List, Optional + + +class DistroName(str, Enum): + ALPINE = "alpine" + UBUNTU = "ubuntu" + + +@dataclass +class Distro: + name: "DistroName" + version: str + + +LATEST_SUPPORTED_PYTHON_VERSION = "3.11" +SUPPORTED_PYTHON_VERSIONS = [ + "3.8", + "3.9", + "3.10", + LATEST_SUPPORTED_PYTHON_VERSION, +] + +DOCKERFILE_ROOT = "src/docker" + + +@dataclass +class BaseImage: + distro: Distro + python_version: str + namespace_repository: str + file_dir: str + tag: str + flwr_version: str + + +def new_base_image( + flwr_version: str, python_version: str, distro: Distro +) -> Dict[str, Any]: + return BaseImage( + distro, + python_version, + "flwr/base", + f"{DOCKERFILE_ROOT}/base/{distro.name.value}", + f"{flwr_version}-py{python_version}-{distro.name.value}{distro.version}", + flwr_version, + ) + + +def generate_base_images( + flwr_version: str, python_versions: List[str], distros: List[Dict[str, str]] +) -> List[Dict[str, Any]]: + return [ + new_base_image(flwr_version, python_version, distro) + for distro in distros + for python_version in python_versions + ] + + +@dataclass +class BinaryImage: + namespace_repository: str + file_dir: str + base_image: str + tags: List[str] + + +def new_binary_image( + name: str, + base_image: BaseImage, + tags_fn: Optional[Callable], +) -> Dict[str, Any]: + tags = [] + if tags_fn is not None: + tags += tags_fn(base_image) or [] + + return BinaryImage( + f"flwr/{name}", + f"{DOCKERFILE_ROOT}/{name}", + base_image.tag, + "\n".join(tags), + ) + + +def generate_binary_images( + name: str, + base_images: List[BaseImage], + tags_fn: Optional[Callable] = None, + filter: Optional[Callable] = None, +) -> List[Dict[str, Any]]: + filter = filter or (lambda _: True) + + return [ + new_binary_image(name, image, tags_fn) for image in base_images if filter(image) + ] + + +def tag_latest_alpine_with_flwr_version(image: BaseImage) -> List[str]: + if ( + image.distro.name == DistroName.ALPINE + and image.python_version == LATEST_SUPPORTED_PYTHON_VERSION + ): + return [image.tag, image.flwr_version] + else: + return [image.tag] + + +def tag_latest_ubuntu_with_flwr_version(image: BaseImage) -> List[str]: + if ( + image.distro.name == DistroName.UBUNTU + and image.python_version == LATEST_SUPPORTED_PYTHON_VERSION + ): + return [image.tag, image.flwr_version] + else: + return [image.tag] + + +if __name__ == "__main__": + arg_parser = argparse.ArgumentParser( + description="Generate Github Docker workflow matrix" + ) + arg_parser.add_argument("--flwr-version", type=str, required=True) + args = arg_parser.parse_args() + + flwr_version = args.flwr_version + + # ubuntu base images for each supported python version + ubuntu_base_images = generate_base_images( + flwr_version, + SUPPORTED_PYTHON_VERSIONS, + [Distro(DistroName.UBUNTU, "22.04")], + ) + # alpine base images for the latest supported python version + alpine_base_images = generate_base_images( + flwr_version, + [LATEST_SUPPORTED_PYTHON_VERSION], + [Distro(DistroName.ALPINE, "3.19")], + ) + + base_images = ubuntu_base_images + alpine_base_images + + binary_images = ( + # ubuntu and alpine images for the latest supported python version + generate_binary_images( + "superlink", + base_images, + tag_latest_alpine_with_flwr_version, + lambda image: image.python_version == LATEST_SUPPORTED_PYTHON_VERSION, + ) + # ubuntu images for each supported python version + + generate_binary_images( + "supernode", + base_images, + tag_latest_ubuntu_with_flwr_version, + lambda image: image.distro.name == DistroName.UBUNTU, + ) + # ubuntu images for each supported python version + + generate_binary_images( + "serverapp", + base_images, + tag_latest_ubuntu_with_flwr_version, + lambda image: image.distro.name == DistroName.UBUNTU, + ) + ) + + print( + json.dumps( + { + "base": {"images": list(map(lambda image: asdict(image), base_images))}, + "binary": { + "images": list(map(lambda image: asdict(image), binary_images)) + }, + } + ) + ) diff --git a/src/docker/serverapp/Dockerfile b/src/docker/serverapp/Dockerfile index 22b464a3838c..08eceacc4557 100644 --- a/src/docker/serverapp/Dockerfile +++ b/src/docker/serverapp/Dockerfile @@ -14,19 +14,7 @@ # ============================================================================== ARG BASE_REPOSITORY=flwr/base -ARG PYTHON_VERSION=3.11 -ARG UBUNTU_VERSION=ubuntu22.04 -FROM $BASE_REPOSITORY:py${PYTHON_VERSION}-${UBUNTU_VERSION} +ARG BASE_IMAGE +FROM $BASE_REPOSITORY:$BASE_IMAGE -ARG FLWR_PACKAGE=flwr -ARG FLWR_VERSION -RUN python -m pip install -U --no-cache-dir \ - ${FLWR_PACKAGE}==${FLWR_VERSION} && \ - # Without pyenv rehash the executable cannot be found. - # pyenv rehash is usually called via the shell by adding - # `pyenv init -` in the shell profile, but that doesn't work - # well in docker - pyenv rehash - -WORKDIR /app ENTRYPOINT ["flower-server-app"] diff --git a/src/docker/superlink/Dockerfile b/src/docker/superlink/Dockerfile index acf06f66f2fb..31c0906dfd22 100644 --- a/src/docker/superlink/Dockerfile +++ b/src/docker/superlink/Dockerfile @@ -14,19 +14,7 @@ # ============================================================================== ARG BASE_REPOSITORY=flwr/base -ARG PYTHON_VERSION=3.11 -ARG UBUNTU_VERSION=ubuntu22.04 -FROM $BASE_REPOSITORY:py${PYTHON_VERSION}-${UBUNTU_VERSION} +ARG BASE_IMAGE +FROM $BASE_REPOSITORY:$BASE_IMAGE -ARG FLWR_PACKAGE=flwr -ARG FLWR_VERSION -RUN python -m pip install -U --no-cache-dir \ - ${FLWR_PACKAGE}==${FLWR_VERSION} && \ - # Without pyenv rehash the executable cannot be found. - # pyenv rehash is usually called via the shell by adding - # `pyenv init -` in the shell profile, but that doesn't work - # well in docker - pyenv rehash - -WORKDIR /app ENTRYPOINT ["flower-superlink"] diff --git a/src/docker/supernode/Dockerfile b/src/docker/supernode/Dockerfile index 8117dcc295df..8dce1c389a5b 100644 --- a/src/docker/supernode/Dockerfile +++ b/src/docker/supernode/Dockerfile @@ -14,15 +14,7 @@ # ============================================================================== ARG BASE_REPOSITORY=flwr/base -ARG PYTHON_VERSION=3.11 -ARG UBUNTU_VERSION=ubuntu22.04 -FROM $BASE_REPOSITORY:py${PYTHON_VERSION}-${UBUNTU_VERSION} +ARG BASE_IMAGE +FROM $BASE_REPOSITORY:$BASE_IMAGE -ARG FLWR_PACKAGE=flwr -ARG FLWR_VERSION -RUN python -m pip install -U --no-cache-dir \ - ${FLWR_PACKAGE}==${FLWR_VERSION} && \ - pyenv rehash - -WORKDIR /app ENTRYPOINT ["flower-client-app"] From 856409ea0f1d77db3fd4c7907aa4febb0c38d988 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 24 May 2024 12:43:27 +0100 Subject: [PATCH 013/124] fix(*:skip) Update `ray` and unpin `setuptools` (#3501) --------- Co-authored-by: Taner Topal --- pyproject.toml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index adacd5d2b4e1..2d8c24d8e80c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,9 +73,8 @@ iterators = "^0.0.2" typer = { version = "^0.9.0", extras=["all"] } tomli = "^2.0.1" pathspec = "^0.12.1" -setuptools = "!=70.0.0" # Optional dependencies (Simulation Engine) -ray = { version = "==2.6.3", optional = true, python = ">=3.8,<3.12" } +ray = { version = "==2.10.0", optional = true, python = ">=3.8,<3.12" } # Optional dependencies (REST transport layer) requests = { version = "^2.31.0", optional = true } starlette = { version = "^0.31.0", optional = true } From 0cd41cc4572076f0c698a79e471964bd36bc11b2 Mon Sep 17 00:00:00 2001 From: mohammadnaseri Date: Fri, 24 May 2024 15:28:03 +0100 Subject: [PATCH 014/124] docs(framework) Fix the number of examples in pytorch-flower doc (#3498) Co-authored-by: Taner Topal --- .../tutorial-series-get-started-with-flower-pytorch.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb b/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb index c9d38b417a92..d8e6e58fafab 100644 --- a/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb +++ b/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb @@ -160,7 +160,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "We now have a list of ten training sets and ten validation sets (`trainloaders` and `valloaders`) representing the data of ten different organizations. Each `trainloader`/`valloader` pair contains 4500 training examples and 500 validation examples. There's also a single `testloader` (we did not split the test set). Again, this is only necessary for building research or educational systems, actual federated learning systems have their data naturally distributed across multiple partitions.\n", + "We now have a list of ten training sets and ten validation sets (`trainloaders` and `valloaders`) representing the data of ten different organizations. Each `trainloader`/`valloader` pair contains 4000 training examples and 1000 validation examples. There's also a single `testloader` (we did not split the test set). Again, this is only necessary for building research or educational systems, actual federated learning systems have their data naturally distributed across multiple partitions.\n", "\n", "Let's take a look at the first batch of images and labels in the first training set (i.e., `trainloaders[0]`) before we move on:" ] From 05ad7df2a810a1bad90af98ccac460fb38cb8cc4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 24 May 2024 15:33:38 +0000 Subject: [PATCH 015/124] chore(deps): update torch requirement in /e2e/opacus (#3502) Updates the requirements on [torch](https://github.com/pytorch/pytorch) to permit the latest version. - [Release notes](https://github.com/pytorch/pytorch/releases) - [Changelog](https://github.com/pytorch/pytorch/blob/main/RELEASE.md) - [Commits](https://github.com/pytorch/pytorch/compare/v1.13.1...v2.3.0) --- updated-dependencies: - dependency-name: torch dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Taner Topal --- e2e/opacus/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/e2e/opacus/pyproject.toml b/e2e/opacus/pyproject.toml index 8fd1056f43a3..cee9fc1914cf 100644 --- a/e2e/opacus/pyproject.toml +++ b/e2e/opacus/pyproject.toml @@ -12,7 +12,7 @@ authors = [ dependencies = [ "flwr[simulation] @ {root:parent:parent:uri}", "opacus>=1.4.0,<2.0.0", - "torch>=1.13.1,<2.0.0", + "torch>=1.13.1,<3.0.0", "torchvision>=0.14.0,<2.0.0", ] From 83e9ba4c7722c9f882748aa8a83adde4d2f1285c Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Fri, 24 May 2024 18:55:04 +0200 Subject: [PATCH 016/124] refactor(framework) Update CLI auth flags (#3503) Co-authored-by: Daniel J. Beutel --- doc/source/how-to-authenticate-supernodes.rst | 17 +-- e2e/test_driver.sh | 7 +- .../README.md | 27 ++--- .../certificate.conf | 0 .../client.py | 0 .../generate.sh | 0 .../pyproject.toml | 0 .../server.py | 0 .../task.py | 0 src/py/flwr/client/supernode/app.py | 64 +++++++---- .../crypto/symmetric_encryption.py | 15 --- src/py/flwr/server/app.py | 100 ++++++++++++------ src/py/flwr/server/server_test.py | 8 +- 13 files changed, 138 insertions(+), 100 deletions(-) rename examples/{flower-client-authentication => flower-authentication}/README.md (73%) rename examples/{flower-client-authentication => flower-authentication}/certificate.conf (100%) rename examples/{flower-client-authentication => flower-authentication}/client.py (100%) rename examples/{flower-client-authentication => flower-authentication}/generate.sh (100%) rename examples/{flower-client-authentication => flower-authentication}/pyproject.toml (100%) rename examples/{flower-client-authentication => flower-authentication}/server.py (100%) rename examples/{flower-client-authentication => flower-authentication}/task.py (100%) diff --git a/doc/source/how-to-authenticate-supernodes.rst b/doc/source/how-to-authenticate-supernodes.rst index 472ba64a8310..e0834a1aff0a 100644 --- a/doc/source/how-to-authenticate-supernodes.rst +++ b/doc/source/how-to-authenticate-supernodes.rst @@ -9,7 +9,7 @@ Flower node authentication works similar to how GitHub SSH authentication works: * Shared secret is used to compute the HMAC value of the message sent from SuperNode to SuperLink as a token * SuperLink verifies the token -We recommend you to check out the complete `code example `_ demonstrating federated learning with Flower in an authenticated setting. +We recommend you to check out the complete `code example `_ demonstrating federated learning with Flower in an authenticated setting. .. note:: This guide covers a preview feature that might change in future versions of Flower. @@ -29,15 +29,17 @@ Use the following terminal command to start a Flower :code:`SuperNode` that has flower-superlink --certificates certificates/ca.crt certificates/server.pem certificates/server.key - --require-client-authentication ./keys/client_public_keys.csv ./keys/server_credentials ./keys/server_credentials.pub + --auth-list-public-keys keys/client_public_keys.csv + --auth-superlink-private-key keys/server_credentials + --auth-superlink-public-key keys/server_credentials.pub -Let's break down the :code:`--require-client-authentication` flag: +Let's break down the authentication flags: -1. The first argument is a path to a CSV file storing all known node public keys. You need to store all known node public keys that are allowed to participate in a federation in one CSV file (:code:`.csv`). +1. The first flag :code:`--auth-list-public-keys` expects a path to a CSV file storing all known node public keys. You need to store all known node public keys that are allowed to participate in a federation in one CSV file (:code:`.csv`). A valid CSV file storing known node public keys should list the keys in OpenSSH format, separated by commas and without any comments. For an example, refer to our code sample, which contains a CSV file with two known node public keys. -2. The second and third arguments are paths to the server's private and public keys. For development purposes, you can generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b 384`. +2. The second and third flags :code:`--auth-superlink-private-key` and :code:`--auth-superlink-public-key` expect paths to the server's private and public keys. For development purposes, you can generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b 384`. .. note:: In Flower 1.9, there is no support for dynamically removing, editing, or adding known node public keys to the SuperLink. @@ -56,9 +58,10 @@ Use the following terminal command to start an authenticated :code:`SuperNode`: flower-client-app client:app --root-certificates certificates/ca.crt --server 127.0.0.1:9092 - --authentication-keys ./keys/client_credentials ./keys/client_credentials.pub + --auth-supernode-private-key keys/client_credentials + --auth-supernode-public-key keys/client_credentials.pub -The :code:`--authentication-keys` flag expects two arguments: a path to the node's private key file and a path to the node's public key file. For development purposes, you can generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b 384`. +The :code:`--auth-supernode-private-key` flag expects a path to the node's private key file and the :code:`--auth-supernode-public-key` flag expects a path to the node's public key file. For development purposes, you can generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b 384`. Security notice diff --git a/e2e/test_driver.sh b/e2e/test_driver.sh index 6d7f6ec864fd..7a312004990d 100755 --- a/e2e/test_driver.sh +++ b/e2e/test_driver.sh @@ -47,9 +47,9 @@ case "$2" in db_arg="--database :flwr-in-memory-state:" server_arg="--certificates certificates/ca.crt certificates/server.pem certificates/server.key" client_arg="--root-certificates certificates/ca.crt" - server_auth="--require-client-authentication keys/client_public_keys.csv keys/server_credentials keys/server_credentials.pub" - client_auth_1="--authentication-keys keys/client_credentials_1 keys/client_credentials_1.pub" - client_auth_2="--authentication-keys keys/client_credentials_2 keys/client_credentials_2.pub" + server_auth="--auth-list-public-keys keys/client_public_keys.csv --auth-superlink-private-key keys/server_credentials --auth-superlink-public-key keys/server_credentials.pub" + client_auth_1="--auth-supernode-private-key keys/client_credentials_1 --auth-supernode-public-key keys/client_credentials_1.pub" + client_auth_2="--auth-supernode-private-key keys/client_credentials_2 --auth-supernode-public-key keys/client_credentials_2.pub" ;; *) rest_arg="" @@ -84,4 +84,3 @@ if [[ "$res" = "0" ]]; then echo "Training worked correctly"; kill $cl1_pid; kill $cl2_pid; kill $sl_pid; else echo "Training had an issue" && exit 1; fi - diff --git a/examples/flower-client-authentication/README.md b/examples/flower-authentication/README.md similarity index 73% rename from examples/flower-client-authentication/README.md rename to examples/flower-authentication/README.md index 7c724fc26f64..e2403be7608d 100644 --- a/examples/flower-client-authentication/README.md +++ b/examples/flower-authentication/README.md @@ -1,19 +1,19 @@ -# Flower Client Authentication with PyTorch 🧪 +# Flower Authentication with PyTorch 🧪 > 🧪 = This example covers experimental features that might change in future versions of Flower > Please consult the regular PyTorch code examples ([quickstart](https://github.com/adap/flower/tree/main/examples/quickstart-pytorch), [advanced](https://github.com/adap/flower/tree/main/examples/advanced-pytorch)) to learn how to use Flower with PyTorch. -The following steps describe how to start a long-running Flower server (SuperLink) and a long-running Flower client (SuperNode) with client authentication enabled. +The following steps describe how to start a long-running Flower server (SuperLink) and a long-running Flower client (SuperNode) with authentication enabled. ## Project Setup Start by cloning the example project. We prepared a single-line command that you can copy into your shell which will checkout the example for you: ```shell -git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/examples/flower-client-authentication . && rm -rf _tmp && cd flower-client-authentication +git clone --depth=1 https://github.com/adap/flower.git _tmp && mv _tmp/examples/flower-authentication . && rm -rf _tmp && cd flower-authentication ``` -This will create a new directory called `flower-client-authentication` with the following project structure: +This will create a new directory called `flower-authentication` with the following project structure: ```bash $ tree . @@ -62,26 +62,28 @@ The script also generates a CSV file that includes each of the generated (client ## Start the long-running Flower server (SuperLink) -To start a long-running Flower server and enable client authentication is very easy; all you need to do is type -`--require-client-authentication` followed by the path to the known `client_public_keys.csv`, server's private key -`server_credentials`, and server's public key `server_credentials.pub`. Notice that you can only enable client -authentication with a secure TLS connection. +To start a long-running Flower server (SuperLink) and enable authentication is very easy; all you need to do is type +`--auth-list-public-keys` containing file path to the known `client_public_keys.csv`, `--auth-superlink-private-key` +containing file path to the SuperLink's private key `server_credentials`, and `--auth-superlink-public-key` containing file path to the SuperLink's public key `server_credentials.pub`. Notice that you can only enable authentication with a secure TLS connection. ```bash flower-superlink \ --certificates certificates/ca.crt certificates/server.pem certificates/server.key \ - --require-client-authentication keys/client_public_keys.csv keys/server_credentials keys/server_credentials.pub + --auth-list-public-keys keys/client_public_keys.csv \ + --auth-superlink-private-key keys/server_credentials \ + --auth-superlink-public-key keys/server_credentials.pub ``` ## Start the long-running Flower client (SuperNode) -In a new terminal window, start the first long-running Flower client: +In a new terminal window, start the first long-running Flower client (SuperNode): ```bash flower-client-app client:app \ --root-certificates certificates/ca.crt \ --server 127.0.0.1:9092 \ - --authentication-keys keys/client_credentials_1 keys/client_credentials_1.pub + --auth-supernode-private-key keys/client_credentials_1 \ + --auth-supernode-public-key keys/client_credentials_1.pub ``` In yet another new terminal window, start the second long-running Flower client: @@ -90,7 +92,8 @@ In yet another new terminal window, start the second long-running Flower client: flower-client-app client:app \ --root-certificates certificates/ca.crt \ --server 127.0.0.1:9092 \ - --authentication-keys keys/client_credentials_2 keys/client_credentials_2.pub + --auth-supernode-private-key keys/client_credentials_2 \ + --auth-supernode-public-key keys/client_credentials_2.pub ``` If you generated more than 2 client credentials, you can add more clients by opening new terminal windows and running the command diff --git a/examples/flower-client-authentication/certificate.conf b/examples/flower-authentication/certificate.conf similarity index 100% rename from examples/flower-client-authentication/certificate.conf rename to examples/flower-authentication/certificate.conf diff --git a/examples/flower-client-authentication/client.py b/examples/flower-authentication/client.py similarity index 100% rename from examples/flower-client-authentication/client.py rename to examples/flower-authentication/client.py diff --git a/examples/flower-client-authentication/generate.sh b/examples/flower-authentication/generate.sh similarity index 100% rename from examples/flower-client-authentication/generate.sh rename to examples/flower-authentication/generate.sh diff --git a/examples/flower-client-authentication/pyproject.toml b/examples/flower-authentication/pyproject.toml similarity index 100% rename from examples/flower-client-authentication/pyproject.toml rename to examples/flower-authentication/pyproject.toml diff --git a/examples/flower-client-authentication/server.py b/examples/flower-authentication/server.py similarity index 100% rename from examples/flower-client-authentication/server.py rename to examples/flower-authentication/server.py diff --git a/examples/flower-client-authentication/task.py b/examples/flower-authentication/task.py similarity index 100% rename from examples/flower-client-authentication/task.py rename to examples/flower-authentication/task.py diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index e46ed43cc676..ac58e9aa4a81 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -20,6 +20,7 @@ from pathlib import Path from typing import Callable, Optional, Tuple +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import ( load_ssh_private_key, @@ -31,9 +32,6 @@ from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log from flwr.common.object_ref import load_app, validate -from flwr.common.secure_aggregation.crypto.symmetric_encryption import ( - ssh_types_to_elliptic_curve, -) from ..app import _start_client_internal @@ -242,40 +240,60 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None: " Default: current working directory.", ) parser.add_argument( - "--authentication-keys", - nargs=2, - metavar=("CLIENT_PRIVATE_KEY", "CLIENT_PUBLIC_KEY"), + "--auth-supernode-private-key", + type=str, + help="The SuperNode's private key (as a path str) to enable authentication.", + ) + parser.add_argument( + "--auth-supernode-public-key", type=str, - help="Provide two file paths: (1) the client's private " - "key file, and (2) the client's public key file.", + help="The SuperNode's public key (as a path str) to enable authentication.", ) def _try_setup_client_authentication( args: argparse.Namespace, ) -> Optional[Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]]: - if not args.authentication_keys: + if not args.auth_supernode_private_key and not args.auth_supernode_public_key: return None - ssh_private_key = load_ssh_private_key( - Path(args.authentication_keys[0]).read_bytes(), - None, - ) - ssh_public_key = load_ssh_public_key(Path(args.authentication_keys[1]).read_bytes()) + if not args.auth_supernode_private_key or not args.auth_supernode_public_key: + sys.exit( + "Authentication requires file paths to both " + "'--auth-supernode-private-key' and '--auth-supernode-public-key'" + "to be provided (providing only one of them is not sufficient)." + ) + + try: + ssh_private_key = load_ssh_private_key( + Path(args.auth_supernode_private_key).read_bytes(), + None, + ) + if not isinstance(ssh_private_key, ec.EllipticCurvePrivateKey): + raise ValueError() + except (ValueError, UnsupportedAlgorithm): + sys.exit( + "Error: Unable to parse the private key file in " + "'--auth-supernode-private-key'. Authentication requires elliptic " + "curve private and public key pair. Please ensure that the file " + "path points to a valid private key file and try again." + ) try: - client_private_key, client_public_key = ssh_types_to_elliptic_curve( - ssh_private_key, ssh_public_key + ssh_public_key = load_ssh_public_key( + Path(args.auth_supernode_public_key).read_bytes() ) - except TypeError: + if not isinstance(ssh_public_key, ec.EllipticCurvePublicKey): + raise ValueError() + except (ValueError, UnsupportedAlgorithm): sys.exit( - "The file paths provided could not be read as a private and public " - "key pair. Client authentication requires an elliptic curve public and " - "private key pair. Please provide the file paths containing elliptic " - "curve private and public keys to '--authentication-keys'." + "Error: Unable to parse the public key file in " + "'--auth-supernode-public-key'. Authentication requires elliptic " + "curve private and public key pair. Please ensure that the file " + "path points to a valid public key file and try again." ) return ( - client_private_key, - client_public_key, + ssh_private_key, + ssh_public_key, ) diff --git a/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py b/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py index 9856b8b706f9..1d004a398ea8 100644 --- a/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +++ b/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py @@ -117,18 +117,3 @@ def verify_hmac(key: bytes, message: bytes, hmac_value: bytes) -> bool: return True except InvalidSignature: return False - - -def ssh_types_to_elliptic_curve( - private_key: serialization.SSHPrivateKeyTypes, - public_key: serialization.SSHPublicKeyTypes, -) -> Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]: - """Cast SSH key types to elliptic curve.""" - if isinstance(private_key, ec.EllipticCurvePrivateKey) and isinstance( - public_key, ec.EllipticCurvePublicKey - ): - return (private_key, public_key) - - raise TypeError( - "The provided key is not an EllipticCurvePrivateKey or EllipticCurvePublicKey" - ) diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 30e73fccb7df..84a075a3e6df 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -26,6 +26,7 @@ from typing import List, Optional, Sequence, Set, Tuple import grpc +from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import ( load_ssh_private_key, @@ -45,7 +46,6 @@ from flwr.common.secure_aggregation.crypto.symmetric_encryption import ( private_key_to_bytes, public_key_to_bytes, - ssh_types_to_elliptic_curve, ) from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611 add_FleetServicer_to_server, @@ -435,44 +435,69 @@ def _try_setup_client_authentication( args: argparse.Namespace, certificates: Optional[Tuple[bytes, bytes, bytes]], ) -> Optional[Tuple[Set[bytes], ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey]]: - if not args.require_client_authentication: + if ( + not args.auth_list_public_keys + and not args.auth_superlink_private_key + and not args.auth_superlink_public_key + ): return None + if ( + not args.auth_list_public_keys + or not args.auth_superlink_private_key + or not args.auth_superlink_public_key + ): + sys.exit( + "Authentication requires providing file paths for " + "'--auth-list-public-keys', '--auth-superlink-private-key' and " + "'--auth-superlink-public-key'. Provide all three to enable authentication." + ) + if certificates is None: sys.exit( - "Client authentication only works over secure connections. " - "Please provide certificate paths using '--certificates' when " - "enabling '--require-client-authentication'." + "Authentication requires secure connections. " + "Please provide certificate paths using '--certificates' and " + "try again." ) - client_keys_file_path = Path(args.require_client_authentication[0]) + client_keys_file_path = Path(args.auth_list_public_keys) if not client_keys_file_path.exists(): sys.exit( - "The provided path to the client public keys CSV file does not exist: " + "The provided path to the known public keys CSV file does not exist: " f"{client_keys_file_path}. " - "Please provide the CSV file path containing known client public keys " - "to '--require-client-authentication'." + "Please provide the CSV file path containing known public keys " + "to '--auth-list-public-keys'." ) client_public_keys: Set[bytes] = set() - ssh_private_key = load_ssh_private_key( - Path(args.require_client_authentication[1]).read_bytes(), - None, - ) - ssh_public_key = load_ssh_public_key( - Path(args.require_client_authentication[2]).read_bytes() - ) try: - server_private_key, server_public_key = ssh_types_to_elliptic_curve( - ssh_private_key, ssh_public_key + ssh_private_key = load_ssh_private_key( + Path(args.auth_superlink_private_key).read_bytes(), + None, ) - except TypeError: + if not isinstance(ssh_private_key, ec.EllipticCurvePrivateKey): + raise ValueError() + except (ValueError, UnsupportedAlgorithm): sys.exit( - "The file paths provided could not be read as a private and public " - "key pair. Client authentication requires an elliptic curve public and " - "private key pair. Please provide the file paths containing elliptic " - "curve private and public keys to '--require-client-authentication'." + "Error: Unable to parse the private key file in " + "'--auth-superlink-private-key'. Authentication requires elliptic " + "curve private and public key pair. Please ensure that the file " + "path points to a valid private key file and try again." + ) + + try: + ssh_public_key = load_ssh_public_key( + Path(args.auth_superlink_public_key).read_bytes() + ) + if not isinstance(ssh_public_key, ec.EllipticCurvePublicKey): + raise ValueError() + except (ValueError, UnsupportedAlgorithm): + sys.exit( + "Error: Unable to parse the public key file in " + "'--auth-superlink-public-key'. Authentication requires elliptic " + "curve private and public key pair. Please ensure that the file " + "path points to a valid public key file and try again." ) with open(client_keys_file_path, newline="", encoding="utf-8") as csvfile: @@ -484,14 +509,14 @@ def _try_setup_client_authentication( client_public_keys.add(public_key_to_bytes(public_key)) else: sys.exit( - "Error: Unable to parse the public keys in the .csv " - "file. Please ensure that the .csv file contains valid " - "SSH public keys and try again." + "Error: Unable to parse the public keys in the CSV " + "file. Please ensure that the CSV file path points to a valid " + "known SSH public keys files and try again." ) return ( client_public_keys, - server_private_key, - server_public_key, + ssh_private_key, + ssh_public_key, ) @@ -714,13 +739,20 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None: default=DATABASE, ) parser.add_argument( - "--require-client-authentication", - nargs=3, - metavar=("CLIENT_KEYS", "SERVER_PRIVATE_KEY", "SERVER_PUBLIC_KEY"), + "--auth-list-public-keys", + type=str, + help="A CSV file (as a path str) containing a list of known public " + "keys to enable authentication.", + ) + parser.add_argument( + "--auth-superlink-private-key", + type=str, + help="The SuperLink's private key (as a path str) to enable authentication.", + ) + parser.add_argument( + "--auth-superlink-public-key", type=str, - help="Provide three file paths: (1) a .csv file containing a list of " - "known client public keys for authentication, (2) the server's private " - "key file, and (3) the server's public key file.", + help="The SuperLink's public key (as a path str) to enable authentication.", ) diff --git a/src/py/flwr/server/server_test.py b/src/py/flwr/server/server_test.py index 51071c13f895..f47b5c3d8469 100644 --- a/src/py/flwr/server/server_test.py +++ b/src/py/flwr/server/server_test.py @@ -242,11 +242,9 @@ def test_setup_client_auth() -> None: # pylint: disable=R0914 # Mock argparse with `require-client-authentication`` flag mock_args = argparse.Namespace( - require_client_authentication=[ - str(client_keys_file_path), - str(server_private_key_path), - str(server_public_key_path), - ] + auth_list_public_keys=str(client_keys_file_path), + auth_superlink_private_key=str(server_private_key_path), + auth_superlink_public_key=str(server_public_key_path), ) # Run _try_setup_client_authentication From 63e1b1fa395bf89fd51ed475c7a987e22fdc94ef Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 24 May 2024 18:35:59 +0100 Subject: [PATCH 017/124] fix(framework) Support empty `Parameters` conversion to/from `RecordSet` (#3344) --- src/py/flwr/common/recordset_compat.py | 9 +++++++- src/py/flwr/common/recordset_compat_test.py | 23 +++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/py/flwr/common/recordset_compat.py b/src/py/flwr/common/recordset_compat.py index 394ea1353bab..1b0bf52d8277 100644 --- a/src/py/flwr/common/recordset_compat.py +++ b/src/py/flwr/common/recordset_compat.py @@ -35,6 +35,8 @@ Status, ) +EMPTY_TENSOR_KEY = "_empty" + def parametersrecord_to_parameters( record: ParametersRecord, keep_input: bool @@ -59,7 +61,8 @@ def parametersrecord_to_parameters( parameters = Parameters(tensors=[], tensor_type="") for key in list(record.keys()): - parameters.tensors.append(record[key].data) + if key != EMPTY_TENSOR_KEY: + parameters.tensors.append(record[key].data) if not parameters.tensor_type: # Setting from first array in record. Recall the warning in the docstrings @@ -103,6 +106,10 @@ def parameters_to_parametersrecord( data=tensor, dtype="", stype=tensor_type, shape=[] ) + if num_arrays == 0: + ordered_dict[EMPTY_TENSOR_KEY] = Array( + data=b"", dtype="", stype=tensor_type, shape=[] + ) return ParametersRecord(ordered_dict, keep_input=keep_input) diff --git a/src/py/flwr/common/recordset_compat_test.py b/src/py/flwr/common/recordset_compat_test.py index 288326dc9e83..e0ac7f216af9 100644 --- a/src/py/flwr/common/recordset_compat_test.py +++ b/src/py/flwr/common/recordset_compat_test.py @@ -74,6 +74,11 @@ def _get_valid_fitins() -> FitIns: return FitIns(parameters=ndarrays_to_parameters(arrays), config={"a": 1.0, "b": 0}) +def _get_valid_fitins_with_empty_ndarrays() -> FitIns: + pp = ndarrays_to_parameters([]) + return FitIns(parameters=pp, config={"a": 1.0, "b": 0}) + + def _get_valid_fitres() -> FitRes: """Returnn Valid parameters but potentially invalid config.""" arrays = get_ndarrays() @@ -138,23 +143,29 @@ def _get_valid_getpropertiesres() -> GetPropertiesRes: @pytest.mark.parametrize( - "keep_input, validate_freed_fn", + "keep_input, validate_freed_fn, fn", [ ( False, lambda x, x_copy, y: len(x.parameters.tensors) == 0 and x_copy == y, + _get_valid_fitins, ), # check tensors were freed + (True, lambda x, x_copy, y: x == y, _get_valid_fitins), ( - True, - lambda x, x_copy, y: x == y, - ), + False, + lambda x, x_copy, y: len(x.parameters.tensors) == 0 and x_copy == y, + _get_valid_fitins_with_empty_ndarrays, + ), # check tensors were freed + (True, lambda x, x_copy, y: x == y, _get_valid_fitins_with_empty_ndarrays), ], ) def test_fitins_to_recordset_and_back( - keep_input: bool, validate_freed_fn: Callable[[FitIns, FitIns, FitIns], bool] + keep_input: bool, + validate_freed_fn: Callable[[FitIns, FitIns, FitIns], bool], + fn: Callable[[], FitIns], ) -> None: """Test conversion FitIns --> RecordSet --> FitIns.""" - fitins = _get_valid_fitins() + fitins = fn() fitins_copy = deepcopy(fitins) From 2d1c3a6e827f4b63bc27c6ea93327e254e2d7584 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Mon, 27 May 2024 10:33:12 +0200 Subject: [PATCH 018/124] ci(*:skip) Update code owners for translations (#3515) --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0f95b023ecaa..0b8702a8360c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -18,6 +18,9 @@ README.md @jafermarq @tanertopal @danieljanes # Changelog /doc/source/ref-changelog.md @jafermarq @tanertopal @danieljanes +# Translations +/doc/locales @charlesbvll @tanertopal @danieljanes + # GitHub Actions and Workflows /.github/workflows @Robert-Steiner @tanertopal @danieljanes /.github/actions @Robert-Steiner @tanertopal @danieljanes From 77bf92ab5f8e3c39a6a747f99d9c623ab6f3b6ed Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 27 May 2024 10:48:27 +0200 Subject: [PATCH 019/124] docs(framework) Add latest Weblate translation updates (#3286) Co-authored-by: Yan Gao Co-authored-by: Young D. Kwon Co-authored-by: Gustavo Bertoli Co-authored-by: Charles Beauville --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 31 +- .../pt_BR/LC_MESSAGES/framework-docs.po | 193 +- .../zh_Hans/LC_MESSAGES/framework-docs.po | 2556 ++++++++++++++--- 3 files changed, 2286 insertions(+), 494 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 8ef7cf887247..63a160232909 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -3,59 +3,63 @@ # This file is distributed under the same license as the Flower package. # FIRST AUTHOR , 2024. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-13 09:48+0200\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2024-05-14 21:01+0000\n" +"Last-Translator: \"Young D. Kwon\" \n" +"Language-Team: Korean \n" "Language: ko\n" -"Language-Team: ko \n" -"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.14.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" -msgstr "" +msgstr "Flower 아키텍처" #: ../../source/contributor-explanation-architecture.rst:5 msgid "Edge Client Engine" -msgstr "" +msgstr "엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" "`Flower `_ core framework architecture with Edge " "Client Engine" -msgstr "" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 " +"엔진" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" -msgstr "" +msgstr "가상 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:15 msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" -msgstr "" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 " +"엔진" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" -msgstr "" +msgstr "동일 작업에서 가상 클라이언트 엔진과 엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:23 msgid "" "`Flower `_ core framework architecture with both " "Virtual Client Engine and Edge Client Engine" -msgstr "" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 " +"클라이언트 엔진" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" -msgstr "" +msgstr "Docker Flower 이미지를 Locally 구축하는 방법" #: ../../source/contributor-how-to-build-docker-images.rst:4 msgid "" @@ -20705,4 +20709,3 @@ msgid "" "pytorch.html>`__ shows how to build a simple federated learning system " "with PyTorch and Flower." msgstr "" - diff --git a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po index 4e117619f9b5..75a49d95d404 100644 --- a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po +++ b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po @@ -3,59 +3,68 @@ # This file is distributed under the same license as the Flower package. # FIRST AUTHOR , 2023. # -#, fuzzy msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-15 14:23+0000\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME \n" +"PO-Revision-Date: 2024-05-25 11:09+0000\n" +"Last-Translator: Gustavo Bertoli \n" +"Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" -"Language-Team: pt_BR \n" -"Plural-Forms: nplurals=2; plural=(n > 1);\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.14.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" -msgstr "" +msgstr "Arquitetura do Flower" #: ../../source/contributor-explanation-architecture.rst:5 msgid "Edge Client Engine" -msgstr "" +msgstr "Engine do Edge Client" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" "`Flower `_ core framework architecture with Edge " "Client Engine" msgstr "" +"`Flower `_ arquitetura principal do framework com Engine " +"do Edge Client" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" -msgstr "" +msgstr "Engine do Virtual Client" #: ../../source/contributor-explanation-architecture.rst:15 msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" msgstr "" +"`Flower `_ arquitetura principal do framework com Engine " +"do Virtual Client" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" msgstr "" +"Engine do Virtual Client e do Edge Client no mesma carga de trabalho " +"(workload)" #: ../../source/contributor-explanation-architecture.rst:23 msgid "" "`Flower `_ core framework architecture with both " "Virtual Client Engine and Edge Client Engine" msgstr "" +"`Flower `_ arquitetura principal do framework com ambas " +"engines do Virtual Client e do Edge Client" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" -msgstr "" +msgstr "Como construir imagens Docker do Flower localmente" #: ../../source/contributor-how-to-build-docker-images.rst:4 msgid "" @@ -66,26 +75,36 @@ msgid "" "if that is what you need. In this guide, we will explain what images " "exist and how to build them locally." msgstr "" +"Flower disponibiliza imagens docker em `Docker Hub `_ que incluem todas as dependências necesárias para " +"executar o servidor. Você pode também compilar suas próprias imagens docker " +"customizadas do zero com uma versão diferente do Python ou do Ubuntu se isso " +"for o que você precisa. Neste guia, explicaremos quais imagens existem e " +"como compilar localmente." #: ../../source/contributor-how-to-build-docker-images.rst:9 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." msgstr "" +"Antes de começarmos, precisamos encontrar alguns pré-requisitos em nosso " +"ambiente de desenvolvimento local." #: ../../source/contributor-how-to-build-docker-images.rst:11 msgid "Clone the flower repository." -msgstr "" +msgstr "Clone o repositório do flower." #: ../../source/contributor-how-to-build-docker-images.rst:17 msgid "Verify the Docker daemon is running." -msgstr "" +msgstr "Verifique que o serviço Docker está rodando." #: ../../source/contributor-how-to-build-docker-images.rst:19 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" +"Por favor, siga a primeira seção em :doc:`Execute o Flower usando Docker " +"` que cobre este passo em mais detalhes." #: ../../source/contributor-how-to-build-docker-images.rst:23 msgid "" @@ -96,6 +115,12 @@ msgid "" "server image is based on the base image, but it additionally installs the" " Flower server using ``pip``." msgstr "" +"Atualmente, Flower fornece duas imagens, uma imagem base e uma imagem de " +"servidor. Também haverá uma imagem de cliente em breve. A imagem base, como " +"o nome sugere, contém dependências básicas que tanto o servidor quanto o " +"cliente precisam. Isso inclui dependências do sistema, Python e ferramentas " +"Python. A imagem do servidor é baseada na imagem base, mas também instala o " +"servidor Flower usando ``pip```." #: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" @@ -103,6 +128,9 @@ msgid "" "respective Dockerfiles. You can find them in the subdirectories of " "``src/docker``." msgstr "" +"As instruções de compilação que montam as imagens estão localizadas nos " +"respectivos Dockerfiles. Você pode encontrá-los nos subdiretórios ``src/" +"docker```." #: ../../source/contributor-how-to-build-docker-images.rst:31 msgid "" @@ -114,91 +142,101 @@ msgid "" "available build arguments for each image are listed in one of the tables " "below." msgstr "" +"Ambas, imagens base e do servidor são configuradas através dos argumentos de " +"compilação. Através dos argumentos de compilação, podemos tornar nossa " +"compilação mais flexível. Por exemplo, na imagem base, podemos especificar a " +"versão do Python para instalar usando o argumento de compilação " +"`PYTHON_VERSION`. Alguns dos argumentos de compilação têm valores padrão, " +"outros devem ser especificados ao compilar a imagem. Todos os argumentos de " +"compilação disponíveis para cada imagem estão listados em uma das tabelas " +"abaixo." #: ../../source/contributor-how-to-build-docker-images.rst:38 msgid "Building the base image" -msgstr "" +msgstr "Construindo a imagem base" #: ../../source/contributor-how-to-build-docker-images.rst:44 #: ../../source/contributor-how-to-build-docker-images.rst:86 msgid "Build argument" -msgstr "" +msgstr "Argumento de compilação" #: ../../source/contributor-how-to-build-docker-images.rst:45 #: ../../source/contributor-how-to-build-docker-images.rst:87 msgid "Description" -msgstr "" +msgstr "Descrição" #: ../../source/contributor-how-to-build-docker-images.rst:46 #: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "Required" -msgstr "" +msgstr "Necessário" #: ../../source/contributor-how-to-build-docker-images.rst:47 #: ../../source/contributor-how-to-build-docker-images.rst:89 msgid "Example" -msgstr "" +msgstr "Exemplo" #: ../../source/contributor-how-to-build-docker-images.rst:48 msgid "``PYTHON_VERSION``" -msgstr "" +msgstr "``PYTHON_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:49 msgid "Version of ``python`` to be installed." -msgstr "" +msgstr "Versão do ``python`` a ser instalada." #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 #: ../../source/contributor-how-to-build-docker-images.rst:58 #: ../../source/contributor-how-to-build-docker-images.rst:100 msgid "Yes" -msgstr "" +msgstr "Sim" #: ../../source/contributor-how-to-build-docker-images.rst:51 msgid "``3.11``" -msgstr "" +msgstr "``3.11``" #: ../../source/contributor-how-to-build-docker-images.rst:52 msgid "``PIP_VERSION``" -msgstr "" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:53 msgid "Version of ``pip`` to be installed." -msgstr "" +msgstr "Versão do ``pip`` a ser instalada." #: ../../source/contributor-how-to-build-docker-images.rst:55 msgid "``23.0.1``" -msgstr "" +msgstr "``23.0.1``" #: ../../source/contributor-how-to-build-docker-images.rst:56 msgid "``SETUPTOOLS_VERSION``" -msgstr "" +msgstr "``SETUPTOOLS_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:57 msgid "Version of ``setuptools`` to be installed." -msgstr "" +msgstr "Versão do ``setuptools`` a ser instalada." #: ../../source/contributor-how-to-build-docker-images.rst:59 msgid "``69.0.2``" -msgstr "" +msgstr "``69.0.2``" #: ../../source/contributor-how-to-build-docker-images.rst:60 msgid "``UBUNTU_VERSION``" -msgstr "" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:61 msgid "Version of the official Ubuntu Docker image." -msgstr "" +msgstr "Versão da imagem Docker oficial do Ubuntu." #: ../../source/contributor-how-to-build-docker-images.rst:62 msgid "Defaults to ``22.04``." -msgstr "" +msgstr "Como padrão ``22.04``." #: ../../source/contributor-how-to-build-docker-images.rst:65 msgid "" "The following example creates a base image with Python 3.11.0, pip 23.0.1" " and setuptools 69.0.2:" msgstr "" +"O exemplo seguinte cria uma imagem base com Python 3.11.0, pip 23.0.1 e " +"setuptools 69.0.2:" #: ../../source/contributor-how-to-build-docker-images.rst:76 msgid "" @@ -206,52 +244,58 @@ msgid "" "the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." msgstr "" +"O nome da imagem é ``flwr_base`` com a tag ``0.1.0``. Lembre-se que os " +"argumentos de construção assim como o nome e a tag podem ser adaptados de " +"acordo com suas necessidades. Estes valores servem apenas como exemplo." #: ../../source/contributor-how-to-build-docker-images.rst:80 msgid "Building the server image" -msgstr "" +msgstr "Construindo a imagem do servidor" #: ../../source/contributor-how-to-build-docker-images.rst:90 msgid "``BASE_REPOSITORY``" -msgstr "" +msgstr "``BASE_REPOSITORY``" #: ../../source/contributor-how-to-build-docker-images.rst:91 msgid "The repository name of the base image." -msgstr "" +msgstr "O nome do repositório da imagem base." #: ../../source/contributor-how-to-build-docker-images.rst:92 msgid "Defaults to ``flwr/server``." -msgstr "" +msgstr "Pré-definido para ``flwr/server``." #: ../../source/contributor-how-to-build-docker-images.rst:94 msgid "``BASE_IMAGE_TAG``" -msgstr "" +msgstr "``BASE_IMAGE_TAG``" #: ../../source/contributor-how-to-build-docker-images.rst:95 +#, fuzzy msgid "The image tag of the base image." -msgstr "" +msgstr "A tag da imagem da imagem base." #: ../../source/contributor-how-to-build-docker-images.rst:96 msgid "Defaults to ``py3.11-ubuntu22.04``." -msgstr "" +msgstr "Pré-definido para ``py3.11-ubuntu22.04``." #: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "``FLWR_VERSION``" -msgstr "" +msgstr "``FLWR_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:99 msgid "Version of Flower to be installed." -msgstr "" +msgstr "Versão do Flower a ser instalada." #: ../../source/contributor-how-to-build-docker-images.rst:101 msgid "``1.7.0``" -msgstr "" +msgstr "``1.7.0``" #: ../../source/contributor-how-to-build-docker-images.rst:103 msgid "" "The following example creates a server image with the official Flower " "base image py3.11-ubuntu22.04 and Flower 1.7.0:" msgstr "" +"O exemplo a seguir cria uma imagem de servidor com a imagem base oficial do " +"Flower py3.11-ubuntu22.04 e Flower 1.7.0:" #: ../../source/contributor-how-to-build-docker-images.rst:114 msgid "" @@ -259,6 +303,9 @@ msgid "" " the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." msgstr "" +"O nome da imagem é ``flwr_server`` e a tag ``0.1.0``. Lembre-se que os " +"argumentos de compilação, bem como o nome e a tag podem ser adaptados às " +"suas necessidades. Esses valores servem apenas como exemplos." #: ../../source/contributor-how-to-build-docker-images.rst:117 msgid "" @@ -268,14 +315,19 @@ msgid "" " match the name of your image and the value of ``BASE_IMAGE_TAG`` must " "match the tag of your image." msgstr "" +"Se você quiser usar sua própria imagem base ao invés da imagem oficial base " +"do Flower, tudo que você precisa fazer é definir os argumentos " +"``BASE_REPOSITORY`` e ``BASE_IMAGE_TAG`` como parte do comando de " +"compilação. O valor de ``BASE_REPOSITORY`` deve corresponder ao nome da sua " +"imagem e o valor de ``BASE_IMAGE_TAG`` deve corresponder à tag da sua imagem." #: ../../source/contributor-how-to-build-docker-images.rst:131 msgid "After creating the image, we can test whether the image is working:" -msgstr "" +msgstr "Depois de criar a imagem, podemos testar se a imagem está funcionando:" #: ../../source/contributor-how-to-contribute-translations.rst:2 msgid "Contribute translations" -msgstr "" +msgstr "Contribua com traduções" #: ../../source/contributor-how-to-contribute-translations.rst:4 msgid "" @@ -288,17 +340,30 @@ msgid "" "also be a great opportunity for those wanting to become open source " "contributors with little prerequisites." msgstr "" +"Desde o `Flower 1.5 `_ nós introduzimos traduções para nossas páginas de " +"documentação, mas, como você pode ter notado, as traduções são muitas vezes " +"imperfeitas. Se você fala línguas diferentes do inglês, você pode ser capaz " +"de nos ajudar neste esforço para tornar o aprendizado federado acessível a " +"tantas pessoas quanto possível, contribuindo para essas traduções! Isso " +"também pode ser uma grande oportunidade para aqueles que querem se tornar " +"contribuintes de código aberto com poucos pré-requisitos." #: ../../source/contributor-how-to-contribute-translations.rst:13 +#, fuzzy msgid "" "Our translation project is publicly available over on `Weblate " "`_, this " "where most of the work will happen." msgstr "" +"Nosso projeto de tradução está disponível publicamente em `Weblate " +"`_, onde a " +"maioria do trabalho acontecerá." #: ../../source/contributor-how-to-contribute-translations.rst:18 +#, fuzzy msgid "Contribute to existing languages" -msgstr "" +msgstr "Contribuir para as línguas existentes" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" @@ -308,6 +373,10 @@ msgid "" " profile settings can be found `here " "`_." msgstr "" +"A primeira coisa que você precisa fazer para contribuir é criar uma conta " +"Weblate gratuita nesta `página `_. Mais informações sobre as configurações de perfil podem ser encontradas " +"`aqui `_." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" @@ -316,12 +385,18 @@ msgid "" "docs/framework/>`_. Here, you should see the different existing languages" " that can be found on the website." msgstr "" +"Uma vez que você esteja conectado ao Weblate, você pode navegar até o " +"projeto `Flower Framework `_. Aqui, você deve ver os diferentes idiomas existentes que " +"podem ser encontrados no site." #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" "Once you have selected the language you want to contribute to, you should" " see a similar interface to this:" msgstr "" +"Uma vez que você tenha selecionado o idioma que deseja contribuir, você deve " +"ver uma interface semelhante a esta:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" @@ -330,10 +405,14 @@ msgid "" "will automatically bring you to the translation interface for " "untranslated strings." msgstr "" +"A opção mais direta aqui é clicar no botão ``Translate`` no canto superior " +"direito (na seção ``Translation status``). Isso te levará automaticamente " +"para a interface de tradução de strings ainda não traduzidas." #: ../../source/contributor-how-to-contribute-translations.rst:43 +#, fuzzy msgid "This is what the interface looks like:" -msgstr "" +msgstr "É assim que a interface se parece:" #: ../../source/contributor-how-to-contribute-translations.rst:47 msgid "" @@ -344,6 +423,13 @@ msgid "" "your translation to suggestions for other users to view), or ``Skip`` (to" " go to the next untranslated string without saving anything)." msgstr "" +"Você insire sua tradução na caixa de texto no topo e depois, uma vez que " +"você está satisfeito com ela, você pressiona ``Save and continue`` (para " +"salvar a tradução e ir para a próxima string não traduzida), ``Save and " +"stay`` (para salvar a tradução e ficar na mesma página), ``Suggest`` (para " +"adicionar sua tradução para sugestões para outros usuários verem), ou " +"``Skip`` (para ir para a próxima string não traduzida sem salvar nada na " +"atual)." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" @@ -353,6 +439,11 @@ msgid "" "translations in ``Other languages``, and the ``History`` of translations " "for this string." msgstr "" +"Para ajudar com as traduções, você pode ver na parte inferior o ``Nearby " +"strings`` (strings próximas), o ``Comments`` (comentários de outros " +"contribuidores), o ``Automatic suggestions`` (sugestões atuomáticas de " +"sistemas de tradução automática), as traduções em ``Other languages`` (" +"outras línguas), e o ``History`` (histórico) de traduções para esta string." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" @@ -360,6 +451,9 @@ msgid "" "click the link under ``Source string location`` in order to view the " "source of the doc file containing the string." msgstr "" +"À direita, sob a seção ``String information``, você também pode clicar no " +"link sob ``Source string location`` para visualizar a fonte do arquivo doc " +"que contém a string." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" @@ -367,10 +461,14 @@ msgid "" "this `in-depth guide " "`_." msgstr "" +"Para obter mais informações sobre como traduzir usando o Weblate, você pode " +"conferir este `guia detalhado `_." #: ../../source/contributor-how-to-contribute-translations.rst:67 +#, fuzzy msgid "Add new languages" -msgstr "" +msgstr "Adicionar novos idiomas" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" @@ -378,10 +476,14 @@ msgid "" "either on `Slack `_, or by opening an issue" " on our `GitHub repo `_." msgstr "" +"Se você quiser adicionar uma nova língua, primeiro você terá que entrar em " +"contato conosco, no `Slack `_, ou abrindo uma " +"issue no nosso `repositório GitHub `_." #: ../../source/contributor-how-to-create-new-messages.rst:2 +#, fuzzy msgid "Creating New Messages" -msgstr "" +msgstr "Criando novas mensagens" #: ../../source/contributor-how-to-create-new-messages.rst:4 msgid "" @@ -21349,4 +21451,3 @@ msgstr "" #~ msgid "|08cb60859b07461588fe44e55810b050|" #~ msgstr "" - diff --git a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po index 86d96e5e6865..4f4d9cfe5214 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po @@ -8,15 +8,16 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-03-15 14:23+0000\n" -"PO-Revision-Date: 2024-02-19 11:37+0000\n" +"PO-Revision-Date: 2024-05-10 06:59+0000\n" "Last-Translator: Yan Gao \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" -"Language-Team: Chinese (Simplified) \n" -"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.5.4-rc\n" "Generated-By: Babel 2.14.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -58,6 +59,7 @@ msgid "How to build Docker Flower images locally" msgstr "如何在本地搭建Docker Flower images" #: ../../source/contributor-how-to-build-docker-images.rst:4 +#, fuzzy msgid "" "Flower provides pre-made docker images on `Docker Hub " "`_ that include all necessary " @@ -66,12 +68,17 @@ msgid "" "if that is what you need. In this guide, we will explain what images " "exist and how to build them locally." msgstr "" +"Flower 在 `Docker Hub `_ " +"上提供了预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要," +"也可以使用不同版本的 Python 或 Ubuntu 从头开始构建自己的定制 docker " +"镜像。在本指南中,我们将介绍有哪些镜像,以及如何在本地构建它们。" #: ../../source/contributor-how-to-build-docker-images.rst:9 +#, fuzzy msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." -msgstr "" +msgstr "在开始之前,我们需要在本地开发环境中满足一些先决条件。" #: ../../source/contributor-how-to-build-docker-images.rst:11 #, fuzzy @@ -79,16 +86,21 @@ msgid "Clone the flower repository." msgstr "**叉花仓库**" #: ../../source/contributor-how-to-build-docker-images.rst:17 +#, fuzzy msgid "Verify the Docker daemon is running." -msgstr "" +msgstr "验证 Docker 守护进程是否正在运行。" #: ../../source/contributor-how-to-build-docker-images.rst:19 +#, fuzzy msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" +"请阅读 :doc:`Run Flower using Docker ` " +"的第一节,其中更详细地介绍了这一步骤。" #: ../../source/contributor-how-to-build-docker-images.rst:23 +#, fuzzy msgid "" "Currently, Flower provides two images, a base image and a server image. " "There will also be a client image soon. The base image, as the name " @@ -97,15 +109,22 @@ msgid "" "server image is based on the base image, but it additionally installs the" " Flower server using ``pip``." msgstr "" +"目前,Flower 提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜" +"像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依" +"赖项、Python 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` " +"额外安装 Flower 服务器。" #: ../../source/contributor-how-to-build-docker-images.rst:28 +#, fuzzy msgid "" "The build instructions that assemble the images are located in the " "respective Dockerfiles. You can find them in the subdirectories of " "``src/docker``." -msgstr "" +msgstr "组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` " +"的子目录中找到它们。" #: ../../source/contributor-how-to-build-docker-images.rst:31 +#, fuzzy msgid "" "Both, base and server image are configured via build arguments. Through " "build arguments, we can make our build more flexible. For example, in the" @@ -115,6 +134,10 @@ msgid "" "available build arguments for each image are listed in one of the tables " "below." msgstr "" +"基础镜像和服务器镜像都是通过构建参数配置的。通过联编参数,我们可以使联编更加" +"灵活。例如,在基础镜像中,我们可以使用 ``PYTHON_VERSION`` " +"联编参数指定要安装的 Python 版本。有些联编参数有默认值,有些则必须在联编映像" +"时指定。每个映像的所有可用联编参数都列在下表中。" #: ../../source/contributor-how-to-build-docker-images.rst:38 #, fuzzy @@ -151,8 +174,9 @@ msgid "``PYTHON_VERSION``" msgstr "Python 版本" #: ../../source/contributor-how-to-build-docker-images.rst:49 +#, fuzzy msgid "Version of ``python`` to be installed." -msgstr "" +msgstr "要安装的 ``python`` 版本。" #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 @@ -168,12 +192,14 @@ msgid "``3.11``" msgstr "``1.0.0rc1``" #: ../../source/contributor-how-to-build-docker-images.rst:52 +#, fuzzy msgid "``PIP_VERSION``" -msgstr "" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:53 +#, fuzzy msgid "Version of ``pip`` to be installed." -msgstr "" +msgstr "要安装的 ``pip` 版本。" #: ../../source/contributor-how-to-build-docker-images.rst:55 #, fuzzy @@ -181,12 +207,14 @@ msgid "``23.0.1``" msgstr "``1.0.0rc1``" #: ../../source/contributor-how-to-build-docker-images.rst:56 +#, fuzzy msgid "``SETUPTOOLS_VERSION``" -msgstr "" +msgstr "设置工具版本" #: ../../source/contributor-how-to-build-docker-images.rst:57 +#, fuzzy msgid "Version of ``setuptools`` to be installed." -msgstr "" +msgstr "要安装的 `setuptools`` 版本。" #: ../../source/contributor-how-to-build-docker-images.rst:59 #, fuzzy @@ -194,29 +222,36 @@ msgid "``69.0.2``" msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-build-docker-images.rst:60 +#, fuzzy msgid "``UBUNTU_VERSION``" -msgstr "" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:61 +#, fuzzy msgid "Version of the official Ubuntu Docker image." -msgstr "" +msgstr "官方 Ubuntu Docker 映像的版本。" #: ../../source/contributor-how-to-build-docker-images.rst:62 +#, fuzzy msgid "Defaults to ``22.04``." -msgstr "" +msgstr "默认为 ``22.04``。" #: ../../source/contributor-how-to-build-docker-images.rst:65 +#, fuzzy msgid "" "The following example creates a base image with Python 3.11.0, pip 23.0.1" " and setuptools 69.0.2:" -msgstr "" +msgstr "下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 " +"创建了基本映像:" #: ../../source/contributor-how-to-build-docker-images.rst:76 +#, fuzzy msgid "" "The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " "the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." -msgstr "" +msgstr "图像名称为 ``flwr_base``,标记为 ``0.1." +"0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" #: ../../source/contributor-how-to-build-docker-images.rst:80 #, fuzzy @@ -224,36 +259,44 @@ msgid "Building the server image" msgstr "启动服务器" #: ../../source/contributor-how-to-build-docker-images.rst:90 +#, fuzzy msgid "``BASE_REPOSITORY``" -msgstr "" +msgstr "基础存储库" #: ../../source/contributor-how-to-build-docker-images.rst:91 +#, fuzzy msgid "The repository name of the base image." -msgstr "" +msgstr "基础镜像的存储库名称。" #: ../../source/contributor-how-to-build-docker-images.rst:92 +#, fuzzy msgid "Defaults to ``flwr/server``." -msgstr "" +msgstr "默认为 ``flwr/server``。" #: ../../source/contributor-how-to-build-docker-images.rst:94 +#, fuzzy msgid "``BASE_IMAGE_TAG``" -msgstr "" +msgstr "基本图像标签" #: ../../source/contributor-how-to-build-docker-images.rst:95 +#, fuzzy msgid "The image tag of the base image." -msgstr "" +msgstr "基础图像的图像标记。" #: ../../source/contributor-how-to-build-docker-images.rst:96 +#, fuzzy msgid "Defaults to ``py3.11-ubuntu22.04``." -msgstr "" +msgstr "默认为 ``py3.11-ubuntu22.04``。" #: ../../source/contributor-how-to-build-docker-images.rst:98 +#, fuzzy msgid "``FLWR_VERSION``" -msgstr "" +msgstr "``FLWR_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:99 +#, fuzzy msgid "Version of Flower to be installed." -msgstr "" +msgstr "要安装的 Flower 版本。" #: ../../source/contributor-how-to-build-docker-images.rst:101 #, fuzzy @@ -261,19 +304,24 @@ msgid "``1.7.0``" msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-build-docker-images.rst:103 +#, fuzzy msgid "" "The following example creates a server image with the official Flower " "base image py3.11-ubuntu22.04 and Flower 1.7.0:" -msgstr "" +msgstr "下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 " +"创建了一个服务器镜像:" #: ../../source/contributor-how-to-build-docker-images.rst:114 +#, fuzzy msgid "" "The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that" " the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." -msgstr "" +msgstr "图像名称为 ``flwr_server``,标记为 ``0.1." +"0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" #: ../../source/contributor-how-to-build-docker-images.rst:117 +#, fuzzy msgid "" "If you want to use your own base image instead of the official Flower " "base image, all you need to do is set the ``BASE_REPOSITORY`` and " @@ -281,10 +329,14 @@ msgid "" " match the name of your image and the value of ``BASE_IMAGE_TAG`` must " "match the tag of your image." msgstr "" +"如果您想使用自己的基础图片而不是 Flower 官方的基础图片,只需设置 " +"``BASE_REPOSITORY`` 和 ``BASE_IMAGE_TAG`` 联编参数即可。`BASE_REPOSITORY``的" +"值必须与您的图像名称一致,`BASE_IMAGE_TAG``的值必须与您的图像标签一致。" #: ../../source/contributor-how-to-build-docker-images.rst:131 +#, fuzzy msgid "After creating the image, we can test whether the image is working:" -msgstr "" +msgstr "创建图像后,我们可以测试图像是否正常工作:" #: ../../source/contributor-how-to-contribute-translations.rst:2 msgid "Contribute translations" @@ -859,13 +911,18 @@ msgid "" msgstr "版本号在 ``pyproject.toml`` 中说明。要发布 Flower 的新版本,需要完成以下工作(按顺序排列):" #: ../../source/contributor-how-to-release-flower.rst:11 +#, fuzzy msgid "" "Run ``python3 src/py/flwr_tool/update_changelog.py `` in " "order to add every new change to the changelog (feel free to make manual " "changes to the changelog afterwards until it looks good)." msgstr "" +"运行 ``python3 src/py/flwr_tool/update_changelog.py `` 以将每" +"项新更改添加到更新日志中(之后可对更新日志进行手动更改,直到看起来不错为止)" +"。" #: ../../source/contributor-how-to-release-flower.rst:12 +#, fuzzy msgid "" "Once the changelog has been updated with all the changes, run ``./dev" "/prepare-release-changelog.sh v``, where ```` " @@ -874,6 +931,11 @@ msgid "" "by the version and current date, and it will add a thanking message for " "the contributors. Open a pull request with those changes." msgstr "" +"更新更新日志后,运行``./dev/prepare-release-changelog.sh " +"v``,其中````是``pyproject." +"toml``中的版本(注意前面的``v``)。这将用版本和当前日期替换更新日志中的 " +"``Unreleased`` " +"标头,并为贡献者添加一条感谢信息。打开一个包含这些更改的拉取请求。" #: ../../source/contributor-how-to-release-flower.rst:13 #, fuzzy @@ -1664,6 +1726,7 @@ msgid "" msgstr "中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 +#, fuzzy msgid "" "It is important to follow the instructions described in comments. For " "instance, in order to not break how our changelog system works, you " @@ -1671,6 +1734,9 @@ msgid "" "carefully. You can also checkout some examples and details in the " ":ref:`changelogentry` appendix." msgstr "" +"请务必遵守注释中的说明。例如,为了不破坏我们的更新日志系统,你应该仔细阅读\"" +"`更新日志条目``\"部分上面的信息。您还可以查看 :ref:`changelogentry` " +"附录中的一些示例和细节。" #: ../../source/contributor-tutorial-contribute-on-github.rst:200 msgid "" @@ -2032,131 +2098,163 @@ msgid "Changelog entry" msgstr "更新日志" #: ../../source/contributor-tutorial-contribute-on-github.rst:356 +#, fuzzy msgid "" "When opening a new PR, inside its description, there should be a " "``Changelog entry`` header." -msgstr "" +msgstr "打开一个新 PR 时,在其描述中应有一个 ``Changelog entry`` 标头。" #: ../../source/contributor-tutorial-contribute-on-github.rst:358 +#, fuzzy msgid "" "Above this header you should see the following comment that explains how " "to write your changelog entry:" -msgstr "" +msgstr "在页眉上方,你会看到以下注释,说明如何编写更新日志条目:" #: ../../source/contributor-tutorial-contribute-on-github.rst:360 +#, fuzzy msgid "" "Inside the following 'Changelog entry' section, you should put the " "description of your changes that will be added to the changelog alongside" " your PR title." -msgstr "" +msgstr "在下面的 \"更新日志条目 \"部分中,您应该在 PR " +"标题旁边写上将添加到更新日志中的更改描述。" #: ../../source/contributor-tutorial-contribute-on-github.rst:363 +#, fuzzy msgid "" "If the section is completely empty (without any token) or non-existent, " "the changelog will just contain the title of the PR for the changelog " "entry, without any description." -msgstr "" +msgstr "如果该部分完全为空(没有任何标记)或不存在,更新日志将只包含更新日志条目的 " +"PR 标题,而不包含任何描述。" #: ../../source/contributor-tutorial-contribute-on-github.rst:366 +#, fuzzy msgid "" "If the section contains some text other than tokens, it will use it to " "add a description to the change." -msgstr "" +msgstr "如果该部分包含标记以外的文本,它将使用这些文本为更改添加说明。" #: ../../source/contributor-tutorial-contribute-on-github.rst:368 +#, fuzzy msgid "" "If the section contains one of the following tokens it will ignore any " "other text and put the PR under the corresponding section of the " "changelog:" -msgstr "" +msgstr "如果该部分包含以下标记之一,它将忽略任何其他文本,并将 PR " +"放在更新日志的相应部分下:" #: ../../source/contributor-tutorial-contribute-on-github.rst:370 +#, fuzzy msgid " is for classifying a PR as a general improvement." -msgstr "" +msgstr " 用于将 PR 划分为一般改进。" #: ../../source/contributor-tutorial-contribute-on-github.rst:372 +#, fuzzy msgid " is to not add the PR to the changelog" -msgstr "" +msgstr "表示不将 PR 添加到更新日志中" #: ../../source/contributor-tutorial-contribute-on-github.rst:374 +#, fuzzy msgid " is to add a general baselines change to the PR" -msgstr "" +msgstr " 是指在 PR 中添加一般基线更改" #: ../../source/contributor-tutorial-contribute-on-github.rst:376 +#, fuzzy msgid " is to add a general examples change to the PR" -msgstr "" +msgstr " 是在 PR 中添加对一般示例的修改" #: ../../source/contributor-tutorial-contribute-on-github.rst:378 +#, fuzzy msgid " is to add a general sdk change to the PR" -msgstr "" +msgstr " 是指在 PR 中添加一般的 sdk 更改" #: ../../source/contributor-tutorial-contribute-on-github.rst:380 +#, fuzzy msgid " is to add a general simulations change to the PR" -msgstr "" +msgstr "(模拟)是在 PR 中添加一般模拟变更" #: ../../source/contributor-tutorial-contribute-on-github.rst:382 +#, fuzzy msgid "Note that only one token should be used." -msgstr "" +msgstr "请注意,只能使用一个标记。" #: ../../source/contributor-tutorial-contribute-on-github.rst:384 +#, fuzzy msgid "" "Its content must have a specific format. We will break down what each " "possibility does:" -msgstr "" +msgstr "其内容必须有特定的格式。我们将分析每种可能性的作用:" #: ../../source/contributor-tutorial-contribute-on-github.rst:386 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains nothing or doesn't exist," " the following text will be added to the changelog::" -msgstr "" +msgstr "如果 ``#### Changelog entry`` " +"部分不包含任何内容或不存在,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:390 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains a description (and no " "token), the following text will be added to the changelog::" -msgstr "" +msgstr "如果 ``#### Changelog entry`` " +"部分包含描述(但没有标记),则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:396 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, nothing will " "change in the changelog." -msgstr "" +msgstr "如果 ``#### Changelog entry`` 部分包含 " +"````,更新日志中将不会有任何更改。" #: ../../source/contributor-tutorial-contribute-on-github.rst:398 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "" +msgstr "如果 ``### Changelog entry`` 部分包含 " +"````,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:402 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "" +msgstr "如果``### " +"更新日志条目``部分包含``<基准线>``,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:406 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "" +msgstr "如果``### 更新日志条目``部分包含``<示例>``,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:410 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the following " "text will be added to the changelog::" -msgstr "" +msgstr "如果``### 更新日志条目``部分包含````,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:414 +#, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "" +msgstr "如果 ``### Changelog entry`` 部分包含 " +"````,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:418 +#, fuzzy msgid "" "Note that only one token must be provided, otherwise, only the first " "action (in the order listed above), will be performed." -msgstr "" +msgstr "请注意,必须只提供一个标记,否则将只执行第一个操作(按上述顺序)。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 msgid "Get started as a contributor" @@ -2198,38 +2296,46 @@ msgid "Developer Machine Setup" msgstr "开发者机器设置" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:21 +#, fuzzy msgid "Preliminarities" -msgstr "" +msgstr "前言" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:22 +#, fuzzy msgid "Some system-wide dependencies are needed." -msgstr "" +msgstr "需要一些全系统依赖性。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:25 +#, fuzzy msgid "For macOS" -msgstr "" +msgstr "适用于 macOS" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 +#, fuzzy msgid "" "Install `homebrew `_. Don't forget the post-" "installation actions to add `brew` to your PATH." -msgstr "" +msgstr "安装 `homebrew `_。别忘了安装后的操作,将 `brew` " +"添加到你的 PATH。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 +#, fuzzy msgid "" "Install `xz` (to install different Python versions) and `pandoc` to build" " the docs::" -msgstr "" +msgstr "安装 `xz`(用于安装不同的 Python 版本)和 `pandoc` 以构建文档::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 +#, fuzzy msgid "For Ubuntu" -msgstr "" +msgstr "针对 Ubuntu" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 +#, fuzzy msgid "" "Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " "necessary packages::" -msgstr "" +msgstr "确保您的系统(Ubuntu 22.04+)为最新版本,并安装了所有必要的软件包::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 #, fuzzy @@ -2244,6 +2350,7 @@ msgid "" msgstr "首先,从 GitHub 克隆 \"Flower 存储库 `_\":" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 +#, fuzzy msgid "" "Let's create the Python environment for all-things Flower. If you wish to" " use :code:`pyenv`, we provide two convenience scripts that you can use. " @@ -2251,6 +2358,9 @@ msgid "" "environment, activate and skip to the last point where all packages are " "installed." msgstr "" +"让我们为 Flower 创建一个 Python 环境。如果您想使用 " +":code:`pyenv`,我们提供了两个方便的脚本供您使用。如果你不喜欢使用 " +":code:`pyenv`,请创建一个新环境,激活并跳到最后一点,即安装所有软件包。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 #, fuzzy @@ -3317,6 +3427,7 @@ msgid "Differential Privacy" msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:3 +#, fuzzy msgid "" "The information in datasets like healthcare, financial transactions, user" " preferences, etc., is valuable and has the potential for scientific " @@ -3324,16 +3435,21 @@ msgid "" "data is also sensitive and there is a risk of compromising individual " "privacy." msgstr "" +"医疗保健、金融交易、用户偏好等数据集中的信息非常宝贵,有可能带来科学突破并提" +"供重要的商业见解。然而,这些数据也是敏感数据,存在泄露个人隐私的风险。" #: ../../source/explanation-differential-privacy.rst:6 +#, fuzzy msgid "" "Traditional methods like anonymization alone would not work because of " "attacks like Re-identification and Data Linkage. That's where " "differential privacy comes in. It provides the possibility of analyzing " "data while ensuring the privacy of individuals." -msgstr "" +msgstr "单靠匿名等传统方法是行不通的,因为会受到重新识别和数据链接等攻击。这就是差异" +"化隐私的用武之地。它提供了在分析数据的同时确保个人隐私的可能性。" #: ../../source/explanation-differential-privacy.rst:12 +#, fuzzy msgid "" "Imagine two datasets that are identical except for a single record (for " "instance, Alice's data). Differential Privacy (DP) guarantees that any " @@ -3342,18 +3458,25 @@ msgid "" "preserves group patterns while obscuring individual details, ensuring the" " individual's information remains hidden in the crowd." msgstr "" +"试想一下,两个数据集除了一条记录(例如 Alice 的数据)之外完全相同。差分隐私(" +"DP)可以保证任何分析(M),比如计算平均收入,对两个数据集都会产生几乎相同的结" +"果(O 和 O' 将是相似的)。这既保留了群体模式,又掩盖了个人细节,确保个人的信" +"息隐藏在人群中。" #: ../../source/explanation-differential-privacy.rst:-1 +#, fuzzy msgid "DP Intro" -msgstr "" +msgstr "DP 介绍" #: ../../source/explanation-differential-privacy.rst:22 +#, fuzzy msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " "individual in the data while preserving the overall accuracy of the " "analysis." -msgstr "" +msgstr "实现 DP 的最常用机制之一是在分析输出中加入足够的噪音,以掩盖数据中每个个体的" +"贡献,同时保持分析的整体准确性。" #: ../../source/explanation-differential-privacy.rst:25 #, fuzzy @@ -3361,6 +3484,7 @@ msgid "Formal Definition" msgstr "编译 ProtoBuf 定义" #: ../../source/explanation-differential-privacy.rst:26 +#, fuzzy msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " @@ -3371,14 +3495,23 @@ msgid "" "databases, D :sub:`1` and D :sub:`2`, that differ in only a single " "record, and for all possible outputs S ⊆ Range(A):" msgstr "" +"差分隐私(Differential Privacy,DP)针对对手通过随机算法的输出所能推断出的信" +"息提供统计保证。它为单个个体通过添加噪声对算法输出的影响提供了一个无条件的上" +"限[1]。如果任意两个相邻的数据库D :sub:`1`和D :sub:`2`只有一条记录不同," +"并且对于所有可能的输出S ⊆ Range(A),随机化机制M提供(:math:`epsilon`,:math:`" +"\\delta`)差异隐私:" #: ../../source/explanation-differential-privacy.rst:32 +#, fuzzy msgid "" "\\small\n" "P[M(D_{1} \\in A)] \\leq e^{\\delta} P[M(D_{2} \\in A)] + \\delta" msgstr "" +"\\small\n" +"P[M(D_{1} \\in A)] \\leq e^{\\delta} P[M(D_{2} \\in A)] + \\delta" #: ../../source/explanation-differential-privacy.rst:38 +#, fuzzy msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " @@ -3389,6 +3522,11 @@ msgid "" "proportional to the sensitivity of the output, which measures the maximum" " change in the output due to the inclusion or removal of a single record." msgstr "" +":math:`\\epsilon`参数也称为隐私预算,是衡量隐私损失的指标。较低的 :math:`" +"\\epsilon` 值表示较高的隐私级别,但也可能降低效用。:math:`\\delta" +"`参数考虑了:math:`\\epsilon`上限不成立的小概率。实现差异化隐私所需的噪声量与" +"输出的灵敏度成正比,而输出的灵敏度是指由于包含或删除一条记录而导致的输出的最" +"大变化。" #: ../../source/explanation-differential-privacy.rst:45 #, fuzzy @@ -3396,6 +3534,7 @@ msgid "Differential Privacy in Machine Learning" msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:46 +#, fuzzy msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " @@ -3409,6 +3548,11 @@ msgid "" "model training. Additionally, such noise can be incorporated into the " "model's output." msgstr "" +"机器学习中可以利用 DP 来保护训练数据的隐私。差分保密机器学习算法的设计方式是" +"防止算法学习到任何单个数据点的任何特定信息,从而防止模型泄露敏感信息。根据引" +"入噪声的阶段,有多种方法可将 DP 应用于机器学习算法。一种方法是在训练数据(特" +"征或标签)中添加噪声,另一种方法是在模型训练过程中向损失函数的梯度注入噪声。" +"此外,这种噪声还可以被纳入模型的输出中。" #: ../../source/explanation-differential-privacy.rst:53 #, fuzzy @@ -3416,6 +3560,7 @@ msgid "Differential Privacy in Federated Learning" msgstr "扩大联邦学习的规模" #: ../../source/explanation-differential-privacy.rst:54 +#, fuzzy msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " @@ -3425,14 +3570,20 @@ msgid "" "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" +"联合学习是一种数据最小化方法,允许多方在不共享原始数据的情况下合作训练一个模" +"型。然而,联合学习也带来了新的隐私挑战。各方与中央服务器之间的模型更新可能会" +"泄露本地数据信息。这些泄漏信息可能会被攻击利用,如成员推断攻击、属性推断攻击" +"或模型反转攻击。" #: ../../source/explanation-differential-privacy.rst:58 +#, fuzzy msgid "" "DP can play a crucial role in federated learning to provide privacy for " "the clients' data." -msgstr "" +msgstr "DP 可以在联合学习中发挥重要作用,为客户数据提供隐私保护。" #: ../../source/explanation-differential-privacy.rst:60 +#, fuzzy msgid "" "Depending on the granularity of privacy provision or the location of " "noise addition, different forms of DP exist in federated learning. In " @@ -3440,21 +3591,28 @@ msgid "" " learning based on where the noise is added: at the server (also known as" " the center) or at the client (also known as the local)." msgstr "" +"根据提供隐私的粒度或添加噪声的位置,联合学习中存在不同形式的 " +"DP。在本说明中,我们将根据添加噪声的位置,重点介绍联合学习中利用 DP " +"的两种方法:在服务器(也称为中心)或客户端(也称为本地)。" #: ../../source/explanation-differential-privacy.rst:63 +#, fuzzy msgid "" "**Central Differential Privacy**: DP is applied by the server and the " "goal is to prevent the aggregated model from leaking information about " "each client's data." -msgstr "" +msgstr "**中央差分隐私**: DP " +"由服务器应用,目标是防止聚合模型泄露每个客户的数据信息。" #: ../../source/explanation-differential-privacy.rst:65 +#, fuzzy msgid "" "**Local Differential Privacy**: DP is applied on the client side before " "sending any information to the server and the goal is to prevent the " "updates that are sent to the server from leaking any information about " "the client's data." -msgstr "" +msgstr "**本地差分隐私**: 在向服务器发送任何信息之前,在客户端应用 " +"DP,目的是防止向服务器发送的更新泄露任何有关客户端数据的信息。" #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:68 @@ -3464,13 +3622,16 @@ msgid "Central Differential Privacy" msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:69 +#, fuzzy msgid "" "In this approach, which is also known as user-level DP, the central " "server is responsible for adding noise to the globally aggregated " "parameters. It should be noted that trust in the server is required." -msgstr "" +msgstr "在这种方法(也称为用户级 DP)中,中央服务器负责在全局汇总参数中添加噪声。需要" +"注意的是,这需要对服务器的信任。" #: ../../source/explanation-differential-privacy.rst:76 +#, fuzzy msgid "" "While there are various ways to implement central DP in federated " "learning, we concentrate on the algorithms proposed by [2] and [3]. The " @@ -3484,12 +3645,21 @@ msgid "" " by restricting the `L2` norm of the clients' model updates, ensuring " "that larger updates are scaled down to fit within the norm `S`." msgstr "" +"虽然在联合学习中实现中央数据处理的方法有很多种,但我们将重点放在[2]和[3]提出" +"的算法上。总体方法是剪辑客户端发送的模型更新,并在聚合模型中添加一定量的噪声" +"。在每次迭代中,以特定概率随机选择一组客户端进行训练。每个客户端对自己的数据" +"进行局部训练。然后,每个客户端的更新会被某个值`S`(灵敏度`S`)剪切。这将限制" +"任何单个客户端的影响,这对隐私至关重要,通常也有利于稳健性。" +"实现这一点的常用方法是限制客户机模型更新的 `L2` 准则," +"确保较大的更新被缩减以适应 `S` 准则。" #: ../../source/explanation-differential-privacy.rst:-1 +#, fuzzy msgid "clipping" -msgstr "" +msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:89 +#, fuzzy msgid "" "Afterwards, the Gaussian mechanism is used to add noise in order to " "distort the sum of all clients' updates. The amount of noise is scaled to" @@ -3497,38 +3667,49 @@ msgid "" "mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " "noise_scale * S ) / (number of sampled clients)`." msgstr "" +"然后,使用高斯机制添加噪声,以扭曲所有客户端的更新总和。噪声量与灵敏度值成正" +"比,以获得隐私保证。高斯机制的噪声采样范围为 `N (0, σ²)` ,其中 σ = ( " +"噪声规模 * S ) / (采样客户数)`。" #: ../../source/explanation-differential-privacy.rst:94 +#, fuzzy msgid "Clipping" -msgstr "" +msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:96 +#, fuzzy msgid "" "There are two forms of clipping commonly used in Central DP: Fixed " "Clipping and Adaptive Clipping." -msgstr "" +msgstr "中央处理器常用的剪切有两种形式:固定剪切和自适应剪切。" #: ../../source/explanation-differential-privacy.rst:98 +#, fuzzy msgid "" "**Fixed Clipping** : A predefined fix threshold is set for the magnitude " "of clients' updates. Any update exceeding this threshold is clipped back " "to the threshold value." -msgstr "" +msgstr "** 固定削波** : 为客户端更新的大小设置了一个预定义的固定阈值。任何超过该阈值" +"的更新都会被剪切回阈值。" #: ../../source/explanation-differential-privacy.rst:100 +#, fuzzy msgid "" "**Adaptive Clipping** : The clipping threshold dynamically adjusts based " "on the observed update distribution [4]. It means that the clipping value" " is tuned during the rounds with respect to the quantile of the update " "norm distribution." -msgstr "" +msgstr "** 自适应削波** : 削波阈值根据观察到的更新分布动态调整[4]。这意味着,在各轮" +"中,会根据更新规范分布的量化值调整削波值。" #: ../../source/explanation-differential-privacy.rst:102 +#, fuzzy msgid "" "The choice between fixed and adaptive clipping depends on various factors" " such as privacy requirements, data distribution, model complexity, and " "others." -msgstr "" +msgstr "在固定剪切和自适应剪切之间做出选择取决于各种因素,如隐私要求、数据分布、模型" +"复杂性等。" #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:105 @@ -3538,45 +3719,62 @@ msgid "Local Differential Privacy" msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:107 +#, fuzzy msgid "" "In this approach, each client is responsible for performing DP. Local DP " "avoids the need for a fully trusted aggregator, but it should be noted " "that local DP leads to a decrease in accuracy but better privacy in " "comparison to central DP." msgstr "" +"在这种方法中,每个客户端都负责执行 DP。本地 DP " +"避免了对完全可信的聚合器的需求,但需要注意的是,与中央 DP 相比,本地 DP " +"会降低准确性,但却能更好地保护隐私。" #: ../../source/explanation-differential-privacy.rst:116 +#, fuzzy msgid "In this explainer, we focus on two forms of achieving Local DP:" -msgstr "" +msgstr "在本说明中,我们将重点介绍实现本地 DP 的两种形式:" #: ../../source/explanation-differential-privacy.rst:118 +#, fuzzy msgid "" "Each client adds noise to the local updates before sending them to the " "server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " "the sensitivity of the local model to be ∆, Gaussian noise is applied " "with a noise scale of σ where:" msgstr "" +"每个客户端在向服务器发送本地更新之前,都会在本地更新中加入噪声。为了实现(:ma" +"th:`\\epsilon`, :math:`\\delta`)-DP,考虑到本地模型的灵敏度为 " +"∆,应用了高斯噪声,噪声尺度为 σ,其中:" #: ../../source/explanation-differential-privacy.rst:120 +#, fuzzy msgid "" "\\small\n" "\\frac{∆ \\times \\sqrt{2 \\times " "\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" "\n" msgstr "" +"\\small\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right" +")}}{\\epsilon}\n" +"\n" #: ../../source/explanation-differential-privacy.rst:125 +#, fuzzy msgid "" "Each client adds noise to the gradients of the model during the local " "training (DP-SGD). More specifically, in this approach, gradients are " "clipped and an amount of calibrated noise is injected into the gradients." -msgstr "" +msgstr "在局部训练过程中,每个客户端都会向模型的梯度添加噪声(DP-SGD)。更具体地说," +"在这种方法中,梯度会被剪切,并在梯度中注入一定量的校准噪声。" #: ../../source/explanation-differential-privacy.rst:128 +#, fuzzy msgid "" "Please note that these two approaches are providing privacy at different " "levels." -msgstr "" +msgstr "请注意,这两种方法提供了不同层次的隐私。" #: ../../source/explanation-differential-privacy.rst:131 #, fuzzy @@ -3584,8 +3782,9 @@ msgid "**References:**" msgstr "参考资料" #: ../../source/explanation-differential-privacy.rst:133 +#, fuzzy msgid "[1] Dwork et al. The Algorithmic Foundations of Differential Privacy." -msgstr "" +msgstr "[1] Dwork 等:《差分隐私的算法基础》。" #: ../../source/explanation-differential-privacy.rst:135 #, fuzzy @@ -3597,10 +3796,11 @@ msgstr "" "language models.\" arXiv preprint arXiv:1710.06963 (2017)." #: ../../source/explanation-differential-privacy.rst:137 +#, fuzzy msgid "" "[3] Geyer et al. Differentially Private Federated Learning: A Client " "Level Perspective." -msgstr "" +msgstr "[3] Geyer 等人。差异化化私人联合学习:客户层面的视角。" #: ../../source/explanation-differential-privacy.rst:139 #, fuzzy @@ -4952,8 +5152,9 @@ msgid "Install stable release" msgstr "安装稳定版" #: ../../source/how-to-install-flower.rst:15 +#, fuzzy msgid "Using pip" -msgstr "" +msgstr "使用 pip" #: ../../source/how-to-install-flower.rst:17 msgid "" @@ -4968,28 +5169,33 @@ msgid "" msgstr "对于使用虚拟客户端引擎的模拟,`flwr`` 应与`simulation`` 一起安装:" #: ../../source/how-to-install-flower.rst:27 +#, fuzzy msgid "Using conda (or mamba)" -msgstr "" +msgstr "使用 conda(或 mamba)" #: ../../source/how-to-install-flower.rst:29 +#, fuzzy msgid "Flower can also be installed from the ``conda-forge`` channel." -msgstr "" +msgstr "Flower 也可以从 ``conda-forge`` 频道安装。" #: ../../source/how-to-install-flower.rst:31 +#, fuzzy msgid "" "If you have not added ``conda-forge`` to your channels, you will first " "need to run the following::" -msgstr "" +msgstr "如果您尚未在频道中添加 ``conda-forge``,则首先需要运行以下程序::" #: ../../source/how-to-install-flower.rst:36 +#, fuzzy msgid "" "Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " "installed with ``conda``::" -msgstr "" +msgstr "一旦启用了 ``conda-forge`` 频道,就可以使用 ``conda``: 安装 ``flwr``:" #: ../../source/how-to-install-flower.rst:40 +#, fuzzy msgid "or with ``mamba``::" -msgstr "" +msgstr "或用 ``mamba`` ::" #: ../../source/how-to-install-flower.rst:46 msgid "Verify installation" @@ -5304,35 +5510,47 @@ msgstr "" "metrics.html>`_" #: ../../source/how-to-run-flower-using-docker.rst:2 +#, fuzzy msgid "Run Flower using Docker" -msgstr "" +msgstr "使用 Docker 运行 Flower" #: ../../source/how-to-run-flower-using-docker.rst:4 +#, fuzzy msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " "`_." msgstr "" +"开始使用 Flower 的最简单方法是使用预制的 Docker 镜像,您可以在 `Docker Hub " +"`_ 上找到这些镜像。" #: ../../source/how-to-run-flower-using-docker.rst:7 +#, fuzzy msgid "Before you start, make sure that the Docker daemon is running:" -msgstr "" +msgstr "开始之前,请确保 Docker 守护进程正在运行:" #: ../../source/how-to-run-flower-using-docker.rst:14 +#, fuzzy msgid "" "If you do not see the version of Docker but instead get an error saying " "that the command was not found, you will need to install Docker first. " "You can find installation instruction `here `_." msgstr "" +"如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。" +"你可以在 `_ 找到安装说明。" #: ../../source/how-to-run-flower-using-docker.rst:20 +#, fuzzy msgid "" "On Linux, Docker commands require ``sudo`` privilege. If you want to " "avoid using ``sudo``, you can follow the `Post-installation steps " "`_ on the " "official Docker website." msgstr "" +"在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``," +"可以按照 Docker 官方网站上的 `安装后步骤 `_进行操作。" #: ../../source/how-to-run-flower-using-docker.rst:25 #, fuzzy @@ -5345,10 +5563,12 @@ msgid "Quickstart" msgstr "快速入门 JAX" #: ../../source/how-to-run-flower-using-docker.rst:30 +#, fuzzy msgid "If you're looking to try out Flower, you can use the following command:" -msgstr "" +msgstr "如果您想试用 Flower,可以使用以下命令:" #: ../../source/how-to-run-flower-using-docker.rst:37 +#, fuzzy msgid "" "The command will pull the Docker image with the tag " "``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. The tag contains the " @@ -5356,16 +5576,24 @@ msgid "" "uses Flower 1.7.0, Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells " "Docker to remove the container after it exits." msgstr "" +"该命令将从 Docker Hub 提取标签为``1.7.0-py3.11-ubuntu22.04``的 Docker 镜像。" +"标签包含使用 Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower 1.7." +"0、Python 3.11 和 Ubuntu 22.04。rm \"标记告诉 Docker 在退出后移除容器。" #: ../../source/how-to-run-flower-using-docker.rst:44 +#, fuzzy msgid "" "By default, the Flower server keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " "starts. We will show below how to save the state in a file on your host " "system." msgstr "" +"默认情况下,Flower 服务器会将状态保存在内存中。使用 Docker 标志 ``--rm`` 时," +"状态不会在容器启动之间持久化。下面我们将展示如何将状态保存到主机系统上的文件" +"中。" #: ../../source/how-to-run-flower-using-docker.rst:48 +#, fuzzy msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " @@ -5374,8 +5602,14 @@ msgid "" "after the tag is passed to the Flower server. Here, we are passing the " "flag ``--insecure``." msgstr "" +"``-p :`` 标记会告诉 Docker 将主机的端口 ``9091``/``9092`` " +"映射到容器的端口 ``9091``/`9092``,这样你就可以在 ``http://localhost:9091`` " +"上访问 Driver API,在 ``http://localhost:9092`` 上访问 Fleet API。最后," +"标签后面的任何标志都会传递给 Flower 服务器。在这里,我们传递的标志是 " +"``--insecure`` 。" #: ../../source/how-to-run-flower-using-docker.rst:55 +#, fuzzy msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " @@ -5383,18 +5617,24 @@ msgid "" "flower-using-docker.html#enabling-ssl-for-secure-connections>`_ when " "deploying to a production environment." msgstr "" +"不安全 \"标志启用不安全通信(使用 HTTP,而非 HTTPS),只能用于测试目的。" +"我们强烈建议在部署到生产环境时启用 `SSL `_。" #: ../../source/how-to-run-flower-using-docker.rst:60 +#, fuzzy msgid "" "You can use ``--help`` to view all available flags that the server " "supports:" -msgstr "" +msgstr "您可以使用 ``--help`` 查看服务器支持的所有可用标记:" #: ../../source/how-to-run-flower-using-docker.rst:67 +#, fuzzy msgid "Mounting a volume to store the state on the host system" -msgstr "" +msgstr "在主机系统上挂载卷以存储状态" #: ../../source/how-to-run-flower-using-docker.rst:69 +#, fuzzy msgid "" "If you want to persist the state of the server on your host system, all " "you need to do is specify a path where you want to save the file on your " @@ -5404,14 +5644,22 @@ msgid "" "Furthermore, we use the flag ``--database`` to specify the name of the " "database file." msgstr "" +"如果想在主机系统上持久保存服务器的状态,只需在主机系统上指定保存文件的路径和" +"数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉 Docker " +"将用户的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外," +"我们使用标志 ``--database`` 来指定数据库文件的名称。" #: ../../source/how-to-run-flower-using-docker.rst:82 +#, fuzzy msgid "" "As soon as the server starts, the file ``state.db`` is created in the " "user's home directory on your host system. If the file already exists, " "the server tries to restore the state from the file. To start the server " "with an empty database, simply remove the ``state.db`` file." msgstr "" +"服务器一启动,就会在主机系统的用户主目录下创建文件 ``state.db``。如果该文件已" +"经存在,服务器会尝试从该文件恢复状态。要以空数据库启动服务器,只需删除 " +"``state.db`` 文件即可。" #: ../../source/how-to-run-flower-using-docker.rst:87 #, fuzzy @@ -5419,20 +5667,26 @@ msgid "Enabling SSL for secure connections" msgstr "启用 SSL 连接" #: ../../source/how-to-run-flower-using-docker.rst:89 +#, fuzzy msgid "" "To enable SSL, you will need a CA certificate, a server certificate and a" " server private key." -msgstr "" +msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" #: ../../source/how-to-run-flower-using-docker.rst:92 +#, fuzzy msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `_ page contains a section that " "will guide you through the process." msgstr "" +"出于测试目的,你可以生成自己的自签名证书。启用 SSL 连接 `_ " +"页面中有一个部分将指导你完成这一过程。" #: ../../source/how-to-run-flower-using-docker.rst:96 +#, fuzzy msgid "" "Assuming all files we need are in the local ``certificates`` directory, " "we can use the flag ``-v`` to mount the local directory into the " @@ -5440,23 +5694,34 @@ msgid "" "the files within the container. Finally, we pass the names of the " "certificates to the server with the ``--certificates`` flag." msgstr "" +"假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 " +"``-v`` 将本地目录挂载到容器的 ``/app/`` " +"目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates``" +" 标志将证书名称传递给服务器。" #: ../../source/how-to-run-flower-using-docker.rst:108 +#, fuzzy msgid "Using a different Flower or Python version" -msgstr "" +msgstr "使用不同的 Flower 或 Python 版本" #: ../../source/how-to-run-flower-using-docker.rst:110 +#, fuzzy msgid "" "If you want to use a different version of Flower or Python, you can do so" " by changing the tag. All versions we provide are available on `Docker " "Hub `_." msgstr "" +"如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。" +"我们提供的所有版本都可以在 `Docker Hub `_ 上找到。" #: ../../source/how-to-run-flower-using-docker.rst:114 +#, fuzzy msgid "Pinning a Docker image to a specific version" -msgstr "" +msgstr "将 Docker 映像固定到特定版本" #: ../../source/how-to-run-flower-using-docker.rst:116 +#, fuzzy msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " @@ -5464,16 +5729,22 @@ msgid "" "you always use the same image, you can specify the hash of the image " "instead of the tag." msgstr "" +"我们可能会更新标签后面的图像。此类更新通常包括系统依赖项的安全更新,不会改变 " +"Flower 的功能。不过,如果您想确保始终使用同一张图片,可以指定图片的哈希值而不" +"是标签。" #: ../../source/how-to-run-flower-using-docker.rst:121 +#, fuzzy msgid "" "The following command returns the current image hash referenced by the " "``server:1.7.0-py3.11-ubuntu22.04`` tag:" -msgstr "" +msgstr "下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` " +"标记引用的当前图像哈希值:" #: ../../source/how-to-run-flower-using-docker.rst:128 +#, fuzzy msgid "Next, we can pin the hash when running a new server container:" -msgstr "" +msgstr "接下来,我们可以在运行新服务器容器时将哈希值固定下来:" #: ../../source/how-to-run-flower-using-docker.rst:137 #, fuzzy @@ -5481,10 +5752,11 @@ msgid "Setting environment variables" msgstr "设置编码环境" #: ../../source/how-to-run-flower-using-docker.rst:139 +#, fuzzy msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." -msgstr "" +msgstr "要在 Docker 容器内设置变量,可以使用 ``-e =`` 标志。" #: ../../source/how-to-run-simulations.rst:2 msgid "Run simulations" @@ -6032,10 +6304,13 @@ msgid "" msgstr "要加载进度,只需在代码中添加以下几行。请注意,这将遍历所有已保存的检查点,并加载最新的检查点:" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 +#, fuzzy msgid "" "Return/use this object of type ``Parameters`` wherever necessary, such as" " in the ``initial_parameters`` when defining a ``Strategy``." msgstr "" +"在必要时返回/使用此 ``Parameters`` 类型的对象,例如在定义 ``Strategy` 时的 " +"``initial_parameters` 中。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:2 msgid "Upgrade to Flower 1.0" @@ -6353,73 +6628,93 @@ msgstr "" "`_ 并使用 \"#questions``\"。" #: ../../source/how-to-use-built-in-mods.rst:2 +#, fuzzy msgid "Use Built-in Mods" -msgstr "" +msgstr "使用内置调制器" #: ../../source/how-to-use-built-in-mods.rst:4 +#, fuzzy msgid "" "**Note: This tutorial covers experimental features. The functionality and" " interfaces may change in future versions.**" -msgstr "" +msgstr "**注:本教程涵盖实验性功能。功能和界面可能会在未来版本中发生变化。" #: ../../source/how-to-use-built-in-mods.rst:6 +#, fuzzy msgid "" "In this tutorial, we will learn how to utilize built-in mods to augment " "the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " "allow us to perform operations before and after a task is processed in " "the ``ClientApp``." msgstr "" +"在本教程中,我们将学习如何利用内置模块来增强 ``ClientApp`` " +"的行为。修改器(有时也称为修改器)允许我们在 ``ClientApp`` " +"处理任务之前和之后执行操作。" #: ../../source/how-to-use-built-in-mods.rst:9 +#, fuzzy msgid "What are Mods?" -msgstr "" +msgstr "什么是 Mods?" #: ../../source/how-to-use-built-in-mods.rst:11 +#, fuzzy msgid "" "A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " "or inspect the incoming ``Message`` and the resulting outgoing " "``Message``. The signature for a ``Mod`` is as follows:" msgstr "" +"Mod 是包裹在 ``ClientApp`` 周围的可调用程序。它可以操作或检查传入的 " +"``Message`` 和由此产生的传出的 ``Message`` 。一个 ``Mod`` 的签名如下:" #: ../../source/how-to-use-built-in-mods.rst:18 +#, fuzzy msgid "A typical mod function might look something like this:" -msgstr "" +msgstr "一个典型的修改函数可能是这样的:" #: ../../source/how-to-use-built-in-mods.rst:31 +#, fuzzy msgid "Using Mods" -msgstr "" +msgstr "使用修改器" #: ../../source/how-to-use-built-in-mods.rst:33 +#, fuzzy msgid "To use mods in your ``ClientApp``, you can follow these steps:" -msgstr "" +msgstr "要在您的 ``ClientApp`` 中使用 mod,可以按照以下步骤操作:" #: ../../source/how-to-use-built-in-mods.rst:36 +#, fuzzy msgid "1. Import the required mods" -msgstr "" +msgstr "1. 导入所需修改" #: ../../source/how-to-use-built-in-mods.rst:38 +#, fuzzy msgid "First, import the built-in mod you intend to use:" -msgstr "" +msgstr "首先,导入您打算使用的内置模式:" #: ../../source/how-to-use-built-in-mods.rst:46 +#, fuzzy msgid "2. Define your client function" -msgstr "" +msgstr "2. 定义客户功能" #: ../../source/how-to-use-built-in-mods.rst:48 +#, fuzzy msgid "" "Define your client function (``client_fn``) that will be wrapped by the " "mod(s):" -msgstr "" +msgstr "定义将被 mod 封装的客户端函数(``client_fn``):" #: ../../source/how-to-use-built-in-mods.rst:57 +#, fuzzy msgid "3. Create the ``ClientApp`` with mods" -msgstr "" +msgstr "3. 用模块创建 ``ClientApp``" #: ../../source/how-to-use-built-in-mods.rst:59 +#, fuzzy msgid "" "Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " "argument. The order in which you provide the mods matters:" -msgstr "" +msgstr "创建您的 ``ClientApp`` 并将 mods 作为列表传递给 ``mods`` 参数。提供 mod " +"的顺序很重要:" #: ../../source/how-to-use-built-in-mods.rst:72 #, fuzzy @@ -6427,50 +6722,62 @@ msgid "Order of execution" msgstr "停用" #: ../../source/how-to-use-built-in-mods.rst:74 +#, fuzzy msgid "" "When the ``ClientApp`` runs, the mods are executed in the order they are " "provided in the list:" -msgstr "" +msgstr "当运行 ``ClientApp`` 时,会按照列表中提供的顺序执行模块:" #: ../../source/how-to-use-built-in-mods.rst:76 +#, fuzzy msgid "``example_mod_1`` (outermost mod)" -msgstr "" +msgstr "``example_mod_1`` (最外层模块)" #: ../../source/how-to-use-built-in-mods.rst:77 +#, fuzzy msgid "``example_mod_2`` (next mod)" -msgstr "" +msgstr "示例模式 2(下一个模式)" #: ../../source/how-to-use-built-in-mods.rst:78 +#, fuzzy msgid "" "Message handler (core function that handles the incoming ``Message`` and " "returns the outgoing ``Message``)" -msgstr "" +msgstr "消息处理程序(处理传入的 \"消息 \"并返回传出的 \"消息 \"的核心函数)" #: ../../source/how-to-use-built-in-mods.rst:79 +#, fuzzy msgid "``example_mod_2`` (on the way back)" -msgstr "" +msgstr "``example_mod_2`` (返回途中)" #: ../../source/how-to-use-built-in-mods.rst:80 +#, fuzzy msgid "``example_mod_1`` (outermost mod on the way back)" -msgstr "" +msgstr "``example_mod_1`` (返回途中最外层的模式)" #: ../../source/how-to-use-built-in-mods.rst:82 +#, fuzzy msgid "" "Each mod has a chance to inspect and modify the incoming ``Message`` " "before passing it to the next mod, and likewise with the outgoing " "``Message`` before returning it up the stack." -msgstr "" +msgstr "每个模块都有机会检查和修改传入的 \"信息\",然后再将其传递给下一个模块,同样," +"也有机会检查和修改传出的 \"信息\",然后再将其返回堆栈。" #: ../../source/how-to-use-built-in-mods.rst:87 +#, fuzzy msgid "" "By following this guide, you have learned how to effectively use mods to " "enhance your ``ClientApp``'s functionality. Remember that the order of " "mods is crucial and affects how the input and output are processed." msgstr "" +"通过本指南,您已学会如何有效地使用 mod 来增强您的 ``ClientApp`` " +"的功能。请记住,mod 的顺序至关重要,它会影响输入和输出的处理方式。" #: ../../source/how-to-use-built-in-mods.rst:89 +#, fuzzy msgid "Enjoy building a more robust and flexible ``ClientApp`` with mods!" -msgstr "" +msgstr "使用 mods 构建更强大、更灵活的 \"客户端应用程序\"!" #: ../../source/how-to-use-differential-privacy.rst:2 #, fuzzy @@ -6478,29 +6785,38 @@ msgid "Use Differential Privacy" msgstr "差分隐私" #: ../../source/how-to-use-differential-privacy.rst:3 +#, fuzzy msgid "" "This guide explains how you can utilize differential privacy in the " "Flower framework. If you are not yet familiar with differential privacy, " "you can refer to :doc:`explanation-differential-privacy`." msgstr "" +"本指南解释了如何在 Flower 框架中使用差分隐私。如果您还不熟悉差分隐私," +"可以参考 :doc:`explanation-differential-privacy` 。" #: ../../source/how-to-use-differential-privacy.rst:7 +#, fuzzy msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " "these features in a production environment with sensitive data, feel free" " contact us to discuss your requirements and to receive guidance on how " "to best use these features." msgstr "" +"Flower 中的差异隐私处于预览阶段。如果您计划在生产环境中使用这些敏感数据功能," +"请随时联系我们,讨论您的需求,并获得如何最好地使用这些功能的指导。" #: ../../source/how-to-use-differential-privacy.rst:12 +#, fuzzy msgid "" "This approach consists of two seprate phases: clipping of the updates and" " adding noise to the aggregated model. For the clipping phase, Flower " "framework has made it possible to decide whether to perform clipping on " "the server side or the client side." -msgstr "" +msgstr "这种方法包括两个独立的阶段:对更新进行剪切和在聚合模型中添加噪声。在剪切阶段" +",Flower 框架可以决定是在服务器端还是在客户端执行剪切。" #: ../../source/how-to-use-differential-privacy.rst:15 +#, fuzzy msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " @@ -6508,14 +6824,19 @@ msgid "" "disadvantage of increasing the computational load on the server due to " "the need to perform the clipping operation for all clients." msgstr "" +"** 服务器端剪切**: 这种方法的优点是服务器可对所有客户端的更新执行统一的剪切" +",并减少剪切值的通信开销。不过,这种方法也有缺点,那就是需要为所有客户端执行" +"剪切操作,从而增加了服务器的计算负荷。" #: ../../source/how-to-use-differential-privacy.rst:16 +#, fuzzy msgid "" "**Client-side Clipping**: This approach has the advantage of reducing the" " computational overhead on the server. However, it also has the " "disadvantage of lacking centralized control, as the server has less " "control over the clipping process." -msgstr "" +msgstr "**客户端剪切**: 这种方法的优点是可以减少服务器的计算开销。不过,它也有缺乏集" +"中控制的缺点,因为服务器对剪切过程的控制较少。" #: ../../source/how-to-use-differential-privacy.rst:21 #, fuzzy @@ -6523,6 +6844,7 @@ msgid "Server-side Clipping" msgstr "服务器端逻辑" #: ../../source/how-to-use-differential-privacy.rst:22 +#, fuzzy msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " @@ -6531,6 +6853,11 @@ msgid "" ":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " "adaptive clipping." msgstr "" +"对于具有服务器端剪裁功能的中央 DP,有两个 :code:`Strategy` 类作为实际 " +":code:`Strategy` 实例(例如 :code:`FedAvg`)的包装器。这两个封装类分别是 " +":code:`DifferentialPrivacyServerSideFixedClipping` 和 " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` " +",用于固定剪辑和自适应剪辑。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -6538,6 +6865,7 @@ msgid "server side clipping" msgstr "服务器端逻辑" #: ../../source/how-to-use-differential-privacy.rst:31 +#, fuzzy msgid "" "The code sample below enables the :code:`FedAvg` strategy to use server-" "side fixed clipping using the " @@ -6546,6 +6874,9 @@ msgid "" ":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" +"下面的代码示例使用 :code:`DifferentialPrivacyServerSideFixedClipping` " +"封装类使 :code:`FedAvg` 策略使用服务器端固定剪辑。通过调整相应的输入参数," +"同样的方法也可用于 :code:`DifferentialPrivacyServerSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:52 #, fuzzy @@ -6553,6 +6884,7 @@ msgid "Client-side Clipping" msgstr "客户端逻辑" #: ../../source/how-to-use-differential-privacy.rst:53 +#, fuzzy msgid "" "For central DP with client-side clipping, the server sends the clipping " "value to selected clients on each round. Clients can use existing Flower " @@ -6562,6 +6894,11 @@ msgid "" ":code:`DifferentialPrivacyClientSideFixedClipping` and " ":code:`DifferentialPrivacyClientSideAdaptiveClipping`." msgstr "" +"对于带有客户端剪裁功能的中央 DP,服务器会在每一轮向选定的客户端发送剪裁值。" +"客户端可以使用现有的 Flower :code:`Mods`来执行剪裁。有两种模式可用于固定和自" +"适应客户端剪辑::code:`fixedclipping_mod` 和 :code:`adaptiveclipping_mod`," +"以及相应的服务器端封装 :code:`DifferentialPrivacyClientSideFixedClipping` 和 " +":code:`DifferentialPrivacyClientSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -6569,49 +6906,66 @@ msgid "client side clipping" msgstr "客户端逻辑" #: ../../source/how-to-use-differential-privacy.rst:63 +#, fuzzy msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " "differential privacy with client-side fixed clipping using both the " ":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " "the client, :code:`fixedclipping_mod`:" msgstr "" +"下面的代码示例使用 :code:`DifferentialPrivacyClientSideFixedClipping` " +"封装类和客户端的 :code:`fixedclipping_mod` 使 :code:`FedAvg` " +"策略在客户端固定剪辑的情况下使用差分隐私:" #: ../../source/how-to-use-differential-privacy.rst:80 +#, fuzzy msgid "" "In addition to the server-side strategy wrapper, the :code:`ClientApp` " "needs to configure the matching :code:`fixedclipping_mod` to perform the " "client-side clipping:" msgstr "" +"除了服务器端策略包装器外,:code:`ClientApp` 还需要配置匹配的 " +":code:`fixedclipping_mod` 以执行客户端剪切:" #: ../../source/how-to-use-differential-privacy.rst:97 +#, fuzzy msgid "" "To utilize local differential privacy (DP) and add noise to the client " "model parameters before transmitting them to the server in Flower, you " "can use the `LocalDpMod`. The following hyperparameters need to be set: " "clipping norm value, sensitivity, epsilon, and delta." msgstr "" +"要利用本地差分隐私(DP)并在将客户端模型参数传输到 Flower " +"服务器之前为其添加噪声,可以使用 " +"`LocalDpMod`。需要设置以下超参数:剪切规范值、灵敏度、ε 和 delta。" #: ../../source/how-to-use-differential-privacy.rst:-1 +#, fuzzy msgid "local DP mod" -msgstr "" +msgstr "本地 DP 模式" #: ../../source/how-to-use-differential-privacy.rst:104 +#, fuzzy msgid "Below is a code example that shows how to use :code:`LocalDpMod`:" -msgstr "" +msgstr "下面的代码示例展示了如何使用 :code:`LocalDpMod`:" #: ../../source/how-to-use-differential-privacy.rst:122 +#, fuzzy msgid "" "Please note that the order of mods, especially those that modify " "parameters, is important when using multiple modifiers. Typically, " "differential privacy (DP) modifiers should be the last to operate on " "parameters." -msgstr "" +msgstr "请注意,在使用多个修改器时,修改器(尤其是修改参数的修改器)的顺序非常重要。" +"通常情况下,差分隐私 (DP) 修改器应最后对参数进行操作。" #: ../../source/how-to-use-differential-privacy.rst:125 +#, fuzzy msgid "Local Training using Privacy Engines" -msgstr "" +msgstr "使用隐私引擎进行本地培训" #: ../../source/how-to-use-differential-privacy.rst:126 +#, fuzzy msgid "" "For ensuring data instance-level privacy during local model training on " "the client side, consider leveraging privacy engines such as Opacus and " @@ -6621,6 +6975,11 @@ msgid "" " Privacy `_)." msgstr "" +"要在客户端本地模型训练期间确保数据实例级隐私,可考虑利用 Opacus 和 " +"TensorFlow Privacy 等隐私引擎。有关将 Flower 与这些引擎结合使用的示例," +"请参阅 Flower 示例目录(`Opacus `_, `Tensorflow Privacy `_)。" #: ../../source/how-to-use-strategies.rst:2 msgid "Use strategies" @@ -6884,12 +7243,14 @@ msgid "Information-oriented API reference and other reference material." msgstr "以信息为导向的 API 参考资料和其他参考资料。" #: ../../source/index.rst:132::1 +#, fuzzy msgid ":py:obj:`flwr `\\" -msgstr "" +msgstr ":py:obj:`flwr `\\" #: ../../source/index.rst:132::1 flwr:1 of +#, fuzzy msgid "Flower main package." -msgstr "" +msgstr "Flower 主包装。" #: ../../source/index.rst:149 msgid "Contributor docs" @@ -6933,28 +7294,32 @@ msgid "flwr" msgstr "Flower" #: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:52 +#, fuzzy msgid "Modules" -msgstr "" +msgstr "模块" #: ../../source/ref-api/flwr.rst:35::1 +#, fuzzy msgid ":py:obj:`flwr.client `\\" -msgstr "" +msgstr ":py:obj:`flwr.client `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.client:1 of msgid "Flower client." msgstr "Flower 客户端。" #: ../../source/ref-api/flwr.rst:35::1 +#, fuzzy msgid ":py:obj:`flwr.common `\\" -msgstr "" +msgstr ":py:obj:`flwr.common `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.common:1 of msgid "Common components shared between server and client." msgstr "服务器和客户端共享的通用组件。" #: ../../source/ref-api/flwr.rst:35::1 +#, fuzzy msgid ":py:obj:`flwr.server `\\" -msgstr "" +msgstr ":py:obj:`flwr.server `\\" #: ../../source/ref-api/flwr.rst:35::1 #: ../../source/ref-api/flwr.server.rst:41::1 flwr.server:1 @@ -6963,8 +7328,9 @@ msgid "Flower server." msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.rst:35::1 +#, fuzzy msgid ":py:obj:`flwr.simulation `\\" -msgstr "" +msgstr ":py:obj:`flwr.simulation `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.simulation:1 of #, fuzzy @@ -6984,8 +7350,9 @@ msgid "Functions" msgstr "四种函数:" #: ../../source/ref-api/flwr.client.rst:24::1 +#, fuzzy msgid ":py:obj:`run_client_app `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_client_app `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:24::1 #: flwr.client.app.run_client_app:1 of @@ -6994,10 +7361,13 @@ msgid "Run Flower client app." msgstr "Flower 客户端。" #: ../../source/ref-api/flwr.client.rst:24::1 +#, fuzzy msgid "" ":py:obj:`start_client `\\ \\(\\*\\, " "server\\_address\\[\\, client\\_fn\\, ...\\]\\)" msgstr "" +":py:obj:`start_client `\\ \\(\\*\\, " +"server\\_address\\[\\, client\\_fn\\, ...\\]\\)" #: ../../source/ref-api/flwr.client.rst:24::1 #: flwr.client.app.start_client:1 of @@ -7005,10 +7375,13 @@ msgid "Start a Flower client node which connects to a Flower server." msgstr "启动一个 Flower 客户节点,连接到 Flower 服务器。" #: ../../source/ref-api/flwr.client.rst:24::1 +#, fuzzy msgid "" ":py:obj:`start_numpy_client `\\ \\(\\*\\," " server\\_address\\, client\\)" msgstr "" +":py:obj:`start_numpy_client `\\ \\(\\*\\, " +"server\\_address\\, client\\)" #: ../../source/ref-api/flwr.client.rst:24::1 #: flwr.client.app.start_numpy_client:1 of @@ -7020,12 +7393,14 @@ msgstr "启动 Flower NumPyClient,连接到 gRPC 服务器。" #: ../../source/ref-api/flwr.server.rst:29 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 +#, fuzzy msgid "Classes" -msgstr "" +msgstr "类别" #: ../../source/ref-api/flwr.client.rst:33::1 +#, fuzzy msgid ":py:obj:`Client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`Client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:33::1 #: flwr.client.client.Client:1 of @@ -7033,10 +7408,12 @@ msgid "Abstract base class for Flower clients." msgstr "Flower 客户端的抽象基类。" #: ../../source/ref-api/flwr.client.rst:33::1 +#, fuzzy msgid "" ":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " "mods\\]\\)" msgstr "" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" #: ../../source/ref-api/flwr.client.rst:33::1 #: flwr.client.client_app.ClientApp:1 of @@ -7045,8 +7422,9 @@ msgid "Flower ClientApp." msgstr "Flower 客户端。" #: ../../source/ref-api/flwr.client.rst:33::1 +#, fuzzy msgid ":py:obj:`NumPyClient `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`NumPyClient `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:33::1 #: flwr.client.numpy_client.NumPyClient:1 of @@ -7056,8 +7434,9 @@ msgstr "使用 NumPy 的 Flower 客户端的抽象基类。" #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.strategy.strategy.Strategy:1 of +#, fuzzy msgid "Bases: :py:class:`~abc.ABC`" -msgstr "" +msgstr "Bases: :py:class:`~abc.ABC`" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 @@ -7122,12 +7501,14 @@ msgstr "" #: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:15 #: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:15 #: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:15 +#, fuzzy msgid "Methods" -msgstr "" +msgstr "方法" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`evaluate `\\ \\(ins\\)" -msgstr "" +msgstr ":py:obj:`evaluate `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7137,8 +7518,9 @@ msgid "Evaluate the provided parameters using the locally held dataset." msgstr "使用本地数据集评估所提供的参数。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`fit `\\ \\(ins\\)" -msgstr "" +msgstr ":py:obj:`fit `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.fit:1 of @@ -7146,8 +7528,9 @@ msgid "Refine the provided parameters using the locally held dataset." msgstr "利用本地数据集完善所提供的参数。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`get_context `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`get_context `\\ \\(\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7158,8 +7541,10 @@ msgid "Get the run context from this client." msgstr "评估客户端的反应。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`get_parameters `\\ \\(ins\\)" msgstr "" +":py:obj:`get_parameters `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7169,8 +7554,10 @@ msgid "Return the current local model parameters." msgstr "返回当前本地模型参数。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`get_properties `\\ \\(ins\\)" msgstr "" +":py:obj:`get_properties `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.get_properties:1 of @@ -7178,19 +7565,22 @@ msgid "Return set of client's properties." msgstr "返回客户端的属性集。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`set_context `\\ \\(context\\)" -msgstr "" +msgstr ":py:obj:`set_context `\\ \\(context\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.client.Client.set_context:1 #: flwr.client.numpy_client.NumPyClient.set_context:1 of +#, fuzzy msgid "Apply a run context to this client." -msgstr "" +msgstr "将运行上下文应用于该客户端。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 +#, fuzzy msgid ":py:obj:`to_client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`to_client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.to_client:1 of @@ -7225,12 +7615,14 @@ msgstr "返回客户端(本身)。" #: ../../source/ref-api/flwr.common.Status.rst:25 #: ../../source/ref-api/flwr.server.LegacyContext.rst:25 #: ../../source/ref-api/flwr.server.ServerConfig.rst:25 +#, fuzzy msgid "Attributes" -msgstr "" +msgstr "属性" #: flwr.client.client.Client.evaluate:1::1 of +#, fuzzy msgid ":py:obj:`context `\\" -msgstr "" +msgstr ":py:obj:`context `\\" #: ../../source/ref-api/flwr.common.Parameters.rst:2 #: flwr.client.app.start_client flwr.client.app.start_numpy_client @@ -7408,8 +7800,9 @@ msgstr "客户端" #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of +#, fuzzy msgid "Bases: :py:class:`object`" -msgstr "" +msgstr "Bases: :py:class:`object`" #: flwr.client.app.start_client:41 flwr.client.app.start_numpy_client:36 #: flwr.client.client_app.ClientApp:4 @@ -7427,41 +7820,52 @@ msgid "Examples" msgstr "实例" #: flwr.client.client_app.ClientApp:5 of +#, fuzzy msgid "" "Assuming a typical `Client` implementation named `FlowerClient`, you can " "wrap it in a `ClientApp` as follows:" -msgstr "" +msgstr "假定有一个名为 `FlowerClient` 的典型 `Client` 实现,可以将其封装在一个 " +"`ClientApp` 中,如下所示:" #: flwr.client.client_app.ClientApp:16 of +#, fuzzy msgid "" "If the above code is in a Python module called `client`, it can be " "started as follows:" -msgstr "" +msgstr "如果上述代码位于一个名为 \"客户端 \"的 Python " +"模块中,则可以按如下方式启动它:" #: flwr.client.client_app.ClientApp:21 of +#, fuzzy msgid "" "In this `client:app` example, `client` refers to the Python module " "`client.py` in which the previous code lives in and `app` refers to the " "global attribute `app` that points to an object of type `ClientApp`." msgstr "" +"在这个 `client:app` 例子中,`client` 指的是前面代码所在的 Python 模块 `client" +".py`,而 `app` 指的是指向 `ClientApp` 类型对象的全局属性 `app` 。" #: flwr.client.client_app.ClientApp.evaluate:1::1 of +#, fuzzy msgid ":py:obj:`evaluate `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`evaluate `\\ \\(\\)" #: flwr.client.client_app.ClientApp.evaluate:1 #: flwr.client.client_app.ClientApp.evaluate:1::1 of +#, fuzzy msgid "Return a decorator that registers the evaluate fn with the client app." -msgstr "" +msgstr "返回一个装饰器,用于向客户端程序注册评估 fn。" #: flwr.client.client_app.ClientApp.evaluate:1::1 of +#, fuzzy msgid ":py:obj:`query `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`query `\\ \\(\\)" #: flwr.client.client_app.ClientApp.evaluate:1::1 #: flwr.client.client_app.ClientApp.query:1 of +#, fuzzy msgid "Return a decorator that registers the query fn with the client app." -msgstr "" +msgstr "返回一个向客户端应用程序注册查询 fn 的装饰器。" #: flwr.client.client_app.ClientApp.evaluate:1::1 of #, fuzzy @@ -7470,22 +7874,28 @@ msgstr "server.strategy.Strategy" #: flwr.client.client_app.ClientApp.evaluate:1::1 #: flwr.client.client_app.ClientApp.train:1 of +#, fuzzy msgid "Return a decorator that registers the train fn with the client app." -msgstr "" +msgstr "返回一个装饰器,用于在客户端应用程序中注册火车 fn。" #: ../../source/ref-api/flwr.client.NumPyClient.rst:2 msgid "NumPyClient" msgstr "NumPyClient" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid "" ":py:obj:`evaluate `\\ \\(parameters\\, " "config\\)" msgstr "" +":py:obj:`evaluate `\\ \\(parameters\\, " +"config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" msgstr "" +":py:obj:`fit `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.fit:1 of @@ -7493,20 +7903,27 @@ msgid "Train the provided parameters using the locally held dataset." msgstr "使用本地数据集训练所提供的参数。" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid ":py:obj:`get_context `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`get_context `\\ \\(\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid "" ":py:obj:`get_parameters `\\ " "\\(config\\)" msgstr "" +":py:obj:`get_parameters `\\ \\(" +"config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid "" ":py:obj:`get_properties `\\ " "\\(config\\)" msgstr "" +":py:obj:`get_properties `\\ \\(" +"config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.get_properties:1 of @@ -7514,14 +7931,17 @@ msgid "Return a client's set of properties." msgstr "返回客户端的属性集。" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid "" ":py:obj:`set_context `\\ " "\\(context\\)" msgstr "" +":py:obj:`set_context `\\ \\(context\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 +#, fuzzy msgid ":py:obj:`to_client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`to_client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.to_client:1 of @@ -7529,8 +7949,9 @@ msgid "Convert to object to Client type and return it." msgstr "将对象转换为客户类型并返回。" #: flwr.client.numpy_client.NumPyClient.evaluate:1::1 of +#, fuzzy msgid ":py:obj:`context `\\" -msgstr "" +msgstr ":py:obj:`context `\\" #: flwr.client.numpy_client.NumPyClient.evaluate:3 #: flwr.client.numpy_client.NumPyClient.fit:3 @@ -7647,8 +8068,9 @@ msgstr "" "类型值的字典。它可用于将任意属性值传回服务器。" #: ../../source/ref-api/flwr.client.run_client_app.rst:2 +#, fuzzy msgid "run\\_client\\_app" -msgstr "" +msgstr "run\\_client\\_app" #: ../../source/ref-api/flwr.client.start_client.rst:2 #, fuzzy @@ -7695,10 +8117,13 @@ msgid "" msgstr "字节字符串或路径字符串形式的 PEM 编码根证书。如果提供,将使用这些证书与启用 SSL 的 Flower 服务器建立安全连接。" #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of +#, fuzzy msgid "" "Starts an insecure gRPC connection when True. Enables HTTPS connection " "when False, using system certificates if `root_certificates` is None." msgstr "" +"为 True 时启动不安全的 gRPC 连接。False 时启用 HTTPS 连接,如果 " +"`root_certificates` 为 None,则使用系统证书。" #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" @@ -7710,18 +8135,22 @@ msgstr "" "'rest': HTTP(实验性)" #: flwr.client.app.start_client:31 of +#, fuzzy msgid "" "The maximum number of times the client will try to connect to the server " "before giving up in case of a connection error. If set to None, there is " "no limit to the number of tries." -msgstr "" +msgstr "客户端在出现连接错误时放弃连接服务器的最大尝试次数。如果设置为 \"无\"" +",则不限制尝试次数。" #: flwr.client.app.start_client:35 of +#, fuzzy msgid "" "The maximum duration before the client stops trying to connect to the " "server in case of connection error. If set to None, there is no limit to " "the total time." -msgstr "" +msgstr "在出现连接错误时,客户端停止尝试连接服务器之前的最长持续时间。如果设置为 \"无" +"\",则总时间没有限制。" #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of msgid "Starting a gRPC client with an insecure server connection:" @@ -7743,12 +8172,16 @@ msgid "start\\_numpy\\_client" msgstr "start_numpy_client" #: flwr.client.app.start_numpy_client:5 of +#, fuzzy msgid "" "This function is deprecated since 1.7.0. Use " ":code:`flwr.client.start_client` instead and first convert your " ":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " ":code:`to_client()` method." msgstr "" +"自 1.7.0 起该函数已被弃用。请使用 :code:`flwr.client.start_client`," +"并首先通过执行 :code:`to_client()`方法将 :code:`NumPyClient`转换为 " +":code:`flwr.client.Client`。" #: flwr.client.app.start_numpy_client:13 of msgid "An implementation of the abstract base class `flwr.client.NumPyClient`." @@ -7759,8 +8192,10 @@ msgid "common" msgstr "常见" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" msgstr "" +":py:obj:`array_from_numpy `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.record.conversion_utils.array_from_numpy:1 of @@ -7769,8 +8204,10 @@ msgid "Create Array from NumPy ndarray." msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.bytes_to_ndarray:1 of @@ -7778,10 +8215,13 @@ msgid "Deserialize NumPy ndarray from bytes." msgstr "从字节反序列化 NumPy ndarray。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid "" ":py:obj:`configure `\\ \\(identifier\\[\\, " "filename\\, host\\]\\)" msgstr "" +":py:obj:`configure `\\ \\(identifier\\[\\, filename\\" +", host\\]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.logger.configure:1 of @@ -7789,21 +8229,28 @@ msgid "Configure logging to file and/or remote log server." msgstr "配置将日志记录到文件和/或远程日志服务器。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid "" ":py:obj:`event `\\ \\(event\\_type\\[\\, " "event\\_details\\]\\)" msgstr "" +":py:obj:`event `\\ \\(event\\_type\\[\\, event\\_details\\" +"]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.telemetry.event:1 of +#, fuzzy msgid "Submit create_event to ThreadPoolExecutor to avoid blocking." -msgstr "" +msgstr "将 create_event 提交给 ThreadPoolExecutor 以避免阻塞。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid "" ":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " "\\*\\*kwargs\\)" msgstr "" +":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, \\*\\*" +"kwargs\\)" #: ../../source/ref-api/flwr.common.rst:30::1 logging.Logger.log:1 #: of @@ -7811,8 +8258,10 @@ msgid "Log 'msg % args' with the integer severity 'level'." msgstr "以整数严重性 \"级别 \"记录 \"msg % args\"。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarray_to_bytes:1 of @@ -7820,8 +8269,9 @@ msgid "Serialize NumPy ndarray to bytes." msgstr "将 NumPy ndarray 序列化为字节。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid ":py:obj:`now `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`now `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.date.now:1 of @@ -7829,10 +8279,13 @@ msgid "Construct a datetime from time.time() with time zone set to UTC." msgstr "从 time.time() 生成日期时间,时区设置为 UTC。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid "" ":py:obj:`ndarrays_to_parameters `\\ " "\\(ndarrays\\)" msgstr "" +":py:obj:`ndarrays_to_parameters `\\ \\(" +"ndarrays\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarrays_to_parameters:1 @@ -7843,10 +8296,13 @@ msgid "Convert NumPy ndarrays to parameters object." msgstr "将 NumPy ndarrays 转换为参数对象。" #: ../../source/ref-api/flwr.common.rst:30::1 +#, fuzzy msgid "" ":py:obj:`parameters_to_ndarrays `\\ " "\\(parameters\\)" msgstr "" +":py:obj:`parameters_to_ndarrays `\\ \\(" +"parameters\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.parameters_to_ndarrays:1 of @@ -7854,10 +8310,12 @@ msgid "Convert parameters object to NumPy ndarrays." msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " "data\\)" msgstr "" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.Array:1 of @@ -7866,10 +8324,13 @@ msgid "Array type." msgstr "返回类型" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`ClientMessage `\\ " "\\(\\[get\\_properties\\_res\\, ...\\]\\)" msgstr "" +":py:obj:`ClientMessage `\\ \\(\\[get\\_properties" +"\\_res\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ClientMessage:1 of @@ -7877,8 +8338,9 @@ msgid "ClientMessage is a container used to hold one result message." msgstr "ClientMessage 是用于容纳一条结果信息的容器。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`Code `\\ \\(value\\)" -msgstr "" +msgstr ":py:obj:`Code `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Code:1 of @@ -7902,17 +8364,20 @@ msgid "Configs record." msgstr "配置日志记录" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`Context `\\ \\(state\\)" -msgstr "" +msgstr ":py:obj:`Context `\\ \\(state\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.context.Context:1 of +#, fuzzy msgid "State of your run." -msgstr "" +msgstr "您的运行状态。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`DisconnectRes `\\ \\(reason\\)" -msgstr "" +msgstr ":py:obj:`DisconnectRes `\\ \\(reason\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.DisconnectRes:1 of @@ -7920,10 +8385,12 @@ msgid "DisconnectRes message from client to server." msgstr "客户端向服务器发送 DisconnectRes 信息。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`EvaluateIns `\\ \\(parameters\\, " "config\\)" msgstr "" +":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.EvaluateIns:1 of @@ -7931,10 +8398,13 @@ msgid "Evaluate instructions for a client." msgstr "评估客户端的指示。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`EvaluateRes `\\ \\(status\\, loss\\, " "num\\_examples\\, metrics\\)" msgstr "" +":py:obj:`EvaluateRes `\\ \\(status\\, loss\\, " +"num\\_examples\\, metrics\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.EvaluateRes:1 of @@ -7942,8 +8412,9 @@ msgid "Evaluate response from a client." msgstr "评估客户端的反应。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`EventType `\\ \\(value\\)" -msgstr "" +msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.telemetry.EventType:1 of @@ -7951,8 +8422,9 @@ msgid "Types of telemetry events." msgstr "遥测事件类型。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`FitIns `\\ \\(parameters\\, config\\)" -msgstr "" +msgstr ":py:obj:`FitIns `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.FitIns:1 of @@ -7960,10 +8432,13 @@ msgid "Fit instructions for a client." msgstr "为客户提供安装说明。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`FitRes `\\ \\(status\\, parameters\\, " "num\\_examples\\, metrics\\)" msgstr "" +":py:obj:`FitRes `\\ \\(status\\, parameters\\, " +"num\\_examples\\, metrics\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.FitRes:1 of @@ -7971,17 +8446,21 @@ msgid "Fit response from a client." msgstr "来自客户端的合适回复。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`Error `\\ \\(code\\[\\, reason\\]\\)" -msgstr "" +msgstr ":py:obj:`Error `\\ \\(code\\[\\, reason\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Error:1 of +#, fuzzy msgid "A dataclass that stores information about an error that occurred." -msgstr "" +msgstr "数据类,用于存储所发生错误的相关信息。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" msgstr "" +":py:obj:`GetParametersIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetParametersIns:1 of @@ -7989,10 +8468,13 @@ msgid "Parameters request for a client." msgstr "客户端的参数请求。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`GetParametersRes `\\ \\(status\\, " "parameters\\)" msgstr "" +":py:obj:`GetParametersRes `\\ \\(status\\, " +"parameters\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetParametersRes:1 of @@ -8000,8 +8482,10 @@ msgid "Response when asked to return parameters." msgstr "要求返回参数时的响应。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" msgstr "" +":py:obj:`GetPropertiesIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetPropertiesIns:1 of @@ -8009,10 +8493,13 @@ msgid "Properties request for a client." msgstr "客户端的属性请求。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`GetPropertiesRes `\\ \\(status\\, " "properties\\)" msgstr "" +":py:obj:`GetPropertiesRes `\\ \\(status\\, " +"properties\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetPropertiesRes:1 of @@ -8020,71 +8507,94 @@ msgid "Properties response from a client." msgstr "来自客户端的属性响应。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`Message `\\ \\(metadata\\[\\, content\\, " "error\\]\\)" msgstr "" +":py:obj:`Message `\\ \\(metadata\\[\\, content\\, " +"error\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Message:1 of +#, fuzzy msgid "State of your application from the viewpoint of the entity using it." -msgstr "" +msgstr "从使用实体的角度看应用程序的状态。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`MessageType `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`MessageType `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.constant.MessageType:1 of +#, fuzzy msgid "Message type." -msgstr "" +msgstr "信息类型。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`MessageTypeLegacy `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`MessageTypeLegacy `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.constant.MessageTypeLegacy:1 of +#, fuzzy msgid "Legacy message type." -msgstr "" +msgstr "传统信息类型。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`Metadata `\\ \\(run\\_id\\, " "message\\_id\\, src\\_node\\_id\\, ...\\)" msgstr "" +":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " +"src\\_node\\_id\\, ...\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Metadata:1 of +#, fuzzy msgid "A dataclass holding metadata associated with the current message." -msgstr "" +msgstr "数据类型,包含与当前报文相关的元数据。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`MetricsRecord `\\ " "\\(\\[metrics\\_dict\\, keep\\_input\\]\\)" msgstr "" +":py:obj:`MetricsRecord `\\ \\(\\[metrics\\_dict\\" +", keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.metricsrecord.MetricsRecord:1 of +#, fuzzy msgid "Metrics record." -msgstr "" +msgstr "指标记录。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`NDArray `\\" -msgstr "" +msgstr ":py:obj:`NDArray `\\" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" "alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " ":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " +":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`Parameters `\\ \\(tensors\\, " "tensor\\_type\\)" msgstr "" +":py:obj:`Parameters `\\ \\(tensors\\, tensor\\_type\\" +")" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Parameters:1 of @@ -8092,10 +8602,13 @@ msgid "Model parameters." msgstr "模型参数。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`ParametersRecord `\\ " "\\(\\[array\\_dict\\, keep\\_input\\]\\)" msgstr "" +":py:obj:`ParametersRecord `\\ \\(\\[" +"array\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.ParametersRecord:1 of @@ -8104,8 +8617,9 @@ msgid "Parameters record." msgstr "参数" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`ReconnectIns `\\ \\(seconds\\)" -msgstr "" +msgstr ":py:obj:`ReconnectIns `\\ \\(seconds\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ReconnectIns:1 of @@ -8113,21 +8627,28 @@ msgid "ReconnectIns message from server to client." msgstr "服务器发送给客户端的重新连接信息。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`RecordSet `\\ " "\\(\\[parameters\\_records\\, ...\\]\\)" msgstr "" +":py:obj:`RecordSet `\\ \\(\\[parameters\\_records\\, " +"...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.recordset.RecordSet:1 of +#, fuzzy msgid "RecordSet stores groups of parameters, metrics and configs." -msgstr "" +msgstr "RecordSet 可存储参数、指标和配置组。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid "" ":py:obj:`ServerMessage `\\ " "\\(\\[get\\_properties\\_ins\\, ...\\]\\)" msgstr "" +":py:obj:`ServerMessage `\\ \\(\\[get\\_properties" +"\\_ins\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ServerMessage:1 of @@ -8135,8 +8656,9 @@ msgid "ServerMessage is a container used to hold one instruction message." msgstr "ServerMessage 是用于容纳一条指令信息的容器。" #: ../../source/ref-api/flwr.common.rst:64::1 +#, fuzzy msgid ":py:obj:`Status `\\ \\(code\\, message\\)" -msgstr "" +msgstr ":py:obj:`Status `\\ \\(code\\, message\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Status:1 of @@ -8144,37 +8666,45 @@ msgid "Client status." msgstr "客户端状态。" #: ../../source/ref-api/flwr.common.Array.rst:2 +#, fuzzy msgid "Array" -msgstr "" +msgstr "数组" #: flwr.common.record.parametersrecord.Array:3 of +#, fuzzy msgid "" "A dataclass containing serialized data from an array-like or tensor-like " "object along with some metadata about it." -msgstr "" +msgstr "数据类,包含数组类或张量类对象的序列化数据以及相关元数据。" #: flwr.common.record.parametersrecord.Array:6 of +#, fuzzy msgid "" "A string representing the data type of the serialised object (e.g. " "`np.float32`)" -msgstr "" +msgstr "表示序列化对象数据类型的字符串(例如 `np.float32`)" #: flwr.common.record.parametersrecord.Array:8 of +#, fuzzy msgid "" "A list representing the shape of the unserialized array-like object. This" " is used to deserialize the data (depending on the serialization method) " "or simply as a metadata field." -msgstr "" +msgstr "代表未序列化数组对象形状的列表。它可用于反序列化数据(取决于序列化方法),或" +"仅作为元数据字段使用。" #: flwr.common.record.parametersrecord.Array:12 of +#, fuzzy msgid "" "A string indicating the type of serialisation mechanism used to generate " "the bytes in `data` from an array-like or tensor-like object." -msgstr "" +msgstr "表示序列化机制类型的字符串,用于从类似数组或类似张量的对象中生成 `data` " +"中的字节。" #: flwr.common.record.parametersrecord.Array:15 of +#, fuzzy msgid "A buffer of bytes containing the data." -msgstr "" +msgstr "包含数据的字节缓冲区。" #: ../../source/ref-api/flwr.common.Array.rst:26::1 #, fuzzy @@ -8188,8 +8718,9 @@ msgid "Return the array as a NumPy array." msgstr "以 NumPy ndarrays 列表形式返回模型参数" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of +#, fuzzy msgid ":py:obj:`dtype `\\" -msgstr "" +msgstr ":py:obj:`dtype `\\" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of #, fuzzy @@ -8202,8 +8733,9 @@ msgid ":py:obj:`stype `\\" msgstr "server.strategy.Strategy" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of +#, fuzzy msgid ":py:obj:`data `\\" -msgstr "" +msgstr ":py:obj:`data `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:2 #, fuzzy @@ -8211,58 +8743,77 @@ msgid "ClientMessage" msgstr "客户端" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 +#, fuzzy msgid ":py:obj:`evaluate_res `\\" -msgstr "" +msgstr ":py:obj:`evaluate_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 +#, fuzzy msgid ":py:obj:`fit_res `\\" -msgstr "" +msgstr ":py:obj:`fit_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 +#, fuzzy msgid "" ":py:obj:`get_parameters_res " "`\\" msgstr "" +":py:obj:`get_parameters_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 +#, fuzzy msgid "" ":py:obj:`get_properties_res " "`\\" msgstr "" +":py:obj:`get_properties_res `\\" #: ../../source/ref-api/flwr.common.Code.rst:2 +#, fuzzy msgid "Code" -msgstr "" +msgstr "代码" #: flwr.common.typing.Code:1 of +#, fuzzy msgid "Bases: :py:class:`~enum.Enum`" -msgstr "" +msgstr "Bases: :py:class:`~enum.Enum`" #: ../../source/ref-api/flwr.common.Code.rst:26::1 +#, fuzzy msgid ":py:obj:`OK `\\" -msgstr "" +msgstr ":py:obj:`OK `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 +#, fuzzy msgid "" ":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " "`\\" msgstr "" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 +#, fuzzy msgid "" ":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " "`\\" msgstr "" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 +#, fuzzy msgid ":py:obj:`FIT_NOT_IMPLEMENTED `\\" -msgstr "" +msgstr ":py:obj:`FIT_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 +#, fuzzy msgid "" ":py:obj:`EVALUATE_NOT_IMPLEMENTED " "`\\" msgstr "" +":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:2 #, fuzzy @@ -8270,6 +8821,7 @@ msgid "ConfigsRecord" msgstr "配置日志记录" #: flwr.common.record.configsrecord.ConfigsRecord:1 of +#, fuzzy msgid "" "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " "[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " @@ -8279,77 +8831,101 @@ msgid "" ":py:class:`~typing.List`\\ [:py:class:`bytes`], " ":py:class:`~typing.List`\\ [:py:class:`bool`]]]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, " +":py:class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing." +"List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], " +":py:class:`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ " +"[:py:class:`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1 #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid "Remove all items from R." -msgstr "" +msgstr "从 R 中删除所有项目。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`count_bytes `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.configsrecord.ConfigsRecord.count_bytes:1 #: flwr.common.record.metricsrecord.MetricsRecord.count_bytes:1 #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:1 #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid "Return number of Bytes stored in this object." -msgstr "" +msgstr "返回存储在此对象中的字节数。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.get:1 of +#, fuzzy msgid "d defaults to None." -msgstr "" +msgstr "d 默认为 \"无\"。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of +#, fuzzy msgid "If key is not found, d is returned if given, otherwise KeyError is raised." -msgstr "" +msgstr "如果未找到 key,则返回 d(如果给定),否则引发 KeyError。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" +")" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.update:1 of +#, fuzzy msgid "Update R from dict/iterable E and F." -msgstr "" +msgstr "根据二进制/可迭代 E 和 F 更新 R。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`values `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`values `\\ \\(\\)" #: flwr.common.record.configsrecord.ConfigsRecord.count_bytes:3 of +#, fuzzy msgid "This function counts booleans as occupying 1 Byte." -msgstr "" +msgstr "该函数将布尔值计算为占用 1 个字节。" #: ../../source/ref-api/flwr.common.Context.rst:2 +#, fuzzy msgid "Context" -msgstr "" +msgstr "背景" #: flwr.common.context.Context:3 of +#, fuzzy msgid "" "Holds records added by the entity in a given run and that will stay " "local. This means that the data it holds will never leave the system it's" @@ -8358,6 +8934,9 @@ msgid "" "different points during the lifecycle of this entity (e.g. across " "multiple rounds)" msgstr "" +"保存实体在给定运行中添加的记录,这些记录将保留在本地。这意味着它保存的数据永" +"远不会离开运行的系统。在执行模式时,它可用作中间存储或抓取板。它还可以作为存" +"储器,在实体生命周期的不同阶段(如多轮)进行访问。" #: ../../source/ref-api/flwr.common.Context.rst:28::1 #, fuzzy @@ -8365,40 +8944,49 @@ msgid ":py:obj:`state `\\" msgstr "server.strategy.Strategy" #: ../../source/ref-api/flwr.common.DisconnectRes.rst:2 +#, fuzzy msgid "DisconnectRes" -msgstr "" +msgstr "断开Res" #: ../../source/ref-api/flwr.common.DisconnectRes.rst:28::1 +#, fuzzy msgid ":py:obj:`reason `\\" -msgstr "" +msgstr ":py:obj:`reason `\\" #: ../../source/ref-api/flwr.common.Error.rst:2 +#, fuzzy msgid "Error" -msgstr "" +msgstr "错误" #: flwr.common.message.Error:3 of +#, fuzzy msgid "An identifier for the error." -msgstr "" +msgstr "错误的标识符。" #: flwr.common.message.Error:5 of +#, fuzzy msgid "A reason for why the error arose (e.g. an exception stack-trace)" -msgstr "" +msgstr "出错原因(如异常堆栈跟踪)" #: flwr.common.Error.code:1::1 of +#, fuzzy msgid ":py:obj:`code `\\" -msgstr "" +msgstr ":py:obj:`code `\\" #: flwr.common.Error.code:1 flwr.common.Error.code:1::1 of +#, fuzzy msgid "Error code." -msgstr "" +msgstr "错误代码。" #: flwr.common.Error.code:1::1 of +#, fuzzy msgid ":py:obj:`reason `\\" -msgstr "" +msgstr ":py:obj:`reason `\\" #: flwr.common.Error.code:1::1 flwr.common.Error.reason:1 of +#, fuzzy msgid "Reason reported about the error." -msgstr "" +msgstr "报告的错误原因。" #: ../../source/ref-api/flwr.common.EvaluateIns.rst:2 #, fuzzy @@ -8406,32 +8994,39 @@ msgid "EvaluateIns" msgstr "说明" #: ../../source/ref-api/flwr.common.EvaluateIns.rst:29::1 +#, fuzzy msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.EvaluateIns.rst:29::1 +#, fuzzy msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:2 +#, fuzzy msgid "EvaluateRes" -msgstr "" +msgstr "评估Res" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 +#, fuzzy msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 +#, fuzzy msgid ":py:obj:`loss `\\" -msgstr "" +msgstr ":py:obj:`loss `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 +#, fuzzy msgid ":py:obj:`num_examples `\\" -msgstr "" +msgstr ":py:obj:`num_examples `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 +#, fuzzy msgid ":py:obj:`metrics `\\" -msgstr "" +msgstr ":py:obj:`metrics `\\" #: ../../source/ref-api/flwr.common.EventType.rst:2 #, fuzzy @@ -8439,148 +9034,198 @@ msgid "EventType" msgstr "返回类型" #: flwr.common.telemetry.EventType:1 of +#, fuzzy msgid "Bases: :py:class:`str`, :py:class:`~enum.Enum`" -msgstr "" +msgstr "Bases: :py:class:`str`, :py:class:`~enum.Enum`" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`PING `\\" -msgstr "" +msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_CLIENT_ENTER `\\" msgstr "" +":py:obj:`START_CLIENT_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" +":py:obj:`START_CLIENT_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_SERVER_ENTER `\\" msgstr "" +":py:obj:`START_SERVER_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_SERVER_LEAVE `\\" msgstr "" +":py:obj:`START_SERVER_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_DRIVER_API_ENTER " "`\\" msgstr "" +":py:obj:`RUN_DRIVER_API_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_DRIVER_API_LEAVE " "`\\" msgstr "" +":py:obj:`RUN_DRIVER_API_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_FLEET_API_ENTER " "`\\" msgstr "" +":py:obj:`RUN_FLEET_API_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_FLEET_API_LEAVE " "`\\" msgstr "" +":py:obj:`RUN_FLEET_API_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_SUPERLINK_ENTER " "`\\" msgstr "" +":py:obj:`RUN_SUPERLINK_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_SUPERLINK_LEAVE " "`\\" msgstr "" +":py:obj:`RUN_SUPERLINK_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`START_SIMULATION_ENTER " "`\\" msgstr "" +":py:obj:`START_SIMULATION_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`START_SIMULATION_LEAVE " "`\\" msgstr "" +":py:obj:`START_SIMULATION_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`DRIVER_CONNECT `\\" -msgstr "" +msgstr ":py:obj:`DRIVER_CONNECT `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`DRIVER_DISCONNECT `\\" -msgstr "" +msgstr ":py:obj:`DRIVER_DISCONNECT `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_DRIVER_ENTER `\\" msgstr "" +":py:obj:`START_DRIVER_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid ":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" +":py:obj:`START_DRIVER_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_CLIENT_APP_ENTER " "`\\" msgstr "" +":py:obj:`RUN_CLIENT_APP_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_CLIENT_APP_LEAVE " "`\\" msgstr "" +":py:obj:`RUN_CLIENT_APP_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_SERVER_APP_ENTER " "`\\" msgstr "" +":py:obj:`RUN_SERVER_APP_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#, fuzzy msgid "" ":py:obj:`RUN_SERVER_APP_LEAVE " "`\\" msgstr "" +":py:obj:`RUN_SERVER_APP_LEAVE `\\" #: ../../source/ref-api/flwr.common.FitIns.rst:2 +#, fuzzy msgid "FitIns" -msgstr "" +msgstr "FitIns" #: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +#, fuzzy msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +#, fuzzy msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:2 +#, fuzzy msgid "FitRes" -msgstr "" +msgstr "FitRes" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#, fuzzy msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#, fuzzy msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#, fuzzy msgid ":py:obj:`num_examples `\\" -msgstr "" +msgstr ":py:obj:`num_examples `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#, fuzzy msgid ":py:obj:`metrics `\\" -msgstr "" +msgstr ":py:obj:`metrics `\\" #: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 #, fuzzy @@ -8588,8 +9233,9 @@ msgid "GetParametersIns" msgstr "参数" #: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 +#, fuzzy msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 #, fuzzy @@ -8597,32 +9243,39 @@ msgid "GetParametersRes" msgstr "参数" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +#, fuzzy msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +#, fuzzy msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 +#, fuzzy msgid "GetPropertiesIns" -msgstr "" +msgstr "GetPropertiesIns" #: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 +#, fuzzy msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 +#, fuzzy msgid "GetPropertiesRes" -msgstr "" +msgstr "GetPropertiesRes" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +#, fuzzy msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +#, fuzzy msgid ":py:obj:`properties `\\" -msgstr "" +msgstr ":py:obj:`properties `\\" #: ../../source/ref-api/flwr.common.Message.rst:2 #, fuzzy @@ -8631,64 +9284,81 @@ msgstr "服务器端" #: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 #: flwr.common.message.Message:3 of +#, fuzzy msgid "A dataclass including information about the message to be executed." -msgstr "" +msgstr "数据类型,包括要执行的信息的相关信息。" #: flwr.common.message.Message:5 of +#, fuzzy msgid "" "Holds records either sent by another entity (e.g. sent by the server-side" " logic to a client, or vice-versa) or that will be sent to it." -msgstr "" +msgstr "保存由其他实体发送的记录(如由服务器端逻辑发送到客户端,反之亦然)或将发送到" +"该实体的记录。" #: flwr.common.message.Message:8 of +#, fuzzy msgid "" "A dataclass that captures information about an error that took place when" " processing another message." -msgstr "" +msgstr "数据类,用于捕捉处理其他报文时发生的错误信息。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 +#, fuzzy msgid "" ":py:obj:`create_error_reply `\\ " "\\(error\\, ttl\\)" msgstr "" +":py:obj:`create_error_reply `\\ \\(" +"error\\, ttl\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.create_error_reply:1 of +#, fuzzy msgid "Construct a reply message indicating an error happened." -msgstr "" +msgstr "构建一条回复信息,说明发生了错误。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 +#, fuzzy msgid "" ":py:obj:`create_reply `\\ \\(content\\," " ttl\\)" msgstr "" +":py:obj:`create_reply `\\ \\(content\\, " +"ttl\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.create_reply:1 of +#, fuzzy msgid "Create a reply to this message with specified content and TTL." -msgstr "" +msgstr "以指定的内容和 TTL 创建对该信息的回复。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 +#, fuzzy msgid ":py:obj:`has_content `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`has_content `\\ \\(\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.has_content:1 of +#, fuzzy msgid "Return True if message has content, else False." -msgstr "" +msgstr "如果信息有内容,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 +#, fuzzy msgid ":py:obj:`has_error `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`has_error `\\ \\(\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.has_error:1 of +#, fuzzy msgid "Return True if message has an error, else False." -msgstr "" +msgstr "如果信息有错误,则返回 True,否则返回 False。" #: flwr.common.Message.content:1::1 of +#, fuzzy msgid ":py:obj:`content `\\" -msgstr "" +msgstr ":py:obj:`content `\\" #: flwr.common.Message.content:1 flwr.common.Message.content:1::1 #: of @@ -8697,42 +9367,53 @@ msgid "The content of this message." msgstr "评估客户端的反应。" #: flwr.common.Message.content:1::1 of +#, fuzzy msgid ":py:obj:`error `\\" -msgstr "" +msgstr ":py:obj:`error `\\" #: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of +#, fuzzy msgid "Error captured by this message." -msgstr "" +msgstr "该信息捕捉到的错误。" #: flwr.common.Message.content:1::1 of +#, fuzzy msgid ":py:obj:`metadata `\\" -msgstr "" +msgstr ":py:obj:`metadata `\\" #: flwr.common.message.Message.create_error_reply:3 of +#, fuzzy msgid "The error that was encountered." -msgstr "" +msgstr "遇到的错误。" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.ttl:1 flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 flwr.common.message.Metadata:16 #: of +#, fuzzy msgid "Time-to-live for this message." -msgstr "" +msgstr "该信息的有效时间。" #: flwr.common.message.Message.create_reply:3 of +#, fuzzy msgid "" "The method generates a new `Message` as a reply to this message. It " "inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " "this message and sets 'reply_to_message' to the ID of this message." msgstr "" +"该方法会生成一条新的 \"信息\",作为对该信息的回复。该方法继承了该消息的 " +"\"run_id\"、\"src_node_id\"、\"dst_node_id \"和 \"message_type\",并将 " +"\"reply_to_message \"设置为该消息的 ID。" #: flwr.common.message.Message.create_reply:7 of +#, fuzzy msgid "The content for the reply message." -msgstr "" +msgstr "回复信息的内容。" #: flwr.common.message.Message.create_reply:12 of +#, fuzzy msgid "A new `Message` instance representing the reply." -msgstr "" +msgstr "代表回复的新的 `Message` 实例。" #: ../../source/ref-api/flwr.common.MessageType.rst:2 #, fuzzy @@ -8740,176 +9421,223 @@ msgid "MessageType" msgstr "返回类型" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#, fuzzy msgid ":py:obj:`EVALUATE `\\" -msgstr "" +msgstr ":py:obj:`EVALUATE `\\" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#, fuzzy msgid ":py:obj:`QUERY `\\" -msgstr "" +msgstr ":py:obj:`QUERY `\\" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#, fuzzy msgid ":py:obj:`TRAIN `\\" -msgstr "" +msgstr ":py:obj:`TRAIN `\\" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 +#, fuzzy msgid "MessageTypeLegacy" -msgstr "" +msgstr "MessageTypeLegacy" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#, fuzzy msgid ":py:obj:`GET_PARAMETERS `\\" msgstr "" +":py:obj:`GET_PARAMETERS `\\" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#, fuzzy msgid ":py:obj:`GET_PROPERTIES `\\" msgstr "" +":py:obj:`GET_PROPERTIES `\\" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of +#, fuzzy msgid "An identifier for the current run." -msgstr "" +msgstr "当前运行的标识符。" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of +#, fuzzy msgid "An identifier for the current message." -msgstr "" +msgstr "当前信息的标识符。" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of +#, fuzzy msgid "An identifier for the node sending this message." -msgstr "" +msgstr "发送此信息的节点的标识符。" #: flwr.common.Metadata.dst_node_id:1 #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.message.Metadata:9 of +#, fuzzy msgid "An identifier for the node receiving this message." -msgstr "" +msgstr "接收此信息的节点的标识符。" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of +#, fuzzy msgid "An identifier for the message this message replies to." -msgstr "" +msgstr "该信息回复的信息的标识符。" #: flwr.common.message.Metadata:13 of +#, fuzzy msgid "" "An identifier for grouping messages. In some settings, this is used as " "the FL round." -msgstr "" +msgstr "用于分组报文的标识符。在某些设置中,它被用作 FL 轮。" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of +#, fuzzy msgid "A string that encodes the action to be executed on the receiving end." -msgstr "" +msgstr "编码接收端要执行的操作的字符串。" #: flwr.common.message.Metadata:21 of +#, fuzzy msgid "" "An identifier that can be used when loading a particular data partition " "for a ClientApp. Making use of this identifier is more relevant when " "conducting simulations." -msgstr "" +msgstr "为 ClientApp " +"加载特定数据分区时可使用的标识符。在进行模拟时,使用该标识符更有意义。" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`dst_node_id `\\" -msgstr "" +msgstr ":py:obj:`dst_node_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`group_id `\\" -msgstr "" +msgstr ":py:obj:`group_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.group_id:1 of +#, fuzzy msgid "An identifier for grouping messages." -msgstr "" +msgstr "用于分组信息的标识符。" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`message_id `\\" -msgstr "" +msgstr ":py:obj:`message_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`message_type `\\" -msgstr "" +msgstr ":py:obj:`message_type `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`partition_id `\\" -msgstr "" +msgstr ":py:obj:`partition_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 #: flwr.common.Metadata.partition_id:1 of +#, fuzzy msgid "An identifier telling which data partition a ClientApp should use." -msgstr "" +msgstr "告诉 ClientApp 应使用哪个数据分区的标识符。" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`reply_to_message `\\" -msgstr "" +msgstr ":py:obj:`reply_to_message `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`run_id `\\" -msgstr "" +msgstr ":py:obj:`run_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`src_node_id `\\" -msgstr "" +msgstr ":py:obj:`src_node_id `\\" #: flwr.common.Metadata.dst_node_id:1::1 of +#, fuzzy msgid ":py:obj:`ttl `\\" -msgstr "" +msgstr ":py:obj:`ttl `\\" #: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 +#, fuzzy msgid "MetricsRecord" -msgstr "" +msgstr "MetricsRecord" #: flwr.common.record.metricsrecord.MetricsRecord:1 of +#, fuzzy msgid "" "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " "[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " ":py:class:`float`, :py:class:`~typing.List`\\ [:py:class:`int`], " ":py:class:`~typing.List`\\ [:py:class:`float`]]]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, " +":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " +"[:py:class:`float`]]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`count_bytes `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" +")" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`values `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`values `\\ \\(\\)" #: ../../source/ref-api/flwr.common.NDArray.rst:2 +#, fuzzy msgid "NDArray" -msgstr "" +msgstr "NDArray" #: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +#, fuzzy msgid ":py:obj:`tensors `\\" -msgstr "" +msgstr ":py:obj:`tensors `\\" #: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +#, fuzzy msgid ":py:obj:`tensor_type `\\" -msgstr "" +msgstr ":py:obj:`tensor_type `\\" #: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 #, fuzzy @@ -8917,59 +9645,79 @@ msgid "ParametersRecord" msgstr "参数" #: flwr.common.record.parametersrecord.ParametersRecord:1 of +#, fuzzy msgid "" "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " "[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:class:`~flwr.common.record.parametersrecord.Array`]" #: flwr.common.record.parametersrecord.ParametersRecord:3 of +#, fuzzy msgid "" "A dataclass storing named Arrays in order. This means that it holds " "entries as an OrderedDict[str, Array]. ParametersRecord objects can be " "viewed as an equivalent to PyTorch's state_dict, but holding serialised " "tensors instead." msgstr "" +"按顺序存储命名数组的数据类。这意味着它以 OrderedDict[str, Array] " +"的形式保存条目。ParametersRecord 对象相当于 PyTorch 的 " +"state_dict,但它保存的是序列化的张量。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" +":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*" +"F\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#, fuzzy msgid ":py:obj:`values `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`values `\\ \\(\\)" #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of +#, fuzzy msgid "" "Note that a small amount of Bytes might also be included in this counting" " that correspond to metadata of the serialized object (e.g. of NumPy " "array) needed for deseralization." -msgstr "" +msgstr "请注意,该计数中还可能包含少量字节,这些字节与序列化对象(如 NumPy " +"数组)的元数据相对应,需要进行去eralization。" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 #, fuzzy @@ -8977,39 +9725,48 @@ msgid "ReconnectIns" msgstr "启用 SSL 连接" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 +#, fuzzy msgid ":py:obj:`seconds `\\" -msgstr "" +msgstr ":py:obj:`seconds `\\" #: ../../source/ref-api/flwr.common.RecordSet.rst:2 +#, fuzzy msgid "RecordSet" -msgstr "" +msgstr "RecordSet" #: flwr.common.RecordSet.configs_records:1::1 of +#, fuzzy msgid ":py:obj:`configs_records `\\" -msgstr "" +msgstr ":py:obj:`configs_records `\\" #: flwr.common.RecordSet.configs_records:1 #: flwr.common.RecordSet.configs_records:1::1 of +#, fuzzy msgid "Dictionary holding ConfigsRecord instances." -msgstr "" +msgstr "包含 ConfigsRecord 实例的字典。" #: flwr.common.RecordSet.configs_records:1::1 of +#, fuzzy msgid ":py:obj:`metrics_records `\\" -msgstr "" +msgstr ":py:obj:`metrics_records `\\" #: flwr.common.RecordSet.configs_records:1::1 #: flwr.common.RecordSet.metrics_records:1 of +#, fuzzy msgid "Dictionary holding MetricsRecord instances." -msgstr "" +msgstr "保存 MetricsRecord 实例的字典。" #: flwr.common.RecordSet.configs_records:1::1 of +#, fuzzy msgid ":py:obj:`parameters_records `\\" msgstr "" +":py:obj:`parameters_records `\\" #: flwr.common.RecordSet.configs_records:1::1 #: flwr.common.RecordSet.parameters_records:1 of +#, fuzzy msgid "Dictionary holding ParametersRecord instances." -msgstr "" +msgstr "存放 ParametersRecord 实例的字典。" #: ../../source/ref-api/flwr.common.ServerMessage.rst:2 #, fuzzy @@ -9017,24 +9774,30 @@ msgid "ServerMessage" msgstr "服务器端" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#, fuzzy msgid ":py:obj:`evaluate_ins `\\" -msgstr "" +msgstr ":py:obj:`evaluate_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#, fuzzy msgid ":py:obj:`fit_ins `\\" -msgstr "" +msgstr ":py:obj:`fit_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#, fuzzy msgid "" ":py:obj:`get_parameters_ins " "`\\" msgstr "" +":py:obj:`get_parameters_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#, fuzzy msgid "" ":py:obj:`get_properties_ins " "`\\" msgstr "" +":py:obj:`get_properties_ins `\\" #: ../../source/ref-api/flwr.common.Status.rst:2 #, fuzzy @@ -9042,20 +9805,24 @@ msgid "Status" msgstr "客户端状态。" #: ../../source/ref-api/flwr.common.Status.rst:29::1 +#, fuzzy msgid ":py:obj:`code `\\" -msgstr "" +msgstr ":py:obj:`code `\\" #: ../../source/ref-api/flwr.common.Status.rst:29::1 +#, fuzzy msgid ":py:obj:`message `\\" -msgstr "" +msgstr ":py:obj:`message `\\" #: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 +#, fuzzy msgid "array\\_from\\_numpy" -msgstr "" +msgstr "array\\_from\\_numpy" #: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 +#, fuzzy msgid "bytes\\_to\\_ndarray" -msgstr "" +msgstr "bytes\\_to\\_ndarray" #: ../../source/ref-api/flwr.common.configure.rst:2 #, fuzzy @@ -9063,12 +9830,14 @@ msgid "configure" msgstr "配置日志记录" #: ../../source/ref-api/flwr.common.event.rst:2 +#, fuzzy msgid "event" -msgstr "" +msgstr "事件" #: ../../source/ref-api/flwr.common.log.rst:2 +#, fuzzy msgid "log" -msgstr "" +msgstr "登录" #: logging.Logger.log:3 of msgid "" @@ -9082,28 +9851,33 @@ msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" msgstr "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" #: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 +#, fuzzy msgid "ndarray\\_to\\_bytes" -msgstr "" +msgstr "ndarray\\_to\\_bytes" #: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 +#, fuzzy msgid "ndarrays\\_to\\_parameters" -msgstr "" +msgstr "ndarrays\\_to\\_parameters" #: ../../source/ref-api/flwr.common.now.rst:2 +#, fuzzy msgid "now" -msgstr "" +msgstr "现在" #: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 +#, fuzzy msgid "parameters\\_to\\_ndarrays" -msgstr "" +msgstr "parameters\\_to\\_ndarrays" #: ../../source/ref-api/flwr.server.rst:2 msgid "server" msgstr "服务器" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid ":py:obj:`run_driver_api `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_driver_api `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.app.run_driver_api:1 of @@ -9112,8 +9886,9 @@ msgid "Run Flower server (Driver API)." msgstr "flower-driver-api" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_fleet_api `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.app.run_fleet_api:1 of @@ -9122,8 +9897,9 @@ msgid "Run Flower server (Fleet API)." msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid ":py:obj:`run_server_app `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_server_app `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.run_serverapp.run_server_app:1 of @@ -9132,19 +9908,24 @@ msgid "Run Flower server app." msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid ":py:obj:`run_superlink `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_superlink `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.app.run_superlink:1 of +#, fuzzy msgid "Run Flower server (Driver API and Fleet API)." -msgstr "" +msgstr "运行 Flower 服务器(Driver API 和 Fleet API)。" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid "" ":py:obj:`start_driver `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" msgstr "" +":py:obj:`start_driver `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.compat.app.start_driver:1 of @@ -9153,10 +9934,13 @@ msgid "Start a Flower Driver API server." msgstr "启动基于 Ray 的Flower模拟服务器。" #: ../../source/ref-api/flwr.server.rst:27::1 +#, fuzzy msgid "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" msgstr "" +":py:obj:`start_server `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.rst:27::1 #: flwr.server.app.start_server:1 of @@ -9164,8 +9948,9 @@ msgid "Start a Flower server using the gRPC transport layer." msgstr "使用 gRPC 传输层启动 Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:41::1 +#, fuzzy msgid ":py:obj:`ClientManager `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`ClientManager `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.client_manager.ClientManager:1 of @@ -9185,12 +9970,14 @@ msgstr "" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.driver.driver.Driver:1 of +#, fuzzy msgid "`Driver` class provides an interface to the Driver API." -msgstr "" +msgstr "`Driver` 类为驱动程序 API 提供了一个接口。" #: ../../source/ref-api/flwr.server.rst:41::1 +#, fuzzy msgid ":py:obj:`History `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`History `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.history.History:1 of @@ -9199,21 +9986,28 @@ msgid "History class for training and/or evaluation metrics collection." msgstr "**hist** -- 包含训练和评估指标的对象。" #: ../../source/ref-api/flwr.server.rst:41::1 +#, fuzzy msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" msgstr "" +":py:obj:`LegacyContext `\\ \\(state\\[\\, config\\" +", strategy\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of +#, fuzzy msgid "Legacy Context." -msgstr "" +msgstr "传承背景。" #: ../../source/ref-api/flwr.server.rst:41::1 +#, fuzzy msgid "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " "strategy\\]\\)" msgstr "" +":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " +"strategy\\]\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #, fuzzy @@ -9245,8 +10039,10 @@ msgid "Flower server config." msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:41::1 +#, fuzzy msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" +":py:obj:`SimpleClientManager `\\ \\(\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.client_manager.SimpleClientManager:1 of @@ -9281,19 +10077,23 @@ msgid "ClientManager" msgstr "客户端" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid ":py:obj:`all `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`all `\\ \\(\\)" #: flwr.server.client_manager.ClientManager.all:1 #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.SimpleClientManager.all:1 #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "Return all available clients." -msgstr "" +msgstr "返回所有可用客户。" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid ":py:obj:`num_available `\\ \\(\\)" msgstr "" +":py:obj:`num_available `\\ \\(\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.num_available:1 @@ -9304,70 +10104,87 @@ msgid "Return the number of available clients." msgstr "返回样本大小和所需的可用客户数量。" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid ":py:obj:`register `\\ \\(client\\)" -msgstr "" +msgstr ":py:obj:`register `\\ \\(client\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.register:1 #: flwr.server.client_manager.SimpleClientManager.all:1::1 #: flwr.server.client_manager.SimpleClientManager.register:1 of +#, fuzzy msgid "Register Flower ClientProxy instance." -msgstr "" +msgstr "注册 Flower ClientProxy 实例。" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`sample `\\ " "\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" +":py:obj:`sample `\\ \\(num\\_clients\\[\\, " +"min\\_num\\_clients\\, criterion\\]\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.sample:1 #: flwr.server.client_manager.SimpleClientManager.all:1::1 #: flwr.server.client_manager.SimpleClientManager.sample:1 of +#, fuzzy msgid "Sample a number of Flower ClientProxy instances." -msgstr "" +msgstr "取样若干 Flower ClientProxy 实例。" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid ":py:obj:`unregister `\\ \\(client\\)" msgstr "" +":py:obj:`unregister `\\ \\(client\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.unregister:1 #: flwr.server.client_manager.SimpleClientManager.all:1::1 #: flwr.server.client_manager.SimpleClientManager.unregister:1 of +#, fuzzy msgid "Unregister Flower ClientProxy instance." -msgstr "" +msgstr "取消注册 Flower ClientProxy 实例。" #: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`wait_for `\\ " "\\(num\\_clients\\, timeout\\)" msgstr "" +":py:obj:`wait_for `\\ \\(num\\_clients\\" +", timeout\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.wait_for:1 #: flwr.server.client_manager.SimpleClientManager.all:1::1 #: flwr.server.client_manager.SimpleClientManager.wait_for:1 of +#, fuzzy msgid "Wait until at least `num_clients` are available." -msgstr "" +msgstr "等待至少 `num_clients` 可用。" #: flwr.server.client_manager.ClientManager.num_available:3 #: flwr.server.client_manager.SimpleClientManager.num_available:3 of +#, fuzzy msgid "**num_available** -- The number of currently available clients." -msgstr "" +msgstr "**num_available** -- 当前可用客户端的数量。" #: flwr.server.client_manager.ClientManager.register:6 #: flwr.server.client_manager.SimpleClientManager.register:6 of +#, fuzzy msgid "" "**success** -- Indicating if registration was successful. False if " "ClientProxy is already registered or can not be registered for any " "reason." -msgstr "" +msgstr "**success** -- 表示注册是否成功。如果 ClientProxy 已注册或因故无法注册,则为 " +"False。" #: flwr.server.client_manager.ClientManager.unregister:3 #: flwr.server.client_manager.SimpleClientManager.unregister:3 of +#, fuzzy msgid "This method is idempotent." -msgstr "" +msgstr "这种方法是幂等的。" #: ../../source/ref-api/flwr.server.Driver.rst:2 #, fuzzy @@ -9417,50 +10234,64 @@ msgstr "server.strategy.Strategy" #: flwr.server.driver.driver.Driver.close:1 #: flwr.server.driver.driver.Driver.close:1::1 of +#, fuzzy msgid "Disconnect from the SuperLink if connected." -msgstr "" +msgstr "如果已连接,请断开与超级链接的连接。" #: flwr.server.driver.driver.Driver.close:1::1 of +#, fuzzy msgid "" ":py:obj:`create_message `\\ " "\\(content\\, message\\_type\\, ...\\)" msgstr "" +":py:obj:`create_message `\\ \\(content\\, " +"message\\_type\\, ...\\)" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.create_message:1 of +#, fuzzy msgid "Create a new message with specified parameters." -msgstr "" +msgstr "使用指定参数创建新信息。" #: flwr.server.driver.driver.Driver.close:1::1 of +#, fuzzy msgid ":py:obj:`get_node_ids `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`get_node_ids `\\ \\(\\)" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.get_node_ids:1 of +#, fuzzy msgid "Get node IDs." -msgstr "" +msgstr "获取节点 ID。" #: flwr.server.driver.driver.Driver.close:1::1 of +#, fuzzy msgid "" ":py:obj:`pull_messages `\\ " "\\(message\\_ids\\)" msgstr "" +":py:obj:`pull_messages `\\ \\(message\\_ids" +"\\)" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.pull_messages:1 of +#, fuzzy msgid "Pull messages based on message IDs." -msgstr "" +msgstr "根据信息 ID 提取信息。" #: flwr.server.driver.driver.Driver.close:1::1 of +#, fuzzy msgid "" ":py:obj:`push_messages `\\ " "\\(messages\\)" msgstr "" +":py:obj:`push_messages `\\ \\(messages\\)" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.push_messages:1 of +#, fuzzy msgid "Push messages to specified node IDs." -msgstr "" +msgstr "向指定的节点 ID 推送信息。" #: flwr.server.driver.driver.Driver.close:1::1 of #, fuzzy @@ -9474,98 +10305,119 @@ msgstr "" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.send_and_receive:1 of +#, fuzzy msgid "Push messages to specified node IDs and pull the reply messages." -msgstr "" +msgstr "向指定的节点 ID 推送信息并提取回复信息。" #: flwr.server.driver.driver.Driver.create_message:3 of +#, fuzzy msgid "" "This method constructs a new `Message` with given content and metadata. " "The `run_id` and `src_node_id` will be set automatically." -msgstr "" +msgstr "本方法使用给定的内容和元数据构建新的 `Message` 。run_id \"和 \"src_node_id " +"\"将自动设置。" #: flwr.server.driver.driver.Driver.create_message:6 of +#, fuzzy msgid "" "The content for the new message. This holds records that are to be sent " "to the destination node." -msgstr "" +msgstr "新信息的内容。其中包含要发送到目的节点的记录。" #: flwr.server.driver.driver.Driver.create_message:9 of +#, fuzzy msgid "" "The type of the message, defining the action to be executed on the " "receiving end." -msgstr "" +msgstr "信息类型,定义接收端要执行的操作。" #: flwr.server.driver.driver.Driver.create_message:12 of +#, fuzzy msgid "The ID of the destination node to which the message is being sent." -msgstr "" +msgstr "信息发送目的地节点的 ID。" #: flwr.server.driver.driver.Driver.create_message:14 of +#, fuzzy msgid "" "The ID of the group to which this message is associated. In some " "settings, this is used as the FL round." -msgstr "" +msgstr "与该信息相关联的组的 ID。在某些设置中,它被用作 FL 轮。" #: flwr.server.driver.driver.Driver.create_message:17 of +#, fuzzy msgid "" "Time-to-live for the round trip of this message, i.e., the time from " "sending this message to receiving a reply. It specifies the duration for " "which the message and its potential reply are considered valid." -msgstr "" +msgstr "此报文往返的有效时间,即从发送此报文到收到回复的时间。它规定了信息及其潜在回" +"复被视为有效的持续时间。" #: flwr.server.driver.driver.Driver.create_message:22 of +#, fuzzy msgid "" "**message** -- A new `Message` instance with the specified content and " "metadata." -msgstr "" +msgstr "**message** -- 具有指定内容和元数据的新 \"信息 \"实例。" #: flwr.server.driver.driver.Driver.pull_messages:3 of +#, fuzzy msgid "" "This method is used to collect messages from the SuperLink that " "correspond to a set of given message IDs." -msgstr "" +msgstr "该方法用于从超级链接中收集与一组给定消息 ID 相对应的消息。" #: flwr.server.driver.driver.Driver.pull_messages:6 of +#, fuzzy msgid "An iterable of message IDs for which reply messages are to be retrieved." -msgstr "" +msgstr "要检索回复信息的信息 ID 的可迭代项。" #: flwr.server.driver.driver.Driver.pull_messages:9 of +#, fuzzy msgid "**messages** -- An iterable of messages received." -msgstr "" +msgstr "**messages** -- 收到的信息迭代。" #: flwr.server.driver.driver.Driver.push_messages:3 of +#, fuzzy msgid "" "This method takes an iterable of messages and sends each message to the " "node specified in `dst_node_id`." -msgstr "" +msgstr "该方法接收一个可迭代的消息,并将每条消息发送到 `dst_node_id` 中指定的节点。" #: flwr.server.driver.driver.Driver.push_messages:6 #: flwr.server.driver.driver.Driver.send_and_receive:7 of +#, fuzzy msgid "An iterable of messages to be sent." -msgstr "" +msgstr "要发送的信息迭代。" #: flwr.server.driver.driver.Driver.push_messages:9 of +#, fuzzy msgid "" "**message_ids** -- An iterable of IDs for the messages that were sent, " "which can be used to pull replies." -msgstr "" +msgstr "**message_ids** -- 已发送信息的可迭代 ID,可用于提取回复信息。" #: flwr.server.driver.driver.Driver.send_and_receive:3 of +#, fuzzy msgid "" "This method sends a list of messages to their destination node IDs and " "then waits for the replies. It continues to pull replies until either all" " replies are received or the specified timeout duration is exceeded." -msgstr "" +msgstr "该方法会向目标节点 ID 发送信息列表,然后等待回复。它会继续提取回复,直到收到" +"所有回复或超过指定的超时时间。" #: flwr.server.driver.driver.Driver.send_and_receive:9 of +#, fuzzy msgid "" "The timeout duration in seconds. If specified, the method will wait for " "replies for this duration. If `None`, there is no time limit and the " "method will wait until replies for all messages are received." -msgstr "" +msgstr "超时时间(秒)。如果指定,该方法将在此期限内等待回复。如果指定为 \"无\"" +",则没有时间限制,该方法将等待直到收到所有信息的回复。" #: flwr.server.driver.driver.Driver.send_and_receive:14 of +#, fuzzy msgid "**replies** -- An iterable of reply messages received from the SuperLink." -msgstr "" +msgstr "**replies** -- 从超级链接收到的回复信息的迭代。" #: flwr.server.driver.driver.Driver.send_and_receive:18 #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 @@ -9576,23 +10428,31 @@ msgid "Notes" msgstr "无" #: flwr.server.driver.driver.Driver.send_and_receive:19 of +#, fuzzy msgid "" "This method uses `push_messages` to send the messages and `pull_messages`" " to collect the replies. If `timeout` is set, the method may not return " "replies for all sent messages. A message remains valid until its TTL, " "which is not affected by `timeout`." msgstr "" +"该方法使用 `push_messages` 发送信息,并使用 `pull_messages` 收集回复。" +"如果设置了 `timeout`,该方法可能不会返回所有已发送消息的回复。消息在其 TTL " +"之前一直有效,不受 `timeout` 影响。" #: ../../source/ref-api/flwr.server.History.rst:2 +#, fuzzy msgid "History" -msgstr "" +msgstr "历史" #: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy msgid "" ":py:obj:`add_loss_centralized " "`\\ \\(server\\_round\\, " "loss\\)" msgstr "" +":py:obj:`add_loss_centralized `\\ " +"\\(server\\_round\\, loss\\)" #: flwr.server.history.History.add_loss_centralized:1 #: flwr.server.history.History.add_loss_centralized:1::1 of @@ -9601,23 +10461,30 @@ msgid "Add one loss entry (from centralized evaluation)." msgstr "集中评估" #: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy msgid "" ":py:obj:`add_loss_distributed " "`\\ \\(server\\_round\\, " "loss\\)" msgstr "" +":py:obj:`add_loss_distributed `\\ " +"\\(server\\_round\\, loss\\)" #: flwr.server.history.History.add_loss_centralized:1::1 #: flwr.server.history.History.add_loss_distributed:1 of +#, fuzzy msgid "Add one loss entry (from distributed evaluation)." -msgstr "" +msgstr "增加一个损失条目(来自分布式评估)。" #: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy msgid "" ":py:obj:`add_metrics_centralized " "`\\ \\(server\\_round\\, " "metrics\\)" msgstr "" +":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" #: flwr.server.history.History.add_loss_centralized:1::1 #: flwr.server.history.History.add_metrics_centralized:1 of @@ -9626,11 +10493,14 @@ msgid "Add metrics entries (from centralized evaluation)." msgstr "集中评估" #: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy msgid "" ":py:obj:`add_metrics_distributed " "`\\ \\(server\\_round\\, " "metrics\\)" msgstr "" +":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" #: flwr.server.history.History.add_loss_centralized:1::1 #: flwr.server.history.History.add_metrics_distributed:1 of @@ -9639,24 +10509,30 @@ msgid "Add metrics entries (from distributed evaluation)." msgstr "定制的集中/分布式评估" #: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy msgid "" ":py:obj:`add_metrics_distributed_fit " "`\\ \\(server\\_round\\," " ...\\)" msgstr "" +":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" #: flwr.server.history.History.add_loss_centralized:1::1 #: flwr.server.history.History.add_metrics_distributed_fit:1 of +#, fuzzy msgid "Add metrics entries (from distributed fit)." -msgstr "" +msgstr "添加度量条目(来自分布式拟合)。" #: ../../source/ref-api/flwr.server.LegacyContext.rst:2 +#, fuzzy msgid "LegacyContext" -msgstr "" +msgstr "遗留上下文" #: flwr.server.compat.legacy_context.LegacyContext:1 of +#, fuzzy msgid "Bases: :py:class:`~flwr.common.context.Context`" -msgstr "" +msgstr "Bases: :py:class:`~flwr.common.context.Context`" #: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 #, fuzzy @@ -9669,8 +10545,9 @@ msgid ":py:obj:`strategy `\\" msgstr "server.strategy.Strategy" #: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy msgid ":py:obj:`client_manager `\\" -msgstr "" +msgstr ":py:obj:`client_manager `\\" #: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 #, fuzzy @@ -9683,8 +10560,9 @@ msgid ":py:obj:`state `\\" msgstr "server.strategy.Strategy" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid ":py:obj:`client_manager `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`client_manager `\\ \\(\\)" #: flwr.server.server.Server.client_manager:1 #: flwr.server.server.Server.client_manager:1::1 of @@ -9693,21 +10571,28 @@ msgid "Return ClientManager." msgstr "返回客户端(本身)。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid "" ":py:obj:`disconnect_all_clients " "`\\ \\(timeout\\)" msgstr "" +":py:obj:`disconnect_all_clients `" +"\\ \\(timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.disconnect_all_clients:1 of +#, fuzzy msgid "Send shutdown signal to all clients." -msgstr "" +msgstr "向所有客户端发送关闭信号。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate_round `\\ " "\\(server\\_round\\, timeout\\)" msgstr "" +":py:obj:`evaluate_round `\\ \\(" +"server\\_round\\, timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.evaluate_round:1 of @@ -9716,8 +10601,9 @@ msgid "Validate current global model on a number of clients." msgstr "当前(全局)模型参数。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" -msgstr "" +msgstr ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.fit:1 of @@ -9726,10 +10612,13 @@ msgid "Run federated averaging for a number of rounds." msgstr "联邦平均动量策略。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid "" ":py:obj:`fit_round `\\ \\(server\\_round\\," " timeout\\)" msgstr "" +":py:obj:`fit_round `\\ \\(server\\_round\\, " +"timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.fit_round:1 of @@ -9738,19 +10627,25 @@ msgid "Perform a single round of federated averaging." msgstr "本轮联邦学习。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid "" ":py:obj:`set_max_workers `\\ " "\\(max\\_workers\\)" msgstr "" +":py:obj:`set_max_workers `\\ \\(" +"max\\_workers\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.set_max_workers:1 of +#, fuzzy msgid "Set the max_workers used by ThreadPoolExecutor." -msgstr "" +msgstr "设置 ThreadPoolExecutor 使用的最大工作器数。" #: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" +":py:obj:`set_strategy `\\ \\(strategy\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.set_strategy:1 of @@ -9769,8 +10664,9 @@ msgid "Use the `ServerApp` with an existing `Strategy`:" msgstr "使用现有策略" #: flwr.server.server_app.ServerApp:15 of +#, fuzzy msgid "Use the `ServerApp` with a custom main function:" -msgstr "" +msgstr "使用带有自定义主函数的 `ServerApp`:" #: flwr.server.server_app.ServerApp.main:1::1 of #, fuzzy @@ -9779,8 +10675,9 @@ msgstr "server.strategy.Strategy" #: flwr.server.server_app.ServerApp.main:1 #: flwr.server.server_app.ServerApp.main:1::1 of +#, fuzzy msgid "Return a decorator that registers the main fn with the server app." -msgstr "" +msgstr "返回向服务器应用程序注册 main fn 的装饰器。" #: ../../source/ref-api/flwr.server.ServerConfig.rst:2 #, fuzzy @@ -9788,78 +10685,102 @@ msgid "ServerConfig" msgstr "服务器" #: flwr.server.server_config.ServerConfig:3 of +#, fuzzy msgid "" "All attributes have default values which allows users to configure just " "the ones they care about." -msgstr "" +msgstr "所有属性都有默认值,用户只需配置自己关心的属性即可。" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +#, fuzzy msgid ":py:obj:`num_rounds `\\" -msgstr "" +msgstr ":py:obj:`num_rounds `\\" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +#, fuzzy msgid ":py:obj:`round_timeout `\\" -msgstr "" +msgstr ":py:obj:`round_timeout `\\" #: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 +#, fuzzy msgid "SimpleClientManager" -msgstr "" +msgstr "SimpleClientManager" #: flwr.server.client_manager.SimpleClientManager:1 of +#, fuzzy msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" -msgstr "" +msgstr "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid ":py:obj:`all `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`all `\\ \\(\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`num_available `\\" " \\(\\)" msgstr "" +":py:obj:`num_available `\\ \\(" +"\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`register `\\ " "\\(client\\)" msgstr "" +":py:obj:`register `\\ \\(client\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`sample `\\ " "\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" +":py:obj:`sample `\\ \\(num\\_clients" +"\\[\\, min\\_num\\_clients\\, criterion\\]\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`unregister `\\ " "\\(client\\)" msgstr "" +":py:obj:`unregister `\\ \\(" +"client\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy msgid "" ":py:obj:`wait_for `\\ " "\\(num\\_clients\\[\\, timeout\\]\\)" msgstr "" +":py:obj:`wait_for `\\ \\(" +"num\\_clients\\[\\, timeout\\]\\)" #: flwr.server.client_manager.SimpleClientManager.wait_for:3 of +#, fuzzy msgid "" "Blocks until the requested number of clients is available or until a " "timeout is reached. Current timeout default: 1 day." -msgstr "" +msgstr "阻塞,直到请求的客户端数量可用或达到超时为止。当前超时默认值:1 天。" #: flwr.server.client_manager.SimpleClientManager.wait_for:6 of +#, fuzzy msgid "The number of clients to wait for." -msgstr "" +msgstr "需要等待的客户数量。" #: flwr.server.client_manager.SimpleClientManager.wait_for:8 of +#, fuzzy msgid "The time in seconds to wait for, defaults to 86400 (24h)." -msgstr "" +msgstr "以秒为单位的等待时间,默认为 86400(24 小时)。" #: flwr.server.client_manager.SimpleClientManager.wait_for:11 of +#, fuzzy msgid "**success**" -msgstr "" +msgstr "**success**" #: ../../source/ref-api/flwr.server.run_driver_api.rst:2 #, fuzzy @@ -9867,12 +10788,14 @@ msgid "run\\_driver\\_api" msgstr "flower-driver-api" #: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 +#, fuzzy msgid "run\\_fleet\\_api" -msgstr "" +msgstr "run\\_fleet\\_api" #: ../../source/ref-api/flwr.server.run_server_app.rst:2 +#, fuzzy msgid "run\\_server\\_app" -msgstr "" +msgstr "run\\_server\\_app" #: ../../source/ref-api/flwr.server.run_superlink.rst:2 #, fuzzy @@ -9925,8 +10848,9 @@ msgstr "" "`flwr.server.client_manager.SimpleClientManager`。" #: flwr.server.compat.app.start_driver:25 of +#, fuzzy msgid "The Driver object to use." -msgstr "" +msgstr "要使用的驱动程序对象。" #: flwr.server.app.start_server:37 flwr.server.compat.app.start_driver:28 of msgid "**hist** -- Object containing training and evaluation metrics." @@ -9992,10 +10916,13 @@ msgid "strategy" msgstr "Krum 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`Bulyan `\\ \\(\\*\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" msgstr "" +":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.bulyan.Bulyan:1 of @@ -10003,10 +10930,13 @@ msgid "Bulyan strategy." msgstr "Bulyan 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DPFedAvgAdaptive `\\ " "\\(strategy\\, num\\_sampled\\_clients\\)" msgstr "" +":py:obj:`DPFedAvgAdaptive `\\ \\(" +"strategy\\, num\\_sampled\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of @@ -10014,10 +10944,13 @@ msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DPFedAvgFixed `\\ " "\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" msgstr "" +":py:obj:`DPFedAvgFixed `\\ \\(strategy\\" +", num\\_sampled\\_clients\\, ...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of @@ -10025,11 +10958,14 @@ msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " "`\\ " "\\(...\\)" msgstr "" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 @@ -10039,11 +10975,14 @@ msgid "Strategy wrapper for central DP with client-side adaptive clipping." msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " "`\\ " "\\(...\\)" msgstr "" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 @@ -10053,11 +10992,14 @@ msgid "Strategy wrapper for central DP with server-side adaptive clipping." msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DifferentialPrivacyClientSideFixedClipping " "`\\ " "\\(...\\)" msgstr "" +":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 @@ -10067,11 +11009,14 @@ msgid "Strategy wrapper for central DP with client-side fixed clipping." msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`DifferentialPrivacyServerSideFixedClipping " "`\\ " "\\(...\\)" msgstr "" +":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 @@ -10081,10 +11026,13 @@ msgid "Strategy wrapper for central DP with server-side fixed clipping." msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedadagrad.FedAdagrad:1 of @@ -10092,10 +11040,13 @@ msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." msgstr "FedAdagrad 策略 - 使用 Adagrad 进行自适应联合优化。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedAdam `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedAdam `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedadam.FedAdam:1 of @@ -10103,10 +11054,13 @@ msgid "FedAdam - Adaptive Federated Optimization using Adam." msgstr "FedAdam - 使用 Adam 进行自适应联合优化。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedAvg `\\ \\(\\*\\[\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, fraction\\_fit" +"\\, fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedavg.FedAvg:1 @@ -10115,16 +11069,22 @@ msgid "Federated Averaging strategy." msgstr "联邦平均策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedAvgAndroid `\\ " "\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedavgm.FedAvgM:1 of @@ -10132,10 +11092,13 @@ msgid "Federated Averaging with Momentum strategy." msgstr "联邦平均动量策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedMedian `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedMedian `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedmedian.FedMedian:1 of @@ -10144,10 +11107,13 @@ msgid "Configurable FedMedian strategy implementation." msgstr "可配置的 FedAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedOpt `\\ \\(\\*\\[\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, fraction\\_fit" +"\\, fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedopt.FedOpt:1 of @@ -10156,10 +11122,13 @@ msgid "Federated Optim strategy." msgstr "联邦优化策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedProx `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedProx `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedprox.FedProx:1 of @@ -10167,10 +11136,13 @@ msgid "Federated Optimization strategy." msgstr "联邦优化策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedTrimmedAvg `\\ " "\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of @@ -10178,10 +11150,13 @@ msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." msgstr "带修剪均值的联邦平均法[Dong Yin 等,2021]。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedXgbBagging `\\ " "\\(\\[evaluate\\_function\\]\\)" msgstr "" +":py:obj:`FedXgbBagging `\\ \\(\\[" +"evaluate\\_function\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of @@ -10190,10 +11165,13 @@ msgid "Configurable FedXgbBagging strategy implementation." msgstr "可配置的 FedXgbNAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedXgbCyclic `\\ " "\\(\\*\\*kwargs\\)" msgstr "" +":py:obj:`FedXgbCyclic `\\ \\(\\*\\*" +"kwargs\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of @@ -10202,10 +11180,13 @@ msgid "Configurable FedXgbCyclic strategy implementation." msgstr "可配置的 FedAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " "\\*\\*kwargs\\)" msgstr "" +":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, \\*" +"\\*kwargs\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of @@ -10213,10 +11194,13 @@ msgid "Configurable FedXgbNnAvg strategy implementation." msgstr "可配置的 FedXgbNAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FedYogi `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FedYogi `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedyogi.FedYogi:1 of @@ -10224,11 +11208,14 @@ msgid "FedYogi [Reddi et al., 2020] strategy." msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`FaultTolerantFedAvg " "`\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" msgstr "" +":py:obj:`FaultTolerantFedAvg `\\ \\" +"(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of @@ -10236,10 +11223,13 @@ msgid "Configurable fault-tolerant FedAvg strategy implementation." msgstr "可配置的容错 FedAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`Krum `\\ \\(\\*\\[\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" +":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.krum.Krum:1 of @@ -10248,10 +11238,13 @@ msgid "Krum [Blanchard et al., 2017] strategy." msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy msgid "" ":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " "q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " +"qffl\\_learning\\_rate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.qfedavg.QFedAvg:1 of @@ -10269,8 +11262,9 @@ msgid "Abstract base class for server strategy implementations." msgstr "服务器策略实现的抽象基类。" #: ../../source/ref-api/flwr.server.strategy.Bulyan.rst:2 +#, fuzzy msgid "Bulyan" -msgstr "" +msgstr "Bulyan" #: flwr.server.strategy.bulyan.Bulyan:1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 @@ -10429,11 +11423,14 @@ msgid "arguments to the first_aggregation rule" msgstr "第一聚类规则的参数" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\, " "results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `" +"\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10447,10 +11444,13 @@ msgid "Aggregate evaluation losses using weighted average." msgstr "采用加权平均法计算评估损失总额。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -10458,11 +11458,14 @@ msgid "Aggregate fit results using Bulyan." msgstr "使用 Bulyan 技术汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `" +"\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 @@ -10488,10 +11491,13 @@ msgid "Configure the next round of evaluation." msgstr "配置下一轮评估。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 @@ -10520,10 +11526,13 @@ msgid "Configure the next round of training." msgstr "配置下一轮训练。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round" +"\\, parameters\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -10539,11 +11548,14 @@ msgid "Evaluate model parameters using an evaluation function." msgstr "使用评估函数评估模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -10558,11 +11570,14 @@ msgid "Initialize global model parameters." msgstr "初始化全局模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -10577,10 +11592,13 @@ msgid "Use a fraction of available clients for evaluation." msgstr "使用部分可用客户进行评估。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients `\\" " \\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(" +"num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -10599,21 +11617,26 @@ msgid "DPFedAvgAdaptive" msgstr "DPFedAvgAdaptive" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +#, fuzzy msgid "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" -msgstr "" +msgstr "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:3 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:3 of +#, fuzzy msgid "This class is deprecated and will be removed in a future release." -msgstr "" +msgstr "该类已被弃用,将在以后的版本中删除。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -10631,11 +11654,14 @@ msgstr "使用给定的策略汇总评估损失。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `" +"\\ \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -10645,11 +11671,14 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of @@ -10658,18 +11687,24 @@ msgstr "使用指定策略配置下一轮评估。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `" +"\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 @@ -10686,11 +11721,14 @@ msgstr "使用策略中的评估函数评估模型参数。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 @@ -10747,24 +11785,31 @@ msgstr "DPFedAvgFixed" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 #: flwr.server.strategy.fedavg.FedAvg:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +#, fuzzy msgid "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" -msgstr "" +msgstr "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_fit:1 of @@ -10773,19 +11818,25 @@ msgstr "使用非加权汇总法汇总训练结果。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of @@ -10796,18 +11847,24 @@ msgstr "配置包含差分隐私 (DP) 的下一轮训练。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" @@ -10828,16 +11885,19 @@ msgstr "" "一个元组列表。列表中的每个元组都标识了一个`ClientProxy`和该特定`ClientProxy`的`FitIns'。如果某个特定的`ClientProxy`不在此列表中,则表示该`ClientProxy`将不参加下一轮联合学习。" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 +#, fuzzy msgid "DifferentialPrivacyClientSideAdaptiveClipping" -msgstr "" +msgstr "DifferentialPrivacyClientSideAdaptiveClipping" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:3 #: of +#, fuzzy msgid "Use `adaptiveclipping_mod` modifier at the client side." -msgstr "" +msgstr "在客户端使用 \"adaptiveclipping_mod \"修改器。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:5 #: of +#, fuzzy msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " @@ -10845,57 +11905,68 @@ msgid "" "happen on the client-side, usually by using the built-in " "`adaptiveclipping_mod`." msgstr "" +"与在服务器端执行剪切的 `DifferentialPrivacyServerSideAdaptiveClipping` " +"相比,`DifferentialPrivacyClientSideAdaptiveClipping` 希望在客户端进行剪切," +"通常使用内置的 `adaptiveclipping_mod`。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:10 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:3 #: of +#, fuzzy msgid "The strategy to which DP functionalities will be added by this wrapper." -msgstr "" +msgstr "该包装器将添加 DP 功能的策略。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:12 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:5 #: of +#, fuzzy msgid "The noise multiplier for the Gaussian mechanism for model updates." -msgstr "" +msgstr "用于模型更新的高斯机制的噪声乘数。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:14 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:7 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:17 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:10 #: of +#, fuzzy msgid "The number of clients that are sampled on each round." -msgstr "" +msgstr "每轮取样的客户数。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:16 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:9 #: of +#, fuzzy msgid "" "The initial value of clipping norm. Defaults to 0.1. Andrew et al. " "recommends to set to 0.1." -msgstr "" +msgstr "剪切规范的初始值。默认为 0.1。安德鲁等人建议设置为 0.1。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of +#, fuzzy msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." -msgstr "" +msgstr "需要剪切的更新量化值。默认为 0.5。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 #: of +#, fuzzy msgid "" "The learning rate for the clipping norm adaptation. Defaults to 0.2. " "Andrew et al. recommends to set to 0.2." -msgstr "" +msgstr "剪切规范适应的学习率。默认为 0.2。安德鲁等人建议设置为 0.2。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of +#, fuzzy msgid "" "The stddev of the noise added to the count of updates currently below the" " estimate. Andrew et al. recommends to set to `expected_num_records/20`" -msgstr "" +msgstr "添加到当前低于估计值的更新计数中的噪声的 stddev。安德鲁等人建议设置为 " +"\"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 @@ -10908,31 +11979,41 @@ msgstr "server.strategy" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 #: of +#, fuzzy msgid "" "Wrap the strategy with the " "`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" -msgstr "" +msgstr "用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 #: of +#, fuzzy msgid "On the client, add the `adaptiveclipping_mod` to the client-side mods:" -msgstr "" +msgstr "在客户端,将 \"adaptiveclipping_mod \"添加到客户端模块中:" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\" " \\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(" +"server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\" " \\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 @@ -10945,35 +12026,51 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate " "`\\" " \\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round" +"\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\" " \\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(" +"client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 #, fuzzy @@ -10982,59 +12079,76 @@ msgstr "差分隐私" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:3 #: of +#, fuzzy msgid "Use `fixedclipping_mod` modifier at the client side." -msgstr "" +msgstr "在客户端使用 `fixedclipping_mod` 修改器。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:5 #: of +#, fuzzy msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " "`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " "on the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" +"与在服务器端执行剪切的 \"DifferentialPrivacyServerSideFixedClipping \"相比," +"\"DifferentialPrivacyClientSideFixedClipping \"希望在客户端进行剪切," +"通常是使用内置的 \"fixedclipping_mod\"。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of +#, fuzzy msgid "" "The noise multiplier for the Gaussian mechanism for model updates. A " "value of 1.0 or higher is recommended for strong privacy." -msgstr "" +msgstr "模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 #: of +#, fuzzy msgid "The value of the clipping norm." -msgstr "" +msgstr "削波法线的值。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 #: of +#, fuzzy msgid "" "Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` " "wrapper:" -msgstr "" +msgstr "用 \"DifferentialPrivacyClientSideFixedClipping \"包装器包装策略:" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:32 #: of +#, fuzzy msgid "On the client, add the `fixedclipping_mod` to the client-side mods:" -msgstr "" +msgstr "在客户端,将 \"fixedclipping_mod \"添加到客户端模块中:" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\" " \\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(" +"server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\" " \\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 @@ -11045,102 +12159,146 @@ msgstr "然后将汇总结果序列化:" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate " "`\\" " \\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\" " \\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(" +"client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 +#, fuzzy msgid "DifferentialPrivacyServerSideAdaptiveClipping" -msgstr "" +msgstr "DifferentialPrivacyServerSideAdaptiveClipping" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 #: of +#, fuzzy msgid "" "The standard deviation of the noise added to the count of updates below " "the estimate. Andrew et al. recommends to set to " "`expected_num_records/20`" -msgstr "" +msgstr "添加到低于估计值的更新计数中的噪声标准偏差。安德鲁等人建议设置为 " +"\"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 #: of +#, fuzzy msgid "" "Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping " "wrapper" -msgstr "" +msgstr "用 DifferentialPrivacyServerSideAdaptiveClipping 封装器封装策略" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\" " \\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(" +"server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\" " \\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate " "`\\" " \\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round" +"\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\" " \\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(" +"client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 #, fuzzy @@ -11149,69 +12307,96 @@ msgstr "差分隐私" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 #: of +#, fuzzy msgid "" "Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " "wrapper" -msgstr "" +msgstr "用 DifferentialPrivacyServerSideFixedClipping 封装器封装策略" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\" " \\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(" +"server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\" " \\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 #: of +#, fuzzy msgid "Compute the updates, clip, and pass them for aggregation." -msgstr "" +msgstr "计算更新、剪辑并将其传递给聚合。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate " "`\\" " \\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\" " \\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(" +"client\\_manager\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 #: of +#, fuzzy msgid "Afterward, add noise to the aggregated parameters." -msgstr "" +msgstr "然后,在汇总参数中添加噪声。" #: ../../source/ref-api/flwr.server.strategy.FaultTolerantFedAvg.rst:2 #, fuzzy @@ -11220,19 +12405,25 @@ msgstr "server.strategy.FaultTolerantFedAvg" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 @@ -11252,50 +12443,68 @@ msgstr "使用加权平均法汇总拟合结果。" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 #: ../../source/ref-changelog.md:839 @@ -11305,8 +12514,9 @@ msgstr "FedAdagrad" #: flwr.server.strategy.fedadagrad.FedAdagrad:1 #: flwr.server.strategy.fedadam.FedAdam:1 #: flwr.server.strategy.fedyogi.FedYogi:1 of +#, fuzzy msgid "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" -msgstr "" +msgstr "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" #: flwr.server.strategy.fedadagrad.FedAdagrad:3 #: flwr.server.strategy.fedadam.FedAdam:3 flwr.server.strategy.fedopt.FedOpt:3 @@ -11346,57 +12556,81 @@ msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-9." msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\" " \\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\" " \\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 #, fuzzy @@ -11414,57 +12648,81 @@ msgid "Second moment parameter. Defaults to 0.99." msgstr "第二动量参数。默认为 0.99。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\" +"(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 #, fuzzy @@ -11498,60 +12756,85 @@ msgstr "" "available_clients`,则仍会对 `min_evaluate_clients` 进行采样。默认为 1.0。" #: flwr.server.strategy.fedavg.FedAvg:33 of +#, fuzzy msgid "Enable (True) or disable (False) in-place aggregation of model updates." -msgstr "" +msgstr "启用(真)或禁用(假)模型更新的就地聚合。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\, " "results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `" +"\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `" +"\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round" +"\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients `\\" " \\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(" +"num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 #, fuzzy @@ -11560,26 +12843,35 @@ msgstr "DPFedAvgAdaptive" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`bytes_to_ndarray " "`\\ \\(tensor\\)" msgstr "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of @@ -11589,41 +12881,56 @@ msgstr "从字节反序列化 NumPy ndarray。" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`ndarray_to_bytes " "`\\ \\(ndarray\\)" msgstr "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of @@ -11633,35 +12940,47 @@ msgstr "将 NumPy ndarray 序列化为字节。" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`ndarrays_to_parameters " "`\\ " "\\(ndarrays\\)" msgstr "" +":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`parameters_to_ndarrays " "`\\ " "\\(parameters\\)" msgstr "" +":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 @@ -11691,74 +13010,105 @@ msgid "Server-side momentum factor used for FedAvgM. Defaults to 0.0." msgstr "用于 FedAvgM 的服务器端动量因子。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\" +"(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 +#, fuzzy msgid "FedMedian" -msgstr "" +msgstr "联邦医保" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of @@ -11766,48 +13116,67 @@ msgid "Aggregate fit results using median." msgstr "使用中位数汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 +#, fuzzy msgid "FedOpt" -msgstr "" +msgstr "FedOpt" #: flwr.server.strategy.fedopt.FedOpt:33 of msgid "Momentum parameter. Defaults to 0.0." @@ -11818,60 +13187,85 @@ msgid "Second moment parameter. Defaults to 0.0." msgstr "第二动量参数。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\, " "results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `" +"\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `" +"\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round" +"\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients `\\" " \\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(" +"num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 +#, fuzzy msgid "FedProx" -msgstr "" +msgstr "FedProx" #: flwr.server.strategy.fedprox.FedProx:3 of msgid "Implementation based on https://arxiv.org/abs/1812.06127" @@ -11923,57 +13317,81 @@ msgstr "" "FedAvg,系数越大,使用的正则化就越多(也就是说,在训练过程中,客户端参数需要更接近服务器参数)。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\" +"(num\\_available\\_clients\\)" #: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of msgid "Sends the proximal factor mu to the clients" @@ -11994,18 +13412,24 @@ msgid "Fraction to cut off of both tails of the distribution. Defaults to 0.2." msgstr "截取分布两个尾部的分数。默认为 0.2。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg.aggregate_fit:1 of @@ -12013,57 +13437,79 @@ msgid "Aggregate fit results using trimmed average." msgstr "使用修剪平均值汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 +#, fuzzy msgid "FedXgbBagging" -msgstr "" +msgstr "FedXgbBagging" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 @@ -12076,11 +13522,14 @@ msgstr "采用加权平均法计算评估损失总额。" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_fit:1 @@ -12092,117 +13541,160 @@ msgstr "使用 Bulyan 技术汇总拟合结果。" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 +#, fuzzy msgid "FedXgbCyclic" -msgstr "" +msgstr "FedXgbCyclic" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ \\(server\\_round\\," " results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `" +"\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 #, fuzzy @@ -12210,70 +13702,98 @@ msgid "FedXgbNnAvg" msgstr "DP-FedAvg" #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of +#, fuzzy msgid "" "This strategy is deprecated, but a copy of it is available in Flower " "Baselines: " "https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" +"该策略已被弃用,但在 Flower Baselines: https://github.com/adap/flower/tree/" +"main/baselines/hfedxgboost 中有其副本。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit " "`\\ \\(server\\_round\\, " "results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\" +"(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit " "`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\" +"(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `" +"\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 +#, fuzzy msgid "FedYogi" -msgstr "" +msgstr "FedYogi" #: flwr.server.strategy.fedyogi.FedYogi:32 of #, fuzzy @@ -12291,61 +13811,86 @@ msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-3." msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\" +"(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 +#, fuzzy msgid "Krum" -msgstr "" +msgstr "Krum" #: flwr.server.strategy.krum.Krum:3 of #, fuzzy @@ -12359,17 +13904,23 @@ msgid "" msgstr "求平均值前保留的客户端数量(MultiKrum)。默认值为 0,在这种情况下会应用经典 Krum。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\, " "results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\" +" \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.krum.Krum.aggregate_fit:1 of @@ -12377,43 +13928,61 @@ msgid "Aggregate fit results using Krum." msgstr "使用 Krum 汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(server\\_round\\" +", parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\(" +"num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 #, fuzzy @@ -12421,57 +13990,81 @@ msgid "QFedAvg" msgstr "DP-FedAvg" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_evaluation_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy msgid "" ":py:obj:`num_fit_clients " "`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +":py:obj:`num_fit_clients `\\ \\" +"(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 #, fuzzy @@ -12480,11 +14073,14 @@ msgstr "Krum 策略。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_evaluate " "`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -12494,10 +14090,13 @@ msgstr "聚合评估结果。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" +":py:obj:`aggregate_fit `\\ \\(" +"server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of @@ -12506,25 +14105,34 @@ msgstr "汇总训练结果。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_evaluate " "`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +":py:obj:`configure_fit `\\ \\(" +"server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +":py:obj:`evaluate `\\ \\(" +"server\\_round\\, parameters\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.evaluate:1 of @@ -12533,11 +14141,14 @@ msgstr "评估当前的模型参数。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of +#, fuzzy msgid "" ":py:obj:`initialize_parameters " "`\\ " "\\(client\\_manager\\)" msgstr "" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of @@ -12618,38 +14229,50 @@ msgid "workflow" msgstr "工作流程" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#, fuzzy msgid "" ":py:obj:`DefaultWorkflow `\\ " "\\(\\[fit\\_workflow\\, ...\\]\\)" msgstr "" +":py:obj:`DefaultWorkflow `\\ \\(\\[" +"fit\\_workflow\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of +#, fuzzy msgid "Default workflow in Flower." -msgstr "" +msgstr "Flower 中的默认工作流程。" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#, fuzzy msgid "" ":py:obj:`SecAggPlusWorkflow `\\ " "\\(num\\_shares\\, ...\\[\\, ...\\]\\)" msgstr "" +":py:obj:`SecAggPlusWorkflow `\\ \\(" +"num\\_shares\\, ...\\[\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of +#, fuzzy msgid "The workflow for the SecAgg+ protocol." -msgstr "" +msgstr "SecAgg+ 协议的工作流程。" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#, fuzzy msgid "" ":py:obj:`SecAggWorkflow `\\ " "\\(reconstruction\\_threshold\\, \\*\\)" msgstr "" +":py:obj:`SecAggWorkflow `\\ \\(" +"reconstruction\\_threshold\\, \\*\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +#, fuzzy msgid "The workflow for the SecAgg protocol." -msgstr "" +msgstr "SecAgg 协议的工作流程。" #: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:2 #, fuzzy @@ -12663,6 +14286,7 @@ msgstr "工作流程" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 #: of +#, fuzzy msgid "" "The SecAgg+ protocol ensures the secure summation of integer vectors " "owned by multiple parties, without accessing any individual integer " @@ -12676,47 +14300,63 @@ msgid "" "('parameters') from the client's `FitRes`. The server then aggregates " "these contributions to compute the weighted average of model parameters." msgstr "" +"SecAgg+ 协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向" +"量。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持" +"私密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保" +"护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * params]" +"\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " +"\"FitRes \"中的模型参数(\"parameters\"" +")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 #: of +#, fuzzy msgid "" "The protocol involves four main stages: - 'setup': Send SecAgg+ " "configuration to clients and collect their public keys. - 'share keys': " "Broadcast public keys among clients and collect encrypted secret" msgstr "" +"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg+ 配置并收集其公钥。- " +"共享密钥\": 在客户端之间广播公钥,并收集加密密钥。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 #: of +#, fuzzy msgid "key shares." -msgstr "" +msgstr "关键股份。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:18 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:18 #: of +#, fuzzy msgid "" "'collect masked vectors': Forward encrypted secret key shares to target " "clients and collect masked model parameters." -msgstr "" +msgstr "收集屏蔽向量\": 向目标客户端转发加密密钥共享,并收集屏蔽模型参数。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:20 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:20 #: of +#, fuzzy msgid "" "'unmask': Collect secret key shares to decrypt and aggregate the model " "parameters." -msgstr "" +msgstr "解密\": 收集密钥共享,解密并汇总模型参数。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:22 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 #: of +#, fuzzy msgid "" "Only the aggregated model parameters are exposed and passed to " "`Strategy.aggregate_fit`, ensuring individual data privacy." -msgstr "" +msgstr "只有聚合模型参数才会公开并传递给 `Strategy." +"aggregate_fit`,从而确保个人数据隐私。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of +#, fuzzy msgid "" "The number of shares into which each client's private key is split under " "the SecAgg+ protocol. If specified as a float, it represents the " @@ -12725,10 +14365,14 @@ msgid "" "these shares, allowing for the secure aggregation of model updates. Each " "client sends one share to each of its neighbors while retaining one." msgstr "" +"在 SecAgg+ 协议下,每个客户的私钥被分成的份数。如果指定为浮点数,则代表所有选" +"定客户的比例,份额数将在运行时动态设置。私钥可以从这些份额中重建,从而实现模" +"型更新的安全聚合。每个客户端向其每个邻居发送一份,同时保留一份。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 #: of +#, fuzzy msgid "" "The minimum number of shares required to reconstruct a client's private " "key, or, if specified as a float, it represents the proportion of the " @@ -12736,149 +14380,194 @@ msgid "" "privacy by allowing for the recovery of contributions from dropped " "clients during aggregation, without compromising individual client data." msgstr "" +"重建客户私钥所需的最小份数,如果指定为浮动,则表示重建所需的份数占总份数的比" +"例。这个阈值允许在聚合过程中恢复掉线客户的贡献,从而确保隐私,而不会泄露单个" +"客户的数据。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 #: of +#, fuzzy msgid "" "The maximum value of the weight that can be assigned to any single " "client's update during the weighted average calculation on the server " "side, e.g., in the FedAvg algorithm." -msgstr "" +msgstr "在服务器端进行加权平均计算(如 FedAvg " +"算法)时,可分配给任何单个客户端更新的权重的最大值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 #: of +#, fuzzy msgid "" "The range within which model parameters are clipped before quantization. " "This parameter ensures each model parameter is bounded within " "[-clipping_range, clipping_range], facilitating quantization." -msgstr "" +msgstr "量化前模型参数的裁剪范围。该参数可确保每个模型参数都在 [-clipping_range, " +"clipping_range] 范围内,便于量化。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 #: of +#, fuzzy msgid "" "The size of the range into which floating-point model parameters are " "quantized, mapping each parameter to an integer in [0, " "quantization_range-1]. This facilitates cryptographic operations on the " "model updates." -msgstr "" +msgstr "浮点模型参数量化范围的大小,将每个参数映射为 [0, quantization_range-1] " +"中的整数。这有助于对模型更新进行加密操作。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 #: of +#, fuzzy msgid "" "The range of values from which random mask entries are uniformly sampled " "([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " "Please use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" +"对随机掩码条目进行均匀采样的数值范围([0, modulus_range-1])。modulus_range " +"\"必须小于 4294967296。为防止出现溢出问题,请为 `modulus_range` 使用 2**n " +"的值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of +#, fuzzy msgid "" "The timeout duration in seconds. If specified, the workflow will wait for" " replies for this duration each time. If `None`, there is no time limit " "and the workflow will wait until replies for all messages are received." msgstr "" +"超时时间(秒)。如果指定,工作流将在每次等待回复的时间内等待回复。如果指定为 " +"\"无\",则没有时间限制,工作流程将一直等待到收到所有信息的回复。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 #: of +#, fuzzy msgid "" "Generally, higher `num_shares` means more robust to dropouts while " "increasing the computational costs; higher `reconstruction_threshold` " "means better privacy guarantees but less tolerance to dropouts." msgstr "" +"一般来说,\"份额数 \"越高,意味着对丢弃的鲁棒性越强,同时计算成本也会增加;" +"\"重构阈值 \"越高,意味着隐私保证越好,但对丢弃的容忍度越低。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of +#, fuzzy msgid "Too large `max_weight` may compromise the precision of the quantization." -msgstr "" +msgstr "过大的 `max_weight` 可能会影响量化的精度。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:65 #: of +#, fuzzy msgid "`modulus_range` must be 2**n and larger than `quantization_range`." -msgstr "" +msgstr "modulus_range \"必须为 2**n,且大于 \"quantization_range\"。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:66 #: of +#, fuzzy msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " "selected clients, and hence the number of shares will be determined in " "the runtime. This allows for dynamic adjustment based on the total number" " of participating clients." msgstr "" +"当 `num_shares` 为浮点数时,它被解释为所有选定客户端的比例,因此份额数将在运" +"行时确定。这样就可以根据参与客户端的总数进行动态调整。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 #: of +#, fuzzy msgid "" "Similarly, when `reconstruction_threshold` is a float, it is interpreted " "as the proportion of the number of shares needed for the reconstruction " "of a private key. This feature enables flexibility in setting the " "security threshold relative to the number of distributed shares." msgstr "" +"同样,当 `reconstruction_threshold` 为浮点数时,它被解释为重建私钥所需的份额" +"数比例。这一功能使我们可以根据分发的份额数灵活设置安全阈值。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 #: of +#, fuzzy msgid "" "`num_shares`, `reconstruction_threshold`, and the quantization parameters" " (`clipping_range`, `quantization_range`, `modulus_range`) play critical " "roles in balancing privacy, robustness, and efficiency within the SecAgg+" " protocol." msgstr "" +"份额数\"、\"重建阈值 \"和量化参数(\"裁剪范围\"、\"量化范围\"、\"模数范围\")" +"在平衡 SecAgg+ 协议的隐私性、稳健性和效率方面发挥着关键作用。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`collect_masked_vectors_stage " "`\\" " \\(driver\\, ...\\)" msgstr "" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "Execute the 'collect masked vectors' stage." -msgstr "" +msgstr "执行 \"收集屏蔽向量 \"阶段。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`setup_stage " "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" +":py:obj:`setup_stage `\\" +" \\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 #: of +#, fuzzy msgid "Execute the 'setup' stage." -msgstr "" +msgstr "执行 \"设置 \"阶段。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`share_keys_stage " "`\\ " "\\(driver\\, context\\, state\\)" msgstr "" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 #: of +#, fuzzy msgid "Execute the 'share keys' stage." -msgstr "" +msgstr "执行 \"共享密钥 \"阶段。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`unmask_stage " "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" +":py:obj:`unmask_stage `" +"\\ \\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 @@ -23111,4 +24800,3 @@ msgstr "" #~ msgid "|08cb60859b07461588fe44e55810b050|" #~ msgstr "" - From 2e1d943d88893adc7a3061316676655ea7afbe90 Mon Sep 17 00:00:00 2001 From: Javier Date: Mon, 27 May 2024 10:58:52 +0100 Subject: [PATCH 020/124] fix(framework:skip) Remove `pydantic` from list of extras in `pyproject.toml` (#3514) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 2d8c24d8e80c..a045987367f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,7 +81,7 @@ starlette = { version = "^0.31.0", optional = true } uvicorn = { version = "^0.23.0", extras = ["standard"], optional = true } [tool.poetry.extras] -simulation = ["ray", "pydantic"] +simulation = ["ray"] rest = ["requests", "starlette", "uvicorn"] [tool.poetry.group.dev.dependencies] From 1647bd2bbc49246ac90f586fbbf78c47d5d2b3b3 Mon Sep 17 00:00:00 2001 From: Javier Date: Mon, 27 May 2024 11:22:15 +0100 Subject: [PATCH 021/124] break(framework) Remove option to start SuperLink for simulation (#3513) --- src/py/flwr/server/app.py | 78 --------------------------------------- 1 file changed, 78 deletions(-) diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 84a075a3e6df..8049a864fd5d 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -15,7 +15,6 @@ """Flower server app.""" import argparse -import asyncio import csv import importlib.util import sys @@ -39,7 +38,6 @@ MISSING_EXTRA_REST, TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_REST, - TRANSPORT_TYPE_VCE, ) from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log, warn_deprecated_feature @@ -63,7 +61,6 @@ ) from .superlink.fleet.grpc_rere.fleet_servicer import FleetServicer from .superlink.fleet.grpc_rere.server_interceptor import AuthenticateServerInterceptor -from .superlink.fleet.vce import start_vce from .superlink.state import StateFactory ADDRESS_DRIVER_API = "0.0.0.0:9091" @@ -401,17 +398,6 @@ def run_superlink() -> None: interceptors=interceptors, ) grpc_servers.append(fleet_server) - elif args.fleet_api_type == TRANSPORT_TYPE_VCE: - f_stop = asyncio.Event() # Does nothing - _run_fleet_api_vce( - num_supernodes=args.num_supernodes, - client_app_attr=args.client_app, - backend_name=args.backend, - backend_config_json_stream=args.backend_config, - app_dir=args.app_dir, - state_factory=state_factory, - f_stop=f_stop, - ) else: raise ValueError(f"Unknown fleet_api_type: {args.fleet_api_type}") @@ -569,29 +555,6 @@ def _run_fleet_api_grpc_rere( return fleet_grpc_server -# pylint: disable=too-many-arguments -def _run_fleet_api_vce( - num_supernodes: int, - client_app_attr: str, - backend_name: str, - backend_config_json_stream: str, - app_dir: str, - state_factory: StateFactory, - f_stop: asyncio.Event, -) -> None: - log(INFO, "Flower VCE: Starting Fleet API (VirtualClientEngine)") - - start_vce( - num_supernodes=num_supernodes, - client_app_attr=client_app_attr, - backend_name=backend_name, - backend_config_json_stream=backend_config_json_stream, - state_factory=state_factory, - app_dir=app_dir, - f_stop=f_stop, - ) - - # pylint: disable=import-outside-toplevel,too-many-arguments def _run_fleet_api_rest( host: str, @@ -783,14 +746,6 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: help="Start a Fleet API server (REST, experimental)", ) - ex_group.add_argument( - "--vce", - action="store_const", - dest="fleet_api_type", - const=TRANSPORT_TYPE_VCE, - help="Start a Fleet API server (VirtualClientEngine)", - ) - # Fleet API gRPC-rere options grpc_rere_group = parser.add_argument_group( "Fleet API (gRPC-rere) server options", "" @@ -826,36 +781,3 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: type=int, default=1, ) - - # Fleet API VCE options - vce_group = parser.add_argument_group("Fleet API (VCE) server options", "") - vce_group.add_argument( - "--client-app", - help="For example: `client:app` or `project.package.module:wrapper.app`.", - ) - vce_group.add_argument( - "--num-supernodes", - type=int, - help="Number of simulated SuperNodes.", - ) - vce_group.add_argument( - "--backend", - default="ray", - type=str, - help="Simulation backend that executes the ClientApp.", - ) - vce_group.add_argument( - "--backend-config", - type=str, - default='{"client_resources": {"num_cpus":1, "num_gpus":0.0}, "tensorflow": 0}', - help='A JSON formatted stream, e.g \'{"":, "":}\' to ' - "configure a backend. Values supported in are those included by " - "`flwr.common.typing.ConfigsRecordValues`. ", - ) - parser.add_argument( - "--app-dir", - default="", - help="Add specified directory to the PYTHONPATH and load" - "ClientApp from there." - " Default: current working directory.", - ) From 17cd81ab481bc511fd8df878434b60a87c859bbf Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Mon, 27 May 2024 13:13:05 +0200 Subject: [PATCH 022/124] ci(skip:*) Use new base images is nightly CI (#3484) Signed-off-by: Robert Steiner --- .github/workflows/release-nightly.yml | 41 +++++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index f9668131b5a6..939a9581871c 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -17,9 +17,12 @@ jobs: name: ${{ steps.release.outputs.name }} version: ${{ steps.release.outputs.version }} skip: ${{ steps.release.outputs.skip }} + pip-version: ${{ steps.release.outputs.pip-version }} + setuptools-version: ${{ steps.release.outputs.setuptools-version }} steps: - uses: actions/checkout@v4 - name: Bootstrap + id: bootstrap uses: ./.github/actions/bootstrap - name: Release nightly if: github.event.schedule == '0 23 * * *' @@ -37,26 +40,46 @@ jobs: echo "name=$(poetry version | awk {'print $1'})" >> $GITHUB_OUTPUT echo "version=$(poetry version -s)" >> $GITHUB_OUTPUT + echo "pip-version=${{ steps.bootstrap.outputs.pip-version }}" >> "$GITHUB_OUTPUT" + echo "setuptools-version=${{ steps.bootstrap.outputs.setuptools-version }}" >> "$GITHUB_OUTPUT" - build-docker-images: - name: Build nightly images + build-docker-base-images: + name: Build nightly base images if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' && github.event.schedule == '30 23 * * *' uses: ./.github/workflows/_docker-build.yml needs: release-nightly + with: + namespace-repository: flwr/base + file-dir: src/docker/base/ubuntu + build-args: | + PIP_VERSION=${{ needs.release-nightly.outputs.pip-version }} + SETUPTOOLS_VERSION=${{ needs.release-nightly.outputs.setuptools-version }} + FLWR_VERSION=${{ needs.release-nightly.outputs.version }} + FLWR_PACKAGE=${{ needs.release-nightly.outputs.name }} + tags: | + ${{ needs.release-nightly.outputs.version }} + nightly + secrets: + dockerhub-user: ${{ secrets.DOCKERHUB_USERNAME }} + dockerhub-token: ${{ secrets.DOCKERHUB_TOKEN }} + + build-docker-binary-images: + name: Build nightly binary images + if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' && github.event.schedule == '30 23 * * *' + uses: ./.github/workflows/_docker-build.yml + needs: [release-nightly, build-docker-base-images] strategy: fail-fast: false matrix: images: [ - { repository: "flwr/superlink", file-dir: "src/docker/superlink" }, - { repository: "flwr/supernode", file-dir: "src/docker/supernode" }, - { repository: "flwr/serverapp", file-dir: "src/docker/serverapp" } + { repository: "flwr/superlink", file_dir: "src/docker/superlink" }, + { repository: "flwr/supernode", file_dir: "src/docker/supernode" }, + { repository: "flwr/serverapp", file_dir: "src/docker/serverapp" } ] with: namespace-repository: ${{ matrix.images.repository }} - file-dir: ${{ matrix.images.file-dir }} - build-args: | - FLWR_VERSION=${{ needs.release-nightly.outputs.version }} - FLWR_PACKAGE=${{ needs.release-nightly.outputs.name }} + file-dir: ${{ matrix.images.file_dir }} + build-args: BASE_IMAGE=${{ needs.release-nightly.outputs.version }} tags: | ${{ needs.release-nightly.outputs.version }} nightly From ca36bcf494ce37672337395321d993ca0cead814 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 27 May 2024 17:24:09 +0200 Subject: [PATCH 023/124] docs(framework) Add latest Hosted Weblate translation updates (#3516) Co-authored-by: Yan Gao Co-authored-by: Charles Beauville --- .../zh_Hans/LC_MESSAGES/framework-docs.po | 17671 ++++++++-------- 1 file changed, 8881 insertions(+), 8790 deletions(-) diff --git a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po index 4f4d9cfe5214..253dfe0ccc86 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po @@ -30,8 +30,8 @@ msgstr "边缘客户端引擎" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" -"`Flower `_ core framework architecture with Edge " -"Client Engine" +"`Flower `_ core framework architecture with Edge Client " +"Engine" msgstr "具有边缘客户端引擎的`Flower `核心架构" #: ../../source/contributor-explanation-architecture.rst:13 @@ -50,9 +50,10 @@ msgstr "可同步进行的虚拟客户端引擎和边缘客户端引擎" #: ../../source/contributor-explanation-architecture.rst:23 msgid "" -"`Flower `_ core framework architecture with both " -"Virtual Client Engine and Edge Client Engine" -msgstr "具有虚拟客户端引擎和边缘客户端引擎的`Flower `核心架构" +"`Flower `_ core framework architecture with both Virtual " +"Client Engine and Edge Client Engine" +msgstr "" +"具有虚拟客户端引擎和边缘客户端引擎的`Flower `核心架构" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" @@ -61,17 +62,17 @@ msgstr "如何在本地搭建Docker Flower images" #: ../../source/contributor-how-to-build-docker-images.rst:4 #, fuzzy msgid "" -"Flower provides pre-made docker images on `Docker Hub " -"`_ that include all necessary " -"dependencies for running the server. You can also build your own custom " -"docker images from scratch with a different version of Python or Ubuntu " -"if that is what you need. In this guide, we will explain what images " -"exist and how to build them locally." +"Flower provides pre-made docker images on `Docker Hub `_ that include all necessary dependencies for " +"running the server. You can also build your own custom docker images from " +"scratch with a different version of Python or Ubuntu if that is what you " +"need. In this guide, we will explain what images exist and how to build them " +"locally." msgstr "" -"Flower 在 `Docker Hub `_ " -"上提供了预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要," -"也可以使用不同版本的 Python 或 Ubuntu 从头开始构建自己的定制 docker " -"镜像。在本指南中,我们将介绍有哪些镜像,以及如何在本地构建它们。" +"Flower 在 `Docker Hub `_ 上提供了" +"预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要,也可以使" +"用不同版本的 Python 或 Ubuntu 从头开始构建自己的定制 docker 镜像。在本指南" +"中,我们将介绍有哪些镜像,以及如何在本地构建它们。" #: ../../source/contributor-how-to-build-docker-images.rst:9 #, fuzzy @@ -93,51 +94,51 @@ msgstr "验证 Docker 守护进程是否正在运行。" #: ../../source/contributor-how-to-build-docker-images.rst:19 #, fuzzy msgid "" -"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." +"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -"请阅读 :doc:`Run Flower using Docker ` " -"的第一节,其中更详细地介绍了这一步骤。" +"请阅读 :doc:`Run Flower using Docker ` 的第一" +"节,其中更详细地介绍了这一步骤。" #: ../../source/contributor-how-to-build-docker-images.rst:23 #, fuzzy msgid "" "Currently, Flower provides two images, a base image and a server image. " "There will also be a client image soon. The base image, as the name " -"suggests, contains basic dependencies that both the server and the client" -" need. This includes system dependencies, Python and Python tools. The " -"server image is based on the base image, but it additionally installs the" -" Flower server using ``pip``." +"suggests, contains basic dependencies that both the server and the client " +"need. This includes system dependencies, Python and Python tools. The server " +"image is based on the base image, but it additionally installs the Flower " +"server using ``pip``." msgstr "" "目前,Flower 提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜" "像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依" -"赖项、Python 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` " -"额外安装 Flower 服务器。" +"赖项、Python 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` 额外" +"安装 Flower 服务器。" #: ../../source/contributor-how-to-build-docker-images.rst:28 #, fuzzy msgid "" "The build instructions that assemble the images are located in the " -"respective Dockerfiles. You can find them in the subdirectories of " -"``src/docker``." -msgstr "组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` " -"的子目录中找到它们。" +"respective Dockerfiles. You can find them in the subdirectories of ``src/" +"docker``." +msgstr "" +"组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` 的子目录" +"中找到它们。" #: ../../source/contributor-how-to-build-docker-images.rst:31 #, fuzzy msgid "" "Both, base and server image are configured via build arguments. Through " -"build arguments, we can make our build more flexible. For example, in the" -" base image, we can specify the version of Python to install using the " -"``PYTHON_VERSION`` build argument. Some of the build arguments have " -"default values, others must be specified when building the image. All " -"available build arguments for each image are listed in one of the tables " -"below." +"build arguments, we can make our build more flexible. For example, in the " +"base image, we can specify the version of Python to install using the " +"``PYTHON_VERSION`` build argument. Some of the build arguments have default " +"values, others must be specified when building the image. All available " +"build arguments for each image are listed in one of the tables below." msgstr "" "基础镜像和服务器镜像都是通过构建参数配置的。通过联编参数,我们可以使联编更加" -"灵活。例如,在基础镜像中,我们可以使用 ``PYTHON_VERSION`` " -"联编参数指定要安装的 Python 版本。有些联编参数有默认值,有些则必须在联编映像" -"时指定。每个映像的所有可用联编参数都列在下表中。" +"灵活。例如,在基础镜像中,我们可以使用 ``PYTHON_VERSION`` 联编参数指定要安装" +"的 Python 版本。有些联编参数有默认值,有些则必须在联编映像时指定。每个映像的" +"所有可用联编参数都列在下表中。" #: ../../source/contributor-how-to-build-docker-images.rst:38 #, fuzzy @@ -239,19 +240,21 @@ msgstr "默认为 ``22.04``。" #: ../../source/contributor-how-to-build-docker-images.rst:65 #, fuzzy msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1" -" and setuptools 69.0.2:" -msgstr "下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 " -"创建了基本映像:" +"The following example creates a base image with Python 3.11.0, pip 23.0.1 " +"and setuptools 69.0.2:" +msgstr "" +"下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 创建了基本映" +"像:" #: ../../source/contributor-how-to-build-docker-images.rst:76 #, fuzzy msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." -msgstr "图像名称为 ``flwr_base``,标记为 ``0.1." -"0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the " +"build arguments as well as the name and tag can be adapted to your needs. " +"These values serve as examples only." +msgstr "" +"图像名称为 ``flwr_base``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都" +"可以根据需要进行调整。这些值仅供参考。" #: ../../source/contributor-how-to-build-docker-images.rst:80 #, fuzzy @@ -306,28 +309,30 @@ msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-build-docker-images.rst:103 #, fuzzy msgid "" -"The following example creates a server image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.7.0:" -msgstr "下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 " -"创建了一个服务器镜像:" +"The following example creates a server image with the official Flower base " +"image py3.11-ubuntu22.04 and Flower 1.7.0:" +msgstr "" +"下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 创建" +"了一个服务器镜像:" #: ../../source/contributor-how-to-build-docker-images.rst:114 #, fuzzy msgid "" -"The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that" -" the build arguments as well as the name and tag can be adapted to your " +"The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that " +"the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." -msgstr "图像名称为 ``flwr_server``,标记为 ``0.1." -"0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" +msgstr "" +"图像名称为 ``flwr_server``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记" +"都可以根据需要进行调整。这些值仅供参考。" #: ../../source/contributor-how-to-build-docker-images.rst:117 #, fuzzy msgid "" -"If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY`` and " -"``BASE_IMAGE_TAG`` build arguments. The value of ``BASE_REPOSITORY`` must" -" match the name of your image and the value of ``BASE_IMAGE_TAG`` must " -"match the tag of your image." +"If you want to use your own base image instead of the official Flower base " +"image, all you need to do is set the ``BASE_REPOSITORY`` and " +"``BASE_IMAGE_TAG`` build arguments. The value of ``BASE_REPOSITORY`` must " +"match the name of your image and the value of ``BASE_IMAGE_TAG`` must match " +"the tag of your image." msgstr "" "如果您想使用自己的基础图片而不是 Flower 官方的基础图片,只需设置 " "``BASE_REPOSITORY`` 和 ``BASE_IMAGE_TAG`` 联编参数即可。`BASE_REPOSITORY``的" @@ -345,25 +350,26 @@ msgstr "贡献译文" #: ../../source/contributor-how-to-contribute-translations.rst:4 #, fuzzy msgid "" -"Since `Flower 1.5 `_ we have introduced translations to " -"our doc pages, but, as you might have noticed, the translations are often" -" imperfect. If you speak languages other than English, you might be able " -"to help us in our effort to make Federated Learning accessible to as many" -" people as possible by contributing to those translations! This might " -"also be a great opportunity for those wanting to become open source " -"contributors with little prerequisites." +"Since `Flower 1.5 `_ we have introduced translations to our doc pages, " +"but, as you might have noticed, the translations are often imperfect. If you " +"speak languages other than English, you might be able to help us in our " +"effort to make Federated Learning accessible to as many people as possible " +"by contributing to those translations! This might also be a great " +"opportunity for those wanting to become open source contributors with little " +"prerequisites." msgstr "" -"从 `Flower 1.5 `_ " -"开始,我们在文档页面中引入了翻译,但正如你可能已经注意到的,这些翻译往往并不完美。如果您会说英语以外的语言,也许您可以帮助我们翻译这些文档,让更多的人了解" -" Federated Learning!对于那些想成为开源贡献者的人来说,这也是一个很好的机会。" +"从 `Flower 1.5 `_ 开始,我们在文档页面中引入了翻译,但正如你可能已经" +"注意到的,这些翻译往往并不完美。如果您会说英语以外的语言,也许您可以帮助我们" +"翻译这些文档,让更多的人了解 Federated Learning!对于那些想成为开源贡献者的人" +"来说,这也是一个很好的机会。" #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" -"Our translation project is publicly available over on `Weblate " -"`_, this " -"where most of the work will happen." +"Our translation project is publicly available over on `Weblate `_, this where most of " +"the work will happen." msgstr "" "我们的翻译项目已在 \"Weblate `_\"上公开,大部分工作都将在这里进行。" @@ -374,39 +380,41 @@ msgstr "为现有语言作出贡献" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" -"The first thing you will need to do in order to contribute is to create a" -" free Weblate account on this `page " -"`_. More information about" -" profile settings can be found `here " +"The first thing you will need to do in order to contribute is to create a " +"free Weblate account on this `page `_. More information about profile settings can be found `here " "`_." msgstr "" -"您需要做的第一件事就是在本`网页`_上创建一个免费的Weblate帐户。有关个人资料设置的更多信息,请参阅`这里" -" `_。" +"您需要做的第一件事就是在本`网页`_上创建一个免费的Weblate帐户。有关个人资料设置的更多信息,请参阅`这里 " +"`_。" #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" -"Once you are signed in to Weblate, you can navigate to the `Flower " -"Framework project `_. Here, you should see the different existing languages" -" that can be found on the website." +"Once you are signed in to Weblate, you can navigate to the `Flower Framework " +"project `_. " +"Here, you should see the different existing languages that can be found on " +"the website." msgstr "" -"登录到Weblate后,您可以导航到 \"Flower Framework " -"\"项目`_。在这里,您可以看到网站上现有的各种语言。" +"登录到Weblate后,您可以导航到 \"Flower Framework \"项目`_。在这里,您可以看到网站上现有" +"的各种语言。" #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" -"Once you have selected the language you want to contribute to, you should" -" see a similar interface to this:" +"Once you have selected the language you want to contribute to, you should " +"see a similar interface to this:" msgstr "选择您要贡献的语言后,您应该会看到与此类似的界面:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" "The most straight forward option here is to click on the ``Translate`` " -"button on the top right (in the ``Translation status`` section). This " -"will automatically bring you to the translation interface for " -"untranslated strings." -msgstr "最简单的方法是点击右上角(\"翻译状态 \"部分)的 \"翻译 \"按钮。这将自动带您进入未翻译字符串的翻译界面。" +"button on the top right (in the ``Translation status`` section). This will " +"automatically bring you to the translation interface for untranslated " +"strings." +msgstr "" +"最简单的方法是点击右上角(\"翻译状态 \"部分)的 \"翻译 \"按钮。这将自动带您进" +"入未翻译字符串的翻译界面。" #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" @@ -415,43 +423,46 @@ msgstr "这就是界面的样子:" #: ../../source/contributor-how-to-contribute-translations.rst:47 #, fuzzy msgid "" -"You input your translation in the text box at the top and then, once you " -"are happy with it, you either press ``Save and continue`` (to save the " -"translation and go to the next untranslated string), ``Save and stay`` " -"(to save the translation and stay on the same page), ``Suggest`` (to add " -"your translation to suggestions for other users to view), or ``Skip`` (to" -" go to the next untranslated string without saving anything)." +"You input your translation in the text box at the top and then, once you are " +"happy with it, you either press ``Save and continue`` (to save the " +"translation and go to the next untranslated string), ``Save and stay`` (to " +"save the translation and stay on the same page), ``Suggest`` (to add your " +"translation to suggestions for other users to view), or ``Skip`` (to go to " +"the next untranslated string without saving anything)." msgstr "" -"您可以在顶部的文本框中输入翻译内容,满意后按 " -"\"保存并继续\"(保存翻译内容并转到下一个未翻译的字符串)、\"保存并停留\"(保存翻译内容并停留在同一页面)、\"建议\"(将您的翻译添加到建议中供其他用户查看)或" -" \"跳过\"(转到下一个未翻译的字符串而不保存任何内容)。" +"您可以在顶部的文本框中输入翻译内容,满意后按 \"保存并继续\"(保存翻译内容并转" +"到下一个未翻译的字符串)、\"保存并停留\"(保存翻译内容并停留在同一页" +"面)、\"建议\"(将您的翻译添加到建议中供其他用户查看)或 \"跳过\"(转到下一个" +"未翻译的字符串而不保存任何内容)。" #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" "In order to help with the translations, you can see on the bottom the " "``Nearby strings``, the ``Comments`` (from other contributors), the " "``Automatic suggestions`` (from machine translation engines), the " -"translations in ``Other languages``, and the ``History`` of translations " -"for this string." +"translations in ``Other languages``, and the ``History`` of translations for " +"this string." msgstr "" -"为了帮助翻译,您可以在底部看到 \"邻近字符串\"、\"评论\"(来自其他贡献者)、\"自动建议\"(来自机器翻译引擎)、\"其他语言 " -"\"中的翻译以及该字符串的 \"历史翻译\"。" +"为了帮助翻译,您可以在底部看到 \"邻近字符串\"、\"评论\"(来自其他贡献" +"者)、\"自动建议\"(来自机器翻译引擎)、\"其他语言 \"中的翻译以及该字符串的 " +"\"历史翻译\"。" #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" -"On the right, under the ``String information`` section, you can also " -"click the link under ``Source string location`` in order to view the " -"source of the doc file containing the string." -msgstr "在右侧的 \"字符串信息 \"部分,您还可以单击 \"源字符串位置 \"下的链接,以查看包含字符串的 doc 文件的源文件。" +"On the right, under the ``String information`` section, you can also click " +"the link under ``Source string location`` in order to view the source of the " +"doc file containing the string." +msgstr "" +"在右侧的 \"字符串信息 \"部分,您还可以单击 \"源字符串位置 \"下的链接,以查看" +"包含字符串的 doc 文件的源文件。" #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" -"For more information about translating using Weblate, you can check out " -"this `in-depth guide " -"`_." +"For more information about translating using Weblate, you can check out this " +"`in-depth guide `_." msgstr "" -"有关使用 Weblate 进行翻译的更多信息,您可以查看本 \"深入指南 " -"`_\"。" +"有关使用 Weblate 进行翻译的更多信息,您可以查看本 \"深入指南 `_\"。" #: ../../source/contributor-how-to-contribute-translations.rst:67 msgid "Add new languages" @@ -459,12 +470,13 @@ msgstr "添加新语言" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" -"If you want to add a new language, you will first have to contact us, " -"either on `Slack `_, or by opening an issue" -" on our `GitHub repo `_." +"If you want to add a new language, you will first have to contact us, either " +"on `Slack `_, or by opening an issue on our " +"`GitHub repo `_." msgstr "" -"如果您想添加新语言,请先联系我们,可以在 `Slack `_ 上联系,也可以在我们的 " -"`GitHub repo `_ 上提交问题。" +"如果您想添加新语言,请先联系我们,可以在 `Slack `_ 上联系,也可以在我们的 `GitHub repo `_ 上提交问题。" #: ../../source/contributor-how-to-create-new-messages.rst:2 msgid "Creating New Messages" @@ -472,15 +484,16 @@ msgstr "创建新信息" #: ../../source/contributor-how-to-create-new-messages.rst:4 msgid "" -"This is a simple guide for creating a new type of message between the " -"server and clients in Flower." +"This is a simple guide for creating a new type of message between the server " +"and clients in Flower." msgstr "这是一个如何用Flower在服务器和客户端之间创建新类型的信息的简要指导。" #: ../../source/contributor-how-to-create-new-messages.rst:6 msgid "" -"Let's suppose we have the following example functions in " -":code:`server.py` and :code:`numpy_client.py`..." -msgstr "假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." +"Let's suppose we have the following example functions in :code:`server.py` " +"and :code:`numpy_client.py`..." +msgstr "" +"假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." #: ../../source/contributor-how-to-create-new-messages.rst:8 msgid "Server's side:" @@ -492,9 +505,11 @@ msgstr "在客户端:" #: ../../source/contributor-how-to-create-new-messages.rst:26 msgid "" -"Let's now see what we need to implement in order to get this simple " -"function between the server and client to work!" -msgstr "现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要实现哪些功能!" +"Let's now see what we need to implement in order to get this simple function " +"between the server and client to work!" +msgstr "" +"现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要" +"实现哪些功能!" #: ../../source/contributor-how-to-create-new-messages.rst:30 msgid "Message Types for Protocol Buffers" @@ -503,15 +518,15 @@ msgstr "协议缓冲区的信息类型" #: ../../source/contributor-how-to-create-new-messages.rst:32 #, fuzzy msgid "" -"The first thing we need to do is to define a message type for the RPC " -"system in :code:`transport.proto`. Note that we have to do it for both " -"the request and response messages. For more details on the syntax of " -"proto3, please see the `official documentation `_." +"The first thing we need to do is to define a message type for the RPC system " +"in :code:`transport.proto`. Note that we have to do it for both the request " +"and response messages. For more details on the syntax of proto3, please see " +"the `official documentation `_." msgstr "" -"我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC " -"系统的消息类型。请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请参阅官方文档 " -"`_。" +"我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC 系统的消息类型。" +"请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请" +"参阅官方文档 `_。" #: ../../source/contributor-how-to-create-new-messages.rst:35 msgid "Within the :code:`ServerMessage` block:" @@ -523,8 +538,8 @@ msgstr "在 ClientMessage 代码块中:" #: ../../source/contributor-how-to-create-new-messages.rst:70 msgid "" -"Make sure to also add a field of the newly created message type in " -":code:`oneof msg`." +"Make sure to also add a field of the newly created message type in :code:" +"`oneof msg`." msgstr "确保在 :code:`oneof msg` 中也添加一个新创建的消息类型字段。" #: ../../source/contributor-how-to-create-new-messages.rst:72 @@ -545,8 +560,9 @@ msgid "" "datatypes to or from our defined RPC message types. You should add these " "functions in :code:`serde.py`." msgstr "" -"下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC 消息类型或从我们定义的 RPC 消息类型反序列化和反序列化 " -"Python 数据类型。您应该在 :code:`serde.py` 中添加这些函数。" +"下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC 消息" +"类型或从我们定义的 RPC 消息类型反序列化和反序列化 Python 数据类型。您应该在 :" +"code:`serde.py` 中添加这些函数。" #: ../../source/contributor-how-to-create-new-messages.rst:91 msgid "The four functions:" @@ -558,9 +574,11 @@ msgstr "从服务器发送信息" #: ../../source/contributor-how-to-create-new-messages.rst:114 msgid "" -"Now write the request function in your Client Proxy class (e.g., " -":code:`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 serde 函数编写请求函数:" +"Now write the request function in your Client Proxy class (e.g., :code:" +"`grpc_client_proxy.py`) using the serde functions you just created:" +msgstr "" +"现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 " +"serde 函数编写请求函数:" #: ../../source/contributor-how-to-create-new-messages.rst:128 msgid "Receiving the Message by the Client" @@ -568,12 +586,12 @@ msgstr "由客户端接收信息" #: ../../source/contributor-how-to-create-new-messages.rst:130 msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the " -"field of your message and call the :code:`example_response` function. " -"Remember to use the serde functions!" +"Last step! Modify the code in :code:`message_handler.py` to check the field " +"of your message and call the :code:`example_response` function. Remember to " +"use the serde functions!" msgstr "" -"最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用 " -":code:`example_response` 函数。记住使用 serde 函数!" +"最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用 :" +"code:`example_response` 函数。记住使用 serde 函数!" #: ../../source/contributor-how-to-create-new-messages.rst:132 msgid "Within the handle function:" @@ -593,46 +611,51 @@ msgstr "使用 VSCode Dev Containers 进行开发" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" -"When working on the Flower framework we want to ensure that all " -"contributors use the same developer environment to format code or run " -"tests. For this purpose we are using the VSCode Remote Containers " -"extension. What is it? Read the following quote:" +"When working on the Flower framework we want to ensure that all contributors " +"use the same developer environment to format code or run tests. For this " +"purpose we are using the VSCode Remote Containers extension. What is it? " +"Read the following quote:" msgstr "" -"在开发 Flower 框架时,我们希望确保所有贡献者使用相同的开发环境来格式化代码或运行测试。为此,我们使用了 VSCode " -"远程容器扩展。这是什么?请阅读下面这段话:" +"在开发 Flower 框架时,我们希望确保所有贡献者使用相同的开发环境来格式化代码或" +"运行测试。为此,我们使用了 VSCode 远程容器扩展。这是什么?请阅读下面这段话:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" -"The Visual Studio Code Remote - Containers extension lets you use a " -"Docker container as a fully-featured development environment. It allows " -"you to open any folder inside (or mounted into) a container and take " -"advantage of Visual Studio Code's full feature set. A " -":code:`devcontainer.json` file in your project tells VS Code how to " -"access (or create) a development container with a well-defined tool and " -"runtime stack. This container can be used to run an application or to " -"separate tools, libraries, or runtimes needed for working with a " -"codebase." -msgstr "" -"Visual Studio Code Remote - " -"Containers扩展可让你将Docker容器用作功能齐全的开发环境。它允许你打开容器内(或挂载到容器内)的任何文件夹,并利用 Visual " -"Studio Code 的全部功能集。项目中的 :code:`devcontainer.json` 文件会告诉 VS Code " -"如何访问(或创建)一个带有定义明确的工具和运行时栈的开发容器。该容器可用于运行应用程序,也可用于分离处理代码库所需的工具、库或运行时。" +"The Visual Studio Code Remote - Containers extension lets you use a Docker " +"container as a fully-featured development environment. It allows you to open " +"any folder inside (or mounted into) a container and take advantage of Visual " +"Studio Code's full feature set. A :code:`devcontainer.json` file in your " +"project tells VS Code how to access (or create) a development container with " +"a well-defined tool and runtime stack. This container can be used to run an " +"application or to separate tools, libraries, or runtimes needed for working " +"with a codebase." +msgstr "" +"Visual Studio Code Remote - Containers扩展可让你将Docker容器用作功能齐全的开" +"发环境。它允许你打开容器内(或挂载到容器内)的任何文件夹,并利用 Visual " +"Studio Code 的全部功能集。项目中的 :code:`devcontainer.json` 文件会告诉 VS " +"Code 如何访问(或创建)一个带有定义明确的工具和运行时栈的开发容器。该容器可用" +"于运行应用程序,也可用于分离处理代码库所需的工具、库或运行时。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" -"Workspace files are mounted from the local file system or copied or " -"cloned into the container. Extensions are installed and run inside the " -"container, where they have full access to the tools, platform, and file " -"system. This means that you can seamlessly switch your entire development" -" environment just by connecting to a different container." -msgstr "工作区文件从本地文件系统加载,或复制或克隆到容器中。扩展在容器内安装和运行,在容器内它们可以完全访问工具、平台和文件系统。这意味着,只需连接到不同的容器,就能无缝切换整个开发环境。" +"Workspace files are mounted from the local file system or copied or cloned " +"into the container. Extensions are installed and run inside the container, " +"where they have full access to the tools, platform, and file system. This " +"means that you can seamlessly switch your entire development environment " +"just by connecting to a different container." +msgstr "" +"工作区文件从本地文件系统加载,或复制或克隆到容器中。扩展在容器内安装和运行," +"在容器内它们可以完全访问工具、平台和文件系统。这意味着,只需连接到不同的容" +"器,就能无缝切换整个开发环境。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 #, fuzzy msgid "" -"Source: `Official VSCode documentation " -"`_" -msgstr "来源:`VSCode 官方文档 `_" +"Source: `Official VSCode documentation `_" +msgstr "" +"来源:`VSCode 官方文档 `_" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 msgid "Getting started" @@ -641,42 +664,43 @@ msgstr "开始" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 #, fuzzy msgid "" -"Configuring and setting up the :code:`Dockerfile` as well the " -"configuration for the devcontainer can be a bit more involved. The good " -"thing is you don't have to do it. Usually it should be enough to install " -"`Docker `_ on your system and " -"ensure its available on your command line. Additionally, install the " -"`VSCode Containers Extension `_." +"Configuring and setting up the :code:`Dockerfile` as well the configuration " +"for the devcontainer can be a bit more involved. The good thing is you don't " +"have to do it. Usually it should be enough to install `Docker `_ on your system and ensure its available on " +"your command line. Additionally, install the `VSCode Containers Extension " +"`_." msgstr "" -"配置和设置 :code:`Dockerfile` 以及 devcontainer 的配置可能比较复杂。好在你想做就得做。通常只需在系统中安装 " -"Docker 并确保其在命令行中可用即可。此外,请安装 `VSCode Containers Extension " -"`_。" +"配置和设置 :code:`Dockerfile` 以及 devcontainer 的配置可能比较复杂。好在你想" +"做就得做。通常只需在系统中安装 Docker 并确保其在命令行中可用即可。此外,请安" +"装 `VSCode Containers Extension `_。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" -"Now you should be good to go. When starting VSCode, it will ask you to " -"run in the container environment and - if you confirm - automatically " -"build the container and use it. To manually instruct VSCode to use the " -"devcontainer, you can, after installing the extension, click the green " -"area in the bottom left corner of your VSCode window and select the " -"option *(Re)Open Folder in Container*." +"Now you should be good to go. When starting VSCode, it will ask you to run " +"in the container environment and - if you confirm - automatically build the " +"container and use it. To manually instruct VSCode to use the devcontainer, " +"you can, after installing the extension, click the green area in the bottom " +"left corner of your VSCode window and select the option *(Re)Open Folder in " +"Container*." msgstr "" -"现在你应该可以开始了。启动 VSCode 时,它会要求你在容器环境中运行,如果你确认,它会自动构建容器并使用它。要手动指示 VSCode 使用 " -"devcontainer,可以在安装扩展后,点击 VSCode 窗口左下角的绿色区域,然后选择 \"*(重新)在容器中打开文件夹*\"选项。" +"现在你应该可以开始了。启动 VSCode 时,它会要求你在容器环境中运行,如果你确" +"认,它会自动构建容器并使用它。要手动指示 VSCode 使用 devcontainer,可以在安装" +"扩展后,点击 VSCode 窗口左下角的绿色区域,然后选择 \"*(重新)在容器中打开文" +"件夹*\"选项。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" -"In some cases your setup might be more involved. For those cases consult " -"the following sources:" +"In some cases your setup might be more involved. For those cases consult the " +"following sources:" msgstr "在某些情况下,您的设置可能更复杂。有关这些情况,请参考以下资料:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 #, fuzzy msgid "" -"`Developing inside a Container " -"`_" +"`Developing inside a Container `_" msgstr "" "在容器内开发 `_" @@ -684,9 +708,11 @@ msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 #, fuzzy msgid "" -"`Remote development in Containers " -"`_" -msgstr "容器中的远程开发 `_" +"`Remote development in Containers `_" +msgstr "" +"容器中的远程开发 `_" #: ../../source/contributor-how-to-install-development-versions.rst:2 msgid "Install development versions" @@ -702,19 +728,21 @@ msgstr "使用诗歌(推荐)" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" -"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency " -"in ``pyproject.toml`` and then reinstall (don't forget to delete " -"``poetry.lock`` (``rm poetry.lock``) before running ``poetry install``)." +"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency in " +"``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." +"lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" "安装来自 PyPI 的 ``flwr`` 预发布版本:更新 ``pyproject.toml`` 中的 ``flwr`` " -"依赖关系,然后重新安装(运行 ``poetry install` 前,别忘了删除 ``poetry.lock` (``rm " -"poetry.lock`))。" +"依赖关系,然后重新安装(运行 ``poetry install` 前,别忘了删除 ``poetry.lock` " +"(``rm poetry.lock`))。" #: ../../source/contributor-how-to-install-development-versions.rst:12 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (without " "extras)" -msgstr "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (不含额外内容)" +msgstr "" +"``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (不含额外内" +"容)" #: ../../source/contributor-how-to-install-development-versions.rst:13 msgid "" @@ -726,8 +754,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" -"Install ``flwr`` from a local copy of the Flower source code via " -"``pyproject.toml``:" +"Install ``flwr`` from a local copy of the Flower source code via ``pyproject." +"toml``:" msgstr "通过 ``pyproject.toml`` 从 Flower 源代码的本地副本安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:17 @@ -736,11 +764,11 @@ msgstr "``flwr = { path = \"../../\", develop = true }`` (不含额外内容 #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " -"}`` (with extras)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " +"(with extras)" msgstr "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " -"}`` (包含额外内容)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " +"(包含额外内容)" #: ../../source/contributor-how-to-install-development-versions.rst:20 msgid "Install ``flwr`` from a local wheel file via ``pyproject.toml``:" @@ -749,9 +777,11 @@ msgstr "通过 ``pyproject.toml`` 从本地轮子文件安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:22 #, fuzzy msgid "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without" -" extras)" -msgstr "``flwr = { path = \"../../dist/flwr-1.0.0-py3-none-any.whl\" }``(无额外内容)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " +"extras)" +msgstr "" +"``flwr = { path = \"../../dist/flwr-1.0.0-py3-none-any.whl\" }``(无额外内" +"容)" #: ../../source/contributor-how-to-install-development-versions.rst:23 #, fuzzy @@ -768,8 +798,8 @@ msgid "" "Dependency Specification `_" msgstr "" -"有关详细信息,请参阅 Poetry 文档: 诗歌依赖性规范 `_" +"有关详细信息,请参阅 Poetry 文档: 诗歌依赖性规范 `_" #: ../../source/contributor-how-to-install-development-versions.rst:28 msgid "Using pip (recommended on Colab)" @@ -791,7 +821,8 @@ msgstr "`pip install -U -pre flwr[simulation]``(包含额外功能)" msgid "" "Python packages can be installed from git repositories. Use one of the " "following commands to install the Flower directly from GitHub." -msgstr "Python 软件包可以从 git 仓库安装。使用以下命令之一直接从 GitHub 安装 Flower。" +msgstr "" +"Python 软件包可以从 git 仓库安装。使用以下命令之一直接从 GitHub 安装 Flower。" #: ../../source/contributor-how-to-install-development-versions.rst:37 msgid "Install ``flwr`` from the default GitHub branch (``main``):" @@ -799,17 +830,17 @@ msgstr "从 GitHub 的默认分支 (``main`) 安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" -"``pip install flwr@git+https://github.com/adap/flower.git`` (without " -"extras)" -msgstr "`pip install flwr@git+https://github.com/adap/flower.git`` (不含额外功能)" +"``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" +msgstr "" +"`pip install flwr@git+https://github.com/adap/flower.git`` (不含额外功能)" #: ../../source/contributor-how-to-install-development-versions.rst:40 msgid "" "``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` " "(with extras)" msgstr "" -"`pip install " -"flwr[simulation]@git+https://github.com/adap/flower.git``(带附加功能)" +"`pip install flwr[simulation]@git+https://github.com/adap/flower.git``(带附" +"加功能)" #: ../../source/contributor-how-to-install-development-versions.rst:42 msgid "Install ``flwr`` from a specific GitHub branch (``branch-name``):" @@ -820,14 +851,16 @@ msgid "" "``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " "(without extras)" msgstr "" -"`pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " -"(不含附加功能)" +"`pip install flwr@git+https://github.com/adap/flower.git@branch-name`` (不含" +"附加功能)" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" -"@branch-name`` (with extras)" -msgstr "`pip安装flwr[模拟]@git+https://github.com/adap/flower.git@分支名``(带附加功能)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" +"name`` (with extras)" +msgstr "" +"`pip安装flwr[模拟]@git+https://github.com/adap/flower.git@分支名``(带附加功" +"能)" #: ../../source/contributor-how-to-install-development-versions.rst:49 msgid "Open Jupyter Notebooks on Google Colab" @@ -835,33 +868,34 @@ msgstr "在谷歌 Colab 上打开 Jupyter 笔记本" #: ../../source/contributor-how-to-install-development-versions.rst:51 msgid "" -"Open the notebook ``doc/source/tutorial-get-started-with-flower-" -"pytorch.ipynb``:" -msgstr "打开笔记本 ``doc/source/tutorial-get-started-with-flower-pytorch.ipynb``:" +"Open the notebook ``doc/source/tutorial-get-started-with-flower-pytorch." +"ipynb``:" +msgstr "" +"打开笔记本 ``doc/source/tutorial-get-started-with-flower-pytorch.ipynb``:" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" -"Open a development version of the same notebook from branch `branch-name`" -" by changing ``main`` to ``branch-name`` (right after ``blob``):" +"Open a development version of the same notebook from branch `branch-name` by " +"changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" -"将 ``main`` 改为 ``branch-name``(紧跟在 ``blob``之后),从分支 `branch-name` " -"打开同一笔记本的开发版本:" +"将 ``main`` 改为 ``branch-name``(紧跟在 ``blob``之后),从分支 `branch-" +"name` 打开同一笔记本的开发版本:" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:59 msgid "Install a `whl` on Google Colab:" @@ -869,8 +903,8 @@ msgstr "在 Google Colab 上安装 `whl`:" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" -"In the vertical icon grid on the left hand side, select ``Files`` > " -"``Upload to session storage``" +"In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " +"to session storage``" msgstr "在左侧的垂直图标网格中,选择 \"文件\">\"上传到会话存储\"" #: ../../source/contributor-how-to-install-development-versions.rst:62 @@ -881,13 +915,13 @@ msgstr "更新 whl (e.g., ``flwr-1.7.0-py3-none-any.whl``)" #: ../../source/contributor-how-to-install-development-versions.rst:63 #, fuzzy msgid "" -"Change ``!pip install -q 'flwr[simulation]' torch torchvision " -"matplotlib`` to ``!pip install -q 'flwr-1.8.0-py3-none-" -"any.whl[simulation]' torch torchvision matplotlib``" +"Change ``!pip install -q 'flwr[simulation]' torch torchvision matplotlib`` " +"to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " +"torchvision matplotlib``" msgstr "" -"把``!pip install -q 'flwr[simulation]' torch torchvision " -"matplotlib``变为``!pip install -q 'flwr-1.7.0-py3-none-any.whl[simulation]'" -" torch torchvision matplotlib``" +"把``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``变为``!" +"pip install -q 'flwr-1.7.0-py3-none-any.whl[simulation]' torch torchvision " +"matplotlib``" #: ../../source/contributor-how-to-release-flower.rst:2 msgid "Release Flower" @@ -905,10 +939,11 @@ msgstr "在发布期间" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" -"The version number of a release is stated in ``pyproject.toml``. To " -"release a new version of Flower, the following things need to happen (in " -"that order):" -msgstr "版本号在 ``pyproject.toml`` 中说明。要发布 Flower 的新版本,需要完成以下工作(按顺序排列):" +"The version number of a release is stated in ``pyproject.toml``. To release " +"a new version of Flower, the following things need to happen (in that order):" +msgstr "" +"版本号在 ``pyproject.toml`` 中说明。要发布 Flower 的新版本,需要完成以下工作" +"(按顺序排列):" #: ../../source/contributor-how-to-release-flower.rst:11 #, fuzzy @@ -918,39 +953,39 @@ msgid "" "changes to the changelog afterwards until it looks good)." msgstr "" "运行 ``python3 src/py/flwr_tool/update_changelog.py `` 以将每" -"项新更改添加到更新日志中(之后可对更新日志进行手动更改,直到看起来不错为止)" -"。" +"项新更改添加到更新日志中(之后可对更新日志进行手动更改,直到看起来不错为" +"止)。" #: ../../source/contributor-how-to-release-flower.rst:12 #, fuzzy msgid "" -"Once the changelog has been updated with all the changes, run ``./dev" -"/prepare-release-changelog.sh v``, where ```` " -"is the version stated in ``pyproject.toml`` (notice the ``v`` added " -"before it). This will replace the ``Unreleased`` header of the changelog " -"by the version and current date, and it will add a thanking message for " -"the contributors. Open a pull request with those changes." +"Once the changelog has been updated with all the changes, run ``./dev/" +"prepare-release-changelog.sh v``, where ```` is " +"the version stated in ``pyproject.toml`` (notice the ``v`` added before it). " +"This will replace the ``Unreleased`` header of the changelog by the version " +"and current date, and it will add a thanking message for the contributors. " +"Open a pull request with those changes." msgstr "" -"更新更新日志后,运行``./dev/prepare-release-changelog.sh " -"v``,其中````是``pyproject." -"toml``中的版本(注意前面的``v``)。这将用版本和当前日期替换更新日志中的 " -"``Unreleased`` " -"标头,并为贡献者添加一条感谢信息。打开一个包含这些更改的拉取请求。" +"更新更新日志后,运行``./dev/prepare-release-changelog.sh v``,其" +"中````是``pyproject.toml``中的版本(注意前面的``v``)。这将用版" +"本和当前日期替换更新日志中的 ``Unreleased`` 标头,并为贡献者添加一条感谢信" +"息。打开一个包含这些更改的拉取请求。" #: ../../source/contributor-how-to-release-flower.rst:13 #, fuzzy msgid "" "Once the pull request is merged, tag the release commit with the version " -"number as soon as the PR is merged: ``git tag v`` (notice " -"the ``v`` added before the version number), then ``git push --tags``. " -"This will create a draft release on GitHub containing the correct " -"artifacts and the relevant part of the changelog." +"number as soon as the PR is merged: ``git tag v`` (notice the " +"``v`` added before the version number), then ``git push --tags``. This will " +"create a draft release on GitHub containing the correct artifacts and the " +"relevant part of the changelog." msgstr "" -"在 PR 合并后立即用版本号标记发布提交:``git tag v0.12.3``,然后``git push --tags``。这将在 GitHub" -" 上创建一个包含正确工件和更新日志相关部分的发布草案。" +"在 PR 合并后立即用版本号标记发布提交:``git tag v0.12.3``,然后``git push --" +"tags``。这将在 GitHub 上创建一个包含正确工件和更新日志相关部分的发布草案。" #: ../../source/contributor-how-to-release-flower.rst:14 -msgid "Check the draft release on GitHub, and if everything is good, publish it." +msgid "" +"Check the draft release on GitHub, and if everything is good, publish it." msgstr "检查 GitHub 上的发布稿,如果一切正常,就发布它。" #: ../../source/contributor-how-to-release-flower.rst:17 @@ -975,8 +1010,8 @@ msgstr "在 ``changelog.md`` 中添加新的 ``Unreleased`` 部分。" #: ../../source/contributor-how-to-release-flower.rst:25 msgid "" -"Merge the pull request on the same day (i.e., before a new nightly " -"release gets published to PyPI)." +"Merge the pull request on the same day (i.e., before a new nightly release " +"gets published to PyPI)." msgstr "在同一天合并拉取请求(即在新版本发布到 PyPI 之前)。" #: ../../source/contributor-how-to-release-flower.rst:28 @@ -989,9 +1024,11 @@ msgstr "释放前命名" #: ../../source/contributor-how-to-release-flower.rst:33 msgid "" -"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" -" MUST use one of the following naming patterns:" -msgstr "PyPI 支持预发布版本(alpha、beta、release candidate)。预发布版本必须使用以下命名模式之一:" +"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases " +"MUST use one of the following naming patterns:" +msgstr "" +"PyPI 支持预发布版本(alpha、beta、release candidate)。预发布版本必须使用以下" +"命名模式之一:" #: ../../source/contributor-how-to-release-flower.rst:35 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" @@ -1037,38 +1074,41 @@ msgstr "`PEP-440 `_" #: ../../source/contributor-how-to-release-flower.rst:50 msgid "" -"`PyPA Choosing a versioning scheme " -"`_" +"`PyPA Choosing a versioning scheme `_" msgstr "" -"`PyPA 选择版本控制方案 `_" +"`PyPA 选择版本控制方案 `_" #: ../../source/contributor-how-to-release-flower.rst:52 msgid "" -"Note that the approach defined by PyPA is not compatible with SemVer " -"2.0.0 spec, for details consult the `Semantic Versioning Specification " -"`_ (specifically item " -"11 on precedence)." +"Note that the approach defined by PyPA is not compatible with SemVer 2.0.0 " +"spec, for details consult the `Semantic Versioning Specification `_ (specifically item 11 on " +"precedence)." msgstr "" -"请注意,PyPA 所定义的方法与 SemVer 2.0.0 " -"规范不兼容,详情请查阅《语义版本规范》`_(特别是关于优先级的第 11 项)。" +"请注意,PyPA 所定义的方法与 SemVer 2.0.0 规范不兼容,详情请查阅《语义版本规" +"范》`_(特别是关于优先级的" +"第 11 项)。" #: ../../source/contributor-how-to-release-flower.rst:55 msgid "Pre-release classification" msgstr "发布前分类" #: ../../source/contributor-how-to-release-flower.rst:57 -msgid "Should the next pre-release be called alpha, beta, or release candidate?" +msgid "" +"Should the next pre-release be called alpha, beta, or release candidate?" msgstr "下一个预发布版应该叫阿尔法版、贝塔版还是候选发布版?" #: ../../source/contributor-how-to-release-flower.rst:59 msgid "" -"RC: feature complete, no known issues (apart from issues that are " -"classified as \"won't fix\" for the next stable release) - if no issues " -"surface this will become the next stable release" -msgstr "RC:功能完整,无已知问题(除了下一个稳定版中被列为 \"不会修复 \"的问题)--如果没有问题出现,这将成为下一个稳定版" +"RC: feature complete, no known issues (apart from issues that are classified " +"as \"won't fix\" for the next stable release) - if no issues surface this " +"will become the next stable release" +msgstr "" +"RC:功能完整,无已知问题(除了下一个稳定版中被列为 \"不会修复 \"的问题)--如" +"果没有问题出现,这将成为下一个稳定版" #: ../../source/contributor-how-to-release-flower.rst:60 msgid "Beta: feature complete, allowed to have known issues" @@ -1086,11 +1126,12 @@ msgstr "建立虚拟环境" msgid "" "It is recommended to run your Python setup within a virtual environment. " "This guide shows three different examples how to create a virtual " -"environment with pyenv virtualenv, poetry, or Anaconda. You can follow " -"the instructions or choose your preferred setup." +"environment with pyenv virtualenv, poetry, or Anaconda. You can follow the " +"instructions or choose your preferred setup." msgstr "" -"建议在虚拟环境中运行 Python 设置。本指南展示了如何使用 pyenv virtualenv、poes 或 Anaconda " -"创建虚拟环境的三个不同示例。您可以按照说明或选择您喜欢的设置。" +"建议在虚拟环境中运行 Python 设置。本指南展示了如何使用 pyenv virtualenv、" +"poes 或 Anaconda 创建虚拟环境的三个不同示例。您可以按照说明或选择您喜欢的设" +"置。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 msgid "Python Version" @@ -1099,12 +1140,11 @@ msgstr "Python 版本" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 msgid "" -"Flower requires at least `Python 3.8 `_, " -"but `Python 3.10 `_ or above is " -"recommended." +"Flower requires at least `Python 3.8 `_, but " +"`Python 3.10 `_ or above is recommended." msgstr "" -"Flower 至少需要 `Python 3.8 `_,但建议使用 `Python " -"3.10 `_或更高版本。" +"Flower 至少需要 `Python 3.8 `_,但建议使用 " +"`Python 3.10 `_或更高版本。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 msgid "Virutualenv with Pyenv/Virtualenv" @@ -1112,20 +1152,22 @@ msgstr "Virutualenv 和 Pyenv/Virtualenv" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:16 msgid "" -"One of the recommended virtual environment is `pyenv " -"`_/`virtualenv `_. Please see `Flower examples " -"`_ for details." +"One of the recommended virtual environment is `pyenv `_/`virtualenv `_. " +"Please see `Flower examples `_ for details." msgstr "" -"其中一个推荐的虚拟环境是 `pyenv `_/`virtualenv " -"`_。详情请参见 `Flower 示例 " -"`_。" +"其中一个推荐的虚拟环境是 `pyenv `_/" +"`virtualenv `_。详情请参见 " +"`Flower 示例 `_。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:18 msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " "`_ or above:" -msgstr "一旦设置好 Pyenv,就可以用它来安装 `Python 3.10 `_ 或更高版本:" +msgstr "" +"一旦设置好 Pyenv,就可以用它来安装 `Python 3.10 `_ 或更高版本:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:24 msgid "Create the virtualenv with:" @@ -1141,17 +1183,17 @@ msgstr "有诗意的 Virtualenv" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:41 msgid "" -"The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " -"simply create a virtual environment with:" +"The Flower examples are based on `Poetry `_ " +"to manage dependencies. After installing Poetry you simply create a virtual " +"environment with:" msgstr "" -"Flower 示例基于 `Poetry `_ 来管理依赖关系。安装 Poetry" -" 后,只需创建一个虚拟环境即可:" +"Flower 示例基于 `Poetry `_ 来管理依赖关系。" +"安装 Poetry 后,只需创建一个虚拟环境即可:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:47 msgid "" -"If you open a new terminal you can activate the previously created " -"virtual environment with the following command:" +"If you open a new terminal you can activate the previously created virtual " +"environment with the following command:" msgstr "如果打开一个新终端,可以使用以下命令激活之前创建的虚拟环境:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:55 @@ -1160,14 +1202,14 @@ msgstr "使用 Anaconda 的 Virtualenv" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:57 msgid "" -"If you prefer to use Anaconda for your virtual environment then install " -"and setup the `conda `_ package. After setting it up you can " -"create a virtual environment with:" +"If you prefer to use Anaconda for your virtual environment then install and " +"setup the `conda `_ package. After setting it up you can create a virtual " +"environment with:" msgstr "" -"如果你更喜欢在虚拟环境中使用 Anaconda,那么请安装并设置 `conda " -"`_ 软件包。设置完成后,您就可以使用以下工具创建虚拟环境:" +"如果你更喜欢在虚拟环境中使用 Anaconda,那么请安装并设置 `conda `_ 软件包。设" +"置完成后,您就可以使用以下工具创建虚拟环境:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:63 msgid "and activate the virtual environment with:" @@ -1179,11 +1221,11 @@ msgstr "然后呢?" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:73 msgid "" -"As soon as you created your virtual environment you clone one of the " -"`Flower examples `_." +"As soon as you created your virtual environment you clone one of the `Flower " +"examples `_." msgstr "" -"创建虚拟环境后,您可以克隆一个 `Flower 示例 " -"`_。" +"创建虚拟环境后,您可以克隆一个 `Flower 示例 `_。" #: ../../source/contributor-how-to-write-documentation.rst:2 msgid "Write documentation" @@ -1195,24 +1237,23 @@ msgstr "项目布局" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" -"The Flower documentation lives in the ``doc`` directory. The Sphinx-based" -" documentation system supports both reStructuredText (``.rst`` files) and" -" Markdown (``.md`` files)." +"The Flower documentation lives in the ``doc`` directory. The Sphinx-based " +"documentation system supports both reStructuredText (``.rst`` files) and " +"Markdown (``.md`` files)." msgstr "" -"Flower 文档位于 ``doc`` 目录中。基于 Sphinx 的文档系统支持 reStructuredText(``.rst`` 文件)和 " -"Markdown(``.md`` 文件)。" +"Flower 文档位于 ``doc`` 目录中。基于 Sphinx 的文档系统支持 reStructuredText" +"(``.rst`` 文件)和 Markdown(``.md`` 文件)。" #: ../../source/contributor-how-to-write-documentation.rst:10 #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 #, fuzzy msgid "" -"Note that, in order to build the documentation locally (with ``poetry run" -" make html``, like described below), `Pandoc " -"`_ needs to be installed on the " -"system." +"Note that, in order to build the documentation locally (with ``poetry run " +"make html``, like described below), `Pandoc `_ needs to be installed on the system." msgstr "" -"请注意,要在本地构建文档(使用 ``poetry run make html``,如下所述),系统上必须安装 ``Pandoc " -"_`。" +"请注意,要在本地构建文档(使用 ``poetry run make html``,如下所述),系统上必" +"须安装 ``Pandoc _`。" #: ../../source/contributor-how-to-write-documentation.rst:14 msgid "Edit an existing page" @@ -1254,13 +1295,13 @@ msgstr "首次代码贡献" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" -"We welcome contributions to Flower! However, it is not always easy to " -"know where to start. We therefore put together a few recommendations on " -"where to start to increase your chances of getting your PR accepted into " -"the Flower codebase." +"We welcome contributions to Flower! However, it is not always easy to know " +"where to start. We therefore put together a few recommendations on where to " +"start to increase your chances of getting your PR accepted into the Flower " +"codebase." msgstr "" -"我们欢迎为Flower做出代码贡献!然而,要知道从哪里开始并非易事。因此,我们提出了一些建议,告诉您从哪里开始,以增加您的 PR 被 Flower" -" 代码库接受的机会。" +"我们欢迎为Flower做出代码贡献!然而,要知道从哪里开始并非易事。因此,我们提出" +"了一些建议,告诉您从哪里开始,以增加您的 PR 被 Flower 代码库接受的机会。" #: ../../source/contributor-ref-good-first-contributions.rst:11 msgid "Where to start" @@ -1268,10 +1309,12 @@ msgstr "从哪里开始" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" -"Until the Flower core library matures it will be easier to get PR's " -"accepted if they only touch non-core areas of the codebase. Good " -"candidates to get started are:" -msgstr "在 Flower 核心库成熟之前,如果 PR 只涉及代码库中的非核心区域,则会更容易被接受。可以从以下方面入手:" +"Until the Flower core library matures it will be easier to get PR's accepted " +"if they only touch non-core areas of the codebase. Good candidates to get " +"started are:" +msgstr "" +"在 Flower 核心库成熟之前,如果 PR 只涉及代码库中的非核心区域,则会更容易被接" +"受。可以从以下方面入手:" #: ../../source/contributor-ref-good-first-contributions.rst:17 msgid "Documentation: What's missing? What could be expressed more clearly?" @@ -1292,9 +1335,9 @@ msgstr "Flower Baselines的申请" #: ../../source/contributor-ref-good-first-contributions.rst:25 #, fuzzy msgid "" -"If you are not familiar with Flower Baselines, you should probably check-" -"out our `contributing guide for baselines " -"`_." +"If you are not familiar with Flower Baselines, you should probably check-out " +"our `contributing guide for baselines `_." msgstr "" "如果您对 Flower Baselines 还不熟悉,也许可以看看我们的 `Baselines贡献指南 " "`_。" @@ -1302,21 +1345,22 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:27 #, fuzzy msgid "" -"You should then check out the open `issues " -"`_" -" for baseline requests. If you find a baseline that you'd like to work on" -" and that has no assignees, feel free to assign it to yourself and start " -"working on it!" +"You should then check out the open `issues `_ for baseline " +"requests. If you find a baseline that you'd like to work on and that has no " +"assignees, feel free to assign it to yourself and start working on it!" msgstr "" -"然后查看开放的 `issues " -"`_" -" baseline请求。如果您发现了自己想做的baseline,而它还没有被分配,请随时把它分配给自己,然后开始工作!" +"然后查看开放的 `issues `_ baseline请求。如果您发现" +"了自己想做的baseline,而它还没有被分配,请随时把它分配给自己,然后开始工作!" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" -"Otherwise, if you don't find a baseline you'd like to work on, be sure to" -" open a new issue with the baseline request template!" -msgstr "如果您没有找到想要做的baseline,请务必使用baseline请求模板打开一个新问题(GitHub issue)!" +"Otherwise, if you don't find a baseline you'd like to work on, be sure to " +"open a new issue with the baseline request template!" +msgstr "" +"如果您没有找到想要做的baseline,请务必使用baseline请求模板打开一个新问题" +"(GitHub issue)!" #: ../../source/contributor-ref-good-first-contributions.rst:34 msgid "Request for examples" @@ -1325,9 +1369,11 @@ msgstr "示例请求" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" "We wish we had more time to write usage examples because we believe they " -"help users to get started with building what they want to build. Here are" -" a few ideas where we'd be happy to accept a PR:" -msgstr "我们希望有更多的时间来撰写使用示例,因为我们相信这些示例可以帮助用户开始构建他们想要的东西。以下是我们乐意接受 PR 的几个想法:" +"help users to get started with building what they want to build. Here are a " +"few ideas where we'd be happy to accept a PR:" +msgstr "" +"我们希望有更多的时间来撰写使用示例,因为我们相信这些示例可以帮助用户开始构建" +"他们想要的东西。以下是我们乐意接受 PR 的几个想法:" #: ../../source/contributor-ref-good-first-contributions.rst:40 msgid "Llama 2 fine-tuning, with Hugging Face Transformers and PyTorch" @@ -1347,13 +1393,13 @@ msgstr "安全聚合协议" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" -"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg " -"protocol has not been implemented yet, so its diagram and abstraction may" -" not be accurate in practice. The SecAgg protocol can be considered as a " -"special case of the SecAgg+ protocol." +"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg protocol " +"has not been implemented yet, so its diagram and abstraction may not be " +"accurate in practice. The SecAgg protocol can be considered as a special " +"case of the SecAgg+ protocol." msgstr "" -"包括 SecAgg、SecAgg+ 和 LightSecAgg 协议。LightSecAgg " -"协议尚未实施,因此其图表和抽象在实践中可能并不准确。SecAgg 协议可视为 SecAgg+ 协议的特例。" +"包括 SecAgg、SecAgg+ 和 LightSecAgg 协议。LightSecAgg 协议尚未实施,因此其图" +"表和抽象在实践中可能并不准确。SecAgg 协议可视为 SecAgg+ 协议的特例。" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 msgid "The :code:`SecAgg+` abstraction" @@ -1363,17 +1409,17 @@ msgstr "代码:`SecAgg+` 抽象" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 msgid "" "In this implementation, each client will be assigned with a unique index " -"(int) for secure aggregation, and thus many python dictionaries used have" -" keys of int type rather than ClientProxy type." +"(int) for secure aggregation, and thus many python dictionaries used have " +"keys of int type rather than ClientProxy type." msgstr "" -"在此实现中,将为每个客户端分配一个唯一索引(int),以确保聚合的安全性,因此使用的许多 python 字典的键都是 int 类型,而不是 " -"ClientProxy 类型。" +"在此实现中,将为每个客户端分配一个唯一索引(int),以确保聚合的安全性,因此使" +"用的许多 python 字典的键都是 int 类型,而不是 ClientProxy 类型。" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" -"The Flower server will execute and process received results in the " -"following order:" +"The Flower server will execute and process received results in the following " +"order:" msgstr "Flower 服务器将按以下顺序执行和处理收到的结果:" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 @@ -1390,20 +1436,20 @@ msgstr "在 GitHub 上投稿" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" -"This guide is for people who want to get involved with Flower, but who " -"are not used to contributing to GitHub projects." +"This guide is for people who want to get involved with Flower, but who are " +"not used to contributing to GitHub projects." msgstr "本指南适用于想参与 Flower,但不习惯为 GitHub 项目贡献的人。" #: ../../source/contributor-tutorial-contribute-on-github.rst:6 #, fuzzy msgid "" -"If you're familiar with how contributing on GitHub works, you can " -"directly checkout our :doc:`getting started guide for contributors " -"`." +"If you're familiar with how contributing on GitHub works, you can directly " +"checkout our :doc:`getting started guide for contributors `." msgstr "" -"如果您熟悉如何在 GitHub 上贡献,可以直接查看我们的 \"贡献者入门指南\" `_ 和 \"优秀的首次贡献示例\" " -"`_。" +"如果您熟悉如何在 GitHub 上贡献,可以直接查看我们的 \"贡献者入门指南\" " +"`_ 和 \"优秀的" +"首次贡献示例\" `_。" #: ../../source/contributor-tutorial-contribute-on-github.rst:10 msgid "Setting up the repository" @@ -1419,34 +1465,38 @@ msgid "" "Git is a distributed version control tool. This allows for an entire " "codebase's history to be stored and every developer's machine. It is a " "software that will need to be installed on your local machine, you can " -"follow this `guide `_ to set it up." +"follow this `guide `_ to set it up." msgstr "" -"Git 是一种分布式版本控制工具。它可以将整个代码库的历史记录保存在每个开发人员的机器上。您需要在本地计算机上安装该软件,可以按照本指南 " -"`_ 进行设置。" +"Git 是一种分布式版本控制工具。它可以将整个代码库的历史记录保存在每个开发人员" +"的机器上。您需要在本地计算机上安装该软件,可以按照本指南 `_ 进行设置。" #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" "GitHub, itself, is a code hosting platform for version control and " -"collaboration. It allows for everyone to collaborate and work from " -"anywhere on remote repositories." -msgstr "GitHub 本身是一个用于版本控制和协作的代码托管平台。它允许每个人在任何地方对远程仓库进行协作和工作。" +"collaboration. It allows for everyone to collaborate and work from anywhere " +"on remote repositories." +msgstr "" +"GitHub 本身是一个用于版本控制和协作的代码托管平台。它允许每个人在任何地方对远" +"程仓库进行协作和工作。" #: ../../source/contributor-tutorial-contribute-on-github.rst:18 msgid "" "If you haven't already, you will need to create an account on `GitHub " "`_." -msgstr "如果还没有,您需要在 `GitHub `_ 上创建一个账户。" +msgstr "" +"如果还没有,您需要在 `GitHub `_ 上创建一个账户。" #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" -"The idea behind the generic Git and GitHub workflow boils down to this: " -"you download code from a remote repository on GitHub, make changes " -"locally and keep track of them using Git and then you upload your new " -"history back to GitHub." +"The idea behind the generic Git and GitHub workflow boils down to this: you " +"download code from a remote repository on GitHub, make changes locally and " +"keep track of them using Git and then you upload your new history back to " +"GitHub." msgstr "" -"通用的 Git 和 GitHub 工作流程背后的理念可以归结为:从 GitHub 上的远程仓库下载代码,在本地进行修改并使用 Git " -"进行跟踪,然后将新的历史记录上传回 GitHub。" +"通用的 Git 和 GitHub 工作流程背后的理念可以归结为:从 GitHub 上的远程仓库下载" +"代码,在本地进行修改并使用 Git 进行跟踪,然后将新的历史记录上传回 GitHub。" #: ../../source/contributor-tutorial-contribute-on-github.rst:32 msgid "**Forking the Flower repository**" @@ -1455,23 +1505,25 @@ msgstr "**叉花仓库**" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 #, fuzzy msgid "" -"A fork is a personal copy of a GitHub repository. To create one for " -"Flower, you must navigate to ``_ (while " -"connected to your GitHub account) and click the ``Fork`` button situated " -"on the top right of the page." +"A fork is a personal copy of a GitHub repository. To create one for Flower, " +"you must navigate to ``_ (while connected to " +"your GitHub account) and click the ``Fork`` button situated on the top right " +"of the page." msgstr "" "fork 是 GitHub 仓库的个人副本。要为 Flower 创建一个 fork,您必须导航到 " -"https://github.com/adap/flower(同时连接到您的 GitHub 账户),然后点击页面右上方的 ``Fork`` 按钮。" +"https://github.com/adap/flower(同时连接到您的 GitHub 账户),然后点击页面右" +"上方的 ``Fork`` 按钮。" #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" "You can change the name if you want, but this is not necessary as this " -"version of Flower will be yours and will sit inside your own account " -"(i.e., in your own list of repositories). Once created, you should see on" -" the top left corner that you are looking at your own version of Flower." +"version of Flower will be yours and will sit inside your own account (i.e., " +"in your own list of repositories). Once created, you should see on the top " +"left corner that you are looking at your own version of Flower." msgstr "" -"您可以更改名称,但没有必要,因为这个版本的 Flower " -"将是您自己的,并位于您自己的账户中(即,在您自己的版本库列表中)。创建完成后,您会在左上角看到自己的 Flower 版本。" +"您可以更改名称,但没有必要,因为这个版本的 Flower 将是您自己的,并位于您自己" +"的账户中(即,在您自己的版本库列表中)。创建完成后,您会在左上角看到自己的 " +"Flower 版本。" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "**Cloning your forked repository**" @@ -1480,25 +1532,29 @@ msgstr "**克隆你的分叉仓库**" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" "The next step is to download the forked repository on your machine to be " -"able to make changes to it. On your forked repository page, you should " -"first click on the ``Code`` button on the right, this will give you the " -"ability to copy the HTTPS link of the repository." +"able to make changes to it. On your forked repository page, you should first " +"click on the ``Code`` button on the right, this will give you the ability to " +"copy the HTTPS link of the repository." msgstr "" -"下一步是在你的机器上下载分叉版本库,以便对其进行修改。在分叉版本库页面上,首先点击右侧的 \"代码 \"按钮,这样就能复制版本库的 HTTPS " -"链接。" +"下一步是在你的机器上下载分叉版本库,以便对其进行修改。在分叉版本库页面上,首" +"先点击右侧的 \"代码 \"按钮,这样就能复制版本库的 HTTPS 链接。" #: ../../source/contributor-tutorial-contribute-on-github.rst:41 msgid "" "Once you copied the \\, you can open a terminal on your machine, " "navigate to the place you want to download the repository to and type:" -msgstr "一旦复制了 (),你就可以在你的机器上打开一个终端,导航到你想下载软件源的地方,然后键入:" +msgstr "" +"一旦复制了 (),你就可以在你的机器上打开一个终端,导航到你想下载软件" +"源的地方,然后键入:" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 #, fuzzy msgid "" -"This will create a ``flower/`` (or the name of your fork if you renamed " -"it) folder in the current working directory." -msgstr "这将在当前工作目录下创建一个 `flower/`(如果重命名了,则使用 fork 的名称)文件夹。" +"This will create a ``flower/`` (or the name of your fork if you renamed it) " +"folder in the current working directory." +msgstr "" +"这将在当前工作目录下创建一个 `flower/`(如果重命名了,则使用 fork 的名称)文" +"件夹。" #: ../../source/contributor-tutorial-contribute-on-github.rst:66 msgid "**Add origin**" @@ -1510,13 +1566,14 @@ msgstr "然后,您就可以进入存储库文件夹:" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" -"And here we will need to add an origin to our repository. The origin is " -"the \\ of the remote fork repository. To obtain it, we can do as " -"previously mentioned by going to our fork repository on our GitHub " -"account and copying the link." +"And here we will need to add an origin to our repository. The origin is the " +"\\ of the remote fork repository. To obtain it, we can do as " +"previously mentioned by going to our fork repository on our GitHub account " +"and copying the link." msgstr "" "在这里,我们需要为我们的版本库添加一个 origin。origin 是远程 fork 仓库的 " -"\\。要获得它,我们可以像前面提到的那样,访问 GitHub 账户上的分叉仓库并复制链接。" +"\\。要获得它,我们可以像前面提到的那样,访问 GitHub 账户上的分叉仓库并" +"复制链接。" #: ../../source/contributor-tutorial-contribute-on-github.rst:61 msgid "" @@ -1533,28 +1590,33 @@ msgstr "**增加上游**" msgid "" "Now we will add an upstream address to our repository. Still in the same " "directory, we must run the following command:" -msgstr "现在,我们要为版本库添加一个上游地址。还是在同一目录下,我们必须运行以下命令:" +msgstr "" +"现在,我们要为版本库添加一个上游地址。还是在同一目录下,我们必须运行以下命" +"令:" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 -msgid "The following diagram visually explains what we did in the previous steps:" +msgid "" +"The following diagram visually explains what we did in the previous steps:" msgstr "下图直观地解释了我们在前面步骤中的操作:" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" -"The upstream is the GitHub remote address of the parent repository (in " -"this case Flower), i.e. the one we eventually want to contribute to and " -"therefore need an up-to-date history of. The origin is just the GitHub " -"remote address of the forked repository we created, i.e. the copy (fork) " -"in our own account." +"The upstream is the GitHub remote address of the parent repository (in this " +"case Flower), i.e. the one we eventually want to contribute to and therefore " +"need an up-to-date history of. The origin is just the GitHub remote address " +"of the forked repository we created, i.e. the copy (fork) in our own account." msgstr "" -"上游是父版本库(这里是 Flower)的 GitHub 远程地址,即我们最终要贡献的版本库,因此需要最新的历史记录。origin " -"只是我们创建的分叉仓库的 GitHub 远程地址,即我们自己账户中的副本(分叉)。" +"上游是父版本库(这里是 Flower)的 GitHub 远程地址,即我们最终要贡献的版本库," +"因此需要最新的历史记录。origin 只是我们创建的分叉仓库的 GitHub 远程地址,即我" +"们自己账户中的副本(分叉)。" #: ../../source/contributor-tutorial-contribute-on-github.rst:84 msgid "" "To make sure our local version of the fork is up-to-date with the latest " "changes from the Flower repository, we can execute the following command:" -msgstr "为了确保本地版本的分叉程序与 Flower 代码库的最新更改保持一致,我们可以执行以下命令:" +msgstr "" +"为了确保本地版本的分叉程序与 Flower 代码库的最新更改保持一致,我们可以执行以" +"下命令:" #: ../../source/contributor-tutorial-contribute-on-github.rst:93 msgid "Setting up the coding environment" @@ -1564,10 +1626,12 @@ msgstr "设置编码环境" #, fuzzy msgid "" "This can be achieved by following this :doc:`getting started guide for " -"contributors ` (note " -"that you won't need to clone the repository). Once you are able to write " -"code and test it, you can finally start making changes!" -msgstr "您可以按照这份 \"贡献者入门指南\"__(注意,您不需要克隆版本库)来实现这一点。一旦您能够编写代码并进行测试,您就可以开始修改了!" +"contributors ` (note that " +"you won't need to clone the repository). Once you are able to write code and " +"test it, you can finally start making changes!" +msgstr "" +"您可以按照这份 \"贡献者入门指南\"__(注意,您不需要克隆版本库)来实现这一点。" +"一旦您能够编写代码并进行测试,您就可以开始修改了!" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 msgid "Making changes" @@ -1575,8 +1639,7 @@ msgstr "做出改变" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" -"Before making any changes make sure you are up-to-date with your " -"repository:" +"Before making any changes make sure you are up-to-date with your repository:" msgstr "在进行任何更改之前,请确保您的版本库是最新的:" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 @@ -1589,15 +1652,15 @@ msgstr "**创建一个新分支**" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" -"To make the history cleaner and easier to work with, it is good practice " -"to create a new branch for each feature/project that needs to be " -"implemented." -msgstr "为了使历史记录更简洁、更易于操作,为每个需要实现的功能/项目创建一个新分支是个不错的做法。" +"To make the history cleaner and easier to work with, it is good practice to " +"create a new branch for each feature/project that needs to be implemented." +msgstr "" +"为了使历史记录更简洁、更易于操作,为每个需要实现的功能/项目创建一个新分支是个" +"不错的做法。" #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" -"To do so, just run the following command inside the repository's " -"directory:" +"To do so, just run the following command inside the repository's directory:" msgstr "为此,只需在版本库目录下运行以下命令即可:" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 @@ -1605,7 +1668,8 @@ msgid "**Make changes**" msgstr "**进行修改**" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 -msgid "Write great code and create wonderful changes using your favorite editor!" +msgid "" +"Write great code and create wonderful changes using your favorite editor!" msgstr "使用您最喜欢的编辑器编写优秀的代码并创建精彩的更改!" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 @@ -1614,10 +1678,12 @@ msgstr "**测试并格式化您的代码**" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" -"Don't forget to test and format your code! Otherwise your code won't be " -"able to be merged into the Flower repository. This is done so the " -"codebase stays consistent and easy to understand." -msgstr "不要忘记测试和格式化您的代码!否则您的代码将无法并入 Flower 代码库。这样做是为了使代码库保持一致并易于理解。" +"Don't forget to test and format your code! Otherwise your code won't be able " +"to be merged into the Flower repository. This is done so the codebase stays " +"consistent and easy to understand." +msgstr "" +"不要忘记测试和格式化您的代码!否则您的代码将无法并入 Flower 代码库。这样做是" +"为了使代码库保持一致并易于理解。" #: ../../source/contributor-tutorial-contribute-on-github.rst:131 msgid "To do so, we have written a few scripts that you can execute:" @@ -1629,8 +1695,8 @@ msgstr "**舞台变化**" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" -"Before creating a commit that will update your history, you must specify " -"to Git which files it needs to take into account." +"Before creating a commit that will update your history, you must specify to " +"Git which files it needs to take into account." msgstr "在创建更新历史记录的提交之前,必须向 Git 说明需要考虑哪些文件。" #: ../../source/contributor-tutorial-contribute-on-github.rst:143 @@ -1639,10 +1705,12 @@ msgstr "这可以通过:" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" -"To check which files have been modified compared to the last version " -"(last commit) and to see which files are staged for commit, you can use " -"the :code:`git status` command." -msgstr "要查看与上一版本(上次提交)相比哪些文件已被修改,以及哪些文件处于提交阶段,可以使用 :code:`git status` 命令。" +"To check which files have been modified compared to the last version (last " +"commit) and to see which files are staged for commit, you can use the :code:" +"`git status` command." +msgstr "" +"要查看与上一版本(上次提交)相比哪些文件已被修改,以及哪些文件处于提交阶段," +"可以使用 :code:`git status` 命令。" #: ../../source/contributor-tutorial-contribute-on-github.rst:160 msgid "**Commit changes**" @@ -1652,16 +1720,17 @@ msgstr "**提交更改**" msgid "" "Once you have added all the files you wanted to commit using :code:`git " "add`, you can finally create your commit using this command:" -msgstr "使用 :code:`git add` 添加完所有要提交的文件后,就可以使用此命令创建提交了:" +msgstr "" +"使用 :code:`git add` 添加完所有要提交的文件后,就可以使用此命令创建提交了:" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" -"The \\ is there to explain to others what the commit " -"does. It should be written in an imperative style and be concise. An " -"example would be :code:`git commit -m \"Add images to README\"`." +"The \\ is there to explain to others what the commit does. " +"It should be written in an imperative style and be concise. An example would " +"be :code:`git commit -m \"Add images to README\"`." msgstr "" -" 用于向他人解释提交的作用。它应该以命令式风格书写,并且简明扼要。例如 :code:`git commit " -"-m \"Add images to README\"`。" +" 用于向他人解释提交的作用。它应该以命令式风格书写,并且简明" +"扼要。例如 :code:`git commit -m \"Add images to README\"`。" #: ../../source/contributor-tutorial-contribute-on-github.rst:171 msgid "**Push the changes to the fork**" @@ -1669,16 +1738,19 @@ msgstr "**将更改推送到分叉**" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" -"Once we have committed our changes, we have effectively updated our local" -" history, but GitHub has no way of knowing this unless we push our " -"changes to our origin's remote address:" -msgstr "一旦提交了修改,我们就有效地更新了本地历史记录,但除非我们将修改推送到原点的远程地址,否则 GitHub 无法得知:" +"Once we have committed our changes, we have effectively updated our local " +"history, but GitHub has no way of knowing this unless we push our changes to " +"our origin's remote address:" +msgstr "" +"一旦提交了修改,我们就有效地更新了本地历史记录,但除非我们将修改推送到原点的" +"远程地址,否则 GitHub 无法得知:" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 msgid "" "Once this is done, you will see on the GitHub that your forked repo was " "updated with the changes you have made." -msgstr "完成此操作后,您将在 GitHub 上看到您的分叉仓库已根据您所做的更改进行了更新。" +msgstr "" +"完成此操作后,您将在 GitHub 上看到您的分叉仓库已根据您所做的更改进行了更新。" #: ../../source/contributor-tutorial-contribute-on-github.rst:174 msgid "Creating and merging a pull request (PR)" @@ -1690,8 +1762,8 @@ msgstr "**创建 PR**" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" -"Once you have pushed changes, on the GitHub webpage of your repository " -"you should see the following message:" +"Once you have pushed changes, on the GitHub webpage of your repository you " +"should see the following message:" msgstr "推送更改后,在仓库的 GitHub 网页上应该会看到以下信息:" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 @@ -1707,49 +1779,57 @@ msgid "" msgstr "点击 \"比较和拉取请求 \"按钮后,您应该会看到类似下面的内容:" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 -msgid "At the top you have an explanation of which branch will be merged where:" +msgid "" +"At the top you have an explanation of which branch will be merged where:" msgstr "在顶部,你可以看到关于哪个分支将被合并的说明:" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" -"In this example you can see that the request is to merge the branch " -"``doc-fixes`` from my forked repository to branch ``main`` from the " -"Flower repository." -msgstr "在这个例子中,你可以看到请求将我分叉的版本库中的分支 ``doc-fixes`` 合并到 Flower 版本库中的分支 ``main``。" +"In this example you can see that the request is to merge the branch ``doc-" +"fixes`` from my forked repository to branch ``main`` from the Flower " +"repository." +msgstr "" +"在这个例子中,你可以看到请求将我分叉的版本库中的分支 ``doc-fixes`` 合并到 " +"Flower 版本库中的分支 ``main``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" -"The input box in the middle is there for you to describe what your PR " -"does and to link it to existing issues. We have placed comments (that " -"won't be rendered once the PR is opened) to guide you through the " -"process." -msgstr "中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" +"The input box in the middle is there for you to describe what your PR does " +"and to link it to existing issues. We have placed comments (that won't be " +"rendered once the PR is opened) to guide you through the process." +msgstr "" +"中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释" +"(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 #, fuzzy msgid "" "It is important to follow the instructions described in comments. For " -"instance, in order to not break how our changelog system works, you " -"should read the information above the ``Changelog entry`` section " -"carefully. You can also checkout some examples and details in the " -":ref:`changelogentry` appendix." +"instance, in order to not break how our changelog system works, you should " +"read the information above the ``Changelog entry`` section carefully. You " +"can also checkout some examples and details in the :ref:`changelogentry` " +"appendix." msgstr "" -"请务必遵守注释中的说明。例如,为了不破坏我们的更新日志系统,你应该仔细阅读\"" -"`更新日志条目``\"部分上面的信息。您还可以查看 :ref:`changelogentry` " -"附录中的一些示例和细节。" +"请务必遵守注释中的说明。例如,为了不破坏我们的更新日志系统,你应该仔细阅读\"`" +"更新日志条目``\"部分上面的信息。您还可以查看 :ref:`changelogentry` 附录中的一" +"些示例和细节。" #: ../../source/contributor-tutorial-contribute-on-github.rst:200 msgid "" "At the bottom you will find the button to open the PR. This will notify " -"reviewers that a new PR has been opened and that they should look over it" -" to merge or to request changes." -msgstr "在底部,您可以找到打开 PR 的按钮。这将通知审核人员新的 PR 已经打开,他们应该查看该 PR 以进行合并或要求修改。" +"reviewers that a new PR has been opened and that they should look over it to " +"merge or to request changes." +msgstr "" +"在底部,您可以找到打开 PR 的按钮。这将通知审核人员新的 PR 已经打开,他们应该" +"查看该 PR 以进行合并或要求修改。" #: ../../source/contributor-tutorial-contribute-on-github.rst:203 msgid "" -"If your PR is not yet ready for review, and you don't want to notify " -"anyone, you have the option to create a draft pull request:" -msgstr "如果您的 PR 尚未准备好接受审核,而且您不想通知任何人,您可以选择创建一个草案拉取请求:" +"If your PR is not yet ready for review, and you don't want to notify anyone, " +"you have the option to create a draft pull request:" +msgstr "" +"如果您的 PR 尚未准备好接受审核,而且您不想通知任何人,您可以选择创建一个草案" +"拉取请求:" #: ../../source/contributor-tutorial-contribute-on-github.rst:208 msgid "**Making new changes**" @@ -1758,9 +1838,11 @@ msgstr "**作出新的改变**" #: ../../source/contributor-tutorial-contribute-on-github.rst:208 msgid "" "Once the PR has been opened (as draft or not), you can still push new " -"commits to it the same way we did before, by making changes to the branch" -" associated with the PR." -msgstr "一旦 PR 被打开(无论是否作为草案),你仍然可以像以前一样,通过修改与 PR 关联的分支来推送新的提交。" +"commits to it the same way we did before, by making changes to the branch " +"associated with the PR." +msgstr "" +"一旦 PR 被打开(无论是否作为草案),你仍然可以像以前一样,通过修改与 PR 关联" +"的分支来推送新的提交。" #: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "**Review the PR**" @@ -1768,14 +1850,14 @@ msgstr "**审查 PR**" #: ../../source/contributor-tutorial-contribute-on-github.rst:211 msgid "" -"Once the PR has been opened or once the draft PR has been marked as " -"ready, a review from code owners will be automatically requested:" +"Once the PR has been opened or once the draft PR has been marked as ready, a " +"review from code owners will be automatically requested:" msgstr "一旦 PR 被打开或 PR 草案被标记为就绪,就会自动要求代码所有者进行审核:" #: ../../source/contributor-tutorial-contribute-on-github.rst:215 msgid "" -"Code owners will then look into the code, ask questions, request changes " -"or validate the PR." +"Code owners will then look into the code, ask questions, request changes or " +"validate the PR." msgstr "然后,代码所有者会查看代码、提出问题、要求修改或验证 PR。" #: ../../source/contributor-tutorial-contribute-on-github.rst:217 @@ -1784,8 +1866,8 @@ msgstr "如果有正在进行的更改请求,合并将被阻止。" #: ../../source/contributor-tutorial-contribute-on-github.rst:221 msgid "" -"To resolve them, just push the necessary changes to the branch associated" -" with the PR:" +"To resolve them, just push the necessary changes to the branch associated " +"with the PR:" msgstr "要解决这些问题,只需将必要的更改推送到与 PR 关联的分支即可:" #: ../../source/contributor-tutorial-contribute-on-github.rst:225 @@ -1794,8 +1876,7 @@ msgstr "并解决对话:" #: ../../source/contributor-tutorial-contribute-on-github.rst:229 msgid "" -"Once all the conversations have been resolved, you can re-request a " -"review." +"Once all the conversations have been resolved, you can re-request a review." msgstr "一旦所有对话都得到解决,您就可以重新申请审核。" #: ../../source/contributor-tutorial-contribute-on-github.rst:250 @@ -1804,15 +1885,19 @@ msgstr "**一旦 PR 被合并**" #: ../../source/contributor-tutorial-contribute-on-github.rst:233 msgid "" -"If all the automatic tests have passed and reviewers have no more changes" -" to request, they can approve the PR and merge it." -msgstr "如果所有自动测试都已通过,且审核员不再需要修改,他们就可以批准 PR 并将其合并。" +"If all the automatic tests have passed and reviewers have no more changes to " +"request, they can approve the PR and merge it." +msgstr "" +"如果所有自动测试都已通过,且审核员不再需要修改,他们就可以批准 PR 并将其合" +"并。" #: ../../source/contributor-tutorial-contribute-on-github.rst:237 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" -msgstr "合并后,您可以在 GitHub 上删除该分支(会出现一个删除按钮),也可以在本地删除该分支:" +msgstr "" +"合并后,您可以在 GitHub 上删除该分支(会出现一个删除按钮),也可以在本地删除" +"该分支:" #: ../../source/contributor-tutorial-contribute-on-github.rst:244 msgid "Then you should update your forked repository by doing:" @@ -1829,28 +1914,33 @@ msgstr "问题" #: ../../source/contributor-tutorial-contribute-on-github.rst:258 #, fuzzy msgid "" -"For our documentation, we've started to use the `Diàtaxis framework " -"`_." -msgstr "对于我们的文档,我们已经开始使用 \"Diàtaxis 框架 `_\"。" +"For our documentation, we've started to use the `Diàtaxis framework `_." +msgstr "" +"对于我们的文档,我们已经开始使用 \"Diàtaxis 框架 `_\"。" #: ../../source/contributor-tutorial-contribute-on-github.rst:260 #, fuzzy msgid "" -"Our \"How to\" guides should have titles that continue the sentence \"How" -" to …\", for example, \"How to upgrade to Flower 1.0\"." -msgstr "我们的 \"如何 \"指南的标题应延续 \"如何...... \"的句式,例如 \"如何升级到 Flower 1.0\"。" +"Our \"How to\" guides should have titles that continue the sentence \"How to " +"…\", for example, \"How to upgrade to Flower 1.0\"." +msgstr "" +"我们的 \"如何 \"指南的标题应延续 \"如何...... \"的句式,例如 \"如何升级到 " +"Flower 1.0\"。" #: ../../source/contributor-tutorial-contribute-on-github.rst:262 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." -msgstr "我们的大多数指南还没有采用这种新格式,而更改其标题(不幸的是)比人们想象的要复杂得多。" +msgstr "" +"我们的大多数指南还没有采用这种新格式,而更改其标题(不幸的是)比人们想象的要" +"复杂得多。" #: ../../source/contributor-tutorial-contribute-on-github.rst:264 #, fuzzy msgid "" -"This issue is about changing the title of a doc from present continuous " -"to present simple." +"This issue is about changing the title of a doc from present continuous to " +"present simple." msgstr "这个问题是关于将文档标题从现在进行时改为现在进行时。" #: ../../source/contributor-tutorial-contribute-on-github.rst:266 @@ -1858,7 +1948,8 @@ msgstr "这个问题是关于将文档标题从现在进行时改为现在进行 msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" -msgstr "以 \"保存进度 \"为例,我们将其改为 \"保存进度\"。这是否通过了我们的检查?" +msgstr "" +"以 \"保存进度 \"为例,我们将其改为 \"保存进度\"。这是否通过了我们的检查?" #: ../../source/contributor-tutorial-contribute-on-github.rst:268 #, fuzzy @@ -1879,7 +1970,9 @@ msgstr "解决方案" msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " "After cloning and setting up the Flower repo, here's what you should do:" -msgstr "这只是一个很小的改动,但可以让我们测试你的端到端设置。克隆并设置好 Flower repo 后,你应该这样做:" +msgstr "" +"这只是一个很小的改动,但可以让我们测试你的端到端设置。克隆并设置好 Flower " +"repo 后,你应该这样做:" #: ../../source/contributor-tutorial-contribute-on-github.rst:277 #, fuzzy @@ -1896,11 +1989,11 @@ msgstr "在 `.rst` 文件中进行修改(注意,标题下的破折号应与 #: ../../source/contributor-tutorial-contribute-on-github.rst:279 #, fuzzy msgid "" -"Build the docs and `check the result `_" +"Build the docs and `check the result `_" msgstr "" -"构建文档并检查结果: ``_" +"构建文档并检查结果: ``_" #: ../../source/contributor-tutorial-contribute-on-github.rst:282 msgid "Rename file" @@ -1908,13 +2001,14 @@ msgstr "重命名文件" #: ../../source/contributor-tutorial-contribute-on-github.rst:284 msgid "" -"You might have noticed that the file name still reflects the old wording." -" If we just change the file, then we break all existing links to it - it " -"is **very important** to avoid that, breaking links can harm our search " -"engine ranking." +"You might have noticed that the file name still reflects the old wording. If " +"we just change the file, then we break all existing links to it - it is " +"**very important** to avoid that, breaking links can harm our search engine " +"ranking." msgstr "" -"您可能已经注意到,文件名仍然反映了旧的措辞。如果我们只是更改文件,那么就会破坏与该文件的所有现有链接--" -"避免这种情况是***重要的,破坏链接会损害我们的搜索引擎排名。" +"您可能已经注意到,文件名仍然反映了旧的措辞。如果我们只是更改文件,那么就会破" +"坏与该文件的所有现有链接--避免这种情况是***重要的,破坏链接会损害我们的搜索引" +"擎排名。" #: ../../source/contributor-tutorial-contribute-on-github.rst:287 #, fuzzy @@ -1934,9 +2028,11 @@ msgstr "在 `doc/source/conf.py` 中添加重定向规则" #: ../../source/contributor-tutorial-contribute-on-github.rst:292 #, fuzzy msgid "" -"This will cause a redirect from ``saving-progress.html`` to ``save-" -"progress.html``, old links will continue to work." -msgstr "这将导致从 `saving-progress.html` 重定向到 `save-progress.html`,旧链接将继续工作。" +"This will cause a redirect from ``saving-progress.html`` to ``save-progress." +"html``, old links will continue to work." +msgstr "" +"这将导致从 `saving-progress.html` 重定向到 `save-progress.html`,旧链接将继续" +"工作。" #: ../../source/contributor-tutorial-contribute-on-github.rst:295 msgid "Apply changes in the index file" @@ -1948,7 +2044,9 @@ msgid "" "For the lateral navigation bar to work properly, it is very important to " "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." -msgstr "要使横向导航栏正常工作,更新 `index.rst` 文件也非常重要。我们就是在这里定义整个导航栏的结构。" +msgstr "" +"要使横向导航栏正常工作,更新 `index.rst` 文件也非常重要。我们就是在这里定义整" +"个导航栏的结构。" #: ../../source/contributor-tutorial-contribute-on-github.rst:300 #, fuzzy @@ -1962,8 +2060,8 @@ msgstr "开放式 PR" #: ../../source/contributor-tutorial-contribute-on-github.rst:305 #, fuzzy msgid "" -"Commit the changes (commit messages are always imperative: \"Do " -"something\", in this case \"Change …\")" +"Commit the changes (commit messages are always imperative: \"Do something\", " +"in this case \"Change …\")" msgstr "提交更改(提交信息总是命令式的:\"做某事\",这里是 \"更改......\")" #: ../../source/contributor-tutorial-contribute-on-github.rst:306 @@ -1988,28 +2086,31 @@ msgstr "如何撰写好的公关标题" #: ../../source/contributor-tutorial-contribute-on-github.rst:315 msgid "" -"A well-crafted PR title helps team members quickly understand the purpose" -" and scope of the changes being proposed. Here's a guide to help you " -"write a good GitHub PR title:" -msgstr "一个精心撰写的公关标题能帮助团队成员迅速了解所提修改的目的和范围。以下指南可帮助您撰写一个好的 GitHub PR 标题:" +"A well-crafted PR title helps team members quickly understand the purpose " +"and scope of the changes being proposed. Here's a guide to help you write a " +"good GitHub PR title:" +msgstr "" +"一个精心撰写的公关标题能帮助团队成员迅速了解所提修改的目的和范围。以下指南可" +"帮助您撰写一个好的 GitHub PR 标题:" #: ../../source/contributor-tutorial-contribute-on-github.rst:317 msgid "" -"1. Be Clear and Concise: Provide a clear summary of the changes in a " -"concise manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" " -"\"Update,\" or \"Fix\" to indicate the purpose. 1. Include Relevant " -"Information: Mention the affected feature or module for context. 1. Keep " -"it Short: Avoid lengthy titles for easy readability. 1. Use Proper " -"Capitalization and Punctuation: Follow grammar rules for clarity." +"1. Be Clear and Concise: Provide a clear summary of the changes in a concise " +"manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" \"Update,\" " +"or \"Fix\" to indicate the purpose. 1. Include Relevant Information: Mention " +"the affected feature or module for context. 1. Keep it Short: Avoid lengthy " +"titles for easy readability. 1. Use Proper Capitalization and Punctuation: " +"Follow grammar rules for clarity." msgstr "" -"1. 简明扼要: 以简明扼要的方式清楚地概述变化。1. 使用可操作的动词: 使用 \"添加\"、\"更新 \"或 \"修复 " -"\"等动词来表明目的。1. 包含相关信息: 提及受影响的功能或模块以了解上下文。1. 简短:避免冗长的标题,以方便阅读。1. " -"使用正确的大小写和标点符号: 遵守语法规则,以确保清晰。" +"1. 简明扼要: 以简明扼要的方式清楚地概述变化。1. 使用可操作的动词: 使用 \"添" +"加\"、\"更新 \"或 \"修复 \"等动词来表明目的。1. 包含相关信息: 提及受影响的功" +"能或模块以了解上下文。1. 简短:避免冗长的标题,以方便阅读。1. 使用正确的大小" +"写和标点符号: 遵守语法规则,以确保清晰。" #: ../../source/contributor-tutorial-contribute-on-github.rst:323 msgid "" -"Let's start with a few examples for titles that should be avoided because" -" they do not provide meaningful information:" +"Let's start with a few examples for titles that should be avoided because " +"they do not provide meaningful information:" msgstr "让我们先举例说明几个应该避免使用的标题,因为它们不能提供有意义的信息:" #: ../../source/contributor-tutorial-contribute-on-github.rst:325 @@ -2034,10 +2135,12 @@ msgstr "更改 SomeModule" #: ../../source/contributor-tutorial-contribute-on-github.rst:331 msgid "" -"Here are a few positive examples which provide helpful information " -"without repeating how they do it, as that is already visible in the " -"\"Files changed\" section of the PR:" -msgstr "这里有几个正面的例子,提供了有用的信息,但没有重复他们是如何做的,因为在 PR 的 \"已更改文件 \"部分已经可以看到:" +"Here are a few positive examples which provide helpful information without " +"repeating how they do it, as that is already visible in the \"Files " +"changed\" section of the PR:" +msgstr "" +"这里有几个正面的例子,提供了有用的信息,但没有重复他们是如何做的,因为在 PR " +"的 \"已更改文件 \"部分已经可以看到:" #: ../../source/contributor-tutorial-contribute-on-github.rst:333 msgid "Update docs banner to mention Flower Summit 2023" @@ -2053,13 +2156,13 @@ msgstr "删除 FedAvg 子类化策略中的多余属性" #: ../../source/contributor-tutorial-contribute-on-github.rst:336 #, fuzzy -msgid "Add CI job to deploy the staging system when the ``main`` branch changes" +msgid "" +"Add CI job to deploy the staging system when the ``main`` branch changes" msgstr "添加 CI 作业,以便在 \"主 \"分支发生变化时部署暂存系统" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"Add new amazing library which will be used to improve the simulation " -"engine" +"Add new amazing library which will be used to improve the simulation engine" msgstr "添加新的惊人库,用于改进模拟引擎" #: ../../source/contributor-tutorial-contribute-on-github.rst:341 @@ -2073,16 +2176,15 @@ msgstr "接下来的步骤" #: ../../source/contributor-tutorial-contribute-on-github.rst:343 msgid "" -"Once you have made your first PR, and want to contribute more, be sure to" -" check out the following :" +"Once you have made your first PR, and want to contribute more, be sure to " +"check out the following :" msgstr "一旦您完成了第一份 PR,并希望做出更多贡献,请务必查看以下内容:" #: ../../source/contributor-tutorial-contribute-on-github.rst:345 #, fuzzy msgid "" -":doc:`Good first contributions `, where you should particularly look into the " -":code:`baselines` contributions." +":doc:`Good first contributions `, " +"where you should particularly look into the :code:`baselines` contributions." msgstr "" "`优秀的首次贡献 `_,在这里你应该特别看看 :code:`baselines` 的贡献。" @@ -2100,50 +2202,52 @@ msgstr "更新日志" #: ../../source/contributor-tutorial-contribute-on-github.rst:356 #, fuzzy msgid "" -"When opening a new PR, inside its description, there should be a " -"``Changelog entry`` header." +"When opening a new PR, inside its description, there should be a ``Changelog " +"entry`` header." msgstr "打开一个新 PR 时,在其描述中应有一个 ``Changelog entry`` 标头。" #: ../../source/contributor-tutorial-contribute-on-github.rst:358 #, fuzzy msgid "" -"Above this header you should see the following comment that explains how " -"to write your changelog entry:" +"Above this header you should see the following comment that explains how to " +"write your changelog entry:" msgstr "在页眉上方,你会看到以下注释,说明如何编写更新日志条目:" #: ../../source/contributor-tutorial-contribute-on-github.rst:360 #, fuzzy msgid "" "Inside the following 'Changelog entry' section, you should put the " -"description of your changes that will be added to the changelog alongside" -" your PR title." -msgstr "在下面的 \"更新日志条目 \"部分中,您应该在 PR " -"标题旁边写上将添加到更新日志中的更改描述。" +"description of your changes that will be added to the changelog alongside " +"your PR title." +msgstr "" +"在下面的 \"更新日志条目 \"部分中,您应该在 PR 标题旁边写上将添加到更新日志中" +"的更改描述。" #: ../../source/contributor-tutorial-contribute-on-github.rst:363 #, fuzzy msgid "" -"If the section is completely empty (without any token) or non-existent, " -"the changelog will just contain the title of the PR for the changelog " -"entry, without any description." -msgstr "如果该部分完全为空(没有任何标记)或不存在,更新日志将只包含更新日志条目的 " +"If the section is completely empty (without any token) or non-existent, the " +"changelog will just contain the title of the PR for the changelog entry, " +"without any description." +msgstr "" +"如果该部分完全为空(没有任何标记)或不存在,更新日志将只包含更新日志条目的 " "PR 标题,而不包含任何描述。" #: ../../source/contributor-tutorial-contribute-on-github.rst:366 #, fuzzy msgid "" -"If the section contains some text other than tokens, it will use it to " -"add a description to the change." +"If the section contains some text other than tokens, it will use it to add a " +"description to the change." msgstr "如果该部分包含标记以外的文本,它将使用这些文本为更改添加说明。" #: ../../source/contributor-tutorial-contribute-on-github.rst:368 #, fuzzy msgid "" -"If the section contains one of the following tokens it will ignore any " -"other text and put the PR under the corresponding section of the " -"changelog:" -msgstr "如果该部分包含以下标记之一,它将忽略任何其他文本,并将 PR " -"放在更新日志的相应部分下:" +"If the section contains one of the following tokens it will ignore any other " +"text and put the PR under the corresponding section of the changelog:" +msgstr "" +"如果该部分包含以下标记之一,它将忽略任何其他文本,并将 PR 放在更新日志的相应" +"部分下:" #: ../../source/contributor-tutorial-contribute-on-github.rst:370 #, fuzzy @@ -2190,70 +2294,78 @@ msgstr "其内容必须有特定的格式。我们将分析每种可能性的作 #: ../../source/contributor-tutorial-contribute-on-github.rst:386 #, fuzzy msgid "" -"If the ``### Changelog entry`` section contains nothing or doesn't exist," -" the following text will be added to the changelog::" -msgstr "如果 ``#### Changelog entry`` " -"部分不包含任何内容或不存在,则会在更新日志中添加以下文本::" +"If the ``### Changelog entry`` section contains nothing or doesn't exist, " +"the following text will be added to the changelog::" +msgstr "" +"如果 ``#### Changelog entry`` 部分不包含任何内容或不存在,则会在更新日志中添" +"加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:390 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains a description (and no " "token), the following text will be added to the changelog::" -msgstr "如果 ``#### Changelog entry`` " -"部分包含描述(但没有标记),则会在更新日志中添加以下文本::" +msgstr "" +"如果 ``#### Changelog entry`` 部分包含描述(但没有标记),则会在更新日志中添" +"加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:396 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, nothing will " "change in the changelog." -msgstr "如果 ``#### Changelog entry`` 部分包含 " -"````,更新日志中将不会有任何更改。" +msgstr "" +"如果 ``#### Changelog entry`` 部分包含 ````,更新日志中将不会有任何更" +"改。" #: ../../source/contributor-tutorial-contribute-on-github.rst:398 #, fuzzy msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" -msgstr "如果 ``### Changelog entry`` 部分包含 " -"````,则会在更新日志中添加以下文本::" +"If the ``### Changelog entry`` section contains ````, the following " +"text will be added to the changelog::" +msgstr "" +"如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加以下" +"文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:402 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "如果``### " -"更新日志条目``部分包含``<基准线>``,则会在更新日志中添加以下文本::" +msgstr "" +"如果``### 更新日志条目``部分包含``<基准线>``,则会在更新日志中添加以下文" +"本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:406 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "如果``### 更新日志条目``部分包含``<示例>``,则会在更新日志中添加以下文本::" +msgstr "" +"如果``### 更新日志条目``部分包含``<示例>``,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:410 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the following " "text will be added to the changelog::" -msgstr "如果``### 更新日志条目``部分包含````,则会在更新日志中添加以下文本::" +msgstr "" +"如果``### 更新日志条目``部分包含````,则会在更新日志中添加以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:414 #, fuzzy msgid "" "If the ``### Changelog entry`` section contains ````, the " "following text will be added to the changelog::" -msgstr "如果 ``### Changelog entry`` 部分包含 " -"````,则会在更新日志中添加以下文本::" +msgstr "" +"如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加" +"以下文本::" #: ../../source/contributor-tutorial-contribute-on-github.rst:418 #, fuzzy msgid "" -"Note that only one token must be provided, otherwise, only the first " -"action (in the order listed above), will be performed." +"Note that only one token must be provided, otherwise, only the first action " +"(in the order listed above), will be performed." msgstr "请注意,必须只提供一个标记,否则将只执行第一个操作(按上述顺序)。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 @@ -2278,18 +2390,21 @@ msgid "(Optional) `pyenv `_" msgstr "(可选) `pyenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 -msgid "(Optional) `pyenv-virtualenv `_" -msgstr "(可选) `pyenv-virtualenv `_" +msgid "" +"(Optional) `pyenv-virtualenv `_" +msgstr "" +"(可选) `pyenv-virtualenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 #, fuzzy msgid "" "Flower uses :code:`pyproject.toml` to manage dependencies and configure " -"development tools (the ones which support it). Poetry is a build tool " -"which supports `PEP 517 `_." +"development tools (the ones which support it). Poetry is a build tool which " +"supports `PEP 517 `_." msgstr "" -"Flower 使用 :code:`pyproject.toml` 来管理依赖关系和配置开发工具(支持它的)。Poetry 是一种支持 `PEP " -"517 `_ 的构建工具。" +"Flower 使用 :code:`pyproject.toml` 来管理依赖关系和配置开发工具(支持它的)。" +"Poetry 是一种支持 `PEP 517 `_ 的构" +"建工具。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 msgid "Developer Machine Setup" @@ -2313,16 +2428,17 @@ msgstr "适用于 macOS" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 #, fuzzy msgid "" -"Install `homebrew `_. Don't forget the post-" -"installation actions to add `brew` to your PATH." -msgstr "安装 `homebrew `_。别忘了安装后的操作,将 `brew` " -"添加到你的 PATH。" +"Install `homebrew `_. Don't forget the post-installation " +"actions to add `brew` to your PATH." +msgstr "" +"安装 `homebrew `_。别忘了安装后的操作,将 `brew` 添加到你" +"的 PATH。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 #, fuzzy msgid "" -"Install `xz` (to install different Python versions) and `pandoc` to build" -" the docs::" +"Install `xz` (to install different Python versions) and `pandoc` to build " +"the docs::" msgstr "安装 `xz`(用于安装不同的 Python 版本)和 `pandoc` 以构建文档::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 @@ -2333,8 +2449,8 @@ msgstr "针对 Ubuntu" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 #, fuzzy msgid "" -"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " -"necessary packages::" +"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all necessary " +"packages::" msgstr "确保您的系统(Ubuntu 22.04+)为最新版本,并安装了所有必要的软件包::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 @@ -2347,47 +2463,50 @@ msgstr "创建/删除虚拟环境" msgid "" "1. Clone the `Flower repository `_ from " "GitHub::" -msgstr "首先,从 GitHub 克隆 \"Flower 存储库 `_\":" +msgstr "" +"首先,从 GitHub 克隆 \"Flower 存储库 `_\":" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 #, fuzzy msgid "" -"Let's create the Python environment for all-things Flower. If you wish to" -" use :code:`pyenv`, we provide two convenience scripts that you can use. " -"If you prefer using something else than :code:`pyenv`, create a new " +"Let's create the Python environment for all-things Flower. If you wish to " +"use :code:`pyenv`, we provide two convenience scripts that you can use. If " +"you prefer using something else than :code:`pyenv`, create a new " "environment, activate and skip to the last point where all packages are " "installed." msgstr "" -"让我们为 Flower 创建一个 Python 环境。如果您想使用 " -":code:`pyenv`,我们提供了两个方便的脚本供您使用。如果你不喜欢使用 " -":code:`pyenv`,请创建一个新环境,激活并跳到最后一点,即安装所有软件包。" +"让我们为 Flower 创建一个 Python 环境。如果您想使用 :code:`pyenv`,我们提供了" +"两个方便的脚本供您使用。如果你不喜欢使用 :code:`pyenv`,请创建一个新环境,激" +"活并跳到最后一点,即安装所有软件包。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 #, fuzzy msgid "" -"If you don't have :code:`pyenv` installed, the following script that will" -" install it, set it up, and create the virtual environment (with " -":code:`Python 3.8.17` by default)::" +"If you don't have :code:`pyenv` installed, the following script that will " +"install it, set it up, and create the virtual environment (with :code:" +"`Python 3.8.17` by default)::" msgstr "" -"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境(默认使用 " -":code:`Python3.8.17)::" +"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境" +"(默认使用 :code:`Python3.8.17)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 #, fuzzy msgid "" "If you already have :code:`pyenv` installed (along with the :code:`pyenv-" -"virtualenv` plugin), you can use the following convenience script (with " -":code:`Python 3.8.17` by default)::" +"virtualenv` plugin), you can use the following convenience script (with :" +"code:`Python 3.8.17` by default)::" msgstr "" -"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境(默认使用 " -":code:`Python3.8.17)::" +"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境" +"(默认使用 :code:`Python3.8.17)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 #, fuzzy msgid "" -"3. Install the Flower package in development mode (think :code:`pip " -"install -e`) along with all necessary dependencies::" -msgstr "第三,在开发模式下安装 Flower 软件包(想想 :code:`pip install -e`)以及所有必要的依赖项::" +"3. Install the Flower package in development mode (think :code:`pip install -" +"e`) along with all necessary dependencies::" +msgstr "" +"第三,在开发模式下安装 Flower 软件包(想想 :code:`pip install -e`)以及所有必" +"要的依赖项::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 msgid "Convenience Scripts" @@ -2396,10 +2515,12 @@ msgstr "便捷脚本" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" "The Flower repository contains a number of convenience scripts to make " -"recurring development tasks easier and less error-prone. See the " -":code:`/dev` subdirectory for a full list. The following scripts are " -"amongst the most important ones:" -msgstr "Flower 软件仓库包含大量便捷脚本,可使重复性开发任务更轻松、更不易出错。完整列表请参见 :code:`/dev` 子目录。以下是最重要的脚本:" +"recurring development tasks easier and less error-prone. See the :code:`/" +"dev` subdirectory for a full list. The following scripts are amongst the " +"most important ones:" +msgstr "" +"Flower 软件仓库包含大量便捷脚本,可使重复性开发任务更轻松、更不易出错。完整列" +"表请参见 :code:`/dev` 子目录。以下是最重要的脚本:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 msgid "Create/Delete Virtual Environment" @@ -2424,13 +2545,14 @@ msgstr "在本地运行 Github 操作 (CI)" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 #, fuzzy msgid "" -"Developers could run the full set of Github Actions workflows under their" -" local environment by using `Act `_. " -"Please refer to the installation instructions under the linked repository" -" and run the next command under Flower main cloned repository folder::" +"Developers could run the full set of Github Actions workflows under their " +"local environment by using `Act `_. Please " +"refer to the installation instructions under the linked repository and run " +"the next command under Flower main cloned repository folder::" msgstr "" -"开发人员可以使用 `Act _` 在本地环境下运行全套 Github Actions" -" 工作流程。请参考链接仓库下的安装说明,并在 Flower 主克隆仓库文件夹下运行下一条命令::" +"开发人员可以使用 `Act _` 在本地环境下运行全套 " +"Github Actions 工作流程。请参考链接仓库下的安装说明,并在 Flower 主克隆仓库文" +"件夹下运行下一条命令::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:115 msgid "" @@ -2444,15 +2566,16 @@ msgstr "版本发布" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:122 msgid "" -"Flower uses Poetry to build releases. The necessary command is wrapped in" -" a simple script::" +"Flower uses Poetry to build releases. The necessary command is wrapped in a " +"simple script::" msgstr "Flower 使用 Poetry 创建发布版本。必要的命令封装在一个简单的脚本中::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:127 msgid "" -"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" -" the :code:`/dist` subdirectory." -msgstr "生成的 :code:`.whl` 和 :code:`.tar.gz` 版本将存储在 :code:`/dist` 子目录中。" +"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in " +"the :code:`/dist` subdirectory." +msgstr "" +"生成的 :code:`.whl` 和 :code:`.tar.gz` 版本将存储在 :code:`/dist` 子目录中。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:132 msgid "Build Documentation" @@ -2460,12 +2583,12 @@ msgstr "构建文档" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:134 msgid "" -"Flower's documentation uses `Sphinx `_. " -"There's no convenience script to re-build the documentation yet, but it's" -" pretty easy::" +"Flower's documentation uses `Sphinx `_. There's " +"no convenience script to re-build the documentation yet, but it's pretty " +"easy::" msgstr "" -"Flower 的文档使用 `Sphinx `_。目前还没有很方便的脚本来重新构建文档,不过这很容易::" +"Flower 的文档使用 `Sphinx `_。目前还没有很方便的" +"脚本来重新构建文档,不过这很容易::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:140 msgid "This will generate HTML documentation in ``doc/build/html``." @@ -2478,19 +2601,19 @@ msgstr "示例: PyTorch 中的 FedBN - 从集中式到联邦式" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 #, fuzzy msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload with `FedBN " -"`_, a federated training strategy " -"designed for non-iid data. We are using PyTorch to train a Convolutional " -"Neural Network(with Batch Normalization layers) on the CIFAR-10 dataset. " -"When applying FedBN, only few changes needed compared to :doc:`Example: " -"PyTorch - From Centralized To Federated `." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload with `FedBN `_, a federated training strategy designed for non-iid data. We " +"are using PyTorch to train a Convolutional Neural Network(with Batch " +"Normalization layers) on the CIFAR-10 dataset. When applying FedBN, only few " +"changes needed compared to :doc:`Example: PyTorch - From Centralized To " +"Federated `." msgstr "" -"本教程将向您展示如何使用 Flower 为现有的机器学习框架构建一个联邦学习的版本,并使用 \"FedBN `_\"(一种针对非 iid 数据设计的联邦训练策略)。我们使用 PyTorch 在 CIFAR-10 " -"数据集上训练一个卷积神经网络(带有Batch Normalization层)。在应用 FedBN 时,只需对 `示例: PyTorch - " -"从集中式到联邦式 `_\"(一种针对非 iid 数据设" +"计的联邦训练策略)。我们使用 PyTorch 在 CIFAR-10 数据集上训练一个卷积神经网络" +"(带有Batch Normalization层)。在应用 FedBN 时,只需对 `示例: PyTorch - 从集" +"中式到联邦式 `_ 做少量改动。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 @@ -2501,14 +2624,14 @@ msgstr "集中式训练" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 #, fuzzy msgid "" -"All files are revised based on :doc:`Example: PyTorch - From Centralized " -"To Federated `. The only " -"thing to do is modifying the file called :code:`cifar.py`, revised part " -"is shown below:" +"All files are revised based on :doc:`Example: PyTorch - From Centralized To " +"Federated `. The only thing " +"to do is modifying the file called :code:`cifar.py`, revised part is shown " +"below:" msgstr "" -"所有文件均根据 `示例: PyTorch -从集中式到联邦式 `_。唯一要做的就是修改名为 :code:`cifar.py` " -"的文件,修改部分如下所示:" +"所有文件均根据 `示例: PyTorch -从集中式到联邦式 `_。唯一要做的就是修改名" +"为 :code:`cifar.py` 的文件,修改部分如下所示:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:13 msgid "" @@ -2524,13 +2647,14 @@ msgstr "现在,您可以运行您的机器学习工作了:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 #, fuzzy msgid "" -"So far this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"federated learning system within FedBN, the system consists of one server" -" and two clients." +"So far this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a federated " +"learning system within FedBN, the system consists of one server and two " +"clients." msgstr "" -"到目前为止,如果您以前使用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下一步,使用我们所构建的内容在 FedBN " -"中创建一个联邦学习系统,该系统由一个服务器和两个客户端组成。" +"到目前为止,如果您以前使用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下" +"一步,使用我们所构建的内容在 FedBN 中创建一个联邦学习系统,该系统由一个服务器" +"和两个客户端组成。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 #: ../../source/example-pytorch-from-centralized-to-federated.rst:167 @@ -2541,34 +2665,37 @@ msgstr "联邦培训" #, fuzzy msgid "" "If you have read :doc:`Example: PyTorch - From Centralized To Federated " -"`, the following parts are" -" easy to follow, only :code:`get_parameters` and :code:`set_parameters` " -"function in :code:`client.py` needed to revise. If not, please read the " -":doc:`Example: PyTorch - From Centralized To Federated `. first." -msgstr "" -"如果你读过 `示例: PyTorch - 从集中式到联邦式 `_,下面的部分就很容易理解了,只需要修改 " -":code:`get_parameters` 和 :code:`set_parameters` 中的 :code:`client.py` " -"函数。如果没有,请阅读 `示例: PyTorch - 从集中式到联邦式 `_。" +"`, the following parts are " +"easy to follow, only :code:`get_parameters` and :code:`set_parameters` " +"function in :code:`client.py` needed to revise. If not, please read the :doc:" +"`Example: PyTorch - From Centralized To Federated `. first." +msgstr "" +"如果你读过 `示例: PyTorch - 从集中式到联邦式 `_,下面的部分就很容易理" +"解了,只需要修改 :code:`get_parameters` 和 :code:`set_parameters` 中的 :code:" +"`client.py` 函数。如果没有,请阅读 `示例: PyTorch - 从集中式到联邦式 " +"`_。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" -"Our example consists of one *server* and two *clients*. In FedBN, " -":code:`server.py` keeps unchanged, we can start the server directly." -msgstr "我们的示例包括一个*服务器*和两个*客户端*。在 FedBN 中,:code:`server.py` 保持不变,我们可以直接启动服务器。" +"Our example consists of one *server* and two *clients*. In FedBN, :code:" +"`server.py` keeps unchanged, we can start the server directly." +msgstr "" +"我们的示例包括一个*服务器*和两个*客户端*。在 FedBN 中,:code:`server.py` 保持" +"不变,我们可以直接启动服务器。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" -"Finally, we will revise our *client* logic by changing " -":code:`get_parameters` and :code:`set_parameters` in :code:`client.py`, " -"we will exclude batch normalization parameters from model parameter list " -"when sending to or receiving from the server." +"Finally, we will revise our *client* logic by changing :code:" +"`get_parameters` and :code:`set_parameters` in :code:`client.py`, we will " +"exclude batch normalization parameters from model parameter list when " +"sending to or receiving from the server." msgstr "" -"最后,我们将修改 *client* 的逻辑,修改 :code:`client.py` 中的 :code:`get_parameters` 和 " -":code:`set_parameters`,在向服务器发送或从服务器接收时,我们将从模型参数列表中排除batch " -"normalization层的参数。" +"最后,我们将修改 *client* 的逻辑,修改 :code:`client.py` 中的 :code:" +"`get_parameters` 和 :code:`set_parameters`,在向服务器发送或从服务器接收时," +"我们将从模型参数列表中排除batch normalization层的参数。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 msgid "Now, you can now open two additional terminal windows and run" @@ -2576,10 +2703,12 @@ msgstr "现在,您可以打开另外两个终端窗口并运行程序" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your (previously centralized) PyTorch project run federated " -"learning with FedBN strategy across two clients. Congratulations!" -msgstr "确保服务器仍在运行后,然后您就能看到您的 PyTorch 项目(之前是集中式的)通过 FedBN 策略在两个客户端上运行联合学习。祝贺!" +"in each window (make sure that the server is still running before you do so) " +"and see your (previously centralized) PyTorch project run federated learning " +"with FedBN strategy across two clients. Congratulations!" +msgstr "" +"确保服务器仍在运行后,然后您就能看到您的 PyTorch 项目(之前是集中式的)通过 " +"FedBN 策略在两个客户端上运行联合学习。祝贺!" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 @@ -2591,18 +2720,17 @@ msgstr "下一步工作" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" -"The full source code for this example can be found `here " -"`_. Our example is of course somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using different subsets of CIFAR-10 on each client? How about adding more" -" clients?" +"The full source code for this example can be found `here `_. Our " +"example is of course somewhat over-simplified because both clients load the " +"exact same dataset, which isn't realistic. You're now prepared to explore " +"this topic further. How about using different subsets of CIFAR-10 on each " +"client? How about adding more clients?" msgstr "" -"本示例的完整源代码可在 `_ " -"找到。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。让我们准备好进一步探讨这一主题。如在每个客户端使用不同的 " -"CIFAR-10 子集,或者增加客户端的数量。" +"本示例的完整源代码可在 `_ 找到。当然,我们的示例有些过于简单," +"因为两个客户端都加载了完全相同的数据集,这并不真实。让我们准备好进一步探讨这" +"一主题。如在每个客户端使用不同的 CIFAR-10 子集,或者增加客户端的数量。" #: ../../source/example-jax-from-centralized-to-federated.rst:2 msgid "Example: JAX - Run JAX Federated" @@ -2611,32 +2739,32 @@ msgstr "示例: JAX - 运行联邦式 JAX" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing JAX workload. We are using JAX to train a linear " -"regression model on a scikit-learn dataset. We will structure the example" -" similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. First, we build a centralized " -"training approach based on the `Linear Regression with JAX " -"`_" -" tutorial`. Then, we build upon the centralized training code to run the " -"training in a federated fashion." -msgstr "" -"本教程将向您展示如何使用 Flower 构建现有 JAX 的联邦学习版本。我们将使用 JAX 在 scikit-learn " -"数据集上训练线性回归模型。我们将采用与 `PyTorch - 从集中式到联邦式 " -"`_ 教程中类似的示例结构。首先,我们根据 `JAX 的线性回归 " -"`_" -" 教程构建集中式训练方法。然后,我们在集中式训练代码的基础上以联邦方式运行训练。" +"This tutorial will show you how to use Flower to build a federated version " +"of an existing JAX workload. We are using JAX to train a linear regression " +"model on a scikit-learn dataset. We will structure the example similar to " +"our `PyTorch - From Centralized To Federated `_ walkthrough. " +"First, we build a centralized training approach based on the `Linear " +"Regression with JAX `_ tutorial`. Then, we build upon the centralized " +"training code to run the training in a federated fashion." +msgstr "" +"本教程将向您展示如何使用 Flower 构建现有 JAX 的联邦学习版本。我们将使用 JAX " +"在 scikit-learn 数据集上训练线性回归模型。我们将采用与 `PyTorch - 从集中式到" +"联邦式 `_ 教程中类似的示例结构。首先,我们根据 `JAX 的线性" +"回归 `_ 教程构建集中式训练方法。然后,我们在集中式训练代码的基础上以联邦方式" +"运行训练。" #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 msgid "" -"Before we start building our JAX example, we need install the packages " -":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" +"Before we start building our JAX example, we need install the packages :code:" +"`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" -"在开始构建 JAX 示例之前,我们需要安装软件包 :code:`jax`、:code:`jaxlib`、:code:`scikit-learn` " -"和 :code:`flwr`:" +"在开始构建 JAX 示例之前,我们需要安装软件包 :code:`jax`、:code:`jaxlib`、:" +"code:`scikit-learn` 和 :code:`flwr`:" #: ../../source/example-jax-from-centralized-to-federated.rst:18 #: ../../source/tutorial-quickstart-jax.rst:24 @@ -2646,77 +2774,83 @@ msgstr "使用 JAX 进行线性回归" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Linear Regression` model. If you want a more in-depth " -"explanation of what's going on then have a look at the official `JAX " -"documentation `_." +"We begin with a brief description of the centralized training code based on " +"a :code:`Linear Regression` model. If you want a more in-depth explanation " +"of what's going on then have a look at the official `JAX documentation " +"`_." msgstr "" -"首先,我们将简要介绍基于 :code:`Linear Regression` 模型的集中式训练代码。如果您想获得更深入的解释,请参阅官方的 " -"`JAX 文档 `_。" +"首先,我们将简要介绍基于 :code:`Linear Regression` 模型的集中式训练代码。如果" +"您想获得更深入的解释,请参阅官方的 `JAX 文档 `_。" #: ../../source/example-jax-from-centralized-to-federated.rst:23 #: ../../source/tutorial-quickstart-jax.rst:29 msgid "" "Let's create a new file called :code:`jax_training.py` with all the " "components required for a traditional (centralized) linear regression " -"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to " -"be imported. In addition, we need to import :code:`sklearn` since we use " -":code:`make_regression` for the dataset and :code:`train_test_split` to " -"split the dataset into a training and test set. You can see that we do " -"not yet import the :code:`flwr` package for federated learning. This will" -" be done later." -msgstr "" -"让我们创建一个名为 :code:`jax_training.py` 的新文件,其中包含传统(集中式)线性回归训练所需的所有组件。首先,需要导入 " -"JAX 包 :code:`jax` 和 :code:`jaxlib`。此外,我们还需要导入 :code:`sklearn`,因为我们使用 " -":code:`make_regression` 创建数据集,并使用 :code:`train_test_split` " -"将数据集拆分成训练集和测试集。您可以看到,我们还没有导入用于联邦学习的 :code:`flwr` 软件包,这将在稍后完成。" +"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to be " +"imported. In addition, we need to import :code:`sklearn` since we use :code:" +"`make_regression` for the dataset and :code:`train_test_split` to split the " +"dataset into a training and test set. You can see that we do not yet import " +"the :code:`flwr` package for federated learning. This will be done later." +msgstr "" +"让我们创建一个名为 :code:`jax_training.py` 的新文件,其中包含传统(集中式)线" +"性回归训练所需的所有组件。首先,需要导入 JAX 包 :code:`jax` 和 :code:" +"`jaxlib`。此外,我们还需要导入 :code:`sklearn`,因为我们使用 :code:" +"`make_regression` 创建数据集,并使用 :code:`train_test_split` 将数据集拆分成" +"训练集和测试集。您可以看到,我们还没有导入用于联邦学习的 :code:`flwr` 软件" +"包,这将在稍后完成。" #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" -"The :code:`load_data()` function loads the mentioned training and test " -"sets." +"The :code:`load_data()` function loads the mentioned training and test sets." msgstr ":code:`load_data()` 函数会加载上述训练集和测试集。" #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" -"The model architecture (a very simple :code:`Linear Regression` model) is" -" defined in :code:`load_model()`." -msgstr "模型结构(一个非常简单的 :code:`Linear Regression` 线性回归模型)在 :code:`load_model()` 中定义。" +"The model architecture (a very simple :code:`Linear Regression` model) is " +"defined in :code:`load_model()`." +msgstr "" +"模型结构(一个非常简单的 :code:`Linear Regression` 线性回归模型)在 :code:" +"`load_model()` 中定义。" #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 msgid "" -"We now need to define the training (function :code:`train()`), which " -"loops over the training set and measures the loss (function " -":code:`loss_fn()`) for each batch of training examples. The loss function" -" is separate since JAX takes derivatives with a :code:`grad()` function " -"(defined in the :code:`main()` function and called in :code:`train()`)." +"We now need to define the training (function :code:`train()`), which loops " +"over the training set and measures the loss (function :code:`loss_fn()`) for " +"each batch of training examples. The loss function is separate since JAX " +"takes derivatives with a :code:`grad()` function (defined in the :code:" +"`main()` function and called in :code:`train()`)." msgstr "" -"现在,我们需要定义训练函数( :code:`train()`)。它循环遍历训练集,并计算每批训练数据的损失值(函数 " -":code:`loss_fn()`)。由于 JAX 使用 :code:`grad()` 函数提取导数(在 :code:`main()` " -"函数中定义,并在 :code:`train()` 中调用),因此损失函数是独立的。" +"现在,我们需要定义训练函数( :code:`train()`)。它循环遍历训练集,并计算每批" +"训练数据的损失值(函数 :code:`loss_fn()`)。由于 JAX 使用 :code:`grad()` 函数" +"提取导数(在 :code:`main()` 函数中定义,并在 :code:`train()` 中调用),因此损" +"失函数是独立的。" #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 msgid "" -"The evaluation of the model is defined in the function " -":code:`evaluation()`. The function takes all test examples and measures " -"the loss of the linear regression model." -msgstr "模型的评估在函数 :code:`evaluation()` 中定义。该函数获取所有测试数据,并计算线性回归模型的损失值。" +"The evaluation of the model is defined in the function :code:`evaluation()`. " +"The function takes all test examples and measures the loss of the linear " +"regression model." +msgstr "" +"模型的评估在函数 :code:`evaluation()` 中定义。该函数获取所有测试数据,并计算" +"线性回归模型的损失值。" #: ../../source/example-jax-from-centralized-to-federated.rst:88 #: ../../source/tutorial-quickstart-jax.rst:94 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model using JAX. " -"As already mentioned, the :code:`jax.grad()` function is defined in " -":code:`main()` and passed to :code:`train()`." +"evaluation we can put everything together and train our model using JAX. As " +"already mentioned, the :code:`jax.grad()` function is defined in :code:" +"`main()` and passed to :code:`train()`." msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以把这些放在一起,使用 JAX " -"训练我们的模型了。如前所述,:code:`jax.grad()` 函数在 :code:`main()` 中定义,并传递给 " -":code:`train()`。" +"在定义了数据加载、模型架构、训练和评估之后,我们就可以把这些放在一起,使用 " +"JAX 训练我们的模型了。如前所述,:code:`jax.grad()` 函数在 :code:`main()` 中定" +"义,并传递给 :code:`train()`。" #: ../../source/example-jax-from-centralized-to-federated.rst:105 #: ../../source/tutorial-quickstart-jax.rst:111 @@ -2726,10 +2860,12 @@ msgstr "现在您可以运行(集中式)JAX 线性回归工作了:" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 msgid "" -"So far this should all look fairly familiar if you've used JAX before. " -"Let's take the next step and use what we've built to create a simple " -"federated learning system consisting of one server and two clients." -msgstr "到目前为止,如果你以前使用过 JAX,就会对这一切感到很熟悉。下一步,让我们利用已构建的代码创建一个简单的联邦学习系统(一个服务器和两个客户端)。" +"So far this should all look fairly familiar if you've used JAX before. Let's " +"take the next step and use what we've built to create a simple federated " +"learning system consisting of one server and two clients." +msgstr "" +"到目前为止,如果你以前使用过 JAX,就会对这一切感到很熟悉。下一步,让我们利用" +"已构建的代码创建一个简单的联邦学习系统(一个服务器和两个客户端)。" #: ../../source/example-jax-from-centralized-to-federated.rst:115 #: ../../source/tutorial-quickstart-jax.rst:121 @@ -2739,30 +2875,34 @@ msgstr "JAX 结合 Flower" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 msgid "" -"The concept of federating an existing workload is always the same and " -"easy to understand. We have to start a *server* and then use the code in " -":code:`jax_training.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server*, which averages all received " -"parameter updates. This describes one round of the federated learning " -"process, and we repeat this for multiple rounds." -msgstr "" -"把现有工作联邦化的概念始终是相同的,也很容易理解。我们要启动一个*服务器*,然后对连接到*服务器*的*客户端*运行 " -":code:`jax_training.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后服务器对所有收到的参数进行平均聚合。以上的描述构成了一轮联邦学习,我们将重复进行多轮学习。" +"The concept of federating an existing workload is always the same and easy " +"to understand. We have to start a *server* and then use the code in :code:" +"`jax_training.py` for the *clients* that are connected to the *server*. The " +"*server* sends model parameters to the clients. The *clients* run the " +"training and update the parameters. The updated parameters are sent back to " +"the *server*, which averages all received parameter updates. This describes " +"one round of the federated learning process, and we repeat this for multiple " +"rounds." +msgstr "" +"把现有工作联邦化的概念始终是相同的,也很容易理解。我们要启动一个*服务器*,然" +"后对连接到*服务器*的*客户端*运行 :code:`jax_training.py`中的代码。*服务器*向" +"客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*," +"然后服务器对所有收到的参数进行平均聚合。以上的描述构成了一轮联邦学习,我们将" +"重复进行多轮学习。" #: ../../source/example-jax-from-centralized-to-federated.rst:123 #: ../../source/example-mxnet-walk-through.rst:204 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" -"Our example consists of one *server* and two *clients*. Let's set up " -":code:`server.py` first. The *server* needs to import the Flower package " -":code:`flwr`. Next, we use the :code:`start_server` function to start a " -"server and tell it to perform three rounds of federated learning." +"Our example consists of one *server* and two *clients*. Let's set up :code:" +"`server.py` first. The *server* needs to import the Flower package :code:" +"`flwr`. Next, we use the :code:`start_server` function to start a server and " +"tell it to perform three rounds of federated learning." msgstr "" -"我们的示例包括一个*服务器*和两个*客户端*。让我们先设置 :code:`server.py`。*服务器*需要导入 Flower 软件包 " -":code:`flwr`。接下来,我们使用 :code:`start_server` 函数启动服务器,并让它执行三轮联邦学习。" +"我们的示例包括一个*服务器*和两个*客户端*。让我们先设置 :code:`server.py`。*服" +"务器*需要导入 Flower 软件包 :code:`flwr`。接下来,我们使用 :code:" +"`start_server` 函数启动服务器,并让它执行三轮联邦学习。" #: ../../source/example-jax-from-centralized-to-federated.rst:133 #: ../../source/example-mxnet-walk-through.rst:214 @@ -2774,35 +2914,34 @@ msgstr "我们已经可以启动*服务器*了:" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined JAX training in :code:`jax_training.py`. Our" -" *client* needs to import :code:`flwr`, but also :code:`jax` and " -":code:`jaxlib` to update the parameters on our JAX model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined JAX training in :code:`jax_training.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`jax` and :code:" +"`jaxlib` to update the parameters on our JAX model:" msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 " -":code:`jax_training.py` 中定义的 JAX 训练为基础。我们的 *client* 需要导入 " -":code:`flwr`,还需要导入 :code:`jax` 和 :code:`jaxlib` 以更新 JAX 模型的参数:" +"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" +"code:`jax_training.py` 中定义的 JAX 训练为基础。我们的 *client* 需要导入 :" +"code:`flwr`,还需要导入 :code:`jax` 和 :code:`jaxlib` 以更新 JAX 模型的参数:" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`FlowerClient`. :code:`NumPyClient` is slightly " -"easier to implement than :code:`Client` if you use a framework with good " -"NumPy interoperability (like JAX) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`FlowerClient` needs" -" to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" -msgstr "" -"实现一个 Flower *client*基本上意味着去实现一个 :code:`flwr.client.Client` 或 " -":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " -":code:`flwr.client.NumPyClient`,并将其命名为 :code:`FlowerClient`。如果使用具有良好 " -"NumPy 互操作性的框架(如 JAX),:code:`NumPyClient` 比 " -":code:`Client`更容易实现,因为它避免了一些不必要的操作。:code:`FlowerClient` " -"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`FlowerClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like JAX) because it avoids some of the boilerplate that " +"would otherwise be necessary. :code:`FlowerClient` needs to implement four " +"methods, two methods for getting/setting model parameters, one method for " +"training the model, and one method for testing the model:" +msgstr "" +"实现一个 Flower *client*基本上意味着去实现一个 :code:`flwr.client.Client` " +"或 :code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr." +"client.NumPyClient`,并将其命名为 :code:`FlowerClient`。如果使用具有良好 " +"NumPy 互操作性的框架(如 JAX),:code:`NumPyClient` 比 :code:`Client`更容易实" +"现,因为它避免了一些不必要的操作。:code:`FlowerClient` 需要实现四个方法,两个" +"用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" #: ../../source/example-jax-from-centralized-to-federated.rst:161 #: ../../source/example-mxnet-walk-through.rst:242 @@ -2815,8 +2954,7 @@ msgstr ":code:`set_parameters (可选)`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" -"set the model parameters on the local model that are received from the " -"server" +"set the model parameters on the local model that are received from the server" msgstr "在本地模型上设置从服务器接收的模型参数" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2829,9 +2967,11 @@ msgstr "将参数转换为 NumPy :code:`ndarray`格式" #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" -"loop over the list of model parameters received as NumPy " -":code:`ndarray`'s (think list of neural network layers)" -msgstr "循环遍历以 NumPy :code:`ndarray` 形式接收的模型参数列表(可以看作神经网络的列表)" +"loop over the list of model parameters received as NumPy :code:`ndarray`'s " +"(think list of neural network layers)" +msgstr "" +"循环遍历以 NumPy :code:`ndarray` 形式接收的模型参数列表(可以看作神经网络的列" +"表)" #: ../../source/example-jax-from-centralized-to-federated.rst:163 #: ../../source/example-mxnet-walk-through.rst:244 @@ -2848,11 +2988,11 @@ msgstr ":code:`get_parameters`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" -"get the model parameters and return them as a list of NumPy " -":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" +"get the model parameters and return them as a list of NumPy :code:" +"`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" -"获取模型参数,并以 NumPy :code:`ndarray`的列表形式返回(这正是 " -":code:`flwr.client.NumPyClient`所匹配的格式)" +"获取模型参数,并以 NumPy :code:`ndarray`的列表形式返回(这正是 :code:`flwr." +"client.NumPyClient`所匹配的格式)" #: ../../source/example-jax-from-centralized-to-federated.rst:167 #: ../../source/example-mxnet-walk-through.rst:248 @@ -2873,8 +3013,8 @@ msgstr ":code:`fit`" #: ../../source/tutorial-quickstart-jax.rst:172 #: ../../source/tutorial-quickstart-jax.rst:176 msgid "" -"update the parameters of the local model with the parameters received " -"from the server" +"update the parameters of the local model with the parameters received from " +"the server" msgstr "用从服务器接收到的参数更新本地模型的参数" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2914,28 +3054,28 @@ msgstr "向服务器返回本地损失值" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 msgid "" -"The challenging part is to transform the JAX model parameters from " -":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" -" `NumPyClient`." +"The challenging part is to transform the JAX model parameters from :code:" +"`DeviceArray` to :code:`NumPy ndarray` to make them compatible with " +"`NumPyClient`." msgstr "" -"具有挑战性的部分是将 JAX 模型参数从 :code:`DeviceArray` 转换为 :code:`NumPy ndarray`,使其与 " -"`NumPyClient` 兼容。" +"具有挑战性的部分是将 JAX 模型参数从 :code:`DeviceArray` 转换为 :code:`NumPy " +"ndarray`,使其与 `NumPyClient` 兼容。" #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`evaluate()` previously " +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`evaluate()` previously " "defined in :code:`jax_training.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." +"Flower through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type annotations " +"to give you a better understanding of the data types that get passed around." msgstr "" -"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前在 " -":code:`jax_training.py` 中定义的函数 :code:`train()` 和 " -":code:`evaluate()`。因此,我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 Flower " -"在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" +"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前" +"在 :code:`jax_training.py` 中定义的函数 :code:`train()` 和 :code:" +"`evaluate()`。因此,我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 " +"Flower 在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好" +"地理解传递的数据类型。" #: ../../source/example-jax-from-centralized-to-federated.rst:245 #: ../../source/tutorial-quickstart-jax.rst:251 @@ -2952,30 +3092,34 @@ msgstr "就是这样,现在你可以打开另外两个终端窗口,然后运 #: ../../source/example-jax-from-centralized-to-federated.rst:274 #: ../../source/tutorial-quickstart-jax.rst:280 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your JAX project run federated learning across two clients. " +"in each window (make sure that the server is still running before you do so) " +"and see your JAX project run federated learning across two clients. " "Congratulations!" -msgstr "确保服务器仍在运行,然后在每个客户端窗口就能看到你的 JAX 项目在两个客户端上运行联邦学习了。祝贺!" +msgstr "" +"确保服务器仍在运行,然后在每个客户端窗口就能看到你的 JAX 项目在两个客户端上运" +"行联邦学习了。祝贺!" #: ../../source/example-jax-from-centralized-to-federated.rst:279 #: ../../source/tutorial-quickstart-jax.rst:285 msgid "" "The source code of this example was improved over time and can be found " -"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " +"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" -"此示例的源代码经过长期改进,可在此处找到: `Quickstart JAX " -"`_。我们的示例有些过于简单,因为两个客户端都加载了相同的数据集。" +"此示例的源代码经过长期改进,可在此处找到: `Quickstart JAX `_。我们的示例有些过于简" +"单,因为两个客户端都加载了相同的数据集。" #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 msgid "" -"You're now prepared to explore this topic further. How about using a more" -" sophisticated model or using a different dataset? How about adding more " +"You're now prepared to explore this topic further. How about using a more " +"sophisticated model or using a different dataset? How about adding more " "clients?" -msgstr "现在,您已准备好进行更深一步探索了。例如使用更复杂的模型或使用不同的数据集会如何?增加更多客户端会如何?" +msgstr "" +"现在,您已准备好进行更深一步探索了。例如使用更复杂的模型或使用不同的数据集会" +"如何?增加更多客户端会如何?" #: ../../source/example-mxnet-walk-through.rst:2 msgid "Example: MXNet - Run MXNet Federated" @@ -2983,35 +3127,36 @@ msgstr "示例: MXNet - 运行联邦式 MXNet" #: ../../source/example-mxnet-walk-through.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing MXNet workload. We are using MXNet to train a " -"Sequential model on the MNIST dataset. We will structure the example " -"similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. MXNet and PyTorch are very " -"similar and a very good comparison between MXNet and PyTorch is given " -"`here `_. First, we build a centralized " -"training approach based on the `Handwritten Digit Recognition " -"`_" -" tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." -msgstr "" -"本教程将向您展示如何使用 Flower 构建现有 MXNet 的联学习版本。我们将使用 MXNet 在 MNIST " -"数据集上训练一个序列模型。另外,我们将采用与我们的 `PyTorch - 从集中式到联邦式 " -"`_ 教程类似的示例结构。MXNet 和 PyTorch 非常相似,参考 `此处 " -"`_对 MXNet 和 PyTorch " -"进行了详细的比较。首先,我们根据 `手写数字识别 " -"`" -" 教程 建立了集中式训练方法。然后,我们在集中式训练代码的基础上,以联邦方式运行训练。" +"This tutorial will show you how to use Flower to build a federated version " +"of an existing MXNet workload. We are using MXNet to train a Sequential " +"model on the MNIST dataset. We will structure the example similar to our " +"`PyTorch - From Centralized To Federated `_ walkthrough. " +"MXNet and PyTorch are very similar and a very good comparison between MXNet " +"and PyTorch is given `here `_. First, we " +"build a centralized training approach based on the `Handwritten Digit " +"Recognition `_ tutorial. Then, we build upon " +"the centralized training code to run the training in a federated fashion." +msgstr "" +"本教程将向您展示如何使用 Flower 构建现有 MXNet 的联学习版本。我们将使用 " +"MXNet 在 MNIST 数据集上训练一个序列模型。另外,我们将采用与我们的 `PyTorch - " +"从集中式到联邦式 `_ 教程类似的示例结构。MXNet 和 PyTorch 非常相" +"似,参考 `此处 `_对 MXNet 和 PyTorch 进行了" +"详细的比较。首先,我们根据 `手写数字识别 ` 教" +"程 建立了集中式训练方法。然后,我们在集中式训练代码的基础上,以联邦方式运行训" +"练。" #: ../../source/example-mxnet-walk-through.rst:10 msgid "" -"Before we start setting up our MXNet example, we install the " -":code:`mxnet` and :code:`flwr` packages:" -msgstr "在开始设置 MXNet 示例之前,我们先安装 :code:`mxnet` 和 :code:`flwr` 软件包:" +"Before we start setting up our MXNet example, we install the :code:`mxnet` " +"and :code:`flwr` packages:" +msgstr "" +"在开始设置 MXNet 示例之前,我们先安装 :code:`mxnet` 和 :code:`flwr` 软件包:" #: ../../source/example-mxnet-walk-through.rst:19 msgid "MNIST Training with MXNet" @@ -3019,61 +3164,69 @@ msgstr "使用 MXNet 进行 MNIST 训练" #: ../../source/example-mxnet-walk-through.rst:21 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Sequential` model. If you want a more in-depth explanation of" -" what's going on then have a look at the official `MXNet tutorial " -"`_." +"We begin with a brief description of the centralized training code based on " +"a :code:`Sequential` model. If you want a more in-depth explanation of " +"what's going on then have a look at the official `MXNet tutorial `_." msgstr "" -"首先,我们将简要介绍基于 :code:`Sequential` 模型的集中式训练代码。如果您想获得更深入的解释,请参阅官方的 `MXNet教程 " -"`_。" +"首先,我们将简要介绍基于 :code:`Sequential` 模型的集中式训练代码。如果您想获" +"得更深入的解释,请参阅官方的 `MXNet教程 `_。" #: ../../source/example-mxnet-walk-through.rst:24 msgid "" -"Let's create a new file called:code:`mxnet_mnist.py` with all the " -"components required for a traditional (centralized) MNIST training. " -"First, the MXNet package :code:`mxnet` needs to be imported. You can see " -"that we do not yet import the :code:`flwr` package for federated " -"learning. This will be done later." +"Let's create a new file called:code:`mxnet_mnist.py` with all the components " +"required for a traditional (centralized) MNIST training. First, the MXNet " +"package :code:`mxnet` needs to be imported. You can see that we do not yet " +"import the :code:`flwr` package for federated learning. This will be done " +"later." msgstr "" -"让我们创建一个名为:code:`mxnet_mnist.py`的新文件,其中包含传统(集中式)MNIST 训练所需的所有组件。首先,需要导入 " -"MXNet 包 :code:`mxnet`。您可以看到,我们尚未导入用于联合学习的 :code:`flwr` 包,这将在稍后完成。" +"让我们创建一个名为:code:`mxnet_mnist.py`的新文件,其中包含传统(集中式)" +"MNIST 训练所需的所有组件。首先,需要导入 MXNet 包 :code:`mxnet`。您可以看到," +"我们尚未导入用于联合学习的 :code:`flwr` 包,这将在稍后完成。" #: ../../source/example-mxnet-walk-through.rst:42 -msgid "The :code:`load_data()` function loads the MNIST training and test sets." +msgid "" +"The :code:`load_data()` function loads the MNIST training and test sets." msgstr ":code:`load_data()` 函数加载 MNIST 训练集和测试集。" #: ../../source/example-mxnet-walk-through.rst:57 msgid "" "As already mentioned, we will use the MNIST dataset for this machine " -"learning workload. The model architecture (a very simple " -":code:`Sequential` model) is defined in :code:`model()`." +"learning workload. The model architecture (a very simple :code:`Sequential` " +"model) is defined in :code:`model()`." msgstr "" -"如前所述,我们将使用 MNIST 数据集进行机器学习。模型架构(一个非常简单的 :code:`Sequential` 模型)在 " -":code:`model()` 中定义。" +"如前所述,我们将使用 MNIST 数据集进行机器学习。模型架构(一个非常简单的 :" +"code:`Sequential` 模型)在 :code:`model()` 中定义。" #: ../../source/example-mxnet-walk-through.rst:70 msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set and measures the loss for each batch of training " +"We now need to define the training (function :code:`train()`) which loops " +"over the training set and measures the loss for each batch of training " "examples." -msgstr "现在,我们需要定义训练函数( :code:`train()`),该函数在训练集上循环训练,并计算每批训练示例的损失值。" +msgstr "" +"现在,我们需要定义训练函数( :code:`train()`),该函数在训练集上循环训练,并" +"计算每批训练示例的损失值。" #: ../../source/example-mxnet-walk-through.rst:123 msgid "" "The evaluation of the model is defined in function :code:`test()`. The " -"function loops over all test samples and measures the loss and accuracy " -"of the model based on the test dataset." -msgstr "模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并根据测试数据集计算模型的损失值和准确度。" +"function loops over all test samples and measures the loss and accuracy of " +"the model based on the test dataset." +msgstr "" +"模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并根据测" +"试数据集计算模型的损失值和准确度。" #: ../../source/example-mxnet-walk-through.rst:158 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model on MNIST. " -"Note that the GPU/CPU device for the training and testing is defined " -"within the :code:`ctx` (context)." +"evaluation we can put everything together and train our model on MNIST. Note " +"that the GPU/CPU device for the training and testing is defined within the :" +"code:`ctx` (context)." msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以把所有放在一起,在 MNIST 上训练我们的模型了。请注意,用于训练和测试的 GPU/CPU" -" 设备是在 :code:`ctx`中定义的。" +"在定义了数据加载、模型架构、训练和评估之后,我们就可以把所有放在一起,在 " +"MNIST 上训练我们的模型了。请注意,用于训练和测试的 GPU/CPU 设备是在 :code:" +"`ctx`中定义的。" #: ../../source/example-mxnet-walk-through.rst:184 msgid "You can now run your (centralized) MXNet machine learning workload:" @@ -3081,13 +3234,13 @@ msgstr "现在,您可以运行(集中式)MXNet 机器学习工作:" #: ../../source/example-mxnet-walk-through.rst:190 msgid "" -"So far this should all look fairly familiar if you've used MXNet (or even" -" PyTorch) before. Let's take the next step and use what we've built to " -"create a simple federated learning system consisting of one server and " -"two clients." +"So far this should all look fairly familiar if you've used MXNet (or even " +"PyTorch) before. Let's take the next step and use what we've built to create " +"a simple federated learning system consisting of one server and two clients." msgstr "" -"到目前为止,如果你以前使用过 MXNet(甚至 " -"PyTorch),这一切看起来应该相当熟悉。下一步,让我们利用已构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组成)。" +"到目前为止,如果你以前使用过 MXNet(甚至 PyTorch),这一切看起来应该相当熟" +"悉。下一步,让我们利用已构建的内容创建一个简单联邦学习系统(由一个服务器和两" +"个客户端组成)。" #: ../../source/example-mxnet-walk-through.rst:194 msgid "MXNet meets Flower" @@ -3096,59 +3249,61 @@ msgstr "MXNet 结合 Flower" #: ../../source/example-mxnet-walk-through.rst:196 msgid "" "So far, it was not easily possible to use MXNet workloads for federated " -"learning because federated learning is not supported in MXNet. Since " -"Flower is fully agnostic towards the underlying machine learning " -"framework, it can be used to federated arbitrary machine learning " -"workloads. This section will show you how Flower can be used to federate " -"our centralized MXNet workload." +"learning because federated learning is not supported in MXNet. Since Flower " +"is fully agnostic towards the underlying machine learning framework, it can " +"be used to federated arbitrary machine learning workloads. This section will " +"show you how Flower can be used to federate our centralized MXNet workload." msgstr "" -"由于 MXNet 目前不支持联邦学习,因此无法轻松地直接将 MXNet 用于联邦学习之中。Flower " -"与底层机器学习框架完全无关,因此它可用于任意联邦式机器学习工作。本节将向你展示如何使用 Flower 将我们的集中式 MXNet 改为联邦式训练。" +"由于 MXNet 目前不支持联邦学习,因此无法轻松地直接将 MXNet 用于联邦学习之中。" +"Flower 与底层机器学习框架完全无关,因此它可用于任意联邦式机器学习工作。本节将" +"向你展示如何使用 Flower 将我们的集中式 MXNet 改为联邦式训练。" #: ../../source/example-mxnet-walk-through.rst:198 msgid "" -"The concept to federate an existing workload is always the same and easy " -"to understand. We have to start a *server* and then use the code in " -":code:`mxnet_mnist.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." -msgstr "" -"将现有模型框架联邦化的概念始终是相同的,也很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*使用 " -":code:`mxnet_mnist.py`中的代码。*服务器*向客户端发送模型参数,然后*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" +"The concept to federate an existing workload is always the same and easy to " +"understand. We have to start a *server* and then use the code in :code:" +"`mxnet_mnist.py` for the *clients* that are connected to the *server*. The " +"*server* sends model parameters to the clients. The *clients* run the " +"training and update the parameters. The updated parameters are sent back to " +"the *server* which averages all received parameter updates. This describes " +"one round of the federated learning process and we repeat this for multiple " +"rounds." +msgstr "" +"将现有模型框架联邦化的概念始终是相同的,也很容易理解。我们必须启动一个*服务器" +"*,然后对连接到*服务器*的*客户端*使用 :code:`mxnet_mnist.py`中的代码。*服务器" +"*向客户端发送模型参数,然后*客户端*运行训练并更新参数。更新后的参数被发回*服" +"务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程," +"我们将重复进行多轮学习。" #: ../../source/example-mxnet-walk-through.rst:220 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined MXNet training in :code:`mxnet_mnist.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`mxnet` to " -"update the parameters on our MXNet model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined MXNet training in :code:`mxnet_mnist.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`mxnet` to update the " +"parameters on our MXNet model:" msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :code:`mxnet_mnist.py`" -" 中定义的 MXNet 训练为基础。我们的 *client* 不仅需要导入 :code:`flwr`,还需要导入 " -":code:`mxnet`,以更新 MXNet 模型的参数:" +"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" +"code:`mxnet_mnist.py` 中定义的 MXNet 训练为基础。我们的 *client* 不仅需要导" +"入 :code:`flwr`,还需要导入 :code:`mxnet`,以更新 MXNet 模型的参数:" #: ../../source/example-mxnet-walk-through.rst:235 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " "interoperability (like PyTorch or MXNet) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs " -"to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" -msgstr "" -"实现 Flower *client*基本上意味着要实现 :code:`flwr.client.Client` 或 " -":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " -":code:`flwr.client.NumPyClient`,并将其命名为 :code:`MNISTClient`。如果使用具有良好 NumPy" -" 互操作性的框架(如 PyTorch 或 MXNet),:code:`NumPyClient` 比 " -":code:`Client`更容易实现,因为它避免了一些不必要的操作。:code:`MNISTClient` " -"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" +"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs to " +"implement four methods, two methods for getting/setting model parameters, " +"one method for training the model, and one method for testing the model:" +msgstr "" +"实现 Flower *client*基本上意味着要实现 :code:`flwr.client.Client` 或 :code:" +"`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr.client." +"NumPyClient`,并将其命名为 :code:`MNISTClient`。如果使用具有良好 NumPy 互操作" +"性的框架(如 PyTorch 或 MXNet),:code:`NumPyClient` 比 :code:`Client`更容易" +"实现,因为它避免了一些不必要的操作。:code:`MNISTClient` 需要实现四个方法,两" +"个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" #: ../../source/example-mxnet-walk-through.rst:242 msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" @@ -3166,58 +3321,57 @@ msgstr "向服务器返回本地损失值和精确度" #: ../../source/example-mxnet-walk-through.rst:255 msgid "" -"The challenging part is to transform the MXNet parameters from " -":code:`NDArray` to :code:`NumPy Arrays` to make it readable for Flower." +"The challenging part is to transform the MXNet parameters from :code:" +"`NDArray` to :code:`NumPy Arrays` to make it readable for Flower." msgstr "" -"具有挑战性的部分是将 MXNet 参数从 :code:`NDArray` 转换为 :code:`NumPy Arrays` 以便 Flower " -"可以读取。" +"具有挑战性的部分是将 MXNet 参数从 :code:`NDArray` 转换为 :code:`NumPy " +"Arrays` 以便 Flower 可以读取。" #: ../../source/example-mxnet-walk-through.rst:257 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`mxnet_mnist.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`test()` previously defined " +"in :code:`mxnet_mnist.py`. So what we really do here is we tell Flower " +"through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type annotations " +"to give you a better understanding of the data types that get passed around." msgstr "" -"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前在 " -":code:`mxnet_mnist.py` 中定义的函数 :code:`train()` 和 " -":code:`test()`。因此,我们要做的就是通过 :code:`NumPyClient` 子类告知 Flower " -"在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" +"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前" +"在 :code:`mxnet_mnist.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因" +"此,我们要做的就是通过 :code:`NumPyClient` 子类告知 Flower 在训练和评估时要调" +"用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" #: ../../source/example-mxnet-walk-through.rst:319 msgid "" -"Having defined data loading, model architecture, training, and evaluation" -" we can put everything together and train our :code:`Sequential` model on" -" MNIST." +"Having defined data loading, model architecture, training, and evaluation we " +"can put everything together and train our :code:`Sequential` model on MNIST." msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以将所有内容整合在一起,在 MNIST 上训练我们的 :code:`Sequential` " -"模型。" +"在定义了数据加载、模型架构、训练和评估之后,我们就可以将所有内容整合在一起," +"在 MNIST 上训练我们的 :code:`Sequential` 模型。" #: ../../source/example-mxnet-walk-through.rst:353 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your MXNet project run federated learning across two clients." -" Congratulations!" -msgstr "确保服务器仍在运行后,然后就能在每个窗口中看到 MXNet 项目在两个客户端上运行联邦学习了。祝贺!" +"in each window (make sure that the server is still running before you do so) " +"and see your MXNet project run federated learning across two clients. " +"Congratulations!" +msgstr "" +"确保服务器仍在运行后,然后就能在每个窗口中看到 MXNet 项目在两个客户端上运行联" +"邦学习了。祝贺!" #: ../../source/example-mxnet-walk-through.rst:358 msgid "" -"The full source code for this example: `MXNet: From Centralized To " -"Federated (Code) `_. Our example is of course " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using a CNN or using a different dataset? How about " -"adding more clients?" +"The full source code for this example: `MXNet: From Centralized To Federated " +"(Code) `_. Our example is of course somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using a CNN or using a different dataset? How about adding more clients?" msgstr "" "此示例的完整源代码在:\"MXNet: From Centralized To Federated (Code) " -"`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现在您已经准备好进一步探讨了。使用 " -"CNN 或使用不同的数据集会如何?添加更多客户端会如何?" +"`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的" +"数据集,这并不真实。现在您已经准备好进一步探讨了。使用 CNN 或使用不同的数据集" +"会如何?添加更多客户端会如何?" #: ../../source/example-pytorch-from-centralized-to-federated.rst:2 msgid "Example: PyTorch - From Centralized To Federated" @@ -3225,41 +3379,44 @@ msgstr "实例: PyTorch - 从集中式到联邦式" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload. We are using PyTorch to" -" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " -"introduce this machine learning task with a centralized training approach" -" based on the `Deep Learning with PyTorch " -"`_ " -"tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload. We are using PyTorch to train a " +"Convolutional Neural Network on the CIFAR-10 dataset. First, we introduce " +"this machine learning task with a centralized training approach based on the " +"`Deep Learning with PyTorch `_ tutorial. Then, we build upon the centralized " +"training code to run the training in a federated fashion." msgstr "" -"本教程将向您展示如何使用 Flower 构建现有机器学习工作的联邦版本。我们使用 PyTorch 在 CIFAR-10 " -"数据集上训练一个卷积神经网络。首先,我们基于 \"Deep Learning with PyTorch " -"`_\"教程,采用集中式训练方法介绍了这项机器学习任务。然后,我们在集中式训练代码的基础上以联邦方式运行训练。" +"本教程将向您展示如何使用 Flower 构建现有机器学习工作的联邦版本。我们使用 " +"PyTorch 在 CIFAR-10 数据集上训练一个卷积神经网络。首先,我们基于 \"Deep " +"Learning with PyTorch `_\"教程,采用集中式训练方法介绍了这项机器学习任务。然" +"后,我们在集中式训练代码的基础上以联邦方式运行训练。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"We begin with a brief description of the centralized CNN training code. " -"If you want a more in-depth explanation of what's going on then have a " -"look at the official `PyTorch tutorial " -"`_." +"We begin with a brief description of the centralized CNN training code. If " +"you want a more in-depth explanation of what's going on then have a look at " +"the official `PyTorch tutorial `_." msgstr "" -"我们首先简要介绍一下集中式 CNN 训练代码。如果您想获得更深入的解释,请参阅 PyTorch 官方教程`PyTorch tutorial " -"`_。" +"我们首先简要介绍一下集中式 CNN 训练代码。如果您想获得更深入的解释,请参阅 " +"PyTorch 官方教程`PyTorch tutorial `_。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" "Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all" -" required packages (such as :code:`torch` and :code:`torchvision`) need " -"to be imported. You can see that we do not import any package for " -"federated learning. You can keep all these imports as they are even when " -"we add the federated learning components at a later point." +"required for a traditional (centralized) training on CIFAR-10. First, all " +"required packages (such as :code:`torch` and :code:`torchvision`) need to be " +"imported. You can see that we do not import any package for federated " +"learning. You can keep all these imports as they are even when we add the " +"federated learning components at a later point." msgstr "" -"让我们创建一个名为 :code:`cifar.py` 的新文件,其中包含 CIFAR-10 " -"传统(集中)培训所需的所有组件。首先,需要导入所有必需的软件包(如 :code:`torch` 和 " -":code:`torchvision`)。您可以看到,我们没有导入任何用于联邦学习的软件包。即使在以后添加联邦学习组件时,也可以保留所有这些导入。" +"让我们创建一个名为 :code:`cifar.py` 的新文件,其中包含 CIFAR-10 传统(集中)" +"培训所需的所有组件。首先,需要导入所有必需的软件包(如 :code:`torch` 和 :" +"code:`torchvision`)。您可以看到,我们没有导入任何用于联邦学习的软件包。即使" +"在以后添加联邦学习组件时,也可以保留所有这些导入。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" @@ -3267,107 +3424,122 @@ msgid "" "learning workload. The model architecture (a very simple Convolutional " "Neural Network) is defined in :code:`class Net()`." msgstr "" -"如前所述,我们将使用 CIFAR-10 数据集进行机器学习。模型架构(一个非常简单的卷积神经网络)在 :code:`class Net()` " -"中定义。" +"如前所述,我们将使用 CIFAR-10 数据集进行机器学习。模型架构(一个非常简单的卷" +"积神经网络)在 :code:`class Net()` 中定义。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test " -"sets. The :code:`transform` normalized the data after loading." +"The :code:`load_data()` function loads the CIFAR-10 training and test sets. " +"The :code:`transform` normalized the data after loading." msgstr "" -":code:`load_data()` 函数加载 CIFAR-10 " -"训练集和测试集。加载数据后,:code:`transform`函数对数据进行了归一化处理。" +":code:`load_data()` 函数加载 CIFAR-10 训练集和测试集。加载数据后,:code:" +"`transform`函数对数据进行了归一化处理。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set, measures the loss, backpropagates it, and then " -"takes one optimizer step for each batch of training examples." -msgstr "现在,我们需要定义训练函数(:code:`train()`),该函数在训练集上循环训练,计算损失值并反向传播,然后为每批训练数据在优化器上执行一个优化步骤。" +"We now need to define the training (function :code:`train()`) which loops " +"over the training set, measures the loss, backpropagates it, and then takes " +"one optimizer step for each batch of training examples." +msgstr "" +"现在,我们需要定义训练函数(:code:`train()`),该函数在训练集上循环训练,计算" +"损失值并反向传播,然后为每批训练数据在优化器上执行一个优化步骤。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in the function :code:`test()`. " -"The function loops over all test samples and measures the loss of the " -"model based on the test dataset." -msgstr "模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并计算测试数据集的模型损失值。" +"The evaluation of the model is defined in the function :code:`test()`. The " +"function loops over all test samples and measures the loss of the model " +"based on the test dataset." +msgstr "" +"模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并计算测" +"试数据集的模型损失值。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " "evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "在确定了数据加载、模型架构、训练和评估之后,我们就可以将所有整合在一起,在 CIFAR-10 上训练我们的 CNN。" +msgstr "" +"在确定了数据加载、模型架构、训练和评估之后,我们就可以将所有整合在一起,在 " +"CIFAR-10 上训练我们的 CNN。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far, this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"simple federated learning system consisting of one server and two " -"clients." +"So far, this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a simple " +"federated learning system consisting of one server and two clients." msgstr "" -"到目前为止,如果你以前用过 " -"PyTorch,这一切看起来应该相当熟悉。让我们进行下一步,利用我们所构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组成)。" +"到目前为止,如果你以前用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下一" +"步,利用我们所构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组" +"成)。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" -"The simple machine learning project discussed in the previous section " -"trains the model on a single dataset (CIFAR-10), we call this centralized" -" learning. This concept of centralized learning, as shown in the previous" -" section, is probably known to most of you, and many of you have used it " -"previously. Normally, if you'd want to run machine learning workloads in " -"a federated fashion, then you'd have to change most of your code and set " -"everything up from scratch. This can be a considerable effort." -msgstr "上一节讨论的简单机器学习项目在单一数据集(CIFAR-10)上训练模型,我们称之为集中学习。如上一节所示,集中学习的概念可能为大多数人所熟知,而且很多人以前都使用过。通常情况下,如果要以联邦方式运行机器学习工作,就必须更改大部分代码,并从头开始设置一切。这可能是一个相当大的工作量。" +"The simple machine learning project discussed in the previous section trains " +"the model on a single dataset (CIFAR-10), we call this centralized learning. " +"This concept of centralized learning, as shown in the previous section, is " +"probably known to most of you, and many of you have used it previously. " +"Normally, if you'd want to run machine learning workloads in a federated " +"fashion, then you'd have to change most of your code and set everything up " +"from scratch. This can be a considerable effort." +msgstr "" +"上一节讨论的简单机器学习项目在单一数据集(CIFAR-10)上训练模型,我们称之为集" +"中学习。如上一节所示,集中学习的概念可能为大多数人所熟知,而且很多人以前都使" +"用过。通常情况下,如果要以联邦方式运行机器学习工作,就必须更改大部分代码,并" +"从头开始设置一切。这可能是一个相当大的工作量。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"However, with Flower you can evolve your pre-existing code into a " -"federated learning setup without the need for a major rewrite." -msgstr "不过,有了 Flower,您可以轻松地将已有的代码转变成联邦学习的模式,无需进行大量重写。" +"However, with Flower you can evolve your pre-existing code into a federated " +"learning setup without the need for a major rewrite." +msgstr "" +"不过,有了 Flower,您可以轻松地将已有的代码转变成联邦学习的模式,无需进行大量" +"重写。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept is easy to understand. We have to start a *server* and then " -"use the code in :code:`cifar.py` for the *clients* that are connected to " -"the *server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." +"The concept is easy to understand. We have to start a *server* and then use " +"the code in :code:`cifar.py` for the *clients* that are connected to the " +"*server*. The *server* sends model parameters to the clients. The *clients* " +"run the training and update the parameters. The updated parameters are sent " +"back to the *server* which averages all received parameter updates. This " +"describes one round of the federated learning process and we repeat this for " +"multiple rounds." msgstr "" -"这个概念很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*使用 " -":code:`cifar.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" +"这个概念很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*" +"使用 :code:`cifar.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练" +"并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚" +"合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined centralized training in :code:`cifar.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " -"update the parameters on our PyTorch model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined centralized training in :code:`cifar.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`torch` to update the " +"parameters on our PyTorch model:" msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :code:`cifar.py` " -"中定义的集中式训练为基础。我们的 *client* 不仅需要导入 :code:`flwr`,还需要导入 :code:`torch`,以更新 " -"PyTorch 模型的参数:" +"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" +"code:`cifar.py` 中定义的集中式训练为基础。我们的 *client* 不仅需要导入 :code:" +"`flwr`,还需要导入 :code:`torch`,以更新 PyTorch 模型的参数:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " -"some of the boilerplate that would otherwise be necessary. " -":code:`CifarClient` needs to implement four methods, two methods for " -"getting/setting model parameters, one method for training the model, and " -"one method for testing the model:" -msgstr "" -"实现 Flower *client*基本上意味着实现 :code:`flwr.client.Client` 或 " -":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " -":code:`flwr.client.NumPyClient`,并将其命名为 :code:`CifarClient`。如果使用具有良好 NumPy" -" 互操作性的框架(如 PyTorch 或 TensorFlow/Keras),:code:`NumPyClient`的实现比 " -":code:`Client`略微容易一些,因为它避免了一些不必要的操作。:code:`CifarClient` " -"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids some " +"of the boilerplate that would otherwise be necessary. :code:`CifarClient` " +"needs to implement four methods, two methods for getting/setting model " +"parameters, one method for training the model, and one method for testing " +"the model:" +msgstr "" +"实现 Flower *client*基本上意味着实现 :code:`flwr.client.Client` 或 :code:" +"`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr.client." +"NumPyClient`,并将其命名为 :code:`CifarClient`。如果使用具有良好 NumPy 互操作" +"性的框架(如 PyTorch 或 TensorFlow/Keras),:code:`NumPyClient`的实现比 :" +"code:`Client`略微容易一些,因为它避免了一些不必要的操作。:code:`CifarClient` " +"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模" +"型:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 msgid ":code:`set_parameters`" @@ -3375,50 +3547,55 @@ msgstr ":code:`set_parameters`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`cifar.py`. So what we really do here is we tell Flower " -"through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`test()` previously defined " +"in :code:`cifar.py`. So what we really do here is we tell Flower through " +"our :code:`NumPyClient` subclass which of our already defined functions to " +"call for training and evaluation. We included type annotations to give you a " +"better understanding of the data types that get passed around." msgstr "" -"这两个 :code:`NumPyClient` 中的方法 :code:`fit` 和 :code:`evaluate` 使用了之前在 " -":code:`cifar.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因此,我们在这里要做的就是通过 " -":code:`NumPyClient` 子类告知 Flower " -"在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让你更好地理解传递的数据类型。" +"这两个 :code:`NumPyClient` 中的方法 :code:`fit` 和 :code:`evaluate` 使用了之" +"前在 :code:`cifar.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因此," +"我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 Flower 在训练和评估时要" +"调用哪些已定义的函数。我们加入了类型注解,以便让你更好地理解传递的数据类型。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" "All that's left to do it to define a function that loads both model and " -"data, creates a :code:`CifarClient`, and starts this client. You load " -"your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " -"with the function :code:`fl.client.start_client()` by pointing it at the " -"same IP address we used in :code:`server.py`:" -msgstr "剩下的就是定义模型和数据加载函数了。创建一个:code:`CifarClient`类,并运行这个客服端。您将通过:code:`cifar.py`加载数据和模型。另外,通过:code:`fl.client.start_client()`函数来运行客户端:code:`CifarClient`,需要保证IP地址和:code:`server.py`中所使用的一致:" +"data, creates a :code:`CifarClient`, and starts this client. You load your " +"data and model by using :code:`cifar.py`. Start :code:`CifarClient` with the " +"function :code:`fl.client.start_client()` by pointing it at the same IP " +"address we used in :code:`server.py`:" +msgstr "" +"剩下的就是定义模型和数据加载函数了。创建一个:code:`CifarClient`类,并运行这个" +"客服端。您将通过:code:`cifar.py`加载数据和模型。另外,通过:code:`fl.client." +"start_client()`函数来运行客户端:code:`CifarClient`,需要保证IP地址和:code:" +"`server.py`中所使用的一致:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" -"in each window (make sure that the server is running before you do so) " -"and see your (previously centralized) PyTorch project run federated " -"learning across two clients. Congratulations!" -msgstr "确保服务器正在运行后,您就能看到您的 PyTorch 项目(之前是集中式的)在两个客户端上运行联邦学习了。祝贺!" +"in each window (make sure that the server is running before you do so) and " +"see your (previously centralized) PyTorch project run federated learning " +"across two clients. Congratulations!" +msgstr "" +"确保服务器正在运行后,您就能看到您的 PyTorch 项目(之前是集中式的)在两个客户" +"端上运行联邦学习了。祝贺!" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" "The full source code for this example: `PyTorch: From Centralized To " -"Federated (Code) `_. Our example is, of course, " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using different subsets of CIFAR-10 on each client? " -"How about adding more clients?" -msgstr "" -"本示例的完整源代码为:`PyTorch: 从集中式到联合式 " -"`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现在,您已经准备好进一步探讨这一主题了。比如在每个客户端使用不同的" -" CIFAR-10 子集会如何?增加更多客户端会如何?" +"Federated (Code) `_. Our example is, of course, somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using different subsets of CIFAR-10 on each client? How about adding more " +"clients?" +msgstr "" +"本示例的完整源代码为:`PyTorch: 从集中式到联合式 `_。当然,我" +"们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现" +"在,您已经准备好进一步探讨这一主题了。比如在每个客户端使用不同的 CIFAR-10 子" +"集会如何?增加更多客户端会如何?" #: ../../source/explanation-differential-privacy.rst:2 #: ../../source/explanation-differential-privacy.rst:11 @@ -3429,11 +3606,10 @@ msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:3 #, fuzzy msgid "" -"The information in datasets like healthcare, financial transactions, user" -" preferences, etc., is valuable and has the potential for scientific " -"breakthroughs and provides important business insights. However, such " -"data is also sensitive and there is a risk of compromising individual " -"privacy." +"The information in datasets like healthcare, financial transactions, user " +"preferences, etc., is valuable and has the potential for scientific " +"breakthroughs and provides important business insights. However, such data " +"is also sensitive and there is a risk of compromising individual privacy." msgstr "" "医疗保健、金融交易、用户偏好等数据集中的信息非常宝贵,有可能带来科学突破并提" "供重要的商业见解。然而,这些数据也是敏感数据,存在泄露个人隐私的风险。" @@ -3442,10 +3618,11 @@ msgstr "" #, fuzzy msgid "" "Traditional methods like anonymization alone would not work because of " -"attacks like Re-identification and Data Linkage. That's where " -"differential privacy comes in. It provides the possibility of analyzing " -"data while ensuring the privacy of individuals." -msgstr "单靠匿名等传统方法是行不通的,因为会受到重新识别和数据链接等攻击。这就是差异" +"attacks like Re-identification and Data Linkage. That's where differential " +"privacy comes in. It provides the possibility of analyzing data while " +"ensuring the privacy of individuals." +msgstr "" +"单靠匿名等传统方法是行不通的,因为会受到重新识别和数据链接等攻击。这就是差异" "化隐私的用武之地。它提供了在分析数据的同时确保个人隐私的可能性。" #: ../../source/explanation-differential-privacy.rst:12 @@ -3455,13 +3632,13 @@ msgid "" "instance, Alice's data). Differential Privacy (DP) guarantees that any " "analysis (M), like calculating the average income, will produce nearly " "identical results for both datasets (O and O' would be similar). This " -"preserves group patterns while obscuring individual details, ensuring the" -" individual's information remains hidden in the crowd." +"preserves group patterns while obscuring individual details, ensuring the " +"individual's information remains hidden in the crowd." msgstr "" -"试想一下,两个数据集除了一条记录(例如 Alice 的数据)之外完全相同。差分隐私(" -"DP)可以保证任何分析(M),比如计算平均收入,对两个数据集都会产生几乎相同的结" -"果(O 和 O' 将是相似的)。这既保留了群体模式,又掩盖了个人细节,确保个人的信" -"息隐藏在人群中。" +"试想一下,两个数据集除了一条记录(例如 Alice 的数据)之外完全相同。差分隐私" +"(DP)可以保证任何分析(M),比如计算平均收入,对两个数据集都会产生几乎相同的" +"结果(O 和 O' 将是相似的)。这既保留了群体模式,又掩盖了个人细节,确保个人的" +"信息隐藏在人群中。" #: ../../source/explanation-differential-privacy.rst:-1 #, fuzzy @@ -3473,9 +3650,9 @@ msgstr "DP 介绍" msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " -"individual in the data while preserving the overall accuracy of the " -"analysis." -msgstr "实现 DP 的最常用机制之一是在分析输出中加入足够的噪音,以掩盖数据中每个个体的" +"individual in the data while preserving the overall accuracy of the analysis." +msgstr "" +"实现 DP 的最常用机制之一是在分析输出中加入足够的噪音,以掩盖数据中每个个体的" "贡献,同时保持分析的整体准确性。" #: ../../source/explanation-differential-privacy.rst:25 @@ -3488,18 +3665,18 @@ msgstr "编译 ProtoBuf 定义" msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " -"algorithm. It provides an unconditional upper bound on the influence of a" -" single individual on the output of the algorithm by adding noise [1]. A " -"randomized mechanism M provides (:math:`\\epsilon`, " -":math:`\\delta`)-differential privacy if for any two neighboring " -"databases, D :sub:`1` and D :sub:`2`, that differ in only a single " -"record, and for all possible outputs S ⊆ Range(A):" +"algorithm. It provides an unconditional upper bound on the influence of a " +"single individual on the output of the algorithm by adding noise [1]. A " +"randomized mechanism M provides (:math:`\\epsilon`, :math:`\\delta`)-" +"differential privacy if for any two neighboring databases, D :sub:`1` and D :" +"sub:`2`, that differ in only a single record, and for all possible outputs S " +"⊆ Range(A):" msgstr "" "差分隐私(Differential Privacy,DP)针对对手通过随机算法的输出所能推断出的信" "息提供统计保证。它为单个个体通过添加噪声对算法输出的影响提供了一个无条件的上" -"限[1]。如果任意两个相邻的数据库D :sub:`1`和D :sub:`2`只有一条记录不同," -"并且对于所有可能的输出S ⊆ Range(A),随机化机制M提供(:math:`epsilon`,:math:`" -"\\delta`)差异隐私:" +"限[1]。如果任意两个相邻的数据库D :sub:`1`和D :sub:`2`只有一条记录不同,并且对" +"于所有可能的输出S ⊆ Range(A),随机化机制M提供(:math:`epsilon`,:math:" +"`\\delta`)差异隐私:" #: ../../source/explanation-differential-privacy.rst:32 #, fuzzy @@ -3516,17 +3693,16 @@ msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " "lower :math:`\\epsilon` values indicate higher levels of privacy but are " -"likely to reduce utility as well. The :math:`\\delta` parameter accounts " -"for a small probability on which the upper bound :math:`\\epsilon` does " -"not hold. The amount of noise needed to achieve differential privacy is " -"proportional to the sensitivity of the output, which measures the maximum" -" change in the output due to the inclusion or removal of a single record." -msgstr "" -":math:`\\epsilon`参数也称为隐私预算,是衡量隐私损失的指标。较低的 :math:`" -"\\epsilon` 值表示较高的隐私级别,但也可能降低效用。:math:`\\delta" -"`参数考虑了:math:`\\epsilon`上限不成立的小概率。实现差异化隐私所需的噪声量与" -"输出的灵敏度成正比,而输出的灵敏度是指由于包含或删除一条记录而导致的输出的最" -"大变化。" +"likely to reduce utility as well. The :math:`\\delta` parameter accounts for " +"a small probability on which the upper bound :math:`\\epsilon` does not " +"hold. The amount of noise needed to achieve differential privacy is " +"proportional to the sensitivity of the output, which measures the maximum " +"change in the output due to the inclusion or removal of a single record." +msgstr "" +":math:`\\epsilon`参数也称为隐私预算,是衡量隐私损失的指标。较低的 :math:" +"`\\epsilon` 值表示较高的隐私级别,但也可能降低效用。:math:`\\delta`参数考虑" +"了:math:`\\epsilon`上限不成立的小概率。实现差异化隐私所需的噪声量与输出的灵敏" +"度成正比,而输出的灵敏度是指由于包含或删除一条记录而导致的输出的最大变化。" #: ../../source/explanation-differential-privacy.rst:45 #, fuzzy @@ -3538,15 +3714,14 @@ msgstr "差分隐私" msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " -"designed in a way to prevent the algorithm to learn any specific " -"information about any individual data points and subsequently prevent the" -" model from revealing sensitive information. Depending on the stage at " -"which noise is introduced, various methods exist for applying DP to " -"machine learning algorithms. One approach involves adding noise to the " -"training data (either to the features or labels), while another method " -"entails injecting noise into the gradients of the loss function during " -"model training. Additionally, such noise can be incorporated into the " -"model's output." +"designed in a way to prevent the algorithm to learn any specific information " +"about any individual data points and subsequently prevent the model from " +"revealing sensitive information. Depending on the stage at which noise is " +"introduced, various methods exist for applying DP to machine learning " +"algorithms. One approach involves adding noise to the training data (either " +"to the features or labels), while another method entails injecting noise " +"into the gradients of the loss function during model training. Additionally, " +"such noise can be incorporated into the model's output." msgstr "" "机器学习中可以利用 DP 来保护训练数据的隐私。差分保密机器学习算法的设计方式是" "防止算法学习到任何单个数据点的任何特定信息,从而防止模型泄露敏感信息。根据引" @@ -3565,8 +3740,8 @@ msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " "However, federated learning also introduces new privacy challenges. The " -"model updates between parties and the central server can leak information" -" about the local data. These leaks can be exploited by attacks such as " +"model updates between parties and the central server can leak information " +"about the local data. These leaks can be exploited by attacks such as " "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" @@ -3578,41 +3753,43 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:58 #, fuzzy msgid "" -"DP can play a crucial role in federated learning to provide privacy for " -"the clients' data." +"DP can play a crucial role in federated learning to provide privacy for the " +"clients' data." msgstr "DP 可以在联合学习中发挥重要作用,为客户数据提供隐私保护。" #: ../../source/explanation-differential-privacy.rst:60 #, fuzzy msgid "" -"Depending on the granularity of privacy provision or the location of " -"noise addition, different forms of DP exist in federated learning. In " -"this explainer, we focus on two approaches of DP utilization in federated" -" learning based on where the noise is added: at the server (also known as" -" the center) or at the client (also known as the local)." +"Depending on the granularity of privacy provision or the location of noise " +"addition, different forms of DP exist in federated learning. In this " +"explainer, we focus on two approaches of DP utilization in federated " +"learning based on where the noise is added: at the server (also known as the " +"center) or at the client (also known as the local)." msgstr "" -"根据提供隐私的粒度或添加噪声的位置,联合学习中存在不同形式的 " -"DP。在本说明中,我们将根据添加噪声的位置,重点介绍联合学习中利用 DP " -"的两种方法:在服务器(也称为中心)或客户端(也称为本地)。" +"根据提供隐私的粒度或添加噪声的位置,联合学习中存在不同形式的 DP。在本说明中," +"我们将根据添加噪声的位置,重点介绍联合学习中利用 DP 的两种方法:在服务器(也" +"称为中心)或客户端(也称为本地)。" #: ../../source/explanation-differential-privacy.rst:63 #, fuzzy msgid "" -"**Central Differential Privacy**: DP is applied by the server and the " -"goal is to prevent the aggregated model from leaking information about " -"each client's data." -msgstr "**中央差分隐私**: DP " -"由服务器应用,目标是防止聚合模型泄露每个客户的数据信息。" +"**Central Differential Privacy**: DP is applied by the server and the goal " +"is to prevent the aggregated model from leaking information about each " +"client's data." +msgstr "" +"**中央差分隐私**: DP 由服务器应用,目标是防止聚合模型泄露每个客户的数据信" +"息。" #: ../../source/explanation-differential-privacy.rst:65 #, fuzzy msgid "" "**Local Differential Privacy**: DP is applied on the client side before " -"sending any information to the server and the goal is to prevent the " -"updates that are sent to the server from leaking any information about " -"the client's data." -msgstr "**本地差分隐私**: 在向服务器发送任何信息之前,在客户端应用 " -"DP,目的是防止向服务器发送的更新泄露任何有关客户端数据的信息。" +"sending any information to the server and the goal is to prevent the updates " +"that are sent to the server from leaking any information about the client's " +"data." +msgstr "" +"**本地差分隐私**: 在向服务器发送任何信息之前,在客户端应用 DP,目的是防止向" +"服务器发送的更新泄露任何有关客户端数据的信息。" #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:68 @@ -3624,34 +3801,34 @@ msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:69 #, fuzzy msgid "" -"In this approach, which is also known as user-level DP, the central " -"server is responsible for adding noise to the globally aggregated " -"parameters. It should be noted that trust in the server is required." -msgstr "在这种方法(也称为用户级 DP)中,中央服务器负责在全局汇总参数中添加噪声。需要" +"In this approach, which is also known as user-level DP, the central server " +"is responsible for adding noise to the globally aggregated parameters. It " +"should be noted that trust in the server is required." +msgstr "" +"在这种方法(也称为用户级 DP)中,中央服务器负责在全局汇总参数中添加噪声。需要" "注意的是,这需要对服务器的信任。" #: ../../source/explanation-differential-privacy.rst:76 #, fuzzy msgid "" -"While there are various ways to implement central DP in federated " -"learning, we concentrate on the algorithms proposed by [2] and [3]. The " -"overall approach is to clip the model updates sent by the clients and add" -" some amount of noise to the aggregated model. In each iteration, a " -"random set of clients is chosen with a specific probability for training." -" Each client performs local training on its own data. The update of each " -"client is then clipped by some value `S` (sensitivity `S`). This would " -"limit the impact of any individual client which is crucial for privacy " -"and often beneficial for robustness. A common approach to achieve this is" -" by restricting the `L2` norm of the clients' model updates, ensuring " -"that larger updates are scaled down to fit within the norm `S`." +"While there are various ways to implement central DP in federated learning, " +"we concentrate on the algorithms proposed by [2] and [3]. The overall " +"approach is to clip the model updates sent by the clients and add some " +"amount of noise to the aggregated model. In each iteration, a random set of " +"clients is chosen with a specific probability for training. Each client " +"performs local training on its own data. The update of each client is then " +"clipped by some value `S` (sensitivity `S`). This would limit the impact of " +"any individual client which is crucial for privacy and often beneficial for " +"robustness. A common approach to achieve this is by restricting the `L2` " +"norm of the clients' model updates, ensuring that larger updates are scaled " +"down to fit within the norm `S`." msgstr "" "虽然在联合学习中实现中央数据处理的方法有很多种,但我们将重点放在[2]和[3]提出" -"的算法上。总体方法是剪辑客户端发送的模型更新,并在聚合模型中添加一定量的噪声" -"。在每次迭代中,以特定概率随机选择一组客户端进行训练。每个客户端对自己的数据" -"进行局部训练。然后,每个客户端的更新会被某个值`S`(灵敏度`S`)剪切。这将限制" -"任何单个客户端的影响,这对隐私至关重要,通常也有利于稳健性。" -"实现这一点的常用方法是限制客户机模型更新的 `L2` 准则," -"确保较大的更新被缩减以适应 `S` 准则。" +"的算法上。总体方法是剪辑客户端发送的模型更新,并在聚合模型中添加一定量的噪" +"声。在每次迭代中,以特定概率随机选择一组客户端进行训练。每个客户端对自己的数" +"据进行局部训练。然后,每个客户端的更新会被某个值`S`(灵敏度`S`)剪切。这将限" +"制任何单个客户端的影响,这对隐私至关重要,通常也有利于稳健性。实现这一点的常" +"用方法是限制客户机模型更新的 `L2` 准则,确保较大的更新被缩减以适应 `S` 准则。" #: ../../source/explanation-differential-privacy.rst:-1 #, fuzzy @@ -3661,15 +3838,15 @@ msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:89 #, fuzzy msgid "" -"Afterwards, the Gaussian mechanism is used to add noise in order to " -"distort the sum of all clients' updates. The amount of noise is scaled to" -" the sensitivity value to obtain a privacy guarantee. The Gaussian " -"mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " -"noise_scale * S ) / (number of sampled clients)`." +"Afterwards, the Gaussian mechanism is used to add noise in order to distort " +"the sum of all clients' updates. The amount of noise is scaled to the " +"sensitivity value to obtain a privacy guarantee. The Gaussian mechanism is " +"used with a noise sampled from `N (0, σ²)` where `σ = ( noise_scale * S ) / " +"(number of sampled clients)`." msgstr "" "然后,使用高斯机制添加噪声,以扭曲所有客户端的更新总和。噪声量与灵敏度值成正" -"比,以获得隐私保证。高斯机制的噪声采样范围为 `N (0, σ²)` ,其中 σ = ( " -"噪声规模 * S ) / (采样客户数)`。" +"比,以获得隐私保证。高斯机制的噪声采样范围为 `N (0, σ²)` ,其中 σ = ( 噪声规" +"模 * S ) / (采样客户数)`。" #: ../../source/explanation-differential-privacy.rst:94 #, fuzzy @@ -3679,36 +3856,39 @@ msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:96 #, fuzzy msgid "" -"There are two forms of clipping commonly used in Central DP: Fixed " -"Clipping and Adaptive Clipping." +"There are two forms of clipping commonly used in Central DP: Fixed Clipping " +"and Adaptive Clipping." msgstr "中央处理器常用的剪切有两种形式:固定剪切和自适应剪切。" #: ../../source/explanation-differential-privacy.rst:98 #, fuzzy msgid "" -"**Fixed Clipping** : A predefined fix threshold is set for the magnitude " -"of clients' updates. Any update exceeding this threshold is clipped back " -"to the threshold value." -msgstr "** 固定削波** : 为客户端更新的大小设置了一个预定义的固定阈值。任何超过该阈值" +"**Fixed Clipping** : A predefined fix threshold is set for the magnitude of " +"clients' updates. Any update exceeding this threshold is clipped back to the " +"threshold value." +msgstr "" +"** 固定削波** : 为客户端更新的大小设置了一个预定义的固定阈值。任何超过该阈值" "的更新都会被剪切回阈值。" #: ../../source/explanation-differential-privacy.rst:100 #, fuzzy msgid "" -"**Adaptive Clipping** : The clipping threshold dynamically adjusts based " -"on the observed update distribution [4]. It means that the clipping value" -" is tuned during the rounds with respect to the quantile of the update " -"norm distribution." -msgstr "** 自适应削波** : 削波阈值根据观察到的更新分布动态调整[4]。这意味着,在各轮" +"**Adaptive Clipping** : The clipping threshold dynamically adjusts based on " +"the observed update distribution [4]. It means that the clipping value is " +"tuned during the rounds with respect to the quantile of the update norm " +"distribution." +msgstr "" +"** 自适应削波** : 削波阈值根据观察到的更新分布动态调整[4]。这意味着,在各轮" "中,会根据更新规范分布的量化值调整削波值。" #: ../../source/explanation-differential-privacy.rst:102 #, fuzzy msgid "" -"The choice between fixed and adaptive clipping depends on various factors" -" such as privacy requirements, data distribution, model complexity, and " +"The choice between fixed and adaptive clipping depends on various factors " +"such as privacy requirements, data distribution, model complexity, and " "others." -msgstr "在固定剪切和自适应剪切之间做出选择取决于各种因素,如隐私要求、数据分布、模型" +msgstr "" +"在固定剪切和自适应剪切之间做出选择取决于各种因素,如隐私要求、数据分布、模型" "复杂性等。" #: ../../source/explanation-differential-privacy.rst:-1 @@ -3722,13 +3902,13 @@ msgstr "差分隐私" #, fuzzy msgid "" "In this approach, each client is responsible for performing DP. Local DP " -"avoids the need for a fully trusted aggregator, but it should be noted " -"that local DP leads to a decrease in accuracy but better privacy in " -"comparison to central DP." +"avoids the need for a fully trusted aggregator, but it should be noted that " +"local DP leads to a decrease in accuracy but better privacy in comparison to " +"central DP." msgstr "" -"在这种方法中,每个客户端都负责执行 DP。本地 DP " -"避免了对完全可信的聚合器的需求,但需要注意的是,与中央 DP 相比,本地 DP " -"会降低准确性,但却能更好地保护隐私。" +"在这种方法中,每个客户端都负责执行 DP。本地 DP 避免了对完全可信的聚合器的需" +"求,但需要注意的是,与中央 DP 相比,本地 DP 会降低准确性,但却能更好地保护隐" +"私。" #: ../../source/explanation-differential-privacy.rst:116 #, fuzzy @@ -3739,25 +3919,25 @@ msgstr "在本说明中,我们将重点介绍实现本地 DP 的两种形式 #, fuzzy msgid "" "Each client adds noise to the local updates before sending them to the " -"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " -"the sensitivity of the local model to be ∆, Gaussian noise is applied " -"with a noise scale of σ where:" +"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering the " +"sensitivity of the local model to be ∆, Gaussian noise is applied with a " +"noise scale of σ where:" msgstr "" -"每个客户端在向服务器发送本地更新之前,都会在本地更新中加入噪声。为了实现(:ma" -"th:`\\epsilon`, :math:`\\delta`)-DP,考虑到本地模型的灵敏度为 " -"∆,应用了高斯噪声,噪声尺度为 σ,其中:" +"每个客户端在向服务器发送本地更新之前,都会在本地更新中加入噪声。为了实现(:" +"math:`\\epsilon`, :math:`\\delta`)-DP,考虑到本地模型的灵敏度为 ∆,应用了高" +"斯噪声,噪声尺度为 σ,其中:" #: ../../source/explanation-differential-privacy.rst:120 #, fuzzy msgid "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times " -"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" +"{\\epsilon}\n" "\n" msgstr "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right" -")}}{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" +"{\\epsilon}\n" "\n" #: ../../source/explanation-differential-privacy.rst:125 @@ -3766,7 +3946,8 @@ msgid "" "Each client adds noise to the gradients of the model during the local " "training (DP-SGD). More specifically, in this approach, gradients are " "clipped and an amount of calibrated noise is injected into the gradients." -msgstr "在局部训练过程中,每个客户端都会向模型的梯度添加噪声(DP-SGD)。更具体地说," +msgstr "" +"在局部训练过程中,每个客户端都会向模型的梯度添加噪声(DP-SGD)。更具体地说," "在这种方法中,梯度会被剪切,并在梯度中注入一定量的校准噪声。" #: ../../source/explanation-differential-privacy.rst:128 @@ -3789,26 +3970,25 @@ msgstr "[1] Dwork 等:《差分隐私的算法基础》。" #: ../../source/explanation-differential-privacy.rst:135 #, fuzzy msgid "" -"[2] McMahan et al. Learning Differentially Private Recurrent Language " -"Models." +"[2] McMahan et al. Learning Differentially Private Recurrent Language Models." msgstr "" -"McMahan, H. Brendan等. \"Learning differentially private recurrent " -"language models.\" arXiv preprint arXiv:1710.06963 (2017)." +"McMahan, H. Brendan等. \"Learning differentially private recurrent language " +"models.\" arXiv preprint arXiv:1710.06963 (2017)." #: ../../source/explanation-differential-privacy.rst:137 #, fuzzy msgid "" -"[3] Geyer et al. Differentially Private Federated Learning: A Client " -"Level Perspective." +"[3] Geyer et al. Differentially Private Federated Learning: A Client Level " +"Perspective." msgstr "[3] Geyer 等人。差异化化私人联合学习:客户层面的视角。" #: ../../source/explanation-differential-privacy.rst:139 #, fuzzy -msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." +msgid "" +"[4] Galen et al. Differentially Private Learning with Adaptive Clipping." msgstr "" -"Andrew, Galen等. \"Differentially private learning with adaptive " -"clipping.\" Advances in Neural Information Processing Systems 34 (2021): " -"17455-17466." +"Andrew, Galen等. \"Differentially private learning with adaptive clipping.\" " +"Advances in Neural Information Processing Systems 34 (2021): 17455-17466." #: ../../source/explanation-federated-evaluation.rst:2 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:292 @@ -3818,9 +3998,11 @@ msgstr "联邦学习评估" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" "There are two main approaches to evaluating models in federated learning " -"systems: centralized (or server-side) evaluation and federated (or " -"client-side) evaluation." -msgstr "评估联合学习系统中的模型主要有两种方法:集中(或服务器端)评估和联邦(或客户端)评估。" +"systems: centralized (or server-side) evaluation and federated (or client-" +"side) evaluation." +msgstr "" +"评估联合学习系统中的模型主要有两种方法:集中(或服务器端)评估和联邦(或客户" +"端)评估。" #: ../../source/explanation-federated-evaluation.rst:8 msgid "Centralized Evaluation" @@ -3836,7 +4018,9 @@ msgid "" "evaluation function during initialization. An evaluation function is any " "function that can take the current global model parameters as input and " "return evaluation results:" -msgstr "所有内置策略都通过在初始化过程中提供一个评估函数来支持集中评估。评估函数是任何可以将当前全局模型参数作为输入并返回评估结果的函数:" +msgstr "" +"所有内置策略都通过在初始化过程中提供一个评估函数来支持集中评估。评估函数是任" +"何可以将当前全局模型参数作为输入并返回评估结果的函数:" #: ../../source/explanation-federated-evaluation.rst:58 msgid "Custom Strategies" @@ -3844,14 +4028,14 @@ msgstr "定制策略" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" -"The :code:`Strategy` abstraction provides a method called " -":code:`evaluate` that can directly be used to evaluate the current global" -" model parameters. The current server implementation calls " -":code:`evaluate` after parameter aggregation and before federated " -"evaluation (see next paragraph)." +"The :code:`Strategy` abstraction provides a method called :code:`evaluate` " +"that can directly be used to evaluate the current global model parameters. " +"The current server implementation calls :code:`evaluate` after parameter " +"aggregation and before federated evaluation (see next paragraph)." msgstr "" -":code:`Strategy` 抽象提供了一个名为 :code:`evaluate` " -"的方法,可直接用于评估当前的全局模型参数。服务器会在参数聚合后和联邦评估前调用 :code:`evaluate`(见下段)。" +":code:`Strategy` 抽象提供了一个名为 :code:`evaluate` 的方法,可直接用于评估当" +"前的全局模型参数。服务器会在参数聚合后和联邦评估前调用 :code:`evaluate`(见下" +"段)。" #: ../../source/explanation-federated-evaluation.rst:65 msgid "Federated Evaluation" @@ -3863,9 +4047,10 @@ msgstr "实现联邦评估" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" -"Client-side evaluation happens in the :code:`Client.evaluate` method and " -"can be configured from the server side." -msgstr "客户端评估在 :code:`Client.evaluate` 方法中进行,并可从服务器端进行配置。" +"Client-side evaluation happens in the :code:`Client.evaluate` method and can " +"be configured from the server side." +msgstr "" +"客户端评估在 :code:`Client.evaluate` 方法中进行,并可从服务器端进行配置。" #: ../../source/explanation-federated-evaluation.rst:101 msgid "Configuring Federated Evaluation" @@ -3879,51 +4064,55 @@ msgstr "联邦评估可从服务器端进行配置。内置策略支持以下参 #: ../../source/explanation-federated-evaluation.rst:105 msgid "" -":code:`fraction_evaluate`: a :code:`float` defining the fraction of " -"clients that will be selected for evaluation. If " -":code:`fraction_evaluate` is set to :code:`0.1` and :code:`100` clients " -"are connected to the server, then :code:`10` will be randomly selected " -"for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " -"federated evaluation will be disabled." +":code:`fraction_evaluate`: a :code:`float` defining the fraction of clients " +"that will be selected for evaluation. If :code:`fraction_evaluate` is set " +"to :code:`0.1` and :code:`100` clients are connected to the server, then :" +"code:`10` will be randomly selected for evaluation. If :code:" +"`fraction_evaluate` is set to :code:`0.0`, federated evaluation will be " +"disabled." msgstr "" -":code:`fraction_evaluate`: :code:`float`,定义了被选中进行评估的客户端的比例。如果 " -":code:`fraction_evaluate` 设置为 :code:`0.1`,并且 :code:`100` 个客户端连接到服务器,那么 " -":code:`10` 个客户端将被随机选中进行评估。如果 :code:`fraction_evaluate` 设置为 " -":code:`0.0`,联邦评估将被禁用。" +":code:`fraction_evaluate`: :code:`float`,定义了被选中进行评估的客户端的比" +"例。如果 :code:`fraction_evaluate` 设置为 :code:`0.1`,并且 :code:`100` 个客" +"户端连接到服务器,那么 :code:`10` 个客户端将被随机选中进行评估。如果 :code:" +"`fraction_evaluate` 设置为 :code:`0.0`,联邦评估将被禁用。" #: ../../source/explanation-federated-evaluation.rst:106 msgid "" -":code:`min_evaluate_clients`: an :code:`int`: the minimum number of " -"clients to be selected for evaluation. If :code:`fraction_evaluate` is " -"set to :code:`0.1`, :code:`min_evaluate_clients` is set to 20, and " -":code:`100` clients are connected to the server, then :code:`20` clients " -"will be selected for evaluation." +":code:`min_evaluate_clients`: an :code:`int`: the minimum number of clients " +"to be selected for evaluation. If :code:`fraction_evaluate` is set to :code:" +"`0.1`, :code:`min_evaluate_clients` is set to 20, and :code:`100` clients " +"are connected to the server, then :code:`20` clients will be selected for " +"evaluation." msgstr "" -":code:`min_evaluate_clients`:一个 :code:`int`,需要评估的客户的最小数量。如果 " -":code:`fraction_evaluate` 设置为 :code:`0.1`,:code:`min_evaluate_clients` " -"设置为 20,并且有 :code:`100` 个客户端已连接到服务器,那么 :code:`20` 个客户端将被选中进行评估。" +":code:`min_evaluate_clients`:一个 :code:`int`,需要评估的客户的最小数量。如" +"果 :code:`fraction_evaluate` 设置为 :code:`0.1`,:code:" +"`min_evaluate_clients` 设置为 20,并且有 :code:`100` 个客户端已连接到服务器," +"那么 :code:`20` 个客户端将被选中进行评估。" #: ../../source/explanation-federated-evaluation.rst:107 msgid "" ":code:`min_available_clients`: an :code:`int` that defines the minimum " -"number of clients which need to be connected to the server before a round" -" of federated evaluation can start. If fewer than " -":code:`min_available_clients` are connected to the server, the server " -"will wait until more clients are connected before it continues to sample " -"clients for evaluation." +"number of clients which need to be connected to the server before a round of " +"federated evaluation can start. If fewer than :code:`min_available_clients` " +"are connected to the server, the server will wait until more clients are " +"connected before it continues to sample clients for evaluation." msgstr "" -":code:`min_available_clients`: " -":code:`int`,定义了在一轮联邦评估开始之前,需要连接到服务器的最小客户端数量。如果连接到服务器的客户端数量少于 " -":code:`min_available_clients`,服务器将等待更多客户端连接后,才继续采样客户端进行评估。" +":code:`min_available_clients`: :code:`int`,定义了在一轮联邦评估开始之前,需" +"要连接到服务器的最小客户端数量。如果连接到服务器的客户端数量少于 :code:" +"`min_available_clients`,服务器将等待更多客户端连接后,才继续采样客户端进行评" +"估。" #: ../../source/explanation-federated-evaluation.rst:108 msgid "" ":code:`on_evaluate_config_fn`: a function that returns a configuration " -"dictionary which will be sent to the selected clients. The function will " -"be called during each round and provides a convenient way to customize " -"client-side evaluation from the server side, for example, to configure " -"the number of validation steps performed." -msgstr "code:`on_evaluate_config_fn`:返回配置字典的函数,该字典将发送给选定的客户端。该函数将在每一轮中被调用,并提供了一种方便的方法来从服务器端自定义客户端评估,例如,配置执行的验证步骤数。" +"dictionary which will be sent to the selected clients. The function will be " +"called during each round and provides a convenient way to customize client-" +"side evaluation from the server side, for example, to configure the number " +"of validation steps performed." +msgstr "" +"code:`on_evaluate_config_fn`:返回配置字典的函数,该字典将发送给选定的客户" +"端。该函数将在每一轮中被调用,并提供了一种方便的方法来从服务器端自定义客户端" +"评估,例如,配置执行的验证步骤数。" #: ../../source/explanation-federated-evaluation.rst:135 msgid "Evaluating Local Model Updates During Training" @@ -3931,10 +4120,11 @@ msgstr "评估训练期间的本地模型更新" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" -"Model parameters can also be evaluated during training. " -":code:`Client.fit` can return arbitrary evaluation results as a " -"dictionary:" -msgstr "模型参数也可在训练过程中进行评估。 :code:`Client.fit`可以字典形式返回任意评估结果:" +"Model parameters can also be evaluated during training. :code:`Client.fit` " +"can return arbitrary evaluation results as a dictionary:" +msgstr "" +"模型参数也可在训练过程中进行评估。 :code:`Client.fit`可以字典形式返回任意评估" +"结果:" #: ../../source/explanation-federated-evaluation.rst:177 msgid "Full Code Example" @@ -3942,14 +4132,14 @@ msgstr "完整代码示例" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" -"For a full code example that uses both centralized and federated " -"evaluation, see the *Advanced TensorFlow Example* (the same approach can " -"be applied to workloads implemented in any other framework): " -"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" +"For a full code example that uses both centralized and federated evaluation, " +"see the *Advanced TensorFlow Example* (the same approach can be applied to " +"workloads implemented in any other framework): https://github.com/adap/" +"flower/tree/main/examples/advanced-tensorflow" msgstr "" "有关同时使用集中评估和联邦评估的完整代码示例,请参阅 *Advanced TensorFlow " -"Example*(同样的方法也可应用于任何其他框架中): " -"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" +"Example*(同样的方法也可应用于任何其他框架中): https://github.com/adap/" +"flower/tree/main/examples/advanced-tensorflow" #: ../../source/fed/0000-20200102-fed-template.md:10 msgid "FED Template" @@ -4122,10 +4312,12 @@ msgstr "保留 GitHub 问题,用于跟踪进行中的工作" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" -"ensure community participants can successfully drive changes to " -"completion across one or more releases while stakeholders are adequately " -"represented throughout the process" -msgstr "确保社区参与者能够成功推动改动,完成一个或多个版本,同时利益相关者在整个过程中得到充分展现" +"ensure community participants can successfully drive changes to completion " +"across one or more releases while stakeholders are adequately represented " +"throughout the process" +msgstr "" +"确保社区参与者能够成功推动改动,完成一个或多个版本,同时利益相关者在整个过程" +"中得到充分展现" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 msgid "Hence, an Enhancement Doc combines aspects of" @@ -4152,61 +4344,69 @@ msgstr "该文件是与社区合作逐步创建的。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" "For far-fetching changes or features proposed to Flower, an abstraction " -"beyond a single GitHub issue or pull request is required to understand " -"and communicate upcoming changes to the project." +"beyond a single GitHub issue or pull request is required to understand and " +"communicate upcoming changes to the project." msgstr "" -"对于向 Flower 提出的远期变更或功能,需要一个超越单个 GitHub 问题或拉取请求(pull " -"request)的抽象概念,以了解和沟通项目即将发生的变更。" +"对于向 Flower 提出的远期变更或功能,需要一个超越单个 GitHub 问题或拉取请求" +"(pull request)的抽象概念,以了解和沟通项目即将发生的变更。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" -"The purpose of this process is to reduce the amount of \"tribal " -"knowledge\" in our community. By moving decisions from Slack threads, " -"video calls, and hallway conversations into a well-tracked artifact, this" -" process aims to enhance communication and discoverability." +"The purpose of this process is to reduce the amount of \"tribal knowledge\" " +"in our community. By moving decisions from Slack threads, video calls, and " +"hallway conversations into a well-tracked artifact, this process aims to " +"enhance communication and discoverability." msgstr "" -"这一流程的目的是减少我们社区中 \"部落知识 \"的数量。通过将决策从 Slack " -"线程、视频通话和走廊对话转移到一个跟踪良好的工作环境中,该流程旨在加强沟通和可发现性。" +"这一流程的目的是减少我们社区中 \"部落知识 \"的数量。通过将决策从 Slack 线程、" +"视频通话和走廊对话转移到一个跟踪良好的工作环境中,该流程旨在加强沟通和可发现" +"性。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" -"Roughly any larger, user-facing enhancement should follow the Enhancement" -" process. If an enhancement would be described in either written or " -"verbal communication to anyone besides the author or developer, then " -"consider creating an Enhancement Doc." -msgstr "任何较大的、面向用户的增强都应遵循增强流程。如果要以书面或口头形式向作者或开发人员以外的任何人描述增强功能,则应考虑创建改善文档。" +"Roughly any larger, user-facing enhancement should follow the Enhancement " +"process. If an enhancement would be described in either written or verbal " +"communication to anyone besides the author or developer, then consider " +"creating an Enhancement Doc." +msgstr "" +"任何较大的、面向用户的增强都应遵循增强流程。如果要以书面或口头形式向作者或开" +"发人员以外的任何人描述增强功能,则应考虑创建改善文档。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" -"Similarly, any technical effort (refactoring, major architectural change)" -" that will impact a large section of the development community should " -"also be communicated widely. The Enhancement process is suited for this " -"even if it will have zero impact on the typical user or operator." -msgstr "同样,任何会对开发社区的大部分人产生影响的技术工作(重构、重大架构变更)也应广泛传播。即使对典型用户或操作员的影响为零,改进流程也适用于这种情况。" +"Similarly, any technical effort (refactoring, major architectural change) " +"that will impact a large section of the development community should also be " +"communicated widely. The Enhancement process is suited for this even if it " +"will have zero impact on the typical user or operator." +msgstr "" +"同样,任何会对开发社区的大部分人产生影响的技术工作(重构、重大架构变更)也应" +"广泛传播。即使对典型用户或操作员的影响为零,改进流程也适用于这种情况。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" -"For small changes and additions, going through the Enhancement process " -"would be time-consuming and unnecessary. This includes, for example, " -"adding new Federated Learning algorithms, as these only add features " -"without changing how Flower works or is used." +"For small changes and additions, going through the Enhancement process would " +"be time-consuming and unnecessary. This includes, for example, adding new " +"Federated Learning algorithms, as these only add features without changing " +"how Flower works or is used." msgstr "" -"对于小的改动和添加,通过 \"改善\"程序既耗时又没有必要。例如,这包括添加新的联邦学习算法,因为这只会增加功能,而不会改变 \"Flower " -"\"的工作或使用方式。" +"对于小的改动和添加,通过 \"改善\"程序既耗时又没有必要。例如,这包括添加新的联" +"邦学习算法,因为这只会增加功能,而不会改变 \"Flower \"的工作或使用方式。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " -"providing a laid-out path for implementation and are championed by " -"members of the community." -msgstr "增强功能与功能请求不同,因为它们已经提供了实施路径,并得到了社区成员的支持。" +"providing a laid-out path for implementation and are championed by members " +"of the community." +msgstr "" +"增强功能与功能请求不同,因为它们已经提供了实施路径,并得到了社区成员的支持。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" "An Enhancement is captured in a Markdown file that follows a defined " -"template and a workflow to review and store enhancement docs for " -"reference — the Enhancement Doc." -msgstr "增强功能被记录在一个 Markdown 文件中,该文件遵循已定义的模板和工作流程,用于审查和存储增强功能文档(即增强功能文档)以供参考。" +"template and a workflow to review and store enhancement docs for reference " +"— the Enhancement Doc." +msgstr "" +"增强功能被记录在一个 Markdown 文件中,该文件遵循已定义的模板和工作流程,用于" +"审查和存储增强功能文档(即增强功能文档)以供参考。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:69 msgid "Enhancement Doc Template" @@ -4257,9 +4457,11 @@ msgstr "描述数据" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" -"**fed-number** (Required) The `fed-number` of the last Flower Enhancement" -" Doc + 1. With this number, it becomes easy to reference other proposals." -msgstr "**fed-number**(必填)上一个Flower增强文件的 \"fed-number \"+1。有了这个编号,就很容易参考其他提案。" +"**fed-number** (Required) The `fed-number` of the last Flower Enhancement " +"Doc + 1. With this number, it becomes easy to reference other proposals." +msgstr "" +"**fed-number**(必填)上一个Flower增强文件的 \"fed-number \"+1。有了这个编" +"号,就很容易参考其他提案。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 msgid "**title** (Required) The title of the proposal in plain language." @@ -4267,20 +4469,22 @@ msgstr "**标题** (必填)用简明语言写出提案的标题。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" -"**status** (Required) The current status of the proposal. See " -"[workflow](#workflow) for the possible states." -msgstr "**status** (必填)提案的当前状态。有关可能的状态,请参阅 [工作流程](#workflow)。" +"**status** (Required) The current status of the proposal. See [workflow]" +"(#workflow) for the possible states." +msgstr "" +"**status** (必填)提案的当前状态。有关可能的状态,请参阅 [工作流程]" +"(#workflow)。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" -"**authors** (Required) A list of authors of the proposal. This is simply " -"the GitHub ID." +"**authors** (Required) A list of authors of the proposal. This is simply the " +"GitHub ID." msgstr "**作者**(必填) 提案的作者列表。这只是 GitHub ID。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" -"**creation-date** (Required) The date that the proposal was first " -"submitted in a PR." +"**creation-date** (Required) The date that the proposal was first submitted " +"in a PR." msgstr "**创建日期**(必填) 建议书在 PR 中首次提交的日期。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 @@ -4291,8 +4495,8 @@ msgstr "**最后更新** (可选)提案最后一次重大修改的日期。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" -"**see-also** (Optional) A list of other proposals that are relevant to " -"this one." +"**see-also** (Optional) A list of other proposals that are relevant to this " +"one." msgstr "**另见** (可选)与本提案相关的其他提案清单。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 @@ -4300,7 +4504,8 @@ msgid "**replaces** (Optional) A list of proposals that this one replaces." msgstr "**取代**(可选) 这份提案所取代的提案列表。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 -msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." +msgid "" +"**superseded-by** (Optional) A list of proposals that this one supersedes." msgstr "**被取代者** (可选) 此提案取代的提案列表。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 @@ -4310,46 +4515,52 @@ msgstr "工作流程" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" "The idea forming the enhancement should already have been discussed or " -"pitched in the community. As such, it needs a champion, usually the " -"author, who shepherds the enhancement. This person also has to find " -"committers to Flower willing to review the proposal." -msgstr "形成增强功能的想法应该已经在社区中讨论过或提出过。因此,它需要一个支持者(通常是作者)来引导增强。这个人还必须找到愿意审核提案的提交者。" +"pitched in the community. As such, it needs a champion, usually the author, " +"who shepherds the enhancement. This person also has to find committers to " +"Flower willing to review the proposal." +msgstr "" +"形成增强功能的想法应该已经在社区中讨论过或提出过。因此,它需要一个支持者(通" +"常是作者)来引导增强。这个人还必须找到愿意审核提案的提交者。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" "New enhancements are checked in with a file name in the form of `NNNN-" -"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement " -"Doc number, to `enhancements`. All enhancements start in `provisional` " -"state as part of a pull request. Discussions are done as part of the pull" -" request review." +"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement Doc " +"number, to `enhancements`. All enhancements start in `provisional` state as " +"part of a pull request. Discussions are done as part of the pull request " +"review." msgstr "" -"新的增强功能以 `NNNN-YYYYMMDD-enhancement-title.md` 的文件名签入,其中 `NNNN` " -"是花朵增强文档的编号,并将其转入 `enhancements`。作为拉取请求(pull request)的一部分,所有增强功能都从 " -"`provisional` 状态开始。讨论是作为拉取请求审查的一部分进行的。" +"新的增强功能以 `NNNN-YYYYMMDD-enhancement-title.md` 的文件名签入,其中 " +"`NNNN` 是花朵增强文档的编号,并将其转入 `enhancements`。作为拉取请求(pull " +"request)的一部分,所有增强功能都从 `provisional` 状态开始。讨论是作为拉取请" +"求审查的一部分进行的。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" -"Once an enhancement has been reviewed and approved, its status is changed" -" to `implementable`. The actual implementation is then done in separate " -"pull requests. These pull requests should mention the respective " -"enhancement as part of their description. After the implementation is " -"done, the proposal status is changed to `implemented`." +"Once an enhancement has been reviewed and approved, its status is changed to " +"`implementable`. The actual implementation is then done in separate pull " +"requests. These pull requests should mention the respective enhancement as " +"part of their description. After the implementation is done, the proposal " +"status is changed to `implemented`." msgstr "" -"一旦增强功能通过审核和批准,其状态就会变为 " -"`可实施`。实际的实施工作将在单独的拉取请求中完成。这些拉取请求应在其描述中提及相应的增强功能。实施完成后,提案状态将更改为 `已实施`。" +"一旦增强功能通过审核和批准,其状态就会变为 `可实施`。实际的实施工作将在单独的" +"拉取请求中完成。这些拉取请求应在其描述中提及相应的增强功能。实施完成后,提案" +"状态将更改为 `已实施`。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" -"Under certain conditions, other states are possible. An Enhancement has " -"the following states:" +"Under certain conditions, other states are possible. An Enhancement has the " +"following states:" msgstr "在某些条件下,还可能出现其他状态。增强提案具有以下状态:" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" "`provisional`: The enhancement has been proposed and is actively being " -"defined. This is the starting state while the proposal is being fleshed " -"out and actively defined and discussed." -msgstr "`暂定`: 已提出改进建议并正在积极定义。这是在提案得到充实、积极定义和讨论时的起始状态。" +"defined. This is the starting state while the proposal is being fleshed out " +"and actively defined and discussed." +msgstr "" +"`暂定`: 已提出改进建议并正在积极定义。这是在提案得到充实、积极定义和讨论时的" +"起始状态。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 msgid "`implementable`: The enhancement has been reviewed and approved." @@ -4362,13 +4573,14 @@ msgid "" msgstr "`已实施`: 增强功能已实施,不再主动更改。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 -msgid "`deferred`: The enhancement is proposed but not actively being worked on." +msgid "" +"`deferred`: The enhancement is proposed but not actively being worked on." msgstr "`推迟`: 已提出改进建议,但尚未积极开展工作。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" -"`rejected`: The authors and reviewers have decided that this enhancement " -"is not moving forward." +"`rejected`: The authors and reviewers have decided that this enhancement is " +"not moving forward." msgstr "`拒绝`: 作者和审稿人已决定不再推进该增强功能。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 @@ -4381,17 +4593,21 @@ msgstr "`已替换`: 增强功能已被新的增强功能取代。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" -"Adding an additional process to the ones already provided by GitHub " -"(Issues and Pull Requests) adds more complexity and can be a barrier for " -"potential first-time contributors." -msgstr "在 GitHub 已提供的流程(问题和拉取请求)之外再增加一个流程,会增加复杂性,并可能成为潜在首次贡献者的障碍。" +"Adding an additional process to the ones already provided by GitHub (Issues " +"and Pull Requests) adds more complexity and can be a barrier for potential " +"first-time contributors." +msgstr "" +"在 GitHub 已提供的流程(问题和拉取请求)之外再增加一个流程,会增加复杂性,并" +"可能成为潜在首次贡献者的障碍。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" "Expanding the proposal template beyond the single-sentence description " -"currently required in the features issue template may be a heavy burden " -"for non-native English speakers." -msgstr "对于英语非母语者来说,将提案模板扩展到目前要求的单句描述之外可能是一个沉重的负担。" +"currently required in the features issue template may be a heavy burden for " +"non-native English speakers." +msgstr "" +"对于英语非母语者来说,将提案模板扩展到目前要求的单句描述之外可能是一个沉重的" +"负担。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 msgid "GitHub Issues" @@ -4400,16 +4616,17 @@ msgstr "GitHub 问题" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" "Using GitHub Issues for these kinds of enhancements is doable. One could " -"use, for example, tags, to differentiate and filter them from other " -"issues. The main issue is in discussing and reviewing an enhancement: " -"GitHub issues only have a single thread for comments. Enhancements " -"usually have multiple threads of discussion at the same time for various " -"parts of the doc. Managing these multiple discussions can be confusing " -"when using GitHub Issues." -msgstr "" -"使用 GitHub Issues 进行此类改进是可行的。例如,我们可以使用标签来区分和过滤这些问题。主要的问题在于讨论和审查增强功能: " -"GitHub 问题只有一个评论线程。而增强功能通常会同时有多个讨论线程,针对文档的不同部分。在使用 GitHub " -"问题时,管理这些多重讨论会很混乱。" +"use, for example, tags, to differentiate and filter them from other issues. " +"The main issue is in discussing and reviewing an enhancement: GitHub issues " +"only have a single thread for comments. Enhancements usually have multiple " +"threads of discussion at the same time for various parts of the doc. " +"Managing these multiple discussions can be confusing when using GitHub " +"Issues." +msgstr "" +"使用 GitHub Issues 进行此类改进是可行的。例如,我们可以使用标签来区分和过滤这" +"些问题。主要的问题在于讨论和审查增强功能: GitHub 问题只有一个评论线程。而增" +"强功能通常会同时有多个讨论线程,针对文档的不同部分。在使用 GitHub 问题时,管" +"理这些多重讨论会很混乱。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 msgid "Google Docs" @@ -4417,15 +4634,15 @@ msgstr "谷歌文档" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" -"Google Docs allow for multiple threads of discussions. But as Google Docs" -" are hosted outside the project, their discoverability by the community " -"needs to be taken care of. A list of links to all proposals has to be " -"managed and made available for the community. Compared to shipping " -"proposals as part of Flower's repository, the potential for missing links" -" is much higher." +"Google Docs allow for multiple threads of discussions. But as Google Docs " +"are hosted outside the project, their discoverability by the community needs " +"to be taken care of. A list of links to all proposals has to be managed and " +"made available for the community. Compared to shipping proposals as part of " +"Flower's repository, the potential for missing links is much higher." msgstr "" -"谷歌文档允许多线程讨论。但是,由于谷歌文档是在项目之外托管的,因此需要注意它们是否能被社区发现。我们必须管理所有提案的链接列表,并提供给社区使用。与作为" -" Flower 资源库一部分的提案相比,丢失链接的可能性要大得多。" +"谷歌文档允许多线程讨论。但是,由于谷歌文档是在项目之外托管的,因此需要注意它" +"们是否能被社区发现。我们必须管理所有提案的链接列表,并提供给社区使用。与作为 " +"Flower 资源库一部分的提案相比,丢失链接的可能性要大得多。" #: ../../source/fed/index.md:1 msgid "FED - Flower Enhancement Doc" @@ -4437,9 +4654,10 @@ msgstr "整合评估结果" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" -"The Flower server does not prescribe a way to aggregate evaluation " -"results, but it enables the user to fully customize result aggregation." -msgstr "Flower 服务器没有规定整合评估结果的方法,但用户可以完全自定义如何整合。" +"The Flower server does not prescribe a way to aggregate evaluation results, " +"but it enables the user to fully customize result aggregation." +msgstr "" +"Flower 服务器没有规定整合评估结果的方法,但用户可以完全自定义如何整合。" #: ../../source/how-to-aggregate-evaluation-results.rst:8 msgid "Aggregate Custom Evaluation Results" @@ -4447,10 +4665,12 @@ msgstr "自定义整合评估结果" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" -"The same :code:`Strategy`-customization approach can be used to aggregate" -" custom evaluation results coming from individual clients. Clients can " -"return custom metrics to the server by returning a dictionary:" -msgstr "同样的 :code:`Strategy` 定制方法也可用于汇总来自单个客户端的自定义评估结果。客户端可以通过返回字典的方式向服务器返回自定义指标:" +"The same :code:`Strategy`-customization approach can be used to aggregate " +"custom evaluation results coming from individual clients. Clients can return " +"custom metrics to the server by returning a dictionary:" +msgstr "" +"同样的 :code:`Strategy` 定制方法也可用于汇总来自单个客户端的自定义评估结果。" +"客户端可以通过返回字典的方式向服务器返回自定义指标:" #: ../../source/how-to-aggregate-evaluation-results.rst:36 msgid "" @@ -4465,10 +4685,12 @@ msgstr "配置客户端" #: ../../source/how-to-configure-clients.rst:4 msgid "" "Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are," -" for example, a popular way to control client-side hyperparameters from " -"the server." -msgstr "除了模型参数,Flower 还可以向客户端发送配置值。配置值有多种用途。它们是一种从服务器控制客户端超参数的常用方法。" +"clients. Configuration values can be used for various purposes. They are, " +"for example, a popular way to control client-side hyperparameters from the " +"server." +msgstr "" +"除了模型参数,Flower 还可以向客户端发送配置值。配置值有多种用途。它们是一种从" +"服务器控制客户端超参数的常用方法。" #: ../../source/how-to-configure-clients.rst:7 msgid "Configuration values" @@ -4476,41 +4698,45 @@ msgstr "配置值" #: ../../source/how-to-configure-clients.rst:9 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys " -"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " -"float), ``int``, or ``str`` (or equivalent types in different languages)." -" Here is an example of a configuration dictionary in Python:" +"Configuration values are represented as a dictionary with ``str`` keys and " +"values of type ``bool``, ``bytes``, ``double`` (64-bit precision float), " +"``int``, or ``str`` (or equivalent types in different languages). Here is an " +"example of a configuration dictionary in Python:" msgstr "" -"配置值以字典的形式表示,字典的键为 ``str``,值的类型为 ``bool``、``bytes``、``double``(64 " -"位精度浮点型)、``int``或 ``str`(或不同语言中的等效类型)。下面是一个 Python 配置字典的示例:" +"配置值以字典的形式表示,字典的键为 ``str``,值的类型为 ``bool``、``bytes``、" +"``double``(64 位精度浮点型)、``int``或 ``str`(或不同语言中的等效类型)。下" +"面是一个 Python 配置字典的示例:" #: ../../source/how-to-configure-clients.rst:20 msgid "" "Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client " -"using gRPC, and then deserializes them back to Python dictionaries." +"short) to their ProtoBuf representation, transports them to the client using " +"gRPC, and then deserializes them back to Python dictionaries." msgstr "" -"Flower 将这些配置字典(简称 *config dict*)序列化为 ProtoBuf 表示形式,使用 gRPC " -"将其传输到客户端,然后再反序列化为 Python 字典。" +"Flower 将这些配置字典(简称 *config dict*)序列化为 ProtoBuf 表示形式,使用 " +"gRPC 将其传输到客户端,然后再反序列化为 Python 字典。" #: ../../source/how-to-configure-clients.rst:24 msgid "" -"Currently, there is no support for directly sending collection types " -"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " -"dictionaries. There are several workarounds to send collections as values" -" by converting them to one of the supported value types (and converting " -"them back on the client-side)." +"Currently, there is no support for directly sending collection types (e.g., " +"``Set``, ``List``, ``Map``) as values in configuration dictionaries. There " +"are several workarounds to send collections as values by converting them to " +"one of the supported value types (and converting them back on the client-" +"side)." msgstr "" "目前,还不支持在配置字典中直接发送作为值的集合类型(例如,`Set``, `List`, " -"`Map``)。有几种变通方法可将集合转换为支持的值类型之一(并在客户端将其转换回),从而将集合作为值发送。" +"`Map``)。有几种变通方法可将集合转换为支持的值类型之一(并在客户端将其转换" +"回),从而将集合作为值发送。" #: ../../source/how-to-configure-clients.rst:26 msgid "" "One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and" -" then convert the JSON string back to a list of floating-point numbers on" -" the client." -msgstr "例如,可以将浮点数列表转换为 JSON 字符串,然后使用配置字典发送 JSON 字符串,再在客户端将 JSON 字符串转换回浮点数列表。" +"string, then send the JSON string using the configuration dictionary, and " +"then convert the JSON string back to a list of floating-point numbers on the " +"client." +msgstr "" +"例如,可以将浮点数列表转换为 JSON 字符串,然后使用配置字典发送 JSON 字符串," +"再在客户端将 JSON 字符串转换回浮点数列表。" #: ../../source/how-to-configure-clients.rst:30 msgid "Configuration through built-in strategies" @@ -4518,57 +4744,65 @@ msgstr "通过内置策略进行配置" #: ../../source/how-to-configure-clients.rst:32 msgid "" -"The easiest way to send configuration values to clients is to use a " -"built-in strategy like :code:`FedAvg`. Built-in strategies support so-" -"called configuration functions. A configuration function is a function " -"that the built-in strategy calls to get the configuration dictionary for " -"the current round. It then forwards the configuration dictionary to all " -"the clients selected during that round." +"The easiest way to send configuration values to clients is to use a built-in " +"strategy like :code:`FedAvg`. Built-in strategies support so-called " +"configuration functions. A configuration function is a function that the " +"built-in strategy calls to get the configuration dictionary for the current " +"round. It then forwards the configuration dictionary to all the clients " +"selected during that round." msgstr "" -"向客户端发送配置值的最简单方法是使用内置策略,如 " -":code:`FedAvg`。内置策略支持所谓的配置函数。配置函数是内置策略调用的函数,用于获取当前轮的配置字典。然后,它会将配置字典转发给该轮中选择的所有客户端。" +"向客户端发送配置值的最简单方法是使用内置策略,如 :code:`FedAvg`。内置策略支持" +"所谓的配置函数。配置函数是内置策略调用的函数,用于获取当前轮的配置字典。然" +"后,它会将配置字典转发给该轮中选择的所有客户端。" #: ../../source/how-to-configure-clients.rst:34 msgid "" "Let's start with a simple example. Imagine we want to send (a) the batch " -"size that the client should use, (b) the current global round of " -"federated learning, and (c) the number of epochs to train on the client-" -"side. Our configuration function could look like this:" -msgstr "让我们从一个简单的例子开始。想象一下,我们想要发送给客户端(a)应该使用的批次大小,(b)当前联邦学习的全局轮次,以及(c)客户端训练的遍历数。我们的配置函数可以是这样的:" +"size that the client should use, (b) the current global round of federated " +"learning, and (c) the number of epochs to train on the client-side. Our " +"configuration function could look like this:" +msgstr "" +"让我们从一个简单的例子开始。想象一下,我们想要发送给客户端(a)应该使用的批次" +"大小,(b)当前联邦学习的全局轮次,以及(c)客户端训练的遍历数。我们的配置函" +"数可以是这样的:" #: ../../source/how-to-configure-clients.rst:47 msgid "" "To make the built-in strategies use this function, we can pass it to " -"``FedAvg`` during initialization using the parameter " -":code:`on_fit_config_fn`:" -msgstr "为了让内置策略使用这个函数,我们可以在初始化时使用参数 :code:`on_fit_config_fn` 将它传递给 ``FedAvg`` :" +"``FedAvg`` during initialization using the parameter :code:" +"`on_fit_config_fn`:" +msgstr "" +"为了让内置策略使用这个函数,我们可以在初始化时使用参数 :code:" +"`on_fit_config_fn` 将它传递给 ``FedAvg`` :" #: ../../source/how-to-configure-clients.rst:56 -msgid "One the client side, we receive the configuration dictionary in ``fit``:" +msgid "" +"One the client side, we receive the configuration dictionary in ``fit``:" msgstr "在客户端,我们在 ``fit`` 中接收配置字典:" #: ../../source/how-to-configure-clients.rst:67 msgid "" "There is also an `on_evaluate_config_fn` to configure evaluation, which " -"works the same way. They are separate functions because one might want to" -" send different configuration values to `evaluate` (for example, to use a" -" different batch size)." +"works the same way. They are separate functions because one might want to " +"send different configuration values to `evaluate` (for example, to use a " +"different batch size)." msgstr "" -"还有一个 `on_evaluate_config_fn` 用于配置评估,其工作方式相同。它们是不同的函数,因为可能需要向 `evaluate` " -"发送不同的配置值(例如,使用不同的批量大小)。" +"还有一个 `on_evaluate_config_fn` 用于配置评估,其工作方式相同。它们是不同的函" +"数,因为可能需要向 `evaluate` 发送不同的配置值(例如,使用不同的批量大小)。" #: ../../source/how-to-configure-clients.rst:69 msgid "" -"The built-in strategies call this function every round (that is, every " -"time `Strategy.configure_fit` or `Strategy.configure_evaluate` runs). " -"Calling `on_evaluate_config_fn` every round allows us to vary/change the " -"config dict over consecutive rounds. If we wanted to implement a " -"hyperparameter schedule, for example, to increase the number of local " -"epochs during later rounds, we could do the following:" +"The built-in strategies call this function every round (that is, every time " +"`Strategy.configure_fit` or `Strategy.configure_evaluate` runs). Calling " +"`on_evaluate_config_fn` every round allows us to vary/change the config dict " +"over consecutive rounds. If we wanted to implement a hyperparameter " +"schedule, for example, to increase the number of local epochs during later " +"rounds, we could do the following:" msgstr "" -"内置策略每轮都会调用此函数(即每次运行 `Strategy.configure_fit` 或 " -"`Strategy.configure_evaluate` 时)。每轮调用 `on_evaluate_config_fn` " -"允许我们在连续几轮中改变配置指令。例如,如果我们想实现一个超参数时间表,以增加后几轮的本地遍历次数,我们可以这样做:" +"内置策略每轮都会调用此函数(即每次运行 `Strategy.configure_fit` 或 `Strategy." +"configure_evaluate` 时)。每轮调用 `on_evaluate_config_fn` 允许我们在连续几轮" +"中改变配置指令。例如,如果我们想实现一个超参数时间表,以增加后几轮的本地遍历" +"次数,我们可以这样做:" #: ../../source/how-to-configure-clients.rst:82 msgid "The :code:`FedAvg` strategy will call this function *every round*." @@ -4587,19 +4821,18 @@ msgstr "在某些情况下,有必要向不同的客户端发送不同的配置 #: ../../source/how-to-configure-clients.rst:89 #, fuzzy msgid "" -"This can be achieved by customizing an existing strategy or by " -":doc:`implementing a custom strategy from scratch `. Here's a nonsensical example that customizes :code:`FedAvg`" -" by adding a custom ``\"hello\": \"world\"`` configuration key/value pair" -" to the config dict of a *single client* (only the first client in the " -"list, the other clients in this round to not receive this \"special\" " -"config value):" +"This can be achieved by customizing an existing strategy or by :doc:" +"`implementing a custom strategy from scratch `. " +"Here's a nonsensical example that customizes :code:`FedAvg` by adding a " +"custom ``\"hello\": \"world\"`` configuration key/value pair to the config " +"dict of a *single client* (only the first client in the list, the other " +"clients in this round to not receive this \"special\" config value):" msgstr "" -"这可以通过定制现有策略或 `从头开始实施一个定制策略 `_来实现。下面是一个无厘头的例子,`FedAvg`通过在*单个客户端*的配置指令(config " -"dict)中添加自定义的``\"hello\": \"world\"``配置键/值对添加到此的配置 dict " -"中(仅列表中的第一个客户端,本轮中的其他客户端不会收到此 \"特殊 \"配置值):" +"这可以通过定制现有策略或 `从头开始实施一个定制策略 `_来实现。下面是一个无厘头的例子," +"`FedAvg`通过在*单个客户端*的配置指令(config dict)中添加自定义的" +"``\"hello\": \"world\"``配置键/值对添加到此的配置 dict 中(仅列表中的第一个" +"客户端,本轮中的其他客户端不会收到此 \"特殊 \"配置值):" #: ../../source/how-to-configure-logging.rst:2 msgid "Configure logging" @@ -4608,19 +4841,21 @@ msgstr "配置日志记录" #: ../../source/how-to-configure-logging.rst:4 msgid "" "The Flower logger keeps track of all core events that take place in " -"federated learning workloads. It presents information by default " -"following a standard message format:" -msgstr "Flower 日志记录器会跟踪联邦学习工作负载中发生的所有核心事件。它默认按照标准信息格式提供信息:" +"federated learning workloads. It presents information by default following a " +"standard message format:" +msgstr "" +"Flower 日志记录器会跟踪联邦学习工作负载中发生的所有核心事件。它默认按照标准信" +"息格式提供信息:" #: ../../source/how-to-configure-logging.rst:13 msgid "" -"containing relevant information including: log message level (e.g. " -":code:`INFO`, :code:`DEBUG`), a timestamp, the line where the logging " -"took place from, as well as the log message itself. In this way, the " -"logger would typically display information on your terminal as follows:" +"containing relevant information including: log message level (e.g. :code:" +"`INFO`, :code:`DEBUG`), a timestamp, the line where the logging took place " +"from, as well as the log message itself. In this way, the logger would " +"typically display information on your terminal as follows:" msgstr "" -"相关信息包括:日志信息级别(例如 " -":code:`INFO`、:code:`DEBUG`)、时间戳、日志记录的行以及日志信息本身。这样,日志记录器通常会在终端上显示如下信息:" +"相关信息包括:日志信息级别(例如 :code:`INFO`、:code:`DEBUG`)、时间戳、日志" +"记录的行以及日志信息本身。这样,日志记录器通常会在终端上显示如下信息:" #: ../../source/how-to-configure-logging.rst:34 msgid "Saving log to file" @@ -4630,31 +4865,30 @@ msgstr "将日志保存到文件" msgid "" "By default, the Flower log is outputted to the terminal where you launch " "your Federated Learning workload from. This applies for both gRPC-based " -"federation (i.e. when you do :code:`fl.server.start_server`) and when " -"using the :code:`VirtualClientEngine` (i.e. when you do " -":code:`fl.simulation.start_simulation`). In some situations you might " -"want to save this log to disk. You can do so by calling the " -"`fl.common.logger.configure() " -"`_" -" function. For example:" -msgstr "" -"默认情况下,Flower 日志会输出到启动联邦学习工作负载的终端。这既适用于基于 gRPC 的联邦学习(即执行 " -":code:`fl.server.start_server` 时),也适用于使用 :code:`VirtualClientEngine` " -"时(即执行 :code:`fl.simulation.start_simulation` " -"时)。在某些情况下,您可能希望将此日志保存到磁盘。为此,您可以调用 `fl.common.logger.configure() " -"`_" -" 函数。例如:" +"federation (i.e. when you do :code:`fl.server.start_server`) and when using " +"the :code:`VirtualClientEngine` (i.e. when you do :code:`fl.simulation." +"start_simulation`). In some situations you might want to save this log to " +"disk. You can do so by calling the `fl.common.logger.configure() `_ function. " +"For example:" +msgstr "" +"默认情况下,Flower 日志会输出到启动联邦学习工作负载的终端。这既适用于基于 " +"gRPC 的联邦学习(即执行 :code:`fl.server.start_server` 时),也适用于使用 :" +"code:`VirtualClientEngine` 时(即执行 :code:`fl.simulation.start_simulation` " +"时)。在某些情况下,您可能希望将此日志保存到磁盘。为此,您可以调用 `fl." +"common.logger.configure() `_ 函数。例如:" #: ../../source/how-to-configure-logging.rst:53 msgid "" -"With the above, Flower will record the log you see on your terminal to " -":code:`log.txt`. This file will be created in the same directory as were " -"you are running the code from. If we inspect we see the log above is also" -" recorded but prefixing with :code:`identifier` each line:" +"With the above, Flower will record the log you see on your terminal to :code:" +"`log.txt`. This file will be created in the same directory as were you are " +"running the code from. If we inspect we see the log above is also recorded " +"but prefixing with :code:`identifier` each line:" msgstr "" -"通过上述操作,Flower 会将您在终端上看到的日志记录到 " -":code:`log.txt`。该文件将创建在运行代码的同一目录下。如果我们检查一下,就会发现上面的日志也被记录了下来,但每一行都以 " -":code:`identifier` 作为前缀:" +"通过上述操作,Flower 会将您在终端上看到的日志记录到 :code:`log.txt`。该文件将" +"创建在运行代码的同一目录下。如果我们检查一下,就会发现上面的日志也被记录了下" +"来,但每一行都以 :code:`identifier` 作为前缀:" #: ../../source/how-to-configure-logging.rst:74 msgid "Log your own messages" @@ -4662,16 +4896,19 @@ msgstr "记录自己的信息" #: ../../source/how-to-configure-logging.rst:76 msgid "" -"You might expand the information shown by default with the Flower logger " -"by adding more messages relevant to your application. You can achieve " -"this easily as follows." -msgstr "您可以通过添加更多与应用程序相关的信息来扩展 Flower 日志记录器默认显示的信息。您可以通过以下方法轻松实现这一目标。" +"You might expand the information shown by default with the Flower logger by " +"adding more messages relevant to your application. You can achieve this " +"easily as follows." +msgstr "" +"您可以通过添加更多与应用程序相关的信息来扩展 Flower 日志记录器默认显示的信" +"息。您可以通过以下方法轻松实现这一目标。" #: ../../source/how-to-configure-logging.rst:102 msgid "" -"In this way your logger will show, in addition to the default messages, " -"the ones introduced by the clients as specified above." -msgstr "这样,除默认信息外,您的日志记录器还将显示由客户引入的信息,如上文所述。" +"In this way your logger will show, in addition to the default messages, the " +"ones introduced by the clients as specified above." +msgstr "" +"这样,除默认信息外,您的日志记录器还将显示由客户引入的信息,如上文所述。" #: ../../source/how-to-configure-logging.rst:128 msgid "Log to a remote service" @@ -4679,20 +4916,21 @@ msgstr "登录远程服务" #: ../../source/how-to-configure-logging.rst:130 msgid "" -"The :code:`fl.common.logger.configure` function, also allows specifying a" -" host to which logs can be pushed (via :code:`POST`) through a native " -"Python :code:`logging.handler.HTTPHandler`. This is a particularly useful" -" feature in :code:`gRPC`-based Federated Learning workloads where " -"otherwise gathering logs from all entities (i.e. the server and the " -"clients) might be cumbersome. Note that in Flower simulation, the server " -"automatically displays all logs. You can still specify a " -":code:`HTTPHandler` should you wish to backup or analyze the logs " -"somewhere else." -msgstr "" -"此外,:code:`fl.common.logger.configure`函数还允许指定主机,通过本地 Python " -":code:`logging.handler.HTTPHandler`,向该主机推送日志(通过 :code:`POST`)。在基于 " -":code:`gRPC` 的联邦学习工作负载中,这是一个特别有用的功能,否则从所有实体(即服务器和客户端)收集日志可能会很麻烦。请注意,在 " -"Flower 模拟器中,服务器会自动显示所有日志。如果希望在其他地方备份或分析日志,仍可指定 :code:`HTTPHandler`。" +"The :code:`fl.common.logger.configure` function, also allows specifying a " +"host to which logs can be pushed (via :code:`POST`) through a native Python :" +"code:`logging.handler.HTTPHandler`. This is a particularly useful feature " +"in :code:`gRPC`-based Federated Learning workloads where otherwise gathering " +"logs from all entities (i.e. the server and the clients) might be " +"cumbersome. Note that in Flower simulation, the server automatically " +"displays all logs. You can still specify a :code:`HTTPHandler` should you " +"wish to backup or analyze the logs somewhere else." +msgstr "" +"此外,:code:`fl.common.logger.configure`函数还允许指定主机,通过本地 Python :" +"code:`logging.handler.HTTPHandler`,向该主机推送日志(通过 :code:`POST`)。在" +"基于 :code:`gRPC` 的联邦学习工作负载中,这是一个特别有用的功能,否则从所有实" +"体(即服务器和客户端)收集日志可能会很麻烦。请注意,在 Flower 模拟器中,服务" +"器会自动显示所有日志。如果希望在其他地方备份或分析日志,仍可指定 :code:" +"`HTTPHandler`。" #: ../../source/how-to-enable-ssl-connections.rst:2 msgid "Enable SSL connections" @@ -4702,24 +4940,26 @@ msgstr "启用 SSL 连接" msgid "" "This guide describes how to a SSL-enabled secure Flower server can be " "started and how a Flower client can establish a secure connections to it." -msgstr "本指南介绍如何启动启用 SSL 的安全 Flower 服务器,以及 Flower 客户端如何与其建立安全连接。" +msgstr "" +"本指南介绍如何启动启用 SSL 的安全 Flower 服务器,以及 Flower 客户端如何与其建" +"立安全连接。" #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" -"A complete code example demonstrating a secure connection can be found " -"`here `_." +"A complete code example demonstrating a secure connection can be found `here " +"`_." msgstr "" -"有关安全连接的完整代码示例,请参见 `_ 。" +"有关安全连接的完整代码示例,请参见 `_ 。" #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" -"The code example comes with a README.md file which will explain how to " -"start it. Although it is already SSL-enabled, it might be less " -"descriptive on how. Stick to this guide for a deeper introduction to the " -"topic." -msgstr "代码示例附带的 README.md 文件将解释如何启动它。虽然它已经启用了 SSL,但对如何启用可能描述较少。请参考本指南,了解更深入的相关介绍。" +"The code example comes with a README.md file which will explain how to start " +"it. Although it is already SSL-enabled, it might be less descriptive on how. " +"Stick to this guide for a deeper introduction to the topic." +msgstr "" +"代码示例附带的 README.md 文件将解释如何启动它。虽然它已经启用了 SSL,但对如何" +"启用可能描述较少。请参考本指南,了解更深入的相关介绍。" #: ../../source/how-to-enable-ssl-connections.rst:16 msgid "Certificates" @@ -4728,13 +4968,14 @@ msgstr "证书" #: ../../source/how-to-enable-ssl-connections.rst:18 msgid "" "Using SSL-enabled connections requires certificates to be passed to the " -"server and client. For the purpose of this guide we are going to generate" -" self-signed certificates. As this can become quite complex we are going " -"to ask you to run the script in :code:`examples/advanced-" -"tensorflow/certificates/generate.sh`" +"server and client. For the purpose of this guide we are going to generate " +"self-signed certificates. As this can become quite complex we are going to " +"ask you to run the script in :code:`examples/advanced-tensorflow/" +"certificates/generate.sh`" msgstr "" -"使用支持 SSL 的连接需要向服务器和客户端传递证书。在本指南中,我们将生成自签名证书。由于这可能会变得相当复杂,我们将要求你运行 " -":code:`examples/advanced-tensorflow/certificates/generate.sh` 中的脚本" +"使用支持 SSL 的连接需要向服务器和客户端传递证书。在本指南中,我们将生成自签名" +"证书。由于这可能会变得相当复杂,我们将要求你运行 :code:`examples/advanced-" +"tensorflow/certificates/generate.sh` 中的脚本" #: ../../source/how-to-enable-ssl-connections.rst:23 msgid "with the following command sequence:" @@ -4742,9 +4983,10 @@ msgstr "使用以下命令序列:" #: ../../source/how-to-enable-ssl-connections.rst:30 msgid "" -"This will generate the certificates in :code:`examples/advanced-" -"tensorflow/.cache/certificates`." -msgstr "这将在 :code:`examples/advanced-tensorflow/.cache/certificates` 中生成证书。" +"This will generate the certificates in :code:`examples/advanced-tensorflow/." +"cache/certificates`." +msgstr "" +"这将在 :code:`examples/advanced-tensorflow/.cache/certificates` 中生成证书。" #: ../../source/how-to-enable-ssl-connections.rst:32 msgid "" @@ -4753,12 +4995,14 @@ msgid "" "complete for production environments. Please refer to other sources " "regarding the issue of correctly generating certificates for production " "environments." -msgstr "本示例中生成 SSL 证书的方法可作为启发和起点,但不应被视为生产环境的完整方法。有关在生产环境中正确生成证书的问题,请参考其他资料。" +msgstr "" +"本示例中生成 SSL 证书的方法可作为启发和起点,但不应被视为生产环境的完整方法。" +"有关在生产环境中正确生成证书的问题,请参考其他资料。" #: ../../source/how-to-enable-ssl-connections.rst:36 msgid "" -"In case you are a researcher you might be just fine using the self-signed" -" certificates generated using the scripts which are part of this guide." +"In case you are a researcher you might be just fine using the self-signed " +"certificates generated using the scripts which are part of this guide." msgstr "如果你是一名研究人员,使用本指南中的脚本生成的自签名证书就可以了。" #: ../../source/how-to-enable-ssl-connections.rst:41 @@ -4775,12 +5019,12 @@ msgstr "现在,我们将展示如何编写一个使用先前生成的脚本的 #: ../../source/how-to-enable-ssl-connections.rst:61 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates. :code:`Path` can be used to easily read the contents of " -"those files into byte strings, which is the data type " -":code:`start_server` expects." +"certificates. :code:`Path` can be used to easily read the contents of those " +"files into byte strings, which is the data type :code:`start_server` expects." msgstr "" -"在提供证书时,服务器希望得到由三个证书组成的元组。 :code:`Path` 可用于轻松地将这些文件的内容读取为字节字符串,这就是 " -":code:`start_server` 期望的数据类型。" +"在提供证书时,服务器希望得到由三个证书组成的元组。 :code:`Path` 可用于轻松地" +"将这些文件的内容读取为字节字符串,这就是 :code:`start_server` 期望的数据类" +"型。" #: ../../source/how-to-enable-ssl-connections.rst:65 #: ../../source/how-to-upgrade-to-flower-1.0.rst:37 @@ -4796,12 +5040,12 @@ msgstr "现在我们将演示如何编写一个客户端,使用之前生成的 #: ../../source/how-to-enable-ssl-connections.rst:84 msgid "" -"When setting :code:`root_certificates`, the client expects the PEM-" -"encoded root certificates as a byte string. We are again using " -":code:`Path` to simplify reading those as byte strings." +"When setting :code:`root_certificates`, the client expects the PEM-encoded " +"root certificates as a byte string. We are again using :code:`Path` to " +"simplify reading those as byte strings." msgstr "" -"当设置 :code:`root_certificates` 时,客户端希望 PEM 编码的根证书是字节字符串。我们再次使用 " -":code:`Path` 来简化以字节字符串形式读取证书的过程。" +"当设置 :code:`root_certificates` 时,客户端希望 PEM 编码的根证书是字节字符" +"串。我们再次使用 :code:`Path` 来简化以字节字符串形式读取证书的过程。" #: ../../source/how-to-enable-ssl-connections.rst:89 #: ../../source/how-to-use-built-in-mods.rst:85 @@ -4811,10 +5055,12 @@ msgstr "总结" #: ../../source/how-to-enable-ssl-connections.rst:91 msgid "" -"You should now have learned how to generate self-signed certificates " -"using the given script, start a SSL-enabled server, and have a client " -"establish a secure connection to it." -msgstr "现在,你应该已经学会了如何使用给定的脚本生成自签名证书、启动启用 SSL 的服务器并让客户端与其建立安全连接。" +"You should now have learned how to generate self-signed certificates using " +"the given script, start a SSL-enabled server, and have a client establish a " +"secure connection to it." +msgstr "" +"现在,你应该已经学会了如何使用给定的脚本生成自签名证书、启动启用 SSL 的服务器" +"并让客户端与其建立安全连接。" #: ../../source/how-to-enable-ssl-connections.rst:96 msgid "Additional resources" @@ -4822,8 +5068,8 @@ msgstr "补充资源" #: ../../source/how-to-enable-ssl-connections.rst:98 msgid "" -"These additional sources might be relevant if you would like to dive " -"deeper into the topic of certificates:" +"These additional sources might be relevant if you would like to dive deeper " +"into the topic of certificates:" msgstr "如果您想更深入地了解证书主题,这些额外的资料来源可能有帮助:" #: ../../source/how-to-enable-ssl-connections.rst:100 @@ -4840,15 +5086,16 @@ msgstr "实施策略" #: ../../source/how-to-implement-strategies.rst:4 msgid "" -"The strategy abstraction enables implementation of fully custom " -"strategies. A strategy is basically the federated learning algorithm that" -" runs on the server. Strategies decide how to sample clients, how to " -"configure clients for training, how to aggregate updates, and how to " -"evaluate models. Flower provides a few built-in strategies which are " -"based on the same API described below." +"The strategy abstraction enables implementation of fully custom strategies. " +"A strategy is basically the federated learning algorithm that runs on the " +"server. Strategies decide how to sample clients, how to configure clients " +"for training, how to aggregate updates, and how to evaluate models. Flower " +"provides a few built-in strategies which are based on the same API described " +"below." msgstr "" -"策略抽象类可以实现完全定制的策略。策略基本上就是在服务器上运行的联邦学习算法。策略决定如何对客户端进行采样、如何配置客户端进行训练、如何聚合参数更新以及如何评估模型。Flower" -" 提供了一些内置策略,这些策略基于下文所述的相同 API。" +"策略抽象类可以实现完全定制的策略。策略基本上就是在服务器上运行的联邦学习算" +"法。策略决定如何对客户端进行采样、如何配置客户端进行训练、如何聚合参数更新以" +"及如何评估模型。Flower 提供了一些内置策略,这些策略基于下文所述的相同 API。" #: ../../source/how-to-implement-strategies.rst:11 msgid "The :code:`Strategy` abstraction" @@ -4856,14 +5103,13 @@ msgstr ":code:`策略 ` 抽象类" #: ../../source/how-to-implement-strategies.rst:13 msgid "" -"All strategy implementation are derived from the abstract base class " -":code:`flwr.server.strategy.Strategy`, both built-in implementations and " -"third party implementations. This means that custom strategy " -"implementations have the exact same capabilities at their disposal as " -"built-in ones." +"All strategy implementation are derived from the abstract base class :code:" +"`flwr.server.strategy.Strategy`, both built-in implementations and third " +"party implementations. This means that custom strategy implementations have " +"the exact same capabilities at their disposal as built-in ones." msgstr "" -"所有策略实现均源自抽象基类 " -":code:`flwr.server.strategy.Strategy`,包括内置实现和第三方实现。这意味着自定义策略实现与内置实现具有完全相同的功能。" +"所有策略实现均源自抽象基类 :code:`flwr.server.strategy.Strategy`,包括内置实" +"现和第三方实现。这意味着自定义策略实现与内置实现具有完全相同的功能。" #: ../../source/how-to-implement-strategies.rst:18 msgid "" @@ -4873,10 +5119,12 @@ msgstr "策略抽象定义了一些需要实现的抽象方法:" #: ../../source/how-to-implement-strategies.rst:75 msgid "" -"Creating a new strategy means implementing a new :code:`class` (derived " -"from the abstract base class :code:`Strategy`) that implements for the " -"previously shown abstract methods:" -msgstr "创建一个新策略意味着要实现一个新的 :code:`class`(从抽象基类 :code:`Strategy` 派生),该类要实现前面显示的抽象方法:" +"Creating a new strategy means implementing a new :code:`class` (derived from " +"the abstract base class :code:`Strategy`) that implements for the previously " +"shown abstract methods:" +msgstr "" +"创建一个新策略意味着要实现一个新的 :code:`class`(从抽象基类 :code:" +"`Strategy` 派生),该类要实现前面显示的抽象方法:" #: ../../source/how-to-implement-strategies.rst:100 msgid "The Flower server calls these methods in the following order:" @@ -4892,44 +5140,48 @@ msgstr ":code:`初始化参数` 方法" #: ../../source/how-to-implement-strategies.rst:182 msgid "" -":code:`initialize_parameters` is called only once, at the very beginning " -"of an execution. It is responsible for providing the initial global model" -" parameters in a serialized form (i.e., as a :code:`Parameters` object)." +":code:`initialize_parameters` is called only once, at the very beginning of " +"an execution. It is responsible for providing the initial global model " +"parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" -":code:`initialize_parameters` 只调用一次,即在执行开始时。它负责以序列化形式(即 " -":code:`Parameters` 对象)提供初始全局模型参数。" +":code:`initialize_parameters` 只调用一次,即在执行开始时。它负责以序列化形式" +"(即 :code:`Parameters` 对象)提供初始全局模型参数。" #: ../../source/how-to-implement-strategies.rst:184 msgid "" -"Built-in strategies return user-provided initial parameters. The " -"following example shows how initial parameters can be passed to " -":code:`FedAvg`:" -msgstr "内置策略会返回用户提供的初始参数。下面的示例展示了如何将初始参数传递给 :code:`FedAvg`:" +"Built-in strategies return user-provided initial parameters. The following " +"example shows how initial parameters can be passed to :code:`FedAvg`:" +msgstr "" +"内置策略会返回用户提供的初始参数。下面的示例展示了如何将初始参数传递给 :code:" +"`FedAvg`:" #: ../../source/how-to-implement-strategies.rst:209 msgid "" "The Flower server will call :code:`initialize_parameters`, which either " -"returns the parameters that were passed to :code:`initial_parameters`, or" -" :code:`None`. If no parameters are returned from " -":code:`initialize_parameters` (i.e., :code:`None`), the server will " -"randomly select one client and ask it to provide its parameters. This is " -"a convenience feature and not recommended in practice, but it can be " -"useful for prototyping. In practice, it is recommended to always use " -"server-side parameter initialization." -msgstr "" -"Flower 服务器将调用 :code:`initialize_parameters`,返回传给 " -":code:`initial_parameters` 的参数或 :code:`None`。如果 " -":code:`initialize_parameters` 没有返回任何参数(即 " -":code:`None`),服务器将随机选择一个客户端并要求其提供参数。这只是一个便捷的功能,在实际应用中并不推荐使用,但在原型开发中可能很有用。在实践中,建议始终使用服务器端参数初始化。" +"returns the parameters that were passed to :code:`initial_parameters`, or :" +"code:`None`. If no parameters are returned from :code:" +"`initialize_parameters` (i.e., :code:`None`), the server will randomly " +"select one client and ask it to provide its parameters. This is a " +"convenience feature and not recommended in practice, but it can be useful " +"for prototyping. In practice, it is recommended to always use server-side " +"parameter initialization." +msgstr "" +"Flower 服务器将调用 :code:`initialize_parameters`,返回传给 :code:" +"`initial_parameters` 的参数或 :code:`None`。如果 :code:" +"`initialize_parameters` 没有返回任何参数(即 :code:`None`),服务器将随机选择" +"一个客户端并要求其提供参数。这只是一个便捷的功能,在实际应用中并不推荐使用," +"但在原型开发中可能很有用。在实践中,建议始终使用服务器端参数初始化。" #: ../../source/how-to-implement-strategies.rst:213 msgid "" "Server-side parameter initialization is a powerful mechanism. It can be " -"used, for example, to resume training from a previously saved checkpoint." -" It is also the fundamental capability needed to implement hybrid " -"approaches, for example, to fine-tune a pre-trained model using federated" -" learning." -msgstr "服务器端参数初始化是一种强大的机制。例如,它可以用来从先前保存的检查点恢复训练。它也是实现混合方法所需的基本能力,例如,使用联邦学习对预先训练好的模型进行微调。" +"used, for example, to resume training from a previously saved checkpoint. It " +"is also the fundamental capability needed to implement hybrid approaches, " +"for example, to fine-tune a pre-trained model using federated learning." +msgstr "" +"服务器端参数初始化是一种强大的机制。例如,它可以用来从先前保存的检查点恢复训" +"练。它也是实现混合方法所需的基本能力,例如,使用联邦学习对预先训练好的模型进" +"行微调。" #: ../../source/how-to-implement-strategies.rst:216 msgid "The :code:`configure_fit` method" @@ -4937,21 +5189,23 @@ msgstr ":code:`configure_fit`方法" #: ../../source/how-to-implement-strategies.rst:218 msgid "" -":code:`configure_fit` is responsible for configuring the upcoming round " -"of training. What does *configure* mean in this context? Configuring a " -"round means selecting clients and deciding what instructions to send to " -"these clients. The signature of :code:`configure_fit` makes this clear:" +":code:`configure_fit` is responsible for configuring the upcoming round of " +"training. What does *configure* mean in this context? Configuring a round " +"means selecting clients and deciding what instructions to send to these " +"clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" -":code:`configure_fit` " -"负责配置即将开始的一轮训练。*配置*在这里是什么意思?配置一轮训练意味着选择客户并决定向这些客户发送什么指令。:code:`configure_fit`" -" 说明了这一点:" +":code:`configure_fit` 负责配置即将开始的一轮训练。*配置*在这里是什么意思?配" +"置一轮训练意味着选择客户并决定向这些客户发送什么指令。:code:`configure_fit` " +"说明了这一点:" #: ../../source/how-to-implement-strategies.rst:231 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_fit`:" -msgstr "返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :code:`configure_fit` 中执行以下步骤:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_fit`:" +msgstr "" +"返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :" +"code:`configure_fit` 中执行以下步骤:" #: ../../source/how-to-implement-strategies.rst:233 #: ../../source/how-to-implement-strategies.rst:280 @@ -4959,39 +5213,40 @@ msgid "" "Use the :code:`client_manager` to randomly sample all (or a subset of) " "available clients (each represented as a :code:`ClientProxy` object)" msgstr "" -"使用 :code:`client_manager` 随机抽样所有(或部分)可用客户端(每个客户端都表示为 :code:`ClientProxy` " -"对象)" +"使用 :code:`client_manager` 随机抽样所有(或部分)可用客户端(每个客户端都表" +"示为 :code:`ClientProxy` 对象)" #: ../../source/how-to-implement-strategies.rst:234 msgid "" "Pair each :code:`ClientProxy` with the same :code:`FitIns` holding the " "current global model :code:`parameters` and :code:`config` dict" msgstr "" -"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:`config` " -"dict 的 :code:`FitIns` 配对" +"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:" +"`config` dict 的 :code:`FitIns` 配对" #: ../../source/how-to-implement-strategies.rst:236 #, fuzzy msgid "" "More sophisticated implementations can use :code:`configure_fit` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_fit`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_fit`." msgstr "" -"更复杂的实现可以使用 :code:`configure_fit` 来实现自定义的客户端选择逻辑。只有当相应的 " -":code:`ClientProxy` 包含在 :code:`configure_fit` 返回的列表中时,客户端才会参与进来。" +"更复杂的实现可以使用 :code:`configure_fit` 来实现自定义的客户端选择逻辑。只有" +"当相应的 :code:`ClientProxy` 包含在 :code:`configure_fit` 返回的列表中时,客" +"户端才会参与进来。" #: ../../source/how-to-implement-strategies.rst:240 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to train, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"train, for example, different models on different clients, or use different " +"hyperparameters on different clients (via the :code:`config` dict)." msgstr "" -"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向每个客户端发送不同的指令。这使得自定义策略成为可能,例如在不同的客户端上训练不同的模型,或在不同的客户端上使用不同的超参数(通过" -" :code:`config` dict)。" +"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向" +"每个客户端发送不同的指令。这使得自定义策略成为可能,例如在不同的客户端上训练" +"不同的模型,或在不同的客户端上使用不同的超参数(通过 :code:`config` dict)。" #: ../../source/how-to-implement-strategies.rst:243 msgid "The :code:`aggregate_fit` method" @@ -4999,31 +5254,33 @@ msgstr ":code:`aggregate_fit` 方法" #: ../../source/how-to-implement-strategies.rst:245 msgid "" -":code:`aggregate_fit` is responsible for aggregating the results returned" -" by the clients that were selected and asked to train in " -":code:`configure_fit`." -msgstr ":code:`aggregate_fit` 负责汇总在 :code:`configure_fit` 中选择并要求训练的客户端所返回的结果。" +":code:`aggregate_fit` is responsible for aggregating the results returned by " +"the clients that were selected and asked to train in :code:`configure_fit`." +msgstr "" +":code:`aggregate_fit` 负责汇总在 :code:`configure_fit` 中选择并要求训练的客户" +"端所返回的结果。" #: ../../source/how-to-implement-strategies.rst:258 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " -"of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_fit`). :code:`aggregate_fit` therefore receives a list of :code:" +"`results`, but also a list of :code:`failures`." msgstr "" -"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:`configure_fit`)的所有客户端获得结果。因此 " -":code:`aggregate_fit` 会收到 :code:`results` 的列表,但也会收到 :code:`failures` 的列表。" +"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:" +"`configure_fit`)的所有客户端获得结果。因此 :code:`aggregate_fit` 会收到 :" +"code:`results` 的列表,但也会收到 :code:`failures` 的列表。" #: ../../source/how-to-implement-strategies.rst:260 msgid "" -":code:`aggregate_fit` returns an optional :code:`Parameters` object and a" -" dictionary of aggregated metrics. The :code:`Parameters` return value is" -" optional because :code:`aggregate_fit` might decide that the results " +":code:`aggregate_fit` returns an optional :code:`Parameters` object and a " +"dictionary of aggregated metrics. The :code:`Parameters` return value is " +"optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" -":code:`aggregate_fit` 返回一个可选的 :code:`Parameters` " -"对象和一个聚合度量的字典。:code:`Parameters` 返回值是可选的,因为 :code:`aggregate_fit` " -"可能会认为所提供的结果不足以进行聚合(例如,失败次数过多)。" +":code:`aggregate_fit` 返回一个可选的 :code:`Parameters` 对象和一个聚合度量的" +"字典。:code:`Parameters` 返回值是可选的,因为 :code:`aggregate_fit` 可能会认" +"为所提供的结果不足以进行聚合(例如,失败次数过多)。" #: ../../source/how-to-implement-strategies.rst:263 msgid "The :code:`configure_evaluate` method" @@ -5031,53 +5288,55 @@ msgstr ":code:`configure_evaluate`方法" #: ../../source/how-to-implement-strategies.rst:265 msgid "" -":code:`configure_evaluate` is responsible for configuring the upcoming " -"round of evaluation. What does *configure* mean in this context? " -"Configuring a round means selecting clients and deciding what " -"instructions to send to these clients. The signature of " -":code:`configure_evaluate` makes this clear:" +":code:`configure_evaluate` is responsible for configuring the upcoming round " +"of evaluation. What does *configure* mean in this context? Configuring a " +"round means selecting clients and deciding what instructions to send to " +"these clients. The signature of :code:`configure_evaluate` makes this clear:" msgstr "" -":code:`configure_evaluate` " -"负责配置下一轮评估。*配置*在这里是什么意思?配置一轮评估意味着选择客户端并决定向这些客户端发送什么指令。:code:`configure_evaluate`" -" 说明了这一点:" +":code:`configure_evaluate` 负责配置下一轮评估。*配置*在这里是什么意思?配置一" +"轮评估意味着选择客户端并决定向这些客户端发送什么指令。:code:" +"`configure_evaluate` 说明了这一点:" #: ../../source/how-to-implement-strategies.rst:278 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_evaluate`:" -msgstr "返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :code:`configure_evaluate` 中执行以下步骤:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_evaluate`:" +msgstr "" +"返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :" +"code:`configure_evaluate` 中执行以下步骤:" #: ../../source/how-to-implement-strategies.rst:281 msgid "" -"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " -"the current global model :code:`parameters` and :code:`config` dict" +"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding the " +"current global model :code:`parameters` and :code:`config` dict" msgstr "" -"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:`config` " -"dict 的 :code:`EvaluateIns` 配对" +"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:" +"`config` dict 的 :code:`EvaluateIns` 配对" #: ../../source/how-to-implement-strategies.rst:283 #, fuzzy msgid "" "More sophisticated implementations can use :code:`configure_evaluate` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_evaluate`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_evaluate`." msgstr "" -"更复杂的实现可以使用 :code:`configure_evaluate` 来实现自定义的客户端选择逻辑。只有当相应的 " -":code:`ClientProxy` 包含在 :code:`configure_evaluate` 返回的列表中时,客户端才会参与进来。" +"更复杂的实现可以使用 :code:`configure_evaluate` 来实现自定义的客户端选择逻" +"辑。只有当相应的 :code:`ClientProxy` 包含在 :code:`configure_evaluate` 返回的" +"列表中时,客户端才会参与进来。" #: ../../source/how-to-implement-strategies.rst:287 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to evaluate, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"evaluate, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` dict)." msgstr "" -"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向每个客户端发送不同的指令。这使得自定义策略可以在不同客户端上评估不同的模型,或在不同客户端上使用不同的超参数(通过" -" :code:`config` dict)。" +"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向" +"每个客户端发送不同的指令。这使得自定义策略可以在不同客户端上评估不同的模型," +"或在不同客户端上使用不同的超参数(通过 :code:`config` dict)。" #: ../../source/how-to-implement-strategies.rst:291 msgid "The :code:`aggregate_evaluate` method" @@ -5086,33 +5345,34 @@ msgstr ":code:`aggregate_evaluate` 方法" #: ../../source/how-to-implement-strategies.rst:293 msgid "" ":code:`aggregate_evaluate` is responsible for aggregating the results " -"returned by the clients that were selected and asked to evaluate in " -":code:`configure_evaluate`." +"returned by the clients that were selected and asked to evaluate in :code:" +"`configure_evaluate`." msgstr "" -":code:`aggregate_evaluate` 负责汇总在 :code:`configure_evaluate` " -"中选择并要求评估的客户端返回的结果。" +":code:`aggregate_evaluate` 负责汇总在 :code:`configure_evaluate` 中选择并要求" +"评估的客户端返回的结果。" #: ../../source/how-to-implement-strategies.rst:306 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " -"receives a list of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_evaluate`). :code:`aggregate_evaluate` therefore receives a list " +"of :code:`results`, but also a list of :code:`failures`." msgstr "" -"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 " -":code:`configure_evaluate`)的所有客户端获得结果。因此, :code:`aggregate_evaluate` 会接收 " -":code:`results` 的列表,但也会接收 :code:`failures` 的列表。" +"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:" +"`configure_evaluate`)的所有客户端获得结果。因此, :code:" +"`aggregate_evaluate` 会接收 :code:`results` 的列表,但也会接收 :code:" +"`failures` 的列表。" #: ../../source/how-to-implement-strategies.rst:308 msgid "" -":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a" -" dictionary of aggregated metrics. The :code:`float` return value is " -"optional because :code:`aggregate_evaluate` might decide that the results" -" provided are not sufficient for aggregation (e.g., too many failures)." +":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a " +"dictionary of aggregated metrics. The :code:`float` return value is optional " +"because :code:`aggregate_evaluate` might decide that the results provided " +"are not sufficient for aggregation (e.g., too many failures)." msgstr "" -":code:`aggregate_evaluate` 返回一个可选的 " -":code:`float`(损失值)和一个聚合指标字典。:code:`float` 返回值是可选的,因为 " -":code:`aggregate_evaluate` 可能会认为所提供的结果不足以进行聚合(例如,失败次数过多)。" +":code:`aggregate_evaluate` 返回一个可选的 :code:`float`(损失值)和一个聚合指" +"标字典。:code:`float` 返回值是可选的,因为 :code:`aggregate_evaluate` 可能会" +"认为所提供的结果不足以进行聚合(例如,失败次数过多)。" #: ../../source/how-to-implement-strategies.rst:311 msgid "The :code:`evaluate` method" @@ -5121,23 +5381,24 @@ msgstr ":code:`evaluate`方法" #: ../../source/how-to-implement-strategies.rst:313 msgid "" ":code:`evaluate` is responsible for evaluating model parameters on the " -"server-side. Having :code:`evaluate` in addition to " -":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " -"to perform both servers-side and client-side (federated) evaluation." +"server-side. Having :code:`evaluate` in addition to :code:" +"`configure_evaluate`/:code:`aggregate_evaluate` enables strategies to " +"perform both servers-side and client-side (federated) evaluation." msgstr "" -":code:`evaluate` 负责在服务器端评估模型参数。除了 " -":code:`configure_evaluate`/:code:`aggregate_evaluate` 之外,:code:`evaluate`" -" 可以使策略同时执行服务器端和客户端(联邦)评估。" +":code:`evaluate` 负责在服务器端评估模型参数。除了 :code:" +"`configure_evaluate`/:code:`aggregate_evaluate` 之外,:code:`evaluate` 可以使" +"策略同时执行服务器端和客户端(联邦)评估。" #: ../../source/how-to-implement-strategies.rst:323 msgid "" -"The return value is again optional because the strategy might not need to" -" implement server-side evaluation or because the user-defined " -":code:`evaluate` method might not complete successfully (e.g., it might " -"fail to load the server-side evaluation data)." +"The return value is again optional because the strategy might not need to " +"implement server-side evaluation or because the user-defined :code:" +"`evaluate` method might not complete successfully (e.g., it might fail to " +"load the server-side evaluation data)." msgstr "" -"返回值也是可选的,因为策略可能不需要执行服务器端评估,或者因为用户定义的 :code:`evaluate` " -"方法可能无法成功完成(例如,它可能无法加载服务器端评估数据)。" +"返回值也是可选的,因为策略可能不需要执行服务器端评估,或者因为用户定义的 :" +"code:`evaluate` 方法可能无法成功完成(例如,它可能无法加载服务器端评估数" +"据)。" #: ../../source/how-to-install-flower.rst:2 msgid "Install Flower" @@ -5158,8 +5419,7 @@ msgstr "使用 pip" #: ../../source/how-to-install-flower.rst:17 msgid "" -"Stable releases are available on `PyPI " -"`_::" +"Stable releases are available on `PyPI `_::" msgstr "稳定版本可在 `PyPI `_::" #: ../../source/how-to-install-flower.rst:21 @@ -5181,15 +5441,15 @@ msgstr "Flower 也可以从 ``conda-forge`` 频道安装。" #: ../../source/how-to-install-flower.rst:31 #, fuzzy msgid "" -"If you have not added ``conda-forge`` to your channels, you will first " -"need to run the following::" +"If you have not added ``conda-forge`` to your channels, you will first need " +"to run the following::" msgstr "如果您尚未在频道中添加 ``conda-forge``,则首先需要运行以下程序::" #: ../../source/how-to-install-flower.rst:36 #, fuzzy msgid "" -"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " -"installed with ``conda``::" +"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be installed " +"with ``conda``::" msgstr "一旦启用了 ``conda-forge`` 频道,就可以使用 ``conda``: 安装 ``flwr``:" #: ../../source/how-to-install-flower.rst:40 @@ -5205,9 +5465,11 @@ msgstr "验证安装" #, fuzzy msgid "" "The following command can be used to verify if Flower was successfully " -"installed. If everything worked, it should print the version of Flower to" -" the command line::" -msgstr "可以使用以下命令来验证 Flower 是否安装成功。如果一切正常,它将在命令行中打印 Flower 的版本::" +"installed. If everything worked, it should print the version of Flower to " +"the command line::" +msgstr "" +"可以使用以下命令来验证 Flower 是否安装成功。如果一切正常,它将在命令行中打印 " +"Flower 的版本::" #: ../../source/how-to-install-flower.rst:55 msgid "Advanced installation options" @@ -5231,16 +5493,19 @@ msgstr "安装预发布版本" #: ../../source/how-to-install-flower.rst:65 msgid "" -"New (possibly unstable) versions of Flower are sometimes available as " -"pre-release versions (alpha, beta, release candidate) before the stable " -"release happens::" -msgstr "在稳定版发布之前,Flower 的新版本(可能是不稳定版)有时会作为预发布版本(alpha、beta、候选发布版本)提供::" +"New (possibly unstable) versions of Flower are sometimes available as pre-" +"release versions (alpha, beta, release candidate) before the stable release " +"happens::" +msgstr "" +"在稳定版发布之前,Flower 的新版本(可能是不稳定版)有时会作为预发布版本" +"(alpha、beta、候选发布版本)提供::" #: ../../source/how-to-install-flower.rst:69 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" -" should be installed with the ``simulation`` extra::" -msgstr "对于使用虚拟客户端引擎的模拟,`flwr``预发行版应与`simulation``一起安装:" +"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases " +"should be installed with the ``simulation`` extra::" +msgstr "" +"对于使用虚拟客户端引擎的模拟,`flwr``预发行版应与`simulation``一起安装:" #: ../../source/how-to-install-flower.rst:74 msgid "Install nightly release" @@ -5248,14 +5513,14 @@ msgstr "安装隔夜版本" #: ../../source/how-to-install-flower.rst:76 msgid "" -"The latest (potentially unstable) changes in Flower are available as " -"nightly releases::" +"The latest (potentially unstable) changes in Flower are available as nightly " +"releases::" msgstr "Flower 中最新(可能不稳定)的更改以隔夜发布的形式提供::" #: ../../source/how-to-install-flower.rst:80 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr-nightly`` " -"should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr-nightly`` should " +"be installed with the ``simulation`` extra::" msgstr "对于使用虚拟客户端引擎的模拟,`flwr-nightly`应与`simulation`一起安装:" #: ../../source/how-to-monitor-simulation.rst:2 @@ -5264,20 +5529,23 @@ msgstr "监控模拟" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" -"Flower allows you to monitor system resources while running your " -"simulation. Moreover, the Flower simulation engine is powerful and " -"enables you to decide how to allocate resources per client manner and " -"constrain the total usage. Insights from resource consumption can help " -"you make smarter decisions and speed up the execution time." +"Flower allows you to monitor system resources while running your simulation. " +"Moreover, the Flower simulation engine is powerful and enables you to decide " +"how to allocate resources per client manner and constrain the total usage. " +"Insights from resource consumption can help you make smarter decisions and " +"speed up the execution time." msgstr "" -"Flower 允许您在运行模拟时监控系统资源。此外,Flower " -"仿真引擎功能强大,能让您决定如何按客户端方式分配资源并限制总使用量。从资源消耗中获得的观察可以帮助您做出更明智的决策,并加快执行时间。" +"Flower 允许您在运行模拟时监控系统资源。此外,Flower 仿真引擎功能强大,能让您" +"决定如何按客户端方式分配资源并限制总使用量。从资源消耗中获得的观察可以帮助您" +"做出更明智的决策,并加快执行时间。" #: ../../source/how-to-monitor-simulation.rst:6 msgid "" -"The specific instructions assume you are using macOS and have the " -"`Homebrew `_ package manager installed." -msgstr "具体说明假定你使用的是 macOS,并且安装了 `Homebrew `_ 软件包管理器。" +"The specific instructions assume you are using macOS and have the `Homebrew " +"`_ package manager installed." +msgstr "" +"具体说明假定你使用的是 macOS,并且安装了 `Homebrew `_ 软件" +"包管理器。" #: ../../source/how-to-monitor-simulation.rst:10 msgid "Downloads" @@ -5285,14 +5553,14 @@ msgstr "下载" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" -"`Prometheus `_ is used for data collection, while" -" `Grafana `_ will enable you to visualize the " -"collected data. They are both well integrated with `Ray " -"`_ which Flower uses under the hood." +"`Prometheus `_ is used for data collection, while " +"`Grafana `_ will enable you to visualize the collected " +"data. They are both well integrated with `Ray `_ which " +"Flower uses under the hood." msgstr "" -"`Prometheus `_ 用于收集数据,而 `Grafana " -"`_ 则能让你将收集到的数据可视化。它们都与 Flower 在引擎下使用的 `Ray " -"`_ 紧密集成。" +"`Prometheus `_ 用于收集数据,而 `Grafana `_ 则能让你将收集到的数据可视化。它们都与 Flower 在引擎下使用的 " +"`Ray `_ 紧密集成。" #: ../../source/how-to-monitor-simulation.rst:18 msgid "" @@ -5310,23 +5578,26 @@ msgstr "在上一代英特尔 Mac 设备上,应该是这样:" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" -"Open the respective configuration files and change them. Depending on " -"your device, use one of the two following commands:" +"Open the respective configuration files and change them. Depending on your " +"device, use one of the two following commands:" msgstr "打开相应的配置文件并修改它们。根据设备情况,使用以下两个命令之一:" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" -"and then delete all the text in the file and paste a new Prometheus " -"config you see below. You may adjust the time intervals to your " -"requirements:" -msgstr "然后删除文件中的所有文本,粘贴一个新的 Prometheus 配置文件,如下所示。您可以根据需要调整时间间隔:" +"and then delete all the text in the file and paste a new Prometheus config " +"you see below. You may adjust the time intervals to your requirements:" +msgstr "" +"然后删除文件中的所有文本,粘贴一个新的 Prometheus 配置文件,如下所示。您可以" +"根据需要调整时间间隔:" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" -"Now after you have edited the Prometheus configuration, do the same with " -"the Grafana configuration files. Open those using one of the following " -"commands as before:" -msgstr "编辑完 Prometheus 配置后,请对 Grafana 配置文件执行同样的操作。与之前一样,使用以下命令之一打开这些文件:" +"Now after you have edited the Prometheus configuration, do the same with the " +"Grafana configuration files. Open those using one of the following commands " +"as before:" +msgstr "" +"编辑完 Prometheus 配置后,请对 Grafana 配置文件执行同样的操作。与之前一样,使" +"用以下命令之一打开这些文件:" #: ../../source/how-to-monitor-simulation.rst:69 msgid "" @@ -5336,8 +5607,8 @@ msgstr "您的终端编辑器应该会打开,并允许您像之前一样应用 #: ../../source/how-to-monitor-simulation.rst:84 msgid "" -"Congratulations, you just downloaded all the necessary software needed " -"for metrics tracking. Now, let’s start it." +"Congratulations, you just downloaded all the necessary software needed for " +"metrics tracking. Now, let’s start it." msgstr "恭喜您,您刚刚下载了指标跟踪所需的所有软件。现在,让我们开始吧。" #: ../../source/how-to-monitor-simulation.rst:88 @@ -5352,8 +5623,8 @@ msgstr "在运行 Flower 模拟之前,您必须启动刚刚安装和配置的 #: ../../source/how-to-monitor-simulation.rst:97 msgid "" -"Please include the following argument in your Python code when starting a" -" simulation." +"Please include the following argument in your Python code when starting a " +"simulation." msgstr "开始模拟时,请在 Python 代码中加入以下参数。" #: ../../source/how-to-monitor-simulation.rst:108 @@ -5362,8 +5633,8 @@ msgstr "现在,您可以开始工作了。" #: ../../source/how-to-monitor-simulation.rst:110 msgid "" -"Shortly after the simulation starts, you should see the following logs in" -" your terminal:" +"Shortly after the simulation starts, you should see the following logs in " +"your terminal:" msgstr "模拟启动后不久,您就会在终端中看到以下日志:" #: ../../source/how-to-monitor-simulation.rst:117 @@ -5372,28 +5643,31 @@ msgstr "您可以在 ``_ 查看所有内容。" #: ../../source/how-to-monitor-simulation.rst:119 msgid "" -"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" -" lowest option)." -msgstr "这是一个 Ray Dashboard。您可以导航到 \"度量标准\"(左侧面板,最低选项)。" +"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the " +"lowest option)." +msgstr "" +"这是一个 Ray Dashboard。您可以导航到 \"度量标准\"(左侧面板,最低选项)。" #: ../../source/how-to-monitor-simulation.rst:121 msgid "" -"Or alternatively, you can just see them in Grafana by clicking on the " -"right-up corner, “View in Grafana”. Please note that the Ray dashboard is" -" only accessible during the simulation. After the simulation ends, you " -"can only use Grafana to explore the metrics. You can start Grafana by " -"going to ``http://localhost:3000/``." +"Or alternatively, you can just see them in Grafana by clicking on the right-" +"up corner, “View in Grafana”. Please note that the Ray dashboard is only " +"accessible during the simulation. After the simulation ends, you can only " +"use Grafana to explore the metrics. You can start Grafana by going to " +"``http://localhost:3000/``." msgstr "" -"或者,您也可以点击右上角的 \"在 Grafana 中查看\",在 Grafana 中查看它们。请注意,Ray " -"仪表盘只能在模拟期间访问。模拟结束后,您只能使用 Grafana 浏览指标。您可以访问 ``http://localhost:3000/``启动 " -"Grafana。" +"或者,您也可以点击右上角的 \"在 Grafana 中查看\",在 Grafana 中查看它们。请注" +"意,Ray 仪表盘只能在模拟期间访问。模拟结束后,您只能使用 Grafana 浏览指标。您" +"可以访问 ``http://localhost:3000/``启动 Grafana。" #: ../../source/how-to-monitor-simulation.rst:123 msgid "" "After you finish the visualization, stop Prometheus and Grafana. This is " "important as they will otherwise block, for example port :code:`3000` on " "your machine as long as they are running." -msgstr "完成可视化后,请停止 Prometheus 和 Grafana。这一点很重要,否则只要它们在运行,就会阻塞机器上的端口 :code:`3000`。" +msgstr "" +"完成可视化后,请停止 Prometheus 和 Grafana。这一点很重要,否则只要它们在运" +"行,就会阻塞机器上的端口 :code:`3000`。" #: ../../source/how-to-monitor-simulation.rst:132 msgid "Resource allocation" @@ -5401,21 +5675,24 @@ msgstr "资源分配" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" -"You must understand how the Ray library works to efficiently allocate " -"system resources to simulation clients on your own." -msgstr "您必须了解 Ray 库是如何工作的,才能有效地为自己的仿真客户端分配系统资源。" +"You must understand how the Ray library works to efficiently allocate system " +"resources to simulation clients on your own." +msgstr "" +"您必须了解 Ray 库是如何工作的,才能有效地为自己的仿真客户端分配系统资源。" #: ../../source/how-to-monitor-simulation.rst:136 msgid "" "Initially, the simulation (which Ray handles under the hood) starts by " "default with all the available resources on the system, which it shares " -"among the clients. It doesn't mean it divides it equally among all of " -"them, nor that the model training happens at all of them simultaneously. " -"You will learn more about that in the later part of this blog. You can " -"check the system resources by running the following:" +"among the clients. It doesn't mean it divides it equally among all of them, " +"nor that the model training happens at all of them simultaneously. You will " +"learn more about that in the later part of this blog. You can check the " +"system resources by running the following:" msgstr "" -"最初,模拟(由 Ray " -"在引擎下处理)默认使用系统上的所有可用资源启动,并在客户端之间共享。但这并不意味着它会将资源平均分配给所有客户端,也不意味着模型训练会在所有客户端同时进行。您将在本博客的后半部分了解到更多相关信息。您可以运行以下命令检查系统资源:" +"最初,模拟(由 Ray 在引擎下处理)默认使用系统上的所有可用资源启动,并在客户端" +"之间共享。但这并不意味着它会将资源平均分配给所有客户端,也不意味着模型训练会" +"在所有客户端同时进行。您将在本博客的后半部分了解到更多相关信息。您可以运行以" +"下命令检查系统资源:" #: ../../source/how-to-monitor-simulation.rst:143 msgid "In Google Colab, the result you see might be similar to this:" @@ -5423,8 +5700,8 @@ msgstr "在 Google Colab 中,您看到的结果可能与此类似:" #: ../../source/how-to-monitor-simulation.rst:155 msgid "" -"However, you can overwrite the defaults. When starting a simulation, do " -"the following (you don't need to overwrite all of them):" +"However, you can overwrite the defaults. When starting a simulation, do the " +"following (you don't need to overwrite all of them):" msgstr "不过,您可以覆盖默认值。开始模拟时,请执行以下操作(不必全部覆盖):" #: ../../source/how-to-monitor-simulation.rst:175 @@ -5433,23 +5710,26 @@ msgstr "我们还可以为单个客户指定资源。" #: ../../source/how-to-monitor-simulation.rst:205 msgid "" -"Now comes the crucial part. Ray will start a new client only when it has " -"all the required resources (such that they run in parallel) when the " -"resources allow." -msgstr "现在到了关键部分。只有在资源允许的情况下,Ray 才会在拥有所有所需资源(如并行运行)时启动新客户端。" +"Now comes the crucial part. Ray will start a new client only when it has all " +"the required resources (such that they run in parallel) when the resources " +"allow." +msgstr "" +"现在到了关键部分。只有在资源允许的情况下,Ray 才会在拥有所有所需资源(如并行" +"运行)时启动新客户端。" #: ../../source/how-to-monitor-simulation.rst:207 msgid "" -"In the example above, only one client will be run, so your clients won't " -"run concurrently. Setting :code:`client_num_gpus = 0.5` would allow " -"running two clients and therefore enable them to run concurrently. Be " -"careful not to require more resources than available. If you specified " -":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " -"had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." +"In the example above, only one client will be run, so your clients won't run " +"concurrently. Setting :code:`client_num_gpus = 0.5` would allow running two " +"clients and therefore enable them to run concurrently. Be careful not to " +"require more resources than available. If you specified :code:" +"`client_num_gpus = 2`, the simulation wouldn't start (even if you had 2 GPUs " +"but decided to set 1 in :code:`ray_init_args`)." msgstr "" -"在上面的示例中,将只运行一个客户端,因此您的客户端不会并发运行。设置 :code:`client_num_gpus = 0.5` " -"将允许运行两个客户端,从而使它们能够并发运行。请注意,所需的资源不要超过可用资源。如果您指定 :code:`client_num_gpus = " -"2`,模拟将无法启动(即使您有 2 个 GPU,但决定在 :code:`ray_init_args` 中设置为 1)。" +"在上面的示例中,将只运行一个客户端,因此您的客户端不会并发运行。设置 :code:" +"`client_num_gpus = 0.5` 将允许运行两个客户端,从而使它们能够并发运行。请注" +"意,所需的资源不要超过可用资源。如果您指定 :code:`client_num_gpus = 2`,模拟" +"将无法启动(即使您有 2 个 GPU,但决定在 :code:`ray_init_args` 中设置为 1)。" #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 msgid "FAQ" @@ -5461,22 +5741,25 @@ msgstr "问:我没有看到任何指标记录。" #: ../../source/how-to-monitor-simulation.rst:216 msgid "" -"A: The timeframe might not be properly set. The setting is in the top " -"right corner (\"Last 30 minutes\" by default). Please change the " -"timeframe to reflect the period when the simulation was running." -msgstr "答:时间范围可能没有正确设置。设置在右上角(默认为 \"最后 30 分钟\")。请更改时间框架,以反映模拟运行的时间段。" +"A: The timeframe might not be properly set. The setting is in the top right " +"corner (\"Last 30 minutes\" by default). Please change the timeframe to " +"reflect the period when the simulation was running." +msgstr "" +"答:时间范围可能没有正确设置。设置在右上角(默认为 \"最后 30 分钟\")。请更改" +"时间框架,以反映模拟运行的时间段。" #: ../../source/how-to-monitor-simulation.rst:218 msgid "" -"Q: I see “Grafana server not detected. Please make sure the Grafana " -"server is running and refresh this page” after going to the Metrics tab " -"in Ray Dashboard." -msgstr "问:我看到 \"未检测到 Grafana 服务器。请确保 Grafana 服务器正在运行并刷新此页面\"。" +"Q: I see “Grafana server not detected. Please make sure the Grafana server " +"is running and refresh this page” after going to the Metrics tab in Ray " +"Dashboard." +msgstr "" +"问:我看到 \"未检测到 Grafana 服务器。请确保 Grafana 服务器正在运行并刷新此页" +"面\"。" #: ../../source/how-to-monitor-simulation.rst:220 msgid "" -"A: You probably don't have Grafana running. Please check the running " -"services" +"A: You probably don't have Grafana running. Please check the running services" msgstr "答:您可能没有运行 Grafana。请检查正在运行的服务" #: ../../source/how-to-monitor-simulation.rst:226 @@ -5487,8 +5770,8 @@ msgstr "问:在访问 ``_时,我看到 \"无法访问 #: ../../source/how-to-monitor-simulation.rst:228 msgid "" -"A: Either the simulation has already finished, or you still need to start" -" Prometheus." +"A: Either the simulation has already finished, or you still need to start " +"Prometheus." msgstr "答:要么模拟已经完成,要么您还需要启动Prometheus。" #: ../../source/how-to-monitor-simulation.rst:232 @@ -5500,14 +5783,15 @@ msgstr "资源" msgid "" "Ray Dashboard: ``_" -msgstr "Ray 仪表盘: ``_" +msgstr "" +"Ray 仪表盘: ``_" #: ../../source/how-to-monitor-simulation.rst:236 #, fuzzy msgid "Ray Metrics: ``_" msgstr "" -"Ray 指标: ``_" +"Ray 指标: ``_" #: ../../source/how-to-run-flower-using-docker.rst:2 #, fuzzy @@ -5517,9 +5801,9 @@ msgstr "使用 Docker 运行 Flower" #: ../../source/how-to-run-flower-using-docker.rst:4 #, fuzzy msgid "" -"The simplest way to get started with Flower is by using the pre-made " -"Docker images, which you can find on `Docker Hub " -"`_." +"The simplest way to get started with Flower is by using the pre-made Docker " +"images, which you can find on `Docker Hub `_." msgstr "" "开始使用 Flower 的最简单方法是使用预制的 Docker 镜像,您可以在 `Docker Hub " "`_ 上找到这些镜像。" @@ -5532,25 +5816,24 @@ msgstr "开始之前,请确保 Docker 守护进程正在运行:" #: ../../source/how-to-run-flower-using-docker.rst:14 #, fuzzy msgid "" -"If you do not see the version of Docker but instead get an error saying " -"that the command was not found, you will need to install Docker first. " -"You can find installation instruction `here `_." +"If you do not see the version of Docker but instead get an error saying that " +"the command was not found, you will need to install Docker first. You can " +"find installation instruction `here `_." msgstr "" -"如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。" -"你可以在 `_ 找到安装说明。" +"如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。你" +"可以在 `_ 找到安装说明。" #: ../../source/how-to-run-flower-using-docker.rst:20 #, fuzzy msgid "" -"On Linux, Docker commands require ``sudo`` privilege. If you want to " -"avoid using ``sudo``, you can follow the `Post-installation steps " -"`_ on the " -"official Docker website." +"On Linux, Docker commands require ``sudo`` privilege. If you want to avoid " +"using ``sudo``, you can follow the `Post-installation steps `_ on the official Docker " +"website." msgstr "" -"在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``," -"可以按照 Docker 官方网站上的 `安装后步骤 `_进行操作。" +"在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``,可以按" +"照 Docker 官方网站上的 `安装后步骤 `_进行操作。" #: ../../source/how-to-run-flower-using-docker.rst:25 #, fuzzy @@ -5570,23 +5853,22 @@ msgstr "如果您想试用 Flower,可以使用以下命令:" #: ../../source/how-to-run-flower-using-docker.rst:37 #, fuzzy msgid "" -"The command will pull the Docker image with the tag " -"``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. The tag contains the " -"information which Flower, Python and Ubuntu is used. In this case, it " -"uses Flower 1.7.0, Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells " -"Docker to remove the container after it exits." +"The command will pull the Docker image with the tag ``1.7.0-py3.11-" +"ubuntu22.04`` from Docker Hub. The tag contains the information which " +"Flower, Python and Ubuntu is used. In this case, it uses Flower 1.7.0, " +"Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells Docker to remove the " +"container after it exits." msgstr "" "该命令将从 Docker Hub 提取标签为``1.7.0-py3.11-ubuntu22.04``的 Docker 镜像。" -"标签包含使用 Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower 1.7." -"0、Python 3.11 和 Ubuntu 22.04。rm \"标记告诉 Docker 在退出后移除容器。" +"标签包含使用 Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower " +"1.7.0、Python 3.11 和 Ubuntu 22.04。rm \"标记告诉 Docker 在退出后移除容器。" #: ../../source/how-to-run-flower-using-docker.rst:44 #, fuzzy msgid "" -"By default, the Flower server keeps state in-memory. When using the " -"Docker flag ``--rm``, the state is not persisted between container " -"starts. We will show below how to save the state in a file on your host " -"system." +"By default, the Flower server keeps state in-memory. When using the Docker " +"flag ``--rm``, the state is not persisted between container starts. We will " +"show below how to save the state in a file on your host system." msgstr "" "默认情况下,Flower 服务器会将状态保存在内存中。使用 Docker 标志 ``--rm`` 时," "状态不会在容器启动之间持久化。下面我们将展示如何将状态保存到主机系统上的文件" @@ -5595,37 +5877,35 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:48 #, fuzzy msgid "" -"The ``-p :`` flag tells Docker to map the ports " -"``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " -"allowing you to access the Driver API on ``http://localhost:9091`` and " -"the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " -"after the tag is passed to the Flower server. Here, we are passing the " -"flag ``--insecure``." +"The ``-p :`` flag tells Docker to map the ports ``9091``/" +"``9092`` of the host to ``9091``/``9092`` of the container, allowing you to " +"access the Driver API on ``http://localhost:9091`` and the Fleet API on " +"``http://localhost:9092``. Lastly, any flag that comes after the tag is " +"passed to the Flower server. Here, we are passing the flag ``--insecure``." msgstr "" -"``-p :`` 标记会告诉 Docker 将主机的端口 ``9091``/``9092`` " -"映射到容器的端口 ``9091``/`9092``,这样你就可以在 ``http://localhost:9091`` " -"上访问 Driver API,在 ``http://localhost:9092`` 上访问 Fleet API。最后," -"标签后面的任何标志都会传递给 Flower 服务器。在这里,我们传递的标志是 " -"``--insecure`` 。" +"``-p :`` 标记会告诉 Docker 将主机的端口 ``9091``/``9092`` 映" +"射到容器的端口 ``9091``/`9092``,这样你就可以在 ``http://localhost:9091`` 上" +"访问 Driver API,在 ``http://localhost:9092`` 上访问 Fleet API。最后,标签后" +"面的任何标志都会传递给 Flower 服务器。在这里,我们传递的标志是 ``--" +"insecure`` 。" #: ../../source/how-to-run-flower-using-docker.rst:55 #, fuzzy msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " -"HTTPS) and should only be used for testing purposes. We strongly " -"recommend enabling `SSL `_ when " -"deploying to a production environment." +"HTTPS) and should only be used for testing purposes. We strongly recommend " +"enabling `SSL `_ when deploying to a " +"production environment." msgstr "" -"不安全 \"标志启用不安全通信(使用 HTTP,而非 HTTPS),只能用于测试目的。" -"我们强烈建议在部署到生产环境时启用 `SSL `_。" +"不安全 \"标志启用不安全通信(使用 HTTP,而非 HTTPS),只能用于测试目的。我们" +"强烈建议在部署到生产环境时启用 `SSL `_。" #: ../../source/how-to-run-flower-using-docker.rst:60 #, fuzzy msgid "" -"You can use ``--help`` to view all available flags that the server " -"supports:" +"You can use ``--help`` to view all available flags that the server supports:" msgstr "您可以使用 ``--help`` 查看服务器支持的所有可用标记:" #: ../../source/how-to-run-flower-using-docker.rst:67 @@ -5636,26 +5916,25 @@ msgstr "在主机系统上挂载卷以存储状态" #: ../../source/how-to-run-flower-using-docker.rst:69 #, fuzzy msgid "" -"If you want to persist the state of the server on your host system, all " -"you need to do is specify a path where you want to save the file on your " -"host system and a name for the database file. In the example below, we " -"tell Docker via the flag ``-v`` to mount the user's home directory " -"(``~/`` on your host) into the ``/app/`` directory of the container. " -"Furthermore, we use the flag ``--database`` to specify the name of the " -"database file." +"If you want to persist the state of the server on your host system, all you " +"need to do is specify a path where you want to save the file on your host " +"system and a name for the database file. In the example below, we tell " +"Docker via the flag ``-v`` to mount the user's home directory (``~/`` on " +"your host) into the ``/app/`` directory of the container. Furthermore, we " +"use the flag ``--database`` to specify the name of the database file." msgstr "" "如果想在主机系统上持久保存服务器的状态,只需在主机系统上指定保存文件的路径和" -"数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉 Docker " -"将用户的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外," -"我们使用标志 ``--database`` 来指定数据库文件的名称。" +"数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉 Docker 将用户" +"的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外,我们使用标志 " +"``--database`` 来指定数据库文件的名称。" #: ../../source/how-to-run-flower-using-docker.rst:82 #, fuzzy msgid "" -"As soon as the server starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, " -"the server tries to restore the state from the file. To start the server " -"with an empty database, simply remove the ``state.db`` file." +"As soon as the server starts, the file ``state.db`` is created in the user's " +"home directory on your host system. If the file already exists, the server " +"tries to restore the state from the file. To start the server with an empty " +"database, simply remove the ``state.db`` file." msgstr "" "服务器一启动,就会在主机系统的用户主目录下创建文件 ``state.db``。如果该文件已" "经存在,服务器会尝试从该文件恢复状态。要以空数据库启动服务器,只需删除 " @@ -5669,35 +5948,34 @@ msgstr "启用 SSL 连接" #: ../../source/how-to-run-flower-using-docker.rst:89 #, fuzzy msgid "" -"To enable SSL, you will need a CA certificate, a server certificate and a" -" server private key." +"To enable SSL, you will need a CA certificate, a server certificate and a " +"server private key." msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" #: ../../source/how-to-run-flower-using-docker.rst:92 #, fuzzy msgid "" -"For testing purposes, you can generate your own self-signed certificates." -" The `Enable SSL connections `_ page contains a section that " -"will guide you through the process." +"For testing purposes, you can generate your own self-signed certificates. " +"The `Enable SSL connections `_ page contains a section that will guide " +"you through the process." msgstr "" "出于测试目的,你可以生成自己的自签名证书。启用 SSL 连接 `_ " -"页面中有一个部分将指导你完成这一过程。" +"docs/framework/how-to-enable-ssl-connections.html#certificates>`_ 页面中有一" +"个部分将指导你完成这一过程。" #: ../../source/how-to-run-flower-using-docker.rst:96 #, fuzzy msgid "" -"Assuming all files we need are in the local ``certificates`` directory, " -"we can use the flag ``-v`` to mount the local directory into the " -"``/app/`` directory of the container. This allows the server to access " -"the files within the container. Finally, we pass the names of the " -"certificates to the server with the ``--certificates`` flag." +"Assuming all files we need are in the local ``certificates`` directory, we " +"can use the flag ``-v`` to mount the local directory into the ``/app/`` " +"directory of the container. This allows the server to access the files " +"within the container. Finally, we pass the names of the certificates to the " +"server with the ``--certificates`` flag." msgstr "" "假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 " -"``-v`` 将本地目录挂载到容器的 ``/app/`` " -"目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates``" -" 标志将证书名称传递给服务器。" +"``-v`` 将本地目录挂载到容器的 ``/app/`` 目录中。这样,服务器就可以访问容器内" +"的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" #: ../../source/how-to-run-flower-using-docker.rst:108 #, fuzzy @@ -5707,13 +5985,13 @@ msgstr "使用不同的 Flower 或 Python 版本" #: ../../source/how-to-run-flower-using-docker.rst:110 #, fuzzy msgid "" -"If you want to use a different version of Flower or Python, you can do so" -" by changing the tag. All versions we provide are available on `Docker " -"Hub `_." +"If you want to use a different version of Flower or Python, you can do so by " +"changing the tag. All versions we provide are available on `Docker Hub " +"`_." msgstr "" -"如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。" -"我们提供的所有版本都可以在 `Docker Hub `_ 上找到。" +"如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。我们提供的所" +"有版本都可以在 `Docker Hub `_ 上找" +"到。" #: ../../source/how-to-run-flower-using-docker.rst:114 #, fuzzy @@ -5725,9 +6003,9 @@ msgstr "将 Docker 映像固定到特定版本" msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that " -"you always use the same image, you can specify the hash of the image " -"instead of the tag." +"change the functionality of Flower. However, if you want to ensure that you " +"always use the same image, you can specify the hash of the image instead of " +"the tag." msgstr "" "我们可能会更新标签后面的图像。此类更新通常包括系统依赖项的安全更新,不会改变 " "Flower 的功能。不过,如果您想确保始终使用同一张图片,可以指定图片的哈希值而不" @@ -5738,8 +6016,9 @@ msgstr "" msgid "" "The following command returns the current image hash referenced by the " "``server:1.7.0-py3.11-ubuntu22.04`` tag:" -msgstr "下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` " -"标记引用的当前图像哈希值:" +msgstr "" +"下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` 标记引用的当前图像哈希" +"值:" #: ../../source/how-to-run-flower-using-docker.rst:128 #, fuzzy @@ -5765,81 +6044,85 @@ msgstr "运行模拟" #: ../../source/how-to-run-simulations.rst:8 msgid "" "Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients " -"but without having to source, configure and mange a large number of " -"physical devices; you might want to run your FL workloads as fast as " -"possible on the compute systems you have access to without having to go " -"through a complex setup process; you might want to validate your " -"algorithm on different scenarios at varying levels of data and system " -"heterogeneity, client availability, privacy budgets, etc. These are among" -" some of the use-cases where simulating FL workloads makes sense. Flower " -"can accommodate these scenarios by means of its `VirtualClientEngine " -"`_ or " -"VCE." -msgstr "" -"模拟联邦学习工作负载可用于多种案例:您可能希望在大量客户端上运行您的工作负载,但无需采购、配置和管理大量物理设备;您可能希望在您可以访问的计算系统上尽可能快地运行您的" -" FL 工作负载,而无需经过复杂的设置过程;您可能希望在不同数据和系统异构性、客户端可用性、隐私预算等不同水平的场景中验证您的算法。这些都是模拟 " -"FL 工作负载的一些案例。Flower 可以通过其 \"虚拟客户端引擎\"(VirtualClientEngine)_或 VCE 来匹配这些情况。" +"cases: you might want to run your workload on a large cohort of clients but " +"without having to source, configure and mange a large number of physical " +"devices; you might want to run your FL workloads as fast as possible on the " +"compute systems you have access to without having to go through a complex " +"setup process; you might want to validate your algorithm on different " +"scenarios at varying levels of data and system heterogeneity, client " +"availability, privacy budgets, etc. These are among some of the use-cases " +"where simulating FL workloads makes sense. Flower can accommodate these " +"scenarios by means of its `VirtualClientEngine `_ or VCE." +msgstr "" +"模拟联邦学习工作负载可用于多种案例:您可能希望在大量客户端上运行您的工作负" +"载,但无需采购、配置和管理大量物理设备;您可能希望在您可以访问的计算系统上尽" +"可能快地运行您的 FL 工作负载,而无需经过复杂的设置过程;您可能希望在不同数据" +"和系统异构性、客户端可用性、隐私预算等不同水平的场景中验证您的算法。这些都是" +"模拟 FL 工作负载的一些案例。Flower 可以通过其 \"虚拟客户端引擎" +"\"(VirtualClientEngine)_或 VCE 来匹配这些情况。" #: ../../source/how-to-run-simulations.rst:10 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" -" clients. These clients are identical to `non-virtual` clients (i.e. the " -"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " -"creating a class inheriting, for example, from `flwr.client.NumPyClient " -"`_ and therefore behave in an " -"identical way. In addition to that, clients managed by the " -":code:`VirtualClientEngine` are:" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " +"clients. These clients are identical to `non-virtual` clients (i.e. the ones " +"you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by creating a " +"class inheriting, for example, from `flwr.client.NumPyClient `_ and therefore behave in an identical way. In " +"addition to that, clients managed by the :code:`VirtualClientEngine` are:" msgstr "" -":code:`VirtualClientEngine`用来规划,启动和管理`虚拟`客户端。这些客户端跟`非虚拟`客户端是一样的(即为您通过`flwr.client.start_client" -" `_启动的客户端),因为它们可以通过创建一个继承自 " -"`flwr.client.NumPyClient `_ " -"的类进行配置,因此其行为方式相同。另外,由 `VirtualClientEngine` 管理的客户端有:" +":code:`VirtualClientEngine`用来规划,启动和管理`虚拟`客户端。这些客户端跟`非" +"虚拟`客户端是一样的(即为您通过`flwr.client.start_client `_启动的客户端),因为它们可以通过创建一个继承自 `flwr." +"client.NumPyClient `_ 的类进行配" +"置,因此其行为方式相同。另外,由 `VirtualClientEngine` 管理的客户端有:" #: ../../source/how-to-run-simulations.rst:12 msgid "" -"resource-aware: this means that each client gets assigned a portion of " -"the compute and memory on your system. You as a user can control this at " -"the beginning of the simulation and allows you to control the degree of " +"resource-aware: this means that each client gets assigned a portion of the " +"compute and memory on your system. You as a user can control this at the " +"beginning of the simulation and allows you to control the degree of " "parallelism of your Flower FL simulation. The fewer the resources per " "client, the more clients can run concurrently on the same hardware." msgstr "" -"资源感知:这意味着每个客户端都会分配到系统中的一部分计算和内存。作为用户,您可以在模拟开始时对其进行控制,从而控制 Flower FL " -"模拟的并行程度。每个客户端的资源越少,在同一硬件上并发运行的客户端就越多。" +"资源感知:这意味着每个客户端都会分配到系统中的一部分计算和内存。作为用户,您" +"可以在模拟开始时对其进行控制,从而控制 Flower FL 模拟的并行程度。每个客户端的" +"资源越少,在同一硬件上并发运行的客户端就越多。" #: ../../source/how-to-run-simulations.rst:13 msgid "" -"self-managed: this means that you as a user do not need to launch clients" -" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"self-managed: this means that you as a user do not need to launch clients " +"manually, instead this gets delegated to :code:`VirtualClientEngine`'s " "internals." -msgstr "自管理:这意味着用户无需手动启动客户端,而是由 :code:`VirtualClientEngine` 负责。" +msgstr "" +"自管理:这意味着用户无需手动启动客户端,而是由 :code:`VirtualClientEngine` 负" +"责。" #: ../../source/how-to-run-simulations.rst:14 msgid "" -"ephemeral: this means that a client is only materialized when it is " -"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," -" releasing the resources it was assigned and allowing in this way other " -"clients to participate." +"ephemeral: this means that a client is only materialized when it is required " +"in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards, releasing the resources it was " +"assigned and allowing in this way other clients to participate." msgstr "" -"即时性:这意味着客户端只有在 FL 进程中需要它时才会被实体化(例如执行 `fit() `_ " -")。之后该对象将被销毁,释放分配给它的资源,并允许其他客户端以这种方式参与。" +"即时性:这意味着客户端只有在 FL 进程中需要它时才会被实体化(例如执行 `fit() " +"`_ )。之后该对象将被销毁,释放分配" +"给它的资源,并允许其他客户端以这种方式参与。" #: ../../source/how-to-run-simulations.rst:16 msgid "" "The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " "`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " -"of `Actors `_ to " -"spawn `virtual` clients and run their workload." +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use of " +"`Actors `_ to spawn " +"`virtual` clients and run their workload." msgstr "" -":code:`VirtualClientEngine`使用`Ray " -"`_来实现`虚拟`客户端,这是一个用于可扩展 Python 工作负载的开源框架。特别地,Flower 的" -" :code:`VirtualClientEngine` 使用 `Actors `_ 来生成 `virtual` 客户端并运行它们的工作负载。" +":code:`VirtualClientEngine`使用`Ray `_来实现`虚拟`客户" +"端,这是一个用于可扩展 Python 工作负载的开源框架。特别地,Flower 的 :code:" +"`VirtualClientEngine` 使用 `Actors `_ 来生成 `virtual` 客户端并运行它们的工作负载。" #: ../../source/how-to-run-simulations.rst:20 msgid "Launch your Flower simulation" @@ -5847,16 +6130,16 @@ msgstr "启动 Flower 模拟" #: ../../source/how-to-run-simulations.rst:22 msgid "" -"Running Flower simulations still require you to define your client class," -" a strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your " -"simulation is done with `start_simulation `_ and a minimal example looks" -" as follows:" +"Running Flower simulations still require you to define your client class, a " +"strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your simulation " +"is done with `start_simulation `_ and a minimal example looks as follows:" msgstr "" -"运行 Flower 模拟器仍然需要定义客户端类、策略以及下载和加载(可能还需要分割)数据集的实用程序。在完成这些工作后,就可以使用 " -"\"start_simulation `_\" 来启动模拟了,一个最简单的示例如下:" +"运行 Flower 模拟器仍然需要定义客户端类、策略以及下载和加载(可能还需要分割)" +"数据集的实用程序。在完成这些工作后,就可以使用 \"start_simulation `_\" 来启动模拟了,一个最简单的示" +"例如下:" #: ../../source/how-to-run-simulations.rst:44 msgid "VirtualClientEngine resources" @@ -5864,23 +6147,24 @@ msgstr "虚拟客户端引擎资源" #: ../../source/how-to-run-simulations.rst:45 msgid "" -"By default the VCE has access to all system resources (i.e. all CPUs, all" -" GPUs, etc) since that is also the default behavior when starting Ray. " -"However, in some settings you might want to limit how many of your system" -" resources are used for simulation. You can do this via the " -":code:`ray_init_args` input argument to :code:`start_simulation` which " -"the VCE internally passes to Ray's :code:`ray.init` command. For a " -"complete list of settings you can configure check the `ray.init " -"`_" -" documentation. Do not set :code:`ray_init_args` if you want the VCE to " -"use all your system's CPUs and GPUs." -msgstr "" -"默认情况下,VCE 可以访问所有系统资源(即所有 CPU、所有 GPU 等),因为这也是启动 Ray " -"时的默认行为。不过,在某些设置中,您可能希望限制有多少系统资源用于模拟。您可以通过 :code:`ray_init_args` 输入到 " -":code:`start_simulation` 的参数来做到这一点,VCE 会在内部将该参数传递给 Ray 的 :code:`ray.init`" -" 命令。有关您可以配置的设置的完整列表,请查看 `ray.init `_ 文档。如果希望 VCE 使用系统中所有的 CPU 和 " -"GPU,请不要设置 :code:`ray_init_args`。" +"By default the VCE has access to all system resources (i.e. all CPUs, all " +"GPUs, etc) since that is also the default behavior when starting Ray. " +"However, in some settings you might want to limit how many of your system " +"resources are used for simulation. You can do this via the :code:" +"`ray_init_args` input argument to :code:`start_simulation` which the VCE " +"internally passes to Ray's :code:`ray.init` command. For a complete list of " +"settings you can configure check the `ray.init `_ documentation. Do not set :" +"code:`ray_init_args` if you want the VCE to use all your system's CPUs and " +"GPUs." +msgstr "" +"默认情况下,VCE 可以访问所有系统资源(即所有 CPU、所有 GPU 等),因为这也是启" +"动 Ray 时的默认行为。不过,在某些设置中,您可能希望限制有多少系统资源用于模" +"拟。您可以通过 :code:`ray_init_args` 输入到 :code:`start_simulation` 的参数来" +"做到这一点,VCE 会在内部将该参数传递给 Ray 的 :code:`ray.init` 命令。有关您可" +"以配置的设置的完整列表,请查看 `ray.init `_ 文档。如果希望 VCE 使用系统中所有的 " +"CPU 和 GPU,请不要设置 :code:`ray_init_args`。" #: ../../source/how-to-run-simulations.rst:62 msgid "Assigning client resources" @@ -5888,27 +6172,27 @@ msgstr "分配客户端资源" #: ../../source/how-to-run-simulations.rst:63 msgid "" -"By default the :code:`VirtualClientEngine` assigns a single CPU core (and" -" nothing else) to each virtual client. This means that if your system has" -" 10 cores, that many virtual clients can be concurrently running." +"By default the :code:`VirtualClientEngine` assigns a single CPU core (and " +"nothing else) to each virtual client. This means that if your system has 10 " +"cores, that many virtual clients can be concurrently running." msgstr "" -"默认情况下,:code:`VirtualClientEngine` 会为每个虚拟客户端分配一个 CPU " -"内核(不分配其他任何内核)。这意味着,如果系统有 10 个内核,那么可以同时运行这么多虚拟客户端。" +"默认情况下,:code:`VirtualClientEngine` 会为每个虚拟客户端分配一个 CPU 内核" +"(不分配其他任何内核)。这意味着,如果系统有 10 个内核,那么可以同时运行这么" +"多虚拟客户端。" #: ../../source/how-to-run-simulations.rst:65 msgid "" -"More often than not, you would probably like to adjust the resources your" -" clients get assigned based on the complexity (i.e. compute and memory " -"footprint) of your FL workload. You can do so when starting your " -"simulation by setting the argument `client_resources` to " -"`start_simulation `_." -" Two keys are internally used by Ray to schedule and spawn workloads (in " -"our case Flower clients):" +"More often than not, you would probably like to adjust the resources your " +"clients get assigned based on the complexity (i.e. compute and memory " +"footprint) of your FL workload. You can do so when starting your simulation " +"by setting the argument `client_resources` to `start_simulation `_. Two keys are internally used " +"by Ray to schedule and spawn workloads (in our case Flower clients):" msgstr "" -"通常情况下,您可能希望根据 FL 工作负载的复杂性(即计算和内存占用)来调整分配给客户端的资源。您可以在启动模拟时将参数 " -"`client_resources` 设置为 `start_simulation `_ 。Ray " -"内部使用两个键来调度和生成工作负载(在我们的例子中是 Flower 客户端):" +"通常情况下,您可能希望根据 FL 工作负载的复杂性(即计算和内存占用)来调整分配" +"给客户端的资源。您可以在启动模拟时将参数 `client_resources` 设置为 " +"`start_simulation `_ 。" +"Ray 内部使用两个键来调度和生成工作负载(在我们的例子中是 Flower 客户端):" #: ../../source/how-to-run-simulations.rst:67 msgid ":code:`num_cpus` indicates the number of CPU cores a client would get." @@ -5928,29 +6212,30 @@ msgstr "让我们来看几个例子:" msgid "" "While the :code:`client_resources` can be used to control the degree of " "concurrency in your FL simulation, this does not stop you from running " -"dozens, hundreds or even thousands of clients in the same round and " -"having orders of magnitude more `dormant` (i.e. not participating in a " -"round) clients. Let's say you want to have 100 clients per round but your" -" system can only accommodate 8 clients concurrently. The " -":code:`VirtualClientEngine` will schedule 100 jobs to run (each " -"simulating a client sampled by the strategy) and then will execute them " -"in a resource-aware manner in batches of 8." -msgstr "" -"虽然 :code:`client_resources` 可用来控制 FL " -"模拟的并发程度,但这并不能阻止您在同一轮模拟中运行几十、几百甚至上千个客户端,并拥有数量级更多的 " -"\"休眠\"(即不参与一轮模拟)客户端。比方说,您希望每轮有 100 个客户端,但您的系统只能同时容纳 8 " -"个客户端。:code:`VirtualClientEngine` 将安排运行 100 " -"个工作(每个工作模拟策略采样的一个客户端),然后以资源感知的方式分批执行。" +"dozens, hundreds or even thousands of clients in the same round and having " +"orders of magnitude more `dormant` (i.e. not participating in a round) " +"clients. Let's say you want to have 100 clients per round but your system " +"can only accommodate 8 clients concurrently. The :code:`VirtualClientEngine` " +"will schedule 100 jobs to run (each simulating a client sampled by the " +"strategy) and then will execute them in a resource-aware manner in batches " +"of 8." +msgstr "" +"虽然 :code:`client_resources` 可用来控制 FL 模拟的并发程度,但这并不能阻止您" +"在同一轮模拟中运行几十、几百甚至上千个客户端,并拥有数量级更多的 \"休眠\"(即" +"不参与一轮模拟)客户端。比方说,您希望每轮有 100 个客户端,但您的系统只能同时" +"容纳 8 个客户端。:code:`VirtualClientEngine` 将安排运行 100 个工作(每个工作" +"模拟策略采样的一个客户端),然后以资源感知的方式分批执行。" #: ../../source/how-to-run-simulations.rst:91 msgid "" "To understand all the intricate details on how resources are used to " -"schedule FL clients and how to define custom resources, please take a " -"look at the `Ray documentation `_." +"schedule FL clients and how to define custom resources, please take a look " +"at the `Ray documentation `_." msgstr "" -"要了解资源如何用于调度 FL 客户端以及如何定义自定义资源的所有复杂细节,请查看 `Ray 文档 " -"`_。" +"要了解资源如何用于调度 FL 客户端以及如何定义自定义资源的所有复杂细节,请查看 " +"`Ray 文档 `_。" #: ../../source/how-to-run-simulations.rst:94 msgid "Simulation examples" @@ -5958,26 +6243,27 @@ msgstr "模拟示例" #: ../../source/how-to-run-simulations.rst:96 msgid "" -"A few ready-to-run complete examples for Flower simulation in " -"Tensorflow/Keras and PyTorch are provided in the `Flower repository " -"`_. You can run them on Google Colab too:" +"A few ready-to-run complete examples for Flower simulation in Tensorflow/" +"Keras and PyTorch are provided in the `Flower repository `_. You can run them on Google Colab too:" msgstr "" -"在 Tensorflow/Keras 和 PyTorch 中进行 Flower 模拟的几个可随时运行的完整示例已在 `Flower 库 " -"`_ 中提供。您也可以在 Google Colab 上运行它们:" +"在 Tensorflow/Keras 和 PyTorch 中进行 Flower 模拟的几个可随时运行的完整示例已" +"在 `Flower 库 `_ 中提供。您也可以在 Google " +"Colab 上运行它们:" #: ../../source/how-to-run-simulations.rst:98 msgid "" -"`Tensorflow/Keras Simulation " -"`_: 100 clients collaboratively train a MLP model on MNIST." +"`Tensorflow/Keras Simulation `_: 100 clients collaboratively train a MLP " +"model on MNIST." msgstr "" -"Tensorflow/Keras模拟 `_:100个客户端在MNIST上协作训练一个MLP模型。" +"Tensorflow/Keras模拟 `_:100个客户端在MNIST上协作训练一个MLP模型。" #: ../../source/how-to-run-simulations.rst:99 msgid "" -"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " +"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " "MNIST." msgstr "" "PyTorch 模拟 `)" -msgstr "在所有节点中都有一份数据集副本(更多相关信息请参阅 :ref:`模拟注意事项`)" +"Have a copy of your dataset in all nodes (more about this in :ref:" +"`simulation considerations `)" +msgstr "" +"在所有节点中都有一份数据集副本(更多相关信息请参阅 :ref:`模拟注意事项" +"`)" #: ../../source/how-to-run-simulations.rst:111 msgid "" -"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation " -"`_ so the " -":code:`VirtualClientEngine` attaches to a running Ray instance." +"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation `_ so the :code:" +"`VirtualClientEngine` attaches to a running Ray instance." msgstr "" "将 :code:`ray_init_args={\"address\"=\"auto\"}`传递给 `start_simulation `_ ,这样 " -":code:`VirtualClientEngine`就会连接到正在运行的 Ray 实例。" +"api-flwr.html#flwr.simulation.start_simulation>`_ ,这样 :code:" +"`VirtualClientEngine`就会连接到正在运行的 Ray 实例。" #: ../../source/how-to-run-simulations.rst:112 msgid "" -"Start Ray on you head node: on the terminal type :code:`ray start " -"--head`. This command will print a few lines, one of which indicates how " -"to attach other nodes to the head node." +"Start Ray on you head node: on the terminal type :code:`ray start --head`. " +"This command will print a few lines, one of which indicates how to attach " +"other nodes to the head node." msgstr "" -"在头部节点上启动 Ray:在终端上输入 :code:`raystart--" -"head`。该命令将打印几行输出,其中一行说明如何将其他节点连接到头部节点。" +"在头部节点上启动 Ray:在终端上输入 :code:`raystart--head`。该命令将打印几行输" +"出,其中一行说明如何将其他节点连接到头部节点。" #: ../../source/how-to-run-simulations.rst:113 msgid "" -"Attach other nodes to the head node: copy the command shown after " -"starting the head and execute it on terminal of a new node: for example " -":code:`ray start --address='192.168.1.132:6379'`" +"Attach other nodes to the head node: copy the command shown after starting " +"the head and execute it on terminal of a new node: for example :code:`ray " +"start --address='192.168.1.132:6379'`" msgstr "" -"将其他节点附加到头部节点:复制启动头部后显示的命令,并在新节点的终端上执行:例如 :code:`ray start " -"--address='192.168.1.132:6379'`" +"将其他节点附加到头部节点:复制启动头部后显示的命令,并在新节点的终端上执行:" +"例如 :code:`ray start --address='192.168.1.132:6379'`" #: ../../source/how-to-run-simulations.rst:115 msgid "" "With all the above done, you can run your code from the head node as you " "would if the simulation was running on a single node." -msgstr "完成上述所有操作后,您就可以在头部节点上运行代码了,就像在单个节点上运行模拟一样。" +msgstr "" +"完成上述所有操作后,您就可以在头部节点上运行代码了,就像在单个节点上运行模拟" +"一样。" #: ../../source/how-to-run-simulations.rst:117 msgid "" -"Once your simulation is finished, if you'd like to dismantle your cluster" -" you simply need to run the command :code:`ray stop` in each node's " -"terminal (including the head node)." -msgstr "模拟结束后,如果要拆除集群,只需在每个节点(包括头部节点)的终端运行 :code:`ray stop` 命令即可。" +"Once your simulation is finished, if you'd like to dismantle your cluster " +"you simply need to run the command :code:`ray stop` in each node's terminal " +"(including the head node)." +msgstr "" +"模拟结束后,如果要拆除集群,只需在每个节点(包括头部节点)的终端运行 :code:" +"`ray stop` 命令即可。" #: ../../source/how-to-run-simulations.rst:120 msgid "Multi-node simulation good-to-know" @@ -6061,28 +6355,27 @@ msgstr "在此,我们列举了运行多节点 FL 模拟时的一些有趣功 #: ../../source/how-to-run-simulations.rst:124 msgid "" -"User :code:`ray status` to check all nodes connected to your head node as" -" well as the total resources available to the " -":code:`VirtualClientEngine`." +"User :code:`ray status` to check all nodes connected to your head node as " +"well as the total resources available to the :code:`VirtualClientEngine`." msgstr "" -"使用 :code:`ray status` 查看连接到头部节点的所有节点,以及 :code:`VirtualClientEngine` " -"可用的总资源。" +"使用 :code:`ray status` 查看连接到头部节点的所有节点,以及 :code:" +"`VirtualClientEngine` 可用的总资源。" #: ../../source/how-to-run-simulations.rst:126 msgid "" -"When attaching a new node to the head, all its resources (i.e. all CPUs, " -"all GPUs) will be visible by the head node. This means that the " -":code:`VirtualClientEngine` can schedule as many `virtual` clients as " -"that node can possible run. In some settings you might want to exclude " -"certain resources from the simulation. You can do this by appending " -"`--num-cpus=` and/or `--num-" -"gpus=` in any :code:`ray start` command (including " -"when starting the head)" +"When attaching a new node to the head, all its resources (i.e. all CPUs, all " +"GPUs) will be visible by the head node. This means that the :code:" +"`VirtualClientEngine` can schedule as many `virtual` clients as that node " +"can possible run. In some settings you might want to exclude certain " +"resources from the simulation. You can do this by appending `--num-" +"cpus=` and/or `--num-gpus=` in any :" +"code:`ray start` command (including when starting the head)" msgstr "" -"将新节点附加到头部节点时,头部节点将可见其所有资源(即所有 CPU 和 GPU)。这意味着 :code:`VirtualClientEngine`" -" 可以调度尽可能多的 \"虚拟 \"客户端来运行该节点。在某些设置中,您可能希望将某些资源排除在模拟之外。为此,您可以在任何 :code:`ray" -" start` 命令(包括启动头部时)中添加 `--num-cpus=`和/或 `--num-" -"gpus=`" +"将新节点附加到头部节点时,头部节点将可见其所有资源(即所有 CPU 和 GPU)。这意" +"味着 :code:`VirtualClientEngine` 可以调度尽可能多的 \"虚拟 \"客户端来运行该节" +"点。在某些设置中,您可能希望将某些资源排除在模拟之外。为此,您可以在任何 :" +"code:`ray start` 命令(包括启动头部时)中添加 `--num-" +"cpus=`和/或 `--num-gpus=`" #: ../../source/how-to-run-simulations.rst:132 msgid "Considerations for simulations" @@ -6090,23 +6383,26 @@ msgstr "模拟的注意事项" #: ../../source/how-to-run-simulations.rst:135 msgid "" -"We are actively working on these fronts so to make it trivial to run any " -"FL workload with Flower simulation." -msgstr "我们正在积极开展这些方面的工作,以便使 FL 工作负载与 Flower 模拟的运行变得轻而易举。" +"We are actively working on these fronts so to make it trivial to run any FL " +"workload with Flower simulation." +msgstr "" +"我们正在积极开展这些方面的工作,以便使 FL 工作负载与 Flower 模拟的运行变得轻" +"而易举。" #: ../../source/how-to-run-simulations.rst:138 msgid "" -"The current VCE allows you to run Federated Learning workloads in " -"simulation mode whether you are prototyping simple scenarios on your " -"personal laptop or you want to train a complex FL pipeline across " -"multiple high-performance GPU nodes. While we add more capabilities to " -"the VCE, the points below highlight some of the considerations to keep in" -" mind when designing your FL pipeline with Flower. We also highlight a " -"couple of current limitations in our implementation." +"The current VCE allows you to run Federated Learning workloads in simulation " +"mode whether you are prototyping simple scenarios on your personal laptop or " +"you want to train a complex FL pipeline across multiple high-performance GPU " +"nodes. While we add more capabilities to the VCE, the points below highlight " +"some of the considerations to keep in mind when designing your FL pipeline " +"with Flower. We also highlight a couple of current limitations in our " +"implementation." msgstr "" -"当前的 VCE 允许您在模拟模式下运行联邦学习工作负载,无论您是在个人笔记本电脑上建立简单的场景原型,还是要在多个高性能 GPU 节点上训练复杂的" -" FL情景。虽然我们为 VCE 增加了更多的功能,但以下几点强调了在使用 Flower 设计 FL " -"时需要注意的一些事项。我们还强调了我们的实现中目前存在的一些局限性。" +"当前的 VCE 允许您在模拟模式下运行联邦学习工作负载,无论您是在个人笔记本电脑上" +"建立简单的场景原型,还是要在多个高性能 GPU 节点上训练复杂的 FL情景。虽然我们" +"为 VCE 增加了更多的功能,但以下几点强调了在使用 Flower 设计 FL 时需要注意的一" +"些事项。我们还强调了我们的实现中目前存在的一些局限性。" #: ../../source/how-to-run-simulations.rst:141 msgid "GPU resources" @@ -6114,28 +6410,29 @@ msgstr "GPU 资源" #: ../../source/how-to-run-simulations.rst:143 msgid "" -"The VCE assigns a share of GPU memory to a client that specifies the key " -":code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " +"The VCE assigns a share of GPU memory to a client that specifies the key :" +"code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " "internally by the VCE) is by default:" msgstr "" -"VCE 会为指定 :code:`client_resources` 中 :code:`num_gpus` 关键字的客户端分配 GPU " -"内存份额。也就是说,Ray(VCE 内部使用)是默认的:" +"VCE 会为指定 :code:`client_resources` 中 :code:`num_gpus` 关键字的客户端分配 " +"GPU 内存份额。也就是说,Ray(VCE 内部使用)是默认的:" #: ../../source/how-to-run-simulations.rst:146 msgid "" -"not aware of the total VRAM available on the GPUs. This means that if you" -" set :code:`num_gpus=0.5` and you have two GPUs in your system with " -"different (e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients" -" concurrently." +"not aware of the total VRAM available on the GPUs. This means that if you " +"set :code:`num_gpus=0.5` and you have two GPUs in your system with different " +"(e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients concurrently." msgstr "" -"不知道 GPU 上可用的总 VRAM。这意味着,如果您设置 :code:`num_gpus=0.5`,而系统中有两个不同(如 32GB 和 " -"8GB)VRAM 的 GPU,它们都将同时运行 2 个客户端。" +"不知道 GPU 上可用的总 VRAM。这意味着,如果您设置 :code:`num_gpus=0.5`,而系统" +"中有两个不同(如 32GB 和 8GB)VRAM 的 GPU,它们都将同时运行 2 个客户端。" #: ../../source/how-to-run-simulations.rst:147 msgid "" "not aware of other unrelated (i.e. not created by the VCE) workloads are " "running on the GPU. Two takeaways from this are:" -msgstr "不知道 GPU 上正在运行其他无关(即不是由 VCE 创建)的工作负载。从中可以得到以下两点启示:" +msgstr "" +"不知道 GPU 上正在运行其他无关(即不是由 VCE 创建)的工作负载。从中可以得到以" +"下两点启示:" #: ../../source/how-to-run-simulations.rst:149 msgid "" @@ -6143,28 +6440,27 @@ msgid "" "aggregation (by instance when making use of the `evaluate method `_)" msgstr "" -"您的 Flower 服务器可能需要 GPU 来评估聚合后的 \"全局模型\"(例如在使用 \"评估方法\"`_时)" +"您的 Flower 服务器可能需要 GPU 来评估聚合后的 \"全局模型\"(例如在使用 \"评估" +"方法\"`_时)" #: ../../source/how-to-run-simulations.rst:150 msgid "" "If you want to run several independent Flower simulations on the same " -"machine you need to mask-out your GPUs with " -":code:`CUDA_VISIBLE_DEVICES=\"\"` when launching your " -"experiment." +"machine you need to mask-out your GPUs with :code:" +"`CUDA_VISIBLE_DEVICES=\"\"` when launching your experiment." msgstr "" -"如果您想在同一台机器上运行多个独立的 Flower 模拟,则需要在启动实验时使用 " -":code:`CUDA_VISIBLE_DEVICES=\"\"` 屏蔽 GPU。" +"如果您想在同一台机器上运行多个独立的 Flower 模拟,则需要在启动实验时使用 :" +"code:`CUDA_VISIBLE_DEVICES=\"\"` 屏蔽 GPU。" #: ../../source/how-to-run-simulations.rst:153 msgid "" -"In addition, the GPU resource limits passed to :code:`client_resources` " -"are not `enforced` (i.e. they can be exceeded) which can result in the " -"situation of client using more VRAM than the ratio specified when " -"starting the simulation." +"In addition, the GPU resource limits passed to :code:`client_resources` are " +"not `enforced` (i.e. they can be exceeded) which can result in the situation " +"of client using more VRAM than the ratio specified when starting the " +"simulation." msgstr "" -"此外,传递给 :code:`client_resources` 的 GPU 资源限制并不是 \"强制 \"的(即可以超出),这可能导致客户端使用的" -" VRAM 超过启动模拟时指定的比例。" +"此外,传递给 :code:`client_resources` 的 GPU 资源限制并不是 \"强制 \"的(即可" +"以超出),这可能导致客户端使用的 VRAM 超过启动模拟时指定的比例。" #: ../../source/how-to-run-simulations.rst:156 msgid "TensorFlow with GPUs" @@ -6172,42 +6468,40 @@ msgstr "使用 GPU 的 TensorFlow" #: ../../source/how-to-run-simulations.rst:158 msgid "" -"When `using a GPU with TensorFlow " -"`_ nearly your entire GPU memory of" -" all your GPUs visible to the process will be mapped. This is done by " -"TensorFlow for optimization purposes. However, in settings such as FL " -"simulations where we want to split the GPU into multiple `virtual` " -"clients, this is not a desirable mechanism. Luckily we can disable this " -"default behavior by `enabling memory growth " -"`_." +"When `using a GPU with TensorFlow `_ " +"nearly your entire GPU memory of all your GPUs visible to the process will " +"be mapped. This is done by TensorFlow for optimization purposes. However, in " +"settings such as FL simulations where we want to split the GPU into multiple " +"`virtual` clients, this is not a desirable mechanism. Luckily we can disable " +"this default behavior by `enabling memory growth `_." msgstr "" -"在 TensorFlow `_ 中使用 GPU 时,几乎所有进程可见的" -" GPU 内存都将被映射。TensorFlow 这样做是出于优化目的。然而,在 FL 模拟等设置中,我们希望将 GPU 分割成多个 \"虚拟 " -"\"客户端,这并不是一个理想的机制。幸运的是,我们可以通过 `启用内存增长 " -"`_来禁用这一默认行为。" +"在 TensorFlow `_ 中使用 GPU 时,几乎所" +"有进程可见的 GPU 内存都将被映射。TensorFlow 这样做是出于优化目的。然而,在 " +"FL 模拟等设置中,我们希望将 GPU 分割成多个 \"虚拟 \"客户端,这并不是一个理想" +"的机制。幸运的是,我们可以通过 `启用内存增长 `_来禁用这一默认行为。" #: ../../source/how-to-run-simulations.rst:160 msgid "" -"This would need to be done in the main process (which is where the server" -" would run) and in each Actor created by the VCE. By means of " -":code:`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` " -"in order to specify a function to be executed upon actor initialization. " -"In this case, to enable GPU growth for TF workloads. It would look as " -"follows:" +"This would need to be done in the main process (which is where the server " +"would run) and in each Actor created by the VCE. By means of :code:" +"`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` in order " +"to specify a function to be executed upon actor initialization. In this " +"case, to enable GPU growth for TF workloads. It would look as follows:" msgstr "" -"这需要在主进程(也就是服务器运行的地方)和 VCE 创建的每个角色中完成。通过 " -":code:`actor_kwargs`,我们可以传递保留关键字`\"on_actor_init_fn\"`,以指定在角色初始化时执行的函数。在本例中,为了使" -" TF 工作负载的 GPU 增长,它看起来如下:" +"这需要在主进程(也就是服务器运行的地方)和 VCE 创建的每个角色中完成。通过 :" +"code:`actor_kwargs`,我们可以传递保留关键字`\"on_actor_init_fn\"`,以指定在角" +"色初始化时执行的函数。在本例中,为了使 TF 工作负载的 GPU 增长,它看起来如下:" #: ../../source/how-to-run-simulations.rst:179 msgid "" "This is precisely the mechanism used in `Tensorflow/Keras Simulation " -"`_ example." +"`_ " +"example." msgstr "" -"这正是 \"Tensorflow/Keras 模拟 " -"`_\"示例中使用的机制。" +"这正是 \"Tensorflow/Keras 模拟 `_\"示例中使用的机制。" #: ../../source/how-to-run-simulations.rst:183 msgid "Multi-node setups" @@ -6215,35 +6509,35 @@ msgstr "多节点设置" #: ../../source/how-to-run-simulations.rst:185 msgid "" -"The VCE does not currently offer a way to control on which node a " -"particular `virtual` client is executed. In other words, if more than a " -"single node have the resources needed by a client to run, then any of " -"those nodes could get the client workload scheduled onto. Later in the FL" -" process (i.e. in a different round) the same client could be executed by" -" a different node. Depending on how your clients access their datasets, " -"this might require either having a copy of all dataset partitions on all " -"nodes or a dataset serving mechanism (e.g. using nfs, a database) to " -"circumvent data duplication." -msgstr "" -"VCE 目前不提供控制特定 \"虚拟 " -"\"客户端在哪个节点上执行的方法。换句话说,如果不止一个节点拥有客户端运行所需的资源,那么这些节点中的任何一个都可能被调度到客户端工作负载上。在 " -"FL " -"进程的稍后阶段(即在另一轮中),同一客户端可以由不同的节点执行。根据客户访问数据集的方式,这可能需要在所有节点上复制所有数据集分区,或采用数据集服务机制(如使用" -" nfs 或数据库)来避免数据重复。" +"The VCE does not currently offer a way to control on which node a particular " +"`virtual` client is executed. In other words, if more than a single node " +"have the resources needed by a client to run, then any of those nodes could " +"get the client workload scheduled onto. Later in the FL process (i.e. in a " +"different round) the same client could be executed by a different node. " +"Depending on how your clients access their datasets, this might require " +"either having a copy of all dataset partitions on all nodes or a dataset " +"serving mechanism (e.g. using nfs, a database) to circumvent data " +"duplication." +msgstr "" +"VCE 目前不提供控制特定 \"虚拟 \"客户端在哪个节点上执行的方法。换句话说,如果" +"不止一个节点拥有客户端运行所需的资源,那么这些节点中的任何一个都可能被调度到" +"客户端工作负载上。在 FL 进程的稍后阶段(即在另一轮中),同一客户端可以由不同" +"的节点执行。根据客户访问数据集的方式,这可能需要在所有节点上复制所有数据集分" +"区,或采用数据集服务机制(如使用 nfs 或数据库)来避免数据重复。" #: ../../source/how-to-run-simulations.rst:187 msgid "" -"By definition virtual clients are `stateless` due to their ephemeral " -"nature. A client state can be implemented as part of the Flower client " -"class but users need to ensure this saved to persistent storage (e.g. a " -"database, disk) and that can be retrieve later by the same client " -"regardless on which node it is running from. This is related to the point" -" above also since, in some way, the client's dataset could be seen as a " -"type of `state`." +"By definition virtual clients are `stateless` due to their ephemeral nature. " +"A client state can be implemented as part of the Flower client class but " +"users need to ensure this saved to persistent storage (e.g. a database, " +"disk) and that can be retrieve later by the same client regardless on which " +"node it is running from. This is related to the point above also since, in " +"some way, the client's dataset could be seen as a type of `state`." msgstr "" -"根据定义,虚拟客户端是 \"无状态 \"的,因为它们具有即时性。客户机状态可以作为 Flower " -"客户机类的一部分来实现,但用户需要确保将其保存到持久存储(如数据库、磁盘)中,而且无论客户机在哪个节点上运行,都能在以后检索到。这也与上述观点有关,因为在某种程度上,客户端的数据集可以被视为一种" -" \"状态\"。" +"根据定义,虚拟客户端是 \"无状态 \"的,因为它们具有即时性。客户机状态可以作为 " +"Flower 客户机类的一部分来实现,但用户需要确保将其保存到持久存储(如数据库、磁" +"盘)中,而且无论客户机在哪个节点上运行,都能在以后检索到。这也与上述观点有" +"关,因为在某种程度上,客户端的数据集可以被视为一种 \"状态\"。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:2 msgid "Save and load model checkpoints" @@ -6251,10 +6545,12 @@ msgstr "保存和加载模型检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:4 msgid "" -"Flower does not automatically save model updates on the server-side. This" -" how-to guide describes the steps to save (and load) model checkpoints in" -" Flower." -msgstr "Flower 不会在服务器端自动保存模型更新。本指南将介绍在 Flower 中保存(和加载)模型检查点的步骤。" +"Flower does not automatically save model updates on the server-side. This " +"how-to guide describes the steps to save (and load) model checkpoints in " +"Flower." +msgstr "" +"Flower 不会在服务器端自动保存模型更新。本指南将介绍在 Flower 中保存(和加载)" +"模型检查点的步骤。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:8 msgid "Model checkpointing" @@ -6262,22 +6558,22 @@ msgstr "模型检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:10 msgid "" -"Model updates can be persisted on the server-side by customizing " -":code:`Strategy` methods. Implementing custom strategies is always an " -"option, but for many cases it may be more convenient to simply customize " -"an existing strategy. The following code example defines a new " -":code:`SaveModelStrategy` which customized the existing built-in " -":code:`FedAvg` strategy. In particular, it customizes " -":code:`aggregate_fit` by calling :code:`aggregate_fit` in the base class " -"(:code:`FedAvg`). It then continues to save returned (aggregated) weights" -" before it returns those aggregated weights to the caller (i.e., the " -"server):" -msgstr "" -"模型更新可通过自定义 :code:`Strategy` " -"方法在服务器端持久化。实现自定义策略始终是一种选择,但在许多情况下,简单地自定义现有策略可能更方便。下面的代码示例定义了一个新的 " -":code:`SaveModelStrategy`,它自定义了现有的内置 :code:`FedAvg` " -"策略。特别是,它通过调用基类(:code:`FedAvg`)中的 :code:`aggregate_fit` 来定制 " -":code:`aggregate_fit`。然后继续保存返回的(聚合)参数,然后再将这些聚合参数返回给调用者(即服务器):" +"Model updates can be persisted on the server-side by customizing :code:" +"`Strategy` methods. Implementing custom strategies is always an option, but " +"for many cases it may be more convenient to simply customize an existing " +"strategy. The following code example defines a new :code:`SaveModelStrategy` " +"which customized the existing built-in :code:`FedAvg` strategy. In " +"particular, it customizes :code:`aggregate_fit` by calling :code:" +"`aggregate_fit` in the base class (:code:`FedAvg`). It then continues to " +"save returned (aggregated) weights before it returns those aggregated " +"weights to the caller (i.e., the server):" +msgstr "" +"模型更新可通过自定义 :code:`Strategy` 方法在服务器端持久化。实现自定义策略始" +"终是一种选择,但在许多情况下,简单地自定义现有策略可能更方便。下面的代码示例" +"定义了一个新的 :code:`SaveModelStrategy`,它自定义了现有的内置 :code:" +"`FedAvg` 策略。特别是,它通过调用基类(:code:`FedAvg`)中的 :code:" +"`aggregate_fit` 来定制 :code:`aggregate_fit`。然后继续保存返回的(聚合)参" +"数,然后再将这些聚合参数返回给调用者(即服务器):" #: ../../source/how-to-save-and-load-model-checkpoints.rst:47 msgid "Save and load PyTorch checkpoints" @@ -6285,29 +6581,32 @@ msgstr "保存和加载 PyTorch 检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:49 msgid "" -"Similar to the previous example but with a few extra steps, we'll show " -"how to store a PyTorch checkpoint we'll use the ``torch.save`` function. " -"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be" -" transformed into a list of NumPy ``ndarray``'s, then those are " -"transformed into the PyTorch ``state_dict`` following the ``OrderedDict``" -" class structure." +"Similar to the previous example but with a few extra steps, we'll show how " +"to store a PyTorch checkpoint we'll use the ``torch.save`` function. " +"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be " +"transformed into a list of NumPy ``ndarray``'s, then those are transformed " +"into the PyTorch ``state_dict`` following the ``OrderedDict`` class " +"structure." msgstr "" -"与前面的例子类似,但多了几个步骤,我们将展示如何存储一个 PyTorch 检查点,我们将使用 ``torch.save`` " -"函数。首先,``aggregate_fit`` 返回一个 ``Parameters`` 对象,它必须被转换成一个 NumPy " -"``ndarray`` 的列表,然后这些对象按照 ``OrderedDict`` 类结构被转换成 PyTorch `state_dict` 对象。" +"与前面的例子类似,但多了几个步骤,我们将展示如何存储一个 PyTorch 检查点,我们" +"将使用 ``torch.save`` 函数。首先,``aggregate_fit`` 返回一个 ``Parameters`` " +"对象,它必须被转换成一个 NumPy ``ndarray`` 的列表,然后这些对象按照 " +"``OrderedDict`` 类结构被转换成 PyTorch `state_dict` 对象。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:85 msgid "" -"To load your progress, you simply append the following lines to your " -"code. Note that this will iterate over all saved checkpoints and load the" -" latest one:" -msgstr "要加载进度,只需在代码中添加以下几行。请注意,这将遍历所有已保存的检查点,并加载最新的检查点:" +"To load your progress, you simply append the following lines to your code. " +"Note that this will iterate over all saved checkpoints and load the latest " +"one:" +msgstr "" +"要加载进度,只需在代码中添加以下几行。请注意,这将遍历所有已保存的检查点,并" +"加载最新的检查点:" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 #, fuzzy msgid "" -"Return/use this object of type ``Parameters`` wherever necessary, such as" -" in the ``initial_parameters`` when defining a ``Strategy``." +"Return/use this object of type ``Parameters`` wherever necessary, such as in " +"the ``initial_parameters`` when defining a ``Strategy``." msgstr "" "在必要时返回/使用此 ``Parameters`` 类型的对象,例如在定义 ``Strategy` 时的 " "``initial_parameters` 中。" @@ -6318,13 +6617,14 @@ msgstr "升级至 Flower 1.0" #: ../../source/how-to-upgrade-to-flower-1.0.rst:4 msgid "" -"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable" -" foundation for future growth. Compared to Flower 0.19 (and other 0.x " -"series releases), there are a few breaking changes that make it necessary" -" to change the code of existing 0.x-series projects." +"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable " +"foundation for future growth. Compared to Flower 0.19 (and other 0.x series " +"releases), there are a few breaking changes that make it necessary to change " +"the code of existing 0.x-series projects." msgstr "" -"Flower 1.0 正式发布。除了新功能,Flower 1.0 还为未来的发展奠定了稳定的基础。与 Flower 0.19(以及其他 0.x " -"系列版本)相比,有一些破坏性改动需要修改现有 0.x 系列项目的代码。" +"Flower 1.0 正式发布。除了新功能,Flower 1.0 还为未来的发展奠定了稳定的基础。" +"与 Flower 0.19(以及其他 0.x 系列版本)相比,有一些破坏性改动需要修改现有 0." +"x 系列项目的代码。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 msgid "Install update" @@ -6332,8 +6632,8 @@ msgstr "安装更新" #: ../../source/how-to-upgrade-to-flower-1.0.rst:10 msgid "" -"Here's how to update an existing installation to Flower 1.0 using either " -"pip or Poetry:" +"Here's how to update an existing installation to Flower 1.0 using either pip " +"or Poetry:" msgstr "下面介绍如何使用 pip 或 Poetry 将现有安装更新到 Flower 1.0:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:12 @@ -6344,13 +6644,15 @@ msgstr "pip: 安装时添加 ``-U``." msgid "" "``python -m pip install -U flwr`` (when using ``start_server`` and " "``start_client``)" -msgstr "`python -m pip install -U flwr``(当使用`start_server`和`start_client`时)" +msgstr "" +"`python -m pip install -U flwr``(当使用`start_server`和`start_client`时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:15 msgid "" "``python -m pip install -U flwr[simulation]`` (when using " "``start_simulation``)" -msgstr "`python -m pip install -U flwr[simulation]``(当使用`start_simulation``时)" +msgstr "" +"`python -m pip install -U flwr[simulation]``(当使用`start_simulation``时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:17 msgid "" @@ -6358,20 +6660,21 @@ msgid "" "reinstall (don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` " "before running ``poetry install``)." msgstr "" -"Poetry:更新 ``pyproject.toml`` 中的 ``flwr`` 依赖包,然后重新安装(运行 ``poetry install``" -" 前,别忘了通过 ``rm poetry.lock` 删除 ``poetry.lock`)。" +"Poetry:更新 ``pyproject.toml`` 中的 ``flwr`` 依赖包,然后重新安装(运行 " +"``poetry install`` 前,别忘了通过 ``rm poetry.lock` 删除 ``poetry.lock`)。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:19 -msgid "``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" +msgid "" +"``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" msgstr "``flwr = \"^1.0.0\"`` (当使用 ``start_server` 和 ``start_client` 时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:20 msgid "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when " -"using ``start_simulation``)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when using " +"``start_simulation``)" msgstr "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] " -"}``(当使用``start_simulation``时)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }``(当使用" +"``start_simulation``时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 msgid "Required changes" @@ -6395,13 +6698,13 @@ msgstr "将所有参数作为关键字参数传递(而不是位置参数)。 msgid "" "Flower 0.19 (positional arguments): ``start_client(\"127.0.0.1:8080\", " "FlowerClient())``" -msgstr "Flower 0.19 (位置参数): ``start_client(\"127.0.0.1:8080\", FlowerClient())``" +msgstr "" +"Flower 0.19 (位置参数): ``start_client(\"127.0.0.1:8080\", FlowerClient())``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:34 msgid "" "Flower 1.0 (keyword arguments): " -"``start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())``" +"``start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())``" msgstr "" "Flower 1.0(关键字参数): ``start_client(server_address=\"127.0.0.1:8080\", " "client=FlowerClient())``" @@ -6419,8 +6722,8 @@ msgid "" "Subclasses of ``Client``: change ``def get_parameters(self):``` to ``def " "get_parameters(self, ins: GetParametersIns):``" msgstr "" -"客户端 \"的子类:将 \"get_parameters(self): \"改为 \"get_parameters(self, ins: " -"GetParametersIns):\"" +"客户端 \"的子类:将 \"get_parameters(self): \"改为 \"get_parameters(self, " +"ins: GetParametersIns):\"" #: ../../source/how-to-upgrade-to-flower-1.0.rst:43 msgid "Strategies / ``start_server`` / ``start_simulation``" @@ -6444,29 +6747,30 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:48 msgid "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" msgstr "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:50 msgid "" "Replace ``num_rounds=1`` in ``start_simulation`` with the new " "``config=ServerConfig(...)`` (see previous item)" -msgstr "将`start_simulation``中的`num_rounds=1``替换为新的`config=ServerConfig(...)`(参见前一项)" +msgstr "" +"将`start_simulation``中的`num_rounds=1``替换为新的`config=ServerConfig(...)`" +"(参见前一项)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:51 msgid "" "Remove ``force_final_distributed_eval`` parameter from calls to " -"``start_server``. Distributed evaluation on all clients can be enabled by" -" configuring the strategy to sample all clients for evaluation after the " -"last round of training." +"``start_server``. Distributed evaluation on all clients can be enabled by " +"configuring the strategy to sample all clients for evaluation after the last " +"round of training." msgstr "" -"删除调用 ``start_server`` 时的 ``force_final_distributed_eval` " -"参数。可以通过配置策略,在最后一轮训练后对所有客户端进行抽样评估,从而启用对所有客户端的分布式评估。" +"删除调用 ``start_server`` 时的 ``force_final_distributed_eval` 参数。可以通过" +"配置策略,在最后一轮训练后对所有客户端进行抽样评估,从而启用对所有客户端的分" +"布式评估。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:52 msgid "Rename parameter/ndarray conversion functions:" @@ -6482,17 +6786,18 @@ msgstr "``weights_to_parameters`` --> ``ndarrays_to_parameters``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:57 msgid "" -"Strategy initialization: if the strategy relies on the default values for" -" ``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " +"Strategy initialization: if the strategy relies on the default values for " +"``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " "``fraction_evaluate`` manually to ``0.1``. Projects that do not manually " "create a strategy (by calling ``start_server`` or ``start_simulation`` " -"without passing a strategy instance) should now manually initialize " -"FedAvg with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." +"without passing a strategy instance) should now manually initialize FedAvg " +"with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." msgstr "" -"策略初始化:如果策略依赖于 ``fraction_fit`` 和 ``fraction_evaluate`` 的默认值,请手动将 " -"``fraction_fit`` 和 ``fraction_evaluate`` 设置为 ``0.1``。未手动创建策略的项目(调用 " -"``start_server` 或 ``start_simulation` 时未传递策略实例)现在应手动初始化 FedAvg,并将 " -"`fraction_fit` 和 `fraction_evaluate` 设为 `0.1``。" +"策略初始化:如果策略依赖于 ``fraction_fit`` 和 ``fraction_evaluate`` 的默认" +"值,请手动将 ``fraction_fit`` 和 ``fraction_evaluate`` 设置为 ``0.1``。未手动" +"创建策略的项目(调用 ``start_server` 或 ``start_simulation` 时未传递策略实" +"例)现在应手动初始化 FedAvg,并将 `fraction_fit` 和 `fraction_evaluate` 设为 " +"`0.1``。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:58 msgid "Rename built-in strategy parameters (e.g., ``FedAvg``):" @@ -6517,8 +6822,8 @@ msgid "" "``configure_evaluate``, ``aggregate_evaluate``, and ``evaluate_fn``." msgstr "" "将 `rnd` 更名为 `server_round`。这会影响多个方法和函数,例如 " -"``configure_fit``、``aggregate_fit``、``configure_evaluate``、`aggregate_evaluate``" -" 和 ``evaluate_fn``。" +"``configure_fit``、``aggregate_fit``、``configure_evaluate``、" +"`aggregate_evaluate`` 和 ``evaluate_fn``。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:65 msgid "Add ``server_round`` and ``config`` to ``evaluate_fn``:" @@ -6526,21 +6831,19 @@ msgstr "在 ``evaluate_fn` 中添加 ``server_round` 和 ``config`:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:67 msgid "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " -"Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " +"Dict[str, Scalar]]]:``" msgstr "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " -"Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " +"Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:68 msgid "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " -"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " -"Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " +"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " -"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " -"Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " +"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:71 msgid "Custom strategies" @@ -6548,22 +6851,23 @@ msgstr "定制策略" #: ../../source/how-to-upgrade-to-flower-1.0.rst:73 msgid "" -"The type of parameter ``failures`` has changed from " -"``List[BaseException]`` to ``List[Union[Tuple[ClientProxy, FitRes], " -"BaseException]]`` (in ``aggregate_fit``) and " -"``List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]]`` (in " -"``aggregate_evaluate``)" +"The type of parameter ``failures`` has changed from ``List[BaseException]`` " +"to ``List[Union[Tuple[ClientProxy, FitRes], BaseException]]`` (in " +"``aggregate_fit``) and ``List[Union[Tuple[ClientProxy, EvaluateRes], " +"BaseException]]`` (in ``aggregate_evaluate``)" msgstr "" -"参数``failures``的类型已从``List[BaseException]``变为``List[Union[Tuple[ClientProxy," -" FitRes], " -"BaseException]]``(在``agregate_fit``中)和``List[Union[Tuple[ClientProxy, " -"EvaluateRes], BaseException]]``(在``agregate_evaluate``中)" +"参数``failures``的类型已从``List[BaseException]``变为" +"``List[Union[Tuple[ClientProxy, FitRes], BaseException]]``(在" +"``agregate_fit``中)和``List[Union[Tuple[ClientProxy, EvaluateRes], " +"BaseException]]``(在``agregate_evaluate``中)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:74 msgid "" "The ``Strategy`` method ``evaluate`` now receives the current round of " "federated learning/evaluation as the first parameter:" -msgstr "``Strategy``方法 的``evaluate``现在会接收当前一轮联邦学习/评估作为第一个参数:" +msgstr "" +"``Strategy``方法 的``evaluate``现在会接收当前一轮联邦学习/评估作为第一个参" +"数:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:76 msgid "" @@ -6575,11 +6879,11 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:77 msgid "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " -"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" +"> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " -"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" +"> Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:80 msgid "Optional improvements" @@ -6594,12 +6898,11 @@ msgstr "除了上述必要的改动之外,还有一些潜在的改进措施: #: ../../source/how-to-upgrade-to-flower-1.0.rst:84 msgid "" "Remove \"placeholder\" methods from subclasses of ``Client`` or " -"``NumPyClient``. If you, for example, use server-side evaluation, then " -"empty placeholder implementations of ``evaluate`` are no longer " -"necessary." +"``NumPyClient``. If you, for example, use server-side evaluation, then empty " +"placeholder implementations of ``evaluate`` are no longer necessary." msgstr "" -"删除 ``Client`` 或 ``NumPyClient`` 子类中的 \"占位符 " -"\"方法。例如,如果你使用服务器端评估,那么就不再需要``evaluate``的 \"空占位符 \"实现。" +"删除 ``Client`` 或 ``NumPyClient`` 子类中的 \"占位符 \"方法。例如,如果你使用" +"服务器端评估,那么就不再需要``evaluate``的 \"空占位符 \"实现。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:85 msgid "" @@ -6607,9 +6910,8 @@ msgid "" "``start_simulation(..., config=flwr.server.ServerConfig(num_rounds=3, " "round_timeout=600.0), ...)``" msgstr "" -"通过 ``start_simulation`` 配置循环超时: ``start_simulation(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"通过 ``start_simulation`` 配置循环超时: ``start_simulation(..., config=flwr." +"server.ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 msgid "Further help" @@ -6617,15 +6919,16 @@ msgstr "更多帮助" #: ../../source/how-to-upgrade-to-flower-1.0.rst:91 msgid "" -"Most official `Flower code examples " -"`_ are already updated" -" to Flower 1.0, they can serve as a reference for using the Flower 1.0 " -"API. If there are further questions, `join the Flower Slack " -"`_ and use the channel ``#questions``." +"Most official `Flower code examples `_ are already updated to Flower 1.0, they can serve as a " +"reference for using the Flower 1.0 API. If there are further questions, " +"`join the Flower Slack `_ and use the channel " +"``#questions``." msgstr "" -"大多数官方的 `Flower 代码示例 `_" -" 已经更新到 Flower 1.0,它们可以作为使用 Flower 1.0 API 的参考。如果还有其他问题,请加入 Flower Slack " -"`_ 并使用 \"#questions``\"。" +"大多数官方的 `Flower 代码示例 `_ 已经更新到 Flower 1.0,它们可以作为使用 Flower 1.0 API 的参考。如" +"果还有其他问题,请加入 Flower Slack `_ 并使用 " +"\"#questions``\"。" #: ../../source/how-to-use-built-in-mods.rst:2 #, fuzzy @@ -6635,21 +6938,20 @@ msgstr "使用内置调制器" #: ../../source/how-to-use-built-in-mods.rst:4 #, fuzzy msgid "" -"**Note: This tutorial covers experimental features. The functionality and" -" interfaces may change in future versions.**" +"**Note: This tutorial covers experimental features. The functionality and " +"interfaces may change in future versions.**" msgstr "**注:本教程涵盖实验性功能。功能和界面可能会在未来版本中发生变化。" #: ../../source/how-to-use-built-in-mods.rst:6 #, fuzzy msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment " -"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " -"allow us to perform operations before and after a task is processed in " -"the ``ClientApp``." +"In this tutorial, we will learn how to utilize built-in mods to augment the " +"behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) allow us " +"to perform operations before and after a task is processed in the " +"``ClientApp``." msgstr "" -"在本教程中,我们将学习如何利用内置模块来增强 ``ClientApp`` " -"的行为。修改器(有时也称为修改器)允许我们在 ``ClientApp`` " -"处理任务之前和之后执行操作。" +"在本教程中,我们将学习如何利用内置模块来增强 ``ClientApp`` 的行为。修改器(有" +"时也称为修改器)允许我们在 ``ClientApp`` 处理任务之前和之后执行操作。" #: ../../source/how-to-use-built-in-mods.rst:9 #, fuzzy @@ -6659,9 +6961,9 @@ msgstr "什么是 Mods?" #: ../../source/how-to-use-built-in-mods.rst:11 #, fuzzy msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " -"or inspect the incoming ``Message`` and the resulting outgoing " -"``Message``. The signature for a ``Mod`` is as follows:" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate or " +"inspect the incoming ``Message`` and the resulting outgoing ``Message``. The " +"signature for a ``Mod`` is as follows:" msgstr "" "Mod 是包裹在 ``ClientApp`` 周围的可调用程序。它可以操作或检查传入的 " "``Message`` 和由此产生的传出的 ``Message`` 。一个 ``Mod`` 的签名如下:" @@ -6713,8 +7015,9 @@ msgstr "3. 用模块创建 ``ClientApp``" msgid "" "Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " "argument. The order in which you provide the mods matters:" -msgstr "创建您的 ``ClientApp`` 并将 mods 作为列表传递给 ``mods`` 参数。提供 mod " -"的顺序很重要:" +msgstr "" +"创建您的 ``ClientApp`` 并将 mods 作为列表传递给 ``mods`` 参数。提供 mod 的顺" +"序很重要:" #: ../../source/how-to-use-built-in-mods.rst:72 #, fuzzy @@ -6758,21 +7061,22 @@ msgstr "``example_mod_1`` (返回途中最外层的模式)" #: ../../source/how-to-use-built-in-mods.rst:82 #, fuzzy msgid "" -"Each mod has a chance to inspect and modify the incoming ``Message`` " -"before passing it to the next mod, and likewise with the outgoing " -"``Message`` before returning it up the stack." -msgstr "每个模块都有机会检查和修改传入的 \"信息\",然后再将其传递给下一个模块,同样," +"Each mod has a chance to inspect and modify the incoming ``Message`` before " +"passing it to the next mod, and likewise with the outgoing ``Message`` " +"before returning it up the stack." +msgstr "" +"每个模块都有机会检查和修改传入的 \"信息\",然后再将其传递给下一个模块,同样," "也有机会检查和修改传出的 \"信息\",然后再将其返回堆栈。" #: ../../source/how-to-use-built-in-mods.rst:87 #, fuzzy msgid "" "By following this guide, you have learned how to effectively use mods to " -"enhance your ``ClientApp``'s functionality. Remember that the order of " -"mods is crucial and affects how the input and output are processed." +"enhance your ``ClientApp``'s functionality. Remember that the order of mods " +"is crucial and affects how the input and output are processed." msgstr "" -"通过本指南,您已学会如何有效地使用 mod 来增强您的 ``ClientApp`` " -"的功能。请记住,mod 的顺序至关重要,它会影响输入和输出的处理方式。" +"通过本指南,您已学会如何有效地使用 mod 来增强您的 ``ClientApp`` 的功能。请记" +"住,mod 的顺序至关重要,它会影响输入和输出的处理方式。" #: ../../source/how-to-use-built-in-mods.rst:89 #, fuzzy @@ -6787,20 +7091,20 @@ msgstr "差分隐私" #: ../../source/how-to-use-differential-privacy.rst:3 #, fuzzy msgid "" -"This guide explains how you can utilize differential privacy in the " -"Flower framework. If you are not yet familiar with differential privacy, " -"you can refer to :doc:`explanation-differential-privacy`." +"This guide explains how you can utilize differential privacy in the Flower " +"framework. If you are not yet familiar with differential privacy, you can " +"refer to :doc:`explanation-differential-privacy`." msgstr "" -"本指南解释了如何在 Flower 框架中使用差分隐私。如果您还不熟悉差分隐私," -"可以参考 :doc:`explanation-differential-privacy` 。" +"本指南解释了如何在 Flower 框架中使用差分隐私。如果您还不熟悉差分隐私,可以参" +"考 :doc:`explanation-differential-privacy` 。" #: ../../source/how-to-use-differential-privacy.rst:7 #, fuzzy msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " -"these features in a production environment with sensitive data, feel free" -" contact us to discuss your requirements and to receive guidance on how " -"to best use these features." +"these features in a production environment with sensitive data, feel free " +"contact us to discuss your requirements and to receive guidance on how to " +"best use these features." msgstr "" "Flower 中的差异隐私处于预览阶段。如果您计划在生产环境中使用这些敏感数据功能," "请随时联系我们,讨论您的需求,并获得如何最好地使用这些功能的指导。" @@ -6808,12 +7112,13 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:12 #, fuzzy msgid "" -"This approach consists of two seprate phases: clipping of the updates and" -" adding noise to the aggregated model. For the clipping phase, Flower " -"framework has made it possible to decide whether to perform clipping on " -"the server side or the client side." -msgstr "这种方法包括两个独立的阶段:对更新进行剪切和在聚合模型中添加噪声。在剪切阶段" -",Flower 框架可以决定是在服务器端还是在客户端执行剪切。" +"This approach consists of two seprate phases: clipping of the updates and " +"adding noise to the aggregated model. For the clipping phase, Flower " +"framework has made it possible to decide whether to perform clipping on the " +"server side or the client side." +msgstr "" +"这种方法包括两个独立的阶段:对更新进行剪切和在聚合模型中添加噪声。在剪切阶" +"段,Flower 框架可以决定是在服务器端还是在客户端执行剪切。" #: ../../source/how-to-use-differential-privacy.rst:15 #, fuzzy @@ -6821,21 +7126,22 @@ msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " "communication overhead for clipping values. However, it also has the " -"disadvantage of increasing the computational load on the server due to " -"the need to perform the clipping operation for all clients." +"disadvantage of increasing the computational load on the server due to the " +"need to perform the clipping operation for all clients." msgstr "" -"** 服务器端剪切**: 这种方法的优点是服务器可对所有客户端的更新执行统一的剪切" -",并减少剪切值的通信开销。不过,这种方法也有缺点,那就是需要为所有客户端执行" -"剪切操作,从而增加了服务器的计算负荷。" +"** 服务器端剪切**: 这种方法的优点是服务器可对所有客户端的更新执行统一的剪" +"切,并减少剪切值的通信开销。不过,这种方法也有缺点,那就是需要为所有客户端执" +"行剪切操作,从而增加了服务器的计算负荷。" #: ../../source/how-to-use-differential-privacy.rst:16 #, fuzzy msgid "" -"**Client-side Clipping**: This approach has the advantage of reducing the" -" computational overhead on the server. However, it also has the " -"disadvantage of lacking centralized control, as the server has less " -"control over the clipping process." -msgstr "**客户端剪切**: 这种方法的优点是可以减少服务器的计算开销。不过,它也有缺乏集" +"**Client-side Clipping**: This approach has the advantage of reducing the " +"computational overhead on the server. However, it also has the disadvantage " +"of lacking centralized control, as the server has less control over the " +"clipping process." +msgstr "" +"**客户端剪切**: 这种方法的优点是可以减少服务器的计算开销。不过,它也有缺乏集" "中控制的缺点,因为服务器对剪切过程的控制较少。" #: ../../source/how-to-use-differential-privacy.rst:21 @@ -6848,16 +7154,15 @@ msgstr "服务器端逻辑" msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " -"(for example, :code:`FedAvg`). The two wrapper classes are " -":code:`DifferentialPrivacyServerSideFixedClipping` and " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " -"adaptive clipping." +"(for example, :code:`FedAvg`). The two wrapper classes are :code:" +"`DifferentialPrivacyServerSideFixedClipping` and :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and adaptive " +"clipping." msgstr "" -"对于具有服务器端剪裁功能的中央 DP,有两个 :code:`Strategy` 类作为实际 " -":code:`Strategy` 实例(例如 :code:`FedAvg`)的包装器。这两个封装类分别是 " -":code:`DifferentialPrivacyServerSideFixedClipping` 和 " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` " -",用于固定剪辑和自适应剪辑。" +"对于具有服务器端剪裁功能的中央 DP,有两个 :code:`Strategy` 类作为实际 :code:" +"`Strategy` 实例(例如 :code:`FedAvg`)的包装器。这两个封装类分别是 :code:" +"`DifferentialPrivacyServerSideFixedClipping` 和 :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` ,用于固定剪辑和自适应剪辑。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -6867,16 +7172,15 @@ msgstr "服务器端逻辑" #: ../../source/how-to-use-differential-privacy.rst:31 #, fuzzy msgid "" -"The code sample below enables the :code:`FedAvg` strategy to use server-" -"side fixed clipping using the " -":code:`DifferentialPrivacyServerSideFixedClipping` wrapper class. The " -"same approach can be used with " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " +"The code sample below enables the :code:`FedAvg` strategy to use server-side " +"fixed clipping using the :code:`DifferentialPrivacyServerSideFixedClipping` " +"wrapper class. The same approach can be used with :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" -"下面的代码示例使用 :code:`DifferentialPrivacyServerSideFixedClipping` " -"封装类使 :code:`FedAvg` 策略使用服务器端固定剪辑。通过调整相应的输入参数," -"同样的方法也可用于 :code:`DifferentialPrivacyServerSideAdaptiveClipping`。" +"下面的代码示例使用 :code:`DifferentialPrivacyServerSideFixedClipping` 封装类" +"使 :code:`FedAvg` 策略使用服务器端固定剪辑。通过调整相应的输入参数,同样的方" +"法也可用于 :code:`DifferentialPrivacyServerSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:52 #, fuzzy @@ -6887,18 +7191,18 @@ msgstr "客户端逻辑" #, fuzzy msgid "" "For central DP with client-side clipping, the server sends the clipping " -"value to selected clients on each round. Clients can use existing Flower " -":code:`Mods` to perform the clipping. Two mods are available for fixed " -"and adaptive client-side clipping: :code:`fixedclipping_mod` and " -":code:`adaptiveclipping_mod` with corresponding server-side wrappers " -":code:`DifferentialPrivacyClientSideFixedClipping` and " -":code:`DifferentialPrivacyClientSideAdaptiveClipping`." -msgstr "" -"对于带有客户端剪裁功能的中央 DP,服务器会在每一轮向选定的客户端发送剪裁值。" -"客户端可以使用现有的 Flower :code:`Mods`来执行剪裁。有两种模式可用于固定和自" -"适应客户端剪辑::code:`fixedclipping_mod` 和 :code:`adaptiveclipping_mod`," -"以及相应的服务器端封装 :code:`DifferentialPrivacyClientSideFixedClipping` 和 " -":code:`DifferentialPrivacyClientSideAdaptiveClipping`。" +"value to selected clients on each round. Clients can use existing Flower :" +"code:`Mods` to perform the clipping. Two mods are available for fixed and " +"adaptive client-side clipping: :code:`fixedclipping_mod` and :code:" +"`adaptiveclipping_mod` with corresponding server-side wrappers :code:" +"`DifferentialPrivacyClientSideFixedClipping` and :code:" +"`DifferentialPrivacyClientSideAdaptiveClipping`." +msgstr "" +"对于带有客户端剪裁功能的中央 DP,服务器会在每一轮向选定的客户端发送剪裁值。客" +"户端可以使用现有的 Flower :code:`Mods`来执行剪裁。有两种模式可用于固定和自适" +"应客户端剪辑::code:`fixedclipping_mod` 和 :code:`adaptiveclipping_mod`,以及" +"相应的服务器端封装 :code:`DifferentialPrivacyClientSideFixedClipping` 和 :" +"code:`DifferentialPrivacyClientSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -6909,35 +7213,35 @@ msgstr "客户端逻辑" #, fuzzy msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " -"differential privacy with client-side fixed clipping using both the " -":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " -"the client, :code:`fixedclipping_mod`:" +"differential privacy with client-side fixed clipping using both the :code:" +"`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on the " +"client, :code:`fixedclipping_mod`:" msgstr "" -"下面的代码示例使用 :code:`DifferentialPrivacyClientSideFixedClipping` " -"封装类和客户端的 :code:`fixedclipping_mod` 使 :code:`FedAvg` " -"策略在客户端固定剪辑的情况下使用差分隐私:" +"下面的代码示例使用 :code:`DifferentialPrivacyClientSideFixedClipping` 封装类" +"和客户端的 :code:`fixedclipping_mod` 使 :code:`FedAvg` 策略在客户端固定剪辑的" +"情况下使用差分隐私:" #: ../../source/how-to-use-differential-privacy.rst:80 #, fuzzy msgid "" -"In addition to the server-side strategy wrapper, the :code:`ClientApp` " -"needs to configure the matching :code:`fixedclipping_mod` to perform the " -"client-side clipping:" +"In addition to the server-side strategy wrapper, the :code:`ClientApp` needs " +"to configure the matching :code:`fixedclipping_mod` to perform the client-" +"side clipping:" msgstr "" -"除了服务器端策略包装器外,:code:`ClientApp` 还需要配置匹配的 " -":code:`fixedclipping_mod` 以执行客户端剪切:" +"除了服务器端策略包装器外,:code:`ClientApp` 还需要配置匹配的 :code:" +"`fixedclipping_mod` 以执行客户端剪切:" #: ../../source/how-to-use-differential-privacy.rst:97 #, fuzzy msgid "" -"To utilize local differential privacy (DP) and add noise to the client " -"model parameters before transmitting them to the server in Flower, you " -"can use the `LocalDpMod`. The following hyperparameters need to be set: " -"clipping norm value, sensitivity, epsilon, and delta." +"To utilize local differential privacy (DP) and add noise to the client model " +"parameters before transmitting them to the server in Flower, you can use the " +"`LocalDpMod`. The following hyperparameters need to be set: clipping norm " +"value, sensitivity, epsilon, and delta." msgstr "" -"要利用本地差分隐私(DP)并在将客户端模型参数传输到 Flower " -"服务器之前为其添加噪声,可以使用 " -"`LocalDpMod`。需要设置以下超参数:剪切规范值、灵敏度、ε 和 delta。" +"要利用本地差分隐私(DP)并在将客户端模型参数传输到 Flower 服务器之前为其添加" +"噪声,可以使用 `LocalDpMod`。需要设置以下超参数:剪切规范值、灵敏度、ε 和 " +"delta。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -6952,11 +7256,11 @@ msgstr "下面的代码示例展示了如何使用 :code:`LocalDpMod`:" #: ../../source/how-to-use-differential-privacy.rst:122 #, fuzzy msgid "" -"Please note that the order of mods, especially those that modify " -"parameters, is important when using multiple modifiers. Typically, " -"differential privacy (DP) modifiers should be the last to operate on " -"parameters." -msgstr "请注意,在使用多个修改器时,修改器(尤其是修改参数的修改器)的顺序非常重要。" +"Please note that the order of mods, especially those that modify parameters, " +"is important when using multiple modifiers. Typically, differential privacy " +"(DP) modifiers should be the last to operate on parameters." +msgstr "" +"请注意,在使用多个修改器时,修改器(尤其是修改参数的修改器)的顺序非常重要。" "通常情况下,差分隐私 (DP) 修改器应最后对参数进行操作。" #: ../../source/how-to-use-differential-privacy.rst:125 @@ -6967,17 +7271,16 @@ msgstr "使用隐私引擎进行本地培训" #: ../../source/how-to-use-differential-privacy.rst:126 #, fuzzy msgid "" -"For ensuring data instance-level privacy during local model training on " -"the client side, consider leveraging privacy engines such as Opacus and " -"TensorFlow Privacy. For examples of using Flower with these engines, " -"please refer to the Flower examples directory (`Opacus " -"`_, `Tensorflow" -" Privacy `_)." +"For ensuring data instance-level privacy during local model training on the " +"client side, consider leveraging privacy engines such as Opacus and " +"TensorFlow Privacy. For examples of using Flower with these engines, please " +"refer to the Flower examples directory (`Opacus `_, `Tensorflow Privacy `_)." msgstr "" "要在客户端本地模型训练期间确保数据实例级隐私,可考虑利用 Opacus 和 " -"TensorFlow Privacy 等隐私引擎。有关将 Flower 与这些引擎结合使用的示例," -"请参阅 Flower 示例目录(`Opacus `_, `Tensorflow Privacy `_)。" @@ -6987,15 +7290,17 @@ msgstr "使用策略" #: ../../source/how-to-use-strategies.rst:4 msgid "" -"Flower allows full customization of the learning process through the " -":code:`Strategy` abstraction. A number of built-in strategies are " -"provided in the core framework." -msgstr "Flower 允许通过 :code:`Strategy` 抽象类对学习过程进行完全定制。核心框架中提供了许多内置策略。" +"Flower allows full customization of the learning process through the :code:" +"`Strategy` abstraction. A number of built-in strategies are provided in the " +"core framework." +msgstr "" +"Flower 允许通过 :code:`Strategy` 抽象类对学习过程进行完全定制。核心框架中提供" +"了许多内置策略。" #: ../../source/how-to-use-strategies.rst:6 msgid "" -"There are three ways to customize the way Flower orchestrates the " -"learning process on the server side:" +"There are three ways to customize the way Flower orchestrates the learning " +"process on the server side:" msgstr "有三种方法可以自定义 Flower 在服务器端协调学习过程的方式:" #: ../../source/how-to-use-strategies.rst:8 @@ -7018,23 +7323,27 @@ msgstr "使用现有策略" #: ../../source/how-to-use-strategies.rst:16 msgid "" -"Flower comes with a number of popular federated learning strategies " -"built-in. A built-in strategy can be instantiated as follows:" +"Flower comes with a number of popular federated learning strategies built-" +"in. A built-in strategy can be instantiated as follows:" msgstr "Flower 内置了许多流行的联邦学习策略。内置策略的实例化方法如下:" #: ../../source/how-to-use-strategies.rst:25 msgid "" -"This creates a strategy with all parameters left at their default values " -"and passes it to the :code:`start_server` function. It is usually " -"recommended to adjust a few parameters during instantiation:" -msgstr "这会创建一个所有参数都保持默认值的策略,并将其传递给 :code:`start_server` 函数。通常建议在实例化过程中调整一些参数:" +"This creates a strategy with all parameters left at their default values and " +"passes it to the :code:`start_server` function. It is usually recommended to " +"adjust a few parameters during instantiation:" +msgstr "" +"这会创建一个所有参数都保持默认值的策略,并将其传递给 :code:`start_server` 函" +"数。通常建议在实例化过程中调整一些参数:" #: ../../source/how-to-use-strategies.rst:42 msgid "" "Existing strategies provide several ways to customize their behaviour. " "Callback functions allow strategies to call user-provided code during " "execution." -msgstr "现有的策略提供了多种自定义行为的方法。回调函数允许策略在执行过程中调用用户提供的代码。" +msgstr "" +"现有的策略提供了多种自定义行为的方法。回调函数允许策略在执行过程中调用用户提" +"供的代码。" #: ../../source/how-to-use-strategies.rst:45 msgid "Configuring client fit and client evaluate" @@ -7043,36 +7352,37 @@ msgstr "配置客户匹配和客户评估" #: ../../source/how-to-use-strategies.rst:47 msgid "" "The server can pass new configuration values to the client each round by " -"providing a function to :code:`on_fit_config_fn`. The provided function " -"will be called by the strategy and must return a dictionary of " -"configuration key values pairs that will be sent to the client. It must " -"return a dictionary of arbitrary configuration values :code:`client.fit`" -" and :code:`client.evaluate` functions during each round of federated " -"learning." +"providing a function to :code:`on_fit_config_fn`. The provided function will " +"be called by the strategy and must return a dictionary of configuration key " +"values pairs that will be sent to the client. It must return a dictionary of " +"arbitrary configuration values :code:`client.fit` and :code:`client." +"evaluate` functions during each round of federated learning." msgstr "" -"服务器可以通过向 :code:`on_fit_config_fn` " -"提供一个函数,在每一轮向客户端传递新的配置值。提供的函数将被策略调用,并且必须返回一个配置键值对的字典,该字典将被发送到客户端。在每一轮联邦学习期间,它必须返回一个任意配置值" -" dictionary :code:`client.fit`和 :code:`client.evaluate`函数。" +"服务器可以通过向 :code:`on_fit_config_fn` 提供一个函数,在每一轮向客户端传递" +"新的配置值。提供的函数将被策略调用,并且必须返回一个配置键值对的字典,该字典" +"将被发送到客户端。在每一轮联邦学习期间,它必须返回一个任意配置值 dictionary :" +"code:`client.fit`和 :code:`client.evaluate`函数。" #: ../../source/how-to-use-strategies.rst:75 msgid "" "The :code:`on_fit_config_fn` can be used to pass arbitrary configuration " "values from server to client, and poetentially change these values each " -"round, for example, to adjust the learning rate. The client will receive " -"the dictionary returned by the :code:`on_fit_config_fn` in its own " -":code:`client.fit()` function." +"round, for example, to adjust the learning rate. The client will receive the " +"dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client." +"fit()` function." msgstr "" -":code:`on_fit_config_fn`可用于将任意配置值从服务器传递到客户端,并在每一轮改变这些值,例如,调整学习率。客户端将在自己的 " -":code:`client.fit()` 函数中接收 :code:`on_fit_config_fn` 返回的字典。" +":code:`on_fit_config_fn`可用于将任意配置值从服务器传递到客户端,并在每一轮改" +"变这些值,例如,调整学习率。客户端将在自己的 :code:`client.fit()` 函数中接" +"收 :code:`on_fit_config_fn` 返回的字典。" #: ../../source/how-to-use-strategies.rst:78 msgid "" -"Similar to :code:`on_fit_config_fn`, there is also " -":code:`on_evaluate_config_fn` to customize the configuration sent to " -":code:`client.evaluate()`" +"Similar to :code:`on_fit_config_fn`, there is also :code:" +"`on_evaluate_config_fn` to customize the configuration sent to :code:`client." +"evaluate()`" msgstr "" -"与 :code:`on_fit_config_fn` 类似,还有 :code:`on_evaluate_config_fn` 用于定制发送到 " -":code:`client.evaluate()` 的配置" +"与 :code:`on_fit_config_fn` 类似,还有 :code:`on_evaluate_config_fn` 用于定制" +"发送到 :code:`client.evaluate()` 的配置" #: ../../source/how-to-use-strategies.rst:81 msgid "Configuring server-side evaluation" @@ -7080,18 +7390,18 @@ msgstr "配置服务器端评估" #: ../../source/how-to-use-strategies.rst:83 msgid "" -"Server-side evaluation can be enabled by passing an evaluation function " -"to :code:`evaluate_fn`." +"Server-side evaluation can be enabled by passing an evaluation function to :" +"code:`evaluate_fn`." msgstr "服务器端评估可通过向 :code:`evaluate_fn` 传递评估函数来启用。" #: ../../source/how-to-use-strategies.rst:89 msgid "" -"Writing a fully custom strategy is a bit more involved, but it provides " -"the most flexibility. Read the `Implementing Strategies `_ guide to learn more." +"Writing a fully custom strategy is a bit more involved, but it provides the " +"most flexibility. Read the `Implementing Strategies `_ guide to learn more." msgstr "" -"编写完全自定义的策略涉及的内容较多,但灵活性最高。阅读 `实施策略 _ " -"指南,了解更多信息。" +"编写完全自定义的策略涉及的内容较多,但灵活性最高。阅读 `实施策略 _ 指南,了解更多信息。" #: ../../source/index.rst:34 msgid "Tutorial" @@ -7151,7 +7461,9 @@ msgstr "Flower 框架文档" msgid "" "Welcome to Flower's documentation. `Flower `_ is a " "friendly federated learning framework." -msgstr "欢迎访问 Flower 文档。`Flower `_ 是一个友好的联邦学习框架。" +msgstr "" +"欢迎访问 Flower 文档。`Flower `_ 是一个友好的联邦学习框" +"架。" #: ../../source/index.rst:11 msgid "Join the Flower Community" @@ -7162,7 +7474,9 @@ msgid "" "The Flower Community is growing quickly - we're a friendly group of " "researchers, engineers, students, professionals, academics, and other " "enthusiasts." -msgstr "Flower 社区发展迅速--我们是一个由研究人员、工程师、学生、专业人士、学者和其他爱好者组成的友好团体。" +msgstr "" +"Flower 社区发展迅速--我们是一个由研究人员、工程师、学生、专业人士、学者和其他" +"爱好者组成的友好团体。" #: ../../source/index.rst:15 msgid "Join us on Slack" @@ -7176,11 +7490,12 @@ msgstr "Flower 框架" msgid "" "The user guide is targeted at researchers and developers who want to use " "Flower to bring existing machine learning workloads into a federated " -"setting. One of Flower's design goals was to make this simple. Read on to" -" learn more." +"setting. One of Flower's design goals was to make this simple. Read on to " +"learn more." msgstr "" -"该用户指南面向希望使用 Flower 将现有机器学习工作负载引入联邦环境的研究人员和开发人员。Flower " -"的设计目标之一就是让这一切变得简单。请继续阅读,了解更多信息。" +"该用户指南面向希望使用 Flower 将现有机器学习工作负载引入联邦环境的研究人员和" +"开发人员。Flower 的设计目标之一就是让这一切变得简单。请继续阅读,了解更多信" +"息。" #: ../../source/index.rst:30 msgid "Tutorials" @@ -7188,31 +7503,31 @@ msgstr "教程" #: ../../source/index.rst:32 msgid "" -"A learning-oriented series of federated learning tutorials, the best " -"place to start." +"A learning-oriented series of federated learning tutorials, the best place " +"to start." msgstr "以学习为导向的联邦学习教程系列,最好的起点。" #: ../../source/index.rst:62 msgid "" -"QUICKSTART TUTORIALS: :doc:`PyTorch ` | " -":doc:`TensorFlow ` | :doc:`🤗 Transformers" -" ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " -"` | :doc:`PyTorch Lightning ` | :doc:`MXNet `" -" | :doc:`scikit-learn ` | :doc:`XGBoost " -"` | :doc:`Android ` | :doc:`iOS `" -msgstr "" -"快速入门教程: :doc:`PyTorch ` | :doc:`TensorFlow " -"` | :doc:`🤗 Transformers ` | :doc:`JAX ` | " -":doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc" -":`scikit-learn ` | :doc:`XGBoost " -"` | :doc:`Android ` | :doc:`iOS `" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" +"`TensorFlow ` | :doc:`🤗 Transformers " +"` | :doc:`JAX ` | :" +"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc:`scikit-learn " +"` | :doc:`XGBoost ` | :doc:`Android ` | :doc:`iOS " +"`" +msgstr "" +"快速入门教程: :doc:`PyTorch ` | :doc:" +"`TensorFlow ` | :doc:`🤗 Transformers " +"` | :doc:`JAX ` | :" +"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc:`scikit-learn " +"` | :doc:`XGBoost ` | :doc:`Android ` | :doc:`iOS " +"`" #: ../../source/index.rst:64 msgid "We also made video tutorials for PyTorch:" @@ -7224,15 +7539,17 @@ msgstr "还有 TensorFlow:" #: ../../source/index.rst:77 msgid "" -"Problem-oriented how-to guides show step-by-step how to achieve a " -"specific goal." +"Problem-oriented how-to guides show step-by-step how to achieve a specific " +"goal." msgstr "以问题为导向的 \"如何做 \"指南逐步展示如何实现特定目标。" #: ../../source/index.rst:111 msgid "" "Understanding-oriented concept guides explain and discuss key topics and " "underlying ideas behind Flower and collaborative AI." -msgstr "以理解为导向的概念指南解释并讨论了Flower和协作式人工智能背后的关键主题和基本思想。" +msgstr "" +"以理解为导向的概念指南解释并讨论了Flower和协作式人工智能背后的关键主题和基本" +"思想。" #: ../../source/index.rst:121 msgid "References" @@ -7258,8 +7575,8 @@ msgstr "贡献者文档" #: ../../source/index.rst:151 msgid "" -"The Flower community welcomes contributions. The following docs are " -"intended to help along the way." +"The Flower community welcomes contributions. The following docs are intended " +"to help along the way." msgstr "Flower 社区欢迎您的贡献。以下文档旨在为您提供帮助。" #: ../../source/ref-api-cli.rst:2 @@ -7377,8 +7694,8 @@ msgstr "启动一个 Flower 客户节点,连接到 Flower 服务器。" #: ../../source/ref-api/flwr.client.rst:24::1 #, fuzzy msgid "" -":py:obj:`start_numpy_client `\\ \\(\\*\\," -" server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\, " +"server\\_address\\, client\\)" msgstr "" ":py:obj:`start_numpy_client `\\ \\(\\*\\, " "server\\_address\\, client\\)" @@ -7410,8 +7727,7 @@ msgstr "Flower 客户端的抽象基类。" #: ../../source/ref-api/flwr.client.rst:33::1 #, fuzzy msgid "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " -"mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" msgstr "" ":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" @@ -7542,8 +7858,9 @@ msgstr "评估客户端的反应。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #, fuzzy -msgid ":py:obj:`get_parameters `\\ \\(ins\\)" -msgstr "" +msgid "" +":py:obj:`get_parameters `\\ \\(ins\\)" +msgstr "" ":py:obj:`get_parameters `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 @@ -7555,7 +7872,8 @@ msgstr "返回当前本地模型参数。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #, fuzzy -msgid ":py:obj:`get_properties `\\ \\(ins\\)" +msgid "" +":py:obj:`get_properties `\\ \\(ins\\)" msgstr "" ":py:obj:`get_properties `\\ \\(ins\\)" @@ -7676,10 +7994,12 @@ msgstr "参数" #: flwr.client.client.Client.evaluate:3 of msgid "" -"The evaluation instructions containing (global) model parameters received" -" from the server and a dictionary of configuration values used to " -"customize the local evaluation process." -msgstr "评估指令包含从服务器接收的(全局)模型参数,以及用于定制本地评估流程的配置值字典。" +"The evaluation instructions containing (global) model parameters received " +"from the server and a dictionary of configuration values used to customize " +"the local evaluation process." +msgstr "" +"评估指令包含从服务器接收的(全局)模型参数,以及用于定制本地评估流程的配置值" +"字典。" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -7715,7 +8035,8 @@ msgstr "返回" msgid "" "The evaluation result containing the loss on the local dataset and other " "details such as the number of local data examples used for evaluation." -msgstr "评估结果包含本地数据集上的损失值和其他详细信息,如用于评估的本地数据的数量。" +msgstr "" +"评估结果包含本地数据集上的损失值和其他详细信息,如用于评估的本地数据的数量。" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -7747,15 +8068,17 @@ msgstr "返回类型" #: flwr.client.client.Client.fit:3 of msgid "" -"The training instructions containing (global) model parameters received " -"from the server and a dictionary of configuration values used to " -"customize the local training process." -msgstr "训练指令,包含从服务器接收的(全局)模型参数,以及用于定制本地训练过程的配置值字典。" +"The training instructions containing (global) model parameters received from " +"the server and a dictionary of configuration values used to customize the " +"local training process." +msgstr "" +"训练指令,包含从服务器接收的(全局)模型参数,以及用于定制本地训练过程的配置" +"值字典。" #: flwr.client.client.Client.fit:8 of msgid "" -"The training result containing updated parameters and other details such " -"as the number of local training examples used for training." +"The training result containing updated parameters and other details such as " +"the number of local training examples used for training." msgstr "训练结果包含更新的参数和其他详细信息,如用于训练的本地训练示例的数量。" #: flwr.client.client.Client.get_parameters:3 of @@ -7824,26 +8147,28 @@ msgstr "实例" msgid "" "Assuming a typical `Client` implementation named `FlowerClient`, you can " "wrap it in a `ClientApp` as follows:" -msgstr "假定有一个名为 `FlowerClient` 的典型 `Client` 实现,可以将其封装在一个 " +msgstr "" +"假定有一个名为 `FlowerClient` 的典型 `Client` 实现,可以将其封装在一个 " "`ClientApp` 中,如下所示:" #: flwr.client.client_app.ClientApp:16 of #, fuzzy msgid "" -"If the above code is in a Python module called `client`, it can be " -"started as follows:" -msgstr "如果上述代码位于一个名为 \"客户端 \"的 Python " -"模块中,则可以按如下方式启动它:" +"If the above code is in a Python module called `client`, it can be started " +"as follows:" +msgstr "" +"如果上述代码位于一个名为 \"客户端 \"的 Python 模块中,则可以按如下方式启动" +"它:" #: flwr.client.client_app.ClientApp:21 of #, fuzzy msgid "" -"In this `client:app` example, `client` refers to the Python module " -"`client.py` in which the previous code lives in and `app` refers to the " -"global attribute `app` that points to an object of type `ClientApp`." +"In this `client:app` example, `client` refers to the Python module `client." +"py` in which the previous code lives in and `app` refers to the global " +"attribute `app` that points to an object of type `ClientApp`." msgstr "" -"在这个 `client:app` 例子中,`client` 指的是前面代码所在的 Python 模块 `client" -".py`,而 `app` 指的是指向 `ClientApp` 类型对象的全局属性 `app` 。" +"在这个 `client:app` 例子中,`client` 指的是前面代码所在的 Python 模块 " +"`client.py`,而 `app` 指的是指向 `ClientApp` 类型对象的全局属性 `app` 。" #: flwr.client.client_app.ClientApp.evaluate:1::1 of #, fuzzy @@ -7893,7 +8218,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy -msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgid "" +":py:obj:`fit `\\ \\(parameters\\, config\\)" msgstr "" ":py:obj:`fit `\\ \\(parameters\\, config\\)" @@ -7913,8 +8239,8 @@ msgid "" ":py:obj:`get_parameters `\\ " "\\(config\\)" msgstr "" -":py:obj:`get_parameters `\\ \\(" -"config\\)" +":py:obj:`get_parameters `\\ " +"\\(config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy @@ -7922,8 +8248,8 @@ msgid "" ":py:obj:`get_properties `\\ " "\\(config\\)" msgstr "" -":py:obj:`get_properties `\\ \\(" -"config\\)" +":py:obj:`get_properties `\\ " +"\\(config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.get_properties:1 of @@ -7933,8 +8259,7 @@ msgstr "返回客户端的属性集。" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy msgid "" -":py:obj:`set_context `\\ " -"\\(context\\)" +":py:obj:`set_context `\\ \\(context\\)" msgstr "" ":py:obj:`set_context `\\ \\(context\\)" @@ -7965,28 +8290,30 @@ msgstr "当前(全局)模型参数。" #: flwr.client.numpy_client.NumPyClient.evaluate:5 of msgid "" -"Configuration parameters which allow the server to influence evaluation " -"on the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to influence the number of examples " -"used for evaluation." -msgstr "允许服务器影响客户端评估的配置参数。它可用于将任意值从服务器传送到客户端,例如,影响用于评估的示例数量。" +"Configuration parameters which allow the server to influence evaluation on " +"the client. It can be used to communicate arbitrary values from the server " +"to the client, for example, to influence the number of examples used for " +"evaluation." +msgstr "" +"允许服务器影响客户端评估的配置参数。它可用于将任意值从服务器传送到客户端,例" +"如,影响用于评估的示例数量。" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" "* **loss** (*float*) -- The evaluation loss of the model on the local " "dataset. * **num_examples** (*int*) -- The number of examples used for " "evaluation. * **metrics** (*Dict[str, Scalar]*) -- A dictionary mapping " -"arbitrary string keys to values of type bool, bytes, float, int, or " -"str. It can be used to communicate arbitrary values back to the server." +"arbitrary string keys to values of type bool, bytes, float, int, or str. " +"It can be used to communicate arbitrary values back to the server." msgstr "" -"**loss** (*float*) -- 模型在本地数据集上的评估损失值。**num_examples** (*int*) -- " -"用于评估的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 " -"bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" +"**loss** (*float*) -- 模型在本地数据集上的评估损失值。**num_examples** " +"(*int*) -- 用于评估的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字" +"符串键映射到 bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传" +"回服务器。" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" -"**loss** (*float*) -- The evaluation loss of the model on the local " -"dataset." +"**loss** (*float*) -- The evaluation loss of the model on the local dataset." msgstr "**loss** (*float*) -- 模型在本地数据集上的评估损失值。" #: flwr.client.numpy_client.NumPyClient.evaluate:12 of @@ -7996,41 +8323,43 @@ msgstr "**num_examples** (*int*) -- 用于评估的示例数量。" #: flwr.client.numpy_client.NumPyClient.evaluate:13 #: flwr.client.numpy_client.NumPyClient.fit:13 of msgid "" -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can be " -"used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" -"**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 bool、bytes、float、int 或 " -"str 类型值的字典。它可用于将任意值传回服务器。" +"**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 bool、bytes、" +"float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" #: flwr.client.numpy_client.NumPyClient.evaluate:19 of msgid "" -"The previous return type format (int, float, float) and the extended " -"format (int, float, float, Dict[str, Scalar]) have been deprecated and " -"removed since Flower 0.19." +"The previous return type format (int, float, float) and the extended format " +"(int, float, float, Dict[str, Scalar]) have been deprecated and removed " +"since Flower 0.19." msgstr "" -"自 Flower 0.19 起,之前的返回类型格式(int、float、float)和扩展格式(int、float、float、Dict[str," -" Scalar])已被弃用和移除。" +"自 Flower 0.19 起,之前的返回类型格式(int、float、float)和扩展格式(int、" +"float、float、Dict[str, Scalar])已被弃用和移除。" #: flwr.client.numpy_client.NumPyClient.fit:5 of msgid "" -"Configuration parameters which allow the server to influence training on " -"the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to set the number of (local) training " -"epochs." -msgstr "允许服务器影响客户端训练的配置参数。它可用于将任意值从服务器传送到客户端,例如设置(本地)训练遍历数。" +"Configuration parameters which allow the server to influence training on the " +"client. It can be used to communicate arbitrary values from the server to " +"the client, for example, to set the number of (local) training epochs." +msgstr "" +"允许服务器影响客户端训练的配置参数。它可用于将任意值从服务器传送到客户端,例" +"如设置(本地)训练遍历数。" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "" "* **parameters** (*NDArrays*) -- The locally updated model parameters. * " "**num_examples** (*int*) -- The number of examples used for training. * " -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can " -"be used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" -"**parameters** (*NDArrays*) -- 本地更新的模型参数。**num_examples** (*int*) -- " -"用于训练的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 " -"bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" +"**parameters** (*NDArrays*) -- 本地更新的模型参数。**num_examples** (*int*) " +"-- 用于训练的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映" +"射到 bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务" +"器。" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "**parameters** (*NDArrays*) -- The locally updated model parameters." @@ -8042,30 +8371,31 @@ msgstr "**num_examples** (*int*) -- 用于训练的数据数量。" #: flwr.client.numpy_client.NumPyClient.get_parameters:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which parameters are needed along with some Scalar " -"attributes." -msgstr "服务器请求的配置参数。这可以用来告诉客户端需要哪些参数以及一些标量属性。" +"Configuration parameters requested by the server. This can be used to tell " +"the client which parameters are needed along with some Scalar attributes." +msgstr "" +"服务器请求的配置参数。这可以用来告诉客户端需要哪些参数以及一些标量属性。" #: flwr.client.numpy_client.NumPyClient.get_parameters:8 of -msgid "**parameters** -- The local model parameters as a list of NumPy ndarrays." +msgid "" +"**parameters** -- The local model parameters as a list of NumPy ndarrays." msgstr "**parameters** -- NumPy ndarrays 的本地模型参数列表。" #: flwr.client.numpy_client.NumPyClient.get_properties:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which properties are needed along with some Scalar " -"attributes." -msgstr "服务器请求的配置参数。这可以用来告诉客户端需要哪些属性以及一些标量属性。" +"Configuration parameters requested by the server. This can be used to tell " +"the client which properties are needed along with some Scalar attributes." +msgstr "" +"服务器请求的配置参数。这可以用来告诉客户端需要哪些属性以及一些标量属性。" #: flwr.client.numpy_client.NumPyClient.get_properties:8 of msgid "" -"**properties** -- A dictionary mapping arbitrary string keys to values of" -" type bool, bytes, float, int, or str. It can be used to communicate " +"**properties** -- A dictionary mapping arbitrary string keys to values of " +"type bool, bytes, float, int, or str. It can be used to communicate " "arbitrary property values back to the server." msgstr "" -"**properties** -- 将任意字符串键映射到 bool、bytes、float、int 或 str " -"类型值的字典。它可用于将任意属性值传回服务器。" +"**properties** -- 将任意字符串键映射到 bool、bytes、float、int 或 str 类型值" +"的字典。它可用于将任意属性值传回服务器。" #: ../../source/ref-api/flwr.client.run_client_app.rst:2 #, fuzzy @@ -8080,8 +8410,7 @@ msgstr "启动客户端" #: flwr.client.app.start_client:3 flwr.client.app.start_numpy_client:9 of msgid "" "The IPv4 or IPv6 address of the server. If the Flower server runs on the " -"same machine on port 8080, then `server_address` would be " -"`\"[::]:8080\"`." +"same machine on port 8080, then `server_address` would be `\"[::]:8080\"`." msgstr "" "服务器的 IPv4 或 IPv6 地址:如果 Flower 服务器在同一台机器上运行,端口为 " "8080,则`server_address`应为`\"[::]:8080\"`。" @@ -8092,35 +8421,38 @@ msgstr "用于实例化客户端的可调用程序。(默认值:无)" #: flwr.client.app.start_client:9 of msgid "" -"An implementation of the abstract base class `flwr.client.Client` " -"(default: None)" +"An implementation of the abstract base class `flwr.client.Client` (default: " +"None)" msgstr "抽象基类 `flwr.client.Client` 的实现(默认值:无)" #: flwr.client.app.start_client:12 flwr.client.app.start_numpy_client:15 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" server. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower server needs to be started with the same value (see " -"`flwr.server.start_server`), otherwise it will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"server. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"server needs to be started with the same value (see `flwr.server." +"start_server`), otherwise it will not know about the increased limit and " +"block larger messages." msgstr "" -"可与 Flower 服务器交换的 gRPC 信息的最大长度:默认值对大多数模型都足够了。训练超大模型的用户可能需要增加该值。请注意,Flower " -"服务器需要以相同的值启动(请参阅 `flwr.server.start_server`),否则它将不知道增加的限制并阻止更大的消息。" +"可与 Flower 服务器交换的 gRPC 信息的最大长度:默认值对大多数模型都足够了。训" +"练超大模型的用户可能需要增加该值。请注意,Flower 服务器需要以相同的值启动(请" +"参阅 `flwr.server.start_server`),否则它将不知道增加的限制并阻止更大的消息。" #: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 #: flwr.server.compat.app.start_driver:21 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " -"provided, a secure connection using the certificates will be established " -"to an SSL-enabled Flower server." -msgstr "字节字符串或路径字符串形式的 PEM 编码根证书。如果提供,将使用这些证书与启用 SSL 的 Flower 服务器建立安全连接。" +"provided, a secure connection using the certificates will be established to " +"an SSL-enabled Flower server." +msgstr "" +"字节字符串或路径字符串形式的 PEM 编码根证书。如果提供,将使用这些证书与启用 " +"SSL 的 Flower 服务器建立安全连接。" #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of #, fuzzy msgid "" -"Starts an insecure gRPC connection when True. Enables HTTPS connection " -"when False, using system certificates if `root_certificates` is None." +"Starts an insecure gRPC connection when True. Enables HTTPS connection when " +"False, using system certificates if `root_certificates` is None." msgstr "" "为 True 时启动不安全的 gRPC 连接。False 时启用 HTTPS 连接,如果 " "`root_certificates` 为 None,则使用系统证书。" @@ -8128,28 +8460,30 @@ msgstr "" #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" "Configure the transport layer. Allowed values: - 'grpc-bidi': gRPC, " -"bidirectional streaming - 'grpc-rere': gRPC, request-response " -"(experimental) - 'rest': HTTP (experimental)" +"bidirectional streaming - 'grpc-rere': gRPC, request-response (experimental) " +"- 'rest': HTTP (experimental)" msgstr "" -"配置传输层:允许的值包括 - 'grpc-bidi': gRPC,双向流 - 'grpc-rere': gRPC,请求-响应(实验性) - " -"'rest': HTTP(实验性)" +"配置传输层:允许的值包括 - 'grpc-bidi': gRPC,双向流 - 'grpc-rere': gRPC,请" +"求-响应(实验性) - 'rest': HTTP(实验性)" #: flwr.client.app.start_client:31 of #, fuzzy msgid "" "The maximum number of times the client will try to connect to the server " -"before giving up in case of a connection error. If set to None, there is " -"no limit to the number of tries." -msgstr "客户端在出现连接错误时放弃连接服务器的最大尝试次数。如果设置为 \"无\"" -",则不限制尝试次数。" +"before giving up in case of a connection error. If set to None, there is no " +"limit to the number of tries." +msgstr "" +"客户端在出现连接错误时放弃连接服务器的最大尝试次数。如果设置为 \"无\",则不限" +"制尝试次数。" #: flwr.client.app.start_client:35 of #, fuzzy msgid "" -"The maximum duration before the client stops trying to connect to the " -"server in case of connection error. If set to None, there is no limit to " -"the total time." -msgstr "在出现连接错误时,客户端停止尝试连接服务器之前的最长持续时间。如果设置为 \"无" +"The maximum duration before the client stops trying to connect to the server " +"in case of connection error. If set to None, there is no limit to the total " +"time." +msgstr "" +"在出现连接错误时,客户端停止尝试连接服务器之前的最长持续时间。如果设置为 \"无" "\",则总时间没有限制。" #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of @@ -8174,14 +8508,13 @@ msgstr "start_numpy_client" #: flwr.client.app.start_numpy_client:5 of #, fuzzy msgid "" -"This function is deprecated since 1.7.0. Use " -":code:`flwr.client.start_client` instead and first convert your " -":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " -":code:`to_client()` method." +"This function is deprecated since 1.7.0. Use :code:`flwr.client." +"start_client` instead and first convert your :code:`NumPyClient` to type :" +"code:`flwr.client.Client` by executing its :code:`to_client()` method." msgstr "" -"自 1.7.0 起该函数已被弃用。请使用 :code:`flwr.client.start_client`," -"并首先通过执行 :code:`to_client()`方法将 :code:`NumPyClient`转换为 " -":code:`flwr.client.Client`。" +"自 1.7.0 起该函数已被弃用。请使用 :code:`flwr.client.start_client`,并首先通" +"过执行 :code:`to_client()`方法将 :code:`NumPyClient`转换为 :code:`flwr." +"client.Client`。" #: flwr.client.app.start_numpy_client:13 of msgid "An implementation of the abstract base class `flwr.client.NumPyClient`." @@ -8193,7 +8526,8 @@ msgstr "常见" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgid "" +":py:obj:`array_from_numpy `\\ \\(ndarray\\)" msgstr "" ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" @@ -8205,7 +8539,8 @@ msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgid "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" @@ -8220,8 +8555,8 @@ msgid "" ":py:obj:`configure `\\ \\(identifier\\[\\, " "filename\\, host\\]\\)" msgstr "" -":py:obj:`configure `\\ \\(identifier\\[\\, filename\\" -", host\\]\\)" +":py:obj:`configure `\\ \\(identifier\\[\\, " +"filename\\, host\\]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.logger.configure:1 of @@ -8234,8 +8569,8 @@ msgid "" ":py:obj:`event `\\ \\(event\\_type\\[\\, " "event\\_details\\]\\)" msgstr "" -":py:obj:`event `\\ \\(event\\_type\\[\\, event\\_details\\" -"]\\)" +":py:obj:`event `\\ \\(event\\_type\\[\\, " +"event\\_details\\]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.telemetry.event:1 of @@ -8249,8 +8584,8 @@ msgid "" ":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " "\\*\\*kwargs\\)" msgstr "" -":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, \\*\\*" -"kwargs\\)" +":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " +"\\*\\*kwargs\\)" #: ../../source/ref-api/flwr.common.rst:30::1 logging.Logger.log:1 #: of @@ -8259,7 +8594,8 @@ msgstr "以整数严重性 \"级别 \"记录 \"msg % args\"。" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgid "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" @@ -8284,8 +8620,8 @@ msgid "" ":py:obj:`ndarrays_to_parameters `\\ " "\\(ndarrays\\)" msgstr "" -":py:obj:`ndarrays_to_parameters `\\ \\(" -"ndarrays\\)" +":py:obj:`ndarrays_to_parameters `\\ " +"\\(ndarrays\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarrays_to_parameters:1 @@ -8301,8 +8637,8 @@ msgid "" ":py:obj:`parameters_to_ndarrays `\\ " "\\(parameters\\)" msgstr "" -":py:obj:`parameters_to_ndarrays `\\ \\(" -"parameters\\)" +":py:obj:`parameters_to_ndarrays `\\ " +"\\(parameters\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.parameters_to_ndarrays:1 of @@ -8312,8 +8648,7 @@ msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " -"data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" msgstr "" ":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" @@ -8329,8 +8664,8 @@ msgid "" ":py:obj:`ClientMessage `\\ " "\\(\\[get\\_properties\\_res\\, ...\\]\\)" msgstr "" -":py:obj:`ClientMessage `\\ \\(\\[get\\_properties" -"\\_res\\, ...\\]\\)" +":py:obj:`ClientMessage `\\ " +"\\(\\[get\\_properties\\_res\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ClientMessage:1 of @@ -8353,9 +8688,8 @@ msgid "" ":py:obj:`ConfigsRecord `\\ " "\\(\\[configs\\_dict\\, keep\\_input\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.configsrecord.ConfigsRecord:1 of @@ -8387,8 +8721,7 @@ msgstr "客户端向服务器发送 DisconnectRes 信息。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, " -"config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" msgstr "" ":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" @@ -8458,7 +8791,8 @@ msgstr "数据类,用于存储所发生错误的相关信息。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy -msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetParametersIns `\\ \\(config\\)" msgstr "" ":py:obj:`GetParametersIns `\\ \\(config\\)" @@ -8483,7 +8817,8 @@ msgstr "要求返回参数时的响应。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy -msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetPropertiesIns `\\ \\(config\\)" msgstr "" ":py:obj:`GetPropertiesIns `\\ \\(config\\)" @@ -8546,8 +8881,8 @@ msgstr "传统信息类型。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`Metadata `\\ \\(run\\_id\\, " -"message\\_id\\, src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " +"src\\_node\\_id\\, ...\\)" msgstr "" ":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " "src\\_node\\_id\\, ...\\)" @@ -8564,8 +8899,8 @@ msgid "" ":py:obj:`MetricsRecord `\\ " "\\(\\[metrics\\_dict\\, keep\\_input\\]\\)" msgstr "" -":py:obj:`MetricsRecord `\\ \\(\\[metrics\\_dict\\" -", keep\\_input\\]\\)" +":py:obj:`MetricsRecord `\\ " +"\\(\\[metrics\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.metricsrecord.MetricsRecord:1 of @@ -8581,11 +8916,11 @@ msgstr ":py:obj:`NDArray `\\" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " -":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" +"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " -":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" +"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy @@ -8593,8 +8928,8 @@ msgid "" ":py:obj:`Parameters `\\ \\(tensors\\, " "tensor\\_type\\)" msgstr "" -":py:obj:`Parameters `\\ \\(tensors\\, tensor\\_type\\" -")" +":py:obj:`Parameters `\\ \\(tensors\\, " +"tensor\\_type\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Parameters:1 of @@ -8607,8 +8942,8 @@ msgid "" ":py:obj:`ParametersRecord `\\ " "\\(\\[array\\_dict\\, keep\\_input\\]\\)" msgstr "" -":py:obj:`ParametersRecord `\\ \\(\\[" -"array\\_dict\\, keep\\_input\\]\\)" +":py:obj:`ParametersRecord `\\ " +"\\(\\[array\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.ParametersRecord:1 of @@ -8632,8 +8967,8 @@ msgid "" ":py:obj:`RecordSet `\\ " "\\(\\[parameters\\_records\\, ...\\]\\)" msgstr "" -":py:obj:`RecordSet `\\ \\(\\[parameters\\_records\\, " -"...\\]\\)" +":py:obj:`RecordSet `\\ " +"\\(\\[parameters\\_records\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.recordset.RecordSet:1 of @@ -8647,8 +8982,8 @@ msgid "" ":py:obj:`ServerMessage `\\ " "\\(\\[get\\_properties\\_ins\\, ...\\]\\)" msgstr "" -":py:obj:`ServerMessage `\\ \\(\\[get\\_properties" -"\\_ins\\, ...\\]\\)" +":py:obj:`ServerMessage `\\ " +"\\(\\[get\\_properties\\_ins\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ServerMessage:1 of @@ -8680,26 +9015,28 @@ msgstr "数据类,包含数组类或张量类对象的序列化数据以及相 #: flwr.common.record.parametersrecord.Array:6 of #, fuzzy msgid "" -"A string representing the data type of the serialised object (e.g. " -"`np.float32`)" +"A string representing the data type of the serialised object (e.g. `np." +"float32`)" msgstr "表示序列化对象数据类型的字符串(例如 `np.float32`)" #: flwr.common.record.parametersrecord.Array:8 of #, fuzzy msgid "" -"A list representing the shape of the unserialized array-like object. This" -" is used to deserialize the data (depending on the serialization method) " -"or simply as a metadata field." -msgstr "代表未序列化数组对象形状的列表。它可用于反序列化数据(取决于序列化方法),或" +"A list representing the shape of the unserialized array-like object. This is " +"used to deserialize the data (depending on the serialization method) or " +"simply as a metadata field." +msgstr "" +"代表未序列化数组对象形状的列表。它可用于反序列化数据(取决于序列化方法),或" "仅作为元数据字段使用。" #: flwr.common.record.parametersrecord.Array:12 of #, fuzzy msgid "" -"A string indicating the type of serialisation mechanism used to generate " -"the bytes in `data` from an array-like or tensor-like object." -msgstr "表示序列化机制类型的字符串,用于从类似数组或类似张量的对象中生成 `data` " -"中的字节。" +"A string indicating the type of serialisation mechanism used to generate the " +"bytes in `data` from an array-like or tensor-like object." +msgstr "" +"表示序列化机制类型的字符串,用于从类似数组或类似张量的对象中生成 `data` 中的" +"字节。" #: flwr.common.record.parametersrecord.Array:15 of #, fuzzy @@ -8755,16 +9092,14 @@ msgstr ":py:obj:`fit_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_parameters_res " -"`\\" +":py:obj:`get_parameters_res `\\" msgstr "" ":py:obj:`get_parameters_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_properties_res " -"`\\" +":py:obj:`get_properties_res `\\" msgstr "" ":py:obj:`get_properties_res `\\" @@ -8786,8 +9121,8 @@ msgstr ":py:obj:`OK `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" msgstr "" ":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" @@ -8795,8 +9130,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" msgstr "" ":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" @@ -8809,8 +9144,8 @@ msgstr ":py:obj:`FIT_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED " -"`\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" msgstr "" ":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" @@ -8823,20 +9158,19 @@ msgstr "配置日志记录" #: flwr.common.record.configsrecord.ConfigsRecord:1 of #, fuzzy msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`str`, :py:class:`bytes`, :py:class:`bool`, " -":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " -"[:py:class:`float`], :py:class:`~typing.List`\\ [:py:class:`str`], " -":py:class:`~typing.List`\\ [:py:class:`bytes`], " -":py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" +"class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing.List`\\ " +"[:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], :py:class:" +"`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ [:py:class:" +"`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" -", :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, " -":py:class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing." -"List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], " -":py:class:`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ " -"[:py:class:`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" +"class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing.List`\\ " +"[:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], :py:class:" +"`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ [:py:class:" +"`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -8891,7 +9225,8 @@ msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of #, fuzzy -msgid "If key is not found, d is returned if given, otherwise KeyError is raised." +msgid "" +"If key is not found, d is returned if given, otherwise KeyError is raised." msgstr "如果未找到 key,则返回 d(如果给定),否则引发 KeyError。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -8900,8 +9235,8 @@ msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" -":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" -")" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.update:1 of @@ -8927,12 +9262,11 @@ msgstr "背景" #: flwr.common.context.Context:3 of #, fuzzy msgid "" -"Holds records added by the entity in a given run and that will stay " -"local. This means that the data it holds will never leave the system it's" -" running from. This can be used as an intermediate storage or scratchpad " -"when executing mods. It can also be used as a memory to access at " -"different points during the lifecycle of this entity (e.g. across " -"multiple rounds)" +"Holds records added by the entity in a given run and that will stay local. " +"This means that the data it holds will never leave the system it's running " +"from. This can be used as an intermediate storage or scratchpad when " +"executing mods. It can also be used as a memory to access at different " +"points during the lifecycle of this entity (e.g. across multiple rounds)" msgstr "" "保存实体在给定运行中添加的记录,这些记录将保留在本地。这意味着它保存的数据永" "远不会离开运行的系统。在执行模式时,它可用作中间存储或抓取板。它还可以作为存" @@ -9045,81 +9379,79 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_CLIENT_ENTER `\\" +msgid "" +":py:obj:`START_CLIENT_ENTER `\\" msgstr "" ":py:obj:`START_CLIENT_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_CLIENT_LEAVE `\\" +msgid "" +":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" ":py:obj:`START_CLIENT_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_SERVER_ENTER `\\" +msgid "" +":py:obj:`START_SERVER_ENTER `\\" msgstr "" ":py:obj:`START_SERVER_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_SERVER_LEAVE `\\" +msgid "" +":py:obj:`START_SERVER_LEAVE `\\" msgstr "" ":py:obj:`START_SERVER_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_DRIVER_API_ENTER " -"`\\" +":py:obj:`RUN_DRIVER_API_ENTER `\\" msgstr "" ":py:obj:`RUN_DRIVER_API_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE " -"`\\" +":py:obj:`RUN_DRIVER_API_LEAVE `\\" msgstr "" ":py:obj:`RUN_DRIVER_API_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_FLEET_API_ENTER " -"`\\" +":py:obj:`RUN_FLEET_API_ENTER `\\" msgstr "" ":py:obj:`RUN_FLEET_API_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_FLEET_API_LEAVE " -"`\\" +":py:obj:`RUN_FLEET_API_LEAVE `\\" msgstr "" ":py:obj:`RUN_FLEET_API_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_SUPERLINK_ENTER " -"`\\" +":py:obj:`RUN_SUPERLINK_ENTER `\\" msgstr "" ":py:obj:`RUN_SUPERLINK_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE " -"`\\" +":py:obj:`RUN_SUPERLINK_LEAVE `\\" msgstr "" ":py:obj:`RUN_SUPERLINK_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`START_SIMULATION_ENTER " -"`\\" +":py:obj:`START_SIMULATION_ENTER `\\" msgstr "" ":py:obj:`START_SIMULATION_ENTER `\\" @@ -9127,8 +9459,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`START_SIMULATION_LEAVE " -"`\\" +":py:obj:`START_SIMULATION_LEAVE `\\" msgstr "" ":py:obj:`START_SIMULATION_LEAVE `\\" @@ -9141,49 +9473,48 @@ msgstr ":py:obj:`DRIVER_CONNECT `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid ":py:obj:`DRIVER_DISCONNECT `\\" -msgstr ":py:obj:`DRIVER_DISCONNECT `\\" +msgstr "" +":py:obj:`DRIVER_DISCONNECT `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_DRIVER_ENTER `\\" +msgid "" +":py:obj:`START_DRIVER_ENTER `\\" msgstr "" ":py:obj:`START_DRIVER_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy -msgid ":py:obj:`START_DRIVER_LEAVE `\\" +msgid "" +":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" ":py:obj:`START_DRIVER_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER " -"`\\" +":py:obj:`RUN_CLIENT_APP_ENTER `\\" msgstr "" ":py:obj:`RUN_CLIENT_APP_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE " -"`\\" +":py:obj:`RUN_CLIENT_APP_LEAVE `\\" msgstr "" ":py:obj:`RUN_CLIENT_APP_LEAVE `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_SERVER_APP_ENTER " -"`\\" +":py:obj:`RUN_SERVER_APP_ENTER `\\" msgstr "" ":py:obj:`RUN_SERVER_APP_ENTER `\\" #: ../../source/ref-api/flwr.common.EventType.rst:42::1 #, fuzzy msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE " -"`\\" +":py:obj:`RUN_SERVER_APP_LEAVE `\\" msgstr "" ":py:obj:`RUN_SERVER_APP_LEAVE `\\" @@ -9291,16 +9622,17 @@ msgstr "数据类型,包括要执行的信息的相关信息。" #: flwr.common.message.Message:5 of #, fuzzy msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side" -" logic to a client, or vice-versa) or that will be sent to it." -msgstr "保存由其他实体发送的记录(如由服务器端逻辑发送到客户端,反之亦然)或将发送到" +"Holds records either sent by another entity (e.g. sent by the server-side " +"logic to a client, or vice-versa) or that will be sent to it." +msgstr "" +"保存由其他实体发送的记录(如由服务器端逻辑发送到客户端,反之亦然)或将发送到" "该实体的记录。" #: flwr.common.message.Message:8 of #, fuzzy msgid "" -"A dataclass that captures information about an error that took place when" -" processing another message." +"A dataclass that captures information about an error that took place when " +"processing another message." msgstr "数据类,用于捕捉处理其他报文时发生的错误信息。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 @@ -9309,8 +9641,8 @@ msgid "" ":py:obj:`create_error_reply `\\ " "\\(error\\, ttl\\)" msgstr "" -":py:obj:`create_error_reply `\\ \\(" -"error\\, ttl\\)" +":py:obj:`create_error_reply `\\ " +"\\(error\\, ttl\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.create_error_reply:1 of @@ -9321,8 +9653,8 @@ msgstr "构建一条回复信息,说明发生了错误。" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #, fuzzy msgid "" -":py:obj:`create_reply `\\ \\(content\\," -" ttl\\)" +":py:obj:`create_reply `\\ \\(content\\, " +"ttl\\)" msgstr "" ":py:obj:`create_reply `\\ \\(content\\, " "ttl\\)" @@ -9397,9 +9729,9 @@ msgstr "该信息的有效时间。" #: flwr.common.message.Message.create_reply:3 of #, fuzzy msgid "" -"The method generates a new `Message` as a reply to this message. It " -"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " -"this message and sets 'reply_to_message' to the ID of this message." +"The method generates a new `Message` as a reply to this message. It inherits " +"'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from this message " +"and sets 'reply_to_message' to the ID of this message." msgstr "" "该方法会生成一条新的 \"信息\",作为对该信息的回复。该方法继承了该消息的 " "\"run_id\"、\"src_node_id\"、\"dst_node_id \"和 \"message_type\",并将 " @@ -9442,13 +9774,15 @@ msgstr "MessageTypeLegacy" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 #, fuzzy -msgid ":py:obj:`GET_PARAMETERS `\\" +msgid "" +":py:obj:`GET_PARAMETERS `\\" msgstr "" ":py:obj:`GET_PARAMETERS `\\" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 #, fuzzy -msgid ":py:obj:`GET_PROPERTIES `\\" +msgid "" +":py:obj:`GET_PROPERTIES `\\" msgstr "" ":py:obj:`GET_PROPERTIES `\\" @@ -9486,8 +9820,8 @@ msgstr "该信息回复的信息的标识符。" #: flwr.common.message.Metadata:13 of #, fuzzy msgid "" -"An identifier for grouping messages. In some settings, this is used as " -"the FL round." +"An identifier for grouping messages. In some settings, this is used as the " +"FL round." msgstr "用于分组报文的标识符。在某些设置中,它被用作 FL 轮。" #: flwr.common.Metadata.dst_node_id:1::1 @@ -9499,11 +9833,12 @@ msgstr "编码接收端要执行的操作的字符串。" #: flwr.common.message.Metadata:21 of #, fuzzy msgid "" -"An identifier that can be used when loading a particular data partition " -"for a ClientApp. Making use of this identifier is more relevant when " -"conducting simulations." -msgstr "为 ClientApp " -"加载特定数据分区时可使用的标识符。在进行模拟时,使用该标识符更有意义。" +"An identifier that can be used when loading a particular data partition for " +"a ClientApp. Making use of this identifier is more relevant when conducting " +"simulations." +msgstr "" +"为 ClientApp 加载特定数据分区时可使用的标识符。在进行模拟时,使用该标识符更有" +"意义。" #: flwr.common.Metadata.dst_node_id:1::1 of #, fuzzy @@ -9570,15 +9905,15 @@ msgstr "MetricsRecord" #: flwr.common.record.metricsrecord.MetricsRecord:1 of #, fuzzy msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`~typing.List`\\ [:py:class:`int`], " -":py:class:`~typing.List`\\ [:py:class:`float`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" +"class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:" +"class:`float`]]]" msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" -", :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, " -":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " -"[:py:class:`float`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" +"class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:" +"class:`float`]]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -9616,8 +9951,8 @@ msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" -":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" -")" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -9647,23 +9982,22 @@ msgstr "参数" #: flwr.common.record.parametersrecord.ParametersRecord:1 of #, fuzzy msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" -", :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" #: flwr.common.record.parametersrecord.ParametersRecord:3 of #, fuzzy msgid "" -"A dataclass storing named Arrays in order. This means that it holds " -"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " -"viewed as an equivalent to PyTorch's state_dict, but holding serialised " -"tensors instead." +"A dataclass storing named Arrays in order. This means that it holds entries " +"as an OrderedDict[str, Array]. ParametersRecord objects can be viewed as an " +"equivalent to PyTorch's state_dict, but holding serialised tensors instead." msgstr "" -"按顺序存储命名数组的数据类。这意味着它以 OrderedDict[str, Array] " -"的形式保存条目。ParametersRecord 对象相当于 PyTorch 的 " -"state_dict,但它保存的是序列化的张量。" +"按顺序存储命名数组的数据类。这意味着它以 OrderedDict[str, Array] 的形式保存条" +"目。ParametersRecord 对象相当于 PyTorch 的 state_dict,但它保存的是序列化的张" +"量。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -9672,7 +10006,8 @@ msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid ":py:obj:`count_bytes `\\ \\(\\)" +msgid "" +":py:obj:`count_bytes `\\ \\(\\)" msgstr "" ":py:obj:`count_bytes `\\ \\(\\)" @@ -9702,8 +10037,8 @@ msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" -":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*" -"F\\)" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -9713,11 +10048,12 @@ msgstr ":py:obj:`values `\\ \\(\\)" #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of #, fuzzy msgid "" -"Note that a small amount of Bytes might also be included in this counting" -" that correspond to metadata of the serialized object (e.g. of NumPy " -"array) needed for deseralization." -msgstr "请注意,该计数中还可能包含少量字节,这些字节与序列化对象(如 NumPy " -"数组)的元数据相对应,需要进行去eralization。" +"Note that a small amount of Bytes might also be included in this counting " +"that correspond to metadata of the serialized object (e.g. of NumPy array) " +"needed for deseralization." +msgstr "" +"请注意,该计数中还可能包含少量字节,这些字节与序列化对象(如 NumPy 数组)的元" +"数据相对应,需要进行去eralization。" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 #, fuzzy @@ -9758,7 +10094,8 @@ msgstr "保存 MetricsRecord 实例的字典。" #: flwr.common.RecordSet.configs_records:1::1 of #, fuzzy -msgid ":py:obj:`parameters_records `\\" +msgid "" +":py:obj:`parameters_records `\\" msgstr "" ":py:obj:`parameters_records `\\" @@ -9786,16 +10123,14 @@ msgstr ":py:obj:`fit_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_parameters_ins " -"`\\" +":py:obj:`get_parameters_ins `\\" msgstr "" ":py:obj:`get_parameters_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_properties_ins " -"`\\" +":py:obj:`get_properties_ins `\\" msgstr "" ":py:obj:`get_properties_ins `\\" @@ -9841,14 +10176,15 @@ msgstr "登录" #: logging.Logger.log:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a " -"true value, e.g." +"To pass exception information, use the keyword argument exc_info with a true " +"value, e.g." msgstr "要传递异常信息,请使用带 true 值的关键字参数 exc_info,例如。" #: logging.Logger.log:6 of #, python-format msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" -msgstr "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" +msgstr "" +"logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" #: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 #, fuzzy @@ -9964,9 +10300,8 @@ msgid "" ":py:obj:`Driver `\\ " "\\(\\[driver\\_service\\_address\\, ...\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.driver.driver.Driver:1 of @@ -9991,8 +10326,8 @@ msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" msgstr "" -":py:obj:`LegacyContext `\\ \\(state\\[\\, config\\" -", strategy\\, ...\\]\\)" +":py:obj:`LegacyContext `\\ \\(state\\[\\, " +"config\\, strategy\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of @@ -10025,12 +10360,11 @@ msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:41::1 #, fuzzy msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," -" round\\_timeout\\]\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\, " +"round\\_timeout\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/ref-api/flwr.server.rst:41::1 #: flwr.server.server_config.ServerConfig:1 of @@ -10040,7 +10374,8 @@ msgstr "Flower 服务器。" #: ../../source/ref-api/flwr.server.rst:41::1 #, fuzzy -msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +msgid "" +":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" ":py:obj:`SimpleClientManager `\\ \\(\\)" @@ -10091,7 +10426,8 @@ msgstr "返回所有可用客户。" #: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy -msgid ":py:obj:`num_available `\\ \\(\\)" +msgid "" +":py:obj:`num_available `\\ \\(\\)" msgstr "" ":py:obj:`num_available `\\ \\(\\)" @@ -10119,8 +10455,8 @@ msgstr "注册 Flower ClientProxy 实例。" #: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`sample `\\ \\(num\\_clients\\[\\, " +"min\\_num\\_clients\\, criterion\\]\\)" msgstr "" ":py:obj:`sample `\\ \\(num\\_clients\\[\\, " "min\\_num\\_clients\\, criterion\\]\\)" @@ -10135,7 +10471,8 @@ msgstr "取样若干 Flower ClientProxy 实例。" #: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy -msgid ":py:obj:`unregister `\\ \\(client\\)" +msgid "" +":py:obj:`unregister `\\ \\(client\\)" msgstr "" ":py:obj:`unregister `\\ \\(client\\)" @@ -10153,8 +10490,8 @@ msgid "" ":py:obj:`wait_for `\\ " "\\(num\\_clients\\, timeout\\)" msgstr "" -":py:obj:`wait_for `\\ \\(num\\_clients\\" -", timeout\\)" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\, timeout\\)" #: flwr.server.client_manager.ClientManager.all:1::1 #: flwr.server.client_manager.ClientManager.wait_for:1 @@ -10175,9 +10512,9 @@ msgstr "**num_available** -- 当前可用客户端的数量。" #, fuzzy msgid "" "**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any " -"reason." -msgstr "**success** -- 表示注册是否成功。如果 ClientProxy 已注册或因故无法注册,则为 " +"ClientProxy is already registered or can not be registered for any reason." +msgstr "" +"**success** -- 表示注册是否成功。如果 ClientProxy 已注册或因故无法注册,则为 " "False。" #: flwr.server.client_manager.ClientManager.unregister:3 @@ -10200,20 +10537,22 @@ msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" #: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order: * CA certificate. * " -"server certificate. * server private key." +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order: * CA certificate. * server " +"certificate. * server private key." msgstr "" -"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以下顺序包含三个字节元素: * CA 证书,* 服务器证书, * " -"服务器私钥。" +"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以" +"下顺序包含三个字节元素: * CA 证书,* 服务器证书, * 服务器私钥。" #: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order:" -msgstr "包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以下顺序包含三个字节元素:" +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order:" +msgstr "" +"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以" +"下顺序包含三个字节元素:" #: flwr.server.app.start_server:32 flwr.server.driver.driver.Driver:10 of msgid "CA certificate." @@ -10241,8 +10580,8 @@ msgstr "如果已连接,请断开与超级链接的连接。" #: flwr.server.driver.driver.Driver.close:1::1 of #, fuzzy msgid "" -":py:obj:`create_message `\\ " -"\\(content\\, message\\_type\\, ...\\)" +":py:obj:`create_message `\\ \\(content\\, " +"message\\_type\\, ...\\)" msgstr "" ":py:obj:`create_message `\\ \\(content\\, " "message\\_type\\, ...\\)" @@ -10270,8 +10609,8 @@ msgid "" ":py:obj:`pull_messages `\\ " "\\(message\\_ids\\)" msgstr "" -":py:obj:`pull_messages `\\ \\(message\\_ids" -"\\)" +":py:obj:`pull_messages `\\ " +"\\(message\\_ids\\)" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.pull_messages:1 of @@ -10282,8 +10621,7 @@ msgstr "根据信息 ID 提取信息。" #: flwr.server.driver.driver.Driver.close:1::1 of #, fuzzy msgid "" -":py:obj:`push_messages `\\ " -"\\(messages\\)" +":py:obj:`push_messages `\\ \\(messages\\)" msgstr "" ":py:obj:`push_messages `\\ \\(messages\\)" @@ -10299,9 +10637,8 @@ msgid "" ":py:obj:`send_and_receive `\\ " "\\(messages\\, \\*\\[\\, timeout\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: flwr.server.driver.driver.Driver.close:1::1 #: flwr.server.driver.driver.Driver.send_and_receive:1 of @@ -10312,23 +10649,24 @@ msgstr "向指定的节点 ID 推送信息并提取回复信息。" #: flwr.server.driver.driver.Driver.create_message:3 of #, fuzzy msgid "" -"This method constructs a new `Message` with given content and metadata. " -"The `run_id` and `src_node_id` will be set automatically." -msgstr "本方法使用给定的内容和元数据构建新的 `Message` 。run_id \"和 \"src_node_id " +"This method constructs a new `Message` with given content and metadata. The " +"`run_id` and `src_node_id` will be set automatically." +msgstr "" +"本方法使用给定的内容和元数据构建新的 `Message` 。run_id \"和 \"src_node_id " "\"将自动设置。" #: flwr.server.driver.driver.Driver.create_message:6 of #, fuzzy msgid "" -"The content for the new message. This holds records that are to be sent " -"to the destination node." +"The content for the new message. This holds records that are to be sent to " +"the destination node." msgstr "新信息的内容。其中包含要发送到目的节点的记录。" #: flwr.server.driver.driver.Driver.create_message:9 of #, fuzzy msgid "" -"The type of the message, defining the action to be executed on the " -"receiving end." +"The type of the message, defining the action to be executed on the receiving " +"end." msgstr "信息类型,定义接收端要执行的操作。" #: flwr.server.driver.driver.Driver.create_message:12 of @@ -10339,17 +10677,18 @@ msgstr "信息发送目的地节点的 ID。" #: flwr.server.driver.driver.Driver.create_message:14 of #, fuzzy msgid "" -"The ID of the group to which this message is associated. In some " -"settings, this is used as the FL round." +"The ID of the group to which this message is associated. In some settings, " +"this is used as the FL round." msgstr "与该信息相关联的组的 ID。在某些设置中,它被用作 FL 轮。" #: flwr.server.driver.driver.Driver.create_message:17 of #, fuzzy msgid "" -"Time-to-live for the round trip of this message, i.e., the time from " -"sending this message to receiving a reply. It specifies the duration for " -"which the message and its potential reply are considered valid." -msgstr "此报文往返的有效时间,即从发送此报文到收到回复的时间。它规定了信息及其潜在回" +"Time-to-live for the round trip of this message, i.e., the time from sending " +"this message to receiving a reply. It specifies the duration for which the " +"message and its potential reply are considered valid." +msgstr "" +"此报文往返的有效时间,即从发送此报文到收到回复的时间。它规定了信息及其潜在回" "复被视为有效的持续时间。" #: flwr.server.driver.driver.Driver.create_message:22 of @@ -10362,13 +10701,14 @@ msgstr "**message** -- 具有指定内容和元数据的新 \"信息 \"实例。 #: flwr.server.driver.driver.Driver.pull_messages:3 of #, fuzzy msgid "" -"This method is used to collect messages from the SuperLink that " -"correspond to a set of given message IDs." +"This method is used to collect messages from the SuperLink that correspond " +"to a set of given message IDs." msgstr "该方法用于从超级链接中收集与一组给定消息 ID 相对应的消息。" #: flwr.server.driver.driver.Driver.pull_messages:6 of #, fuzzy -msgid "An iterable of message IDs for which reply messages are to be retrieved." +msgid "" +"An iterable of message IDs for which reply messages are to be retrieved." msgstr "要检索回复信息的信息 ID 的可迭代项。" #: flwr.server.driver.driver.Driver.pull_messages:9 of @@ -10379,9 +10719,10 @@ msgstr "**messages** -- 收到的信息迭代。" #: flwr.server.driver.driver.Driver.push_messages:3 of #, fuzzy msgid "" -"This method takes an iterable of messages and sends each message to the " -"node specified in `dst_node_id`." -msgstr "该方法接收一个可迭代的消息,并将每条消息发送到 `dst_node_id` 中指定的节点。" +"This method takes an iterable of messages and sends each message to the node " +"specified in `dst_node_id`." +msgstr "" +"该方法接收一个可迭代的消息,并将每条消息发送到 `dst_node_id` 中指定的节点。" #: flwr.server.driver.driver.Driver.push_messages:6 #: flwr.server.driver.driver.Driver.send_and_receive:7 of @@ -10392,31 +10733,34 @@ msgstr "要发送的信息迭代。" #: flwr.server.driver.driver.Driver.push_messages:9 of #, fuzzy msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, " -"which can be used to pull replies." +"**message_ids** -- An iterable of IDs for the messages that were sent, which " +"can be used to pull replies." msgstr "**message_ids** -- 已发送信息的可迭代 ID,可用于提取回复信息。" #: flwr.server.driver.driver.Driver.send_and_receive:3 of #, fuzzy msgid "" -"This method sends a list of messages to their destination node IDs and " -"then waits for the replies. It continues to pull replies until either all" -" replies are received or the specified timeout duration is exceeded." -msgstr "该方法会向目标节点 ID 发送信息列表,然后等待回复。它会继续提取回复,直到收到" +"This method sends a list of messages to their destination node IDs and then " +"waits for the replies. It continues to pull replies until either all replies " +"are received or the specified timeout duration is exceeded." +msgstr "" +"该方法会向目标节点 ID 发送信息列表,然后等待回复。它会继续提取回复,直到收到" "所有回复或超过指定的超时时间。" #: flwr.server.driver.driver.Driver.send_and_receive:9 of #, fuzzy msgid "" "The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the " -"method will wait until replies for all messages are received." -msgstr "超时时间(秒)。如果指定,该方法将在此期限内等待回复。如果指定为 \"无\"" -",则没有时间限制,该方法将等待直到收到所有信息的回复。" +"replies for this duration. If `None`, there is no time limit and the method " +"will wait until replies for all messages are received." +msgstr "" +"超时时间(秒)。如果指定,该方法将在此期限内等待回复。如果指定为 \"无\",则没" +"有时间限制,该方法将等待直到收到所有信息的回复。" #: flwr.server.driver.driver.Driver.send_and_receive:14 of #, fuzzy -msgid "**replies** -- An iterable of reply messages received from the SuperLink." +msgid "" +"**replies** -- An iterable of reply messages received from the SuperLink." msgstr "**replies** -- 从超级链接收到的回复信息的迭代。" #: flwr.server.driver.driver.Driver.send_and_receive:18 @@ -10430,14 +10774,14 @@ msgstr "无" #: flwr.server.driver.driver.Driver.send_and_receive:19 of #, fuzzy msgid "" -"This method uses `push_messages` to send the messages and `pull_messages`" -" to collect the replies. If `timeout` is set, the method may not return " -"replies for all sent messages. A message remains valid until its TTL, " -"which is not affected by `timeout`." +"This method uses `push_messages` to send the messages and `pull_messages` to " +"collect the replies. If `timeout` is set, the method may not return replies " +"for all sent messages. A message remains valid until its TTL, which is not " +"affected by `timeout`." msgstr "" -"该方法使用 `push_messages` 发送信息,并使用 `pull_messages` 收集回复。" -"如果设置了 `timeout`,该方法可能不会返回所有已发送消息的回复。消息在其 TTL " -"之前一直有效,不受 `timeout` 影响。" +"该方法使用 `push_messages` 发送信息,并使用 `pull_messages` 收集回复。如果设" +"置了 `timeout`,该方法可能不会返回所有已发送消息的回复。消息在其 TTL 之前一直" +"有效,不受 `timeout` 影响。" #: ../../source/ref-api/flwr.server.History.rst:2 #, fuzzy @@ -10447,9 +10791,8 @@ msgstr "历史" #: flwr.server.history.History.add_loss_centralized:1::1 of #, fuzzy msgid "" -":py:obj:`add_loss_centralized " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_centralized `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" ":py:obj:`add_loss_centralized `\\ " "\\(server\\_round\\, loss\\)" @@ -10463,9 +10806,8 @@ msgstr "集中评估" #: flwr.server.history.History.add_loss_centralized:1::1 of #, fuzzy msgid "" -":py:obj:`add_loss_distributed " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_distributed `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" ":py:obj:`add_loss_distributed `\\ " "\\(server\\_round\\, loss\\)" @@ -10479,9 +10821,8 @@ msgstr "增加一个损失条目(来自分布式评估)。" #: flwr.server.history.History.add_loss_centralized:1::1 of #, fuzzy msgid "" -":py:obj:`add_metrics_centralized " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" msgstr "" ":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" @@ -10495,9 +10836,8 @@ msgstr "集中评估" #: flwr.server.history.History.add_loss_centralized:1::1 of #, fuzzy msgid "" -":py:obj:`add_metrics_distributed " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" msgstr "" ":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" @@ -10511,9 +10851,8 @@ msgstr "定制的集中/分布式评估" #: flwr.server.history.History.add_loss_centralized:1::1 of #, fuzzy msgid "" -":py:obj:`add_metrics_distributed_fit " -"`\\ \\(server\\_round\\," -" ...\\)" +":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" msgstr "" ":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" @@ -10573,11 +10912,11 @@ msgstr "返回客户端(本身)。" #: flwr.server.server.Server.client_manager:1::1 of #, fuzzy msgid "" -":py:obj:`disconnect_all_clients " -"`\\ \\(timeout\\)" +":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" msgstr "" -":py:obj:`disconnect_all_clients `" -"\\ \\(timeout\\)" +":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.disconnect_all_clients:1 of @@ -10591,8 +10930,8 @@ msgid "" ":py:obj:`evaluate_round `\\ " "\\(server\\_round\\, timeout\\)" msgstr "" -":py:obj:`evaluate_round `\\ \\(" -"server\\_round\\, timeout\\)" +":py:obj:`evaluate_round `\\ " +"\\(server\\_round\\, timeout\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.evaluate_round:1 of @@ -10614,8 +10953,8 @@ msgstr "联邦平均动量策略。" #: flwr.server.server.Server.client_manager:1::1 of #, fuzzy msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\," -" timeout\\)" +":py:obj:`fit_round `\\ \\(server\\_round\\, " +"timeout\\)" msgstr "" ":py:obj:`fit_round `\\ \\(server\\_round\\, " "timeout\\)" @@ -10632,8 +10971,8 @@ msgid "" ":py:obj:`set_max_workers `\\ " "\\(max\\_workers\\)" msgstr "" -":py:obj:`set_max_workers `\\ \\(" -"max\\_workers\\)" +":py:obj:`set_max_workers `\\ " +"\\(max\\_workers\\)" #: flwr.server.server.Server.client_manager:1::1 #: flwr.server.server.Server.set_max_workers:1 of @@ -10643,7 +10982,8 @@ msgstr "设置 ThreadPoolExecutor 使用的最大工作器数。" #: flwr.server.server.Server.client_manager:1::1 of #, fuzzy -msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +msgid "" +":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" ":py:obj:`set_strategy `\\ \\(strategy\\)" @@ -10687,8 +11027,8 @@ msgstr "服务器" #: flwr.server.server_config.ServerConfig:3 of #, fuzzy msgid "" -"All attributes have default values which allows users to configure just " -"the ones they care about." +"All attributes have default values which allows users to configure just the " +"ones they care about." msgstr "所有属性都有默认值,用户只需配置自己关心的属性即可。" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 @@ -10719,17 +11059,16 @@ msgstr ":py:obj:`all `\\ \\(\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of #, fuzzy msgid "" -":py:obj:`num_available `\\" -" \\(\\)" +":py:obj:`num_available `\\ " +"\\(\\)" msgstr "" -":py:obj:`num_available `\\ \\(" -"\\)" +":py:obj:`num_available `\\ " +"\\(\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of #, fuzzy msgid "" -":py:obj:`register `\\ " -"\\(client\\)" +":py:obj:`register `\\ \\(client\\)" msgstr "" ":py:obj:`register `\\ \\(client\\)" @@ -10739,8 +11078,8 @@ msgid "" ":py:obj:`sample `\\ " "\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -":py:obj:`sample `\\ \\(num\\_clients" -"\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of #, fuzzy @@ -10748,8 +11087,8 @@ msgid "" ":py:obj:`unregister `\\ " "\\(client\\)" msgstr "" -":py:obj:`unregister `\\ \\(" -"client\\)" +":py:obj:`unregister `\\ " +"\\(client\\)" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of #, fuzzy @@ -10757,14 +11096,14 @@ msgid "" ":py:obj:`wait_for `\\ " "\\(num\\_clients\\[\\, timeout\\]\\)" msgstr "" -":py:obj:`wait_for `\\ \\(" -"num\\_clients\\[\\, timeout\\]\\)" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\[\\, timeout\\]\\)" #: flwr.server.client_manager.SimpleClientManager.wait_for:3 of #, fuzzy msgid "" -"Blocks until the requested number of clients is available or until a " -"timeout is reached. Current timeout default: 1 day." +"Blocks until the requested number of clients is available or until a timeout " +"is reached. Current timeout default: 1 day." msgstr "阻塞,直到请求的客户端数量可用或达到超时为止。当前超时默认值:1 天。" #: flwr.server.client_manager.SimpleClientManager.wait_for:6 of @@ -10817,35 +11156,39 @@ msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" #: flwr.server.compat.app.start_driver:6 of #, fuzzy msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_driver` will create one." -msgstr "服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例,`start_server` 将创建一个。" +"A server implementation, either `flwr.server.Server` or a subclass thereof. " +"If no instance is provided, then `start_driver` will create one." +msgstr "" +"服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例," +"`start_server` 将创建一个。" #: flwr.server.app.start_server:9 flwr.server.compat.app.start_driver:10 #: flwr.simulation.app.start_simulation:28 of msgid "" "Currently supported values are `num_rounds` (int, default: 1) and " "`round_timeout` in seconds (float, default: None)." -msgstr "目前支持的值有:`num_rounds`(int,默认值:1)和以秒为单位的`round_timeout`(float,默认值:无)。" +msgstr "" +"目前支持的值有:`num_rounds`(int,默认值:1)和以秒为单位的`round_timeout`" +"(float,默认值:无)。" #: flwr.server.app.start_server:12 flwr.server.compat.app.start_driver:13 of msgid "" -"An implementation of the abstract base class " -"`flwr.server.strategy.Strategy`. If no strategy is provided, then " -"`start_server` will use `flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.strategy." +"Strategy`. If no strategy is provided, then `start_server` will use `flwr." +"server.strategy.FedAvg`." msgstr "" -"抽象基类 `flwr.server.strategy.Strategy` 的实现。如果没有提供策略,`start_server` 将使用 " -"`flwr.server.strategy.FedAvg`。" +"抽象基类 `flwr.server.strategy.Strategy` 的实现。如果没有提供策略," +"`start_server` 将使用 `flwr.server.strategy.FedAvg`。" #: flwr.server.compat.app.start_driver:17 of #, fuzzy msgid "" "An implementation of the class `flwr.server.ClientManager`. If no " -"implementation is provided, then `start_driver` will use " -"`flwr.server.SimpleClientManager`." +"implementation is provided, then `start_driver` will use `flwr.server." +"SimpleClientManager`." msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现,`start_server` 将使用 " -"`flwr.server.client_manager.SimpleClientManager`。" +"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," +"`start_server` 将使用 `flwr.server.client_manager.SimpleClientManager`。" #: flwr.server.compat.app.start_driver:25 of #, fuzzy @@ -10877,30 +11220,34 @@ msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" #: flwr.server.app.start_server:5 of msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_server` will create one." -msgstr "服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例,`start_server` 将创建一个。" +"A server implementation, either `flwr.server.Server` or a subclass thereof. " +"If no instance is provided, then `start_server` will create one." +msgstr "" +"服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例," +"`start_server` 将创建一个。" #: flwr.server.app.start_server:16 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_server` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_server` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现,`start_server` 将使用 " -"`flwr.server.client_manager.SimpleClientManager`。" +"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," +"`start_server` 将使用 `flwr.server.client_manager.SimpleClientManager`。" #: flwr.server.app.start_server:21 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" clients. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower clients need to be started with the same value (see " -"`flwr.client.start_client`), otherwise clients will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"clients. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"clients need to be started with the same value (see `flwr.client." +"start_client`), otherwise clients will not know about the increased limit " +"and block larger messages." msgstr "" -"可与 Flower 客户端交换的 gRPC 消息的最大长度:默认值对大多数模型都足够了。训练超大模型的用户可能需要增加该值。请注意,Flower " -"客户端需要以相同的值启动(请参阅 `flwr.client.start_client`),否则客户端将不知道已增加的限制并阻止更大的消息。" +"可与 Flower 客户端交换的 gRPC 消息的最大长度:默认值对大多数模型都足够了。训" +"练超大模型的用户可能需要增加该值。请注意,Flower 客户端需要以相同的值启动(请" +"参阅 `flwr.client.start_client`),否则客户端将不知道已增加的限制并阻止更大的" +"消息。" #: flwr.server.app.start_server:42 of msgid "Starting an insecure server:" @@ -10918,8 +11265,8 @@ msgstr "Krum 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\)" msgstr "" ":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " "fraction\\_evaluate\\, ...\\)" @@ -10935,8 +11282,8 @@ msgid "" ":py:obj:`DPFedAvgAdaptive `\\ " "\\(strategy\\, num\\_sampled\\_clients\\)" msgstr "" -":py:obj:`DPFedAvgAdaptive `\\ \\(" -"strategy\\, num\\_sampled\\_clients\\)" +":py:obj:`DPFedAvgAdaptive `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of @@ -10949,8 +11296,8 @@ msgid "" ":py:obj:`DPFedAvgFixed `\\ " "\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" msgstr "" -":py:obj:`DPFedAvgFixed `\\ \\(strategy\\" -", num\\_sampled\\_clients\\, ...\\)" +":py:obj:`DPFedAvgFixed `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of @@ -10960,9 +11307,8 @@ msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" msgstr "" ":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" @@ -10977,9 +11323,8 @@ msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" msgstr "" ":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" @@ -10994,9 +11339,8 @@ msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" msgstr "" ":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" @@ -11011,9 +11355,8 @@ msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" msgstr "" ":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" @@ -11059,8 +11402,8 @@ msgid "" ":py:obj:`FedAvg `\\ \\(\\*\\[\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -":py:obj:`FedAvg `\\ \\(\\*\\[\\, fraction\\_fit" -"\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedavg.FedAvg:1 @@ -11071,8 +11414,8 @@ msgstr "联邦平均策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`FedAvgAndroid `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" ":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" @@ -11112,8 +11455,8 @@ msgid "" ":py:obj:`FedOpt `\\ \\(\\*\\[\\, " "fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -":py:obj:`FedOpt `\\ \\(\\*\\[\\, fraction\\_fit" -"\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedopt.FedOpt:1 of @@ -11138,8 +11481,8 @@ msgstr "联邦优化策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`FedTrimmedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" ":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " "fraction\\_fit\\, ...\\]\\)" @@ -11155,8 +11498,8 @@ msgid "" ":py:obj:`FedXgbBagging `\\ " "\\(\\[evaluate\\_function\\]\\)" msgstr "" -":py:obj:`FedXgbBagging `\\ \\(\\[" -"evaluate\\_function\\]\\)" +":py:obj:`FedXgbBagging `\\ " +"\\(\\[evaluate\\_function\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of @@ -11170,8 +11513,8 @@ msgid "" ":py:obj:`FedXgbCyclic `\\ " "\\(\\*\\*kwargs\\)" msgstr "" -":py:obj:`FedXgbCyclic `\\ \\(\\*\\*" -"kwargs\\)" +":py:obj:`FedXgbCyclic `\\ " +"\\(\\*\\*kwargs\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of @@ -11185,8 +11528,8 @@ msgid "" ":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " "\\*\\*kwargs\\)" msgstr "" -":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, \\*" -"\\*kwargs\\)" +":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of @@ -11210,12 +11553,11 @@ msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`FaultTolerantFedAvg " -"`\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" -":py:obj:`FaultTolerantFedAvg `\\ \\" -"(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of @@ -11225,8 +11567,8 @@ msgstr "可配置的容错 FedAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\]\\)" msgstr "" ":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " "fraction\\_evaluate\\, ...\\]\\)" @@ -11240,8 +11582,8 @@ msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " -"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " +"qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" ":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " "qffl\\_learning\\_rate\\, ...\\]\\)" @@ -11414,8 +11756,8 @@ msgstr "初始全局模型参数。" #: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of " -"the Bulyan (e.g., Krum)" +"Byzantine resilient aggregation rule that is used as the first step of the " +"Bulyan (e.g., Krum)" msgstr "Byzantine弹性聚合规则,用作 Bulyan 的第一步(如 Krum)" #: flwr.server.strategy.bulyan.Bulyan:29 of @@ -11425,12 +11767,11 @@ msgstr "第一聚类规则的参数" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `" -"\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11449,8 +11790,8 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11460,12 +11801,11 @@ msgstr "使用 Bulyan 技术汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `" -"\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 @@ -11496,8 +11836,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 @@ -11531,8 +11871,8 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round" -"\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -11550,9 +11890,8 @@ msgstr "使用评估函数评估模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -11572,9 +11911,8 @@ msgstr "初始化全局模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -11594,11 +11932,11 @@ msgstr "使用部分可用客户进行评估。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(" -"num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -11631,9 +11969,8 @@ msgstr "该类已被弃用,将在以后的版本中删除。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -11656,12 +11993,11 @@ msgstr "使用给定的策略汇总评估损失。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `" -"\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11673,9 +12009,8 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -11689,12 +12024,11 @@ msgstr "使用指定策略配置下一轮评估。" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `" -"\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of @@ -11703,8 +12037,8 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 @@ -11716,16 +12050,16 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "Evaluate model parameters using an evaluation function from the strategy." +msgid "" +"Evaluate model parameters using an evaluation function from the strategy." msgstr "使用策略中的评估函数评估模型参数。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -11766,13 +12100,14 @@ msgstr "客户端管理器,用于管理当前连接的所有客户端。" msgid "" "**evaluate_configuration** -- A list of tuples. Each tuple in the list " "identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated evaluation." +"`ClientProxy`. If a particular `ClientProxy` is not included in this list, " +"it means that this `ClientProxy` will not participate in the next round of " +"federated evaluation." msgstr "" -"**evaluate_configuration** -- " -"一个元组列表。列表中的每个元组都标识了一个`ClientProxy`和该特定`ClientProxy`的`EvaluateIns`。如果某个特定的" -" `ClientProxy` 未包含在此列表中,则表示该 `ClientProxy` 将不参与下一轮联合评估。" +"**evaluate_configuration** -- 一个元组列表。列表中的每个元组都标识了一个" +"`ClientProxy`和该特定`ClientProxy`的`EvaluateIns`。如果某个特定的 " +"`ClientProxy` 未包含在此列表中,则表示该 `ClientProxy` 将不参与下一轮联合评" +"估。" #: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 msgid "DPFedAvgFixed" @@ -11793,9 +12128,8 @@ msgstr "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -11804,8 +12138,7 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ " @@ -11820,9 +12153,8 @@ msgstr "使用非加权汇总法汇总训练结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -11831,8 +12163,7 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ " @@ -11841,8 +12172,7 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -"Configure the next round of training incorporating Differential Privacy " -"(DP)." +"Configure the next round of training incorporating Differential Privacy (DP)." msgstr "配置包含差分隐私 (DP) 的下一轮训练。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11852,37 +12182,36 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -"Configuration of the next training round includes information related to " -"DP, such as clip norm and noise stddev." +"Configuration of the next training round includes information related to DP, " +"such as clip norm and noise stddev." msgstr "下一轮训练的配置包括与 DP 相关的信息,如片段规范和噪声 stddev。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 #: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `FitIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated learning." +"**fit_configuration** -- A list of tuples. Each tuple in the list identifies " +"a `ClientProxy` and the `FitIns` for this particular `ClientProxy`. If a " +"particular `ClientProxy` is not included in this list, it means that this " +"`ClientProxy` will not participate in the next round of federated learning." msgstr "" -"**fit_configuration** -- " -"一个元组列表。列表中的每个元组都标识了一个`ClientProxy`和该特定`ClientProxy`的`FitIns'。如果某个特定的`ClientProxy`不在此列表中,则表示该`ClientProxy`将不参加下一轮联合学习。" +"**fit_configuration** -- 一个元组列表。列表中的每个元组都标识了一个" +"`ClientProxy`和该特定`ClientProxy`的`FitIns'。如果某个特定的`ClientProxy`不在" +"此列表中,则表示该`ClientProxy`将不参加下一轮联合学习。" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 #, fuzzy @@ -11901,13 +12230,12 @@ msgstr "在客户端使用 \"adaptiveclipping_mod \"修改器。" msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " -"happen on the client-side, usually by using the built-in " -"`adaptiveclipping_mod`." +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `adaptiveclipping_mod`." msgstr "" -"与在服务器端执行剪切的 `DifferentialPrivacyServerSideAdaptiveClipping` " -"相比,`DifferentialPrivacyClientSideAdaptiveClipping` 希望在客户端进行剪切," -"通常使用内置的 `adaptiveclipping_mod`。" +"与在服务器端执行剪切的 `DifferentialPrivacyServerSideAdaptiveClipping` 相比," +"`DifferentialPrivacyClientSideAdaptiveClipping` 希望在客户端进行剪切,通常使" +"用内置的 `adaptiveclipping_mod`。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 @@ -11947,7 +12275,8 @@ msgstr "剪切规范的初始值。默认为 0.1。安德鲁等人建议设置 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of #, fuzzy -msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." +msgid "" +"The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "需要剪切的更新量化值。默认为 0.5。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 @@ -11955,17 +12284,18 @@ msgstr "需要剪切的更新量化值。默认为 0.5。" #: of #, fuzzy msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. " -"Andrew et al. recommends to set to 0.2." +"The learning rate for the clipping norm adaptation. Defaults to 0.2. Andrew " +"et al. recommends to set to 0.2." msgstr "剪切规范适应的学习率。默认为 0.2。安德鲁等人建议设置为 0.2。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of #, fuzzy msgid "" -"The stddev of the noise added to the count of updates currently below the" -" estimate. Andrew et al. recommends to set to `expected_num_records/20`" -msgstr "添加到当前低于估计值的更新计数中的噪声的 stddev。安德鲁等人建议设置为 " +"The stddev of the noise added to the count of updates currently below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" +msgstr "" +"添加到当前低于估计值的更新计数中的噪声的 stddev。安德鲁等人建议设置为 " "\"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 @@ -11981,9 +12311,10 @@ msgstr "server.strategy" #: of #, fuzzy msgid "" -"Wrap the strategy with the " -"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" -msgstr "用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" +"Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` " +"wrapper:" +msgstr "" +"用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 #: of @@ -11995,25 +12326,25 @@ msgstr "在客户端,将 \"adaptiveclipping_mod \"添加到客户端模块中 #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(" -"server\\_round\\, results\\, ...\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate>`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit>`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 @@ -12028,49 +12359,49 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.configure_fit>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" ":py:obj:`evaluate `\\ \\(server\\_round" -"\\, parameters\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.evaluate>`\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(" -"client\\_manager\\)" +"DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters>`\\ " +"\\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 #, fuzzy @@ -12089,21 +12420,22 @@ msgstr "在客户端使用 `fixedclipping_mod` 修改器。" msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `fixedclipping_mod`." +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen on " +"the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" -"与在服务器端执行剪切的 \"DifferentialPrivacyServerSideFixedClipping \"相比," -"\"DifferentialPrivacyClientSideFixedClipping \"希望在客户端进行剪切," -"通常是使用内置的 \"fixedclipping_mod\"。" +"与在服务器端执行剪切的 \"DifferentialPrivacyServerSideFixedClipping \"相" +"比,\"DifferentialPrivacyClientSideFixedClipping \"希望在客户端进行剪切,通常" +"是使用内置的 \"fixedclipping_mod\"。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of #, fuzzy msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A " -"value of 1.0 or higher is recommended for strong privacy." -msgstr "模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" +"The noise multiplier for the Gaussian mechanism for model updates. A value " +"of 1.0 or higher is recommended for strong privacy." +msgstr "" +"模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 @@ -12130,25 +12462,25 @@ msgstr "在客户端,将 \"fixedclipping_mod \"添加到客户端模块中:" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(" -"server\\_round\\, results\\, ...\\)" +"DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate>`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +"DifferentialPrivacyClientSideFixedClipping.aggregate_fit>`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 @@ -12161,33 +12493,33 @@ msgstr "然后将汇总结果序列化:" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyClientSideFixedClipping.configure_evaluate>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyClientSideFixedClipping.configure_fit>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" ":py:obj:`evaluate `\\ \\(server\\_round\\, " @@ -12197,13 +12529,13 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(" -"client\\_manager\\)" +"DifferentialPrivacyClientSideFixedClipping.initialize_parameters>`\\ " +"\\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 #, fuzzy @@ -12214,10 +12546,10 @@ msgstr "DifferentialPrivacyServerSideAdaptiveClipping" #: of #, fuzzy msgid "" -"The standard deviation of the noise added to the count of updates below " -"the estimate. Andrew et al. recommends to set to " -"`expected_num_records/20`" -msgstr "添加到低于估计值的更新计数中的噪声标准偏差。安德鲁等人建议设置为 " +"The standard deviation of the noise added to the count of updates below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" +msgstr "" +"添加到低于估计值的更新计数中的噪声标准偏差。安德鲁等人建议设置为 " "\"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 @@ -12232,73 +12564,73 @@ msgstr "用 DifferentialPrivacyServerSideAdaptiveClipping 封装器封装策略" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(" -"server\\_round\\, results\\, ...\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate>`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.aggregate_fit>`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.configure_evaluate>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.configure_fit>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" ":py:obj:`evaluate `\\ \\(server\\_round" -"\\, parameters\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.evaluate>`\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(" -"client\\_manager\\)" +"DifferentialPrivacyServerSideAdaptiveClipping.initialize_parameters>`\\ " +"\\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 #, fuzzy @@ -12309,33 +12641,32 @@ msgstr "差分隐私" #: of #, fuzzy msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " -"wrapper" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper" msgstr "用 DifferentialPrivacyServerSideFixedClipping 封装器封装策略" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(" -"server\\_round\\, results\\, ...\\)" +"DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate>`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +"DifferentialPrivacyServerSideFixedClipping.aggregate_fit>`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 @@ -12348,33 +12679,33 @@ msgstr "计算更新、剪辑并将其传递给聚合。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyServerSideFixedClipping.configure_evaluate>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +"DifferentialPrivacyServerSideFixedClipping.configure_fit>`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" ":py:obj:`evaluate `\\ \\(server\\_round\\, " @@ -12384,13 +12715,13 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(" -"client\\_manager\\)" +"DifferentialPrivacyServerSideFixedClipping.initialize_parameters>`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 #: of @@ -12407,9 +12738,8 @@ msgstr "server.strategy.FaultTolerantFedAvg" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -12418,9 +12748,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" @@ -12445,9 +12774,8 @@ msgstr "使用加权平均法汇总拟合结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -12456,9 +12784,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -12470,16 +12797,15 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -12488,9 +12814,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -12499,9 +12824,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" @@ -12558,9 +12882,8 @@ msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -12568,18 +12891,17 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -12587,11 +12909,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12599,15 +12921,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -12615,9 +12936,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -12625,12 +12945,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 #, fuzzy @@ -12650,9 +12969,8 @@ msgstr "第二动量参数。默认为 0.99。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -12663,15 +12981,14 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -12682,8 +12999,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12691,15 +13008,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -12707,9 +13023,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -12717,12 +13032,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\" -"(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 #, fuzzy @@ -12738,8 +13052,8 @@ msgstr "实施基于 https://arxiv.org/abs/1602.05629" #: of msgid "" "Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will " -"still be sampled. Defaults to 1.0." +"larger than `fraction_fit * available_clients`, `min_fit_clients` will still " +"be sampled. Defaults to 1.0." msgstr "" "训练过程中使用的客户端比例。如果 `min_fit_clients` 大于 `fraction_fit * " "available_clients`,则仍会对 `min_fit_clients` 进行采样。默认为 1.0。" @@ -12747,13 +13061,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -"Fraction of clients used during validation. In case " -"`min_evaluate_clients` is larger than `fraction_evaluate * " -"available_clients`, `min_evaluate_clients` will still be sampled. " -"Defaults to 1.0." +"Fraction of clients used during validation. In case `min_evaluate_clients` " +"is larger than `fraction_evaluate * available_clients`, " +"`min_evaluate_clients` will still be sampled. Defaults to 1.0." msgstr "" -"验证过程中使用的客户端的比例。如果 `min_evaluate_clients` 大于 `fraction_evaluate * " -"available_clients`,则仍会对 `min_evaluate_clients` 进行采样。默认为 1.0。" +"验证过程中使用的客户端的比例。如果 `min_evaluate_clients` 大于 " +"`fraction_evaluate * available_clients`,则仍会对 `min_evaluate_clients` 进行" +"采样。默认为 1.0。" #: flwr.server.strategy.fedavg.FedAvg:33 of #, fuzzy @@ -12763,12 +13077,11 @@ msgstr "启用(真)或禁用(假)模型更新的就地聚合。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `" -"\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12776,18 +13089,17 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `" -"\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12795,8 +13107,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12804,15 +13116,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round" -"\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -12820,9 +13131,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -12830,11 +13140,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(" -"num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 #, fuzzy @@ -12845,9 +13155,8 @@ msgstr "DPFedAvgAdaptive" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -12856,8 +13165,7 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ " @@ -12867,8 +13175,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`bytes_to_ndarray " -"`\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" @@ -12883,9 +13191,8 @@ msgstr "从字节反序列化 NumPy ndarray。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -12894,8 +13201,7 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ " @@ -12908,16 +13214,15 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -12926,8 +13231,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`ndarray_to_bytes " -"`\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" @@ -12942,9 +13247,8 @@ msgstr "将 NumPy ndarray 序列化为字节。" #: of #, fuzzy msgid "" -":py:obj:`ndarrays_to_parameters " -"`\\ " -"\\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" msgstr "" ":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" @@ -12953,9 +13257,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -12964,9 +13267,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" @@ -12975,9 +13277,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`parameters_to_ndarrays " -"`\\ " -"\\(parameters\\)" +":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" msgstr "" ":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" @@ -13001,8 +13302,7 @@ msgstr "实施基于 https://arxiv.org/pdf/1909.06335.pdf" #: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to " -"1.0." +"Server-side learning rate used in server-side optimization. Defaults to 1.0." msgstr "服务器端优化中使用的服务器端学习率。默认为 1.0。" #: flwr.server.strategy.fedavgm.FedAvgM:28 of @@ -13012,9 +13312,8 @@ msgstr "用于 FedAvgM 的服务器端动量因子。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13025,15 +13324,14 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13044,8 +13342,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13053,15 +13351,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13069,9 +13366,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13079,12 +13375,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\" -"(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 #, fuzzy @@ -13094,9 +13389,8 @@ msgstr "联邦医保" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13107,8 +13401,8 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of @@ -13118,9 +13412,8 @@ msgstr "使用中位数汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13131,8 +13424,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13140,15 +13433,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13156,9 +13448,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13166,8 +13457,7 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_fit_clients `\\ " @@ -13189,12 +13479,11 @@ msgstr "第二动量参数。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `" -"\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13202,18 +13491,17 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `" -"\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13221,8 +13509,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13230,15 +13518,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round" -"\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13246,9 +13533,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13256,11 +13542,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(" -"num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 #, fuzzy @@ -13273,10 +13559,12 @@ msgstr "实施基于 https://arxiv.org/abs/1812.06127" #: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"The strategy in itself will not be different than FedAvg, the client " -"needs to be adjusted. A proximal term needs to be added to the loss " -"function during the training:" -msgstr "策略本身与 FedAvg 并无不同,客户端需要进行调整。在训练过程中,需要在损失函数中添加一个近端项:" +"The strategy in itself will not be different than FedAvg, the client needs " +"to be adjusted. A proximal term needs to be added to the loss function " +"during the training:" +msgstr "" +"策略本身与 FedAvg 并无不同,客户端需要进行调整。在训练过程中,需要在损失函数" +"中添加一个近端项:" #: flwr.server.strategy.fedprox.FedProx:9 of msgid "" @@ -13310,18 +13598,17 @@ msgstr "其中,\"global_params \"是训练前的参数副本。" msgid "" "The weight of the proximal term used in the optimization. 0.0 makes this " "strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to " -"be closer to the server parameters during training)." +"regularization will be used (that is, the client parameters will need to be " +"closer to the server parameters during training)." msgstr "" -"优化中使用的近端项权重。0.0 使该策略等同于 " -"FedAvg,系数越大,使用的正则化就越多(也就是说,在训练过程中,客户端参数需要更接近服务器参数)。" +"优化中使用的近端项权重。0.0 使该策略等同于 FedAvg,系数越大,使用的正则化就越" +"多(也就是说,在训练过程中,客户端参数需要更接近服务器参数)。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13332,15 +13619,14 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13351,8 +13637,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13360,15 +13646,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13376,9 +13661,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13386,12 +13670,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\" -"(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of msgid "Sends the proximal factor mu to the clients" @@ -13414,9 +13697,8 @@ msgstr "截取分布两个尾部的分数。默认为 0.2。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13424,8 +13706,7 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ " @@ -13439,9 +13720,8 @@ msgstr "使用修剪平均值汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13449,8 +13729,7 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ " @@ -13462,15 +13741,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13478,9 +13756,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13488,9 +13765,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" @@ -13504,9 +13780,8 @@ msgstr "FedXgbBagging" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13524,8 +13799,7 @@ msgstr "采用加权平均法计算评估损失总额。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ " @@ -13543,9 +13817,8 @@ msgstr "使用 Bulyan 技术汇总拟合结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13554,8 +13827,7 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ " @@ -13568,16 +13840,15 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13586,9 +13857,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13597,9 +13867,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" @@ -13613,9 +13882,8 @@ msgstr "FedXgbCyclic" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13624,9 +13892,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\," -" results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" @@ -13635,9 +13902,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13646,9 +13912,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" @@ -13660,16 +13925,15 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13678,9 +13942,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13689,12 +13952,11 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `" -"\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 #, fuzzy @@ -13705,8 +13967,7 @@ msgstr "DP-FedAvg" #, fuzzy msgid "" "This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: " -"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +"Baselines: https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" "该策略已被弃用,但在 Flower Baselines: https://github.com/adap/flower/tree/" "main/baselines/hfedxgboost 中有其副本。" @@ -13714,9 +13975,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13724,19 +13984,17 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\, " -"results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\" -"(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13744,12 +14002,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\" -"(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13757,15 +14014,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13773,9 +14029,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13783,12 +14038,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `" -"\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 #, fuzzy @@ -13813,9 +14067,8 @@ msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -13826,15 +14079,14 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -13845,8 +14097,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13854,15 +14106,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13870,9 +14121,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13880,12 +14130,11 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\" -"(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 #, fuzzy @@ -13899,19 +14148,20 @@ msgstr "实施基于 https://arxiv.org/abs/2304.07537。" #: flwr.server.strategy.krum.Krum:17 of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" -" that case classical Krum is applied." -msgstr "求平均值前保留的客户端数量(MultiKrum)。默认值为 0,在这种情况下会应用经典 Krum。" +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in " +"that case classical Krum is applied." +msgstr "" +"求平均值前保留的客户端数量(MultiKrum)。默认值为 0,在这种情况下会应用经典 " +"Krum。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13919,8 +14169,8 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.krum.Krum.aggregate_fit:1 of @@ -13930,12 +14180,11 @@ msgstr "使用 Krum 汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13943,8 +14192,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13952,15 +14201,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round\\" -", parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -13968,9 +14216,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -13981,8 +14228,8 @@ msgid "" ":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(" -"num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 #, fuzzy @@ -13992,9 +14239,8 @@ msgstr "DP-FedAvg" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -14005,15 +14251,14 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -14024,8 +14269,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14033,15 +14278,14 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -14049,9 +14293,8 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" ":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" @@ -14059,12 +14302,11 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\" -"(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 #, fuzzy @@ -14075,9 +14317,8 @@ msgstr "Krum 策略。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" ":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" @@ -14095,8 +14336,8 @@ msgid "" ":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(" -"server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of @@ -14107,9 +14348,8 @@ msgstr "汇总训练结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" ":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" @@ -14121,8 +14361,8 @@ msgid "" ":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(" -"server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of @@ -14131,8 +14371,8 @@ msgid "" ":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(" -"server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.evaluate:1 of @@ -14143,9 +14383,8 @@ msgstr "评估当前的模型参数。" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" ":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" @@ -14157,19 +14396,22 @@ msgstr "初始化(全局)模型参数。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " -"one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" -"从先前选定和配置的客户端进行的成功更新。每一对`(ClientProxy, " -"FitRes)`都是来自先前选定客户端的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,`failures`中都应该有一个`Exception`。" +"从先前选定和配置的客户端进行的成功更新。每一对`(ClientProxy, FitRes)`都是来自" +"先前选定客户端的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表" +"中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,`failures`中" +"都应该有一个`Exception`。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "Exceptions that occurred while the server was waiting for client updates." +msgid "" +"Exceptions that occurred while the server was waiting for client updates." msgstr "服务器等待客户端更新时发生的异常。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of @@ -14180,29 +14422,31 @@ msgstr "**aggregation_result** -- 汇总的评估结果。聚合通常使用某 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" -" one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes)` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" -"来自先前选定和配置的客户端的成功更新。每一对`(ClientProxy, " -"FitRes)`都构成先前选定的客户端之一的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,\"失败" -" \"中都应该有一个 \"异常\"。" +"来自先前选定和配置的客户端的成功更新。每一对`(ClientProxy, FitRes)`都构成先前" +"选定的客户端之一的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表" +"中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,\"失败 \"中都" +"应该有一个 \"异常\"。" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the " -"previous parameters with the ones returned from this method). If `None` " -"is returned (e.g., because there were only failures and no viable " -"results) then the server will no update the previous model parameters, " -"the updates received in this round are discarded, and the global model " -"parameters remain the same." +"these as the new global model parameters (i.e., it will replace the previous " +"parameters with the ones returned from this method). If `None` is returned " +"(e.g., because there were only failures and no viable results) then the " +"server will no update the previous model parameters, the updates received in " +"this round are discarded, and the global model parameters remain the same." msgstr "" -"**parameters** -- 如果返回参数,那么服务器将把这些参数作为新的全局模型参数(即用本方法返回的参数替换之前的参数)。如果返回 " -"\"无\"(例如,因为只有失败而没有可行的结果),那么服务器将不再更新之前的模型参数,本轮收到的更新将被丢弃,全局模型参数保持不变。" +"**parameters** -- 如果返回参数,那么服务器将把这些参数作为新的全局模型参数" +"(即用本方法返回的参数替换之前的参数)。如果返回 \"无\"(例如,因为只有失败而" +"没有可行的结果),那么服务器将不再更新之前的模型参数,本轮收到的更新将被丢" +"弃,全局模型参数保持不变。" #: flwr.server.strategy.strategy.Strategy.evaluate:3 of msgid "" @@ -14212,16 +14456,18 @@ msgstr "该函数可用于对模型参数进行集中(即服务器端)评估 #: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple " -"containing loss and a dictionary containing task-specific metrics (e.g., " -"accuracy)." -msgstr "**evaluation_result** -- 评估结果,通常是一个元组,包含损失值和一个字典,字典中包含特定任务的指标(如准确率)。" +"**evaluation_result** -- The evaluation result, usually a Tuple containing " +"loss and a dictionary containing task-specific metrics (e.g., accuracy)." +msgstr "" +"**evaluation_result** -- 评估结果,通常是一个元组,包含损失值和一个字典,字典" +"中包含特定任务的指标(如准确率)。" #: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " "these as the initial global model parameters." -msgstr "**parameters** -- 如果返回参数,服务器将把这些参数视为初始全局模型参数。" +msgstr "" +"**parameters** -- 如果返回参数,服务器将把这些参数视为初始全局模型参数。" #: ../../source/ref-api/flwr.server.workflow.rst:2 #, fuzzy @@ -14234,8 +14480,8 @@ msgid "" ":py:obj:`DefaultWorkflow `\\ " "\\(\\[fit\\_workflow\\, ...\\]\\)" msgstr "" -":py:obj:`DefaultWorkflow `\\ \\(\\[" -"fit\\_workflow\\, ...\\]\\)" +":py:obj:`DefaultWorkflow `\\ " +"\\(\\[fit\\_workflow\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of @@ -14249,8 +14495,8 @@ msgid "" ":py:obj:`SecAggPlusWorkflow `\\ " "\\(num\\_shares\\, ...\\[\\, ...\\]\\)" msgstr "" -":py:obj:`SecAggPlusWorkflow `\\ \\(" -"num\\_shares\\, ...\\[\\, ...\\]\\)" +":py:obj:`SecAggPlusWorkflow `\\ " +"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 @@ -14265,8 +14511,8 @@ msgid "" ":py:obj:`SecAggWorkflow `\\ " "\\(reconstruction\\_threshold\\, \\*\\)" msgstr "" -":py:obj:`SecAggWorkflow `\\ \\(" -"reconstruction\\_threshold\\, \\*\\)" +":py:obj:`SecAggWorkflow `\\ " +"\\(reconstruction\\_threshold\\, \\*\\)" #: ../../source/ref-api/flwr.server.workflow.rst:24::1 #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of @@ -14288,25 +14534,25 @@ msgstr "工作流程" #: of #, fuzzy msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors " -"owned by multiple parties, without accessing any individual integer " -"vector. This workflow allows the server to compute the weighted average " -"of model parameters across all clients, ensuring individual contributions" -" remain private. This is achieved by clients sending both, a weighting " -"factor and a weighted version of the locally updated parameters, both of " -"which are masked for privacy. Specifically, each client uploads \"[w, w *" -" params]\" with masks, where weighting factor 'w' is the number of " -"examples ('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"The SecAgg+ protocol ensures the secure summation of integer vectors owned " +"by multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " +"parameters across all clients, ensuring individual contributions remain " +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" "SecAgg+ 协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向" "量。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持" "私密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保" -"护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * params]" -"\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " -"\"FitRes \"中的模型参数(\"parameters\"" -")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" +"护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * " +"params]\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客" +"户端 \"FitRes \"中的模型参数(\"parameters\")。然后,服务器会汇总这些贡献," +"计算模型参数的加权平均值。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 #: of @@ -14316,8 +14562,8 @@ msgid "" "configuration to clients and collect their public keys. - 'share keys': " "Broadcast public keys among clients and collect encrypted secret" msgstr "" -"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg+ 配置并收集其公钥。- " -"共享密钥\": 在客户端之间广播公钥,并收集加密密钥。" +"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg+ 配置并收集其公钥。- 共" +"享密钥\": 在客户端之间广播公钥,并收集加密密钥。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 @@ -14349,21 +14595,22 @@ msgstr "解密\": 收集密钥共享,解密并汇总模型参数。" #: of #, fuzzy msgid "" -"Only the aggregated model parameters are exposed and passed to " -"`Strategy.aggregate_fit`, ensuring individual data privacy." -msgstr "只有聚合模型参数才会公开并传递给 `Strategy." -"aggregate_fit`,从而确保个人数据隐私。" +"Only the aggregated model parameters are exposed and passed to `Strategy." +"aggregate_fit`, ensuring individual data privacy." +msgstr "" +"只有聚合模型参数才会公开并传递给 `Strategy.aggregate_fit`,从而确保个人数据隐" +"私。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of #, fuzzy msgid "" -"The number of shares into which each client's private key is split under " -"the SecAgg+ protocol. If specified as a float, it represents the " -"proportion of all selected clients, and the number of shares will be set " -"dynamically in the run time. A private key can be reconstructed from " -"these shares, allowing for the secure aggregation of model updates. Each " -"client sends one share to each of its neighbors while retaining one." +"The number of shares into which each client's private key is split under the " +"SecAgg+ protocol. If specified as a float, it represents the proportion of " +"all selected clients, and the number of shares will be set dynamically in " +"the run time. A private key can be reconstructed from these shares, allowing " +"for the secure aggregation of model updates. Each client sends one share to " +"each of its neighbors while retaining one." msgstr "" "在 SecAgg+ 协议下,每个客户的私钥被分成的份数。如果指定为浮点数,则代表所有选" "定客户的比例,份额数将在运行时动态设置。私钥可以从这些份额中重建,从而实现模" @@ -14374,11 +14621,11 @@ msgstr "" #: of #, fuzzy msgid "" -"The minimum number of shares required to reconstruct a client's private " -"key, or, if specified as a float, it represents the proportion of the " -"total number of shares needed for reconstruction. This threshold ensures " -"privacy by allowing for the recovery of contributions from dropped " -"clients during aggregation, without compromising individual client data." +"The minimum number of shares required to reconstruct a client's private key, " +"or, if specified as a float, it represents the proportion of the total " +"number of shares needed for reconstruction. This threshold ensures privacy " +"by allowing for the recovery of contributions from dropped clients during " +"aggregation, without compromising individual client data." msgstr "" "重建客户私钥所需的最小份数,如果指定为浮动,则表示重建所需的份数占总份数的比" "例。这个阈值允许在聚合过程中恢复掉线客户的贡献,从而确保隐私,而不会泄露单个" @@ -14389,11 +14636,12 @@ msgstr "" #: of #, fuzzy msgid "" -"The maximum value of the weight that can be assigned to any single " -"client's update during the weighted average calculation on the server " -"side, e.g., in the FedAvg algorithm." -msgstr "在服务器端进行加权平均计算(如 FedAvg " -"算法)时,可分配给任何单个客户端更新的权重的最大值。" +"The maximum value of the weight that can be assigned to any single client's " +"update during the weighted average calculation on the server side, e.g., in " +"the FedAvg algorithm." +msgstr "" +"在服务器端进行加权平均计算(如 FedAvg 算法)时,可分配给任何单个客户端更新的" +"权重的最大值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 @@ -14401,9 +14649,10 @@ msgstr "在服务器端进行加权平均计算(如 FedAvg " #, fuzzy msgid "" "The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within " -"[-clipping_range, clipping_range], facilitating quantization." -msgstr "量化前模型参数的裁剪范围。该参数可确保每个模型参数都在 [-clipping_range, " +"This parameter ensures each model parameter is bounded within [-" +"clipping_range, clipping_range], facilitating quantization." +msgstr "" +"量化前模型参数的裁剪范围。该参数可确保每个模型参数都在 [-clipping_range, " "clipping_range] 范围内,便于量化。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 @@ -14415,8 +14664,9 @@ msgid "" "quantized, mapping each parameter to an integer in [0, " "quantization_range-1]. This facilitates cryptographic operations on the " "model updates." -msgstr "浮点模型参数量化范围的大小,将每个参数映射为 [0, quantization_range-1] " -"中的整数。这有助于对模型更新进行加密操作。" +msgstr "" +"浮点模型参数量化范围的大小,将每个参数映射为 [0, quantization_range-1] 中的整" +"数。这有助于对模型更新进行加密操作。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 @@ -14424,21 +14674,21 @@ msgstr "浮点模型参数量化范围的大小,将每个参数映射为 [0, q #, fuzzy msgid "" "The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " -"Please use 2**n values for `modulus_range` to prevent overflow issues." +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. Please " +"use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" "对随机掩码条目进行均匀采样的数值范围([0, modulus_range-1])。modulus_range " -"\"必须小于 4294967296。为防止出现溢出问题,请为 `modulus_range` 使用 2**n " -"的值。" +"\"必须小于 4294967296。为防止出现溢出问题,请为 `modulus_range` 使用 2**n 的" +"值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of #, fuzzy msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for" -" replies for this duration each time. If `None`, there is no time limit " -"and the workflow will wait until replies for all messages are received." +"The timeout duration in seconds. If specified, the workflow will wait for " +"replies for this duration each time. If `None`, there is no time limit and " +"the workflow will wait until replies for all messages are received." msgstr "" "超时时间(秒)。如果指定,工作流将在每次等待回复的时间内等待回复。如果指定为 " "\"无\",则没有时间限制,工作流程将一直等待到收到所有信息的回复。" @@ -14448,8 +14698,8 @@ msgstr "" #, fuzzy msgid "" "Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` " -"means better privacy guarantees but less tolerance to dropouts." +"increasing the computational costs; higher `reconstruction_threshold` means " +"better privacy guarantees but less tolerance to dropouts." msgstr "" "一般来说,\"份额数 \"越高,意味着对丢弃的鲁棒性越强,同时计算成本也会增加;" "\"重构阈值 \"越高,意味着隐私保证越好,但对丢弃的容忍度越低。" @@ -14458,7 +14708,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of #, fuzzy -msgid "Too large `max_weight` may compromise the precision of the quantization." +msgid "" +"Too large `max_weight` may compromise the precision of the quantization." msgstr "过大的 `max_weight` 可能会影响量化的精度。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 @@ -14473,9 +14724,9 @@ msgstr "modulus_range \"必须为 2**n,且大于 \"quantization_range\"。" #, fuzzy msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in " -"the runtime. This allows for dynamic adjustment based on the total number" -" of participating clients." +"selected clients, and hence the number of shares will be determined in the " +"runtime. This allows for dynamic adjustment based on the total number of " +"participating clients." msgstr "" "当 `num_shares` 为浮点数时,它被解释为所有选定客户端的比例,因此份额数将在运" "行时确定。这样就可以根据参与客户端的总数进行动态调整。" @@ -14484,10 +14735,10 @@ msgstr "" #: of #, fuzzy msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted " -"as the proportion of the number of shares needed for the reconstruction " -"of a private key. This feature enables flexibility in setting the " -"security threshold relative to the number of distributed shares." +"Similarly, when `reconstruction_threshold` is a float, it is interpreted as " +"the proportion of the number of shares needed for the reconstruction of a " +"private key. This feature enables flexibility in setting the security " +"threshold relative to the number of distributed shares." msgstr "" "同样,当 `reconstruction_threshold` 为浮点数时,它被解释为重建私钥所需的份额" "数比例。这一功能使我们可以根据分发的份额数灵活设置安全阈值。" @@ -14496,10 +14747,10 @@ msgstr "" #: of #, fuzzy msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters" -" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+" -" protocol." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters " +"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+ " +"protocol." msgstr "" "份额数\"、\"重建阈值 \"和量化参数(\"裁剪范围\"、\"量化范围\"、\"模数范围\")" "在平衡 SecAgg+ 协议的隐私性、稳健性和效率方面发挥着关键作用。" @@ -14508,9 +14759,8 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\" -" \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" ":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" @@ -14526,12 +14776,11 @@ msgstr "执行 \"收集屏蔽向量 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`setup_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 @@ -14544,9 +14793,8 @@ msgstr "执行 \"设置 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`share_keys_stage " -"`\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" ":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" @@ -14562,12 +14810,11 @@ msgstr "执行 \"共享密钥 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" -":py:obj:`unmask_stage `" -"\\ \\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 @@ -14582,51 +14829,50 @@ msgstr "工作流程" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"Bases: " -":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" +"Bases: :py:class:`~flwr.server.workflow.secure_aggregation." +"secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned" -" by multiple parties, without accessing any individual integer vector. " -"This workflow allows the server to compute the weighted average of model " +"The SecAgg protocol ensures the secure summation of integer vectors owned by " +"multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " "parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and" -" a weighted version of the locally updated parameters, both of which are " -"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" -" with masks, where weighting factor 'w' is the number of examples " -"('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +"The protocol involves four main stages: - 'setup': Send SecAgg configuration " +"to clients and collect their public keys. - 'share keys': Broadcast public " +"keys among clients and collect encrypted secret" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"Each client's private key is split into N shares under the SecAgg " -"protocol, where N is the number of selected clients." +"Each client's private key is split into N shares under the SecAgg protocol, " +"where N is the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"Generally, higher `reconstruction_threshold` means better privacy " -"guarantees but less tolerance to dropouts." +"Generally, higher `reconstruction_threshold` means better privacy guarantees " +"but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in " -"setting the security threshold relative to the number of selected " -"clients." +"reconstruction of a private key. This feature enables flexibility in setting " +"the security threshold relative to the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of @@ -14640,32 +14886,29 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\ " -"\\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:2 @@ -14675,8 +14918,8 @@ msgstr "运行模拟" #: ../../source/ref-api/flwr.simulation.rst:19::1 msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\," -" client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\, " +"client\\_fn\\[\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:19::1 @@ -14686,8 +14929,8 @@ msgstr "启动基于 Ray 的Flower模拟服务器。" #: ../../source/ref-api/flwr.simulation.rst:19::1 msgid "" -":py:obj:`run_simulation_from_cli " -"`\\ \\(\\)" +":py:obj:`run_simulation_from_cli `\\ \\(\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:19::1 @@ -14719,15 +14962,14 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive" -" messages sent by the `ServerApp`." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive " +"messages sent by the `ServerApp`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in " -"the ServerApp and receive a Message describing what the ClientApp should " -"perform." +"Number of nodes that run a ClientApp. They can be sampled by a Driver in the " +"ServerApp and receive a Message describing what the ClientApp should perform." msgstr "" #: flwr.simulation.run_simulation.run_simulation:13 of @@ -14736,26 +14978,26 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to " -"configure a backend. Values supported in are those included by " -"`flwr.common.typing.ConfigsRecordValues`." +"'A dictionary, e.g {\"\": , \"\": } to configure a " +"backend. Values supported in are those included by `flwr.common." +"typing.ConfigsRecordValues`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. " -"This is desirable if you make use of a TensorFlow model on your " -"`ServerApp` while having your `ClientApp` running on the same GPU. " -"Without enabling this, you might encounter an out-of-memory error because" -" TensorFlow, by default, allocates all GPU memory. Read more about how " -"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " -"documentation: https://www.tensorflow.org/api/stable." +"A boolean to indicate whether to enable GPU growth on the main thread. This " +"is desirable if you make use of a TensorFlow model on your `ServerApp` while " +"having your `ClientApp` running on the same GPU. Without enabling this, you " +"might encounter an out-of-memory error because TensorFlow, by default, " +"allocates all GPU memory. Read more about how `tf.config.experimental." +"set_memory_growth()` works in the TensorFlow documentation: https://www." +"tensorflow.org/api/stable." msgstr "" #: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" -" enabled, DEBUG-level logs will be displayed." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If " +"enabled, DEBUG-level logs will be displayed." msgstr "" #: ../../source/ref-api/flwr.simulation.run_simulation_from_cli.rst:2 @@ -14770,68 +15012,76 @@ msgstr "start_simulation" #: flwr.simulation.app.start_simulation:3 of msgid "" -"A function creating client instances. The function must take a single " -"`str` argument called `cid`. It should return a single client instance of" -" type Client. Note that the created client instances are ephemeral and " -"will often be destroyed after a single method invocation. Since client " -"instances are not long-lived, they should not attempt to carry state over" -" method invocations. Any state required by the instance (model, dataset, " +"A function creating client instances. The function must take a single `str` " +"argument called `cid`. It should return a single client instance of type " +"Client. Note that the created client instances are ephemeral and will often " +"be destroyed after a single method invocation. Since client instances are " +"not long-lived, they should not attempt to carry state over method " +"invocations. Any state required by the instance (model, dataset, " "hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load " -"evaluation data in the `evaluate` method itself)." +"`client_fn` or the call to any of the client methods (e.g., load evaluation " +"data in the `evaluate` method itself)." msgstr "" -"创建客户端实例的函数。该函数必须接受一个名为 `cid` 的 `str` 参数。它应返回一个 Client " -"类型的客户端实例。请注意,创建的客户端实例是短暂的,通常在调用一个方法后就会被销毁。由于客户机实例不是长期存在的,它们不应试图在方法调用时携带状态数据。实例所需的任何状态数据(模型、数据集、超参数......)都应在调用" -" `client_fn` 或任何客户端方法(例如,在 `evaluate` 方法中加载评估数据)时(重新)创建。" +"创建客户端实例的函数。该函数必须接受一个名为 `cid` 的 `str` 参数。它应返回一" +"个 Client 类型的客户端实例。请注意,创建的客户端实例是短暂的,通常在调用一个" +"方法后就会被销毁。由于客户机实例不是长期存在的,它们不应试图在方法调用时携带" +"状态数据。实例所需的任何状态数据(模型、数据集、超参数......)都应在调用 " +"`client_fn` 或任何客户端方法(例如,在 `evaluate` 方法中加载评估数据)时(重" +"新)创建。" #: flwr.simulation.app.start_simulation:13 of msgid "" "The total number of clients in this simulation. This must be set if " "`clients_ids` is not set and vice-versa." -msgstr "本次模拟的客户总数。如果未设置 `clients_ids`,则必须设置该参数,反之亦然。" +msgstr "" +"本次模拟的客户总数。如果未设置 `clients_ids`,则必须设置该参数,反之亦然。" #: flwr.simulation.app.start_simulation:16 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients`" -" is not set. Setting both `num_clients` and `clients_ids` with " +"List `client_id`s for each client. This is only required if `num_clients` is " +"not set. Setting both `num_clients` and `clients_ids` with " "`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" -"列出每个客户的 `client_id`。只有在未设置 `num_clients` " -"时才需要这样做。同时设置`num_clients`和`clients_ids`,且`len(clients_ids)`不等于`num_clients`,会产生错误。" +"列出每个客户的 `client_id`。只有在未设置 `num_clients` 时才需要这样做。同时设" +"置`num_clients`和`clients_ids`,且`len(clients_ids)`不等于`num_clients`,会产" +"生错误。" #: flwr.simulation.app.start_simulation:20 of #, fuzzy msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` " -"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " -"as well as using custom resources, please consult the Ray documentation." +"CPU and GPU resources for a single client. Supported keys are `num_cpus` and " +"`num_gpus`. To understand the GPU utilization caused by `num_gpus`, as well " +"as using custom resources, please consult the Ray documentation." msgstr "" -"\"num_gpus\": 0.0` 单个客户端的 CPU 和 GPU 资源。支持的键值为 `num_cpus` 和 `num_gpus`。要了解" -" `num_gpus` 所导致的 GPU 利用率,以及使用自定义资源的情况,请查阅 Ray 文档。" +"\"num_gpus\": 0.0` 单个客户端的 CPU 和 GPU 资源。支持的键值为 `num_cpus` 和 " +"`num_gpus`。要了解 `num_gpus` 所导致的 GPU 利用率,以及使用自定义资源的情况," +"请查阅 Ray 文档。" #: flwr.simulation.app.start_simulation:25 of msgid "" "An implementation of the abstract base class `flwr.server.Server`. If no " "instance is provided, then `start_server` will create one." -msgstr "抽象基类 `flwr.server.Server`的实现。如果没有提供实例,`start_server` 将创建一个。" +msgstr "" +"抽象基类 `flwr.server.Server`的实现。如果没有提供实例,`start_server` 将创建" +"一个。" #: flwr.simulation.app.start_simulation:31 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If " -"no strategy is provided, then `start_server` will use " -"`flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.Strategy`. If no " +"strategy is provided, then `start_server` will use `flwr.server.strategy." +"FedAvg`." msgstr "" -"抽象基类 `flwr.server.strategy` 的实现。如果没有提供策略,`start_server` 将使用 " -"`flwr.server.strategy.FedAvg`。" +"抽象基类 `flwr.server.strategy` 的实现。如果没有提供策略,`start_server` 将使" +"用 `flwr.server.strategy.FedAvg`。" #: flwr.simulation.app.start_simulation:35 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_simulation` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_simulation` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现,`start_simulation` 将使用 " -"`flwr.server.client_manager.SimpleClientManager`。" +"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," +"`start_simulation` 将使用 `flwr.server.client_manager.SimpleClientManager`。" #: flwr.simulation.app.start_simulation:39 of msgid "" @@ -14839,19 +15089,21 @@ msgid "" "ray_init_args is None (the default), Ray will be initialized with the " "following default args: { \"ignore_reinit_error\": True, " "\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to " -"ray.init." +"(ray_init_args={}) to prevent any arguments from being passed to ray.init." msgstr "" -"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认值),则将使用以下默认参数初始化 Ray:" -" { \"ignore_reinit_error\": True, \"include_dashboard\": False } " -"可以使用空字典(ray_init_args={})来防止向 ray.init 传递任何参数。" +"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认" +"值),则将使用以下默认参数初始化 Ray: { \"ignore_reinit_error\": True, " +"\"include_dashboard\": False } 可以使用空字典(ray_init_args={})来防止向 " +"ray.init 传递任何参数。" #: flwr.simulation.app.start_simulation:39 of msgid "" "Optional dictionary containing arguments for the call to `ray.init`. If " "ray_init_args is None (the default), Ray will be initialized with the " "following default args:" -msgstr "可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认值),则将使用以下默认参数初始化 Ray:" +msgstr "" +"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认" +"值),则将使用以下默认参数初始化 Ray:" #: flwr.simulation.app.start_simulation:43 of msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" @@ -14859,15 +15111,15 @@ msgstr "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" #: flwr.simulation.app.start_simulation:45 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any " -"arguments from being passed to ray.init." +"An empty dictionary can be used (ray_init_args={}) to prevent any arguments " +"from being passed to ray.init." msgstr "可以使用空字典 (ray_init_args={}) 来防止向 ray.init 传递任何参数。" #: flwr.simulation.app.start_simulation:48 of msgid "" -"Set to True to prevent `ray.shutdown()` in case " -"`ray.is_initialized()=True`." -msgstr "设为 True 可在 `ray.is_initialized()=True` 情况下阻止 `ray.shutdown()` 。" +"Set to True to prevent `ray.shutdown()` in case `ray.is_initialized()=True`." +msgstr "" +"设为 True 可在 `ray.is_initialized()=True` 情况下阻止 `ray.shutdown()` 。" #: flwr.simulation.app.start_simulation:50 of #, fuzzy @@ -14875,28 +15127,33 @@ msgid "" "Optionally specify the type of actor to use. The actor object, which " "persists throughout the simulation, will be the process in charge of " "executing a ClientApp wrapping input argument `client_fn`." -msgstr "可选择指定要使用的actor类型。actor对象将在整个模拟过程中持续存在,它将是负责运行客户端作业(即其 `fit()`方法)的进程。" +msgstr "" +"可选择指定要使用的actor类型。actor对象将在整个模拟过程中持续存在,它将是负责" +"运行客户端作业(即其 `fit()`方法)的进程。" #: flwr.simulation.app.start_simulation:54 of msgid "" -"If you want to create your own Actor classes, you might need to pass some" -" input argument. You can use this dictionary for such purpose." -msgstr "如果您想创建自己的 Actor 类,可能需要传递一些输入参数。为此,您可以使用本字典。" +"If you want to create your own Actor classes, you might need to pass some " +"input argument. You can use this dictionary for such purpose." +msgstr "" +"如果您想创建自己的 Actor 类,可能需要传递一些输入参数。为此,您可以使用本字" +"典。" #: flwr.simulation.app.start_simulation:57 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " -"the VCE to choose in which node the actor is placed. If you are an " -"advanced user needed more control you can use lower-level scheduling " -"strategies to pin actors to specific compute nodes (e.g. via " -"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." -" For all details, please refer to the Ray documentation: " -"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for the " +"VCE to choose in which node the actor is placed. If you are an advanced user " +"needed more control you can use lower-level scheduling strategies to pin " +"actors to specific compute nodes (e.g. via NodeAffinitySchedulingStrategy). " +"Please note this is an advanced feature. For all details, please refer to " +"the Ray documentation: https://docs.ray.io/en/latest/ray-core/scheduling/" +"index.html" msgstr "" -"(默认:\"DEFAULT\")可选字符串(\"DEFAULT \"或 \"SPREAD\"),供 VCE " -"选择将行为体放置在哪个节点上。如果你是需要更多控制权的高级用户,可以使用低级调度策略将actor固定到特定计算节点(例如,通过 " -"NodeAffinitySchedulingStrategy)。请注意,这是一项高级功能。有关详细信息,请参阅 Ray " -"文档:https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +"(默认:\"DEFAULT\")可选字符串(\"DEFAULT \"或 \"SPREAD\"),供 VCE 选择将行" +"为体放置在哪个节点上。如果你是需要更多控制权的高级用户,可以使用低级调度策略" +"将actor固定到特定计算节点(例如,通过 NodeAffinitySchedulingStrategy)。请注" +"意,这是一项高级功能。有关详细信息,请参阅 Ray 文档:https://docs.ray.io/en/" +"latest/ray-core/scheduling/index.html" #: flwr.simulation.app.start_simulation:66 of msgid "**hist** -- Object containing metrics from training." @@ -14947,19 +15204,21 @@ msgstr "感谢我们的贡献者" #: ../../source/ref-changelog.md:206 ../../source/ref-changelog.md:290 #: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:412 msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" -msgstr "在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` 顺序排列):" +"We would like to give our special thanks to all the contributors who made " +"the new version of Flower possible (in `git shortlog` order):" +msgstr "" +"在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` " +"顺序排列):" #: ../../source/ref-changelog.md:15 #, fuzzy msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " -"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " -"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " -"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " -"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " -"Shaaban`, `Yan Gao`, `Yasar Abbas` " +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles Beauville`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S Chaitanya Kumar`, `Mohammad " +"Naseri`, `Nikos Vlachakis`, `Pritam Neog`, `Robert Kuska`, `Robert Steiner`, " +"`Taner Topal`, `Yahia Salaheldin Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -14970,104 +15229,98 @@ msgstr "" #: ../../source/ref-changelog.md:19 #, fuzzy msgid "" -"**Introduce stateful clients (experimental)** " -"([#2770](https://github.com/adap/flower/pull/2770), " -"[#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), " -"[#2643](https://github.com/adap/flower/pull/2643), " -"[#2769](https://github.com/adap/flower/pull/2769))" +"**Introduce stateful clients (experimental)** ([#2770](https://github.com/" +"adap/flower/pull/2770), [#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), [#2643](https://github." +"com/adap/flower/pull/2643), [#2769](https://github.com/adap/flower/" +"pull/2769))" msgstr "" "** baselines的普通更新** ([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435))" +"[#2305](https://github.com/adap/flower/pull/2305), [#2307](https://github." +"com/adap/flower/pull/2307), [#2327](https://github.com/adap/flower/" +"pull/2327), [#2435](https://github.com/adap/flower/pull/2435))" #: ../../source/ref-changelog.md:21 msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via " -"`start_simulation`) and networked clients (via `start_client`). It's also" -" the first preview of new abstractions like `Context` and `RecordSet`. " -"Clients can access state of type `RecordSet` via `state: RecordSet = " -"self.context.state`. Changes to this `RecordSet` are preserved across " -"different rounds of execution to enable stateful computations in a " -"unified way across simulation and deployment." +"feature is compatible with both simulated clients (via `start_simulation`) " +"and networked clients (via `start_client`). It's also the first preview of " +"new abstractions like `Context` and `RecordSet`. Clients can access state of " +"type `RecordSet` via `state: RecordSet = self.context.state`. Changes to " +"this `RecordSet` are preserved across different rounds of execution to " +"enable stateful computations in a unified way across simulation and " +"deployment." msgstr "" #: ../../source/ref-changelog.md:23 #, fuzzy msgid "" -"**Improve performance** " -"([#2293](https://github.com/adap/flower/pull/2293))" +"**Improve performance** ([#2293](https://github.com/adap/flower/pull/2293))" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" #: ../../source/ref-changelog.md:25 msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" -"place aggregation to reduce memory consumption. The Flower client " -"serialization/deserialization has been rewritten from the ground up, " -"which results in significant speedups, especially when the client-side " -"training time is short." +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-place " +"aggregation to reduce memory consumption. The Flower client serialization/" +"deserialization has been rewritten from the ground up, which results in " +"significant speedups, especially when the client-side training time is short." msgstr "" #: ../../source/ref-changelog.md:27 #, fuzzy msgid "" -"**Support Federated Learning with Apple MLX and Flower** " -"([#2693](https://github.com/adap/flower/pull/2693))" +"**Support Federated Learning with Apple MLX and Flower** ([#2693](https://" +"github.com/adap/flower/pull/2693))" msgstr "" -"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** ([#1598](https://github." +"com/adap/flower/pull/1598))" #: ../../source/ref-changelog.md:29 msgid "" -"Flower has official support for federated learning using [Apple " -"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " -"example." +"Flower has official support for federated learning using [Apple MLX](https://" +"ml-explore.github.io/mlx) via the new `quickstart-mlx` code example." msgstr "" #: ../../source/ref-changelog.md:31 #, fuzzy msgid "" -"**Introduce new XGBoost cyclic strategy** " -"([#2666](https://github.com/adap/flower/pull/2666), " -"[#2668](https://github.com/adap/flower/pull/2668))" +"**Introduce new XGBoost cyclic strategy** ([#2666](https://github.com/adap/" +"flower/pull/2666), [#2668](https://github.com/adap/flower/pull/2668))" msgstr "" -"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/" +"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" #: ../../source/ref-changelog.md:33 msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of" -" training (often called cyclic). The `xgboost-comprehensive` code example" -" shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower " -"offers best-in-class XGBoost support." +"A new strategy called `FedXgbCyclic` supports a client-by-client style of " +"training (often called cyclic). The `xgboost-comprehensive` code example " +"shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower offers " +"best-in-class XGBoost support." msgstr "" #: ../../source/ref-changelog.md:35 #, fuzzy msgid "" -"**Support Python 3.11** " -"([#2394](https://github.com/adap/flower/pull/2394))" -msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.11** ([#2394](https://github.com/adap/flower/pull/2394))" +msgstr "" +"** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" #: ../../source/ref-changelog.md:37 msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " -"ensure better support for users using more recent Python versions." +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will ensure " +"better support for users using more recent Python versions." msgstr "" #: ../../source/ref-changelog.md:39 #, fuzzy msgid "" -"**Update gRPC and ProtoBuf dependencies** " -"([#2814](https://github.com/adap/flower/pull/2814))" +"**Update gRPC and ProtoBuf dependencies** ([#2814](https://github.com/adap/" +"flower/pull/2814))" msgstr "" -"**更新 REST API 以支持创建和删除节点** " -"([#2283](https://github.com/adap/flower/pull/2283))" +"**更新 REST API 以支持创建和删除节点** ([#2283](https://github.com/adap/" +"flower/pull/2283))" #: ../../source/ref-changelog.md:41 msgid "" @@ -15078,99 +15331,90 @@ msgstr "" #: ../../source/ref-changelog.md:43 #, fuzzy msgid "" -"**Introduce Docker image for Flower server** " -"([#2700](https://github.com/adap/flower/pull/2700), " -"[#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), " -"[#2695](https://github.com/adap/flower/pull/2695), " -"[#2747](https://github.com/adap/flower/pull/2747), " -"[#2746](https://github.com/adap/flower/pull/2746), " -"[#2680](https://github.com/adap/flower/pull/2680), " -"[#2682](https://github.com/adap/flower/pull/2682), " -"[#2701](https://github.com/adap/flower/pull/2701))" -msgstr "" -"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"**Introduce Docker image for Flower server** ([#2700](https://github.com/" +"adap/flower/pull/2700), [#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), [#2695](https://github." +"com/adap/flower/pull/2695), [#2747](https://github.com/adap/flower/" +"pull/2747), [#2746](https://github.com/adap/flower/pull/2746), [#2680]" +"(https://github.com/adap/flower/pull/2680), [#2682](https://github.com/adap/" +"flower/pull/2682), [#2701](https://github.com/adap/flower/pull/2701))" +msgstr "" +"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/" +"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" +"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" +"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" +"github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:45 msgid "" -"The Flower server can now be run using an official Docker image. A new " -"how-to guide explains [how to run Flower using " -"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html). An official Flower client Docker image will follow." +"The Flower server can now be run using an official Docker image. A new how-" +"to guide explains [how to run Flower using Docker](https://flower.ai/docs/" +"framework/how-to-run-flower-using-docker.html). An official Flower client " +"Docker image will follow." msgstr "" #: ../../source/ref-changelog.md:47 #, fuzzy msgid "" -"**Introduce** `flower-via-docker-compose` **example** " -"([#2626](https://github.com/adap/flower/pull/2626))" +"**Introduce** `flower-via-docker-compose` **example** ([#2626](https://" +"github.com/adap/flower/pull/2626))" msgstr "" -"**介绍Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" #: ../../source/ref-changelog.md:49 #, fuzzy msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** " -"([#2719](https://github.com/adap/flower/pull/2719))" -msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce** `quickstart-sklearn-tabular` **example** ([#2719](https://" +"github.com/adap/flower/pull/2719))" +msgstr "" +"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" #: ../../source/ref-changelog.md:51 #, fuzzy msgid "" -"**Introduce** `custom-metrics` **example** " -"([#1958](https://github.com/adap/flower/pull/1958))" -msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce** `custom-metrics` **example** ([#1958](https://github.com/adap/" +"flower/pull/1958))" +msgstr "" +"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" #: ../../source/ref-changelog.md:53 #, fuzzy msgid "" -"**Update code examples to use Flower Datasets** " -"([#2450](https://github.com/adap/flower/pull/2450), " -"[#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), " -"[#2712](https://github.com/adap/flower/pull/2712))" +"**Update code examples to use Flower Datasets** ([#2450](https://github.com/" +"adap/flower/pull/2450), [#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), [#2712](https://github." +"com/adap/flower/pull/2712))" msgstr "" -"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310)" +"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), [#1276]" +"(https://github.com/adap/flower/pull/1276), [#1301](https://github.com/adap/" +"flower/pull/1301), [#1310](https://github.com/adap/flower/pull/1310)" #: ../../source/ref-changelog.md:55 msgid "" -"Several code examples were updated to use [Flower " -"Datasets](https://flower.ai/docs/datasets/)." +"Several code examples were updated to use [Flower Datasets](https://flower." +"ai/docs/datasets/)." msgstr "" #: ../../source/ref-changelog.md:57 #, fuzzy msgid "" -"**General updates to Flower Examples** " -"([#2381](https://github.com/adap/flower/pull/2381), " -"[#2805](https://github.com/adap/flower/pull/2805), " -"[#2782](https://github.com/adap/flower/pull/2782), " -"[#2806](https://github.com/adap/flower/pull/2806), " -"[#2829](https://github.com/adap/flower/pull/2829), " -"[#2825](https://github.com/adap/flower/pull/2825), " -"[#2816](https://github.com/adap/flower/pull/2816), " -"[#2726](https://github.com/adap/flower/pull/2726), " -"[#2659](https://github.com/adap/flower/pull/2659), " -"[#2655](https://github.com/adap/flower/pull/2655))" -msgstr "" -"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/flower/pull/1663)," -" [#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**General updates to Flower Examples** ([#2381](https://github.com/adap/" +"flower/pull/2381), [#2805](https://github.com/adap/flower/pull/2805), [#2782]" +"(https://github.com/adap/flower/pull/2782), [#2806](https://github.com/adap/" +"flower/pull/2806), [#2829](https://github.com/adap/flower/pull/2829), [#2825]" +"(https://github.com/adap/flower/pull/2825), [#2816](https://github.com/adap/" +"flower/pull/2816), [#2726](https://github.com/adap/flower/pull/2726), [#2659]" +"(https://github.com/adap/flower/pull/2659), [#2655](https://github.com/adap/" +"flower/pull/2655))" +msgstr "" +"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/" +"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" +"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" +"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" +"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" +"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" +"(https://github.com/adap/flower/pull/1794))" #: ../../source/ref-changelog.md:59 msgid "Many Flower code examples received substantial updates." @@ -15183,11 +15427,11 @@ msgstr "**更新 Flower Baselines**" #: ../../source/ref-changelog.md:63 #, fuzzy msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " -"[#2771](https://github.com/adap/flower/pull/2771))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), [#2771]" +"(https://github.com/adap/flower/pull/2771))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" #: ../../source/ref-changelog.md:64 #, fuzzy @@ -15217,172 +15461,138 @@ msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" #: ../../source/ref-changelog.md:70 #, fuzzy msgid "" -"**Improve documentation** " -"([#2674](https://github.com/adap/flower/pull/2674), " -"[#2480](https://github.com/adap/flower/pull/2480), " -"[#2826](https://github.com/adap/flower/pull/2826), " -"[#2727](https://github.com/adap/flower/pull/2727), " -"[#2761](https://github.com/adap/flower/pull/2761), " -"[#2900](https://github.com/adap/flower/pull/2900))" +"**Improve documentation** ([#2674](https://github.com/adap/flower/" +"pull/2674), [#2480](https://github.com/adap/flower/pull/2480), [#2826]" +"(https://github.com/adap/flower/pull/2826), [#2727](https://github.com/adap/" +"flower/pull/2727), [#2761](https://github.com/adap/flower/pull/2761), [#2900]" +"(https://github.com/adap/flower/pull/2900))" msgstr "" -"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614)))" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), [#1628]" +"(https://github.com/adap/flower/pull/1628), [#1620](https://github.com/adap/" +"flower/pull/1620), [#1618](https://github.com/adap/flower/pull/1618), [#1617]" +"(https://github.com/adap/flower/pull/1617), [#1613](https://github.com/adap/" +"flower/pull/1613), [#1614](https://github.com/adap/flower/pull/1614)))" #: ../../source/ref-changelog.md:72 msgid "" -"**Improved testing and development infrastructure** " -"([#2797](https://github.com/adap/flower/pull/2797), " -"[#2676](https://github.com/adap/flower/pull/2676), " -"[#2644](https://github.com/adap/flower/pull/2644), " -"[#2656](https://github.com/adap/flower/pull/2656), " -"[#2848](https://github.com/adap/flower/pull/2848), " -"[#2675](https://github.com/adap/flower/pull/2675), " -"[#2735](https://github.com/adap/flower/pull/2735), " -"[#2767](https://github.com/adap/flower/pull/2767), " -"[#2732](https://github.com/adap/flower/pull/2732), " -"[#2744](https://github.com/adap/flower/pull/2744), " -"[#2681](https://github.com/adap/flower/pull/2681), " -"[#2699](https://github.com/adap/flower/pull/2699), " -"[#2745](https://github.com/adap/flower/pull/2745), " -"[#2734](https://github.com/adap/flower/pull/2734), " -"[#2731](https://github.com/adap/flower/pull/2731), " -"[#2652](https://github.com/adap/flower/pull/2652), " -"[#2720](https://github.com/adap/flower/pull/2720), " -"[#2721](https://github.com/adap/flower/pull/2721), " -"[#2717](https://github.com/adap/flower/pull/2717), " -"[#2864](https://github.com/adap/flower/pull/2864), " -"[#2694](https://github.com/adap/flower/pull/2694), " -"[#2709](https://github.com/adap/flower/pull/2709), " -"[#2658](https://github.com/adap/flower/pull/2658), " -"[#2796](https://github.com/adap/flower/pull/2796), " -"[#2692](https://github.com/adap/flower/pull/2692), " -"[#2657](https://github.com/adap/flower/pull/2657), " -"[#2813](https://github.com/adap/flower/pull/2813), " -"[#2661](https://github.com/adap/flower/pull/2661), " -"[#2398](https://github.com/adap/flower/pull/2398))" +"**Improved testing and development infrastructure** ([#2797](https://github." +"com/adap/flower/pull/2797), [#2676](https://github.com/adap/flower/" +"pull/2676), [#2644](https://github.com/adap/flower/pull/2644), [#2656]" +"(https://github.com/adap/flower/pull/2656), [#2848](https://github.com/adap/" +"flower/pull/2848), [#2675](https://github.com/adap/flower/pull/2675), [#2735]" +"(https://github.com/adap/flower/pull/2735), [#2767](https://github.com/adap/" +"flower/pull/2767), [#2732](https://github.com/adap/flower/pull/2732), [#2744]" +"(https://github.com/adap/flower/pull/2744), [#2681](https://github.com/adap/" +"flower/pull/2681), [#2699](https://github.com/adap/flower/pull/2699), [#2745]" +"(https://github.com/adap/flower/pull/2745), [#2734](https://github.com/adap/" +"flower/pull/2734), [#2731](https://github.com/adap/flower/pull/2731), [#2652]" +"(https://github.com/adap/flower/pull/2652), [#2720](https://github.com/adap/" +"flower/pull/2720), [#2721](https://github.com/adap/flower/pull/2721), [#2717]" +"(https://github.com/adap/flower/pull/2717), [#2864](https://github.com/adap/" +"flower/pull/2864), [#2694](https://github.com/adap/flower/pull/2694), [#2709]" +"(https://github.com/adap/flower/pull/2709), [#2658](https://github.com/adap/" +"flower/pull/2658), [#2796](https://github.com/adap/flower/pull/2796), [#2692]" +"(https://github.com/adap/flower/pull/2692), [#2657](https://github.com/adap/" +"flower/pull/2657), [#2813](https://github.com/adap/flower/pull/2813), [#2661]" +"(https://github.com/adap/flower/pull/2661), [#2398](https://github.com/adap/" +"flower/pull/2398))" msgstr "" #: ../../source/ref-changelog.md:74 msgid "" -"The Flower testing and development infrastructure has received " -"substantial updates. This makes Flower 1.7 the most tested release ever." +"The Flower testing and development infrastructure has received substantial " +"updates. This makes Flower 1.7 the most tested release ever." msgstr "" #: ../../source/ref-changelog.md:76 #, fuzzy msgid "" -"**Update dependencies** " -"([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), " -"[#2739](https://github.com/adap/flower/pull/2739), " -"[#2837](https://github.com/adap/flower/pull/2837), " -"[#2788](https://github.com/adap/flower/pull/2788), " -"[#2811](https://github.com/adap/flower/pull/2811), " -"[#2774](https://github.com/adap/flower/pull/2774), " -"[#2790](https://github.com/adap/flower/pull/2790), " -"[#2751](https://github.com/adap/flower/pull/2751), " -"[#2850](https://github.com/adap/flower/pull/2850), " -"[#2812](https://github.com/adap/flower/pull/2812), " -"[#2872](https://github.com/adap/flower/pull/2872), " -"[#2736](https://github.com/adap/flower/pull/2736), " -"[#2756](https://github.com/adap/flower/pull/2756), " -"[#2857](https://github.com/adap/flower/pull/2857), " -"[#2757](https://github.com/adap/flower/pull/2757), " -"[#2810](https://github.com/adap/flower/pull/2810), " -"[#2740](https://github.com/adap/flower/pull/2740), " -"[#2789](https://github.com/adap/flower/pull/2789))" -msgstr "" -"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"**Update dependencies** ([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), [#2739](https://github." +"com/adap/flower/pull/2739), [#2837](https://github.com/adap/flower/" +"pull/2837), [#2788](https://github.com/adap/flower/pull/2788), [#2811]" +"(https://github.com/adap/flower/pull/2811), [#2774](https://github.com/adap/" +"flower/pull/2774), [#2790](https://github.com/adap/flower/pull/2790), [#2751]" +"(https://github.com/adap/flower/pull/2751), [#2850](https://github.com/adap/" +"flower/pull/2850), [#2812](https://github.com/adap/flower/pull/2812), [#2872]" +"(https://github.com/adap/flower/pull/2872), [#2736](https://github.com/adap/" +"flower/pull/2736), [#2756](https://github.com/adap/flower/pull/2756), [#2857]" +"(https://github.com/adap/flower/pull/2857), [#2757](https://github.com/adap/" +"flower/pull/2757), [#2810](https://github.com/adap/flower/pull/2810), [#2740]" +"(https://github.com/adap/flower/pull/2740), [#2789](https://github.com/adap/" +"flower/pull/2789))" +msgstr "" +"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), [#1873]" +"(https://github.com/adap/flower/pull/1873), [#1981](https://github.com/adap/" +"flower/pull/1981), [#1988](https://github.com/adap/flower/pull/1988), [#1984]" +"(https://github.com/adap/flower/pull/1984), [#1982](https://github.com/adap/" +"flower/pull/1982), [#2112](https://github.com/adap/flower/pull/2112), [#2144]" +"(https://github.com/adap/flower/pull/2144), [#2174](https://github.com/adap/" +"flower/pull/2174), [#2225](https://github.com/adap/flower/pull/2225), [#2183]" +"(https://github.com/adap/flower/pull/2183))" #: ../../source/ref-changelog.md:78 msgid "" -"**General improvements** " -"([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), " -"[#2877](https://github.com/adap/flower/pull/2877), " -"[#2690](https://github.com/adap/flower/pull/2690), " -"[#2889](https://github.com/adap/flower/pull/2889), " -"[#2874](https://github.com/adap/flower/pull/2874), " -"[#2819](https://github.com/adap/flower/pull/2819), " -"[#2689](https://github.com/adap/flower/pull/2689), " -"[#2457](https://github.com/adap/flower/pull/2457), " -"[#2870](https://github.com/adap/flower/pull/2870), " -"[#2669](https://github.com/adap/flower/pull/2669), " -"[#2876](https://github.com/adap/flower/pull/2876), " -"[#2885](https://github.com/adap/flower/pull/2885), " -"[#2858](https://github.com/adap/flower/pull/2858), " -"[#2867](https://github.com/adap/flower/pull/2867), " -"[#2351](https://github.com/adap/flower/pull/2351), " -"[#2886](https://github.com/adap/flower/pull/2886), " -"[#2860](https://github.com/adap/flower/pull/2860), " -"[#2828](https://github.com/adap/flower/pull/2828), " -"[#2869](https://github.com/adap/flower/pull/2869), " -"[#2875](https://github.com/adap/flower/pull/2875), " -"[#2733](https://github.com/adap/flower/pull/2733), " -"[#2488](https://github.com/adap/flower/pull/2488), " -"[#2646](https://github.com/adap/flower/pull/2646), " -"[#2879](https://github.com/adap/flower/pull/2879), " -"[#2821](https://github.com/adap/flower/pull/2821), " -"[#2855](https://github.com/adap/flower/pull/2855), " -"[#2800](https://github.com/adap/flower/pull/2800), " -"[#2807](https://github.com/adap/flower/pull/2807), " -"[#2801](https://github.com/adap/flower/pull/2801), " -"[#2804](https://github.com/adap/flower/pull/2804), " -"[#2851](https://github.com/adap/flower/pull/2851), " -"[#2787](https://github.com/adap/flower/pull/2787), " -"[#2852](https://github.com/adap/flower/pull/2852), " -"[#2672](https://github.com/adap/flower/pull/2672), " -"[#2759](https://github.com/adap/flower/pull/2759))" +"**General improvements** ([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." +"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/" +"pull/2690), [#2889](https://github.com/adap/flower/pull/2889), [#2874]" +"(https://github.com/adap/flower/pull/2874), [#2819](https://github.com/adap/" +"flower/pull/2819), [#2689](https://github.com/adap/flower/pull/2689), [#2457]" +"(https://github.com/adap/flower/pull/2457), [#2870](https://github.com/adap/" +"flower/pull/2870), [#2669](https://github.com/adap/flower/pull/2669), [#2876]" +"(https://github.com/adap/flower/pull/2876), [#2885](https://github.com/adap/" +"flower/pull/2885), [#2858](https://github.com/adap/flower/pull/2858), [#2867]" +"(https://github.com/adap/flower/pull/2867), [#2351](https://github.com/adap/" +"flower/pull/2351), [#2886](https://github.com/adap/flower/pull/2886), [#2860]" +"(https://github.com/adap/flower/pull/2860), [#2828](https://github.com/adap/" +"flower/pull/2828), [#2869](https://github.com/adap/flower/pull/2869), [#2875]" +"(https://github.com/adap/flower/pull/2875), [#2733](https://github.com/adap/" +"flower/pull/2733), [#2488](https://github.com/adap/flower/pull/2488), [#2646]" +"(https://github.com/adap/flower/pull/2646), [#2879](https://github.com/adap/" +"flower/pull/2879), [#2821](https://github.com/adap/flower/pull/2821), [#2855]" +"(https://github.com/adap/flower/pull/2855), [#2800](https://github.com/adap/" +"flower/pull/2800), [#2807](https://github.com/adap/flower/pull/2807), [#2801]" +"(https://github.com/adap/flower/pull/2801), [#2804](https://github.com/adap/" +"flower/pull/2804), [#2851](https://github.com/adap/flower/pull/2851), [#2787]" +"(https://github.com/adap/flower/pull/2787), [#2852](https://github.com/adap/" +"flower/pull/2852), [#2672](https://github.com/adap/flower/pull/2672), [#2759]" +"(https://github.com/adap/flower/pull/2759))" msgstr "" #: ../../source/ref-changelog.md:82 #, fuzzy msgid "" -"**Deprecate** `start_numpy_client` " -"([#2563](https://github.com/adap/flower/pull/2563), " -"[#2718](https://github.com/adap/flower/pull/2718))" +"**Deprecate** `start_numpy_client` ([#2563](https://github.com/adap/flower/" +"pull/2563), [#2718](https://github.com/adap/flower/pull/2718))" msgstr "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" +"github.com/adap/flower/pull/2508))" #: ../../source/ref-changelog.md:84 msgid "" "Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we " -"have introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need " -"to first call the `.to_client()` method and then pass returned `Client` " -"object to `start_client`. The examples and the documentation have been " -"updated accordingly." +"`start_numpy_client`. In our efforts to consolidate framework APIs, we have " +"introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need to " +"first call the `.to_client()` method and then pass returned `Client` object " +"to `start_client`. The examples and the documentation have been updated " +"accordingly." msgstr "" #: ../../source/ref-changelog.md:86 #, fuzzy msgid "" -"**Deprecate legacy DP wrappers** " -"([#2749](https://github.com/adap/flower/pull/2749))" -msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" +"**Deprecate legacy DP wrappers** ([#2749](https://github.com/adap/flower/" +"pull/2749))" +msgstr "" +"**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" #: ../../source/ref-changelog.md:88 msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is " -"in preparation for an all-new pluggable version of differential privacy " -"support in Flower." +"Legacy DP wrapper classes are deprecated, but still functional. This is in " +"preparation for an all-new pluggable version of differential privacy support " +"in Flower." msgstr "" #: ../../source/ref-changelog.md:90 @@ -15391,41 +15601,41 @@ msgid "" "**Make optional arg** `--callable` **in** `flower-client` **a required " "positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" -"**从** `start_client` 中移除** `rest` **实验参数 " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**从** `start_client` 中移除** `rest` **实验参数 ([#2324](https://github.com/" +"adap/flower/pull/2324))" #: ../../source/ref-changelog.md:92 #, fuzzy msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " -"([#2890](https://github.com/adap/flower/pull/2890))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` ([#2890]" +"(https://github.com/adap/flower/pull/2890))" msgstr "" -"**重新命名** `rnd` ** to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**重新命名** `rnd` ** to** `server_round` ([#1321](https://github.com/adap/" +"flower/pull/1321))" #: ../../source/ref-changelog.md:94 #, fuzzy msgid "" -"**Drop experimental** `Task` **fields** " -"([#2866](https://github.com/adap/flower/pull/2866), " -"[#2865](https://github.com/adap/flower/pull/2865))" +"**Drop experimental** `Task` **fields** ([#2866](https://github.com/adap/" +"flower/pull/2866), [#2865](https://github.com/adap/flower/pull/2865))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" #: ../../source/ref-changelog.md:96 msgid "" "Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed " -"fields are superseded by the new `RecordSet` abstraction." +"`legacy_client_message` were removed from `Task` message. The removed fields " +"are superseded by the new `RecordSet` abstraction." msgstr "" #: ../../source/ref-changelog.md:98 #, fuzzy msgid "" -"**Retire MXNet examples** " -"([#2724](https://github.com/adap/flower/pull/2724))" -msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" +"**Retire MXNet examples** ([#2724](https://github.com/adap/flower/pull/2724))" +msgstr "" +"**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/" +"pull/748))" #: ../../source/ref-changelog.md:100 msgid "" @@ -15443,82 +15653,82 @@ msgstr "v1.4.0 (2023-04-21)" msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," -" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " -"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " -"`cnxdeveloper`, `k3nfalt` " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, " +"`Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " +"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " +"`k3nfalt` " msgstr "" #: ../../source/ref-changelog.md:112 msgid "" -"**Add experimental support for Python 3.12** " -"([#2565](https://github.com/adap/flower/pull/2565))" +"**Add experimental support for Python 3.12** ([#2565](https://github.com/" +"adap/flower/pull/2565))" msgstr "" -"** 增加对 Python 3.12 的实验支持** " -"([#2565](https://github.com/adap/flower/pull/2565))" +"** 增加对 Python 3.12 的实验支持** ([#2565](https://github.com/adap/flower/" +"pull/2565))" #: ../../source/ref-changelog.md:114 #, fuzzy msgid "" -"**Add new XGBoost examples** " -"([#2612](https://github.com/adap/flower/pull/2612), " -"[#2554](https://github.com/adap/flower/pull/2554), " -"[#2617](https://github.com/adap/flower/pull/2617), " -"[#2618](https://github.com/adap/flower/pull/2618), " -"[#2619](https://github.com/adap/flower/pull/2619), " -"[#2567](https://github.com/adap/flower/pull/2567))" +"**Add new XGBoost examples** ([#2612](https://github.com/adap/flower/" +"pull/2612), [#2554](https://github.com/adap/flower/pull/2554), [#2617]" +"(https://github.com/adap/flower/pull/2617), [#2618](https://github.com/adap/" +"flower/pull/2618), [#2619](https://github.com/adap/flower/pull/2619), [#2567]" +"(https://github.com/adap/flower/pull/2567))" msgstr "" -"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/pull/1520)," -" [#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/" +"pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" +"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" +"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" +"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" +"flower/pull/1567))" #: ../../source/ref-changelog.md:116 msgid "" -"We have added a new `xgboost-quickstart` example alongside a new " -"`xgboost-comprehensive` example that goes more in-depth." +"We have added a new `xgboost-quickstart` example alongside a new `xgboost-" +"comprehensive` example that goes more in-depth." msgstr "" #: ../../source/ref-changelog.md:118 #, fuzzy msgid "" -"**Add Vertical FL example** " -"([#2598](https://github.com/adap/flower/pull/2598))" -msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" +"**Add Vertical FL example** ([#2598](https://github.com/adap/flower/" +"pull/2598))" +msgstr "" +"**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/" +"pull/1289))" #: ../../source/ref-changelog.md:120 msgid "" -"We had many questions about Vertical Federated Learning using Flower, so " -"we decided to add an simple example for it on the [Titanic " -"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " -"tutorial (in the README)." +"We had many questions about Vertical Federated Learning using Flower, so we " +"decided to add an simple example for it on the [Titanic dataset](https://www." +"kaggle.com/competitions/titanic/data) alongside a tutorial (in the README)." msgstr "" #: ../../source/ref-changelog.md:122 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` " -"([#2292](https://github.com/adap/flower/pull/2292))" -msgstr "**在***`start_driver()`中支持自定义***`ClientManager([#2292](https://github.com/adap/flower/pull/2292))" +"**Support custom** `ClientManager` **in** `start_driver()` ([#2292](https://" +"github.com/adap/flower/pull/2292))" +msgstr "" +"**在***`start_driver()`中支持自定义***`ClientManager([#2292](https://github." +"com/adap/flower/pull/2292))" #: ../../source/ref-changelog.md:124 msgid "" -"**Update REST API to support create and delete nodes** " -"([#2283](https://github.com/adap/flower/pull/2283))" +"**Update REST API to support create and delete nodes** ([#2283](https://" +"github.com/adap/flower/pull/2283))" msgstr "" -"**更新 REST API 以支持创建和删除节点** " -"([#2283](https://github.com/adap/flower/pull/2283))" +"**更新 REST API 以支持创建和删除节点** ([#2283](https://github.com/adap/" +"flower/pull/2283))" #: ../../source/ref-changelog.md:126 #, fuzzy msgid "" -"**Update the Android SDK** " -"([#2187](https://github.com/adap/flower/pull/2187))" +"**Update the Android SDK** ([#2187](https://github.com/adap/flower/" +"pull/2187))" msgstr "" -"**介绍Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" #: ../../source/ref-changelog.md:128 #, fuzzy @@ -15528,16 +15738,14 @@ msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" #: ../../source/ref-changelog.md:130 #, fuzzy msgid "" -"**Update the C++ SDK** " -"([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"**Update the C++ SDK** ([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), [#2523](https://github." +"com/adap/flower/pull/2523), [#2522](https://github.com/adap/flower/" +"pull/2522))" msgstr "" -"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), " -"[#2528](https://github/com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), [#2528]" +"(https://github/com/adap/flower/pull/2528), [#2523](https://github.com/adap/" +"flower/pull/2523), [#2522](https://github.com/adap/flower/pull/2522))" #: ../../source/ref-changelog.md:132 msgid "Add gRPC request-response capability to the C++ SDK." @@ -15546,118 +15754,119 @@ msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" #: ../../source/ref-changelog.md:134 #, fuzzy msgid "" -"**Make HTTPS the new default** " -"([#2591](https://github.com/adap/flower/pull/2591), " -"[#2636](https://github.com/adap/flower/pull/2636))" +"**Make HTTPS the new default** ([#2591](https://github.com/adap/flower/" +"pull/2591), [#2636](https://github.com/adap/flower/pull/2636))" msgstr "" -"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400)" +"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), [#2400]" +"(https://github.com/adap/flower/pull/2400)" #: ../../source/ref-changelog.md:136 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP " -"for prototyping. The same applies to `flower-client`, which can either " -"use user-provided credentials or gRPC-bundled certificates to connect to " -"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " -"enable insecure HTTP connections." +"passing `--certificates`, but users can enable `--insecure` to use HTTP for " +"prototyping. The same applies to `flower-client`, which can either use user-" +"provided credentials or gRPC-bundled certificates to connect to an HTTPS-" +"enabled server or requires opt-out via passing `--insecure` to enable " +"insecure HTTP connections." msgstr "" #: ../../source/ref-changelog.md:138 msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` " -"will still start in insecure mode by default. In a future release, " -"insecure connections will require user opt-in by passing `insecure=True`." +"For backward compatibility, `start_client()` and `start_numpy_client()` will " +"still start in insecure mode by default. In a future release, insecure " +"connections will require user opt-in by passing `insecure=True`." msgstr "" #: ../../source/ref-changelog.md:140 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"[#2390](https://github.com/adap/flower/pull/2390), [#2493](https://github." +"com/adap/flower/pull/2493))" msgstr "" -"** 统一客户端应用程序接口** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"** 统一客户端应用程序接口** ([#2303](https://github.com/adap/flower/" +"pull/2303), [#2390](https://github.com/adap/flower/pull/2390), [#2493]" +"(https://github.com/adap/flower/pull/2493))" #: ../../source/ref-changelog.md:142 #, fuzzy msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as " -"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" -" `start_simulation`) without requiring changes to how the client class is" -" defined and instantiated. The `to_client()` function is introduced to " +"Using the `client_fn`, Flower clients can interchangeably run as standalone " +"processes (i.e. via `start_client`) or in simulation (i.e. via " +"`start_simulation`) without requiring changes to how the client class is " +"defined and instantiated. The `to_client()` function is introduced to " "convert a `NumPyClient` to a `Client`." msgstr "" -"使用 `client_fn`,Flower 客户端可以作为独立进程(即通过 `start_client`)或在模拟中(即通过 " -"`start_simulation`)交替运行,而无需更改客户端类的定义和实例化方式。调用 `start_numpy_client` 现已过时。" +"使用 `client_fn`,Flower 客户端可以作为独立进程(即通过 `start_client`)或在" +"模拟中(即通过 `start_simulation`)交替运行,而无需更改客户端类的定义和实例化" +"方式。调用 `start_numpy_client` 现已过时。" #: ../../source/ref-changelog.md:144 msgid "" -"**Add new** `Bulyan` **strategy** " -"([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891))" +"**Add new** `Bulyan` **strategy** ([#1817](https://github.com/adap/flower/" +"pull/1817), [#1891](https://github.com/adap/flower/pull/1891))" msgstr "" -"**添加新**\"Bulyan " -"\"**策略**([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891)" +"**添加新**\"Bulyan \"**策略**([#1817](https://github.com/adap/flower/" +"pull/1817), [#1891](https://github.com/adap/flower/pull/1891)" #: ../../source/ref-changelog.md:146 msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " -"2018](https://arxiv.org/abs/1802.07927)" -msgstr "新的 \"Bulyan\"策略通过[El Mhamdi 等人,2018](https://arxiv.org/abs/1802.07927)实现" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., 2018]" +"(https://arxiv.org/abs/1802.07927)" +msgstr "" +"新的 \"Bulyan\"策略通过[El Mhamdi 等人,2018](https://arxiv.org/" +"abs/1802.07927)实现" #: ../../source/ref-changelog.md:148 #, fuzzy msgid "" -"**Add new** `XGB Bagging` **strategy** " -"([#2611](https://github.com/adap/flower/pull/2611))" -msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" +"**Add new** `XGB Bagging` **strategy** ([#2611](https://github.com/adap/" +"flower/pull/2611))" +msgstr "" +"**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/" +"pull/1619))" #: ../../source/ref-changelog.md:150 ../../source/ref-changelog.md:152 #, fuzzy msgid "" -"**Introduce `WorkloadState`** " -"([#2564](https://github.com/adap/flower/pull/2564), " -"[#2632](https://github.com/adap/flower/pull/2632))" +"**Introduce `WorkloadState`** ([#2564](https://github.com/adap/flower/" +"pull/2564), [#2632](https://github.com/adap/flower/pull/2632))" msgstr "" -"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822)" +"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) [#822]" +"(https://github.com/adap/flower/pull/822)" #: ../../source/ref-changelog.md:156 msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" +"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" +"pull/2509))" msgstr "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" +"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" +"pull/2509))" #: ../../source/ref-changelog.md:158 msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), [#2400]" +"(https://github.com/adap/flower/pull/2400))" msgstr "" -"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400)" +"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), [#2400]" +"(https://github.com/adap/flower/pull/2400)" #: ../../source/ref-changelog.md:160 msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" +"github.com/adap/flower/pull/2507))" msgstr "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" +"github.com/adap/flower/pull/2507))" #: ../../source/ref-changelog.md:162 msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" +"github.com/adap/flower/pull/2508))" msgstr "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" +"github.com/adap/flower/pull/2508))" #: ../../source/ref-changelog.md:164 msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" @@ -15689,165 +15898,142 @@ msgstr "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" #: ../../source/ref-changelog.md:178 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" #: ../../source/ref-changelog.md:180 #, fuzzy msgid "" -"**General updates to Flower Examples** " -"([#2384](https://github.com/adap/flower/pull/2384), " -"[#2425](https://github.com/adap/flower/pull/2425), " -"[#2526](https://github.com/adap/flower/pull/2526), " -"[#2302](https://github.com/adap/flower/pull/2302), " -"[#2545](https://github.com/adap/flower/pull/2545))" +"**General updates to Flower Examples** ([#2384](https://github.com/adap/" +"flower/pull/2384), [#2425](https://github.com/adap/flower/pull/2425), [#2526]" +"(https://github.com/adap/flower/pull/2526), [#2302](https://github.com/adap/" +"flower/pull/2302), [#2545](https://github.com/adap/flower/pull/2545))" msgstr "" -"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), " -"[#2528](https://github/com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), [#2528]" +"(https://github/com/adap/flower/pull/2528), [#2523](https://github.com/adap/" +"flower/pull/2523), [#2522](https://github.com/adap/flower/pull/2522))" #: ../../source/ref-changelog.md:182 #, fuzzy msgid "" -"**General updates to Flower Baselines** " -"([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435), " -"[#2462](https://github.com/adap/flower/pull/2462), " -"[#2463](https://github.com/adap/flower/pull/2463), " -"[#2461](https://github.com/adap/flower/pull/2461), " -"[#2469](https://github.com/adap/flower/pull/2469), " -"[#2466](https://github.com/adap/flower/pull/2466), " -"[#2471](https://github.com/adap/flower/pull/2471), " -"[#2472](https://github.com/adap/flower/pull/2472), " -"[#2470](https://github.com/adap/flower/pull/2470))" -msgstr "" -"**普通改进**([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[2317](https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/flower/pull/2349)," -" [#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446) " -"[#2561](https://github.com/adap/flower/pull/2561))" +"**General updates to Flower Baselines** ([#2301](https://github.com/adap/" +"flower/pull/2301), [#2305](https://github.com/adap/flower/pull/2305), [#2307]" +"(https://github.com/adap/flower/pull/2307), [#2327](https://github.com/adap/" +"flower/pull/2327), [#2435](https://github.com/adap/flower/pull/2435), [#2462]" +"(https://github.com/adap/flower/pull/2462), [#2463](https://github.com/adap/" +"flower/pull/2463), [#2461](https://github.com/adap/flower/pull/2461), [#2469]" +"(https://github.com/adap/flower/pull/2469), [#2466](https://github.com/adap/" +"flower/pull/2466), [#2471](https://github.com/adap/flower/pull/2471), [#2472]" +"(https://github.com/adap/flower/pull/2472), [#2470](https://github.com/adap/" +"flower/pull/2470))" +msgstr "" +"**普通改进**([#2309](https://github.com/adap/flower/pull/2309), [#2310]" +"(https://github.com/adap/flower/pull/2310), [2313](https://github.com/adap/" +"flower/pull/2313), [#2316](https://github.com/adap/flower/pull/2316), [2317]" +"(https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/" +"flower/pull/2349), [#2360](https://github.com/adap/flower/pull/2360), [#2402]" +"(https://github.com/adap/flower/pull/2402), [#2446](https://github.com/adap/" +"flower/pull/2446) [#2561](https://github.com/adap/flower/pull/2561))" #: ../../source/ref-changelog.md:184 #, fuzzy msgid "" -"**General updates to the simulation engine** " -"([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), " -"[#2294](https://github.com/adap/flower/pull/2294))" +"**General updates to the simulation engine** ([#2331](https://github.com/" +"adap/flower/pull/2331), [#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), [#2294](https://github." +"com/adap/flower/pull/2294))" msgstr "" "**模拟引擎的普通更新** ([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448))" +"[#2447](https://github.com/adap/flower/pull/2447), [#2448](https://github." +"com/adap/flower/pull/2448))" #: ../../source/ref-changelog.md:186 #, fuzzy msgid "" -"**General updates to Flower SDKs** " -"([#2288](https://github.com/adap/flower/pull/2288), " -"[#2429](https://github.com/adap/flower/pull/2429), " -"[#2555](https://github.com/adap/flower/pull/2555), " -"[#2543](https://github.com/adap/flower/pull/2543), " -"[#2544](https://github.com/adap/flower/pull/2544), " -"[#2597](https://github.com/adap/flower/pull/2597), " -"[#2623](https://github.com/adap/flower/pull/2623))" +"**General updates to Flower SDKs** ([#2288](https://github.com/adap/flower/" +"pull/2288), [#2429](https://github.com/adap/flower/pull/2429), [#2555]" +"(https://github.com/adap/flower/pull/2555), [#2543](https://github.com/adap/" +"flower/pull/2543), [#2544](https://github.com/adap/flower/pull/2544), [#2597]" +"(https://github.com/adap/flower/pull/2597), [#2623](https://github.com/adap/" +"flower/pull/2623))" msgstr "" -"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " -"[#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475)))" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), [#1470]" +"(https://github.com/adap/flower/pull/1470), [#1472](https://github.com/adap/" +"flower/pull/1472), [#1473](https://github.com/adap/flower/pull/1473), [#1474]" +"(https://github.com/adap/flower/pull/1474), [#1475](https://github.com/adap/" +"flower/pull/1475)))" #: ../../source/ref-changelog.md:188 msgid "" -"**General improvements** " -"([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[#2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[#2317](https://github.com/adap/flower/pull/2317), " -"[#2349](https://github.com/adap/flower/pull/2349), " -"[#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446), " -"[#2561](https://github.com/adap/flower/pull/2561), " -"[#2273](https://github.com/adap/flower/pull/2273), " -"[#2267](https://github.com/adap/flower/pull/2267), " -"[#2274](https://github.com/adap/flower/pull/2274), " -"[#2275](https://github.com/adap/flower/pull/2275), " -"[#2432](https://github.com/adap/flower/pull/2432), " -"[#2251](https://github.com/adap/flower/pull/2251), " -"[#2321](https://github.com/adap/flower/pull/2321), " -"[#1936](https://github.com/adap/flower/pull/1936), " -"[#2408](https://github.com/adap/flower/pull/2408), " -"[#2413](https://github.com/adap/flower/pull/2413), " -"[#2401](https://github.com/adap/flower/pull/2401), " -"[#2531](https://github.com/adap/flower/pull/2531), " -"[#2534](https://github.com/adap/flower/pull/2534), " -"[#2535](https://github.com/adap/flower/pull/2535), " -"[#2521](https://github.com/adap/flower/pull/2521), " -"[#2553](https://github.com/adap/flower/pull/2553), " -"[#2596](https://github.com/adap/flower/pull/2596))" +"**General improvements** ([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." +"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/" +"pull/2316), [#2317](https://github.com/adap/flower/pull/2317), [#2349]" +"(https://github.com/adap/flower/pull/2349), [#2360](https://github.com/adap/" +"flower/pull/2360), [#2402](https://github.com/adap/flower/pull/2402), [#2446]" +"(https://github.com/adap/flower/pull/2446), [#2561](https://github.com/adap/" +"flower/pull/2561), [#2273](https://github.com/adap/flower/pull/2273), [#2267]" +"(https://github.com/adap/flower/pull/2267), [#2274](https://github.com/adap/" +"flower/pull/2274), [#2275](https://github.com/adap/flower/pull/2275), [#2432]" +"(https://github.com/adap/flower/pull/2432), [#2251](https://github.com/adap/" +"flower/pull/2251), [#2321](https://github.com/adap/flower/pull/2321), [#1936]" +"(https://github.com/adap/flower/pull/1936), [#2408](https://github.com/adap/" +"flower/pull/2408), [#2413](https://github.com/adap/flower/pull/2413), [#2401]" +"(https://github.com/adap/flower/pull/2401), [#2531](https://github.com/adap/" +"flower/pull/2531), [#2534](https://github.com/adap/flower/pull/2534), [#2535]" +"(https://github.com/adap/flower/pull/2535), [#2521](https://github.com/adap/" +"flower/pull/2521), [#2553](https://github.com/adap/flower/pull/2553), [#2596]" +"(https://github.com/adap/flower/pull/2596))" msgstr "" #: ../../source/ref-changelog.md:190 ../../source/ref-changelog.md:280 #: ../../source/ref-changelog.md:344 ../../source/ref-changelog.md:398 #: ../../source/ref-changelog.md:465 -msgid "Flower received many improvements under the hood, too many to list here." +msgid "" +"Flower received many improvements under the hood, too many to list here." msgstr "Flower 进行了许多改进,这里就不一一列举了。" #: ../../source/ref-changelog.md:194 msgid "" -"**Remove support for Python 3.7** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" -msgstr "" -"**移除对 Python 3.7 的支持** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" +"**Remove support for Python 3.7** ([#2280](https://github.com/adap/flower/" +"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" +"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" +"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" +"(https://github.com/adap/flower/pull/2356))" +msgstr "" +"**移除对 Python 3.7 的支持** ([#2280](https://github.com/adap/flower/" +"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" +"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" +"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" +"(https://github.com/adap/flower/pull/2356))" #: ../../source/ref-changelog.md:196 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes" -" support. Flower now requires Python 3.8." -msgstr "在 Flower 1.5 中,Python 3.7 支持已被弃用,本版本将删除该支持。Flower 现在需要 Python 3.8。" +"Python 3.7 support was deprecated in Flower 1.5, and this release removes " +"support. Flower now requires Python 3.8." +msgstr "" +"在 Flower 1.5 中,Python 3.7 支持已被弃用,本版本将删除该支持。Flower 现在需" +"要 Python 3.8。" #: ../../source/ref-changelog.md:198 msgid "" -"**Remove experimental argument** `rest` **from** `start_client` " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**Remove experimental argument** `rest` **from** `start_client` ([#2324]" +"(https://github.com/adap/flower/pull/2324))" msgstr "" -"**从** `start_client` 中移除** `rest` **实验参数 " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**从** `start_client` 中移除** `rest` **实验参数 ([#2324](https://github.com/" +"adap/flower/pull/2324))" #: ../../source/ref-changelog.md:200 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` " -"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " -"experimental REST API instead." +"The (still experimental) argument `rest` was removed from `start_client` and " +"`start_numpy_client`. Use `transport=\"rest\"` to opt into the experimental " +"REST API instead." msgstr "" -"删除了 `start_client` 和 `start_numpy_client` 中的参数 `rest`(仍属试验性质)。请使用 " -"`transport=\"rest\"` 来选择使用试验性 REST API。" +"删除了 `start_client` 和 `start_numpy_client` 中的参数 `rest`(仍属试验性" +"质)。请使用 `transport=\"rest\"` 来选择使用试验性 REST API。" #: ../../source/ref-changelog.md:202 msgid "v1.5.0 (2023-08-31)" @@ -15869,192 +16055,163 @@ msgstr "" #: ../../source/ref-changelog.md:212 msgid "" -"**Introduce new simulation engine** " -"([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"**Introduce new simulation engine** ([#1969](https://github.com/adap/flower/" +"pull/1969), [#2221](https://github.com/adap/flower/pull/2221), [#2248]" +"(https://github.com/adap/flower/pull/2248))" msgstr "" "**引入新的模拟引擎** ([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"[#2221](https://github.com/adap/flower/pull/2221), [#2248](https://github." +"com/adap/flower/pull/2248))" #: ../../source/ref-changelog.md:214 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and" -" memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-" -"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"remains fully backwards compatible. It offers much improved stability and " +"memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-only, " +"CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -"新的模拟引擎从头开始重新编写,但仍完全向后兼容。它的稳定性和内存处理能力大大提高,尤其是在使用 GPU 时。仿真可透明地适应不同的设置,以在仅 " -"CPU、CPU+GPU、多 GPU 或多节点多 GPU 环境中扩展模拟。" +"新的模拟引擎从头开始重新编写,但仍完全向后兼容。它的稳定性和内存处理能力大大" +"提高,尤其是在使用 GPU 时。仿真可透明地适应不同的设置,以在仅 CPU、CPU+GPU、" +"多 GPU 或多节点多 GPU 环境中扩展模拟。" #: ../../source/ref-changelog.md:216 msgid "" -"Comprehensive documentation includes a new [how-to run " -"simulations](https://flower.ai/docs/framework/how-to-run-" -"simulations.html) guide, new [simulation-" +"Comprehensive documentation includes a new [how-to run simulations](https://" +"flower.ai/docs/framework/how-to-run-simulations.html) guide, new [simulation-" "pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " "[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +"tensorflow.html) notebooks, and a new [YouTube tutorial series](https://www." +"youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" -"综合文档包括新的[how-to run simulations](https://flower.ai/docs/framework/how-to-" -"run-simulations.html) guide, new [simulation-" -"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " -"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)。" +"综合文档包括新的[how-to run simulations](https://flower.ai/docs/framework/" +"how-to-run-simulations.html) guide, new [simulation-pytorch](https://flower." +"ai/docs/examples/simulation-pytorch.html) and [simulation-tensorflow]" +"(https://flower.ai/docs/examples/simulation-tensorflow.html) notebooks, and " +"a new [YouTube tutorial series](https://www.youtube.com/watch?" +"v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)。" #: ../../source/ref-changelog.md:218 msgid "" -"**Restructure Flower Docs** " -"([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +"**Restructure Flower Docs** ([#1824](https://github.com/adap/flower/" +"pull/1824), [#1865](https://github.com/adap/flower/pull/1865), [#1884]" +"(https://github.com/adap/flower/pull/1884), [#1887](https://github.com/adap/" +"flower/pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" +"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" +"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" +"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" +"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" +"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" +"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" +"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" +"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" +"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" +"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" +"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" +"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" +"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" +"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" +"(https://github.com/adap/flower/pull/2227))" msgstr "" "**重构 Flower 文档** ([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +"[#1865](https://github.com/adap/flower/pull/1865), [#1884](https://github." +"com/adap/flower/pull/1884), [#1887](https://github.com/adap/flower/" +"pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" +"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" +"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" +"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" +"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" +"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" +"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" +"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" +"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" +"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" +"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" +"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" +"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" +"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" +"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" +"(https://github.com/adap/flower/pull/2227))" #: ../../source/ref-changelog.md:220 #, fuzzy msgid "" -"Much effort went into a completely restructured Flower docs experience. " -"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " -"divided into Flower Framework, Flower Baselines, Flower Android SDK, " -"Flower iOS SDK, and code example projects." +"Much effort went into a completely restructured Flower docs experience. The " +"documentation on [flower.ai/docs](https://flower.ai/docs) is now divided " +"into Flower Framework, Flower Baselines, Flower Android SDK, Flower iOS SDK, " +"and code example projects." msgstr "" -"Flower 文档体验的全面重构耗费了大量精力。现在,[flower.ai/docs](flower.ai/docs)上的文档分为 Flower " -"Framework、Flower Baselines、Flower Android SDK、Flower iOS SDK 和代码示例项目。" +"Flower 文档体验的全面重构耗费了大量精力。现在,[flower.ai/docs](flower.ai/" +"docs)上的文档分为 Flower Framework、Flower Baselines、Flower Android SDK、" +"Flower iOS SDK 和代码示例项目。" #: ../../source/ref-changelog.md:222 msgid "" -"**Introduce Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +"**Introduce Flower Swift SDK** ([#1858](https://github.com/adap/flower/" +"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" msgstr "" -"**介绍 Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +"**介绍 Flower Swift SDK** ([#1858](https://github.com/adap/flower/" +"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" #: ../../source/ref-changelog.md:224 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support" -" on iOS is improving, and alongside the Swift SDK and code example, there" -" is now also an iOS quickstart tutorial." +"This is the first preview release of the Flower Swift SDK. Flower support on " +"iOS is improving, and alongside the Swift SDK and code example, there is now " +"also an iOS quickstart tutorial." msgstr "" -"这是 Flower Swift SDK 的首个预览版。Flower 对 iOS 的支持正在不断改进,除了 Swift SDK " -"和代码示例外,现在还有 iOS 快速入门教程。" +"这是 Flower Swift SDK 的首个预览版。Flower 对 iOS 的支持正在不断改进,除了 " +"Swift SDK 和代码示例外,现在还有 iOS 快速入门教程。" #: ../../source/ref-changelog.md:226 msgid "" -"**Introduce Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**Introduce Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" msgstr "" -"**介绍Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" #: ../../source/ref-changelog.md:228 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower " -"support on Android is improving, and alongside the Kotlin SDK and code " -"example, there is now also an Android quickstart tutorial." +"This is the first preview release of the Flower Kotlin SDK. Flower support " +"on Android is improving, and alongside the Kotlin SDK and code example, " +"there is now also an Android quickstart tutorial." msgstr "" -"这是 Flower Kotlin SDK 的首个预览版。Flower 对 Android 的支持正在不断改进,除了 Kotlin SDK " -"和代码示例,现在还有 Android 快速入门教程。" +"这是 Flower Kotlin SDK 的首个预览版。Flower 对 Android 的支持正在不断改进,除" +"了 Kotlin SDK 和代码示例,现在还有 Android 快速入门教程。" #: ../../source/ref-changelog.md:230 msgid "" -"**Introduce new end-to-end testing infrastructure** " -"([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" +"**Introduce new end-to-end testing infrastructure** ([#1842](https://github." +"com/adap/flower/pull/1842), [#2071](https://github.com/adap/flower/" +"pull/2071), [#2072](https://github.com/adap/flower/pull/2072), [#2068]" +"(https://github.com/adap/flower/pull/2068), [#2067](https://github.com/adap/" +"flower/pull/2067), [#2069](https://github.com/adap/flower/pull/2069), [#2073]" +"(https://github.com/adap/flower/pull/2073), [#2070](https://github.com/adap/" +"flower/pull/2070), [#2074](https://github.com/adap/flower/pull/2074), [#2082]" +"(https://github.com/adap/flower/pull/2082), [#2084](https://github.com/adap/" +"flower/pull/2084), [#2093](https://github.com/adap/flower/pull/2093), [#2109]" +"(https://github.com/adap/flower/pull/2109), [#2095](https://github.com/adap/" +"flower/pull/2095), [#2140](https://github.com/adap/flower/pull/2140), [#2137]" +"(https://github.com/adap/flower/pull/2137), [#2165](https://github.com/adap/" +"flower/pull/2165))" msgstr "" "*介绍新的端到端测试** ([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" +"[#2071](https://github.com/adap/flower/pull/2071), [#2072](https://github." +"com/adap/flower/pull/2072), [#2068](https://github.com/adap/flower/" +"pull/2068), [#2067](https://github.com/adap/flower/pull/2067), [#2069]" +"(https://github.com/adap/flower/pull/2069), [#2073](https://github.com/adap/" +"flower/pull/2073), [#2070](https://github.com/adap/flower/pull/2070), [#2074]" +"(https://github.com/adap/flower/pull/2074), [#2082](https://github.com/adap/" +"flower/pull/2082), [#2084](https://github.com/adap/flower/pull/2084), [#2093]" +"(https://github.com/adap/flower/pull/2093), [#2109](https://github.com/adap/" +"flower/pull/2109), [#2095](https://github.com/adap/flower/pull/2095), [#2140]" +"(https://github.com/adap/flower/pull/2140), [#2137](https://github.com/adap/" +"flower/pull/2137), [#2165](https://github.com/adap/flower/pull/2165))" #: ../../source/ref-changelog.md:232 msgid "" -"A new testing infrastructure ensures that new changes stay compatible " -"with existing framework integrations or strategies." +"A new testing infrastructure ensures that new changes stay compatible with " +"existing framework integrations or strategies." msgstr "新的测试设施可确保新的变更与现有的框架集成或策略保持兼容。" #: ../../source/ref-changelog.md:234 @@ -16063,151 +16220,155 @@ msgstr "** 过时的 Python 3.7**" #: ../../source/ref-changelog.md:236 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" -" Python 3.7 is now deprecated and will be removed in an upcoming release." -msgstr "由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并将在即将发布的版本中移除。" +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for " +"Python 3.7 is now deprecated and will be removed in an upcoming release." +msgstr "" +"由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并" +"将在即将发布的版本中移除。" #: ../../source/ref-changelog.md:238 msgid "" -"**Add new** `FedTrimmedAvg` **strategy** " -"([#1769](https://github.com/adap/flower/pull/1769), " -"[#1853](https://github.com/adap/flower/pull/1853))" +"**Add new** `FedTrimmedAvg` **strategy** ([#1769](https://github.com/adap/" +"flower/pull/1769), [#1853](https://github.com/adap/flower/pull/1853))" msgstr "" -"**添加新的**`FedTrimmedAvg`**策略**([#1769](https://github.com/adap/flower/pull/1769)," -" [#1853](https://github.com/adap/flower/pull/1853)" +"**添加新的**`FedTrimmedAvg`**策略**([#1769](https://github.com/adap/flower/" +"pull/1769), [#1853](https://github.com/adap/flower/pull/1853)" #: ../../source/ref-changelog.md:240 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, 2018]" +"(https://arxiv.org/abs/1803.01498)." msgstr "" -"新的 \"FedTrimmedAvg \"策略实现了[Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)的 \"Trimmed Mean\"。" +"新的 \"FedTrimmedAvg \"策略实现了[Dong Yin, 2018](https://arxiv.org/" +"abs/1803.01498)的 \"Trimmed Mean\"。" #: ../../source/ref-changelog.md:242 msgid "" -"**Introduce start_driver** " -"([#1697](https://github.com/adap/flower/pull/1697))" -msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce start_driver** ([#1697](https://github.com/adap/flower/" +"pull/1697))" +msgstr "" +"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" #: ../../source/ref-changelog.md:244 msgid "" -"In addition to `start_server` and using the raw Driver API, there is a " -"new `start_driver` function that allows for running `start_server` " -"scripts as a Flower driver with only a single-line code change. Check out" -" the `mt-pytorch` code example to see a working example using " -"`start_driver`." +"In addition to `start_server` and using the raw Driver API, there is a new " +"`start_driver` function that allows for running `start_server` scripts as a " +"Flower driver with only a single-line code change. Check out the `mt-" +"pytorch` code example to see a working example using `start_driver`." msgstr "" -"除了 `start_server` 和使用原始驱动 API 之外,还有一个新的 `start_driver` 函数,只需修改一行代码,就能将 " -"`start_server` 脚本作为 Flower 驱动程序运行。请查看 `mt-pytorch` 代码示例,了解使用 " -"`start_driver` 的工作示例。" +"除了 `start_server` 和使用原始驱动 API 之外,还有一个新的 `start_driver` 函" +"数,只需修改一行代码,就能将 `start_server` 脚本作为 Flower 驱动程序运行。请" +"查看 `mt-pytorch` 代码示例,了解使用 `start_driver` 的工作示例。" #: ../../source/ref-changelog.md:246 msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** " -"([#1785](https://github.com/adap/flower/pull/1785))" +"**Add parameter aggregation to** `mt-pytorch` **code example** ([#1785]" +"(https://github.com/adap/flower/pull/1785))" msgstr "" -"为 `mt-pytorch` **代码示例**添加参数聚合 " -"([#1785](https://github.com/adap/flower/pull/1785))" +"为 `mt-pytorch` **代码示例**添加参数聚合 ([#1785](https://github.com/adap/" +"flower/pull/1785))" #: ../../source/ref-changelog.md:248 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a" -" driver script. The included `driver.py` and `server.py` have been " -"aligned to demonstrate both the low-level way and the high-level way of " -"building server-side logic." +"The `mt-pytorch` example shows how to aggregate parameters when writing a " +"driver script. The included `driver.py` and `server.py` have been aligned to " +"demonstrate both the low-level way and the high-level way of building server-" +"side logic." msgstr "" -"`mt-pytorch`示例展示了如何在编写驱动程序脚本时聚合参数。附带的 `driver.py` 和 `server.py` " -"已经进行了调整,以演示构建服务器端逻辑的低级方法和高级方法。" +"`mt-pytorch`示例展示了如何在编写驱动程序脚本时聚合参数。附带的 `driver.py` " +"和 `server.py` 已经进行了调整,以演示构建服务器端逻辑的低级方法和高级方法。" #: ../../source/ref-changelog.md:250 msgid "" -"**Migrate experimental REST API to Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"**Migrate experimental REST API to Starlette** ([2171](https://github.com/" +"adap/flower/pull/2171))" msgstr "" -"**将实验性 REST API 移植到 Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"**将实验性 REST API 移植到 Starlette** ([2171](https://github.com/adap/" +"flower/pull/2171))" #: ../../source/ref-changelog.md:252 msgid "" -"The (experimental) REST API used to be implemented in " -"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" -" use [Starlette](https://www.starlette.io/) directly." +"The (experimental) REST API used to be implemented in [FastAPI](https://" +"fastapi.tiangolo.com/), but it has now been migrated to use [Starlette]" +"(https://www.starlette.io/) directly." msgstr "" -"REST API(试验性)曾在 [FastAPI](https://fastapi.tiangolo.com/) 中实现,但现在已迁移到直接使用 " -"[Starlette](https://www.starlette.io/) 。" +"REST API(试验性)曾在 [FastAPI](https://fastapi.tiangolo.com/) 中实现,但现" +"在已迁移到直接使用 [Starlette](https://www.starlette.io/) 。" #: ../../source/ref-changelog.md:254 msgid "" -"Please note: The REST request-response API is still experimental and will" -" likely change significantly over time." -msgstr "请注意:REST 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" +"Please note: The REST request-response API is still experimental and will " +"likely change significantly over time." +msgstr "" +"请注意:REST 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" #: ../../source/ref-changelog.md:256 msgid "" -"**Introduce experimental gRPC request-response API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901))" +"**Introduce experimental gRPC request-response API** ([#1867](https://github." +"com/adap/flower/pull/1867), [#1901](https://github.com/adap/flower/" +"pull/1901))" msgstr "" -"**引入实验性 gRPC 请求-响应 API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901)" +"**引入实验性 gRPC 请求-响应 API** ([#1867](https://github.com/adap/flower/" +"pull/1867), [#1901](https://github.com/adap/flower/pull/1901)" #: ../../source/ref-changelog.md:258 msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) " -"and the experimental REST API, there is now a new gRPC API that uses a " -"request-response model to communicate with client nodes." +"In addition to the existing gRPC API (based on bidirectional streaming) and " +"the experimental REST API, there is now a new gRPC API that uses a request-" +"response model to communicate with client nodes." msgstr "" -"除了现有的 gRPC 应用程序接口(基于双向流)和试验性 REST 应用程序接口外,现在还有一个新的 gRPC " -"应用程序接口,它使用请求-响应模型与客户端节点通信。" +"除了现有的 gRPC 应用程序接口(基于双向流)和试验性 REST 应用程序接口外,现在" +"还有一个新的 gRPC 应用程序接口,它使用请求-响应模型与客户端节点通信。" #: ../../source/ref-changelog.md:260 msgid "" -"Please note: The gRPC request-response API is still experimental and will" -" likely change significantly over time." -msgstr "请注意:gRPC 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" +"Please note: The gRPC request-response API is still experimental and will " +"likely change significantly over time." +msgstr "" +"请注意:gRPC 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" #: ../../source/ref-changelog.md:262 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"`start_client(transport=\"rest\")` ([#1880](https://github.com/adap/flower/" +"pull/1880))" msgstr "" "**用新的** `start_client(transport=\"rest\")` 替换实验性** " -"`start_client(rest=True)` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"`start_client(rest=True)` ([#1880](https://github.com/adap/flower/pull/1880))" #: ../../source/ref-changelog.md:264 msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in " -"favour of a new argument `transport`. `start_client(transport=\"rest\")` " -"will yield the same behaviour as `start_client(rest=True)` did before. " -"All code should migrate to the new argument `transport`. The deprecated " -"argument `rest` will be removed in a future release." +"The (experimental) `start_client` argument `rest` was deprecated in favour " +"of a new argument `transport`. `start_client(transport=\"rest\")` will yield " +"the same behaviour as `start_client(rest=True)` did before. All code should " +"migrate to the new argument `transport`. The deprecated argument `rest` will " +"be removed in a future release." msgstr "" -"已废弃(试验性的)`start_client`参数`rest`,改用新参数`transport`。`start_client(transport=\"rest\")`将产生与以前的`start_client(rest=True)`相同的行为。所有代码都应迁移到新参数" -" `transport`。过时的参数 `rest` 将在今后的版本中删除。" +"已废弃(试验性的)`start_client`参数`rest`,改用新参数`transport`。" +"`start_client(transport=\"rest\")`将产生与以前的`start_client(rest=True)`相同" +"的行为。所有代码都应迁移到新参数 `transport`。过时的参数 `rest` 将在今后的版" +"本中删除。" #: ../../source/ref-changelog.md:266 msgid "" -"**Add a new gRPC option** " -"([#2197](https://github.com/adap/flower/pull/2197))" -msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" +"**Add a new gRPC option** ([#2197](https://github.com/adap/flower/pull/2197))" +msgstr "" +"** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/" +"pull/2197))" #: ../../source/ref-changelog.md:268 msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" -" option set to 0 by default. This prevents the clients from sending " -"keepalive pings when there is no outstanding stream." +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls` " +"option set to 0 by default. This prevents the clients from sending keepalive " +"pings when there is no outstanding stream." msgstr "" -"现在我们启动一个 gRPC 服务器,并将 `grpc.keepalive_permit_without_calls` 选项默认设置为 " -"0。这将防止客户端在没有未处理数据流时发送 keepalive pings。" +"现在我们启动一个 gRPC 服务器,并将 `grpc.keepalive_permit_without_calls` 选项" +"默认设置为 0。这将防止客户端在没有未处理数据流时发送 keepalive pings。" #: ../../source/ref-changelog.md:270 msgid "" -"**Improve example notebooks** " -"([#2005](https://github.com/adap/flower/pull/2005))" +"**Improve example notebooks** ([#2005](https://github.com/adap/flower/" +"pull/2005))" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" #: ../../source/ref-changelog.md:272 @@ -16217,57 +16378,48 @@ msgstr "有一个新的 30 分钟的联邦学习 PyTorch 教程!" #: ../../source/ref-changelog.md:274 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" -msgstr "" -"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"[#1873](https://github.com/adap/flower/pull/1873), [#1981](https://github." +"com/adap/flower/pull/1981), [#1988](https://github.com/adap/flower/" +"pull/1988), [#1984](https://github.com/adap/flower/pull/1984), [#1982]" +"(https://github.com/adap/flower/pull/1982), [#2112](https://github.com/adap/" +"flower/pull/2112), [#2144](https://github.com/adap/flower/pull/2144), [#2174]" +"(https://github.com/adap/flower/pull/2174), [#2225](https://github.com/adap/" +"flower/pull/2225), [#2183](https://github.com/adap/flower/pull/2183))" +msgstr "" +"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), [#1873]" +"(https://github.com/adap/flower/pull/1873), [#1981](https://github.com/adap/" +"flower/pull/1981), [#1988](https://github.com/adap/flower/pull/1988), [#1984]" +"(https://github.com/adap/flower/pull/1984), [#1982](https://github.com/adap/" +"flower/pull/1982), [#2112](https://github.com/adap/flower/pull/2112), [#2144]" +"(https://github.com/adap/flower/pull/2144), [#2174](https://github.com/adap/" +"flower/pull/2174), [#2225](https://github.com/adap/flower/pull/2225), [#2183]" +"(https://github.com/adap/flower/pull/2183))" #: ../../source/ref-changelog.md:276 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A" -" major upgrade is that all code examples now have a `requirements.txt` " -"(in addition to `pyproject.toml`)." +"compatibility of TensorFlow examples, and code examples for simulation. A " +"major upgrade is that all code examples now have a `requirements.txt` (in " +"addition to `pyproject.toml`)." msgstr "" -"许多示例都进行了重大更新,包括简化了 advanced-tensorflow 和 advanced-pytorch 示例,改进了 " -"TensorFlow 示例的 macOS 兼容性,以及模拟代码示例。一项重大升级是所有代码示例现在都有了 " -"\"requirements.txt\"(除 \"pyproject.toml \"外)。" +"许多示例都进行了重大更新,包括简化了 advanced-tensorflow 和 advanced-pytorch " +"示例,改进了 TensorFlow 示例的 macOS 兼容性,以及模拟代码示例。一项重大升级是" +"所有代码示例现在都有了 \"requirements.txt\"(除 \"pyproject.toml \"外)。" #: ../../source/ref-changelog.md:278 msgid "" -"**General improvements** " -"([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" -msgstr "" -"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" +"**General improvements** ([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), [#1884](https://github." +"com/adap/flower/pull/1884), [#1837](https://github.com/adap/flower/" +"pull/1837), [#1477](https://github.com/adap/flower/pull/1477), [#2171]" +"(https://github.com/adap/flower/pull/2171))" +msgstr "" +"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), [#1866]" +"(https://github.com/adap/flower/pull/1866), [#1884](https://github.com/adap/" +"flower/pull/1884), [#1837](https://github.com/adap/flower/pull/1837), [#1477]" +"(https://github.com/adap/flower/pull/1477), [#2171](https://github.com/adap/" +"flower/pull/2171))" #: ../../source/ref-changelog.md:284 ../../source/ref-changelog.md:348 #: ../../source/ref-changelog.md:406 ../../source/ref-changelog.md:475 @@ -16282,165 +16434,159 @@ msgstr "v1.4.0 (2023-04-21)" #: ../../source/ref-changelog.md:292 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" +"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " +"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " +"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " +"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" +"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " +"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " +"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " +"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" #: ../../source/ref-changelog.md:296 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " -"example)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" -msgstr "" -"**引入对XGBoost的支持(**`FedXgbNnAvg` **策略和示例)** " -"([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and example)** " +"([#1694](https://github.com/adap/flower/pull/1694), [#1709](https://github." +"com/adap/flower/pull/1709), [#1715](https://github.com/adap/flower/" +"pull/1715), [#1717](https://github.com/adap/flower/pull/1717), [#1763]" +"(https://github.com/adap/flower/pull/1763), [#1795](https://github.com/adap/" +"flower/pull/1795))" +msgstr "" +"**引入对XGBoost的支持(**`FedXgbNnAvg` **策略和示例)** ([#1694](https://" +"github.com/adap/flower/pull/1694), [#1709](https://github.com/adap/flower/" +"pull/1709), [#1715](https://github.com/adap/flower/pull/1715), [#1717]" +"(https://github.com/adap/flower/pull/1717), [#1763](https://github.com/adap/" +"flower/pull/1763), [#1795](https://github.com/adap/flower/pull/1795))" #: ../../source/ref-changelog.md:298 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" -" " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" and a [code example](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart) that demonstrates the usage of this new strategy in " -"an XGBoost project." -msgstr "" -"XGBoost 是一种基于树的集合机器学习算法,它使用梯度提升来提高模型的准确性。我们添加了一个新的 " -"\"FedXgbNnAvg\"[策略](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)和一个[代码示例](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart),演示如何在 XGBoost 项目中使用这个新策略。" +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg` " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/" +"strategy/fedxgb_nn_avg.py), and a [code example](https://github.com/adap/" +"flower/tree/main/examples/xgboost-quickstart) that demonstrates the usage of " +"this new strategy in an XGBoost project." +msgstr "" +"XGBoost 是一种基于树的集合机器学习算法,它使用梯度提升来提高模型的准确性。我" +"们添加了一个新的 \"FedXgbNnAvg\"[策略](https://github.com/adap/flower/tree/" +"main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)和一个[代码示例](https://" +"github.com/adap/flower/tree/main/examples/xgboost-quickstart),演示如何在 " +"XGBoost 项目中使用这个新策略。" #: ../../source/ref-changelog.md:300 msgid "" -"**Introduce iOS SDK (preview)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**Introduce iOS SDK (preview)** ([#1621](https://github.com/adap/flower/" +"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" msgstr "" -"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/" +"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" #: ../../source/ref-changelog.md:302 msgid "" -"This is a major update for anyone wanting to implement Federated Learning" -" on iOS mobile devices. We now have a swift iOS SDK present under " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" that will facilitate greatly the app creating process. To showcase its " -"use, the [iOS " +"This is a major update for anyone wanting to implement Federated Learning on " +"iOS mobile devices. We now have a swift iOS SDK present under [src/swift/" +"flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) that will " +"facilitate greatly the app creating process. To showcase its use, the [iOS " "example](https://github.com/adap/flower/tree/main/examples/ios) has also " "been updated!" msgstr "" -"对于想要在 iOS 移动设备上实施联邦学习的人来说,这是一次重大更新。现在,我们在 " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" 下提供了一个迅捷的 iOS SDK,这将大大方便应用程序的创建过程。为了展示其使用情况,我们还更新了 [iOS " -"示例](https://github.com/adap/flower/tree/main/examples/ios)!" +"对于想要在 iOS 移动设备上实施联邦学习的人来说,这是一次重大更新。现在,我们" +"在 [src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) " +"下提供了一个迅捷的 iOS SDK,这将大大方便应用程序的创建过程。为了展示其使用情" +"况,我们还更新了 [iOS 示例](https://github.com/adap/flower/tree/main/" +"examples/ios)!" #: ../../source/ref-changelog.md:304 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** " -"([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" +"**Introduce new \"What is Federated Learning?\" tutorial** ([#1657](https://" +"github.com/adap/flower/pull/1657), [#1721](https://github.com/adap/flower/" +"pull/1721))" msgstr "" -"**引入新的 " -"\"什么是联邦学习?\"教程**([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721)" +"**引入新的 \"什么是联邦学习?\"教程**([#1657](https://github.com/adap/" +"flower/pull/1657), [#1721](https://github.com/adap/flower/pull/1721)" #: ../../source/ref-changelog.md:306 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html) in our documentation explains the basics" -" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" -" Learning to start their journey with Flower. Forward it to anyone who's " +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-what-" +"is-federated-learning.html) in our documentation explains the basics of " +"Fedetated Learning. It enables anyone who's unfamiliar with Federated " +"Learning to start their journey with Flower. Forward it to anyone who's " "interested in Federated Learning!" msgstr "" -"我们的文档中新增了一个[入门级教程](https://flower.ai/docs/framework/tutorial-what-is-" -"federated-learning.html),解释了联邦学习的基础知识。它让任何不熟悉联邦学习的人都能开始 Flower " -"之旅。请转发给对联邦学习感兴趣的人!" +"我们的文档中新增了一个[入门级教程](https://flower.ai/docs/framework/tutorial-" +"what-is-federated-learning.html),解释了联邦学习的基础知识。它让任何不熟悉联" +"邦学习的人都能开始 Flower 之旅。请转发给对联邦学习感兴趣的人!" #: ../../source/ref-changelog.md:308 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" +"**Introduce new Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" +"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." +"com/adap/flower/pull/1679))" msgstr "" -"**引入新的 Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679)" +"**引入新的 Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" +"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." +"com/adap/flower/pull/1679)" #: ../../source/ref-changelog.md:310 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated" -" Optimization in Heterogeneous Networks (Li et al., " -"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," -" which aims at making convergence more robust in heterogeneous settings." +"This new baseline replicates the MNIST+CNN task from the paper [Federated " +"Optimization in Heterogeneous Networks (Li et al., 2018)](https://arxiv.org/" +"abs/1812.06127). It uses the `FedProx` strategy, which aims at making " +"convergence more robust in heterogeneous settings." msgstr "" -"这条新Baseline复现了论文[Federated Optimization in Heterogeneous Networks (Li et " -"al., 2018)](https://arxiv.org/abs/1812.06127)中的 MNIST+CNN 任务。它使用 " -"\"FedProx \"策略,旨在使收敛在异构环境中更加稳健。" +"这条新Baseline复现了论文[Federated Optimization in Heterogeneous Networks " +"(Li et al., 2018)](https://arxiv.org/abs/1812.06127)中的 MNIST+CNN 任务。它使" +"用 \"FedProx \"策略,旨在使收敛在异构环境中更加稳健。" #: ../../source/ref-changelog.md:312 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"**Introduce new Flower Baseline: FedAvg FEMNIST** ([#1655](https://github." +"com/adap/flower/pull/1655))" msgstr "" -"**引入新的 Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"**引入新的 Flower Baseline: FedAvg FEMNIST** ([#1655](https://github.com/" +"adap/flower/pull/1655))" #: ../../source/ref-changelog.md:314 msgid "" -"This new baseline replicates an experiment evaluating the performance of " -"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " -"Benchmark for Federated Settings (Caldas et al., " -"2018)](https://arxiv.org/abs/1812.01097)." +"This new baseline replicates an experiment evaluating the performance of the " +"FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A Benchmark " +"for Federated Settings (Caldas et al., 2018)](https://arxiv.org/" +"abs/1812.01097)." msgstr "" -"这一新Baseline复现了论文[LEAF: A Benchmark for Federated Settings(Caldas 等人,2018 " -"年)](https://arxiv.org/abs/1812.01097)中评估 FedAvg 算法在 FEMNIST 数据集上性能的实验。" +"这一新Baseline复现了论文[LEAF: A Benchmark for Federated Settings(Caldas 等" +"人,2018 年)](https://arxiv.org/abs/1812.01097)中评估 FedAvg 算法在 FEMNIST " +"数据集上性能的实验。" #: ../../source/ref-changelog.md:316 msgid "" -"**Introduce (experimental) REST API** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" -msgstr "" -"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" +"**Introduce (experimental) REST API** ([#1594](https://github.com/adap/" +"flower/pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" +"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" +"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" +"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" +"flower/pull/1733))" +msgstr "" +"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/" +"pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" +"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" +"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" +"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" +"flower/pull/1733))" #: ../../source/ref-changelog.md:318 msgid "" "A new REST API has been introduced as an alternative to the gRPC-based " "communication stack. In this initial version, the REST API only supports " "anonymous clients." -msgstr "作为基于 gRPC 的通信栈的替代方案,我们引入了新的 REST API。在初始版本中,REST API 仅支持匿名客户端。" +msgstr "" +"作为基于 gRPC 的通信栈的替代方案,我们引入了新的 REST API。在初始版本中," +"REST API 仅支持匿名客户端。" #: ../../source/ref-changelog.md:320 msgid "" @@ -16450,203 +16596,171 @@ msgstr "请注意:REST API 仍处于试验阶段,随着时间的推移可能 #: ../../source/ref-changelog.md:322 msgid "" -"**Improve the (experimental) Driver API** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" -msgstr "" -"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/flower/pull/1663)," -" [#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**Improve the (experimental) Driver API** ([#1663](https://github.com/adap/" +"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" +"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" +"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" +"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" +"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" +"(https://github.com/adap/flower/pull/1794))" +msgstr "" +"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/" +"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" +"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" +"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" +"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" +"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" +"(https://github.com/adap/flower/pull/1794))" #: ../../source/ref-changelog.md:324 msgid "" -"The Driver API is still an experimental feature, but this release " -"introduces some major upgrades. One of the main improvements is the " -"introduction of an SQLite database to store server state on disk (instead" -" of in-memory). Another improvement is that tasks (instructions or " -"results) that have been delivered will now be deleted. This greatly " -"improves the memory efficiency of a long-running Flower server." +"The Driver API is still an experimental feature, but this release introduces " +"some major upgrades. One of the main improvements is the introduction of an " +"SQLite database to store server state on disk (instead of in-memory). " +"Another improvement is that tasks (instructions or results) that have been " +"delivered will now be deleted. This greatly improves the memory efficiency " +"of a long-running Flower server." msgstr "" -"驱动程序应用程序接口(Driver API)仍是一项试验性功能,但这一版本引入了一些重大升级。主要改进之一是引入了 SQLite " -"数据库,将服务器状态存储在磁盘上(而不是内存中)。另一项改进是,已交付的任务(指令或结果)现在将被删除。这大大提高了长期运行的 Flower " -"服务器的内存效率。" +"驱动程序应用程序接口(Driver API)仍是一项试验性功能,但这一版本引入了一些重" +"大升级。主要改进之一是引入了 SQLite 数据库,将服务器状态存储在磁盘上(而不是" +"内存中)。另一项改进是,已交付的任务(指令或结果)现在将被删除。这大大提高了" +"长期运行的 Flower 服务器的内存效率。" #: ../../source/ref-changelog.md:326 msgid "" -"**Fix spilling issues related to Ray during simulations** " -"([#1698](https://github.com/adap/flower/pull/1698))" -msgstr "**修复模拟过程中与Ray有关的溢出问题** ([#1698](https://github.com/adap/flower/pull/1698))" +"**Fix spilling issues related to Ray during simulations** ([#1698](https://" +"github.com/adap/flower/pull/1698))" +msgstr "" +"**修复模拟过程中与Ray有关的溢出问题** ([#1698](https://github.com/adap/" +"flower/pull/1698))" #: ../../source/ref-changelog.md:328 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts" -" of data that would make the training unable to continue. This is now " -"fixed! 🎉" -msgstr "在运行长时间模拟时,`ray` 有时会溢出大量数据,导致训练无法继续。现在这个问题已经解决!🎉" +"While running long simulations, `ray` was sometimes spilling huge amounts of " +"data that would make the training unable to continue. This is now fixed! 🎉" +msgstr "" +"在运行长时间模拟时,`ray` 有时会溢出大量数据,导致训练无法继续。现在这个问题" +"已经解决!🎉" #: ../../source/ref-changelog.md:330 msgid "" -"**Add new example using** `TabNet` **and Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"**Add new example using** `TabNet` **and Flower** ([#1725](https://github." +"com/adap/flower/pull/1725))" msgstr "" -"** 添加使用** `TabNet` ** 的新示例** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"** 添加使用** `TabNet` ** 的新示例** ([#1725](https://github.com/adap/flower/" +"pull/1725))" #: ../../source/ref-changelog.md:332 msgid "" -"TabNet is a powerful and flexible framework for training machine learning" -" models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" -"/quickstart-tabnet)." +"TabNet is a powerful and flexible framework for training machine learning " +"models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples/" +"quickstart-tabnet)." msgstr "" -"TabNet 是一个强大而灵活的框架,用于在表格数据上训练机器学习模型。我们现在有一个使用 Flower 的联邦示例:[quickstart-" -"tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" -"tabnet)。" +"TabNet 是一个强大而灵活的框架,用于在表格数据上训练机器学习模型。我们现在有一" +"个使用 Flower 的联邦示例:[quickstart-tabnet](https://github.com/adap/flower/" +"tree/main/examples/quickstart-tabnet)。" #: ../../source/ref-changelog.md:334 msgid "" -"**Add new how-to guide for monitoring simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" -msgstr "** 添加新的模拟监控指南** ([#1649](https://github.com/adap/flower/pull/1649))" +"**Add new how-to guide for monitoring simulations** ([#1649](https://github." +"com/adap/flower/pull/1649))" +msgstr "" +"** 添加新的模拟监控指南** ([#1649](https://github.com/adap/flower/pull/1649))" #: ../../source/ref-changelog.md:336 msgid "" -"We now have a documentation guide to help users monitor their performance" -" during simulations." +"We now have a documentation guide to help users monitor their performance " +"during simulations." msgstr "我们现在有一份文档指南,可帮助用户在模拟过程中监控其性能。" #: ../../source/ref-changelog.md:338 msgid "" -"**Add training metrics to** `History` **object during simulations** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**Add training metrics to** `History` **object during simulations** ([#1696]" +"(https://github.com/adap/flower/pull/1696))" msgstr "" -"**在模拟过程中为***`历史`***对象添加训练指标*** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**在模拟过程中为***`历史`***对象添加训练指标*** ([#1696](https://github.com/" +"adap/flower/pull/1696))" #: ../../source/ref-changelog.md:340 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training " -"metrics, but previous releases did not save the results in the `History` " -"object. This is now the case!" +"The `fit_metrics_aggregation_fn` can be used to aggregate training metrics, " +"but previous releases did not save the results in the `History` object. This " +"is now the case!" msgstr "" -"`fit_metrics_aggregation_fn`可用于汇总训练指标,但以前的版本不会将结果保存在 \"History " -"\"对象中。现在可以了!" +"`fit_metrics_aggregation_fn`可用于汇总训练指标,但以前的版本不会将结果保存在 " +"\"History \"对象中。现在可以了!" #: ../../source/ref-changelog.md:342 msgid "" -"**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" -msgstr "" -"**普通改进** ([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" +"**General improvements** ([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), [#1647](https://github." +"com/adap/flower/pull/1647), [#1471](https://github.com/adap/flower/" +"pull/1471), [#1648](https://github.com/adap/flower/pull/1648), [#1651]" +"(https://github.com/adap/flower/pull/1651), [#1652](https://github.com/adap/" +"flower/pull/1652), [#1653](https://github.com/adap/flower/pull/1653), [#1659]" +"(https://github.com/adap/flower/pull/1659), [#1665](https://github.com/adap/" +"flower/pull/1665), [#1670](https://github.com/adap/flower/pull/1670), [#1672]" +"(https://github.com/adap/flower/pull/1672), [#1677](https://github.com/adap/" +"flower/pull/1677), [#1684](https://github.com/adap/flower/pull/1684), [#1683]" +"(https://github.com/adap/flower/pull/1683), [#1686](https://github.com/adap/" +"flower/pull/1686), [#1682](https://github.com/adap/flower/pull/1682), [#1685]" +"(https://github.com/adap/flower/pull/1685), [#1692](https://github.com/adap/" +"flower/pull/1692), [#1705](https://github.com/adap/flower/pull/1705), [#1708]" +"(https://github.com/adap/flower/pull/1708), [#1711](https://github.com/adap/" +"flower/pull/1711), [#1713](https://github.com/adap/flower/pull/1713), [#1714]" +"(https://github.com/adap/flower/pull/1714), [#1718](https://github.com/adap/" +"flower/pull/1718), [#1716](https://github.com/adap/flower/pull/1716), [#1723]" +"(https://github.com/adap/flower/pull/1723), [#1735](https://github.com/adap/" +"flower/pull/1735), [#1678](https://github.com/adap/flower/pull/1678), [#1750]" +"(https://github.com/adap/flower/pull/1750), [#1753](https://github.com/adap/" +"flower/pull/1753), [#1736](https://github.com/adap/flower/pull/1736), [#1766]" +"(https://github.com/adap/flower/pull/1766), [#1760](https://github.com/adap/" +"flower/pull/1760), [#1775](https://github.com/adap/flower/pull/1775), [#1776]" +"(https://github.com/adap/flower/pull/1776), [#1777](https://github.com/adap/" +"flower/pull/1777), [#1779](https://github.com/adap/flower/pull/1779), [#1784]" +"(https://github.com/adap/flower/pull/1784), [#1773](https://github.com/adap/" +"flower/pull/1773), [#1755](https://github.com/adap/flower/pull/1755), [#1789]" +"(https://github.com/adap/flower/pull/1789), [#1788](https://github.com/adap/" +"flower/pull/1788), [#1798](https://github.com/adap/flower/pull/1798), [#1799]" +"(https://github.com/adap/flower/pull/1799), [#1739](https://github.com/adap/" +"flower/pull/1739), [#1800](https://github.com/adap/flower/pull/1800), [#1804]" +"(https://github.com/adap/flower/pull/1804), [#1805](https://github.com/adap/" +"flower/pull/1805))" +msgstr "" +"**普通改进** ([#1659](https://github.com/adap/flower/pull/1659), [#1646]" +"(https://github.com/adap/flower/pull/1646), [#1647](https://github.com/adap/" +"flower/pull/1647), [#1471](https://github.com/adap/flower/pull/1471), [#1648]" +"(https://github.com/adap/flower/pull/1648), [#1651](https://github.com/adap/" +"flower/pull/1651), [#1652](https://github.com/adap/flower/pull/1652), [#1653]" +"(https://github.com/adap/flower/pull/1653), [#1659](https://github.com/adap/" +"flower/pull/1659), [#1665](https://github.com/adap/flower/pull/1665), [#1670]" +"(https://github.com/adap/flower/pull/1670), [#1672](https://github.com/adap/" +"flower/pull/1672), [#1677](https://github.com/adap/flower/pull/1677), [#1684]" +"(https://github.com/adap/flower/pull/1684), [#1683](https://github.com/adap/" +"flower/pull/1683), [#1686](https://github.com/adap/flower/pull/1686), [#1682]" +"(https://github.com/adap/flower/pull/1682), [#1685](https://github.com/adap/" +"flower/pull/1685), [#1692](https://github.com/adap/flower/pull/1692), [#1705]" +"(https://github.com/adap/flower/pull/1705), [#1708](https://github.com/adap/" +"flower/pull/1708), [#1711](https://github.com/adap/flower/pull/1711), [#1713]" +"(https://github.com/adap/flower/pull/1713), [#1714](https://github.com/adap/" +"flower/pull/1714), [#1718](https://github.com/adap/flower/pull/1718), [#1716]" +"(https://github.com/adap/flower/pull/1716), [#1723](https://github.com/adap/" +"flower/pull/1723), [#1735](https://github.com/adap/flower/pull/1735), [#1678]" +"(https://github.com/adap/flower/pull/1678), [#1750](https://github.com/adap/" +"flower/pull/1750), [#1753](https://github.com/adap/flower/pull/1753), [#1736]" +"(https://github.com/adap/flower/pull/1736), [#1766](https://github.com/adap/" +"flower/pull/1766), [#1760](https://github.com/adap/flower/pull/1760), [#1775]" +"(https://github.com/adap/flower/pull/1775), [#1776](https://github.com/adap/" +"flower/pull/1776), [#1777](https://github.com/adap/flower/pull/1777), [#1779]" +"(https://github.com/adap/flower/pull/1779), [#1784](https://github.com/adap/" +"flower/pull/1784), [#1773](https://github.com/adap/flower/pull/1773), [#1755]" +"(https://github.com/adap/flower/pull/1755), [#1789](https://github.com/adap/" +"flower/pull/1789), [#1788](https://github.com/adap/flower/pull/1788), [#1798]" +"(https://github.com/adap/flower/pull/1798), [#1799](https://github.com/adap/" +"flower/pull/1799), [#1739](https://github.com/adap/flower/pull/1739), [#1800]" +"(https://github.com/adap/flower/pull/1800), [#1804](https://github.com/adap/" +"flower/pull/1804), [#1805](https://github.com/adap/flower/pull/1805))" #: ../../source/ref-changelog.md:350 msgid "v1.3.0 (2023-02-06)" @@ -16654,48 +16768,49 @@ msgstr "v1.3.0 (2023-02-06)" #: ../../source/ref-changelog.md:356 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " +"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " +"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" #: ../../source/ref-changelog.md:360 msgid "" "**Add support for** `workload_id` **and** `group_id` **in Driver API** " "([#1595](https://github.com/adap/flower/pull/1595))" msgstr "" -"**在驱动程序应用程序接口中添加对** `workload_id` **和** `group_id` **的支持** " -"([#1595](https://github.com/adap/flower/pull/1595))" +"**在驱动程序应用程序接口中添加对** `workload_id` **和** `group_id` **的支持" +"** ([#1595](https://github.com/adap/flower/pull/1595))" #: ../../source/ref-changelog.md:362 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be " -"used to identify which workload a task belongs to. It also supports a new" -" `group_id` that can be used, for example, to indicate the current " -"training round. Both the `workload_id` and `group_id` enable client nodes" -" to decide whether they want to handle a task or not." +"The (experimental) Driver API now supports a `workload_id` that can be used " +"to identify which workload a task belongs to. It also supports a new " +"`group_id` that can be used, for example, to indicate the current training " +"round. Both the `workload_id` and `group_id` enable client nodes to decide " +"whether they want to handle a task or not." msgstr "" -"驱动程序 API(试验性)现在支持 `workload_id`,可用于识别任务所属的工作量。它还支持新的 " -"`group_id`,例如,可用于指示当前的训练轮次。通过 `workload_id` 和 `group_id` " -"客户端节点可以决定是否要处理某个任务。" +"驱动程序 API(试验性)现在支持 `workload_id`,可用于识别任务所属的工作量。它" +"还支持新的 `group_id`,例如,可用于指示当前的训练轮次。通过 `workload_id` 和 " +"`group_id` 客户端节点可以决定是否要处理某个任务。" #: ../../source/ref-changelog.md:364 msgid "" -"**Make Driver API and Fleet API address configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Make Driver API and Fleet API address configurable** ([#1637](https://" +"github.com/adap/flower/pull/1637))" msgstr "" -"**使Driver API 和Fleet " -"API地址可配置**([#1637](https://github.com/adap/flower/pull/1637))" +"**使Driver API 和Fleet API地址可配置**([#1637](https://github.com/adap/" +"flower/pull/1637))" #: ../../source/ref-changelog.md:366 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) " -"can now configure the server address of both Driver API (via `--driver-" -"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +"The (experimental) long-running Flower server (Driver API and Fleet API) can " +"now configure the server address of both Driver API (via `--driver-api-" +"address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" -"长期运行的 Flower 服务器(Driver API 和 Fleet API)现在可以在启动时配置 Driver API(通过 " -"`--driver-api-address`)和 Fleet API(通过 `-fleet-api-address`)的服务器地址:" +"长期运行的 Flower 服务器(Driver API 和 Fleet API)现在可以在启动时配置 " +"Driver API(通过 `--driver-api-address`)和 Fleet API(通过 `-fleet-api-" +"address`)的服务器地址:" #: ../../source/ref-changelog.md:368 #, fuzzy @@ -16712,68 +16827,69 @@ msgstr "支持 IPv4 和 IPv6 地址。" #: ../../source/ref-changelog.md:372 msgid "" -"**Add new example of Federated Learning using fastai and Flower** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"**Add new example of Federated Learning using fastai and Flower** ([#1598]" +"(https://github.com/adap/flower/pull/1598))" msgstr "" -"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** ([#1598](https://github." +"com/adap/flower/pull/1598))" #: ../../source/ref-changelog.md:374 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" -"/quickstart-fastai)." +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples/" +"quickstart-fastai)." msgstr "" -"一个新的代码示例(`quickstart-fastai`)演示了使用 [fastai](https://www.fast.ai/) 和 " -"Flower 的联邦学习。您可以在这里找到它: [quickstart-" -"fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" -"fastai)。" +"一个新的代码示例(`quickstart-fastai`)演示了使用 [fastai](https://www.fast." +"ai/) 和 Flower 的联邦学习。您可以在这里找到它: [quickstart-fastai](https://" +"github.com/adap/flower/tree/main/examples/quickstart-fastai)。" #: ../../source/ref-changelog.md:376 msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" -" versions of Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest " +"versions of Android** ([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -"**使安卓示例兼容** `flwr >= 1.0.0` **和最新版本的安卓** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"**使安卓示例兼容** `flwr >= 1.0.0` **和最新版本的安卓** ([#1603](https://" +"github.com/adap/flower/pull/1603))" #: ../../source/ref-changelog.md:378 msgid "" -"The Android code example has received a substantial update: the project " -"is compatible with Flower 1.0 (and later), the UI received a full " -"refresh, and the project is updated to be compatible with newer Android " -"tooling." +"The Android code example has received a substantial update: the project is " +"compatible with Flower 1.0 (and later), the UI received a full refresh, and " +"the project is updated to be compatible with newer Android tooling." msgstr "" -"Android 代码示例已进行了大幅更新:项目兼容 Flower 1.0(及更高版本),用户界面已全面刷新,项目已更新为兼容较新的 Android" -" 工具。" +"Android 代码示例已进行了大幅更新:项目兼容 Flower 1.0(及更高版本),用户界面" +"已全面刷新,项目已更新为兼容较新的 Android 工具。" #: ../../source/ref-changelog.md:380 msgid "" -"**Add new `FedProx` strategy** " -"([#1619](https://github.com/adap/flower/pull/1619))" -msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" +"**Add new `FedProx` strategy** ([#1619](https://github.com/adap/flower/" +"pull/1619))" +msgstr "" +"**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/" +"pull/1619))" #: ../../source/ref-changelog.md:382 msgid "" -"This " -"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" is almost identical to " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" but helps users replicate what is described in this " -"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " -"parameter called `proximal_mu` to regularize the local models with " -"respect to the global models." +"This [strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/" +"strategy/fedprox.py) is almost identical to [`FedAvg`](https://github.com/" +"adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py), but helps " +"users replicate what is described in this [paper](https://arxiv.org/" +"abs/1812.06127). It essentially adds a parameter called `proximal_mu` to " +"regularize the local models with respect to the global models." msgstr "" -"该[策略](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)与[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)几乎相同,但可以帮助用户复现本[论文](https://arxiv.org/abs/1812.06127)中的描述。它的本质是添加一个名为" -" `proximal_mu`的参数,使局部模型与全局模型正则化。" +"该[策略](https://github.com/adap/flower/blob/main/src/py/flwr/server/" +"strategy/fedprox.py)与[`FedAvg`](https://github.com/adap/flower/blob/main/" +"src/py/flwr/server/strategy/fedavg.py)几乎相同,但可以帮助用户复现本[论文]" +"(https://arxiv.org/abs/1812.06127)中的描述。它的本质是添加一个名为 " +"`proximal_mu`的参数,使局部模型与全局模型正则化。" #: ../../source/ref-changelog.md:384 msgid "" -"**Add new metrics to telemetry events** " -"([#1640](https://github.com/adap/flower/pull/1640))" -msgstr "**为遥测事件添加新指标**([#1640](https://github.com/adap/flower/pull/1640))" +"**Add new metrics to telemetry events** ([#1640](https://github.com/adap/" +"flower/pull/1640))" +msgstr "" +"**为遥测事件添加新指标**([#1640](https://github.com/adap/flower/pull/1640))" #: ../../source/ref-changelog.md:386 msgid "" @@ -16783,134 +16899,114 @@ msgstr "例如,更新后的事件结构可以将同一工作负载中的事件 #: ../../source/ref-changelog.md:388 msgid "" -"**Add new custom strategy tutorial section** " -"[#1623](https://github.com/adap/flower/pull/1623)" -msgstr "**添加新的自定义策略教程部分** [#1623](https://github.com/adap/flower/pull/1623)" +"**Add new custom strategy tutorial section** [#1623](https://github.com/adap/" +"flower/pull/1623)" +msgstr "" +"**添加新的自定义策略教程部分** [#1623](https://github.com/adap/flower/" +"pull/1623)" #: ../../source/ref-changelog.md:390 msgid "" -"The Flower tutorial now has a new section that covers implementing a " -"custom strategy from scratch: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers implementing a custom " +"strategy from scratch: [Open in Colab](https://colab.research.google.com/" +"github/adap/flower/blob/main/doc/source/tutorial-build-a-strategy-from-" +"scratch-pytorch.ipynb)" msgstr "" -"Flower 教程新增了一个章节,介绍如何从零开始实施自定义策略: [在 Colab " -"中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"Flower 教程新增了一个章节,介绍如何从零开始实施自定义策略: [在 Colab 中打开]" +"(https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" #: ../../source/ref-changelog.md:392 msgid "" -"**Add new custom serialization tutorial section** " -"([#1622](https://github.com/adap/flower/pull/1622))" -msgstr "** 添加新的自定义序列化教程部分** ([#1622](https://github.com/adap/flower/pull/1622))" +"**Add new custom serialization tutorial section** ([#1622](https://github." +"com/adap/flower/pull/1622))" +msgstr "" +"** 添加新的自定义序列化教程部分** ([#1622](https://github.com/adap/flower/" +"pull/1622))" #: ../../source/ref-changelog.md:394 msgid "" -"The Flower tutorial now has a new section that covers custom " -"serialization: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers custom serialization: " +"[Open in Colab](https://colab.research.google.com/github/adap/flower/blob/" +"main/doc/source/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" -"Flower 教程现在新增了一个章节,介绍自定义序列化: [在 Colab " -"中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"Flower 教程现在新增了一个章节,介绍自定义序列化: [在 Colab 中打开](https://" +"colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-" +"customize-the-client-pytorch.ipynb)" #: ../../source/ref-changelog.md:396 msgid "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github.com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" -msgstr "" -"**普通改进** ([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github. com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github. com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github. com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" +"**General improvements** ([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), [#1636](https://github." +"com/adap/flower/pull/1636), [#1635](https://github.com/adap/flower/" +"pull/1635), [#1633](https://github.com/adap/flower/pull/1633), [#1632]" +"(https://github.com/adap/flower/pull/1632), [#1631](https://github.com/adap/" +"flower/pull/1631), [#1630](https://github.com/adap/flower/pull/1630), [#1627]" +"(https://github.com/adap/flower/pull/1627), [#1593](https://github.com/adap/" +"flower/pull/1593), [#1616](https://github.com/adap/flower/pull/1616), [#1615]" +"(https://github.com/adap/flower/pull/1615), [#1607](https://github.com/adap/" +"flower/pull/1607), [#1609](https://github.com/adap/flower/pull/1609), [#1608]" +"(https://github.com/adap/flower/pull/1608), [#1603](https://github.com/adap/" +"flower/pull/1603), [#1590](https://github.com/adap/flower/pull/1590), [#1580]" +"(https://github.com/adap/flower/pull/1580), [#1599](https://github.com/adap/" +"flower/pull/1599), [#1600](https://github.com/adap/flower/pull/1600), [#1601]" +"(https://github.com/adap/flower/pull/1601), [#1597](https://github.com/adap/" +"flower/pull/1597), [#1595](https://github.com/adap/flower/pull/1595), [#1591]" +"(https://github.com/adap/flower/pull/1591), [#1588](https://github.com/adap/" +"flower/pull/1588), [#1589](https://github.com/adap/flower/pull/1589), [#1587]" +"(https://github.com/adap/flower/pull/1587), [#1573](https://github.com/adap/" +"flower/pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" +"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" +"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" +"(https://github.com/adap/flower/pull/1586))" +msgstr "" +"**普通改进** ([#1638](https://github.com/adap/flower/pull/1638), [#1634]" +"(https://github.com/adap/flower/pull/1634), [#1636](https://github.com/adap/" +"flower/pull/1636), [#1635](https://github.com/adap/flower/pull/1635), [#1633]" +"(https://github.com/adap/flower/pull/1633), [#1632](https://github.com/adap/" +"flower/pull/1632), [#1631](https://github.com/adap/flower/pull/1631), [#1630]" +"(https://github.com/adap/flower/pull/1630), [#1627](https://github. com/adap/" +"flower/pull/1627), [#1593](https://github.com/adap/flower/pull/1593), [#1616]" +"(https://github.com/adap/flower/pull/1616), [#1615](https://github.com/adap/" +"flower/pull/1615), [#1607](https://github.com/adap/flower/pull/1607), [#1609]" +"(https://github.com/adap/flower/pull/1609), [#1608](https://github.com/adap/" +"flower/pull/1608), [#1603](https://github.com/adap/flower/pull/1603), [#1590]" +"(https://github. com/adap/flower/pull/1590), [#1580](https://github.com/adap/" +"flower/pull/1580), [#1599](https://github.com/adap/flower/pull/1599), [#1600]" +"(https://github.com/adap/flower/pull/1600), [#1601](https://github.com/adap/" +"flower/pull/1601), [#1597](https://github.com/adap/flower/pull/1597), [#1595]" +"(https://github.com/adap/flower/pull/1595), [#1591](https://github.com/adap/" +"flower/pull/1591), [#1588](https://github. com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), [#1587](https://github." +"com/adap/flower/pull/1587), [#1573](https://github.com/adap/flower/" +"pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" +"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" +"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" +"(https://github.com/adap/flower/pull/1586))" #: ../../source/ref-changelog.md:400 msgid "" -"**Updated documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" -msgstr "" -"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614)))" +"**Updated documentation** ([#1629](https://github.com/adap/flower/" +"pull/1629), [#1628](https://github.com/adap/flower/pull/1628), [#1620]" +"(https://github.com/adap/flower/pull/1620), [#1618](https://github.com/adap/" +"flower/pull/1618), [#1617](https://github.com/adap/flower/pull/1617), [#1613]" +"(https://github.com/adap/flower/pull/1613), [#1614](https://github.com/adap/" +"flower/pull/1614))" +msgstr "" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), [#1628]" +"(https://github.com/adap/flower/pull/1628), [#1620](https://github.com/adap/" +"flower/pull/1620), [#1618](https://github.com/adap/flower/pull/1618), [#1617]" +"(https://github.com/adap/flower/pull/1617), [#1613](https://github.com/adap/" +"flower/pull/1613), [#1614](https://github.com/adap/flower/pull/1614)))" #: ../../source/ref-changelog.md:402 ../../source/ref-changelog.md:469 msgid "" -"As usual, the documentation has improved quite a bit. It is another step " -"in our effort to make the Flower documentation the best documentation of " -"any project. Stay tuned and as always, feel free to provide feedback!" -msgstr "和往常一样,我们的文档有了很大的改进。这是我们努力使 Flower 文档成为所有项目中最好文档的又一步骤。请继续关注,并随时提供反馈意见!" +"As usual, the documentation has improved quite a bit. It is another step in " +"our effort to make the Flower documentation the best documentation of any " +"project. Stay tuned and as always, feel free to provide feedback!" +msgstr "" +"和往常一样,我们的文档有了很大的改进。这是我们努力使 Flower 文档成为所有项目" +"中最好文档的又一步骤。请继续关注,并随时提供反馈意见!" #: ../../source/ref-changelog.md:408 msgid "v1.2.0 (2023-01-13)" @@ -16918,21 +17014,19 @@ msgstr "v1.2.0 (2023-01-13)" #: ../../source/ref-changelog.md:414 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " +"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " +"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" #: ../../source/ref-changelog.md:418 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"**Introduce new Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/" +"adap/flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -"**引入新的 Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"**引入新的 Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/adap/" +"flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" #: ../../source/ref-changelog.md:420 msgid "" @@ -16940,283 +17034,272 @@ msgid "" "implementations useful especially to FL newcomers. They will typically " "revisit well known papers from the literature, and be suitable for " "integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in " -"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" +"deepen your knowledge of FL in general. Today's release is the first in this " +"series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-pack-" +"fedavg-mnist-cnn/)" msgstr "" -"在未来几周内,我们将发布一些新的参考,特别是对 FL " -"新手有用的方法。它们通常会重温文献中的知名论文,适合集成到您自己的应用程序中或用于实验,以加深您对 FL " -"的总体了解。今天发布的是该系列中的第一篇。[阅读全文](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" +"在未来几周内,我们将发布一些新的参考,特别是对 FL 新手有用的方法。它们通常会" +"重温文献中的知名论文,适合集成到您自己的应用程序中或用于实验,以加深您对 FL " +"的总体了解。今天发布的是该系列中的第一篇。[阅读全文](https://flower.ai/" +"blog/2023-01-12-fl-starter-pack-fedavg-mnist-cnn/)" #: ../../source/ref-changelog.md:422 msgid "" -"**Improve GPU support in simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" -msgstr "**改进模拟中的 GPU 支持**([#1555](https://github.com/adap/flower/pull/1555))" +"**Improve GPU support in simulations** ([#1555](https://github.com/adap/" +"flower/pull/1555))" +msgstr "" +"**改进模拟中的 GPU 支持**([#1555](https://github.com/adap/flower/" +"pull/1555))" #: ../../source/ref-changelog.md:424 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" -" to improve GPU support. The update includes some of the hard-earned " -"lessons from scaling simulations in GPU cluster environments. New " -"defaults make running GPU-based simulations substantially more robust." +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated to " +"improve GPU support. The update includes some of the hard-earned lessons " +"from scaling simulations in GPU cluster environments. New defaults make " +"running GPU-based simulations substantially more robust." msgstr "" -"基于 Ray 的虚拟客户端引擎 (`start_simulation`)已更新,以改进对 GPU 的支持。此次更新包含了在 GPU " -"集群环境中扩展模拟的一些经验教训。新的默认设置使基于 GPU 的模拟运行更加稳健。" +"基于 Ray 的虚拟客户端引擎 (`start_simulation`)已更新,以改进对 GPU 的支持。此" +"次更新包含了在 GPU 集群环境中扩展模拟的一些经验教训。新的默认设置使基于 GPU " +"的模拟运行更加稳健。" #: ../../source/ref-changelog.md:426 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" +"**Improve GPU support in Jupyter Notebook tutorials** ([#1527](https://" +"github.com/adap/flower/pull/1527), [#1558](https://github.com/adap/flower/" +"pull/1558))" msgstr "" -"**改进 Jupyter Notebook 教程中的 GPU 支持** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" +"**改进 Jupyter Notebook 教程中的 GPU 支持** ([#1527](https://github.com/adap/" +"flower/pull/1527), [#1558](https://github.com/adap/flower/pull/1558))" #: ../../source/ref-changelog.md:428 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to " -"use on GPU instances. We listened and made improvements to all of our " -"Jupyter notebooks! Check out the updated notebooks here:" +"Some users reported that Jupyter Notebooks have not always been easy to use " +"on GPU instances. We listened and made improvements to all of our Jupyter " +"notebooks! Check out the updated notebooks here:" msgstr "" -"一些用户报告说,在 GPU 实例上使用 Jupyter 笔记本并不是很方便。我们听取了他们的意见,并对所有 Jupyter " -"笔记本进行了改进!点击这里查看更新后的笔记本:" +"一些用户报告说,在 GPU 实例上使用 Jupyter 笔记本并不是很方便。我们听取了他们" +"的意见,并对所有 Jupyter 笔记本进行了改进!点击这里查看更新后的笔记本:" #: ../../source/ref-changelog.md:430 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework" -"/tutorial-get-started-with-flower-pytorch.html)" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework/" +"tutorial-get-started-with-flower-pytorch.html)" msgstr "" "[联邦学习简介](https://flower.ai/docs/framework/tutorial-get-started-with-" "flower-pytorch.html)" #: ../../source/ref-changelog.md:431 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework" -"/tutorial-use-a-federated-learning-strategy-pytorch.html)" +"[Strategies in Federated Learning](https://flower.ai/docs/framework/tutorial-" +"use-a-federated-learning-strategy-pytorch.html)" msgstr "" "[联邦学习策略](https://flower.ai/docs/framework/tutorial-use-a-federated-" "learning-strategy-pytorch.html)" #: ../../source/ref-changelog.md:432 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" -"-strategy-from-scratch-pytorch.html)" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a-" +"strategy-from-scratch-pytorch.html)" msgstr "" "[制定策略](https://flower.ai/docs/framework/tutorial-build-a-strategy-from-" "scratch-pytorch.html)" #: ../../source/ref-changelog.md:433 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" -"customize-the-client-pytorch.html)" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" +"the-client-pytorch.html)" msgstr "" "[客户端和 NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" "the-client-pytorch.html)" #: ../../source/ref-changelog.md:435 msgid "" -"**Introduce optional telemetry** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" +"**Introduce optional telemetry** ([#1533](https://github.com/adap/flower/" +"pull/1533), [#1544](https://github.com/adap/flower/pull/1544), [#1584]" +"(https://github.com/adap/flower/pull/1584))" msgstr "" -"**引入可选遥测**([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584)" +"**引入可选遥测**([#1533](https://github.com/adap/flower/pull/1533), [#1544]" +"(https://github.com/adap/flower/pull/1544), [#1584](https://github.com/adap/" +"flower/pull/1584)" #: ../../source/ref-changelog.md:437 msgid "" -"After a [request for " -"feedback](https://github.com/adap/flower/issues/1534) from the community," -" the Flower open-source project introduces optional collection of " -"*anonymous* usage metrics to make well-informed decisions to improve " -"Flower. Doing this enables the Flower team to understand how Flower is " -"used and what challenges users might face." +"After a [request for feedback](https://github.com/adap/flower/issues/1534) " +"from the community, the Flower open-source project introduces optional " +"collection of *anonymous* usage metrics to make well-informed decisions to " +"improve Flower. Doing this enables the Flower team to understand how Flower " +"is used and what challenges users might face." msgstr "" "在社区发出[反馈请求](https://github.com/adap/flower/issues/1534)之后,Flower " -"开放源码项目引入了可选的*匿名*使用指标收集,以便在充分知情的情况下做出改进 Flower 的决定。这样做能让 Flower 团队了解 " -"Flower 的使用情况以及用户可能面临的挑战。" +"开放源码项目引入了可选的*匿名*使用指标收集,以便在充分知情的情况下做出改进 " +"Flower 的决定。这样做能让 Flower 团队了解 Flower 的使用情况以及用户可能面临的" +"挑战。" #: ../../source/ref-changelog.md:439 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users who do not want to share anonymous usage metrics. " -"[Read more.](https://flower.ai/docs/telemetry.html)." +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users who do not want to share anonymous usage metrics. [Read more.]" +"(https://flower.ai/docs/telemetry.html)." msgstr "" -"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower " -"遵循这一声明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。[阅读全文](https://flower.ai/docs/telemetry.html)。" +"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声" +"明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。[阅读全文](https://" +"flower.ai/docs/telemetry.html)。" #: ../../source/ref-changelog.md:441 msgid "" -"**Introduce (experimental) Driver API** " -"([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" -msgstr "" -"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/pull/1520)," -" [#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**Introduce (experimental) Driver API** ([#1520](https://github.com/adap/" +"flower/pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" +"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" +"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" +"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" +"flower/pull/1567))" +msgstr "" +"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/" +"pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" +"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" +"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" +"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" +"flower/pull/1567))" #: ../../source/ref-changelog.md:443 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API" -" will be the abstraction that many upcoming features will be built on - " -"and you can start building those things now, too." +"Analytics applications. Phew, that's a lot! Going forward, the Driver API " +"will be the abstraction that many upcoming features will be built on - and " +"you can start building those things now, too." msgstr "" -"Flower 现在有了一个新的(试验性的)驱动程序应用程序接口(Driver " -"API),它将支持完全可编程、异步和多租户的联邦学习(Federated Learning)和联邦分析(Federated " -"Analytics)应用程序。展望未来,Driver API 将成为许多即将推出的功能的抽象基础,您现在就可以开始构建这些功能。" +"Flower 现在有了一个新的(试验性的)驱动程序应用程序接口(Driver API),它将支" +"持完全可编程、异步和多租户的联邦学习(Federated Learning)和联邦分析" +"(Federated Analytics)应用程序。展望未来,Driver API 将成为许多即将推出的功" +"能的抽象基础,您现在就可以开始构建这些功能。" #: ../../source/ref-changelog.md:445 msgid "" -"The Driver API also enables a new execution mode in which the server runs" -" indefinitely. Multiple individual workloads can run concurrently and " -"start and stop their execution independent of the server. This is " -"especially useful for users who want to deploy Flower in production." +"The Driver API also enables a new execution mode in which the server runs " +"indefinitely. Multiple individual workloads can run concurrently and start " +"and stop their execution independent of the server. This is especially " +"useful for users who want to deploy Flower in production." msgstr "" -"驱动程序应用程序接口还支持一种新的执行模式,在这种模式下,服务器可无限期运行。多个单独的工作负载可以同时运行,并独立于服务器启动和停止执行。这对于希望在生产中部署" -" Flower 的用户来说尤其有用。" +"驱动程序应用程序接口还支持一种新的执行模式,在这种模式下,服务器可无限期运" +"行。多个单独的工作负载可以同时运行,并独立于服务器启动和停止执行。这对于希望" +"在生产中部署 Flower 的用户来说尤其有用。" #: ../../source/ref-changelog.md:447 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward " -"to you feedback!" +"To learn more, check out the `mt-pytorch` code example. We look forward to " +"you feedback!" msgstr "要了解更多信息,请查看 `mt-pytorch` 代码示例。我们期待您的反馈!" #: ../../source/ref-changelog.md:449 msgid "" -"Please note: *The Driver API is still experimental and will likely change" -" significantly over time.*" +"Please note: *The Driver API is still experimental and will likely change " +"significantly over time.*" msgstr "请注意:Driver API仍处于试验阶段,随着时间的推移可能会发生重大变化。*" #: ../../source/ref-changelog.md:451 msgid "" -"**Add new Federated Analytics with Pandas example** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"**Add new Federated Analytics with Pandas example** ([#1469](https://github." +"com/adap/flower/pull/1469), [#1535](https://github.com/adap/flower/" +"pull/1535))" msgstr "" -"** 添加新的使用 Pandas " -"的联邦分析示例**([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535)" +"** 添加新的使用 Pandas 的联邦分析示例**([#1469](https://github.com/adap/" +"flower/pull/1469), [#1535](https://github.com/adap/flower/pull/1535)" #: ../../source/ref-changelog.md:453 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics" -" with Pandas and Flower. You can find it here: [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." +"A new code example (`quickstart-pandas`) demonstrates federated analytics " +"with Pandas and Flower. You can find it here: [quickstart-pandas](https://" +"github.com/adap/flower/tree/main/examples/quickstart-pandas)." msgstr "" -"新代码示例(`quickstart-pandas`)演示了使用 Pandas 和 Flower 进行联邦分析。您可以在此处找到它: " -"[quickstart-pandas](https://github.com/adap/flower/tree/main/examples" -"/quickstart-pandas)。" +"新代码示例(`quickstart-pandas`)演示了使用 Pandas 和 Flower 进行联邦分析。您" +"可以在此处找到它: [quickstart-pandas](https://github.com/adap/flower/tree/" +"main/examples/quickstart-pandas)。" #: ../../source/ref-changelog.md:455 msgid "" -"**Add new strategies: Krum and MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"**Add new strategies: Krum and MultiKrum** ([#1481](https://github.com/adap/" +"flower/pull/1481))" msgstr "" -"**添加新策略: Krum 和 MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"**添加新策略: Krum 和 MultiKrum** ([#1481](https://github.com/adap/flower/" +"pull/1481))" #: ../../source/ref-changelog.md:457 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum " -"and MultiKrum in their workloads." +"contributed a new `Krum` strategy that enables users to easily use Krum and " +"MultiKrum in their workloads." msgstr "" -"罗马萨皮恩扎大学(Sapienza University)计算机科学专业的学生埃多尔多(Edoardo)提出了一种新的 \"Krum " -"\"策略,使用户能够在其工作负载中轻松使用 Krum 和 MultiKrum。" +"罗马萨皮恩扎大学(Sapienza University)计算机科学专业的学生埃多尔多" +"(Edoardo)提出了一种新的 \"Krum \"策略,使用户能够在其工作负载中轻松使用 " +"Krum 和 MultiKrum。" #: ../../source/ref-changelog.md:459 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"**Update C++ example to be compatible with Flower v1.2.0** ([#1495](https://" +"github.com/adap/flower/pull/1495))" msgstr "" -"** 更新 C++ 示例,与 Flower v1.2.0 兼容** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"** 更新 C++ 示例,与 Flower v1.2.0 兼容** ([#1495](https://github.com/adap/" +"flower/pull/1495))" #: ../../source/ref-changelog.md:461 msgid "" -"The C++ code example has received a substantial update to make it " -"compatible with the latest version of Flower." +"The C++ code example has received a substantial update to make it compatible " +"with the latest version of Flower." msgstr "为了与最新版本的 Flower 兼容,C++ 示例代码进行了大幅更新。" #: ../../source/ref-changelog.md:463 msgid "" -"**General improvements** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" -msgstr "" -"**普通改进** ([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github. com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**General improvements** ([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), [#1506](https://github." +"com/adap/flower/pull/1506), [#1514](https://github.com/adap/flower/" +"pull/1514), [#1522](https://github.com/adap/flower/pull/1522), [#1523]" +"(https://github.com/adap/flower/pull/1523), [#1526](https://github.com/adap/" +"flower/pull/1526), [#1528](https://github.com/adap/flower/pull/1528), [#1547]" +"(https://github.com/adap/flower/pull/1547), [#1549](https://github.com/adap/" +"flower/pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" +"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" +"flower/pull/1566))" +msgstr "" +"**普通改进** ([#1491](https://github.com/adap/flower/pull/1491), [#1504]" +"(https://github.com/adap/flower/pull/1504), [#1506](https://github.com/adap/" +"flower/pull/1506), [#1514](https://github.com/adap/flower/pull/1514), [#1522]" +"(https://github.com/adap/flower/pull/1522), [#1523](https://github.com/adap/" +"flower/pull/1523), [#1526](https://github. com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), [#1547](https://github." +"com/adap/flower/pull/1547), [#1549](https://github.com/adap/flower/" +"pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" +"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" +"flower/pull/1566))" #: ../../source/ref-changelog.md:467 msgid "" -"**Updated documentation** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" -msgstr "" -"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" +"**Updated documentation** ([#1494](https://github.com/adap/flower/" +"pull/1494), [#1496](https://github.com/adap/flower/pull/1496), [#1500]" +"(https://github.com/adap/flower/pull/1500), [#1503](https://github.com/adap/" +"flower/pull/1503), [#1505](https://github.com/adap/flower/pull/1505), [#1524]" +"(https://github.com/adap/flower/pull/1524), [#1518](https://github.com/adap/" +"flower/pull/1518), [#1519](https://github.com/adap/flower/pull/1519), [#1515]" +"(https://github.com/adap/flower/pull/1515))" +msgstr "" +"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), [#1496]" +"(https://github.com/adap/flower/pull/1496), [#1500](https://github.com/adap/" +"flower/pull/1500), [#1503](https://github.com/adap/flower/pull/1503), [#1505]" +"(https://github.com/adap/flower/pull/1505), [#1524](https://github.com/adap/" +"flower/pull/1524), [#1518](https://github.com/adap/flower/pull/1518), [#1519]" +"(https://github.com/adap/flower/pull/1519), [#1515](https://github.com/adap/" +"flower/pull/1515))" #: ../../source/ref-changelog.md:471 msgid "" -"One highlight is the new [first time contributor " -"guide](https://flower.ai/docs/first-time-contributors.html): if you've " -"never contributed on GitHub before, this is the perfect place to start!" +"One highlight is the new [first time contributor guide](https://flower.ai/" +"docs/first-time-contributors.html): if you've never contributed on GitHub " +"before, this is the perfect place to start!" msgstr "" "其中一个亮点是新的[首次贡献者指南](https://flower.ai/docs/first-time-" -"contributors.html):如果你以前从未在 GitHub 上做过贡献,这将是一个完美的开始!" +"contributors.html):如果你以前从未在 GitHub 上做过贡献,这将是一个完美的开" +"始!" #: ../../source/ref-changelog.md:477 msgid "v1.1.0 (2022-10-31)" @@ -17226,183 +17309,184 @@ msgstr "v1.1.0 (2022-10-31)" msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" -msgstr "在此,我们向所有促成 Flower 新版本的贡献者致以**特别的谢意(按 \"git shortlog \"顺序排列):" +msgstr "" +"在此,我们向所有促成 Flower 新版本的贡献者致以**特别的谢意(按 \"git " +"shortlog \"顺序排列):" #: ../../source/ref-changelog.md:483 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " +"`edogab33`" msgstr "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " +"`edogab33`" #: ../../source/ref-changelog.md:487 msgid "" -"**Introduce Differential Privacy wrappers (preview)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"**Introduce Differential Privacy wrappers (preview)** ([#1357](https://" +"github.com/adap/flower/pull/1357), [#1460](https://github.com/adap/flower/" +"pull/1460))" msgstr "" -"**引入差分隐私包装器(预览)** ([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"**引入差分隐私包装器(预览)** ([#1357](https://github.com/adap/flower/" +"pull/1357), [#1460](https://github.com/adap/flower/pull/1460))" #: ../../source/ref-changelog.md:489 msgid "" -"The first (experimental) preview of pluggable Differential Privacy " -"wrappers enables easy configuration and usage of differential privacy " -"(DP). The pluggable DP wrappers enable framework-agnostic **and** " -"strategy-agnostic usage of both client-side DP and server-side DP. Head " -"over to the Flower docs, a new explainer goes into more detail." +"The first (experimental) preview of pluggable Differential Privacy wrappers " +"enables easy configuration and usage of differential privacy (DP). The " +"pluggable DP wrappers enable framework-agnostic **and** strategy-agnostic " +"usage of both client-side DP and server-side DP. Head over to the Flower " +"docs, a new explainer goes into more detail." msgstr "" -"可插拔差分隐私封装器的首个(实验性)预览版可轻松配置和使用差分隐私(DP)。可插拔的差分隐私封装器可实现客户端差分隐私和服务器端差分隐私的框架无关**以及**策略无关的使用。请访问" -" Flower 文档,新的解释器会提供更多细节。" +"可插拔差分隐私封装器的首个(实验性)预览版可轻松配置和使用差分隐私(DP)。可" +"插拔的差分隐私封装器可实现客户端差分隐私和服务器端差分隐私的框架无关**以及**" +"策略无关的使用。请访问 Flower 文档,新的解释器会提供更多细节。" #: ../../source/ref-changelog.md:491 msgid "" -"**New iOS CoreML code example** " -"([#1289](https://github.com/adap/flower/pull/1289))" -msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" +"**New iOS CoreML code example** ([#1289](https://github.com/adap/flower/" +"pull/1289))" +msgstr "" +"**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/" +"pull/1289))" #: ../../source/ref-changelog.md:493 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can " -"be built for iOS. The code example contains both Flower iOS SDK " -"components that can be used for many tasks, and one task example running " -"on CoreML." +"Flower goes iOS! A massive new code example shows how Flower clients can be " +"built for iOS. The code example contains both Flower iOS SDK components that " +"can be used for many tasks, and one task example running on CoreML." msgstr "" -"Flower 进入 iOS!大量新代码示例展示了如何为 iOS 构建 Flower 客户端。该代码示例包含可用于多种任务的 Flower iOS " -"SDK 组件,以及在 CoreML 上运行的一个任务示例。" +"Flower 进入 iOS!大量新代码示例展示了如何为 iOS 构建 Flower 客户端。该代码示" +"例包含可用于多种任务的 Flower iOS SDK 组件,以及在 CoreML 上运行的一个任务示" +"例。" #: ../../source/ref-changelog.md:495 msgid "" -"**New FedMedian strategy** " -"([#1461](https://github.com/adap/flower/pull/1461))" -msgstr "**新的联邦医疗策略** ([#1461](https://github.com/adap/flower/pull/1461))" +"**New FedMedian strategy** ([#1461](https://github.com/adap/flower/" +"pull/1461))" +msgstr "" +"**新的联邦医疗策略** ([#1461](https://github.com/adap/flower/pull/1461))" #: ../../source/ref-changelog.md:497 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by " -"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"The new `FedMedian` strategy implements Federated Median (FedMedian) by [Yin " +"et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -"新的 \"FedMedian \"战略实现了[Yin " -"等人,2018]的联邦中值(FedMedian)(https://arxiv.org/pdf/1803.01498v1.pdf)。" +"新的 \"FedMedian \"战略实现了[Yin 等人,2018]的联邦中值(FedMedian)(https://" +"arxiv.org/pdf/1803.01498v1.pdf)。" #: ../../source/ref-changelog.md:499 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** " -"([#1493](https://github.com/adap/flower/pull/1493))" -msgstr "**虚拟客户端引擎中的**日志**`客户端`**异常([#1493](https://github.com/adap/flower/pull/1493))" +"**Log** `Client` **exceptions in Virtual Client Engine** ([#1493](https://" +"github.com/adap/flower/pull/1493))" +msgstr "" +"**虚拟客户端引擎中的**日志**`客户端`**异常([#1493](https://github.com/adap/" +"flower/pull/1493))" #: ../../source/ref-changelog.md:501 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default " -"and not just exposed to the configured `Strategy` (via the `failures` " -"argument)." -msgstr "VCE 中发生的所有 \"客户端 \"异常现在都会被默认记录下来,而不只是暴露给配置的 `Strategy`(通过 `failures`参数)。" +"All `Client` exceptions happening in the VCE are now logged by default and " +"not just exposed to the configured `Strategy` (via the `failures` argument)." +msgstr "" +"VCE 中发生的所有 \"客户端 \"异常现在都会被默认记录下来,而不只是暴露给配置的 " +"`Strategy`(通过 `failures`参数)。" #: ../../source/ref-changelog.md:503 msgid "" -"**Improve Virtual Client Engine internals** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" -msgstr "**改进虚拟客户端引擎内部**([#1401](https://github.com/adap/flower/pull/1401)、[#1453](https://github.com/adap/flower/pull/1453))" +"**Improve Virtual Client Engine internals** ([#1401](https://github.com/adap/" +"flower/pull/1401), [#1453](https://github.com/adap/flower/pull/1453))" +msgstr "" +"**改进虚拟客户端引擎内部**([#1401](https://github.com/adap/flower/" +"pull/1401)、[#1453](https://github.com/adap/flower/pull/1453))" #: ../../source/ref-changelog.md:505 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE " -"now uses Ray 2.0 under the hood, the value type of the `client_resources`" -" dictionary changed to `float` to allow fractions of resources to be " +"Some internals of the Virtual Client Engine have been revamped. The VCE now " +"uses Ray 2.0 under the hood, the value type of the `client_resources` " +"dictionary changed to `float` to allow fractions of resources to be " "allocated." msgstr "" -"虚拟客户端引擎的部分内部结构已进行了修改。VCE 现在使用 Ray 2.0,\"client_resources \"字典的值类型改为 " -"\"float\",以允许分配分数资源。" +"虚拟客户端引擎的部分内部结构已进行了修改。VCE 现在使用 Ray " +"2.0,\"client_resources \"字典的值类型改为 \"float\",以允许分配分数资源。" #: ../../source/ref-changelog.md:507 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual Client " +"Engine**" msgstr "**支持虚拟客户端引擎中的可选** `Client`**/**`NumPyClient` **方法**" #: ../../source/ref-changelog.md:509 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and" -" `NumPyClient`) methods." +"The Virtual Client Engine now has full support for optional `Client` (and " +"`NumPyClient`) methods." msgstr "虚拟客户端引擎现在完全支持可选的 `Client`(和 `NumPyClient`)方法。" #: ../../source/ref-changelog.md:511 msgid "" -"**Provide type information to packages using** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"**Provide type information to packages using** `flwr` ([#1377](https://" +"github.com/adap/flower/pull/1377))" msgstr "" -"**使用** `flwr`向软件包提供类型信息 " -"([#1377](https://github.com/adap/flower/pull/1377))" +"**使用** `flwr`向软件包提供类型信息 ([#1377](https://github.com/adap/flower/" +"pull/1377))" #: ../../source/ref-changelog.md:513 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that " -"the package is typed. This enables typing support for projects or " -"packages that use `flwr` by enabling them to improve their code using " -"static type checkers like `mypy`." +"The package `flwr` is now bundled with a `py.typed` file indicating that the " +"package is typed. This enables typing support for projects or packages that " +"use `flwr` by enabling them to improve their code using static type checkers " +"like `mypy`." msgstr "" -"软件包 `flwr` 现在捆绑了一个 `py.typed` 文件,表明该软件包是类型化的。这样,使用 `flwr` 的项目或软件包就可以使用 " -"`mypy` 等静态类型检查器改进代码,从而获得类型支持。" +"软件包 `flwr` 现在捆绑了一个 `py.typed` 文件,表明该软件包是类型化的。这样," +"使用 `flwr` 的项目或软件包就可以使用 `mypy` 等静态类型检查器改进代码,从而获" +"得类型支持。" #: ../../source/ref-changelog.md:515 msgid "" -"**Updated code example** " -"([#1344](https://github.com/adap/flower/pull/1344), " +"**Updated code example** ([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -"** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" +"** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), [#1347]" +"(https://github.com/adap/flower/pull/1347))" #: ../../source/ref-changelog.md:517 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." -msgstr "涵盖 scikit-learn 和 PyTorch Lightning 的代码示例已更新,以便与最新版本的 Flower 配合使用。" +msgstr "" +"涵盖 scikit-learn 和 PyTorch Lightning 的代码示例已更新,以便与最新版本的 " +"Flower 配合使用。" #: ../../source/ref-changelog.md:519 msgid "" -"**Updated documentation** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" -msgstr "" -"**更新文档** ([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github. com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +"**Updated documentation** ([#1355](https://github.com/adap/flower/" +"pull/1355), [#1558](https://github.com/adap/flower/pull/1558), [#1379]" +"(https://github.com/adap/flower/pull/1379), [#1380](https://github.com/adap/" +"flower/pull/1380), [#1381](https://github.com/adap/flower/pull/1381), [#1332]" +"(https://github.com/adap/flower/pull/1332), [#1391](https://github.com/adap/" +"flower/pull/1391), [#1403](https://github.com/adap/flower/pull/1403), [#1364]" +"(https://github.com/adap/flower/pull/1364), [#1409](https://github.com/adap/" +"flower/pull/1409), [#1419](https://github.com/adap/flower/pull/1419), [#1444]" +"(https://github.com/adap/flower/pull/1444), [#1448](https://github.com/adap/" +"flower/pull/1448), [#1417](https://github.com/adap/flower/pull/1417), [#1449]" +"(https://github.com/adap/flower/pull/1449), [#1465](https://github.com/adap/" +"flower/pull/1465), [#1467](https://github.com/adap/flower/pull/1467))" +msgstr "" +"**更新文档** ([#1355](https://github.com/adap/flower/pull/1355), [#1558]" +"(https://github.com/adap/flower/pull/1558), [#1379](https://github.com/adap/" +"flower/pull/1379), [#1380](https://github.com/adap/flower/pull/1380), [#1381]" +"(https://github.com/adap/flower/pull/1381), [#1332](https://github.com/adap/" +"flower/pull/1332), [#1391](https://github.com/adap/flower/pull/1391), [#1403]" +"(https://github.com/adap/flower/pull/1403), [#1364](https://github. com/adap/" +"flower/pull/1364), [#1409](https://github.com/adap/flower/pull/1409), [#1419]" +"(https://github.com/adap/flower/pull/1419), [#1444](https://github.com/adap/" +"flower/pull/1444), [#1448](https://github.com/adap/flower/pull/1448), [#1417]" +"(https://github.com/adap/flower/pull/1417), [#1449](https://github.com/adap/" +"flower/pull/1449), [#1465](https://github.com/adap/flower/pull/1465), [#1467]" +"(https://github.com/adap/flower/pull/1467))" #: ../../source/ref-changelog.md:521 msgid "" @@ -17412,58 +17496,60 @@ msgstr "文档更新的数量之多,甚至没有必要逐一列出。" #: ../../source/ref-changelog.md:523 msgid "" -"**Restructured documentation** " -"([#1387](https://github.com/adap/flower/pull/1387))" +"**Restructured documentation** ([#1387](https://github.com/adap/flower/" +"pull/1387))" msgstr "**重构文档**([#1387](https://github.com/adap/flower/pull/1387))" #: ../../source/ref-changelog.md:525 msgid "" -"The documentation has been restructured to make it easier to navigate. " -"This is just the first step in a larger effort to make the Flower " -"documentation the best documentation of any project ever. Stay tuned!" -msgstr "我们对文档进行了重组,使其更易于浏览。这只是让 Flower 文档成为所有项目中最好文档的第一步。敬请期待!" +"The documentation has been restructured to make it easier to navigate. This " +"is just the first step in a larger effort to make the Flower documentation " +"the best documentation of any project ever. Stay tuned!" +msgstr "" +"我们对文档进行了重组,使其更易于浏览。这只是让 Flower 文档成为所有项目中最好" +"文档的第一步。敬请期待!" #: ../../source/ref-changelog.md:527 msgid "" -"**Open in Colab button** " -"([#1389](https://github.com/adap/flower/pull/1389))" -msgstr "**在 Colab 中打开按钮** ([#1389](https://github.com/adap/flower/pull/1389))" +"**Open in Colab button** ([#1389](https://github.com/adap/flower/pull/1389))" +msgstr "" +"**在 Colab 中打开按钮** ([#1389](https://github.com/adap/flower/pull/1389))" #: ../../source/ref-changelog.md:529 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a " -"new `Open in Colab` button. No need to install anything on your local " -"machine, you can now use and learn about Flower in your browser, it's " -"only a single click away." +"The four parts of the Flower Federated Learning Tutorial now come with a new " +"`Open in Colab` button. No need to install anything on your local machine, " +"you can now use and learn about Flower in your browser, it's only a single " +"click away." msgstr "" -"Flower 联邦学习教程的四个部分现在都带有一个新的 \"在 Colab 中打开 " -"\"按钮。现在,您无需在本地计算机上安装任何软件,只需点击一下,就可以在浏览器中使用和学习 Flower。" +"Flower 联邦学习教程的四个部分现在都带有一个新的 \"在 Colab 中打开 \"按钮。现" +"在,您无需在本地计算机上安装任何软件,只需点击一下,就可以在浏览器中使用和学" +"习 Flower。" #: ../../source/ref-changelog.md:531 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), [#1472](https://github." +"com/adap/flower/pull/1472), [#1473](https://github.com/adap/flower/" +"pull/1473), [#1474](https://github.com/adap/flower/pull/1474), [#1475]" +"(https://github.com/adap/flower/pull/1475))" msgstr "" -"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " -"[#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475)))" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), [#1470]" +"(https://github.com/adap/flower/pull/1470), [#1472](https://github.com/adap/" +"flower/pull/1472), [#1473](https://github.com/adap/flower/pull/1473), [#1474]" +"(https://github.com/adap/flower/pull/1474), [#1475](https://github.com/adap/" +"flower/pull/1475)))" #: ../../source/ref-changelog.md:533 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved " -"(many small changes and fixes)." +"`NumPyClient`. The existing parts one and two have also been improved (many " +"small changes and fixes)." msgstr "" -"Flower 联邦学习教程有两个全新的部分,涉及自定义策略(仍处于 WIP 阶段)和 `Client` 与 `NumPyClient` " -"之间的区别。现有的第一和第二部分也得到了改进(许多小改动和修正)。" +"Flower 联邦学习教程有两个全新的部分,涉及自定义策略(仍处于 WIP 阶段)和 " +"`Client` 与 `NumPyClient` 之间的区别。现有的第一和第二部分也得到了改进(许多" +"小改动和修正)。" #: ../../source/ref-changelog.md:539 msgid "v1.0.0 (2022-07-28)" @@ -17487,141 +17573,120 @@ msgstr "可配置的`get_parameters`" #: ../../source/ref-changelog.md:546 msgid "" -"Tons of small API cleanups resulting in a more coherent developer " -"experience" +"Tons of small API cleanups resulting in a more coherent developer experience" msgstr "对大量小型应用程序接口进行了清理,使开发人员的体验更加一致" #: ../../source/ref-changelog.md:550 msgid "" "We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +"made Flower 1.0 possible (in reverse [GitHub Contributors](https://github." +"com/adap/flower/graphs/contributors) order):" msgstr "" -"在此,我们谨向所有促成 Flower 1.0 的贡献者致以**特别的谢意(按[GitHub " -"贡献者](https://github.com/adap/flower/graphs/contributors) 倒序排列):" +"在此,我们谨向所有促成 Flower 1.0 的贡献者致以**特别的谢意(按[GitHub 贡献者]" +"(https://github.com/adap/flower/graphs/contributors) 倒序排列):" #: ../../source/ref-changelog.md:552 msgid "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." -msgstr "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." +"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" +"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" +"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" +"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." +"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" +"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." +"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." +"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" +"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" +"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" +"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" +"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" +"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." +"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" +"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" +"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" +"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" +"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" +"tanertopal), [@danieljanes](https://github.com/danieljanes)." +msgstr "" +"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" +"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" +"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" +"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." +"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" +"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." +"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." +"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" +"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" +"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" +"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" +"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" +"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." +"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" +"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" +"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" +"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" +"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" +"tanertopal), [@danieljanes](https://github.com/danieljanes)." #: ../../source/ref-changelog.md:556 msgid "" -"**All arguments must be passed as keyword arguments** " -"([#1338](https://github.com/adap/flower/pull/1338))" -msgstr "** 所有参数必须作为关键字参数传递** ([#1338](https://github.com/adap/flower/pull/1338))" +"**All arguments must be passed as keyword arguments** ([#1338](https://" +"github.com/adap/flower/pull/1338))" +msgstr "" +"** 所有参数必须作为关键字参数传递** ([#1338](https://github.com/adap/flower/" +"pull/1338))" #: ../../source/ref-changelog.md:558 msgid "" -"Pass all arguments as keyword arguments, positional arguments are not " -"longer supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " -"for each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"Pass all arguments as keyword arguments, positional arguments are not longer " +"supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword for " +"each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())`)." msgstr "" -"以关键字参数传递所有参数,不再支持位置参数。使用位置参数的代码(例如,`start_client(\"127.0.0.1:8080\", " -"FlowerClient())`)必须为每个位置参数添加关键字(例如,`start_client(server_address=\"127.0.0.1:8080\"," -" client=FlowerClient())`)。" +"以关键字参数传递所有参数,不再支持位置参数。使用位置参数的代码(例如," +"`start_client(\"127.0.0.1:8080\", FlowerClient())`)必须为每个位置参数添加关" +"键字(例如,`start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)。" #: ../../source/ref-changelog.md:560 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" +"**and** `start_simulation` ([#1317](https://github.com/adap/flower/" +"pull/1317))" msgstr "" "**在*** `start_server` ***和*** `start_simulation` 中引入配置对象*** " "`ServerConfig` ([#1317](https://github.com/adap/flower/pull/1317))" #: ../../source/ref-changelog.md:562 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " -"600.0}`, `start_server` and `start_simulation` now expect a configuration" -" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" -" arguments that as the previous config dict, but it makes writing type-" -"safe code easier and the default parameters values more transparent." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": 600.0}" +"`, `start_server` and `start_simulation` now expect a configuration object " +"of type `flwr.server.ServerConfig`. `ServerConfig` takes the same arguments " +"that as the previous config dict, but it makes writing type-safe code easier " +"and the default parameters values more transparent." msgstr "" -"并非配置字典`{\"num_rounds\": 3, \"round_timeout\": 600.0}`, `start_server`和 " -"`start_simulation`现在用一个类型为 " -"`flwr.server.ServerConfig`的配置对象。`ServerConfig`接收的参数与之前的 config dict " -"相同,但它使编写类型安全代码变得更容易,默认参数值也更加透明。" +"并非配置字典`{\"num_rounds\": 3, \"round_timeout\": 600.0}`, `start_server`" +"和 `start_simulation`现在用一个类型为 `flwr.server.ServerConfig`的配置对象。" +"`ServerConfig`接收的参数与之前的 config dict 相同,但它使编写类型安全代码变得" +"更容易,默认参数值也更加透明。" #: ../../source/ref-changelog.md:564 msgid "" -"**Rename built-in strategy parameters for clarity** " -"([#1334](https://github.com/adap/flower/pull/1334))" -msgstr "**重新命名内置策略参数,使其更加清晰** ([#1334](https://github.com/adap/flower/pull/1334))" +"**Rename built-in strategy parameters for clarity** ([#1334](https://github." +"com/adap/flower/pull/1334))" +msgstr "" +"**重新命名内置策略参数,使其更加清晰** ([#1334](https://github.com/adap/" +"flower/pull/1334))" #: ../../source/ref-changelog.md:566 msgid "" @@ -17643,20 +17708,23 @@ msgstr "`eval_fn` --> `evaluate_fn`" #: ../../source/ref-changelog.md:572 msgid "" -"**Update default arguments of built-in strategies** " -"([#1278](https://github.com/adap/flower/pull/1278))" -msgstr "**更新内置策略的默认参数** ([#1278](https://github.com/adap/flower/pull/1278))" +"**Update default arguments of built-in strategies** ([#1278](https://github." +"com/adap/flower/pull/1278))" +msgstr "" +"**更新内置策略的默认参数** ([#1278](https://github.com/adap/flower/" +"pull/1278))" #: ../../source/ref-changelog.md:574 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently " -"available clients for training and evaluation. Projects that relied on " -"the previous default values can get the previous behaviour by " -"initializing the strategy in the following way:" +"`fraction_evaluate=1.0`, which means they select *all* currently available " +"clients for training and evaluation. Projects that relied on the previous " +"default values can get the previous behaviour by initializing the strategy " +"in the following way:" msgstr "" -"所有内置策略现在都使用 \"fraction_fit=1.0 \"和 " -"\"fraction_evaluate=1.0\",这意味着它们会选择*所有*当前可用的客户端进行训练和评估。依赖以前默认值的项目可以通过以下方式初始化策略,获得以前的行为:" +"所有内置策略现在都使用 \"fraction_fit=1.0 \"和 \"fraction_evaluate=1.0\",这" +"意味着它们会选择*所有*当前可用的客户端进行训练和评估。依赖以前默认值的项目可" +"以通过以下方式初始化策略,获得以前的行为:" #: ../../source/ref-changelog.md:576 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" @@ -17664,17 +17732,18 @@ msgstr "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" #: ../../source/ref-changelog.md:578 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Add** `server_round` **to** `Strategy.evaluate` ([#1334](https://github." +"com/adap/flower/pull/1334))" msgstr "" -"**添加*** `server_round` ***到*** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**添加*** `server_round` ***到*** `Strategy.evaluate` ([#1334](https://" +"github.com/adap/flower/pull/1334))" #: ../../source/ref-changelog.md:580 msgid "" -"The `Strategy` method `evaluate` now receives the current round of " -"federated learning/evaluation as the first parameter." -msgstr "`Strategy`的`evaluate` 方法现在会接收当前一轮联邦学习/评估作为第一个参数。" +"The `Strategy` method `evaluate` now receives the current round of federated " +"learning/evaluation as the first parameter." +msgstr "" +"`Strategy`的`evaluate` 方法现在会接收当前一轮联邦学习/评估作为第一个参数。" #: ../../source/ref-changelog.md:582 msgid "" @@ -17688,48 +17757,51 @@ msgstr "" msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), " -"and (3) a config dictionary (`config`)." +"(`server_round`), (2) the model parameters to evaluate (`parameters`), and " +"(3) a config dictionary (`config`)." msgstr "" -"传递给内置策略(如 `FedAvg`)的 `evaluate_fn` 现在需要三个参数:(1) 当前一轮联邦学习/评估 " -"(`server_round`),(2) 要评估的模型参数 (`parameters`),(3) 配置字典 (`config`)。" +"传递给内置策略(如 `FedAvg`)的 `evaluate_fn` 现在需要三个参数:(1) 当前一轮" +"联邦学习/评估 (`server_round`),(2) 要评估的模型参数 (`parameters`),(3) 配置" +"字典 (`config`)。" #: ../../source/ref-changelog.md:586 msgid "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**Rename** `rnd` **to** `server_round` ([#1321](https://github.com/adap/" +"flower/pull/1321))" msgstr "" -"**重新命名** `rnd` ** to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**重新命名** `rnd` ** to** `server_round` ([#1321](https://github.com/adap/" +"flower/pull/1321))" #: ../../source/ref-changelog.md:588 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. " -"To improve reaability and avoid confusion with *random*, this parameter " -"has been renamed from `rnd` to `server_round`." +"current round of federated learning/evaluation as their first parameter. To " +"improve reaability and avoid confusion with *random*, this parameter has " +"been renamed from `rnd` to `server_round`." msgstr "" -"几个 Flower " -"方法和函数(`evaluate_fn`、`configure_fit`、`aggregate_fit`、`configure_evaluate`、`aggregate_evaluate`)的第一个参数是当前一轮的联邦学习/评估。为提高可重复性并避免与" -" *random* 混淆,该参数已从 `rnd` 更名为 `server_round`。" +"几个 Flower 方法和函数(`evaluate_fn`、`configure_fit`、`aggregate_fit`、" +"`configure_evaluate`、`aggregate_evaluate`)的第一个参数是当前一轮的联邦学习/" +"评估。为提高可重复性并避免与 *random* 混淆,该参数已从 `rnd` 更名为 " +"`server_round`。" #: ../../source/ref-changelog.md:590 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"**Move** `flwr.dataset` **to** `flwr_baselines` ([#1273](https://github.com/" +"adap/flower/pull/1273))" msgstr "" -"**移动*** `flwr.dataset` **到*** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"**移动*** `flwr.dataset` **到*** `flwr_baselines` ([#1273](https://github." +"com/adap/flower/pull/1273))" #: ../../source/ref-changelog.md:592 -msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." +msgid "" +"The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "实验软件包 `flwr.dataset` 已迁移至 Flower Baselines。" #: ../../source/ref-changelog.md:594 msgid "" -"**Remove experimental strategies** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Remove experimental strategies** ([#1280](https://github.com/adap/flower/" +"pull/1280))" msgstr "**删除实验策略** ([#1280](https://github.com/adap/flower/pull/1280))" #: ../../source/ref-changelog.md:596 @@ -17740,45 +17812,45 @@ msgstr "移除未维护的试验性策略(`FastAndSlow`、`FedFSv0`、`FedFSv1 #: ../../source/ref-changelog.md:598 msgid "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Rename** `Weights` **to** `NDArrays` ([#1258](https://github.com/adap/" +"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"**重新命名** `Weights` **到** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**重新命名** `Weights` **到** `NDArrays` ([#1258](https://github.com/adap/" +"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" #: ../../source/ref-changelog.md:600 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." -msgstr "flwr.common.Weights \"更名为 \"flwr.common.NDArrays\",以更好地反映该类型的含义。" +msgstr "" +"flwr.common.Weights \"更名为 \"flwr.common.NDArrays\",以更好地反映该类型的含" +"义。" #: ../../source/ref-changelog.md:602 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Remove antiquated** `force_final_distributed_eval` **from** `start_server` " +"([#1258](https://github.com/adap/flower/pull/1258), [#1259](https://github." +"com/adap/flower/pull/1259))" msgstr "" -"**从** `start_server` 中移除过时的** `force_final_distributed_eval` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**从** `start_server` 中移除过时的** `force_final_distributed_eval` ([#1258]" +"(https://github.com/adap/flower/pull/1258), [#1259](https://github.com/adap/" +"flower/pull/1259))" #: ../../source/ref-changelog.md:604 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been" -" a historic artefact, in this release it is finally gone for good." +"The `start_server` parameter `force_final_distributed_eval` has long been a " +"historic artefact, in this release it is finally gone for good." msgstr "" -"start_server \"参数 \"force_final_distributed_eval " -"\"长期以来一直是个历史遗留问题,在此版本中终于永远消失了。" +"start_server \"参数 \"force_final_distributed_eval \"长期以来一直是个历史遗留" +"问题,在此版本中终于永远消失了。" #: ../../source/ref-changelog.md:606 msgid "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Make** `get_parameters` **configurable** ([#1242](https://github.com/adap/" +"flower/pull/1242))" msgstr "" -"**使** `get_parameters` **可配置** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**使** `get_parameters` **可配置** ([#1242](https://github.com/adap/flower/" +"pull/1242))" #: ../../source/ref-changelog.md:608 msgid "" @@ -17799,79 +17871,82 @@ msgstr "" #: ../../source/ref-changelog.md:612 msgid "" "The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the " -"consistency between `start_simulation` and `start_server` and makes " -"transitioning between the two easier." +"`config` instead of the `num_rounds` integer. This improves the consistency " +"between `start_simulation` and `start_server` and makes transitioning " +"between the two easier." msgstr "" -"现在,`start_simulation`(开始模拟)` 函数接受配置字典 `config` 而不是 `num_rounds` 整数。这改进了 " -"`start_simulation` 和 `start_server` 之间的一致性,并使两者之间的转换更容易。" +"现在,`start_simulation`(开始模拟)` 函数接受配置字典 `config` 而不是 " +"`num_rounds` 整数。这改进了 `start_simulation` 和 `start_server` 之间的一致" +"性,并使两者之间的转换更容易。" #: ../../source/ref-changelog.md:616 msgid "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" -msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" +msgstr "" +"** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" #: ../../source/ref-changelog.md:618 msgid "" -"The previous Flower release introduced experimental support for Python " -"3.10, this release declares Python 3.10 support as stable." -msgstr "上一个 Flower 版本引入了对 Python 3.10 的实验支持,而本版本则宣布对 Python 3.10 的支持为稳定支持。" +"The previous Flower release introduced experimental support for Python 3.10, " +"this release declares Python 3.10 support as stable." +msgstr "" +"上一个 Flower 版本引入了对 Python 3.10 的实验支持,而本版本则宣布对 Python " +"3.10 的支持为稳定支持。" #: ../../source/ref-changelog.md:620 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** ([#1260]" +"(https://github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/" +"flower/pull/1277))" msgstr "" -"**使所有** `Client` **和** `NumPyClient` **方法成为可选** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**使所有** `Client` **和** `NumPyClient` **方法成为可选** ([#1260](https://" +"github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/flower/" +"pull/1277))" #: ../../source/ref-changelog.md:622 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that" -" implement, for example, only `fit`, but no other method. No need to " +"`fit`, and `evaluate` are all optional. This enables writing clients that " +"implement, for example, only `fit`, but no other method. No need to " "implement `evaluate` when using centralized evaluation!" msgstr "" "`Client`/`NumPyClient`的 \"get_properties\"、\"get_parameters\"、\"fit \"和 " -"\"evaluate \"方法都是可选的。这样就可以编写只实现 `fit` 而不实现其他方法的客户端。使用集中评估时,无需实现 " -"`evaluate`!" +"\"evaluate \"方法都是可选的。这样就可以编写只实现 `fit` 而不实现其他方法的客" +"户端。使用集中评估时,无需实现 `evaluate`!" #: ../../source/ref-changelog.md:624 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**Enable passing a** `Server` **instance to** `start_simulation` ([#1281]" +"(https://github.com/adap/flower/pull/1281))" msgstr "" -"**启用向** `start_simulation` 传递** `Server` 实例 " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**启用向** `start_simulation` 传递** `Server` 实例 ([#1281](https://github." +"com/adap/flower/pull/1281))" #: ../../source/ref-changelog.md:626 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server`" -" instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the" -" Virtual Client Engine." +"Similar to `start_server`, `start_simulation` now accepts a full `Server` " +"instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the " +"Virtual Client Engine." msgstr "" -"与 `start_server` 类似,`start_simulation` 现在也接受一个完整的 `Server` " -"实例。这使得用户可以对实验的执行进行大量自定义,并为使用虚拟客户端引擎运行异步 FL 等打开了大门。" +"与 `start_server` 类似,`start_simulation` 现在也接受一个完整的 `Server` 实" +"例。这使得用户可以对实验的执行进行大量自定义,并为使用虚拟客户端引擎运行异步 " +"FL 等打开了大门。" #: ../../source/ref-changelog.md:628 msgid "" -"**Update code examples** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**Update code examples** ([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), [#1282](https://github." +"com/adap/flower/pull/1282))" msgstr "" -"**更新代码示例** ([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**更新代码示例** ([#1291](https://github.com/adap/flower/pull/1291), [#1286]" +"(https://github.com/adap/flower/pull/1286), [#1282](https://github.com/adap/" +"flower/pull/1282))" #: ../../source/ref-changelog.md:630 msgid "" -"Many code examples received small or even large maintenance updates, " -"among them are" +"Many code examples received small or even large maintenance updates, among " +"them are" msgstr "许多代码示例都进行了小规模甚至大规模的维护更新,其中包括" #: ../../source/ref-changelog.md:632 @@ -17900,9 +17975,10 @@ msgstr "`advanced_tensorflow`" #: ../../source/ref-changelog.md:639 msgid "" -"**Remove the obsolete simulation example** " -"([#1328](https://github.com/adap/flower/pull/1328))" -msgstr "**删除过时的模拟示例** ([#1328](https://github.com/adap/flower/pull/1328))" +"**Remove the obsolete simulation example** ([#1328](https://github.com/adap/" +"flower/pull/1328))" +msgstr "" +"**删除过时的模拟示例** ([#1328](https://github.com/adap/flower/pull/1328))" #: ../../source/ref-changelog.md:641 msgid "" @@ -17915,41 +17991,36 @@ msgstr "" #: ../../source/ref-changelog.md:643 msgid "" -"**Update documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" -msgstr "" -"**更新文档** ([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"**Update documentation** ([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), [#1251](https://github." +"com/adap/flower/pull/1251), [#1257](https://github.com/adap/flower/" +"pull/1257), [#1267](https://github.com/adap/flower/pull/1267), [#1268]" +"(https://github.com/adap/flower/pull/1268), [#1300](https://github.com/adap/" +"flower/pull/1300), [#1304](https://github.com/adap/flower/pull/1304), [#1305]" +"(https://github.com/adap/flower/pull/1305), [#1307](https://github.com/adap/" +"flower/pull/1307))" +msgstr "" +"**更新文档** ([#1223](https://github.com/adap/flower/pull/1223), [#1209]" +"(https://github.com/adap/flower/pull/1209), [#1251](https://github.com/adap/" +"flower/pull/1251), [#1257](https://github.com/adap/flower/pull/1257), [#1267]" +"(https://github.com/adap/flower/pull/1267), [#1268](https://github.com/adap/" +"flower/pull/1268), [#1300](https://github.com/adap/flower/pull/1300), [#1304]" +"(https://github.com/adap/flower/pull/1304), [#1305](https://github.com/adap/" +"flower/pull/1305), [#1307](https://github.com/adap/flower/pull/1307))" #: ../../source/ref-changelog.md:645 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the " -"`flwr.common` module in the API reference, includes support for markdown-" -"based documentation, migrates the changelog from `.rst` to `.md`, and " -"fixes a number of smaller details!" +"deprecated library, updates documentation dependencies, includes the `flwr." +"common` module in the API reference, includes support for markdown-based " +"documentation, migrates the changelog from `.rst` to `.md`, and fixes a " +"number of smaller details!" msgstr "" -"其中一个实质性的文档更新修复了多个较小的渲染问题,使标题更加简洁以改善导航,删除了一个已废弃的库,更新了文档依赖关系,在 API 参考中包含了 " -"`flwr.common` 模块,包含了对基于 markdown 的文档的支持,将更新日志从 `.rst` 移植到了 " -"`.md`,并修复了一些较小的细节!" +"其中一个实质性的文档更新修复了多个较小的渲染问题,使标题更加简洁以改善导航," +"删除了一个已废弃的库,更新了文档依赖关系,在 API 参考中包含了 `flwr.common` " +"模块,包含了对基于 markdown 的文档的支持,将更新日志从 `.rst` 移植到了 `." +"md`,并修复了一些较小的细节!" #: ../../source/ref-changelog.md:647 ../../source/ref-changelog.md:702 #: ../../source/ref-changelog.md:771 ../../source/ref-changelog.md:810 @@ -17958,41 +18029,40 @@ msgstr "**小规模更新**" #: ../../source/ref-changelog.md:649 msgid "" -"Add round number to fit and evaluate log messages " -"([#1266](https://github.com/adap/flower/pull/1266))" -msgstr "添加四舍五入数字,以适应和评估日志信息([#1266](https://github.com/adap/flower/pull/1266))" +"Add round number to fit and evaluate log messages ([#1266](https://github." +"com/adap/flower/pull/1266))" +msgstr "" +"添加四舍五入数字,以适应和评估日志信息([#1266](https://github.com/adap/" +"flower/pull/1266))" #: ../../source/ref-changelog.md:650 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example " -"([#847](https://github.com/adap/flower/pull/847))" +"Add secure gRPC connection to the `advanced_tensorflow` code example ([#847]" +"(https://github.com/adap/flower/pull/847))" msgstr "" -"为 `advanced_tensorflow` 代码示例添加安全 gRPC 连接 " -"([#847](https://github.com/adap/flower/pull/847))" +"为 `advanced_tensorflow` 代码示例添加安全 gRPC 连接 ([#847](https://github." +"com/adap/flower/pull/847))" #: ../../source/ref-changelog.md:651 msgid "" -"Update developer tooling " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"Update developer tooling ([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), [#1301](https://github." +"com/adap/flower/pull/1301), [#1310](https://github.com/adap/flower/" +"pull/1310))" msgstr "" -"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310)" +"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), [#1276]" +"(https://github.com/adap/flower/pull/1276), [#1301](https://github.com/adap/" +"flower/pull/1301), [#1310](https://github.com/adap/flower/pull/1310)" #: ../../source/ref-changelog.md:652 msgid "" -"Rename ProtoBuf messages to improve consistency " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " +"Rename ProtoBuf messages to improve consistency ([#1214](https://github.com/" +"adap/flower/pull/1214), [#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"重命名 ProtoBuf 消息以提高一致性([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259)" +"重命名 ProtoBuf 消息以提高一致性([#1214](https://github.com/adap/flower/" +"pull/1214), [#1258](https://github.com/adap/flower/pull/1258), [#1259]" +"(https://github.com/adap/flower/pull/1259)" #: ../../source/ref-changelog.md:654 msgid "v0.19.0 (2022-05-18)" @@ -18000,158 +18070,162 @@ msgstr "v0.19.0 (2022-05-18)" #: ../../source/ref-changelog.md:658 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** ([#919](https://" +"github.com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" +"pull/1127), [#914](https://github.com/adap/flower/pull/914))" msgstr "" -"**Flower Baselines(预览): FedOpt、FedBN、FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines(预览): FedOpt、FedBN、FedAvgM** ([#919](https://github." +"com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" +"pull/1127), [#914](https://github.com/adap/flower/pull/914))" #: ../../source/ref-changelog.md:660 #, fuzzy msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " -"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " -"With this first preview release we're also inviting the community to " -"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" -"contribute-baselines.html)." -msgstr "" -"Flower Baselines 的第一个预览版已经发布!我们通过实现 " -"FedOpt(FedYogi、FedAdam、FedAdagrad)、FedBN 和 FedAvgM 来启动 Flower " -"Baselines。请查阅文档了解如何使用 [Flower Baselines](https://flower.ai/docs/using-" -"baselines.html)。在首次发布预览版时,我们还邀请社区成员[贡献自己的Baselines](https://flower.ai/docs" -"/contributing-baselines.html)。" +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how to " +"use [Flower Baselines](https://flower.ai/docs/using-baselines.html). With " +"this first preview release we're also inviting the community to [contribute " +"their own baselines](https://flower.ai/docs/baselines/how-to-contribute-" +"baselines.html)." +msgstr "" +"Flower Baselines 的第一个预览版已经发布!我们通过实现 FedOpt(FedYogi、" +"FedAdam、FedAdagrad)、FedBN 和 FedAvgM 来启动 Flower Baselines。请查阅文档了" +"解如何使用 [Flower Baselines](https://flower.ai/docs/using-baselines.html)。" +"在首次发布预览版时,我们还邀请社区成员[贡献自己的Baselines](https://flower." +"ai/docs/contributing-baselines.html)。" #: ../../source/ref-changelog.md:662 msgid "" -"**C++ client SDK (preview) and code example** " -"([#1111](https://github.com/adap/flower/pull/1111))" -msgstr "**C++客户端SDK(预览版)和代码示例**([#1111](https://github.com/adap/flower/pull/1111))" +"**C++ client SDK (preview) and code example** ([#1111](https://github.com/" +"adap/flower/pull/1111))" +msgstr "" +"**C++客户端SDK(预览版)和代码示例**([#1111](https://github.com/adap/flower/" +"pull/1111))" #: ../../source/ref-changelog.md:664 msgid "" -"Preview support for Flower clients written in C++. The C++ preview " -"includes a Flower client SDK and a quickstart code example that " -"demonstrates a simple C++ client using the SDK." +"Preview support for Flower clients written in C++. The C++ preview includes " +"a Flower client SDK and a quickstart code example that demonstrates a simple " +"C++ client using the SDK." msgstr "" -"预览版支持用 C++ 编写的 Flower 客户端。C++ 预览版包括一个 Flower 客户端 SDK 和一个快速入门代码示例,使用 SDK " -"演示了一个简单的 C++ 客户端。" +"预览版支持用 C++ 编写的 Flower 客户端。C++ 预览版包括一个 Flower 客户端 SDK " +"和一个快速入门代码示例,使用 SDK 演示了一个简单的 C++ 客户端。" #: ../../source/ref-changelog.md:666 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"**Add experimental support for Python 3.10 and Python 3.11** ([#1135]" +"(https://github.com/adap/flower/pull/1135))" msgstr "" -"** 增加对 Python 3.10 和 Python 3.11 的实验支持** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"** 增加对 Python 3.10 和 Python 3.11 的实验支持** ([#1135](https://github." +"com/adap/flower/pull/1135))" #: ../../source/ref-changelog.md:668 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due" -" to be released in October. This Flower release adds experimental support" -" for both Python versions." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due to " +"be released in October. This Flower release adds experimental support for " +"both Python versions." msgstr "" -"Python 3.10 是 Python 的最新稳定版本,Python 3.11 将于 10 月份发布。Flower 版本增加了对这两个 " -"Python 版本的实验支持。" +"Python 3.10 是 Python 的最新稳定版本,Python 3.11 将于 10 月份发布。Flower 版" +"本增加了对这两个 Python 版本的实验支持。" #: ../../source/ref-changelog.md:670 msgid "" -"**Aggregate custom metrics through user-provided functions** " -"([#1144](https://github.com/adap/flower/pull/1144))" -msgstr "**通过用户提供的函数聚合自定义指标**([#1144](https://github.com/adap/flower/pull/1144))" +"**Aggregate custom metrics through user-provided functions** ([#1144]" +"(https://github.com/adap/flower/pull/1144))" +msgstr "" +"**通过用户提供的函数聚合自定义指标**([#1144](https://github.com/adap/flower/" +"pull/1144))" #: ../../source/ref-changelog.md:672 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" -" customize the strategy. Built-in strategies support two new arguments, " +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to " +"customize the strategy. Built-in strategies support two new arguments, " "`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " "allow passing custom metric aggregation functions." msgstr "" -"现在无需定制策略即可聚合自定义度量(如`准确度`)。内置策略支持两个新参数:`fit_metrics_aggregation_fn` " -"和`evaluate_metrics_aggregation_fn`,允许传递自定义度量聚合函数。" +"现在无需定制策略即可聚合自定义度量(如`准确度`)。内置策略支持两个新参数:" +"`fit_metrics_aggregation_fn` 和`evaluate_metrics_aggregation_fn`,允许传递自" +"定义度量聚合函数。" #: ../../source/ref-changelog.md:674 msgid "" -"**User-configurable round timeout** " -"([#1162](https://github.com/adap/flower/pull/1162))" -msgstr "**用户可配置的回合超时**([#1162](https://github.com/adap/flower/pull/1162))" +"**User-configurable round timeout** ([#1162](https://github.com/adap/flower/" +"pull/1162))" +msgstr "" +"**用户可配置的回合超时**([#1162](https://github.com/adap/flower/pull/1162))" #: ../../source/ref-changelog.md:676 msgid "" "A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary " -"contains a `round_timeout` key (with a `float` value in seconds), the " -"server will wait *at least* `round_timeout` seconds before it closes the " -"connection." +"`start_server` and `start_simulation`. If the `config` dictionary contains a " +"`round_timeout` key (with a `float` value in seconds), the server will wait " +"*at least* `round_timeout` seconds before it closes the connection." msgstr "" -"新的配置值允许为 `start_server` 和 `start_simulation` 设置回合超时。如果 `config` 字典中包含一个 " -"`round_timeout` 键(以秒为单位的 `float`值),服务器将至少等待 ** `round_timeout` 秒后才关闭连接。" +"新的配置值允许为 `start_server` 和 `start_simulation` 设置回合超时。如果 " +"`config` 字典中包含一个 `round_timeout` 键(以秒为单位的 `float`值),服务器" +"将至少等待 ** `round_timeout` 秒后才关闭连接。" #: ../../source/ref-changelog.md:678 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used " -"at the same time in all built-in strategies** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"**Enable both federated evaluation and centralized evaluation to be used at " +"the same time in all built-in strategies** ([#1091](https://github.com/adap/" +"flower/pull/1091))" msgstr "" -"**允许在所有内置策略中同时使用联邦评价和集中评估** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"**允许在所有内置策略中同时使用联邦评价和集中评估** ([#1091](https://github." +"com/adap/flower/pull/1091))" #: ../../source/ref-changelog.md:680 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., " -"client-side) and centralized evaluation (i.e., server-side) in the same " -"round. Federated evaluation can be disabled by setting `fraction_eval` to" -" `0.0`." +"Built-in strategies can now perform both federated evaluation (i.e., client-" +"side) and centralized evaluation (i.e., server-side) in the same round. " +"Federated evaluation can be disabled by setting `fraction_eval` to `0.0`." msgstr "" -"内置策略现在可以在同一轮中同时执行联邦评估(即客户端)和集中评估(即服务器端)。可以通过将 `fraction_eval` 设置为 " -"`0.0`来禁用联邦评估。" +"内置策略现在可以在同一轮中同时执行联邦评估(即客户端)和集中评估(即服务器" +"端)。可以通过将 `fraction_eval` 设置为 `0.0`来禁用联邦评估。" #: ../../source/ref-changelog.md:682 msgid "" -"**Two new Jupyter Notebook tutorials** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"**Two new Jupyter Notebook tutorials** ([#1141](https://github.com/adap/" +"flower/pull/1141))" msgstr "" -"**两本新的 Jupyter Notebook 教程** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"**两本新的 Jupyter Notebook 教程** ([#1141](https://github.com/adap/flower/" +"pull/1141))" #: ../../source/ref-changelog.md:684 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " -"basic and intermediate Flower features:" -msgstr "两本 Jupyter Notebook 教程(与 Google Colab 兼容)介绍了 Flower 的基本和中级功能:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain basic " +"and intermediate Flower features:" +msgstr "" +"两本 Jupyter Notebook 教程(与 Google Colab 兼容)介绍了 Flower 的基本和中级" +"功能:" #: ../../source/ref-changelog.md:686 msgid "" -"*An Introduction to Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"*An Introduction to Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-1-Intro-to-" +"FL-PyTorch.ipynb)" msgstr "" -"*联邦学习简介*: [在 Colab " -"中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"*联邦学习简介*: [在 Colab 中打开](https://colab.research.google.com/github/" +"adap/flower/blob/main/tutorials/Flower-1-Intro-to-FL-PyTorch.ipynb)" #: ../../source/ref-changelog.md:688 msgid "" -"*Using Strategies in Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"*Using Strategies in Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-2-" +"Strategies-in-FL-PyTorch.ipynb)" msgstr "" -"*在联邦学习中使用策略*: [在 Colab " -"中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"*在联邦学习中使用策略*: [在 Colab 中打开](https://colab.research.google.com/" +"github/adap/flower/blob/main/tutorials/Flower-2-Strategies-in-FL-PyTorch." +"ipynb)" #: ../../source/ref-changelog.md:690 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** ([#1076]" +"(https://github.com/adap/flower/pull/1076))" msgstr "" -"**新的 FedAvgM 策略(带服务器动量的联邦平均)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"**新的 FedAvgM 策略(带服务器动量的联邦平均)** ([#1076](https://github.com/" +"adap/flower/pull/1076))" #: ../../source/ref-changelog.md:692 msgid "" @@ -18161,9 +18235,11 @@ msgstr "新的 \"FedAvgM \"策略实现了带服务器动量的联邦平均[Hsu #: ../../source/ref-changelog.md:694 msgid "" -"**New advanced PyTorch code example** " -"([#1007](https://github.com/adap/flower/pull/1007))" -msgstr "**新的 PyTorch 高级代码示例** ([#1007](https://github.com/adap/flower/pull/1007))" +"**New advanced PyTorch code example** ([#1007](https://github.com/adap/" +"flower/pull/1007))" +msgstr "" +"**新的 PyTorch 高级代码示例** ([#1007](https://github.com/adap/flower/" +"pull/1007))" #: ../../source/ref-changelog.md:696 msgid "" @@ -18173,8 +18249,7 @@ msgstr "新代码示例 (`advanced_pytorch`) 演示了 PyTorch 的高级 Flower #: ../../source/ref-changelog.md:698 msgid "" -"**New JAX code example** " -"([#906](https://github.com/adap/flower/pull/906), " +"**New JAX code example** ([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" "**新的 JAX 代码示例**([#906](https://github.com/adap/flower/pull/906), " @@ -18184,107 +18259,114 @@ msgstr "" msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." -msgstr "新代码示例(`jax_from_centralized_to_federated`)展示了使用 JAX 和 Flower 的联邦学习。" +msgstr "" +"新代码示例(`jax_from_centralized_to_federated`)展示了使用 JAX 和 Flower 的" +"联邦学习。" #: ../../source/ref-changelog.md:704 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -"新增选项,用于在 \"start_simulation\"(开始模拟)中已初始化 Ray 的情况下保持 Ray " -"运行([#1177](https://github.com/adap/flower/pull/1177))" +"新增选项,用于在 \"start_simulation\"(开始模拟)中已初始化 Ray 的情况下保持 " +"Ray 运行([#1177](https://github.com/adap/flower/pull/1177))" #: ../../source/ref-changelog.md:705 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -"添加对自定义 \"客户端管理器 \"作为 \"start_simulation " -"\"参数的支持([#1171](https://github.com/adap/flower/pull/1171))" +"添加对自定义 \"客户端管理器 \"作为 \"start_simulation \"参数的支持([#1171]" +"(https://github.com/adap/flower/pull/1171))" #: ../../source/ref-changelog.md:706 msgid "" -"New documentation for [implementing " -"strategies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"New documentation for [implementing strategies](https://flower.ai/docs/" +"framework/how-to-implement-strategies.html) ([#1097](https://github.com/adap/" +"flower/pull/1097), [#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -"[实施战略](https://flower.ai/docs/framework/how-to-implement-strategies.html)" -" 的新文件([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175)" +"[实施战略](https://flower.ai/docs/framework/how-to-implement-strategies." +"html) 的新文件([#1097](https://github.com/adap/flower/pull/1097), [#1175]" +"(https://github.com/adap/flower/pull/1175)" #: ../../source/ref-changelog.md:707 msgid "" -"New mobile-friendly documentation theme " -"([#1174](https://github.com/adap/flower/pull/1174))" -msgstr "新的移动友好型文档主题 ([#1174](https://github.com/adap/flower/pull/1174))" +"New mobile-friendly documentation theme ([#1174](https://github.com/adap/" +"flower/pull/1174))" +msgstr "" +"新的移动友好型文档主题 ([#1174](https://github.com/adap/flower/pull/1174))" #: ../../source/ref-changelog.md:708 msgid "" "Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"compatible releases (`>=1.9.2,<1.12.0`) ([#1205](https://github.com/adap/" +"flower/pull/1205))" msgstr "" "限制(可选)`ray`依赖的版本范围,使其仅包含兼容版本(`>=1.9.2,<1.12.0`) " "([#1205](https://github.com/adap/flower/pull/1205))" #: ../../source/ref-changelog.md:712 msgid "" -"**Remove deprecated support for Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" -msgstr "**删除对 Python 3.6 的过时支持** ([#871](https://github.com/adap/flower/pull/871))" +"**Remove deprecated support for Python 3.6** ([#871](https://github.com/adap/" +"flower/pull/871))" +msgstr "" +"**删除对 Python 3.6 的过时支持** ([#871](https://github.com/adap/flower/" +"pull/871))" #: ../../source/ref-changelog.md:713 msgid "" -"**Remove deprecated KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" -msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" +"**Remove deprecated KerasClient** ([#857](https://github.com/adap/flower/" +"pull/857))" +msgstr "" +"**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" #: ../../source/ref-changelog.md:714 msgid "" -"**Remove deprecated no-op extra installs** " -"([#973](https://github.com/adap/flower/pull/973))" -msgstr "**移除过时的不操作额外安装** ([#973](https://github.com/adap/flower/pull/973))" +"**Remove deprecated no-op extra installs** ([#973](https://github.com/adap/" +"flower/pull/973))" +msgstr "" +"**移除过时的不操作额外安装** ([#973](https://github.com/adap/flower/" +"pull/973))" #: ../../source/ref-changelog.md:715 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" msgstr "" -"**从** `FitRes` **和** `EvaluateRes` 中移除已废弃的 proto 字段 " -"([#869](https://github.com/adap/flower/pull/869))" +"**从** `FitRes` **和** `EvaluateRes` 中移除已废弃的 proto 字段 ([#869]" +"(https://github.com/adap/flower/pull/869))" #: ../../source/ref-changelog.md:716 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** ([#1107]" +"(https://github.com/adap/flower/pull/1107))" msgstr "" -"**移除过时的 QffedAvg 策略(由 QFedAvg 取代)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"**移除过时的 QffedAvg 策略(由 QFedAvg 取代)** ([#1107](https://github.com/" +"adap/flower/pull/1107))" #: ../../source/ref-changelog.md:717 msgid "" -"**Remove deprecated DefaultStrategy strategy** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated DefaultStrategy strategy** ([#1142](https://github.com/" +"adap/flower/pull/1142))" msgstr "" -"**删除过时的 DefaultStrategy 策略** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**删除过时的 DefaultStrategy 策略** ([#1142](https://github.com/adap/flower/" +"pull/1142))" #: ../../source/ref-changelog.md:718 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated support for eval_fn accuracy return value** ([#1142]" +"(https://github.com/adap/flower/pull/1142))" msgstr "" -"**删除已过时的对 eval_fn 返回值准确性的支持** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**删除已过时的对 eval_fn 返回值准确性的支持** ([#1142](https://github.com/" +"adap/flower/pull/1142))" #: ../../source/ref-changelog.md:719 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"**移除对以 NumPy ndarrays 传递初始参数的过时支持** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**移除对以 NumPy ndarrays 传递初始参数的过时支持** ([#1142](https://github." +"com/adap/flower/pull/1142))" #: ../../source/ref-changelog.md:721 msgid "v0.18.0 (2022-02-28)" @@ -18293,197 +18375,201 @@ msgstr "v0.18.0 (2022-02-28)" #: ../../source/ref-changelog.md:725 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), [#872]" +"(https://github.com/adap/flower/pull/872), [#833](https://github.com/adap/" +"flower/pull/833), [#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -"**改进了虚拟客户端引擎与 Jupyter Notebook / Google Colab 的兼容性** " -"([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"**改进了虚拟客户端引擎与 Jupyter Notebook / Google Colab 的兼容性** ([#866]" +"(https://github.com/adap/flower/pull/866), [#872](https://github.com/adap/" +"flower/pull/872), [#833](https://github.com/adap/flower/pull/833), [#1036]" +"(https://github.com/adap/flower/pull/1036))" #: ../../source/ref-changelog.md:727 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) " -"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"Simulations (using the Virtual Client Engine through `start_simulation`) now " +"work more smoothly on Jupyter Notebooks (incl. Google Colab) after " "installing Flower with the `simulation` extra (`pip install " "flwr[simulation]`)." msgstr "" -"通过 `start_simulation` 在 Jupyter 笔记本(包括 Google Colab)上安装 Flower 并附加 " -"`simulation` (`pip install flwr[simulation]`)后,模拟(通过 `start_simulation` " -"使用虚拟客户端引擎)现在可以更流畅地运行。" +"通过 `start_simulation` 在 Jupyter 笔记本(包括 Google Colab)上安装 Flower " +"并附加 `simulation` (`pip install flwr[simulation]`)后,模拟(通过 " +"`start_simulation` 使用虚拟客户端引擎)现在可以更流畅地运行。" #: ../../source/ref-changelog.md:729 msgid "" -"**New Jupyter Notebook code example** " -"([#833](https://github.com/adap/flower/pull/833))" +"**New Jupyter Notebook code example** ([#833](https://github.com/adap/flower/" +"pull/833))" msgstr "" -"**新的 Jupyter Notebook 代码示例** " -"([#833](https://github.com/adap/flower/pull/833))" +"**新的 Jupyter Notebook 代码示例** ([#833](https://github.com/adap/flower/" +"pull/833))" #: ../../source/ref-changelog.md:731 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower " -"simulations using the Virtual Client Engine through Jupyter Notebook " -"(incl. Google Colab)." +"A new code example (`quickstart_simulation`) demonstrates Flower simulations " +"using the Virtual Client Engine through Jupyter Notebook (incl. Google " +"Colab)." msgstr "" "新代码示例(`quickstart_simulation`)通过 Jupyter Notebook(包括 Google " "Colab)演示了使用虚拟客户端引擎进行 Flower 模拟。" #: ../../source/ref-changelog.md:733 msgid "" -"**Client properties (feature preview)** " -"([#795](https://github.com/adap/flower/pull/795))" -msgstr "**客户端属性(功能预览)** ([#795](https://github.com/adap/flower/pull/795))" +"**Client properties (feature preview)** ([#795](https://github.com/adap/" +"flower/pull/795))" +msgstr "" +"**客户端属性(功能预览)** ([#795](https://github.com/adap/flower/pull/795))" #: ../../source/ref-changelog.md:735 msgid "" -"Clients can implement a new method `get_properties` to enable server-side" -" strategies to query client properties." -msgstr "客户端可以实现一个新方法 `get_properties`,以启用服务器端策略来查询客户端属性。" +"Clients can implement a new method `get_properties` to enable server-side " +"strategies to query client properties." +msgstr "" +"客户端可以实现一个新方法 `get_properties`,以启用服务器端策略来查询客户端属" +"性。" #: ../../source/ref-changelog.md:737 msgid "" -"**Experimental Android support with TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" -msgstr "** 使用 TFLite 实验性支持安卓系统** ([#865](https://github.com/adap/flower/pull/865))" +"**Experimental Android support with TFLite** ([#865](https://github.com/adap/" +"flower/pull/865))" +msgstr "" +"** 使用 TFLite 实验性支持安卓系统** ([#865](https://github.com/adap/flower/" +"pull/865))" #: ../../source/ref-changelog.md:739 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has " -"become a lot easier." +"client platforms and with this release, using Flower on Android has become a " +"lot easier." msgstr "" -"`main`终于支持 Android 了!Flower 的设计与客户端和框架无关。我们可以集成任意客户端平台,有了这个版本,在安卓系统上使用 " -"Flower 就变得更容易了。" +"`main`终于支持 Android 了!Flower 的设计与客户端和框架无关。我们可以集成任意" +"客户端平台,有了这个版本,在安卓系统上使用 Flower 就变得更容易了。" #: ../../source/ref-changelog.md:741 msgid "" -"The example uses TFLite on the client side, along with a new " -"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " -"still experimental, but they are a first step towards a fully-fledged " -"Android SDK and a unified `FedAvg` implementation that integrated the new" -" functionality from `FedAvgAndroid`." +"The example uses TFLite on the client side, along with a new `FedAvgAndroid` " +"strategy. The Android client and `FedAvgAndroid` are still experimental, but " +"they are a first step towards a fully-fledged Android SDK and a unified " +"`FedAvg` implementation that integrated the new functionality from " +"`FedAvgAndroid`." msgstr "" "该示例在客户端使用了 TFLite 以及新的 `FedAvgAndroid`策略。Android 客户端和 " -"`FedAvgAndroid`仍处于试验阶段,但这是向成熟的 Android SDK 和集成了 `FedAvgAndroid`新功能的统一 " -"`FedAvg`实现迈出的第一步。" +"`FedAvgAndroid`仍处于试验阶段,但这是向成熟的 Android SDK 和集成了 " +"`FedAvgAndroid`新功能的统一 `FedAvg`实现迈出的第一步。" #: ../../source/ref-changelog.md:743 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default " -"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" +"**Make gRPC keepalive time user-configurable and decrease default keepalive " +"time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -"**使 gRPC 保持连接时间可由用户配置,并缩短默认保持连接时间** " -"([#1069](https://github.com/adap/flower/pull/1069))" +"**使 gRPC 保持连接时间可由用户配置,并缩短默认保持连接时间** ([#1069]" +"(https://github.com/adap/flower/pull/1069))" #: ../../source/ref-changelog.md:745 msgid "" "The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, " -"Microsoft Azure). Users can configure the keepalive time to customize the" -" gRPC stack based on specific requirements." +"compatibility of Flower with more cloud environments (for example, Microsoft " +"Azure). Users can configure the keepalive time to customize the gRPC stack " +"based on specific requirements." msgstr "" -"为提高 Flower 与更多云环境(如 Microsoft Azure)的兼容性,缩短了默认 gRPC 保持时间。用户可以根据具体要求配置 " -"keepalive 时间,自定义 gRPC 堆栈。" +"为提高 Flower 与更多云环境(如 Microsoft Azure)的兼容性,缩短了默认 gRPC 保" +"持时间。用户可以根据具体要求配置 keepalive 时间,自定义 gRPC 堆栈。" #: ../../source/ref-changelog.md:747 msgid "" -"**New differential privacy example using Opacus and PyTorch** " -"([#805](https://github.com/adap/flower/pull/805))" +"**New differential privacy example using Opacus and PyTorch** ([#805]" +"(https://github.com/adap/flower/pull/805))" msgstr "" -"**使用 Opacus 和 PyTorch 的新差分隐私示例** " -"([#805](https://github.com/adap/flower/pull/805))" +"**使用 Opacus 和 PyTorch 的新差分隐私示例** ([#805](https://github.com/adap/" +"flower/pull/805))" #: ../../source/ref-changelog.md:749 msgid "" -"A new code example (`opacus`) demonstrates differentially-private " -"federated learning with Opacus, PyTorch, and Flower." -msgstr "一个新的代码示例(\"opacus\")演示了使用 Opacus、PyTorch 和 Flower 进行差分隐私的联邦学习。" +"A new code example (`opacus`) demonstrates differentially-private federated " +"learning with Opacus, PyTorch, and Flower." +msgstr "" +"一个新的代码示例(\"opacus\")演示了使用 Opacus、PyTorch 和 Flower 进行差分隐" +"私的联邦学习。" #: ../../source/ref-changelog.md:751 msgid "" -"**New Hugging Face Transformers code example** " -"([#863](https://github.com/adap/flower/pull/863))" +"**New Hugging Face Transformers code example** ([#863](https://github.com/" +"adap/flower/pull/863))" msgstr "" -"**新的Hugging Face Transformers代码示例** " -"([#863](https://github.com/adap/flower/pull/863))" +"**新的Hugging Face Transformers代码示例** ([#863](https://github.com/adap/" +"flower/pull/863))" #: ../../source/ref-changelog.md:753 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of " -"Hugging Face Transformers with Flower." -msgstr "新的代码示例(`quickstart_huggingface`)证明了结合Flower和Hugging Face Transformers的实用性。" +"A new code example (`quickstart_huggingface`) demonstrates usage of Hugging " +"Face Transformers with Flower." +msgstr "" +"新的代码示例(`quickstart_huggingface`)证明了结合Flower和Hugging Face " +"Transformers的实用性。" #: ../../source/ref-changelog.md:755 msgid "" -"**New MLCube code example** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"**New MLCube code example** ([#779](https://github.com/adap/flower/" +"pull/779), [#1034](https://github.com/adap/flower/pull/1034), [#1065]" +"(https://github.com/adap/flower/pull/1065), [#1090](https://github.com/adap/" +"flower/pull/1090))" msgstr "" "**新的 MLCube 代码示例** ([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"[#1034](https://github.com/adap/flower/pull/1034), [#1065](https://github." +"com/adap/flower/pull/1065), [#1090](https://github.com/adap/flower/" +"pull/1090))" #: ../../source/ref-changelog.md:757 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " -"with Flower." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube with " +"Flower." msgstr "新代码示例(\"quickstart_mlcube\")演示了 MLCube 与 Flower 的用法。" #: ../../source/ref-changelog.md:759 msgid "" -"**SSL-enabled server and client** " -"([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" -msgstr "" -"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"**SSL-enabled server and client** ([#842](https://github.com/adap/flower/" +"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" +"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" +"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" +"github.com/adap/flower/pull/994))" +msgstr "" +"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/" +"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" +"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" +"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" +"github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:761 msgid "" -"SSL enables secure encrypted connections between clients and servers. " -"This release open-sources the Flower secure gRPC implementation to make " -"encrypted communication channels accessible to all Flower users." -msgstr "SSL 可实现客户端与服务器之间的安全加密连接。该版本开源了 Flower 安全 gRPC 实现,使所有 Flower 用户都能访问加密通信通道。" +"SSL enables secure encrypted connections between clients and servers. This " +"release open-sources the Flower secure gRPC implementation to make encrypted " +"communication channels accessible to all Flower users." +msgstr "" +"SSL 可实现客户端与服务器之间的安全加密连接。该版本开源了 Flower 安全 gRPC 实" +"现,使所有 Flower 用户都能访问加密通信通道。" #: ../../source/ref-changelog.md:763 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** ([#885](https://" +"github.com/adap/flower/pull/885), [#895](https://github.com/adap/flower/" +"pull/895))" msgstr "" -"**更新**`FedAdam`**和**`FedYogi`**战略** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"**更新**`FedAdam`**和**`FedYogi`**战略** ([#885](https://github.com/adap/" +"flower/pull/885), [#895](https://github.com/adap/flower/pull/895))" #: ../../source/ref-changelog.md:765 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive " -"Federated Optimization paper." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive Federated " +"Optimization paper." msgstr "FedAdam \"和 \"FedAdam \"与最新版本的 \"自适应联邦优化 \"论文相匹配。" #: ../../source/ref-changelog.md:767 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** " -"([#860](https://github.com/adap/flower/pull/860))" +"**Initialize** `start_simulation` **with a list of client IDs** ([#860]" +"(https://github.com/adap/flower/pull/860))" msgstr "" -"**初始化** `start_simulation` **使用客户端 ID 列表** " -"([#860](https://github.com/adap/flower/pull/860))" +"**初始化** `start_simulation` **使用客户端 ID 列表** ([#860](https://github." +"com/adap/flower/pull/860))" #: ../../source/ref-changelog.md:769 msgid "" @@ -18494,52 +18580,56 @@ msgid "" "identifiers." msgstr "" "现在可以使用客户端 ID 列表(`clients_ids`,类型:`List[str]`)调用 " -"`start_simulation`。每当需要初始化客户端时,这些 ID 就会被传递到 `client_fn` 中,这样就能更轻松地加载无法通过 " -"`int` 标识符访问的数据分区。" +"`start_simulation`。每当需要初始化客户端时,这些 ID 就会被传递到 `client_fn` " +"中,这样就能更轻松地加载无法通过 `int` 标识符访问的数据分区。" #: ../../source/ref-changelog.md:773 msgid "" -"Update `num_examples` calculation in PyTorch code examples in " -"([#909](https://github.com/adap/flower/pull/909))" +"Update `num_examples` calculation in PyTorch code examples in ([#909]" +"(https://github.com/adap/flower/pull/909))" msgstr "" -"更新 PyTorch 代码示例中的 \"num_examples \"计算 " -"([#909](https://github.com/adap/flower/pull/909))" +"更新 PyTorch 代码示例中的 \"num_examples \"计算 ([#909](https://github.com/" +"adap/flower/pull/909))" #: ../../source/ref-changelog.md:774 msgid "" -"Expose Flower version through `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"Expose Flower version through `flwr.__version__` ([#952](https://github.com/" +"adap/flower/pull/952))" msgstr "" -"通过 `flwr.__version__` 公开 Flower 版本 " -"([#952](https://github.com/adap/flower/pull/952))" +"通过 `flwr.__version__` 公开 Flower 版本 ([#952](https://github.com/adap/" +"flower/pull/952))" #: ../../source/ref-changelog.md:775 msgid "" -"`start_server` in `app.py` now returns a `History` object containing " -"metrics from training ([#974](https://github.com/adap/flower/pull/974))" +"`start_server` in `app.py` now returns a `History` object containing metrics " +"from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -"`app.py`中的 `start_server`现在会返回一个 `History` " -"对象,其中包含训练中的指标([#974](https://github.com/adap/flower/pull/974))" +"`app.py`中的 `start_server`现在会返回一个 `History` 对象,其中包含训练中的指" +"标([#974](https://github.com/adap/flower/pull/974))" #: ../../source/ref-changelog.md:776 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable ([#978]" +"(https://github.com/adap/flower/pull/978))" msgstr "" -"使 `max_workers`(由 " -"`ThreadPoolExecutor`使用)可配置([#978](https://github.com/adap/flower/pull/978))" +"使 `max_workers`(由 `ThreadPoolExecutor`使用)可配置([#978](https://github." +"com/adap/flower/pull/978))" #: ../../source/ref-changelog.md:777 msgid "" -"Increase sleep time after server start to three seconds in all code " -"examples ([#1086](https://github.com/adap/flower/pull/1086))" -msgstr "在所有代码示例中,将服务器启动后的休眠时间延长至三秒([#1086](https://github.com/adap/flower/pull/1086))" +"Increase sleep time after server start to three seconds in all code examples " +"([#1086](https://github.com/adap/flower/pull/1086))" +msgstr "" +"在所有代码示例中,将服务器启动后的休眠时间延长至三秒([#1086](https://github." +"com/adap/flower/pull/1086))" #: ../../source/ref-changelog.md:778 msgid "" -"Added a new FAQ section to the documentation " -"([#948](https://github.com/adap/flower/pull/948))" -msgstr "在文档中添加了新的常见问题部分 ([#948](https://github.com/adap/flower/pull/948))" +"Added a new FAQ section to the documentation ([#948](https://github.com/adap/" +"flower/pull/948))" +msgstr "" +"在文档中添加了新的常见问题部分 ([#948](https://github.com/adap/flower/" +"pull/948))" #: ../../source/ref-changelog.md:779 msgid "" @@ -18552,20 +18642,21 @@ msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" -"**从发布版中删除**`flwr_example`**和**`flwr_experimental`** " -"([#869](https://github.com/adap/flower/pull/869))" +"**从发布版中删除**`flwr_example`**和**`flwr_experimental`** ([#869](https://" +"github.com/adap/flower/pull/869))" #: ../../source/ref-changelog.md:785 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " "builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " -"an upcoming release." +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in an " +"upcoming release." msgstr "" -"自 Flower 0.12.0 起,软件包 `flwr_example` 和 `flwr_experimental` 已被弃用,它们不再包含在 " -"Flower 的发布版本中。相关的额外包(`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`)现在已不再使用,并将在即将发布的版本中移除。" +"自 Flower 0.12.0 起,软件包 `flwr_example` 和 `flwr_experimental` 已被弃用," +"它们不再包含在 Flower 的发布版本中。相关的额外包(`baseline`, `examples-" +"pytorch`, `examples-tensorflow`, `http-logger`, `ops`)现在已不再使用,并将在" +"即将发布的版本中移除。" #: ../../source/ref-changelog.md:787 msgid "v0.17.0 (2021-09-24)" @@ -18573,169 +18664,190 @@ msgstr "v0.17.0 (2021-09-24)" #: ../../source/ref-changelog.md:791 msgid "" -"**Experimental virtual client engine** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"**Experimental virtual client engine** ([#781](https://github.com/adap/" +"flower/pull/781) [#790](https://github.com/adap/flower/pull/790) [#791]" +"(https://github.com/adap/flower/pull/791))" msgstr "" "**实验性虚拟客户端引擎** ([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"[#790](https://github.com/adap/flower/pull/790) [#791](https://github.com/" +"adap/flower/pull/791))" #: ../../source/ref-changelog.md:793 msgid "" -"One of Flower's goals is to enable research at scale. This release " -"enables a first (experimental) peek at a major new feature, codenamed the" -" virtual client engine. Virtual clients enable simulations that scale to " -"a (very) large number of clients on a single machine or compute cluster. " -"The easiest way to test the new functionality is to look at the two new " -"code examples called `quickstart_simulation` and `simulation_pytorch`." +"One of Flower's goals is to enable research at scale. This release enables a " +"first (experimental) peek at a major new feature, codenamed the virtual " +"client engine. Virtual clients enable simulations that scale to a (very) " +"large number of clients on a single machine or compute cluster. The easiest " +"way to test the new functionality is to look at the two new code examples " +"called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -"Flower 的目标之一是实现大规模研究。这一版本首次(试验性地)展示了代号为 \"虚拟客户端引擎 " -"\"的重要新功能。虚拟客户端可以在单台机器或计算集群上对大量客户端进行模拟。测试新功能的最简单方法是查看名为 " -"\"quickstart_simulation \"和 \"simulation_pytorch \"的两个新代码示例。" +"Flower 的目标之一是实现大规模研究。这一版本首次(试验性地)展示了代号为 \"虚" +"拟客户端引擎 \"的重要新功能。虚拟客户端可以在单台机器或计算集群上对大量客户端" +"进行模拟。测试新功能的最简单方法是查看名为 \"quickstart_simulation \"和 " +"\"simulation_pytorch \"的两个新代码示例。" #: ../../source/ref-changelog.md:795 msgid "" -"The feature is still experimental, so there's no stability guarantee for " -"the API. It's also not quite ready for prime time and comes with a few " -"known caveats. However, those who are curious are encouraged to try it " -"out and share their thoughts." +"The feature is still experimental, so there's no stability guarantee for the " +"API. It's also not quite ready for prime time and comes with a few known " +"caveats. However, those who are curious are encouraged to try it out and " +"share their thoughts." msgstr "" -"该功能仍处于试验阶段,因此无法保证 API " -"的稳定性。此外,它还没有完全准备好进入黄金时间,并有一些已知的注意事项。不过,我们鼓励好奇的用户尝试使用并分享他们的想法。" +"该功能仍处于试验阶段,因此无法保证 API 的稳定性。此外,它还没有完全准备好进入" +"黄金时间,并有一些已知的注意事项。不过,我们鼓励好奇的用户尝试使用并分享他们" +"的想法。" #: ../../source/ref-changelog.md:797 msgid "" -"**New built-in strategies** " -"([#828](https://github.com/adap/flower/pull/828) " +"**New built-in strategies** ([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" -"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822)" +"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) [#822]" +"(https://github.com/adap/flower/pull/822)" #: ../../source/ref-changelog.md:799 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" -msgstr "FedYogi - 在服务器端使用 Yogi 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" +msgstr "" +"FedYogi - 在服务器端使用 Yogi 的联邦学习策略。基于 https://arxiv.org/" +"abs/2003.00295 实现" #: ../../source/ref-changelog.md:800 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" -msgstr "FedAdam - 在服务器端使用 Adam 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" +msgstr "" +"FedAdam - 在服务器端使用 Adam 的联邦学习策略。基于 https://arxiv.org/" +"abs/2003.00295 实现" #: ../../source/ref-changelog.md:802 msgid "" -"**New PyTorch Lightning code example** " -"([#617](https://github.com/adap/flower/pull/617))" +"**New PyTorch Lightning code example** ([#617](https://github.com/adap/" +"flower/pull/617))" msgstr "" -"**新的 PyTorch Lightning 代码示例** " -"([#617](https://github.com/adap/flower/pull/617))" +"**新的 PyTorch Lightning 代码示例** ([#617](https://github.com/adap/flower/" +"pull/617))" #: ../../source/ref-changelog.md:804 msgid "" -"**New Variational Auto-Encoder code example** " -"([#752](https://github.com/adap/flower/pull/752))" -msgstr "**新的变分自动编码器代码示例** ([#752](https://github.com/adap/flower/pull/752))" +"**New Variational Auto-Encoder code example** ([#752](https://github.com/" +"adap/flower/pull/752))" +msgstr "" +"**新的变分自动编码器代码示例** ([#752](https://github.com/adap/flower/" +"pull/752))" #: ../../source/ref-changelog.md:806 msgid "" -"**New scikit-learn code example** " -"([#748](https://github.com/adap/flower/pull/748))" -msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" +"**New scikit-learn code example** ([#748](https://github.com/adap/flower/" +"pull/748))" +msgstr "" +"**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/" +"pull/748))" #: ../../source/ref-changelog.md:808 msgid "" -"**New experimental TensorBoard strategy** " -"([#789](https://github.com/adap/flower/pull/789))" -msgstr "**新的实验性 TensorBoard 策略**([#789](https://github.com/adap/flower/pull/789))" +"**New experimental TensorBoard strategy** ([#789](https://github.com/adap/" +"flower/pull/789))" +msgstr "" +"**新的实验性 TensorBoard 策略**([#789](https://github.com/adap/flower/" +"pull/789))" #: ../../source/ref-changelog.md:812 msgid "" -"Improved advanced TensorFlow code example " -"([#769](https://github.com/adap/flower/pull/769))" -msgstr "改进的高级 TensorFlow 代码示例([#769](https://github.com/adap/flower/pull/769)" +"Improved advanced TensorFlow code example ([#769](https://github.com/adap/" +"flower/pull/769))" +msgstr "" +"改进的高级 TensorFlow 代码示例([#769](https://github.com/adap/flower/" +"pull/769)" #: ../../source/ref-changelog.md:813 msgid "" -"Warning when `min_available_clients` is misconfigured " -"([#830](https://github.com/adap/flower/pull/830))" +"Warning when `min_available_clients` is misconfigured ([#830](https://github." +"com/adap/flower/pull/830))" msgstr "" -"当 `min_available_clients` 配置错误时发出警告 " -"([#830](https://github.com/adap/flower/pull/830))" +"当 `min_available_clients` 配置错误时发出警告 ([#830](https://github.com/" +"adap/flower/pull/830))" #: ../../source/ref-changelog.md:814 msgid "" -"Improved gRPC server docs " -"([#841](https://github.com/adap/flower/pull/841))" -msgstr "改进了 gRPC 服务器文档([#841](https://github.com/adap/flower/pull/841))" +"Improved gRPC server docs ([#841](https://github.com/adap/flower/pull/841))" +msgstr "" +"改进了 gRPC 服务器文档([#841](https://github.com/adap/flower/pull/841))" #: ../../source/ref-changelog.md:815 msgid "" -"Improved error message in `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" -msgstr "改进了 `NumPyClient` 中的错误信息 ([#851](https://github.com/adap/flower/pull/851))" +"Improved error message in `NumPyClient` ([#851](https://github.com/adap/" +"flower/pull/851))" +msgstr "" +"改进了 `NumPyClient` 中的错误信息 ([#851](https://github.com/adap/flower/" +"pull/851))" #: ../../source/ref-changelog.md:816 msgid "" -"Improved PyTorch quickstart code example " -"([#852](https://github.com/adap/flower/pull/852))" -msgstr "改进的 PyTorch 快速启动代码示例 ([#852](https://github.com/adap/flower/pull/852))" +"Improved PyTorch quickstart code example ([#852](https://github.com/adap/" +"flower/pull/852))" +msgstr "" +"改进的 PyTorch 快速启动代码示例 ([#852](https://github.com/adap/flower/" +"pull/852))" #: ../../source/ref-changelog.md:820 msgid "" -"**Disabled final distributed evaluation** " -"([#800](https://github.com/adap/flower/pull/800))" -msgstr "**禁用最终分布式评价** ([#800](https://github.com/adap/flower/pull/800))" +"**Disabled final distributed evaluation** ([#800](https://github.com/adap/" +"flower/pull/800))" +msgstr "" +"**禁用最终分布式评价** ([#800](https://github.com/adap/flower/pull/800))" #: ../../source/ref-changelog.md:822 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on" -" all connected clients, which is often not required (e.g., when using " -"server-side evaluation). The prior behaviour can be enabled by passing " +"Prior behaviour was to perform a final round of distributed evaluation on " +"all connected clients, which is often not required (e.g., when using server-" +"side evaluation). The prior behaviour can be enabled by passing " "`force_final_distributed_eval=True` to `start_server`." msgstr "" -"之前的行为是在所有连接的客户端上执行最后一轮分布式评估,而这通常是不需要的(例如,在使用服务器端评估时)。可以通过向 `start_server`" -" 传递 `force_final_distributed_eval=True` 来启用之前的行为。" +"之前的行为是在所有连接的客户端上执行最后一轮分布式评估,而这通常是不需要的" +"(例如,在使用服务器端评估时)。可以通过向 `start_server` 传递 " +"`force_final_distributed_eval=True` 来启用之前的行为。" #: ../../source/ref-changelog.md:824 msgid "" -"**Renamed q-FedAvg strategy** " -"([#802](https://github.com/adap/flower/pull/802))" -msgstr "**更名为 q-FedAvg 策略** ([#802](https://github.com/adap/flower/pull/802))" +"**Renamed q-FedAvg strategy** ([#802](https://github.com/adap/flower/" +"pull/802))" +msgstr "" +"**更名为 q-FedAvg 策略** ([#802](https://github.com/adap/flower/pull/802))" #: ../../source/ref-changelog.md:826 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " -"the notation given in the original paper (q-FFL is the optimization " -"objective, q-FedAvg is the proposed solver). Note the original (now " -"deprecated) `QffedAvg` class is still available for compatibility reasons" -" (it will be removed in a future release)." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect the " +"notation given in the original paper (q-FFL is the optimization objective, q-" +"FedAvg is the proposed solver). Note the original (now deprecated) " +"`QffedAvg` class is still available for compatibility reasons (it will be " +"removed in a future release)." msgstr "" -"名为 `QffedAvg` 的策略已更名为 `QFedAvg`,以更好地反映原始论文中给出的符号(q-FFL 是优化目标,q-FedAvg " -"是建议的求解器)。请注意,出于兼容性原因,原始(现已废弃)的 `QffedAvg` 类仍然可用(它将在未来的版本中移除)。" +"名为 `QffedAvg` 的策略已更名为 `QFedAvg`,以更好地反映原始论文中给出的符号" +"(q-FFL 是优化目标,q-FedAvg 是建议的求解器)。请注意,出于兼容性原因,原始" +"(现已废弃)的 `QffedAvg` 类仍然可用(它将在未来的版本中移除)。" #: ../../source/ref-changelog.md:828 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/pull/791))" msgstr "" -"**删除并重命名代码示例**`simulation_pytorch`**为**`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"**删除并重命名代码示例**`simulation_pytorch`**为" +"**`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/" +"pull/791))" #: ../../source/ref-changelog.md:830 msgid "" -"This example has been replaced by a new example. The new example is based" -" on the experimental virtual client engine, which will become the new " -"default way of doing most types of large-scale simulations in Flower. The" -" existing example was kept for reference purposes, but it might be " -"removed in the future." +"This example has been replaced by a new example. The new example is based on " +"the experimental virtual client engine, which will become the new default " +"way of doing most types of large-scale simulations in Flower. The existing " +"example was kept for reference purposes, but it might be removed in the " +"future." msgstr "" -"该示例已被新示例取代。新示例基于试验性虚拟客户端引擎,它将成为在 Flower " -"中进行大多数类型大规模模拟的新的默认方式。现有示例将作为参考保留,但将来可能会删除。" +"该示例已被新示例取代。新示例基于试验性虚拟客户端引擎,它将成为在 Flower 中进" +"行大多数类型大规模模拟的新的默认方式。现有示例将作为参考保留,但将来可能会删" +"除。" #: ../../source/ref-changelog.md:832 msgid "v0.16.0 (2021-05-11)" @@ -18743,8 +18855,7 @@ msgstr "v0.16.0 (2021-05-11)" #: ../../source/ref-changelog.md:836 msgid "" -"**New built-in strategies** " -"([#549](https://github.com/adap/flower/pull/549))" +"**New built-in strategies** ([#549](https://github.com/adap/flower/pull/549))" msgstr "**新的内置策略** ([#549](https://github.com/adap/flower/pull/549))" #: ../../source/ref-changelog.md:838 @@ -18753,9 +18864,11 @@ msgstr "(摘要) FedOpt" #: ../../source/ref-changelog.md:841 msgid "" -"**Custom metrics for server and strategies** " -"([#717](https://github.com/adap/flower/pull/717))" -msgstr "**服务器和策略的自定义指标** ([#717](https://github.com/adap/flower/pull/717))" +"**Custom metrics for server and strategies** ([#717](https://github.com/adap/" +"flower/pull/717))" +msgstr "" +"**服务器和策略的自定义指标** ([#717](https://github.com/adap/flower/" +"pull/717))" #: ../../source/ref-changelog.md:843 msgid "" @@ -18765,66 +18878,70 @@ msgid "" "dictionary containing custom metrics from client to server. As of this " "release, custom metrics replace task-specific metrics on the server." msgstr "" -"Flower 服务器现在完全与任务无关,所有剩余的任务特定度量(如 \"准确度\")都已被自定义度量字典取代。Flower 0.15 " -"引入了从客户端向服务器传递包含自定义指标的字典的功能。从本版本开始,自定义指标将取代服务器上的特定任务指标。" +"Flower 服务器现在完全与任务无关,所有剩余的任务特定度量(如 \"准确度\")都已" +"被自定义度量字典取代。Flower 0.15 引入了从客户端向服务器传递包含自定义指标的" +"字典的功能。从本版本开始,自定义指标将取代服务器上的特定任务指标。" #: ../../source/ref-changelog.md:845 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are" -" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " -"they enable evaluation functions passed to built-in strategies (via " -"`eval_fn`) to return more than two evaluation metrics. Strategies can " -"even return *aggregated* metrics dictionaries for the server to keep " -"track of." +"Custom metric dictionaries are now used in two user-facing APIs: they are " +"returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and they " +"enable evaluation functions passed to built-in strategies (via `eval_fn`) to " +"return more than two evaluation metrics. Strategies can even return " +"*aggregated* metrics dictionaries for the server to keep track of." msgstr "" -"自定义度量字典现在可在两个面向用户的 API 中使用:它们可从策略方法 `aggregate_fit`/`aggregate_evaluate` " -"返回,还可使传递给内置策略(通过 `eval_fn`)的评估函数返回两个以上的评估度量。策略甚至可以返回 *aggregated* " -"指标字典,以便服务器跟踪。" +"自定义度量字典现在可在两个面向用户的 API 中使用:它们可从策略方法 " +"`aggregate_fit`/`aggregate_evaluate` 返回,还可使传递给内置策略(通过 " +"`eval_fn`)的评估函数返回两个以上的评估度量。策略甚至可以返回 *aggregated* 指" +"标字典,以便服务器跟踪。" #: ../../source/ref-changelog.md:847 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate" -" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"returning an empty `{}`), server-side evaluation functions should migrate " +"from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -"Strategy 实现应将其 `aggregate_fit` 和 `aggregate_evaluate` " -"方法迁移到新的返回类型(例如,只需返回空的 `{}`),服务器端评估函数应从 `return loss, accuracy` 迁移到 " -"`return loss, {\"accuracy\": accuracy}`。" +"Strategy 实现应将其 `aggregate_fit` 和 `aggregate_evaluate` 方法迁移到新的返" +"回类型(例如,只需返回空的 `{}`),服务器端评估函数应从 `return loss, " +"accuracy` 迁移到 `return loss, {\"accuracy\": accuracy}`。" #: ../../source/ref-changelog.md:849 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." -msgstr "Flower 0.15 风格的返回类型已被弃用(但仍受支持),兼容性将在未来的版本中移除。" +msgstr "" +"Flower 0.15 风格的返回类型已被弃用(但仍受支持),兼容性将在未来的版本中移" +"除。" #: ../../source/ref-changelog.md:851 msgid "" -"**Migration warnings for deprecated functionality** " -"([#690](https://github.com/adap/flower/pull/690))" -msgstr "** 过时功能的迁移警告** ([#690](https://github.com/adap/flower/pull/690))" +"**Migration warnings for deprecated functionality** ([#690](https://github." +"com/adap/flower/pull/690))" +msgstr "" +"** 过时功能的迁移警告** ([#690](https://github.com/adap/flower/pull/690))" #: ../../source/ref-changelog.md:853 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces " -"detailed warning messages if usage of deprecated APIs is detected. The " -"new warning messages often provide details on how to migrate to more " -"recent APIs, thus easing the transition from one release to another." +"maintaining compatibility with legacy APIs. This release introduces detailed " +"warning messages if usage of deprecated APIs is detected. The new warning " +"messages often provide details on how to migrate to more recent APIs, thus " +"easing the transition from one release to another." msgstr "" -"Flower 早期版本通常会迁移到新的应用程序接口,同时保持与旧版应用程序接口的兼容。如果检测到使用了过时的 " -"API,本版本将引入详细的警告信息。新的警告信息通常会详细说明如何迁移到更新的 API,从而简化从一个版本到另一个版本的过渡。" +"Flower 早期版本通常会迁移到新的应用程序接口,同时保持与旧版应用程序接口的兼" +"容。如果检测到使用了过时的 API,本版本将引入详细的警告信息。新的警告信息通常" +"会详细说明如何迁移到更新的 API,从而简化从一个版本到另一个版本的过渡。" #: ../../source/ref-changelog.md:855 msgid "" -"Improved docs and docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +"Improved docs and docstrings ([#691](https://github.com/adap/flower/" +"pull/691) [#692](https://github.com/adap/flower/pull/692) [#713](https://" +"github.com/adap/flower/pull/713))" msgstr "" -"改进了文档和文档说明 ([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +"改进了文档和文档说明 ([#691](https://github.com/adap/flower/pull/691) [#692]" +"(https://github.com/adap/flower/pull/692) [#713](https://github.com/adap/" +"flower/pull/713))" #: ../../source/ref-changelog.md:857 msgid "MXNet example and documentation" @@ -18833,55 +18950,52 @@ msgstr "MXNet 示例和文档" #: ../../source/ref-changelog.md:859 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"([#696](https://github.com/adap/flower/pull/696) [#702](https://github.com/" +"adap/flower/pull/702) [#705](https://github.com/adap/flower/pull/705))" msgstr "" -"PyTorch 示例中的 FedBN 实现: 从集中到联邦 " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"PyTorch 示例中的 FedBN 实现: 从集中到联邦 ([#696](https://github.com/adap/" +"flower/pull/696) [#702](https://github.com/adap/flower/pull/702) [#705]" +"(https://github.com/adap/flower/pull/705))" #: ../../source/ref-changelog.md:863 msgid "" -"**Serialization-agnostic server** " -"([#721](https://github.com/adap/flower/pull/721))" +"**Serialization-agnostic server** ([#721](https://github.com/adap/flower/" +"pull/721))" msgstr "**序列化无关服务器** ([#721](https://github.com/adap/flower/pull/721))" #: ../../source/ref-changelog.md:865 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of " -"class `Weights` (which represents parameters as deserialized NumPy " -"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " -"`Parameters` objects are fully serialization-agnostic and represents " -"parameters as byte arrays, the `tensor_type` attributes indicates how " -"these byte arrays should be interpreted (e.g., for " -"serialization/deserialization)." +"The Flower server is now fully serialization-agnostic. Prior usage of class " +"`Weights` (which represents parameters as deserialized NumPy ndarrays) was " +"replaced by class `Parameters` (e.g., in `Strategy`). `Parameters` objects " +"are fully serialization-agnostic and represents parameters as byte arrays, " +"the `tensor_type` attributes indicates how these byte arrays should be " +"interpreted (e.g., for serialization/deserialization)." msgstr "" -"Flower 服务器现在完全不依赖序列化。之前使用的 `Weights` 类(以反序列化的 NumPy ndarrays 表示参数)已被 " -"`Parameters` 类取代(例如在 `Strategy`中)。参数 " -"\"对象与序列化完全无关,它以字节数组的形式表示参数,\"tensor_type \"属性表示如何解释这些字节数组(例如,用于序列化/反序列化)。" +"Flower 服务器现在完全不依赖序列化。之前使用的 `Weights` 类(以反序列化的 " +"NumPy ndarrays 表示参数)已被 `Parameters` 类取代(例如在 `Strategy`中)。参" +"数 \"对象与序列化完全无关,它以字节数组的形式表示参数,\"tensor_type \"属性表" +"示如何解释这些字节数组(例如,用于序列化/反序列化)。" #: ../../source/ref-changelog.md:867 msgid "" -"Built-in strategies implement this approach by handling serialization and" -" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"Built-in strategies implement this approach by handling serialization and " +"deserialization to/from `Weights` internally. Custom/3rd-party Strategy " "implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR " -"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" -" easily migrate to the new format." +"definitions. Strategy authors can consult PR [#721](https://github.com/adap/" +"flower/pull/721) to see how strategies can easily migrate to the new format." msgstr "" -"内置策略通过在内部处理序列化和反序列化到/从`Weights`来实现这种方法。自定义/第三方策略实现应更新为稍有改动的策略方法定义。策略作者可查阅" -" PR [#721](https://github.com/adap/flower/pull/721) 以了解如何将策略轻松迁移到新格式。" +"内置策略通过在内部处理序列化和反序列化到/从`Weights`来实现这种方法。自定义/第" +"三方策略实现应更新为稍有改动的策略方法定义。策略作者可查阅 PR [#721](https://" +"github.com/adap/flower/pull/721) 以了解如何将策略轻松迁移到新格式。" #: ../../source/ref-changelog.md:869 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use " -"`flwr.server.Server.evaluate_round` instead " -"([#717](https://github.com/adap/flower/pull/717))" +"Deprecated `flwr.server.Server.evaluate`, use `flwr.server.Server." +"evaluate_round` instead ([#717](https://github.com/adap/flower/pull/717))" msgstr "" -"已弃用 `flwr.server.Server.evaluate`,改用 " -"`flwr.server.Server.evaluate_round`([#717](https://github.com/adap/flower/pull/717)" +"已弃用 `flwr.server.Server.evaluate`,改用 `flwr.server.Server." +"evaluate_round`([#717](https://github.com/adap/flower/pull/717)" #: ../../source/ref-changelog.md:871 msgid "v0.15.0 (2021-03-12)" @@ -18889,9 +19003,10 @@ msgstr "v0.15.0 (2021-03-12)" #: ../../source/ref-changelog.md:875 msgid "" -"**Server-side parameter initialization** " -"([#658](https://github.com/adap/flower/pull/658))" -msgstr "**服务器端参数初始化** ([#658](https://github.com/adap/flower/pull/658))" +"**Server-side parameter initialization** ([#658](https://github.com/adap/" +"flower/pull/658))" +msgstr "" +"**服务器端参数初始化** ([#658](https://github.com/adap/flower/pull/658))" #: ../../source/ref-changelog.md:877 msgid "" @@ -18899,18 +19014,18 @@ msgid "" "parameter initialization works via a new `Strategy` method called " "`initialize_parameters`." msgstr "" -"现在可以在服务器端初始化模型参数。服务器端参数初始化通过名为 \"initialize_parameters \"的新 \"Strategy " -"\"方法进行。" +"现在可以在服务器端初始化模型参数。服务器端参数初始化通过名为 " +"\"initialize_parameters \"的新 \"Strategy \"方法进行。" #: ../../source/ref-changelog.md:879 msgid "" "Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies " -"will provide these initial parameters to the server on startup and then " -"delete them to free the memory afterwards." +"`initial_parameters` to set the initial parameters. Built-in strategies will " +"provide these initial parameters to the server on startup and then delete " +"them to free the memory afterwards." msgstr "" -"内置策略支持名为 \"initial_parameters " -"\"的新构造函数参数,用于设置初始参数。内置策略会在启动时向服务器提供这些初始参数,然后删除它们以释放内存。" +"内置策略支持名为 \"initial_parameters \"的新构造函数参数,用于设置初始参数。" +"内置策略会在启动时向服务器提供这些初始参数,然后删除它们以释放内存。" #: ../../source/ref-changelog.md:898 msgid "" @@ -18918,7 +19033,9 @@ msgid "" "continue to use the current behaviour (namely, it will ask one of the " "connected clients for its parameters and use these as the initial global " "parameters)." -msgstr "如果没有向策略提供初始参数,服务器将继续使用当前行为(即向其中一个已连接的客户端询问参数,并将这些参数用作初始全局参数)。" +msgstr "" +"如果没有向策略提供初始参数,服务器将继续使用当前行为(即向其中一个已连接的客" +"户端询问参数,并将这些参数用作初始全局参数)。" #: ../../source/ref-changelog.md:900 msgid "Deprecations" @@ -18926,11 +19043,11 @@ msgstr "停用" #: ../../source/ref-changelog.md:902 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " -"`flwr.server.strategy.FedAvg`, which is equivalent)" +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to `flwr.server." +"strategy.FedAvg`, which is equivalent)" msgstr "" -"停用 `flwr.server.strategy.DefaultStrategy`(迁移到等价的 " -"`flwr.server.strategy.FedAvg`)" +"停用 `flwr.server.strategy.DefaultStrategy`(迁移到等价的 `flwr.server." +"strategy.FedAvg`)" #: ../../source/ref-changelog.md:904 msgid "v0.14.0 (2021-02-18)" @@ -18939,87 +19056,90 @@ msgstr "v0.14.0 (2021-02-18)" #: ../../source/ref-changelog.md:908 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"([#610](https://github.com/adap/flower/pull/610) [#572](https://github.com/" +"adap/flower/pull/572) [#633](https://github.com/adap/flower/pull/633))" msgstr "" -"**通用** `Client.fit` **和** `Client.evaluate` **返回值** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"**通用** `Client.fit` **和** `Client.evaluate` **返回值** ([#610](https://" +"github.com/adap/flower/pull/610) [#572](https://github.com/adap/flower/" +"pull/572) [#633](https://github.com/adap/flower/pull/633))" #: ../../source/ref-changelog.md:910 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to " -"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " -"This means one can return almost arbitrary values from `fit`/`evaluate` " -"and make use of them on the server side!" +"Clients can now return an additional dictionary mapping `str` keys to values " +"of the following types: `bool`, `bytes`, `float`, `int`, `str`. This means " +"one can return almost arbitrary values from `fit`/`evaluate` and make use of " +"them on the server side!" msgstr "" -"客户端现在可以返回一个额外的字典,将 `str` 键映射为以下类型的值: " -"bool`、`bytes`、`float`、`int`、`str`。这意味着我们可以从 `fit`/`evaluate` " -"返回几乎任意的值,并在服务器端使用它们!" +"客户端现在可以返回一个额外的字典,将 `str` 键映射为以下类型的值: bool`、" +"`bytes`、`float`、`int`、`str`。这意味着我们可以从 `fit`/`evaluate` 返回几乎" +"任意的值,并在服务器端使用它们!" #: ../../source/ref-changelog.md:912 msgid "" -"This improvement also allowed for more consistent return types between " -"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " -"dict)` representing the loss, number of examples, and a dictionary " -"holding arbitrary problem-specific values like accuracy." +"This improvement also allowed for more consistent return types between `fit` " +"and `evaluate`: `evaluate` should now return a tuple `(float, int, dict)` " +"representing the loss, number of examples, and a dictionary holding " +"arbitrary problem-specific values like accuracy." msgstr "" -"这一改进还使 `fit` 和 `evaluate` 之间的返回类型更加一致:`evaluate` 现在应返回一个元组`(float, int, " -"dict)`,代表损失、示例数和一个包含特定问题任意值(如准确度)的字典。" +"这一改进还使 `fit` 和 `evaluate` 之间的返回类型更加一致:`evaluate` 现在应返" +"回一个元组`(float, int, dict)`,代表损失、示例数和一个包含特定问题任意值(如" +"准确度)的字典。" #: ../../source/ref-changelog.md:914 msgid "" -"In case you wondered: this feature is compatible with existing projects, " -"the additional dictionary return value is optional. New code should " -"however migrate to the new return types to be compatible with upcoming " -"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " -"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " -"details." +"In case you wondered: this feature is compatible with existing projects, the " +"additional dictionary return value is optional. New code should however " +"migrate to the new return types to be compatible with upcoming Flower " +"releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, `evaluate`: " +"`float, int, Dict[str, Scalar]`). See the example below for details." msgstr "" -"如果你想知道:此功能与现有项目兼容,额外的字典返回值是可选的。不过,新代码应迁移到新的返回类型,以便与即将发布的 Flower " -"版本兼容(`fit`: `List[np.ndarray], int, Dict[str, Scalar]`,`evaluate`: " -"`float, int, Dict[str, Scalar]`)。详见下面的示例。" +"如果你想知道:此功能与现有项目兼容,额外的字典返回值是可选的。不过,新代码应" +"迁移到新的返回类型,以便与即将发布的 Flower 版本兼容(`fit`: `List[np." +"ndarray], int, Dict[str, Scalar]`,`evaluate`: `float, int, Dict[str, " +"Scalar]`)。详见下面的示例。" #: ../../source/ref-changelog.md:916 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" -msgstr "*代码示例:* 注意 `FlwrClient.fit` 和 `FlwrClient.evaluate` 中的附加字典返回值:" +msgstr "" +"*代码示例:* 注意 `FlwrClient.fit` 和 `FlwrClient.evaluate` 中的附加字典返回" +"值:" #: ../../source/ref-changelog.md:931 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Generalized** `config` **argument in** `Client.fit` **and** `Client." +"evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -"**在**`Client.fit` " -"**和**`Client.evaluate`中泛化**`config`参数([#595](https://github.com/adap/flower/pull/595))" +"**在**`Client.fit` **和**`Client.evaluate`中泛化**`config`参数([#595]" +"(https://github.com/adap/flower/pull/595))" #: ../../source/ref-changelog.md:933 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means " -"that dictionary values were expected to be strings. The new release " -"generalizes this to enable values of the following types: `bool`, " -"`bytes`, `float`, `int`, `str`." +"The `config` argument used to be of type `Dict[str, str]`, which means that " +"dictionary values were expected to be strings. The new release generalizes " +"this to enable values of the following types: `bool`, `bytes`, `float`, " +"`int`, `str`." msgstr "" -"`config`参数曾是 \"字典[str, str]\"类型,这意味着字典值应是字符串。新版本将其扩展为以下类型的值: " -"bool`、`bytes`、`float`、`int`、`str`。" +"`config`参数曾是 \"字典[str, str]\"类型,这意味着字典值应是字符串。新版本将其" +"扩展为以下类型的值: bool`、`bytes`、`float`、`int`、`str`。" #: ../../source/ref-changelog.md:935 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" -"side and `int(config[\"epochs\"])` on the client side!" +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-side " +"and `int(config[\"epochs\"])` on the client side!" msgstr "" -"这意味着现在可以使用 `config` 字典向 `fit`/`evaluate` 传递几乎任意的值。耶,服务器端不再需要 " -"`str(epochs)`,客户端不再需要 `int(config[\"epochs\"])`!" +"这意味着现在可以使用 `config` 字典向 `fit`/`evaluate` 传递几乎任意的值。耶," +"服务器端不再需要 `str(epochs)`,客户端不再需要 `int(config[\"epochs\"])`!" #: ../../source/ref-changelog.md:937 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" -msgstr "*代码示例:* 注意 `config` 字典现在在 `Client.fit` 和 `Client.evaluate` 中都包含非 `str` 值:" +msgstr "" +"*代码示例:* 注意 `config` 字典现在在 `Client.fit` 和 `Client.evaluate` 中都" +"包含非 `str` 值:" #: ../../source/ref-changelog.md:954 msgid "v0.13.0 (2021-01-08)" @@ -19027,16 +19147,19 @@ msgstr "v0.13.0 (2021-01-08)" #: ../../source/ref-changelog.md:958 msgid "" -"New example: PyTorch From Centralized To Federated " -"([#549](https://github.com/adap/flower/pull/549))" -msgstr "新示例: PyTorch 从集中到联邦 ([#549](https://github.com/adap/flower/pull/549))" +"New example: PyTorch From Centralized To Federated ([#549](https://github." +"com/adap/flower/pull/549))" +msgstr "" +"新示例: PyTorch 从集中到联邦 ([#549](https://github.com/adap/flower/" +"pull/549))" #: ../../source/ref-changelog.md:959 msgid "Improved documentation" msgstr "改进文档" #: ../../source/ref-changelog.md:960 -msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +msgid "" +"New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "新文档主题 ([#551](https://github.com/adap/flower/pull/551))" #: ../../source/ref-changelog.md:961 @@ -19045,14 +19168,14 @@ msgstr "新的 API 参考 ([#554](https://github.com/adap/flower/pull/554))" #: ../../source/ref-changelog.md:962 msgid "" -"Updated examples documentation " -"([#549](https://github.com/adap/flower/pull/549))" +"Updated examples documentation ([#549](https://github.com/adap/flower/" +"pull/549))" msgstr "更新了示例文档 ([#549](https://github.com/adap/flower/pull/549))" #: ../../source/ref-changelog.md:963 msgid "" -"Removed obsolete documentation " -"([#548](https://github.com/adap/flower/pull/548))" +"Removed obsolete documentation ([#548](https://github.com/adap/flower/" +"pull/548))" msgstr "删除了过时的文档 ([#548](https://github.com/adap/flower/pull/548))" #: ../../source/ref-changelog.md:965 @@ -19061,13 +19184,12 @@ msgstr "错误修正:" #: ../../source/ref-changelog.md:967 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the" -" clients is now handled in `flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." +"`Server.fit` does not disconnect clients when finished, disconnecting the " +"clients is now handled in `flwr.server.start_server` ([#553](https://github." +"com/adap/flower/pull/553) [#540](https://github.com/adap/flower/issues/540))." msgstr "" -"Server.fit \"完成后不会断开客户端连接,现在断开客户端连接是在 \"flwr.server.start_server " -"\"中处理的([#553](https://github.com/adap/flower/pull/553) " +"Server.fit \"完成后不会断开客户端连接,现在断开客户端连接是在 \"flwr.server." +"start_server \"中处理的([#553](https://github.com/adap/flower/pull/553) " "[#540](https://github.com/adap/flower/issues/540))。" #: ../../source/ref-changelog.md:969 @@ -19080,30 +19202,29 @@ msgstr "重要变更:" #: ../../source/ref-changelog.md:973 msgid "" -"Added an example for embedded devices " -"([#507](https://github.com/adap/flower/pull/507))" +"Added an example for embedded devices ([#507](https://github.com/adap/flower/" +"pull/507))" msgstr "添加了嵌入式设备示例 ([#507](https://github.com/adap/flower/pull/507))" #: ../../source/ref-changelog.md:974 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +"Added a new NumPyClient (in addition to the existing KerasClient) ([#504]" +"(https://github.com/adap/flower/pull/504) [#508](https://github.com/adap/" +"flower/pull/508))" msgstr "" -"添加了一个新的 NumPyClient(除现有的 KerasClient " -"之外)([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508)" +"添加了一个新的 NumPyClient(除现有的 KerasClient 之外)([#504](https://" +"github.com/adap/flower/pull/504) [#508](https://github.com/adap/flower/" +"pull/508)" #: ../../source/ref-changelog.md:975 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into " -"the top-level `examples` directory " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +"Deprecated `flwr_example` package and started to migrate examples into the " +"top-level `examples` directory ([#494](https://github.com/adap/flower/" +"pull/494) [#512](https://github.com/adap/flower/pull/512))" msgstr "" -"弃用 `flwr_example` 软件包,并开始将示例迁移到顶层的 `examples` 目录 " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +"弃用 `flwr_example` 软件包,并开始将示例迁移到顶层的 `examples` 目录 ([#494]" +"(https://github.com/adap/flower/pull/494) [#512](https://github.com/adap/" +"flower/pull/512))" #: ../../source/ref-changelog.md:977 msgid "v0.11.0 (2020-11-30)" @@ -19115,16 +19236,16 @@ msgstr "不兼容的更改:" #: ../../source/ref-changelog.md:981 msgid "" -"Renamed strategy methods " -"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " -"Flower's public APIs. Other public methods/functions (e.g., every method " -"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " -"which is why we're removing it from the four methods in Strategy. To " -"migrate rename the following `Strategy` methods accordingly:" +"Renamed strategy methods ([#486](https://github.com/adap/flower/pull/486)) " +"to unify the naming of Flower's public APIs. Other public methods/functions " +"(e.g., every method in `Client`, but also `Strategy.evaluate`) do not use " +"the `on_` prefix, which is why we're removing it from the four methods in " +"Strategy. To migrate rename the following `Strategy` methods accordingly:" msgstr "" -"重命名了策略方法([#486](https://github.com/adap/flower/pull/486)),以统一 Flower公共 " -"API 的命名。其他公共方法/函数(例如 `Client` 中的每个方法,以及 `Strategy.evaluate`)不使用 `on_` " -"前缀,这就是我们从 Strategy 中的四个方法中移除它的原因。迁移时,请相应地重命名以下 `Strategy` 方法:" +"重命名了策略方法([#486](https://github.com/adap/flower/pull/486)),以统一 " +"Flower公共 API 的命名。其他公共方法/函数(例如 `Client` 中的每个方法,以及 " +"`Strategy.evaluate`)不使用 `on_` 前缀,这就是我们从 Strategy 中的四个方法中" +"移除它的原因。迁移时,请相应地重命名以下 `Strategy` 方法:" #: ../../source/ref-changelog.md:982 msgid "`on_configure_evaluate` => `configure_evaluate`" @@ -19144,42 +19265,42 @@ msgstr "`on_aggregate_fit` => `aggregate_fit`" #: ../../source/ref-changelog.md:989 msgid "" -"Deprecated `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). To migrate use " -"`FedAvg` instead." +"Deprecated `DefaultStrategy` ([#479](https://github.com/adap/flower/" +"pull/479)). To migrate use `FedAvg` instead." msgstr "" -"已废弃的 `DefaultStrategy` ([#479](https://github.com/adap/flower/pull/479)) " -"。迁移时请使用 `FedAvg`。" +"已废弃的 `DefaultStrategy` ([#479](https://github.com/adap/flower/" +"pull/479)) 。迁移时请使用 `FedAvg`。" #: ../../source/ref-changelog.md:990 msgid "" -"Simplified examples and baselines " -"([#484](https://github.com/adap/flower/pull/484))." -msgstr "简化示例和baselines([#484](https://github.com/adap/flower/pull/484))。" +"Simplified examples and baselines ([#484](https://github.com/adap/flower/" +"pull/484))." +msgstr "" +"简化示例和baselines([#484](https://github.com/adap/flower/pull/484))。" #: ../../source/ref-changelog.md:991 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface " -"([#483](https://github.com/adap/flower/pull/483))." +"Removed presently unused `on_conclude_round` from strategy interface ([#483]" +"(https://github.com/adap/flower/pull/483))." msgstr "" -"删除了策略界面中目前未使用的 " -"\"on_conclude_round\"([#483](https://github.com/adap/flower/pull/483))。" +"删除了策略界面中目前未使用的 \"on_conclude_round\"([#483](https://github." +"com/adap/flower/pull/483))。" #: ../../source/ref-changelog.md:992 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"Set minimal Python version to 3.6.1 instead of 3.6.9 ([#471](https://github." +"com/adap/flower/pull/471))." msgstr "" -"将最小 Python 版本设为 3.6.1,而不是 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"将最小 Python 版本设为 3.6.1,而不是 3.6.9 ([#471](https://github.com/adap/" +"flower/pull/471))." #: ../../source/ref-changelog.md:993 msgid "" -"Improved `Strategy` docstrings " -"([#470](https://github.com/adap/flower/pull/470))." +"Improved `Strategy` docstrings ([#470](https://github.com/adap/flower/" +"pull/470))." msgstr "" -"改进了 `Strategy` " -"docstrings([#470](https://github.com/adap/flower/pull/470))。" +"改进了 `Strategy` docstrings([#470](https://github.com/adap/flower/" +"pull/470))。" #: ../../source/ref-example-projects.rst:2 msgid "Example projects" @@ -19187,15 +19308,15 @@ msgstr "项目实例" #: ../../source/ref-example-projects.rst:4 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate " -"how Flower can be used to federate different kinds of existing machine " -"learning pipelines, usually leveraging popular machine learning " -"frameworks such as `PyTorch `_ or `TensorFlow " -"`_." +"Flower comes with a number of usage examples. The examples demonstrate how " +"Flower can be used to federate different kinds of existing machine learning " +"pipelines, usually leveraging popular machine learning frameworks such as " +"`PyTorch `_ or `TensorFlow `_." msgstr "" -"Flower 附带了许多使用示例。这些示例演示了如何使用 Flower 联邦不同类型的现有机器学习形式,通常是利用流行的机器学习框架,如 " -"`PyTorch `_ 或 `TensorFlow " -"`_。" +"Flower 附带了许多使用示例。这些示例演示了如何使用 Flower 联邦不同类型的现有机" +"器学习形式,通常是利用流行的机器学习框架,如 `PyTorch `_ 或 `TensorFlow `_。" #: ../../source/ref-example-projects.rst:10 #, fuzzy @@ -19206,30 +19327,32 @@ msgstr "以下示例可作为独立项目使用。" #: ../../source/ref-example-projects.rst:14 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image " -"classification with MobileNetV2:" -msgstr "TensorFlow/Keras 快速入门示例展示了使用 MobileNetV2 进行的 CIFAR-10 图像分类:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image classification " +"with MobileNetV2:" +msgstr "" +"TensorFlow/Keras 快速入门示例展示了使用 MobileNetV2 进行的 CIFAR-10 图像分" +"类:" #: ../../source/ref-example-projects.rst:17 msgid "" -"`Quickstart TensorFlow (Code) " -"`_" +"`Quickstart TensorFlow (Code) `_" msgstr "" -"`TensorFlow快速入门 (代码) `_" +"`TensorFlow快速入门 (代码) `_" #: ../../source/ref-example-projects.rst:18 #, fuzzy -msgid ":doc:`Quickstart TensorFlow (Tutorial) `" +msgid "" +":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" "`TensorFlow快速入门 (教程) `_" #: ../../source/ref-example-projects.rst:19 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" "`TensorFlow快速入门 (博客) `_" @@ -19241,24 +19364,25 @@ msgstr "PyTorch快速入门" #: ../../source/ref-example-projects.rst:25 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a" -" simple Convolutional Neural Network:" -msgstr "PyTorch 快速入门范例展示了使用简单卷积神经网络进行 CIFAR-10 图像分类的情况:" +"The PyTorch quickstart example shows CIFAR-10 image classification with a " +"simple Convolutional Neural Network:" +msgstr "" +"PyTorch 快速入门范例展示了使用简单卷积神经网络进行 CIFAR-10 图像分类的情况:" #: ../../source/ref-example-projects.rst:28 msgid "" -"`Quickstart PyTorch (Code) " -"`_" +"`Quickstart PyTorch (Code) `_" msgstr "" -"`PyTorch快速入门 (代码) `_" +"`PyTorch快速入门 (代码) `_" #: ../../source/ref-example-projects.rst:29 #, fuzzy msgid ":doc:`Quickstart PyTorch (Tutorial) `" msgstr "" -"`PyTorch快速入门 (教程) `_" +"`PyTorch快速入门 (教程) `_" #: ../../source/ref-example-projects.rst:33 msgid "PyTorch: From Centralized To Federated" @@ -19272,12 +19396,11 @@ msgstr "本例展示了如何使用 Flower 联邦化一个普通的 PyTorch 项 #: ../../source/ref-example-projects.rst:37 msgid "" -"`PyTorch: From Centralized To Federated (Code) " -"`_" +"`PyTorch: From Centralized To Federated (Code) `_" msgstr "" -"PyTorch: 从集中式到联邦式(代码) `_" +"PyTorch: 从集中式到联邦式(代码) `_" #: ../../source/ref-example-projects.rst:38 #, fuzzy @@ -19285,8 +19408,8 @@ msgid "" ":doc:`PyTorch: From Centralized To Federated (Tutorial) `" msgstr "" -"PyTorch: 从集中式到联邦式(教程) `_" +"PyTorch: 从集中式到联邦式(教程) `_" #: ../../source/ref-example-projects.rst:42 msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" @@ -19296,23 +19419,27 @@ msgstr "树莓派和 Nvidia Jetson 上的联邦学习" msgid "" "This example shows how Flower can be used to build a federated learning " "system that run across Raspberry Pi and Nvidia Jetson:" -msgstr "本示例展示了如何利用 Flower 建立一个跨 Raspberry Pi 和 Nvidia Jetson 运行的联邦学习系统:" +msgstr "" +"本示例展示了如何利用 Flower 建立一个跨 Raspberry Pi 和 Nvidia Jetson 运行的联" +"邦学习系统:" #: ../../source/ref-example-projects.rst:46 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) `_" msgstr "" -"Raspberry Pi 和 Nvidia Jetson 上的联邦学习(代码) " -"`_" +"Raspberry Pi 和 Nvidia Jetson 上的联邦学习(代码) `_" #: ../../source/ref-example-projects.rst:47 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) `_" msgstr "" -"Raspberry Pi和 Nvidia Jetson 上的联邦学习(博客) " -"`_" +"Raspberry Pi和 Nvidia Jetson 上的联邦学习(博客) `_" #: ../../source/ref-faq.rst:4 msgid "" @@ -19323,33 +19450,32 @@ msgstr "本页收集了有关 \"Flower 联邦学习 \"常见问题的答案。" #: ../../source/ref-faq.rst #, fuzzy msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" -msgstr ":fa:`eye,mr-1` Flower 可以在 Juptyter Notebooks / Google Colab 上运行吗?" +msgstr "" +":fa:`eye,mr-1` Flower 可以在 Juptyter Notebooks / Google Colab 上运行吗?" #: ../../source/ref-faq.rst:8 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to" -" make it work even better on Colab. Here's a quickstart example:" -msgstr "是的,它可以!Flower 甚至还进行了一些底层优化,使其在 Colab 上运行得更好。下面是一个快速启动示例:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to " +"make it work even better on Colab. Here's a quickstart example:" +msgstr "" +"是的,它可以!Flower 甚至还进行了一些底层优化,使其在 Colab 上运行得更好。下" +"面是一个快速启动示例:" #: ../../source/ref-faq.rst:10 msgid "" -"`Flower simulation PyTorch " -"`_" +"`Flower simulation PyTorch `_" msgstr "" -"`Flower 模拟 PyTorch " -"`_" +"`Flower 模拟 PyTorch `_" #: ../../source/ref-faq.rst:11 msgid "" -"`Flower simulation TensorFlow/Keras " -"`_" +"`Flower simulation TensorFlow/Keras `_" msgstr "" -"`Flower模拟TensorFlow/Keras " -"`_" +"`Flower模拟TensorFlow/Keras `_" #: ../../source/ref-faq.rst msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" @@ -19358,33 +19484,37 @@ msgstr ":fa:`eye,mr-1` 如何在 Raspberry Pi 上运行联邦学习?" #: ../../source/ref-faq.rst:15 msgid "" "Find the `blog post about federated learning on embedded device here " -"`_" -" and the corresponding `GitHub code example " -"`_." +"`_ " +"and the corresponding `GitHub code example `_." msgstr "" -"请点击此处查看有关嵌入式设备联邦学习的 " -"\"博文\"`_和相应的" -" \"GitHub 代码示例\"`_。" +"请点击此处查看有关嵌入式设备联邦学习的 \"博文\"`_和" +"相应的 \"GitHub 代码示例\"`_。" #: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgid "" +":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr ":fa:`eye,mr-1` Flower 是否支持安卓设备上的联邦学习?" #: ../../source/ref-faq.rst:19 msgid "" -"Yes, it does. Please take a look at our `blog post " -"`_ or check out the code examples:" +"Yes, it does. Please take a look at our `blog post `_ or " +"check out the code examples:" msgstr "" -"是的,确实如此。请查看我们的 \"博客文章 `_\" 或查看代码示例:" +"是的,确实如此。请查看我们的 \"博客文章 `_\" 或查看代码示例:" #: ../../source/ref-faq.rst:21 msgid "" -"`Android Kotlin example `_" -msgstr "`Android Kotlin 示例 `_" +"`Android Kotlin example `_" +msgstr "" +"`Android Kotlin 示例 `_" #: ../../source/ref-faq.rst:22 msgid "`Android Java example `_" @@ -19402,46 +19532,46 @@ msgstr "当然可以。有关在区块链环境中使用 Flower 的可用示例 #: ../../source/ref-faq.rst:28 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." #: ../../source/ref-faq.rst:29 msgid "" -"`Flower meets Nevermined YouTube video " -"`_." +"`Flower meets Nevermined YouTube video `_." msgstr "" -"`Flower meets Nevermined YouTube 视频 " -"`_." +"`Flower meets Nevermined YouTube 视频 `_." #: ../../source/ref-faq.rst:30 #, fuzzy msgid "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." msgstr "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." #: ../../source/ref-faq.rst:31 msgid "" "`Flower meets Talan blog post `_ ." +"learning-same-mask-different-faces-imen-ayari/?" +"trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ ." msgstr "" "`Flower meets Talan博文 `_ 。" +"same-mask-different-faces-imen-ayari/?" +"trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ 。" #: ../../source/ref-faq.rst:32 msgid "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"`Flower meets Talan GitHub Repository `_ ." msgstr "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"`Flower meets Talan GitHub Repository `_ ." #: ../../source/ref-telemetry.md:1 msgid "Telemetry" @@ -19449,60 +19579,64 @@ msgstr "遥测功能" #: ../../source/ref-telemetry.md:3 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to " -"make well-informed decisions to improve Flower. Doing this enables the " -"Flower team to understand how Flower is used and what challenges users " -"might face." +"The Flower open-source project collects **anonymous** usage metrics to make " +"well-informed decisions to improve Flower. Doing this enables the Flower " +"team to understand how Flower is used and what challenges users might face." msgstr "" -"Flower 开源项目收集**匿名**使用指标,以便在充分知情的情况下做出改进 Flower 的决定。这样做能让 Flower 团队了解 " -"Flower 的使用情况以及用户可能面临的挑战。" +"Flower 开源项目收集**匿名**使用指标,以便在充分知情的情况下做出改进 Flower 的" +"决定。这样做能让 Flower 团队了解 Flower 的使用情况以及用户可能面临的挑战。" #: ../../source/ref-telemetry.md:5 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users that do not want to share anonymous usage metrics." -msgstr "**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。" +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users that do not want to share anonymous usage metrics." +msgstr "" +"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声" +"明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。" #: ../../source/ref-telemetry.md:7 msgid "Principles" msgstr "原则" #: ../../source/ref-telemetry.md:9 -msgid "We follow strong principles guarding anonymous usage metrics collection:" +msgid "" +"We follow strong principles guarding anonymous usage metrics collection:" msgstr "我们遵循严格的匿名使用指标收集原则:" #: ../../source/ref-telemetry.md:11 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to " -"learn “[How to opt-out](#how-to-opt-out)”." -msgstr "**可选:** 您始终可以禁用遥测功能;请继续阅读\"[如何退出](#how-to-opt-out)\"。" +"**Optional:** You will always be able to disable telemetry; read on to learn " +"“[How to opt-out](#how-to-opt-out)”." +msgstr "" +"**可选:** 您始终可以禁用遥测功能;请继续阅读\"[如何退出](#how-to-opt-" +"out)\"。" #: ../../source/ref-telemetry.md:12 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not " -"contain any personally identifiable information (PII). See “[Collected " -"metrics](#collected-metrics)” to understand what metrics are being " -"reported." +"**Anonymous:** The reported usage metrics are anonymous and do not contain " +"any personally identifiable information (PII). See “[Collected metrics]" +"(#collected-metrics)” to understand what metrics are being reported." msgstr "" -"**匿名:** 报告的使用指标是匿名的,不包含任何个人身份信息 (PII)。请参阅\"[收集的指标](#collected-metrics) " -"\"了解报告的指标。" +"**匿名:** 报告的使用指标是匿名的,不包含任何个人身份信息 (PII)。请参阅\"[收" +"集的指标](#collected-metrics) \"了解报告的指标。" #: ../../source/ref-telemetry.md:13 msgid "" "**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-" -"to-inspect-what-is-being-reported)”" +"reported; see the section “[How to inspect what is being reported](#how-to-" +"inspect-what-is-being-reported)”" msgstr "" -"**透明:** 您可以轻松查看正在报告的匿名指标;请参阅\"[如何查看正在报告的指标](#how-to-inspect-what-is-" -"being-reported)\"部分" +"**透明:** 您可以轻松查看正在报告的匿名指标;请参阅\"[如何查看正在报告的指标]" +"(#how-to-inspect-what-is-being-reported)\"部分" #: ../../source/ref-telemetry.md:14 msgid "" -"**Open for feedback:** You can always reach out to us if you have " -"feedback; see the section “[How to contact us](#how-to-contact-us)” for " -"details." -msgstr "**欢迎反馈:** 如果您有反馈意见,可以随时联系我们;详情请参见\"[如何联系我们](#how-to-contact-us) \"部分。" +"**Open for feedback:** You can always reach out to us if you have feedback; " +"see the section “[How to contact us](#how-to-contact-us)” for details." +msgstr "" +"**欢迎反馈:** 如果您有反馈意见,可以随时联系我们;详情请参见\"[如何联系我们]" +"(#how-to-contact-us) \"部分。" #: ../../source/ref-telemetry.md:16 msgid "How to opt-out" @@ -19516,17 +19650,17 @@ msgid "" "client, simply do so by prepending your command as in:" msgstr "" "Flower 启动时,会检查环境变量 `FLWR_TELEMETRY_ENABLED` 是否存在。通过设置 " -"`FLWR_TELEMETRY_ENABLED=0` 可以轻松禁用遥测功能。假设你启动的是 Flower " -"服务器或客户端,只需在命令前添加以下内容即可:" +"`FLWR_TELEMETRY_ENABLED=0` 可以轻松禁用遥测功能。假设你启动的是 Flower 服务器" +"或客户端,只需在命令前添加以下内容即可:" #: ../../source/ref-telemetry.md:24 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," -" `.bashrc` (or whatever configuration file applies to your environment) " -"to disable Flower telemetry permanently." +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `." +"bashrc` (or whatever configuration file applies to your environment) to " +"disable Flower telemetry permanently." msgstr "" -"或者,你也可以在 `.bashrc`(或任何适用于你的环境的配置文件)中导出 `FLWR_TELEMETRY_ENABLED=0` 来永久禁用 " -"Flower telemetry。" +"或者,你也可以在 `.bashrc`(或任何适用于你的环境的配置文件)中导出 " +"`FLWR_TELEMETRY_ENABLED=0` 来永久禁用 Flower telemetry。" #: ../../source/ref-telemetry.md:26 msgid "Collected metrics" @@ -19538,17 +19672,21 @@ msgstr "Flower 遥测技术收集以下指标:" #: ../../source/ref-telemetry.md:30 msgid "" -"**Flower version.** Understand which versions of Flower are currently " -"being used. This helps us to decide whether we should invest effort into " -"releasing a patch version for an older version of Flower or instead use " -"the bandwidth to build new features." -msgstr "**了解目前使用的 Flower 版本。这有助于我们决定是否应该投入精力为旧版本的 Flower 发布补丁版本,还是利用带宽来构建新功能。" +"**Flower version.** Understand which versions of Flower are currently being " +"used. This helps us to decide whether we should invest effort into releasing " +"a patch version for an older version of Flower or instead use the bandwidth " +"to build new features." +msgstr "" +"**了解目前使用的 Flower 版本。这有助于我们决定是否应该投入精力为旧版本的 " +"Flower 发布补丁版本,还是利用带宽来构建新功能。" #: ../../source/ref-telemetry.md:32 msgid "" "**Operating system.** Enables us to answer questions such as: *Should we " "create more guides for Linux, macOS, or Windows?*" -msgstr "**操作系统**使我们能够回答以下问题: *我们应该为 Linux、macOS 还是 Windows 创建更多指南?*" +msgstr "" +"**操作系统**使我们能够回答以下问题: *我们应该为 Linux、macOS 还是 Windows 创" +"建更多指南?*" #: ../../source/ref-telemetry.md:34 msgid "" @@ -19556,73 +19694,82 @@ msgid "" "decide whether we should invest effort into supporting old versions of " "Python or stop supporting them and start taking advantage of new Python " "features." -msgstr "**例如,了解 Python 版本有助于我们决定是否应该投入精力支持旧版本的 Python,还是停止支持这些版本并开始利用新的 Python 功能。" +msgstr "" +"**例如,了解 Python 版本有助于我们决定是否应该投入精力支持旧版本的 Python,还" +"是停止支持这些版本并开始利用新的 Python 功能。" #: ../../source/ref-telemetry.md:36 msgid "" -"**Hardware properties.** Understanding the hardware environment that " -"Flower is being used in helps to decide whether we should, for example, " -"put more effort into supporting low-resource environments." -msgstr "**硬件属性** 了解 Flower 的硬件使用环境,有助于决定我们是否应在支持低资源环境等方面投入更多精力。" +"**Hardware properties.** Understanding the hardware environment that Flower " +"is being used in helps to decide whether we should, for example, put more " +"effort into supporting low-resource environments." +msgstr "" +"**硬件属性** 了解 Flower 的硬件使用环境,有助于决定我们是否应在支持低资源环境" +"等方面投入更多精力。" #: ../../source/ref-telemetry.md:38 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables " -"us to understand how heavily certain features are being used and better " +"**Execution mode.** Knowing what execution mode Flower starts in enables us " +"to understand how heavily certain features are being used and better " "prioritize based on that." -msgstr "** 执行模式** 了解 Flower 的启动执行模式,能让我们了解某些功能的使用率,并据此更好地确定优先级。" +msgstr "" +"** 执行模式** 了解 Flower 的启动执行模式,能让我们了解某些功能的使用率,并据" +"此更好地确定优先级。" #: ../../source/ref-telemetry.md:40 msgid "" "**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " "time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete " -"them." +"types not only start Flower workloads but also successfully complete them." msgstr "" -"**每次 Flower 工作负载启动时,Flower 遥测都会随机分配一个内存集群 ID。这样,我们就能了解哪些设备类型不仅启动了 Flower " -"工作负载,而且还成功完成了它们。" +"**每次 Flower 工作负载启动时,Flower 遥测都会随机分配一个内存集群 ID。这样," +"我们就能了解哪些设备类型不仅启动了 Flower 工作负载,而且还成功完成了它们。" #: ../../source/ref-telemetry.md:42 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in " -"`~/.flwr/source` the first time a telemetry event is generated. The " -"source ID is important to identify whether an issue is recurring or " -"whether an issue is triggered by multiple clusters running concurrently " -"(which often happens in simulation). For example, if a device runs " -"multiple workloads at the same time, and this results in an issue, then, " -"in order to reproduce the issue, multiple workloads must be started at " -"the same time." +"**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/" +"source` the first time a telemetry event is generated. The source ID is " +"important to identify whether an issue is recurring or whether an issue is " +"triggered by multiple clusters running concurrently (which often happens in " +"simulation). For example, if a device runs multiple workloads at the same " +"time, and this results in an issue, then, in order to reproduce the issue, " +"multiple workloads must be started at the same time." msgstr "" -"**Source.** Flower 遥测会在第一次生成遥测事件时,尝试在 `~/.flwr/source` 中存储一个随机源 ID。源 ID " -"对于识别问题是否反复出现或问题是否由多个集群同时运行触发(这在模拟中经常发生)非常重要。例如,如果设备同时运行多个工作负载并导致问题,那么为了重现问题,必须同时启动多个工作负载。" +"**Source.** Flower 遥测会在第一次生成遥测事件时,尝试在 `~/.flwr/source` 中存" +"储一个随机源 ID。源 ID 对于识别问题是否反复出现或问题是否由多个集群同时运行触" +"发(这在模拟中经常发生)非常重要。例如,如果设备同时运行多个工作负载并导致问" +"题,那么为了重现问题,必须同时启动多个工作负载。" #: ../../source/ref-telemetry.md:44 msgid "" -"You may delete the source ID at any time. If you wish for all events " -"logged under a specific source ID to be deleted, you can send a deletion " -"request mentioning the source ID to `telemetry@flower.ai`. All events " -"related to that source ID will then be permanently deleted." +"You may delete the source ID at any time. If you wish for all events logged " +"under a specific source ID to be deleted, you can send a deletion request " +"mentioning the source ID to `telemetry@flower.ai`. All events related to " +"that source ID will then be permanently deleted." msgstr "" -"您可以随时删除源 ID。如果您希望删除特定源 ID 下记录的所有事件,可以向 `telemetry@flower.ai` 发送删除请求,并提及该源" -" ID。届时,与该源 ID 相关的所有事件都将被永久删除。" +"您可以随时删除源 ID。如果您希望删除特定源 ID 下记录的所有事件,可以向 " +"`telemetry@flower.ai` 发送删除请求,并提及该源 ID。届时,与该源 ID 相关的所有" +"事件都将被永久删除。" #: ../../source/ref-telemetry.md:46 msgid "" -"We will not collect any personally identifiable information. If you think" -" any of the metrics collected could be misused in any way, please [get in" -" touch with us](#how-to-contact-us). We will update this page to reflect " -"any changes to the metrics collected and publish changes in the " -"changelog." +"We will not collect any personally identifiable information. If you think " +"any of the metrics collected could be misused in any way, please [get in " +"touch with us](#how-to-contact-us). We will update this page to reflect any " +"changes to the metrics collected and publish changes in the changelog." msgstr "" -"我们不会收集任何个人身份信息。如果您认为所收集的任何指标可能以任何方式被滥用,请[与我们联系](#how-to-contact-" -"us)。我们将更新本页面,以反映对所收集指标的任何更改,并在更新日志中公布更改内容。" +"我们不会收集任何个人身份信息。如果您认为所收集的任何指标可能以任何方式被滥" +"用,请[与我们联系](#how-to-contact-us)。我们将更新本页面,以反映对所收集指" +"标的任何更改,并在更新日志中公布更改内容。" #: ../../source/ref-telemetry.md:48 msgid "" "If you think other metrics would be helpful for us to better guide our " "decisions, please let us know! We will carefully review them; if we are " "confident that they do not compromise user privacy, we may add them." -msgstr "如果您认为其他指标有助于我们更好地指导决策,请告诉我们!我们将仔细审查这些指标;如果我们确信它们不会损害用户隐私,我们可能会添加这些指标。" +msgstr "" +"如果您认为其他指标有助于我们更好地指导决策,请告诉我们!我们将仔细审查这些指" +"标;如果我们确信它们不会损害用户隐私,我们可能会添加这些指标。" #: ../../source/ref-telemetry.md:50 msgid "How to inspect what is being reported" @@ -19631,21 +19778,23 @@ msgstr "如何检查报告中的内容" #: ../../source/ref-telemetry.md:52 msgid "" "We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information" -" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " -"is disabled by default. You may use logging independently from " +"metrics are reported. You can view all the reported telemetry information by " +"setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is " +"disabled by default. You may use logging independently from " "`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " "without sending any metrics." msgstr "" -"我们希望能让您轻松查看所报告的匿名使用指标。通过设置环境变量 `FLWR_TELEMETRY_LOGGING=1` " -"可以查看所有报告的遥测信息。日志记录默认为禁用。您可以不使用 `FLWR_TELEMETRY_ENABLED` " -"而单独使用日志记录,这样就可以在不发送任何指标的情况下检查遥测功能。" +"我们希望能让您轻松查看所报告的匿名使用指标。通过设置环境变量 " +"`FLWR_TELEMETRY_LOGGING=1` 可以查看所有报告的遥测信息。日志记录默认为禁用。您" +"可以不使用 `FLWR_TELEMETRY_ENABLED` 而单独使用日志记录,这样就可以在不发送任" +"何指标的情况下检查遥测功能。" #: ../../source/ref-telemetry.md:58 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics," -" use both environment variables:" -msgstr "在不发送任何匿名使用指标的情况下检查 Flower 遥测,可使用这两个环境变量:" +"The inspect Flower telemetry without sending any anonymous usage metrics, " +"use both environment variables:" +msgstr "" +"在不发送任何匿名使用指标的情况下检查 Flower 遥测,可使用这两个环境变量:" #: ../../source/ref-telemetry.md:64 msgid "How to contact us" @@ -19658,14 +19807,16 @@ msgid "" "[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " "(`telemetry@flower.ai`)." msgstr "" -"我们希望听到您的意见。如果您对如何改进我们处理匿名使用指标的方式有任何反馈或想法,请通过 [Slack](https://flower.ai" -"/join-slack/) (频道 `#telemetry`)或电子邮件 (`telemetry@flower.ai`)与我们联系。" +"我们希望听到您的意见。如果您对如何改进我们处理匿名使用指标的方式有任何反馈或" +"想法,请通过 [Slack](https://flower.ai/join-slack/) (频道 `#telemetry`)或电" +"子邮件 (`telemetry@flower.ai`)与我们联系。" #: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android " -"app using Flower." -msgstr "阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 Android 应用程序。" +"Read this Federated Learning quickstart tutorial for creating an Android app " +"using Flower." +msgstr "" +"阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 Android 应用程序。" #: ../../source/tutorial-quickstart-android.rst:5 msgid "Quickstart Android" @@ -19673,24 +19824,24 @@ msgstr "快速入门 Android" #: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"Let's build a federated learning system using TFLite and Flower on " -"Android!" +"Let's build a federated learning system using TFLite and Flower on Android!" msgstr "让我们在 Android 上使用 TFLite 和 Flower 构建一个联邦学习系统!" #: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn " -"more." +"Please refer to the `full code example `_ to learn more." msgstr "" -"请参阅`完整代码示例 " -"`_了解更多信息。" +"请参阅`完整代码示例 `_了解更多信息。" #: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with FastAI to train a vision model on CIFAR-10." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 FastAI 在 CIFAR-10 上训练视觉模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"FastAI to train a vision model on CIFAR-10." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 FastAI 在 CIFAR-10 上训练" +"视觉模型。" #: ../../source/tutorial-quickstart-fastai.rst:5 msgid "Quickstart fastai" @@ -19702,18 +19853,19 @@ msgstr "让我们用 fastai 和 Flower 建立一个联邦学习系统!" #: ../../source/tutorial-quickstart-fastai.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" -"请参阅 `完整代码示例 `_了解更多信息。" +"请参阅 `完整代码示例 `_了解更多信息。" #: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower " -"with HuggingFace Transformers in order to fine-tune an LLM." -msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 HuggingFace Transformers 来微调 LLM。" +"Check out this Federating Learning quickstart tutorial for using Flower with " +"HuggingFace Transformers in order to fine-tune an LLM." +msgstr "" +"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 HuggingFace Transformers " +"来微调 LLM。" #: ../../source/tutorial-quickstart-huggingface.rst:5 msgid "Quickstart 🤗 Transformers" @@ -19721,20 +19873,21 @@ msgstr "🤗 Transformers快速入门" #: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Let's build a federated learning system using Hugging Face Transformers " -"and Flower!" +"Let's build a federated learning system using Hugging Face Transformers and " +"Flower!" msgstr "让我们用Hugging Face Transformers和Flower来构建一个联邦学习系统!" #: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"We will leverage Hugging Face to federate the training of language models" -" over multiple clients using Flower. More specifically, we will fine-tune" -" a pre-trained Transformer model (distilBERT) for sequence classification" -" over a dataset of IMDB ratings. The end goal is to detect if a movie " -"rating is positive or negative." +"We will leverage Hugging Face to federate the training of language models " +"over multiple clients using Flower. More specifically, we will fine-tune a " +"pre-trained Transformer model (distilBERT) for sequence classification over " +"a dataset of IMDB ratings. The end goal is to detect if a movie rating is " +"positive or negative." msgstr "" -"我们将利用Hugging Face技术,使用 Flower 在多个客户端上联邦训练语言模型。更具体地说,我们将对预先训练好的 " -"Transformer 模型(distilBERT)进行微调,以便在 IMDB 评分数据集上进行序列分类。最终目标是检测电影评分是正面还是负面。" +"我们将利用Hugging Face技术,使用 Flower 在多个客户端上联邦训练语言模型。更具" +"体地说,我们将对预先训练好的 Transformer 模型(distilBERT)进行微调,以便在 " +"IMDB 评分数据集上进行序列分类。最终目标是检测电影评分是正面还是负面。" #: ../../source/tutorial-quickstart-huggingface.rst:18 msgid "Dependencies" @@ -19743,12 +19896,12 @@ msgstr "依赖关系" #: ../../source/tutorial-quickstart-huggingface.rst:20 msgid "" "To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " -":code:`torch`, and :code:`transformers`. This can be done using " -":code:`pip`:" +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, " +"and :code:`transformers`. This can be done using :code:`pip`:" msgstr "" -"要学习本教程,您需要安装以下软件包: :code:`datasets`、 :code:`evaluate`、 :code:`flwr`、 " -":code:`torch`和 :code:`transformers`。这可以通过 :code:`pip` 来完成:" +"要学习本教程,您需要安装以下软件包: :code:`datasets`、 :code:`evaluate`、 :" +"code:`flwr`、 :code:`torch`和 :code:`transformers`。这可以通过 :code:`pip` 来" +"完成:" #: ../../source/tutorial-quickstart-huggingface.rst:30 msgid "Standard Hugging Face workflow" @@ -19764,8 +19917,9 @@ msgid "" "library. We then need to tokenize the data and create :code:`PyTorch` " "dataloaders, this is all done in the :code:`load_data` function:" msgstr "" -"为了获取 IMDB 数据集,我们将使用 Hugging Face 的 :code:`datasets` 库。然后,我们需要对数据进行标记化,并创建" -" :code:`PyTorch` 数据加载器,这些都将在 :code:`load_data` 函数中完成:" +"为了获取 IMDB 数据集,我们将使用 Hugging Face 的 :code:`datasets` 库。然后," +"我们需要对数据进行标记化,并创建 :code:`PyTorch` 数据加载器,这些都将在 :" +"code:`load_data` 函数中完成:" #: ../../source/tutorial-quickstart-huggingface.rst:81 msgid "Training and testing the model" @@ -19773,12 +19927,12 @@ msgstr "训练和测试模型" #: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"Once we have a way of creating our trainloader and testloader, we can " -"take care of the training and testing. This is very similar to any " -":code:`PyTorch` training or testing loop:" +"Once we have a way of creating our trainloader and testloader, we can take " +"care of the training and testing. This is very similar to any :code:" +"`PyTorch` training or testing loop:" msgstr "" -"有了创建 trainloader 和 testloader 的方法后,我们就可以进行训练和测试了。这与任何 :code:`PyTorch` " -"训练或测试循环都非常相似:" +"有了创建 trainloader 和 testloader 的方法后,我们就可以进行训练和测试了。这与" +"任何 :code:`PyTorch` 训练或测试循环都非常相似:" #: ../../source/tutorial-quickstart-huggingface.rst:121 msgid "Creating the model itself" @@ -19786,11 +19940,11 @@ msgstr "创建模型本身" #: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT" -" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"To create the model itself, we will just load the pre-trained distillBERT " +"model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" -"要创建模型本身,我们只需使用 Hugging Face 的 :code:`AutoModelForSequenceClassification` " -"加载预训练的 distillBERT 模型:" +"要创建模型本身,我们只需使用 Hugging Face 的 :code:" +"`AutoModelForSequenceClassification` 加载预训练的 distillBERT 模型:" #: ../../source/tutorial-quickstart-huggingface.rst:136 msgid "Federating the example" @@ -19803,23 +19957,24 @@ msgstr "创建 IMDBClient" #: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" "To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " -"This is very easy, as our model is a standard :code:`PyTorch` model:" +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). This " +"is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" -"要将我们的示例联邦到多个客户端,我们首先需要编写 Flower 客户端类(继承自 " -":code:`flwr.client.NumPyClient`)。这很容易,因为我们的模型是一个标准的 :code:`PyTorch` 模型:" +"要将我们的示例联邦到多个客户端,我们首先需要编写 Flower 客户端类(继承自 :" +"code:`flwr.client.NumPyClient`)。这很容易,因为我们的模型是一个标准的 :code:" +"`PyTorch` 模型:" #: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" "The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the " -"server to send its parameters to the client. Finally, the :code:`fit` " -"function trains the model locally for the client, and the " -":code:`evaluate` function tests the model locally and returns the " -"relevant metrics." +"parameters. Inversely, the :code:`set_parameters` function allows the server " +"to send its parameters to the client. Finally, the :code:`fit` function " +"trains the model locally for the client, and the :code:`evaluate` function " +"tests the model locally and returns the relevant metrics." msgstr "" -":code:`get_parameters` " -"函数允许服务器获取客户端的参数。相反,:code:`set_parameters`函数允许服务器将其参数发送给客户端。最后,:code:`fit`函数在本地为客户端训练模型,:code:`evaluate`函数在本地测试模型并返回相关指标。" +":code:`get_parameters` 函数允许服务器获取客户端的参数。相反,:code:" +"`set_parameters`函数允许服务器将其参数发送给客户端。最后,:code:`fit`函数在本" +"地为客户端训练模型,:code:`evaluate`函数在本地测试模型并返回相关指标。" #: ../../source/tutorial-quickstart-huggingface.rst:175 msgid "Starting the server" @@ -19827,25 +19982,26 @@ msgstr "启动服务器" #: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Now that we have a way to instantiate clients, we need to create our " -"server in order to aggregate the results. Using Flower, this can be done " -"very easily by first choosing a strategy (here, we are using " -":code:`FedAvg`, which will define the global weights as the average of " -"all the clients' weights at each round) and then using the " -":code:`flwr.server.start_server` function:" +"Now that we have a way to instantiate clients, we need to create our server " +"in order to aggregate the results. Using Flower, this can be done very " +"easily by first choosing a strategy (here, we are using :code:`FedAvg`, " +"which will define the global weights as the average of all the clients' " +"weights at each round) and then using the :code:`flwr.server.start_server` " +"function:" msgstr "" -"现在我们有了实例化客户端的方法,我们需要创建服务器,以便汇总结果。使用 Flower,首先选择一个策略(这里我们使用 " -":code:`FedAvg`,它将把全局模型参数定义为每轮所有客户端模型参数的平均值),然后使用 " -":code:`flwr.server.start_server`函数,就可以非常轻松地完成这项工作:" +"现在我们有了实例化客户端的方法,我们需要创建服务器,以便汇总结果。使用 " +"Flower,首先选择一个策略(这里我们使用 :code:`FedAvg`,它将把全局模型参数定义" +"为每轮所有客户端模型参数的平均值),然后使用 :code:`flwr.server.start_server`" +"函数,就可以非常轻松地完成这项工作:" #: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"The :code:`weighted_average` function is there to provide a way to " -"aggregate the metrics distributed amongst the clients (basically this " -"allows us to display a nice average accuracy and loss for every round)." +"The :code:`weighted_average` function is there to provide a way to aggregate " +"the metrics distributed amongst the clients (basically this allows us to " +"display a nice average accuracy and loss for every round)." msgstr "" -"使用 :code:`weighted_average` " -"函数是为了提供一种方法来汇总分布在客户端的指标(基本上,这可以让我们显示每一轮的平均精度和损失值)。" +"使用 :code:`weighted_average` 函数是为了提供一种方法来汇总分布在客户端的指标" +"(基本上,这可以让我们显示每一轮的平均精度和损失值)。" #: ../../source/tutorial-quickstart-huggingface.rst:209 msgid "Putting everything together" @@ -19864,33 +20020,38 @@ msgstr "他们就能连接到服务器,开始联邦训练。" #: ../../source/tutorial-quickstart-huggingface.rst:223 #, fuzzy msgid "" -"If you want to check out everything put together, you should check out " -"the `full code example `_ ." +"If you want to check out everything put together, you should check out the " +"`full code example `_ ." msgstr "" -"如果您想查看所有内容,请查看完整的代码示例: [https://github.com/adap/flower/tree/main/examples" -"/quickstart-" -"huggingface](https://github.com/adap/flower/tree/main/examples" -"/quickstart-huggingface)." +"如果您想查看所有内容,请查看完整的代码示例: [https://github.com/adap/flower/" +"tree/main/examples/quickstart-huggingface](https://github.com/adap/flower/" +"tree/main/examples/quickstart-huggingface)." #: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Of course, this is a very basic example, and a lot can be added or " -"modified, it was just to showcase how simply we could federate a Hugging " -"Face workflow using Flower." -msgstr "当然,这只是一个非常基本的示例,还可以添加或修改很多内容,只是为了展示我们可以如何简单地使用 Flower 联合Hugging Face的工作流程。" +"Of course, this is a very basic example, and a lot can be added or modified, " +"it was just to showcase how simply we could federate a Hugging Face workflow " +"using Flower." +msgstr "" +"当然,这只是一个非常基本的示例,还可以添加或修改很多内容,只是为了展示我们可" +"以如何简单地使用 Flower 联合Hugging Face的工作流程。" #: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very" -" well used :code:`TensorFlow`." -msgstr "请注意,在本例中我们使用了 :code:`PyTorch`,但也完全可以使用 :code:`TensorFlow`。" +"Note that in this example we used :code:`PyTorch`, but we could have very " +"well used :code:`TensorFlow`." +msgstr "" +"请注意,在本例中我们使用了 :code:`PyTorch`,但也完全可以使用 :code:" +"`TensorFlow`。" #: ../../source/tutorial-quickstart-ios.rst:-1 msgid "" "Read this Federated Learning quickstart tutorial for creating an iOS app " "using Flower to train a neural network on MNIST." -msgstr "阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 iOS 应用程序,并在 MNIST 上训练神经网络。" +msgstr "" +"阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 iOS 应用程序,并在 " +"MNIST 上训练神经网络。" #: ../../source/tutorial-quickstart-ios.rst:5 msgid "Quickstart iOS" @@ -19898,43 +20059,52 @@ msgstr "快速入门 iOS" #: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST " -"using Flower and CoreML on iOS devices." -msgstr "在本教程中,我们将学习如何在 iOS 设备上使用 Flower 和 CoreML 在 MNIST 上训练神经网络。" +"In this tutorial we will learn how to train a Neural Network on MNIST using " +"Flower and CoreML on iOS devices." +msgstr "" +"在本教程中,我们将学习如何在 iOS 设备上使用 Flower 和 CoreML 在 MNIST 上训练" +"神经网络。" #: ../../source/tutorial-quickstart-ios.rst:12 #, fuzzy msgid "" "First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv" -" `. For the Flower client " +"create a virtual environment and run everything within a :doc:`virtualenv " +"`. For the Flower client " "implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" "首先,为了运行 Flower Python 服务器,建议创建一个虚拟环境,并在 `virtualenv " -"`_ 中运行一切。对于在 iOS 中实现 " -"Flower 客户端,建议使用 Xcode 作为我们的集成开发环境。" +"`_ 中运行一切。对于在 iOS " +"中实现 Flower 客户端,建议使用 Xcode 作为我们的集成开发环境。" #: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that" -" all have the same model." -msgstr "我们的示例包括一个 Python *服务器*和两个 iPhone *客户端*,它们都具有相同的模型。" +"Our example consists of one Python *server* and two iPhone *clients* that " +"all have the same model." +msgstr "" +"我们的示例包括一个 Python *服务器*和两个 iPhone *客户端*,它们都具有相同的模" +"型。" #: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"*Clients* are responsible for generating individual weight updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." -msgstr "*客户端*负责根据其本地数据集为模型生成独立的模型参数。然后,这些参数更新会被发送到*服务器*,由*服务器*汇总后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客户端*。一个完整的参数更新周期称为一*轮*。" +"*Clients* are responsible for generating individual weight updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." +msgstr "" +"*客户端*负责根据其本地数据集为模型生成独立的模型参数。然后,这些参数更新会被" +"发送到*服务器*,由*服务器*汇总后生成一个更好的模型。最后,*服务器*将改进后的" +"模型发送回每个*客户端*。一个完整的参数更新周期称为一*轮*。" #: ../../source/tutorial-quickstart-ios.rst:21 msgid "" "Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You" -" can do this by using pip:" -msgstr "现在我们已经有了一个大致的概念,让我们开始设置 Flower 服务器环境吧。首先,我们需要安装 Flower。你可以使用 pip 来安装:" +"setup our Flower server environment. We first need to install Flower. You " +"can do this by using pip:" +msgstr "" +"现在我们已经有了一个大致的概念,让我们开始设置 Flower 服务器环境吧。首先,我" +"们需要安装 Flower。你可以使用 pip 来安装:" #: ../../source/tutorial-quickstart-ios.rst:27 msgid "Or Poetry:" @@ -19952,29 +20122,29 @@ msgstr "Flower 客户端" #: ../../source/tutorial-quickstart-ios.rst:36 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and " -"MNIST as our dataset. For simplicity reasons we will use the complete " -"Flower client with CoreML, that has been implemented and stored inside " -"the Swift SDK. The client implementation can be seen below:" +"distributed training using CoreML as our local training pipeline and MNIST " +"as our dataset. For simplicity reasons we will use the complete Flower " +"client with CoreML, that has been implemented and stored inside the Swift " +"SDK. The client implementation can be seen below:" msgstr "" -"现在我们已经安装了所有依赖项,让我们使用 CoreML 作为本地训练框架和 MNIST " -"作为数据集,运行一个简单的分布式训练。为了简单起见,我们将使用 CoreML 的完整 Flower 客户端,该客户端已在 Swift SDK " -"中实现并存储。客户端实现如下:" +"现在我们已经安装了所有依赖项,让我们使用 CoreML 作为本地训练框架和 MNIST 作为" +"数据集,运行一个简单的分布式训练。为了简单起见,我们将使用 CoreML 的完整 " +"Flower 客户端,该客户端已在 Swift SDK 中实现并存储。客户端实现如下:" #: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a" -" dependency in your project. For our application, we will store the logic" -" of our app in :code:`FLiOSModel.swift` and the UI elements in " -":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" -" in this quickstart. Please refer to the `full code example " -"`_ to learn more " -"about the app." +"Let's create a new application project in Xcode and add :code:`flwr` as a " +"dependency in your project. For our application, we will store the logic of " +"our app in :code:`FLiOSModel.swift` and the UI elements in :code:" +"`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift` in this " +"quickstart. Please refer to the `full code example `_ to learn more about the app." msgstr "" -"让我们在 Xcode 中创建一个新的应用程序项目,并在项目中添加 :code:`flwr` 作为依赖关系。对于我们的应用程序,我们将在 " -":code:`FLiOSModel.swift` 中存储应用程序的逻辑,在 :code:`ContentView.swift` 中存储 UI " -"元素。在本快速入门中,我们将更多地关注 :code:`FLiOSModel.swift`。请参阅 `完整代码示例 " -"`_ 以了解更多有关应用程序的信息。" +"让我们在 Xcode 中创建一个新的应用程序项目,并在项目中添加 :code:`flwr` 作为依" +"赖关系。对于我们的应用程序,我们将在 :code:`FLiOSModel.swift` 中存储应用程序" +"的逻辑,在 :code:`ContentView.swift` 中存储 UI 元素。在本快速入门中,我们将更" +"多地关注 :code:`FLiOSModel.swift`。请参阅 `完整代码示例 `_ 以了解更多有关应用程序的信息。" #: ../../source/tutorial-quickstart-ios.rst:75 msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" @@ -19983,30 +20153,30 @@ msgstr "在 :code:`FLiOSModel.swift` 中导入 Flower 和 CoreML 相关软件包 #: ../../source/tutorial-quickstart-ios.rst:83 msgid "" "Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS " -"device. We need to pass the url to access mlmodel and run CoreML machine " -"learning processes, it can be retrieved by calling the function " -":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " -"into :code:`MLBatchProvider` object. The preprocessing is done inside " -":code:`DataLoader.swift`." -msgstr "" -"然后通过拖放将 mlmodel 添加到项目中,在部署到 iOS 设备时,mlmodel 将被捆绑到应用程序中。我们需要传递 url 以访问 " -"mlmodel 并运行 CoreML 机器学习进程,可通过调用函数 :code:`Bundle.main.url` 获取。对于 MNIST " -"数据集,我们需要将其预处理为 :code:`MLBatchProvider` 对象。预处理在 :code:`DataLoader.swift` " -"中完成。" +"will be bundled inside the application during deployment to your iOS device. " +"We need to pass the url to access mlmodel and run CoreML machine learning " +"processes, it can be retrieved by calling the function :code:`Bundle.main." +"url`. For the MNIST dataset, we need to preprocess it into :code:" +"`MLBatchProvider` object. The preprocessing is done inside :code:`DataLoader." +"swift`." +msgstr "" +"然后通过拖放将 mlmodel 添加到项目中,在部署到 iOS 设备时,mlmodel 将被捆绑到" +"应用程序中。我们需要传递 url 以访问 mlmodel 并运行 CoreML 机器学习进程,可通" +"过调用函数 :code:`Bundle.main.url` 获取。对于 MNIST 数据集,我们需要将其预处" +"理为 :code:`MLBatchProvider` 对象。预处理在 :code:`DataLoader.swift` 中完成。" #: ../../source/tutorial-quickstart-ios.rst:99 #, fuzzy msgid "" -"Since CoreML does not allow the model parameters to be seen before " -"training, and accessing the model parameters during or after the training" -" can only be done by specifying the layer name, we need to know this " -"information beforehand, through looking at the model specification, which" -" are written as proto files. The implementation can be seen in " -":code:`MLModelInspect`." +"Since CoreML does not allow the model parameters to be seen before training, " +"and accessing the model parameters during or after the training can only be " +"done by specifying the layer name, we need to know this information " +"beforehand, through looking at the model specification, which are written as " +"proto files. The implementation can be seen in :code:`MLModelInspect`." msgstr "" -"由于 CoreML 不允许在训练前查看模型参数,而在训练过程中或训练后访问模型参数只能通过指定层名来完成,因此我们需要事先通过查看模型规范(写成 " -"proto 文件)来了解这些信息。具体实现可参见 :code:`MLModelInspect`。" +"由于 CoreML 不允许在训练前查看模型参数,而在训练过程中或训练后访问模型参数只" +"能通过指定层名来完成,因此我们需要事先通过查看模型规范(写成 proto 文件)来了" +"解这些信息。具体实现可参见 :code:`MLModelInspect`。" #: ../../source/tutorial-quickstart-ios.rst:102 #, fuzzy @@ -20017,22 +20187,25 @@ msgstr "获得所有必要信息后,让我们创建 Flower 客户端。" #: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"Then start the Flower gRPC client and start communicating to the server " -"by passing our Flower client to the function :code:`startFlwrGRPC`." -msgstr "然后启动 Flower gRPC 客户端,并通过将 Flower 客户端传递给函数 :code:`startFlwrGRPC` 来开始与服务器通信。" +"Then start the Flower gRPC client and start communicating to the server by " +"passing our Flower client to the function :code:`startFlwrGRPC`." +msgstr "" +"然后启动 Flower gRPC 客户端,并通过将 Flower 客户端传递给函数 :code:" +"`startFlwrGRPC` 来开始与服务器通信。" #: ../../source/tutorial-quickstart-ios.rst:124 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " -"The attribute :code:`hostname` and :code:`port` tells the client which " -"server to connect to. This can be done by entering the hostname and port " -"in the application before clicking the start button to start the " -"federated learning process." +"That's it for the client. We only have to implement :code:`Client` or call " +"the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. The " +"attribute :code:`hostname` and :code:`port` tells the client which server to " +"connect to. This can be done by entering the hostname and port in the " +"application before clicking the start button to start the federated learning " +"process." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或调用提供的 :code:`MLFlwrClient` 并调用 " -":code:`startFlwrGRPC()`。属性 :code:`hostname` 和 :code:`port` " -"会告诉客户端要连接到哪个服务器。这可以通过在应用程序中输入主机名和端口来实现,然后再点击开始按钮启动联邦学习进程。" +"这就是客户端。我们只需实现 :code:`Client` 或调用提供的 :code:`MLFlwrClient` " +"并调用 :code:`startFlwrGRPC()`。属性 :code:`hostname` 和 :code:`port` 会告诉" +"客户端要连接到哪个服务器。这可以通过在应用程序中输入主机名和端口来实现,然后" +"再点击开始按钮启动联邦学习进程。" #: ../../source/tutorial-quickstart-ios.rst:129 #: ../../source/tutorial-quickstart-mxnet.rst:226 @@ -20049,11 +20222,11 @@ msgstr "Flower 服务器" #: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" "For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named " -":code:`server.py`, import Flower and start the server:" +"configuration possibilities at their default values. In a file named :code:" +"`server.py`, import Flower and start the server:" msgstr "" -"对于简单的工作负载,我们可以启动 Flower 服务器,并将所有配置选项保留为默认值。在名为 :code:`server.py` 的文件中,导入 " -"Flower 并启动服务器:" +"对于简单的工作负载,我们可以启动 Flower 服务器,并将所有配置选项保留为默认" +"值。在名为 :code:`server.py` 的文件中,导入 Flower 并启动服务器:" #: ../../source/tutorial-quickstart-ios.rst:142 #: ../../source/tutorial-quickstart-mxnet.rst:239 @@ -20069,40 +20242,43 @@ msgstr "联邦训练模型!" #: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" "With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and " -"multiple clients. We therefore have to start the server first:" -msgstr "客户端和服务器都已准备就绪,我们现在可以运行一切,看看联邦学习的实际效果。FL 系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +"federated learning in action. FL systems usually have a server and multiple " +"clients. We therefore have to start the server first:" +msgstr "" +"客户端和服务器都已准备就绪,我们现在可以运行一切,看看联邦学习的实际效果。FL " +"系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" #: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Build and run the client through your Xcode, one through Xcode" -" Simulator and the other by deploying it to your iPhone. To see more " -"about how to deploy your app to iPhone or Simulator visit `here " -"`_." +"Once the server is running we can start the clients in different terminals. " +"Build and run the client through your Xcode, one through Xcode Simulator and " +"the other by deploying it to your iPhone. To see more about how to deploy " +"your app to iPhone or Simulator visit `here `_." msgstr "" -"服务器运行后,我们就可以在不同的终端启动客户端。通过 Xcode 构建并运行客户端,一个通过 Xcode 模拟器,另一个通过部署到 " -"iPhone。要了解更多有关如何将应用程序部署到 iPhone 或模拟器的信息,请访问 `此处 " -"`_。" +"服务器运行后,我们就可以在不同的终端启动客户端。通过 Xcode 构建并运行客户端," +"一个通过 Xcode 模拟器,另一个通过部署到 iPhone。要了解更多有关如何将应用程序" +"部署到 iPhone 或模拟器的信息,请访问 `此处 `_。" #: ../../source/tutorial-quickstart-ios.rst:156 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code " -"`_ for this " -"example can be found in :code:`examples/ios`." +"learning system in your ios device. The full `source code `_ for this example can be found in :" +"code:`examples/ios`." msgstr "" -"恭喜您! 您已经成功地在 ios 设备中构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可在 " -":code:`examples/ios` 中找到。" +"恭喜您! 您已经成功地在 ios 设备中构建并运行了第一个联邦学习系统。本示例的`完" +"整源代码 `_ 可在 :" +"code:`examples/ios` 中找到。" #: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Jax to train a linear regression model on a scikit-learn dataset." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 Jax 在 scikit-learn 数据集上训练线性回归模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Jax to train a linear regression model on a scikit-learn dataset." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 Jax 在 scikit-learn 数据集" +"上训练线性回归模型。" #: ../../source/tutorial-quickstart-jax.rst:5 msgid "Quickstart JAX" @@ -20110,9 +20286,11 @@ msgstr "快速入门 JAX" #: ../../source/tutorial-quickstart-mxnet.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with MXNet to train a Sequential model on MNIST." -msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 MXNet 在 MNIST 上训练序列模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"MXNet to train a Sequential model on MNIST." +msgstr "" +"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 MXNet 在 MNIST 上训练序列" +"模型。" #: ../../source/tutorial-quickstart-mxnet.rst:5 msgid "Quickstart MXNet" @@ -20120,53 +20298,59 @@ msgstr "快速入门 MXNet" #: ../../source/tutorial-quickstart-mxnet.rst:7 msgid "" -"MXNet is no longer maintained and has been moved into `Attic " -"`_. As a result, we would " -"encourage you to use other ML frameworks alongside Flower, for example, " -"PyTorch. This tutorial might be removed in future versions of Flower." +"MXNet is no longer maintained and has been moved into `Attic `_. As a result, we would encourage you to " +"use other ML frameworks alongside Flower, for example, PyTorch. This " +"tutorial might be removed in future versions of Flower." msgstr "" #: ../../source/tutorial-quickstart-mxnet.rst:12 msgid "" -"In this tutorial, we will learn how to train a :code:`Sequential` model " -"on MNIST using Flower and MXNet." -msgstr "在本教程中,我们将学习如何使用 Flower 和 MXNet 在 MNIST 上训练 :code:`Sequential` 模型。" +"In this tutorial, we will learn how to train a :code:`Sequential` model on " +"MNIST using Flower and MXNet." +msgstr "" +"在本教程中,我们将学习如何使用 Flower 和 MXNet 在 MNIST 上训练 :code:" +"`Sequential` 模型。" #: ../../source/tutorial-quickstart-mxnet.rst:14 #: ../../source/tutorial-quickstart-scikitlearn.rst:12 #, fuzzy msgid "" -"It is recommended to create a virtual environment and run everything " -"within this :doc:`virtualenv `." +"It is recommended to create a virtual environment and run everything within " +"this :doc:`virtualenv `." msgstr "" -"建议创建一个虚拟环境,并在此 `virtualenv `_ 中运行所有内容。" +"建议创建一个虚拟环境,并在此 `virtualenv `_ 中运行所有内容。" #: ../../source/tutorial-quickstart-mxnet.rst:16 #: ../../source/tutorial-quickstart-pytorch.rst:17 #: ../../source/tutorial-quickstart-scikitlearn.rst:14 msgid "" -"Our example consists of one *server* and two *clients* all having the " -"same model." +"Our example consists of one *server* and two *clients* all having the same " +"model." msgstr "我们的例子包括一个*服务器*和两个*客户端*,它们都有相同的模型。" #: ../../source/tutorial-quickstart-mxnet.rst:18 #: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"*Clients* are responsible for generating individual model parameter " -"updates for the model based on their local datasets. These updates are " -"then sent to the *server* which will aggregate them to produce an updated" -" global model. Finally, the *server* sends this improved version of the " -"model back to each *client*. A complete cycle of parameters updates is " -"called a *round*." -msgstr "*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。然后,这些参数更新将被发送到*服务器*,由*服务器*汇总后生成一个更新的全局模型。最后,*服务器*将这一改进版模型发回给每个*客户端*。一个完整的参数更新周期称为一*轮*。" +"*Clients* are responsible for generating individual model parameter updates " +"for the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce an updated global model. " +"Finally, the *server* sends this improved version of the model back to each " +"*client*. A complete cycle of parameters updates is called a *round*." +msgstr "" +"*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。然后,这些参数更新" +"将被发送到*服务器*,由*服务器*汇总后生成一个更新的全局模型。最后,*服务器*将" +"这一改进版模型发回给每个*客户端*。一个完整的参数更新周期称为一*轮*。" #: ../../source/tutorial-quickstart-mxnet.rst:22 #: ../../source/tutorial-quickstart-scikitlearn.rst:20 msgid "" "Now that we have a rough idea of what is going on, let's get started. We " "first need to install Flower. You can do this by running:" -msgstr "现在,我们已经有了一个大致的概念,让我们开始吧。首先,我们需要安装 Flower。运行:" +msgstr "" +"现在,我们已经有了一个大致的概念,让我们开始吧。首先,我们需要安装 Flower。运" +"行:" #: ../../source/tutorial-quickstart-mxnet.rst:28 msgid "Since we want to use MXNet, let's go ahead and install it:" @@ -20175,19 +20359,19 @@ msgstr "既然我们要使用 MXNet,那就继续安装吧:" #: ../../source/tutorial-quickstart-mxnet.rst:38 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on MXNet´s `Hand-written " -"Digit Recognition tutorial " -"`_." +"distributed training with two clients and one server. Our training procedure " +"and network architecture are based on MXNet´s `Hand-written Digit " +"Recognition tutorial `_." msgstr "" -"现在,我们已经安装了所有依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练程序和网络架构基于 MXNet 的 " -"`手写数字识别教程 " -"`_\"。" +"现在,我们已经安装了所有依赖项,让我们用两个客户端和一个服务器来运行一个简单" +"的分布式训练。我们的训练程序和网络架构基于 MXNet 的 `手写数字识别教程 " +"`_\"。" #: ../../source/tutorial-quickstart-mxnet.rst:40 msgid "" -"In a file called :code:`client.py`, import Flower and MXNet related " -"packages:" +"In a file called :code:`client.py`, import Flower and MXNet related packages:" msgstr "在名为 :code:`client.py` 的文件中,导入 Flower 和 MXNet 相关软件包:" #: ../../source/tutorial-quickstart-mxnet.rst:55 @@ -20197,29 +20381,35 @@ msgstr "此外,还可以在 MXNet 中定义设备分配:" #: ../../source/tutorial-quickstart-mxnet.rst:61 msgid "" "We use MXNet to load MNIST, a popular image classification dataset of " -"handwritten digits for machine learning. The MXNet utility " -":code:`mx.test_utils.get_mnist()` downloads the training and test data." +"handwritten digits for machine learning. The MXNet utility :code:`mx." +"test_utils.get_mnist()` downloads the training and test data." msgstr "" -"我们使用 MXNet 加载 MNIST,这是一个用于机器学习的流行手写数字图像分类数据集。MXNet 工具 " -":code:`mx.test_utils.get_mnist()` 会下载训练和测试数据。" +"我们使用 MXNet 加载 MNIST,这是一个用于机器学习的流行手写数字图像分类数据集。" +"MXNet 工具 :code:`mx.test_utils.get_mnist()` 会下载训练和测试数据。" #: ../../source/tutorial-quickstart-mxnet.rst:75 msgid "" -"Define the training and loss with MXNet. We train the model by looping " -"over the dataset, measure the corresponding loss, and optimize it." -msgstr "用 MXNet 定义训练和损失值。我们在数据集上循环训练模型,测量相应的损失值,并对其进行优化。" +"Define the training and loss with MXNet. We train the model by looping over " +"the dataset, measure the corresponding loss, and optimize it." +msgstr "" +"用 MXNet 定义训练和损失值。我们在数据集上循环训练模型,测量相应的损失值,并对" +"其进行优化。" #: ../../source/tutorial-quickstart-mxnet.rst:113 msgid "" -"Next, we define the validation of our machine learning model. We loop " -"over the test set and measure both loss and accuracy on the test set." -msgstr "接下来,我们定义机器学习模型的验证。我们在测试集上循环,测量测试集上的损失值和准确率。" +"Next, we define the validation of our machine learning model. We loop over " +"the test set and measure both loss and accuracy on the test set." +msgstr "" +"接下来,我们定义机器学习模型的验证。我们在测试集上循环,测量测试集上的损失值" +"和准确率。" #: ../../source/tutorial-quickstart-mxnet.rst:137 msgid "" -"After defining the training and testing of a MXNet machine learning " -"model, we use these functions to implement a Flower client." -msgstr "在定义了 MXNet 机器学习模型的训练和测试后,我们使用这些函数实现了 Flower 客户端。" +"After defining the training and testing of a MXNet machine learning model, " +"we use these functions to implement a Flower client." +msgstr "" +"在定义了 MXNet 机器学习模型的训练和测试后,我们使用这些函数实现了 Flower 客户" +"端。" #: ../../source/tutorial-quickstart-mxnet.rst:139 msgid "Our Flower clients will use a simple :code:`Sequential` model:" @@ -20227,38 +20417,37 @@ msgstr "我们的 Flower 客户端将使用简单的 :code:`Sequential` 模型 #: ../../source/tutorial-quickstart-mxnet.rst:158 msgid "" -"After loading the dataset with :code:`load_data()` we perform one forward" -" propagation to initialize the model and model parameters with " -":code:`model(init)`. Next, we implement a Flower client." +"After loading the dataset with :code:`load_data()` we perform one forward " +"propagation to initialize the model and model parameters with :code:" +"`model(init)`. Next, we implement a Flower client." msgstr "" -"使用 :code:`load_data()` 加载数据集后,我们会执行一次前向传播,使用 :code:`model(init)` " -"初始化模型和模型参数。接下来,我们实现一个 Flower 客户端。" +"使用 :code:`load_data()` 加载数据集后,我们会执行一次前向传播,使用 :code:" +"`model(init)` 初始化模型和模型参数。接下来,我们实现一个 Flower 客户端。" #: ../../source/tutorial-quickstart-mxnet.rst:160 #: ../../source/tutorial-quickstart-pytorch.rst:144 #: ../../source/tutorial-quickstart-tensorflow.rst:54 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to train the neural network we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to train the neural network we defined earlier)." msgstr "" -"Flower 服务器通过一个名为 :code:`Client` " -"的接口与客户端交互。当服务器选择一个特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会调用 :code:`Client`" -" 方法之一来运行您的代码(即训练我们之前定义的神经网络)。" +"Flower 服务器通过一个名为 :code:`Client` 的接口与客户端交互。当服务器选择一个" +"特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会" +"调用 :code:`Client` 方法之一来运行您的代码(即训练我们之前定义的神经网络)。" #: ../../source/tutorial-quickstart-mxnet.rst:166 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses MXNet. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"MXNet. Implementing :code:`NumPyClient` usually means defining the following " +"methods (:code:`set_parameters` is optional though):" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 MXNet 时,它可以让您更轻松地实现 " -":code:`Client` 接口。实现 :code:`NumPyClient` " -"通常意味着定义以下方法(:code:`set_parameters` 是可选的):" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 MXNet " +"时,它可以让您更轻松地实现 :code:`Client` 接口。实现 :code:`NumPyClient` 通常" +"意味着定义以下方法(:code:`set_parameters` 是可选的):" #: ../../source/tutorial-quickstart-mxnet.rst:172 #: ../../source/tutorial-quickstart-pytorch.rst:156 @@ -20276,8 +20465,7 @@ msgstr ":code:`set_parameters` (可选)" #: ../../source/tutorial-quickstart-pytorch.rst:158 #: ../../source/tutorial-quickstart-scikitlearn.rst:111 msgid "" -"update the local model weights with the parameters received from the " -"server" +"update the local model weights with the parameters received from the server" msgstr "用从服务器接收到的参数更新本地模型参数" #: ../../source/tutorial-quickstart-mxnet.rst:176 @@ -20310,34 +20498,38 @@ msgstr "它们可以通过以下方式实现:" #: ../../source/tutorial-quickstart-mxnet.rst:212 msgid "" -"We can now create an instance of our class :code:`MNISTClient` and add " -"one line to actually run this client:" -msgstr "现在我们可以创建一个 :code:`MNISTClient` 类的实例,并添加一行来实际运行该客户端:" +"We can now create an instance of our class :code:`MNISTClient` and add one " +"line to actually run this client:" +msgstr "" +"现在我们可以创建一个 :code:`MNISTClient` 类的实例,并添加一行来实际运行该客户" +"端:" #: ../../source/tutorial-quickstart-mxnet.rst:219 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()` or " -":code:`fl.client.start_numpy_client()`. The string " -":code:`\"0.0.0.0:8080\"` tells the client which server to connect to. In " -"our case we can run the server and the client on the same machine, " -"therefore we use :code:`\"0.0.0.0:8080\"`. If we run a truly federated " -"workload with the server and clients running on different machines, all " -"that needs to change is the :code:`server_address` we pass to the client." -msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 " -":code:`fl.client.start_client()` 或 " -":code:`fl.client.start_numpy_client()`。字符串 " -":code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " -":code:`\"0.0.0.0:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是传递给客户端的" -" :code:`server_address`。" +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()` or :code:`fl.client." +"start_numpy_client()`. The string :code:`\"0.0.0.0:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we pass to " +"the client." +msgstr "" +"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" +"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" +"符串 :code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在" +"同一台机器上运行服务器和客户端,因此我们使用 :code:`\"0.0.0.0:8080\"`。如果我" +"们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变" +"的只是传递给客户端的 :code:`server_address`。" #: ../../source/tutorial-quickstart-mxnet.rst:241 msgid "" "With both client and server ready, we can now run everything and see " "federated learning in action. Federated learning systems usually have a " "server and multiple clients. We therefore have to start the server first:" -msgstr "客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +msgstr "" +"客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。" +"联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" #: ../../source/tutorial-quickstart-mxnet.rst:249 #: ../../source/tutorial-quickstart-pytorch.rst:226 @@ -20345,9 +20537,11 @@ msgstr "客户端和服务器都准备就绪后,我们现在就可以运行一 #: ../../source/tutorial-quickstart-tensorflow.rst:122 #: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Open a new terminal and start the first client:" -msgstr "服务器运行后,我们就可以在不同终端启动客户端了。打开一个新终端,启动第一个客户端:" +"Once the server is running we can start the clients in different terminals. " +"Open a new terminal and start the first client:" +msgstr "" +"服务器运行后,我们就可以在不同终端启动客户端了。打开一个新终端,启动第一个客" +"户端:" #: ../../source/tutorial-quickstart-mxnet.rst:256 #: ../../source/tutorial-quickstart-pytorch.rst:233 @@ -20362,28 +20556,29 @@ msgstr "打开另一台终端,启动第二个客户端:" #: ../../source/tutorial-quickstart-scikitlearn.rst:237 #: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Each client will have its own dataset. You should now see how the " -"training does in the very first terminal (the one that started the " -"server):" -msgstr "每个客户端都有自己的数据集。现在你应该看到第一个终端(启动服务器的终端)的训练效果了:" +"Each client will have its own dataset. You should now see how the training " +"does in the very first terminal (the one that started the server):" +msgstr "" +"每个客户端都有自己的数据集。现在你应该看到第一个终端(启动服务器的终端)的训" +"练效果了:" #: ../../source/tutorial-quickstart-mxnet.rst:294 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-mxnet`." +"learning system. The full `source code `_ for this example can be found " +"in :code:`examples/quickstart-mxnet`." msgstr "" "恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可在 :code:`examples/quickstart-mxnet` 中找到。" +"`_ 可在 :code:`examples/quickstart-mxnet` 中找到。" #: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Pandas to perform Federated Analytics." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 Pandas 执行联邦分析。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Pandas to perform Federated Analytics." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 Pandas 执行联邦分析。" #: ../../source/tutorial-quickstart-pandas.rst:5 msgid "Quickstart Pandas" @@ -20395,68 +20590,78 @@ msgstr "让我们使用 Pandas 和 Flower 建立一个联邦分析系统!" #: ../../source/tutorial-quickstart-pandas.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" -"请参阅 `完整代码示例 `_\" 了解更多信息。" +"请参阅 `完整代码示例 `_\" 了解更多信息。" #: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch to train a CNN model on MNIST." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch 在 MNIST 上训练 CNN 模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch to train a CNN model on MNIST." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch 在 MNIST 上训练 " +"CNN 模型。" #: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural " -"Network on CIFAR10 using Flower and PyTorch." -msgstr "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 CIFAR10 上训练卷积神经网络。" +"In this tutorial we will learn how to train a Convolutional Neural Network " +"on CIFAR10 using Flower and PyTorch." +msgstr "" +"在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 CIFAR10 上训练卷积神经网" +"络。" #: ../../source/tutorial-quickstart-pytorch.rst:15 #: ../../source/tutorial-quickstart-xgboost.rst:39 #, fuzzy msgid "" "First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"everything within a :doc:`virtualenv `." msgstr "" -"首先,建议创建一个虚拟环境,并在 `virtualenv `_ 中运行一切。" +"首先,建议创建一个虚拟环境,并在 `virtualenv `_ 中运行一切。" #: ../../source/tutorial-quickstart-pytorch.rst:19 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." -msgstr "*客户端*负责在其本地数据集上更新模型参数。然后,这些参数会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客户端*。一个完整的模型参数更新周期称为一*轮*。" +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." +msgstr "" +"*客户端*负责在其本地数据集上更新模型参数。然后,这些参数会被发送到*服务器*," +"由*服务器*聚合后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客" +"户端*。一个完整的模型参数更新周期称为一*轮*。" #: ../../source/tutorial-quickstart-pytorch.rst:23 msgid "" "Now that we have a rough idea of what is going on, let's get started. We " "first need to install Flower. You can do this by running :" -msgstr "现在,我们已经有了一个大致的概念了,那就让我们开始吧。首先,我们需要安装 Flower。可以通过运行 :" +msgstr "" +"现在,我们已经有了一个大致的概念了,那就让我们开始吧。首先,我们需要安装 " +"Flower。可以通过运行 :" #: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go " -"ahead and install PyTorch and the **torchvision** library:" -msgstr "既然我们想用 PyTorch 解决计算机视觉任务,那就继续安装 PyTorch 和 **torchvision** 库吧:" +"Since we want to use PyTorch to solve a computer vision task, let's go ahead " +"and install PyTorch and the **torchvision** library:" +msgstr "" +"既然我们想用 PyTorch 解决计算机视觉任务,那就继续安装 PyTorch 和 " +"**torchvision** 库吧:" #: ../../source/tutorial-quickstart-pytorch.rst:39 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on PyTorch's `Deep Learning " -"with PyTorch " +"distributed training with two clients and one server. Our training procedure " +"and network architecture are based on PyTorch's `Deep Learning with PyTorch " "`_." msgstr "" -"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练过程和网络架构基于 PyTorch " -"的《Deep Learning with PyTorch " -"`_》。" +"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单" +"的分布式训练。我们的训练过程和网络架构基于 PyTorch 的《Deep Learning with " +"PyTorch `_》。" #: ../../source/tutorial-quickstart-pytorch.rst:41 msgid "" @@ -20471,35 +20676,40 @@ msgstr "此外,我们还在 PyTorch 中定义了设备分配:" #: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" "We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " -"the training and test data that are then normalized." +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads the " +"training and test data that are then normalized." msgstr "" -"我们使用 PyTorch 来加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据集。PyTorch " -":code:`DataLoader()`下载训练数据和测试数据,然后进行归一化处理。" +"我们使用 PyTorch 来加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据" +"集。PyTorch :code:`DataLoader()`下载训练数据和测试数据,然后进行归一化处理。" #: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset " -"is done by looping over the dataset, measure the corresponding loss and " +"Define the loss and optimizer with PyTorch. The training of the dataset is " +"done by looping over the dataset, measure the corresponding loss and " "optimize it." -msgstr "使用 PyTorch 定义损失和优化器。数据集的训练是通过循环数据集、测量相应的损失值并对其进行优化来完成的。" +msgstr "" +"使用 PyTorch 定义损失和优化器。数据集的训练是通过循环数据集、测量相应的损失值" +"并对其进行优化来完成的。" #: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"Define then the validation of the machine learning network. We loop over" -" the test set and measure the loss and accuracy of the test set." -msgstr "然后定义机器学习网络的验证。我们在测试集上循环,计算测试集的损失值和准确率。" +"Define then the validation of the machine learning network. We loop over " +"the test set and measure the loss and accuracy of the test set." +msgstr "" +"然后定义机器学习网络的验证。我们在测试集上循环,计算测试集的损失值和准确率。" #: ../../source/tutorial-quickstart-pytorch.rst:113 msgid "" -"After defining the training and testing of a PyTorch machine learning " -"model, we use the functions for the Flower clients." -msgstr "在定义了 PyTorch 机器学习模型的训练和测试之后,我们将这些功能用于 Flower 客户端。" +"After defining the training and testing of a PyTorch machine learning model, " +"we use the functions for the Flower clients." +msgstr "" +"在定义了 PyTorch 机器学习模型的训练和测试之后,我们将这些功能用于 Flower 客户" +"端。" #: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " -"Minute Blitz':" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 Minute " +"Blitz':" msgstr "Flower 客户端将使用一个简单的从“PyTorch: 60 分钟突击\"改编的CNN:" #: ../../source/tutorial-quickstart-pytorch.rst:142 @@ -20510,15 +20720,14 @@ msgstr "使用 :code:`load_data()` 加载数据集后,我们定义了 Flower #: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"PyTorch. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 PyTorch 时,它使 " -":code:`Client` 接口的实现变得更容易。实现 :code:`NumPyClient` " -"通常意味着定义以下方法(:code:`set_parameters` 是可选的):" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 " +"PyTorch 时,它使 :code:`Client` 接口的实现变得更容易。实现 :code:" +"`NumPyClient` 通常意味着定义以下方法(:code:`set_parameters` 是可选的):" #: ../../source/tutorial-quickstart-pytorch.rst:166 msgid "which can be implemented in the following way:" @@ -20527,48 +20736,51 @@ msgstr "可以通过以下方式实现:" #: ../../source/tutorial-quickstart-pytorch.rst:189 #: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add " -"one line to actually run this client:" -msgstr "现在我们可以创建一个 :code:`CifarClient` 类的实例,并添加一行来实际运行该客户端:" +"We can now create an instance of our class :code:`CifarClient` and add one " +"line to actually run this client:" +msgstr "" +"现在我们可以创建一个 :code:`CifarClient` 类的实例,并添加一行来实际运行该客户" +"端:" #: ../../source/tutorial-quickstart-pytorch.rst:196 #: ../../source/tutorial-quickstart-tensorflow.rst:90 #, fuzzy msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " -"the client which server to connect to. In our case we can run the server " -"and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"[::]:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"[::]:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we point " +"the client at." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 " -":code:`fl.client.start_client()` 或 " -":code:`fl.client.start_numpy_client()`。字符串 " -":code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此使用 " -":code:`\"[::]:8080\"。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户端指向的 " -":code:`server_address`。" +"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" +"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" +"符串 :code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同" +"一台机器上运行服务器和客户端,因此使用 :code:`\"[::]:8080\"。如果我们运行的是" +"真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户" +"端指向的 :code:`server_address`。" #: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-pytorch`." +"learning system. The full `source code `_ for this example can be found " +"in :code:`examples/quickstart-pytorch`." msgstr "" "恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可以在 :code:`examples/quickstart-pytorch` 中找到。" +"`_ 可以在 :code:`examples/quickstart-pytorch` 中找到。" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch Lightning to train an Auto Encoder model on MNIST." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch Lightning 在 MNIST 上训练自动编码器模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch Lightning to train an Auto Encoder model on MNIST." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch Lightning 在 " +"MNIST 上训练自动编码器模型。" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 msgid "Quickstart PyTorch Lightning" @@ -20576,24 +20788,25 @@ msgstr "快速入门 PyTorch Lightning" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 msgid "" -"Let's build a horizontal federated learning system using PyTorch " -"Lightning and Flower!" +"Let's build a horizontal federated learning system using PyTorch Lightning " +"and Flower!" msgstr "让我们使用 PyTorch Lightning 和 Flower 构建一个水平联邦学习系统!" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" -"请参阅 `完整代码示例 `_ 了解更多信息。" +"请参阅 `完整代码示例 `_ 了解更多信息。" #: ../../source/tutorial-quickstart-scikitlearn.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with scikit-learn to train a linear regression model." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 scikit-learn 训练线性回归模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"scikit-learn to train a linear regression model." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 scikit-learn 训练线性回归" +"模型。" #: ../../source/tutorial-quickstart-scikitlearn.rst:5 msgid "Quickstart scikit-learn" @@ -20601,11 +20814,11 @@ msgstr "scikit-learn快速入门" #: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic " -"Regression` model on MNIST using Flower and scikit-learn." +"In this tutorial, we will learn how to train a :code:`Logistic Regression` " +"model on MNIST using Flower and scikit-learn." msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 scikit-learn 在 MNIST 上训练一个 :code:`Logistic " -"Regression` 模型。" +"在本教程中,我们将学习如何使用 Flower 和 scikit-learn 在 MNIST 上训练一个 :" +"code:`Logistic Regression` 模型。" #: ../../source/tutorial-quickstart-scikitlearn.rst:26 #, fuzzy @@ -20620,13 +20833,15 @@ msgstr "或者直接使用 Poetry 安装所有依赖项:" msgid "" "Now that we have all our dependencies installed, let's run a simple " "distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that" -" we need for our federated learning setup within :code:`utils.py`. The " -":code:`utils.py` contains different functions defining all the machine " -"learning basics:" +"setting up the client and server, we will define all functionalities that we " +"need for our federated learning setup within :code:`utils.py`. The :code:" +"`utils.py` contains different functions defining all the machine learning " +"basics:" msgstr "" -"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。不过,在设置客户端和服务器之前,我们将在 " -":code:`utils.py` 中定义联邦学习设置所需的所有功能。:code:`utils.py`包含定义所有机器学习基础知识的不同函数:" +"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单" +"的分布式训练。不过,在设置客户端和服务器之前,我们将在 :code:`utils.py` 中定" +"义联邦学习设置所需的所有功能。:code:`utils.py`包含定义所有机器学习基础知识的" +"不同函数:" #: ../../source/tutorial-quickstart-scikitlearn.rst:45 msgid ":code:`get_model_parameters()`" @@ -20678,60 +20893,61 @@ msgstr "将数据集分割成多个分区" #: ../../source/tutorial-quickstart-scikitlearn.rst:58 msgid "" -"Please check out :code:`utils.py` `here " -"`_ for more details. The pre-defined functions are used in" -" the :code:`client.py` and imported. The :code:`client.py` also requires " -"to import several packages such as Flower and scikit-learn:" +"Please check out :code:`utils.py` `here `_ for more details. The pre-" +"defined functions are used in the :code:`client.py` and imported. The :code:" +"`client.py` also requires to import several packages such as Flower and " +"scikit-learn:" msgstr "" -"更多详情请查看 :code:`utils.py`` 这里 " -"`_。在 :code:`client.py` 中使用并导入了预定义函数。:code:`client.py` " -"还需要导入几个软件包,如 Flower 和 scikit-learn:" +"更多详情请查看 :code:`utils.py`` 这里 `_。在 :code:`client.py` 中使用并" +"导入了预定义函数。:code:`client.py` 还需要导入几个软件包,如 Flower 和 " +"scikit-learn:" #: ../../source/tutorial-quickstart-scikitlearn.rst:73 #, fuzzy msgid "" -"We load the MNIST dataset from `OpenML " -"`_, a popular " -"image classification dataset of handwritten digits for machine learning. " -"The utility :code:`utils.load_mnist()` downloads the training and test " -"data. The training set is split afterwards into 10 partitions with " -":code:`utils.partition()`." +"We load the MNIST dataset from `OpenML `_, a popular image classification dataset of " +"handwritten digits for machine learning. The utility :code:`utils." +"load_mnist()` downloads the training and test data. The training set is " +"split afterwards into 10 partitions with :code:`utils.partition()`." msgstr "" -"我们从 `OpenML `_ 中加载 MNIST " -"数据集,这是一个用于机器学习的流行手写数字图像分类数据集。实用程序 :code:`utils.load_mnist()` " -"下载训练和测试数据。然后使用 :code:`utils.partition()`将训练集分割成 10 个分区。" +"我们从 `OpenML `_ 中加载 MNIST 数据集,这是一个" +"用于机器学习的流行手写数字图像分类数据集。实用程序 :code:`utils." +"load_mnist()` 下载训练和测试数据。然后使用 :code:`utils.partition()`将训练集" +"分割成 10 个分区。" #: ../../source/tutorial-quickstart-scikitlearn.rst:85 msgid "" -"Next, the logistic regression model is defined and initialized with " -":code:`utils.set_initial_params()`." -msgstr "接下来,使用 :code:`utils.set_initial_params()` 对逻辑回归模型进行定义和初始化。" +"Next, the logistic regression model is defined and initialized with :code:" +"`utils.set_initial_params()`." +msgstr "" +"接下来,使用 :code:`utils.set_initial_params()` 对逻辑回归模型进行定义和初始" +"化。" #: ../../source/tutorial-quickstart-scikitlearn.rst:97 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to fit the logistic regression we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to fit the logistic regression we defined earlier)." msgstr "" -"Flower 服务器通过一个名为 :code:`Client` " -"的接口与客户端交互。当服务器选择一个特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会调用 :code:`Client`" -" 方法之一来运行您的代码(即拟合我们之前定义的逻辑回归)。" +"Flower 服务器通过一个名为 :code:`Client` 的接口与客户端交互。当服务器选择一个" +"特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会" +"调用 :code:`Client` 方法之一来运行您的代码(即拟合我们之前定义的逻辑回归)。" #: ../../source/tutorial-quickstart-scikitlearn.rst:103 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " -"means defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"scikit-learn. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当你的工作负载使用 scikit-learn " -"时,它可以让你更容易地实现 :code:`Client` 接口。实现 :code:`NumPyClient` " -"通常意味着定义以下方法(:code:`set_parameters` 是可选的):" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当你的工作负载使用 " +"scikit-learn 时,它可以让你更容易地实现 :code:`Client` 接口。实现 :code:" +"`NumPyClient` 通常意味着定义以下方法(:code:`set_parameters` 是可选的):" #: ../../source/tutorial-quickstart-scikitlearn.rst:112 msgid "is directly imported with :code:`utils.set_model_params()`" @@ -20743,38 +20959,40 @@ msgstr "这些方法可以通过以下方式实现:" #: ../../source/tutorial-quickstart-scikitlearn.rst:143 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add " -"one line to actually run this client:" -msgstr "现在我们可以创建一个 :code:`MnistClient` 类的实例,并添加一行来实际运行该客户端:" +"We can now create an instance of our class :code:`MnistClient` and add one " +"line to actually run this client:" +msgstr "" +"现在我们可以创建一个 :code:`MnistClient` 类的实例,并添加一行来实际运行该客户" +"端:" #: ../../source/tutorial-quickstart-scikitlearn.rst:150 #, fuzzy msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" -" the client which server to connect to. In our case we can run the server" -" and the client on the same machine, therefore we use " -":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we pass to the client." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we pass to " +"the client." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 " -":code:`fl.client.start_client()` 或 " -":code:`fl.client.start_numpy_client()`。字符串 " -":code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " -":code:`\"0.0.0.0:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是传递给客户端的" -" :code:`server_address`。" +"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" +"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" +"符串 :code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在" +"同一台机器上运行服务器和客户端,因此我们使用 :code:`\"0.0.0.0:8080\"`。如果我" +"们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变" +"的只是传递给客户端的 :code:`server_address`。" #: ../../source/tutorial-quickstart-scikitlearn.rst:159 msgid "" "The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import " -"again all required libraries such as Flower and scikit-learn." +"evaluation function for the server-side evaluation. First, we import again " +"all required libraries such as Flower and scikit-learn." msgstr "" -"下面的 Flower 服务器更先进一些,会返回一个用于服务器端评估的评估函数。首先,我们再次导入所有需要的库,如 Flower 和 scikit-" -"learn。" +"下面的 Flower 服务器更先进一些,会返回一个用于服务器端评估的评估函数。首先," +"我们再次导入所有需要的库,如 Flower 和 scikit-learn。" #: ../../source/tutorial-quickstart-scikitlearn.rst:162 msgid ":code:`server.py`, import Flower and start the server:" @@ -20782,8 +21000,8 @@ msgstr ":code:`server.py`, 导入 Flower 并启动服务器:" #: ../../source/tutorial-quickstart-scikitlearn.rst:173 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and" -" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"The number of federated learning rounds is set in :code:`fit_round()` and " +"the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " "function is called after each federated learning round and gives you " "information about loss and accuracy." msgstr "" @@ -20792,45 +21010,47 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:198 msgid "" -"The :code:`main` contains the server-side parameter initialization " -":code:`utils.set_initial_params()` as well as the aggregation strategy " -":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " -"federated averaging (or FedAvg), with two clients and evaluation after " -"each federated learning round. The server can be started with the command" -" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +"The :code:`main` contains the server-side parameter initialization :code:" +"`utils.set_initial_params()` as well as the aggregation strategy :code:`fl." +"server.strategy:FedAvg()`. The strategy is the default one, federated " +"averaging (or FedAvg), with two clients and evaluation after each federated " +"learning round. The server can be started with the command :code:`fl.server." +"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." +"server.ServerConfig(num_rounds=3))`." msgstr "" -":code:`main`包含服务器端参数初始化:code:`utils.set_initial_params()`以及聚合策略 " -":code:`fl.server.strategy:FedAvg()`。该策略是默认的联邦平均(或 " -"FedAvg)策略,有两个客户端,在每轮联邦学习后进行评估。可以使用 " -":code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))` 命令启动服务器。" +":code:`main`包含服务器端参数初始化:code:`utils.set_initial_params()`以及聚合" +"策略 :code:`fl.server.strategy:FedAvg()`。该策略是默认的联邦平均(或 FedAvg)" +"策略,有两个客户端,在每轮联邦学习后进行评估。可以使用 :code:`fl.server." +"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." +"server.ServerConfig(num_rounds=3))` 命令启动服务器。" #: ../../source/tutorial-quickstart-scikitlearn.rst:217 msgid "" "With both client and server ready, we can now run everything and see " "federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server " -"first:" -msgstr "客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +"server and multiple clients. We, therefore, have to start the server first:" +msgstr "" +"客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。" +"联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" #: ../../source/tutorial-quickstart-scikitlearn.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples/sklearn-logreg-" -"mnist`." +"learning system. The full `source code `_ for this example can be found in :code:" +"`examples/sklearn-logreg-mnist`." msgstr "" "恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可以在 :code:`examples/sklearn-logreg-mnist` 中找到。" +"`_ 可" +"以在 :code:`examples/sklearn-logreg-mnist` 中找到。" #: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with TensorFlow to train a MobilNetV2 model on CIFAR-10." -msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 TensorFlow 在 CIFAR-10 上训练 MobilNetV2 模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"TensorFlow to train a MobilNetV2 model on CIFAR-10." +msgstr "" +"查看此联邦学习快速入门教程,了解如何使用 Flower 和 TensorFlow 在 CIFAR-10 上" +"训练 MobilNetV2 模型。" #: ../../source/tutorial-quickstart-tensorflow.rst:5 msgid "Quickstart TensorFlow" @@ -20846,8 +21066,8 @@ msgstr "在导入 Flower 之前,我们必须先安装它:" #: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install" -" TF as well:" +"Since we want to use the Keras API of TensorFlow (TF), we have to install TF " +"as well:" msgstr "由于我们要使用 TensorFlow (TF) 的 Keras API,因此还必须安装 TF:" #: ../../source/tutorial-quickstart-tensorflow.rst:31 @@ -20856,31 +21076,32 @@ msgstr "接下来,在名为 :code:`client.py` 的文件中导入 Flower 和 Te #: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image" -" classification dataset for machine learning. The call to " -":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " -"it locally, and then returns the entire training and test set as NumPy " -"ndarrays." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image " +"classification dataset for machine learning. The call to :code:`tf.keras." +"datasets.cifar10.load_data()` downloads CIFAR10, caches it locally, and then " +"returns the entire training and test set as NumPy ndarrays." msgstr "" -"我们使用 TF 的 Keras 实用程序加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据集。调用 " -":code:`tf.keras.datasets.cifar10.load_data()` 会下载 CIFAR10,将其缓存到本地,然后以 " -"NumPy ndarrays 的形式返回整个训练集和测试集。" +"我们使用 TF 的 Keras 实用程序加载 CIFAR10,这是一个用于机器学习的流行彩色图像" +"分类数据集。调用 :code:`tf.keras.datasets.cifar10.load_data()` 会下载 " +"CIFAR10,将其缓存到本地,然后以 NumPy ndarrays 的形式返回整个训练集和测试集。" #: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use " -"MobilNetV2 with 10 output classes:" -msgstr "接下来,我们需要一个模型。在本教程中,我们使用带有 10 个输出类的 MobilNetV2:" +"Next, we need a model. For the purpose of this tutorial, we use MobilNetV2 " +"with 10 output classes:" +msgstr "" +"接下来,我们需要一个模型。在本教程中,我们使用带有 10 个输出类的 MobilNetV2:" #: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses Keras. The :code:`NumPyClient` interface defines three " -"methods which can be implemented in the following way:" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"Keras. The :code:`NumPyClient` interface defines three methods which can be " +"implemented in the following way:" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 Keras 时,该类可以更轻松地实现 " -":code:`Client` 接口。:code:`NumPyClient` 接口定义了三个方法,可以通过以下方式实现:" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 Keras " +"时,该类可以更轻松地实现 :code:`Client` 接口。:code:`NumPyClient` 接口定义了" +"三个方法,可以通过以下方式实现:" #: ../../source/tutorial-quickstart-tensorflow.rst:135 msgid "Each client will have its own dataset." @@ -20888,28 +21109,27 @@ msgstr "每个客户都有自己的数据集。" #: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"You should now see how the training does in the very first terminal (the " -"one that started the server):" +"You should now see how the training does in the very first terminal (the one " +"that started the server):" msgstr "现在你应该能在第一个终端(启动服务器的终端)看到训练的效果了:" #: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this can be found in :code:`examples" -"/quickstart-tensorflow/client.py`." +"learning system. The full `source code `_ for this can be found in :" +"code:`examples/quickstart-tensorflow/client.py`." msgstr "" -"恭喜您!您已经成功构建并运行了第一个联邦学习系统。`完整的源代码 " -"`_ 可以在 :code:`examples/quickstart-" -"tensorflow/client.py` 中找到。" +"恭喜您!您已经成功构建并运行了第一个联邦学习系统。`完整的源代码 `_ " +"可以在 :code:`examples/quickstart-tensorflow/client.py` 中找到。" #: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with XGBoost to train classification models on trees." -msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 XGBoost 上训练分类模型。" +"Check out this Federated Learning quickstart tutorial for using Flower with " +"XGBoost to train classification models on trees." +msgstr "" +"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 XGBoost 上训练分类模型。" #: ../../source/tutorial-quickstart-xgboost.rst:5 msgid "Quickstart XGBoost" @@ -20922,22 +21142,24 @@ msgstr "联邦化 XGBoost" #: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" "EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that " -"maximises the computational boundaries for boosted tree methods. It's " -"primarily designed to enhance both the performance and computational " -"speed of machine learning models. In XGBoost, trees are constructed " -"concurrently, unlike the sequential approach taken by GBDT." +"implementation of gradient-boosted decision tree (**GBDT**), that maximises " +"the computational boundaries for boosted tree methods. It's primarily " +"designed to enhance both the performance and computational speed of machine " +"learning models. In XGBoost, trees are constructed concurrently, unlike the " +"sequential approach taken by GBDT." msgstr "" -"EXtreme Gradient " -"Boosting(**XGBoost**)是梯度提升决策树(**GBDT**)的一种稳健而高效的实现方法,能最大限度地提高提升树方法的计算边界。它主要用于提高机器学习模型的性能和计算速度。在" -" XGBoost 中,决策树是并发构建的,与 GBDT 采用的顺序方法不同。" +"EXtreme Gradient Boosting(**XGBoost**)是梯度提升决策树(**GBDT**)的一种稳" +"健而高效的实现方法,能最大限度地提高提升树方法的计算边界。它主要用于提高机器" +"学习模型的性能和计算速度。在 XGBoost 中,决策树是并发构建的,与 GBDT 采用的顺" +"序方法不同。" #: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" "Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning " -"techniques." -msgstr "对于训练示例少于 10k 的中型数据集上的表格数据,XGBoost 的结果往往超过深度学习技术。" +"training examples, XGBoost surpasses the results of deep learning techniques." +msgstr "" +"对于训练示例少于 10k 的中型数据集上的表格数据,XGBoost 的结果往往超过深度学习" +"技术。" #: ../../source/tutorial-quickstart-xgboost.rst:23 msgid "Why federated XGBoost?" @@ -20946,39 +21168,43 @@ msgstr "为什么选择联邦 XGBoost?" #: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" "Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems " -"for specialised applications, like survival analysis and financial fraud " +"there's an increasing requirement to implement federated XGBoost systems for " +"specialised applications, like survival analysis and financial fraud " "detection." -msgstr "事实上,随着对数据隐私和分散学习的需求不断增长,越来越多的专业应用(如生存分析和金融欺诈检测)需要实施联邦 XGBoost 系统。" +msgstr "" +"事实上,随着对数据隐私和分散学习的需求不断增长,越来越多的专业应用(如生存分" +"析和金融欺诈检测)需要实施联邦 XGBoost 系统。" #: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"Federated learning ensures that raw data remains on the local device, " -"making it an attractive approach for sensitive domains where data " -"security and privacy are paramount. Given the robustness and efficiency " -"of XGBoost, combining it with federated learning offers a promising " -"solution for these specific challenges." +"Federated learning ensures that raw data remains on the local device, making " +"it an attractive approach for sensitive domains where data security and " +"privacy are paramount. Given the robustness and efficiency of XGBoost, " +"combining it with federated learning offers a promising solution for these " +"specific challenges." msgstr "" -"联邦学习可确保原始数据保留在本地设备上,因此对于数据安全和隐私至关重要的敏感领域来说,这是一种极具吸引力的方法。鉴于 XGBoost " -"的稳健性和高效性,将其与联邦学习相结合为应对这些特定挑战提供了一种前景广阔的解决方案。" +"联邦学习可确保原始数据保留在本地设备上,因此对于数据安全和隐私至关重要的敏感" +"领域来说,这是一种极具吸引力的方法。鉴于 XGBoost 的稳健性和高效性,将其与联邦" +"学习相结合为应对这些特定挑战提供了一种前景广阔的解决方案。" #: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" "In this tutorial we will learn how to train a federated XGBoost model on " "HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart " -"`_)" -" with two *clients* and one *server* to demonstrate how federated XGBoost" -" works, and then we dive into a more complex example (`full code xgboost-" -"comprehensive `_) to run various experiments." -msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 :code:`xgboost` 软件包在 HIGGS 数据集上训练联邦 XGBoost " -"模型。我们将使用一个包含两个 * 客户端* 和一个 * 服务器* 的简单示例 (`完整代码 xgboost-quickstart " -"`_)来演示联邦 XGBoost 如何工作,然后我们将深入到一个更复杂的示例 (`完整代码 xgboost-" -"comprehensive `_),以运行各种实验。" +"example (`full code xgboost-quickstart `_) with two *clients* and one *server* to " +"demonstrate how federated XGBoost works, and then we dive into a more " +"complex example (`full code xgboost-comprehensive `_) to run various " +"experiments." +msgstr "" +"在本教程中,我们将学习如何使用 Flower 和 :code:`xgboost` 软件包在 HIGGS 数据" +"集上训练联邦 XGBoost 模型。我们将使用一个包含两个 * 客户端* 和一个 * 服务器* " +"的简单示例 (`完整代码 xgboost-quickstart `_)来演示联邦 XGBoost 如何工作,然后我" +"们将深入到一个更复杂的示例 (`完整代码 xgboost-comprehensive `_),以运行各种实" +"验。" #: ../../source/tutorial-quickstart-xgboost.rst:37 msgid "Environment Setup" @@ -20994,21 +21220,27 @@ msgstr "我们首先需要安装 Flower 和 Flower Datasets。您可以通过运 msgid "" "Since we want to use :code:`xgboost` package to build up XGBoost trees, " "let's go ahead and install :code:`xgboost`:" -msgstr "既然我们要使用 :code:`xgboost` 软件包来构建 XGBoost 树,那就继续安装 :code:`xgboost`:" +msgstr "" +"既然我们要使用 :code:`xgboost` 软件包来构建 XGBoost 树,那就继续安装 :code:" +"`xgboost`:" #: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. Now that we have all our " -"dependencies installed, let's run a simple distributed training with two " -"clients and one server." -msgstr "*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。" +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. Now that we have all our dependencies " +"installed, let's run a simple distributed training with two clients and one " +"server." +msgstr "" +"*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。现在我们已经安装了" +"所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。" #: ../../source/tutorial-quickstart-xgboost.rst:60 msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower " -"Datasets and other related functions:" -msgstr "在名为 :code:`client.py` 的文件中,导入 xgboost、Flower、Flower Datasets 和其他相关函数:" +"In a file called :code:`client.py`, import xgboost, Flower, Flower Datasets " +"and other related functions:" +msgstr "" +"在名为 :code:`client.py` 的文件中,导入 xgboost、Flower、Flower Datasets 和其" +"他相关函数:" #: ../../source/tutorial-quickstart-xgboost.rst:87 msgid "Dataset partition and hyper-parameter selection" @@ -21016,30 +21248,37 @@ msgstr "数据集划分和超参数选择" #: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower" -" Datasets and conduct data partitioning for FL:" -msgstr "在本地训练之前,我们需要从 Flower Datasets 加载 HIGGS 数据集,并对 FL 进行数据分区:" +"Prior to local training, we require loading the HIGGS dataset from Flower " +"Datasets and conduct data partitioning for FL:" +msgstr "" +"在本地训练之前,我们需要从 Flower Datasets 加载 HIGGS 数据集,并对 FL 进行数" +"据分区:" #: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" "In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " -"the partition for the given client based on :code:`node_id`:" +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load the " +"partition for the given client based on :code:`node_id`:" msgstr "" -"在此示例中,我们将数据集分割成两个均匀分布的分区(:code:`IidPartitioner(num_partitions=2)`)。然后,我们根据" -" :code:`node_id` 为给定客户端加载分区:" +"在此示例中,我们将数据集分割成两个均匀分布的分区(:code:" +"`IidPartitioner(num_partitions=2)`)。然后,我们根据 :code:`node_id` 为给定客" +"户端加载分区:" #: ../../source/tutorial-quickstart-xgboost.rst:121 msgid "" "After that, we do train/test splitting on the given partition (client's " "local data), and transform data format for :code:`xgboost` package." -msgstr "然后,我们在给定的分区(客户端的本地数据)上进行训练/测试分割,并为 :code:`xgboost` 软件包转换数据格式。" +msgstr "" +"然后,我们在给定的分区(客户端的本地数据)上进行训练/测试分割,并为 :code:" +"`xgboost` 软件包转换数据格式。" #: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"The functions of :code:`train_test_split` and " -":code:`transform_dataset_to_dmatrix` are defined as below:" -msgstr ":code:`train_test_split` 和 :code:`transform_dataset_too_dmatrix` 的函数定义如下:" +"The functions of :code:`train_test_split` and :code:" +"`transform_dataset_to_dmatrix` are defined as below:" +msgstr "" +":code:`train_test_split` 和 :code:`transform_dataset_too_dmatrix` 的函数定义" +"如下:" #: ../../source/tutorial-quickstart-xgboost.rst:158 msgid "Finally, we define the hyper-parameters used for XGBoost training." @@ -21047,13 +21286,14 @@ msgstr "最后,我们定义了用于 XGBoost 训练的超参数。" #: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"The :code:`num_local_round` represents the number of iterations for local" -" tree boost. We use CPU for the training in default. One can shift it to " -"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " -"evaluation metric." +"The :code:`num_local_round` represents the number of iterations for local " +"tree boost. We use CPU for the training in default. One can shift it to GPU " +"by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as evaluation " +"metric." msgstr "" -"代码:`num_local_round`表示本地树的迭代次数。我们默认使用 CPU 进行训练。可以通过将 :code:`tree_method` " -"设置为 :code:`gpu_hist`,将其转换为 GPU。我们使用 AUC 作为评估指标。" +"代码:`num_local_round`表示本地树的迭代次数。我们默认使用 CPU 进行训练。可以通" +"过将 :code:`tree_method` 设置为 :code:`gpu_hist`,将其转换为 GPU。我们使用 " +"AUC 作为评估指标。" #: ../../source/tutorial-quickstart-xgboost.rst:181 msgid "Flower client definition for XGBoost" @@ -21061,110 +21301,116 @@ msgstr "用于 XGBoost 的 Flower 客户端定义" #: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"After loading the dataset we define the Flower client. We follow the " -"general rule to define :code:`XgbClient` class inherited from " -":code:`fl.client.Client`." +"After loading the dataset we define the Flower client. We follow the general " +"rule to define :code:`XgbClient` class inherited from :code:`fl.client." +"Client`." msgstr "" -"加载数据集后,我们定义 Flower 客户端。我们按照一般规则定义从 :code:`fl.client.Client` 继承而来的 " -":code:`XgbClient` 类。" +"加载数据集后,我们定义 Flower 客户端。我们按照一般规则定义从 :code:`fl." +"client.Client` 继承而来的 :code:`XgbClient` 类。" #: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" "The :code:`self.bst` is used to keep the Booster objects that remain " "consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures" -" for training." +"integrated in earlier rounds and maintain other essential data structures " +"for training." msgstr "" -"代码:`self.bst`用于保存在各轮中保持一致的 Booster " -"对象,使其能够存储在前几轮中集成的树的预测结果,并维护其他用于训练的重要数据结构。" +"代码:`self.bst`用于保存在各轮中保持一致的 Booster 对象,使其能够存储在前几轮" +"中集成的树的预测结果,并维护其他用于训练的重要数据结构。" #: ../../source/tutorial-quickstart-xgboost.rst:196 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and " -":code:`evaluate` methods insides :code:`XgbClient` class as follows." +"Then, we override :code:`get_parameters`, :code:`fit` and :code:`evaluate` " +"methods insides :code:`XgbClient` class as follows." msgstr "" -"然后,我们在 :code:`XgbClient` 类中重写 :code:`get_parameters`、:code:`fit` 和 " -":code:`evaluate` 方法如下。" +"然后,我们在 :code:`XgbClient` 类中重写 :code:`get_parameters`、:code:`fit` " +"和 :code:`evaluate` 方法如下。" #: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" "Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use " -":code:`get_parameters` and :code:`set_parameters` to initialise model " -"parameters for XGBoost. As a result, let's return an empty tensor in " -":code:`get_parameters` when it is called by the server at the first " -"round." +"specified random weights. In this case, we do not use :code:`get_parameters` " +"and :code:`set_parameters` to initialise model parameters for XGBoost. As a " +"result, let's return an empty tensor in :code:`get_parameters` when it is " +"called by the server at the first round." msgstr "" -"与神经网络训练不同,XGBoost 树不是从指定的随机参数开始的。在这种情况下,我们不使用 :code:`get_parameters` 和 " -":code:`set_parameters` 来初始化 XGBoost 的模型参数。因此,当服务器在第一轮调用 " -":code:`get_parameters` 时,让我们在 :code:`get_parameters` 中返回一个空张量。" +"与神经网络训练不同,XGBoost 树不是从指定的随机参数开始的。在这种情况下,我们" +"不使用 :code:`get_parameters` 和 :code:`set_parameters` 来初始化 XGBoost 的模" +"型参数。因此,当服务器在第一轮调用 :code:`get_parameters` 时,让我们在 :code:" +"`get_parameters` 中返回一个空张量。" #: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " -"up the first set of trees. the returned Booster object and config are " -"stored in :code:`self.bst` and :code:`self.config`, respectively. From " -"the second round, we load the global model sent from server to " -":code:`self.bst`, and then update model weights on local training data " -"with function :code:`local_boost` as follows:" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build up " +"the first set of trees. the returned Booster object and config are stored " +"in :code:`self.bst` and :code:`self.config`, respectively. From the second " +"round, we load the global model sent from server to :code:`self.bst`, and " +"then update model weights on local training data with function :code:" +"`local_boost` as follows:" msgstr "" -"在 :code:`fit`中,第一轮我们调用 :code:`xgb.train()`来建立第一组树,返回的 Booster 对象和 config " -"分别存储在 :code:`self.bst` 和 :code:`self.config` 中。从第二轮开始,我们将服务器发送的全局模型加载到 " -":code:`self.bst`,然后使用函数 :code:`local_boost`更新本地训练数据的模型权重,如下所示:" +"在 :code:`fit`中,第一轮我们调用 :code:`xgb.train()`来建立第一组树,返回的 " +"Booster 对象和 config 分别存储在 :code:`self.bst` 和 :code:`self.config` 中。" +"从第二轮开始,我们将服务器发送的全局模型加载到 :code:`self.bst`,然后使用函" +"数 :code:`local_boost`更新本地训练数据的模型权重,如下所示:" #: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"Given :code:`num_local_round`, we update trees by calling " -":code:`self.bst.update` method. After training, the last " -":code:`N=num_local_round` trees will be extracted to send to the server." +"Given :code:`num_local_round`, we update trees by calling :code:`self.bst." +"update` method. After training, the last :code:`N=num_local_round` trees " +"will be extracted to send to the server." msgstr "" -"给定 :code:`num_local_round`,我们通过调用 " -":code:`self.bst.update`方法更新树。训练结束后,我们将提取最后一个 :code:`N=num_local_round` " -"树并发送给服务器。" +"给定 :code:`num_local_round`,我们通过调用 :code:`self.bst.update`方法更新" +"树。训练结束后,我们将提取最后一个 :code:`N=num_local_round` 树并发送给服务" +"器。" #: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " -"conduct evaluation on valid set. The AUC value will be returned." -msgstr "在 :code:`evaluate`中,我们调用 :code:`self.bst.eval_set`函数对有效集合进行评估。将返回 AUC 值。" +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to conduct " +"evaluation on valid set. The AUC value will be returned." +msgstr "" +"在 :code:`evaluate`中,我们调用 :code:`self.bst.eval_set`函数对有效集合进行评" +"估。将返回 AUC 值。" #: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one" -" line to actually run this client:" -msgstr "现在,我们可以创建一个 :code:`XgbClient` 类的实例,并添加一行来实际运行该客户端:" +"Now, we can create an instance of our class :code:`XgbClient` and add one " +"line to actually run this client:" +msgstr "" +"现在,我们可以创建一个 :code:`XgbClient` 类的实例,并添加一行来实际运行该客户" +"端:" #: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"That's it for the client. We only have to implement :code:`Client`and " -"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " -"tells the client which server to connect to. In our case we can run the " -"server and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client`and call :" +"code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` tells the " +"client which server to connect to. In our case we can run the server and the " +"client on the same machine, therefore we use :code:`\"[::]:8080\"`. If we " +"run a truly federated workload with the server and clients running on " +"different machines, all that needs to change is the :code:`server_address` " +"we point the client at." msgstr "" -"这就是客户端。我们只需实现 :code:`客户端`并调用 :code:`fl.client.start_client()`。字符串 " -":code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " -":code:`\"[::]:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户端指向的 " -":code:`server_address`。" +"这就是客户端。我们只需实现 :code:`客户端`并调用 :code:`fl.client." +"start_client()`。字符串 :code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本" +"例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 :code:" +"`\"[::]:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同" +"的机器上,那么需要改变的只是客户端指向的 :code:`server_address`。" #: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" "These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version" -" of the model back to each *client* to finish a complete FL round." +"produce a better model. Finally, the *server* sends this improved version of " +"the model back to each *client* to finish a complete FL round." msgstr "" -"然后,这些更新会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*服务器*将这个改进版的模型发回给每个*客户端*,以完成一轮完整的" -" FL。" +"然后,这些更新会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*" +"服务器*将这个改进版的模型发回给每个*客户端*,以完成一轮完整的 FL。" #: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from " -":code:`flwr.server.strategy`." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from :" +"code:`flwr.server.strategy`." msgstr "" -"在名为 :code:`server.py` 的文件中,从 :code:`flwr.server.strategy` 导入 Flower 和 " -"FedXgbBagging。" +"在名为 :code:`server.py` 的文件中,从 :code:`flwr.server.strategy` 导入 " +"Flower 和 FedXgbBagging。" #: ../../source/tutorial-quickstart-xgboost.rst:316 msgid "We first define a strategy for XGBoost bagging aggregation." @@ -21172,12 +21418,12 @@ msgstr "我们首先定义了 XGBoost bagging聚合策略。" #: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"We use two clients for this example. An " -":code:`evaluate_metrics_aggregation` function is defined to collect and " -"wighted average the AUC values from clients." +"We use two clients for this example. An :code:`evaluate_metrics_aggregation` " +"function is defined to collect and wighted average the AUC values from " +"clients." msgstr "" -"本示例使用两个客户端。我们定义了一个 :code:`evaluate_metrics_aggregation` 函数,用于收集客户机的 AUC " -"值并求取平均值。" +"本示例使用两个客户端。我们定义了一个 :code:`evaluate_metrics_aggregation` 函" +"数,用于收集客户机的 AUC 值并求取平均值。" #: ../../source/tutorial-quickstart-xgboost.rst:342 msgid "Then, we start the server:" @@ -21189,45 +21435,49 @@ msgstr "基于树的bagging聚合" #: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"You must be curious about how bagging aggregation works. Let's look into " -"the details." +"You must be curious about how bagging aggregation works. Let's look into the " +"details." msgstr "您一定很好奇bagging聚合是如何工作的。让我们来详细了解一下。" #: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " -":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." -" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " -"and :code:`evaluate` methods as follows:" +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define :code:" +"`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`. Then, we " +"override the :code:`aggregate_fit`, :code:`aggregate_evaluate` and :code:" +"`evaluate` methods as follows:" msgstr "" -"在文件 :code:`flwr.server.strategy.fedxgb_bagging.py`中,我们定义了从 " -":code:`flwr.server.strategy.FedAvg`继承的 :code:`FedXgbBagging`。然后,我们覆盖 " -":code:`aggregate_fit`、:code:`aggregate_evaluate` 和 :code:`evaluate` 方法如下:" +"在文件 :code:`flwr.server.strategy.fedxgb_bagging.py`中,我们定义了从 :code:" +"`flwr.server.strategy.FedAvg`继承的 :code:`FedXgbBagging`。然后,我们覆盖 :" +"code:`aggregate_fit`、:code:`aggregate_evaluate` 和 :code:`evaluate` 方法如" +"下:" #: ../../source/tutorial-quickstart-xgboost.rst:454 msgid "" "In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " "trees by calling :code:`aggregate()` function:" msgstr "" -"在 :code:`aggregate_fit` 中,我们通过调用 :code:`aggregate()` 函数,按顺序聚合客户端的 XGBoost" -" 树:" +"在 :code:`aggregate_fit` 中,我们通过调用 :code:`aggregate()` 函数,按顺序聚" +"合客户端的 XGBoost 树:" #: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" "In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling " -":code:`_get_tree_nums`. Then, the fetched information will be aggregated." -" After that, the trees (containing model weights) are aggregated to " -"generate a new tree model." +"parallel trees for the current and previous model by calling :code:" +"`_get_tree_nums`. Then, the fetched information will be aggregated. After " +"that, the trees (containing model weights) are aggregated to generate a new " +"tree model." msgstr "" -"在该函数中,我们首先通过调用 :code:`_get_tree_nums` " -"获取当前模型和上一个模型的树数和并行树数。然后,对获取的信息进行聚合。然后,聚合树(包含模型参数)生成新的树模型。" +"在该函数中,我们首先通过调用 :code:`_get_tree_nums` 获取当前模型和上一个模型" +"的树数和并行树数。然后,对获取的信息进行聚合。然后,聚合树(包含模型参数)生" +"成新的树模型。" #: ../../source/tutorial-quickstart-xgboost.rst:518 msgid "" "After traversal of all clients' models, a new global model is generated, " "followed by the serialisation, and sending back to each client." -msgstr "在遍历所有客户端的模型后,会生成一个新的全局模型,然后进行序列化,并发回给每个客户端。" +msgstr "" +"在遍历所有客户端的模型后,会生成一个新的全局模型,然后进行序列化,并发回给每" +"个客户端。" #: ../../source/tutorial-quickstart-xgboost.rst:523 msgid "Launch Federated XGBoost!" @@ -21236,21 +21486,22 @@ msgstr "启动联邦 XGBoost!" #: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" "Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in " -":code:`metrics_distributed`. One can see that the average AUC increases " -"over FL rounds." +"XGBoost system. The AUC values can be checked in :code:" +"`metrics_distributed`. One can see that the average AUC increases over FL " +"rounds." msgstr "" -"恭喜您!您已成功构建并运行了第一个联邦 XGBoost 系统。可以在 :code:`metrics_distributed` 中查看 AUC " -"值。我们可以看到,平均 AUC 随 FL 轮数的增加而增加。" +"恭喜您!您已成功构建并运行了第一个联邦 XGBoost 系统。可以在 :code:" +"`metrics_distributed` 中查看 AUC 值。我们可以看到,平均 AUC 随 FL 轮数的增加" +"而增加。" #: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"The full `source code `_ for this example can be found in :code:`examples" -"/xgboost-quickstart`." +"The full `source code `_ for this example can be found in :code:`examples/" +"xgboost-quickstart`." msgstr "" -"此示例的`完整源代码 `_ 可在 :code:`examples/xgboost-quickstart` 中找到。" +"此示例的`完整源代码 `_ 可在 :code:`examples/xgboost-quickstart` 中找到。" #: ../../source/tutorial-quickstart-xgboost.rst:594 msgid "Comprehensive Federated XGBoost" @@ -21259,20 +21510,21 @@ msgstr "综合的联邦 XGBoost" #: ../../source/tutorial-quickstart-xgboost.rst:596 #, fuzzy msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time" -" to run some more comprehensive experiments by customising the " -"experimental settings. In the xgboost-comprehensive example (`full code " -"`_), we provide more options to define various experimental" -" setups, including aggregation strategies, data partitioning and " -"centralised/distributed evaluation. We also support :doc:`Flower " -"simulation ` making it easy to simulate large " -"client cohorts in a resource-aware manner. Let's take a look!" +"Now that you have known how federated XGBoost work with Flower, it's time to " +"run some more comprehensive experiments by customising the experimental " +"settings. In the xgboost-comprehensive example (`full code `_), we provide " +"more options to define various experimental setups, including aggregation " +"strategies, data partitioning and centralised/distributed evaluation. We " +"also support :doc:`Flower simulation ` making it " +"easy to simulate large client cohorts in a resource-aware manner. Let's take " +"a look!" msgstr "" -"既然您已经知道联合 XGBoost 如何与 Flower 协同工作,那么现在就该通过自定义实验设置来运行一些更综合的实验了。在 xgboost-" -"comprehensive 示例 (`完整代码 " -"`_)中,我们提供了更多选项来定义各种实验设置,包括数据分区和集中/分布式评估。让我们一起来看看!" +"既然您已经知道联合 XGBoost 如何与 Flower 协同工作,那么现在就该通过自定义实验" +"设置来运行一些更综合的实验了。在 xgboost-comprehensive 示例 (`完整代码 " +"`_)" +"中,我们提供了更多选项来定义各种实验设置,包括数据分区和集中/分布式评估。让我" +"们一起来看看!" #: ../../source/tutorial-quickstart-xgboost.rst:603 #, fuzzy @@ -21281,41 +21533,40 @@ msgstr "集中式训练" #: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, " -"which performs FL in a client-by-client fashion. Instead of aggregating " -"multiple clients, there is only one single client participating in the " -"training per round in the cyclic training scenario. The trained local " -"XGBoost trees will be passed to the next client as an initialised model " -"for next round's boosting." +"In addition to bagging aggregation, we offer a cyclic training scheme, which " +"performs FL in a client-by-client fashion. Instead of aggregating multiple " +"clients, there is only one single client participating in the training per " +"round in the cyclic training scenario. The trained local XGBoost trees will " +"be passed to the next client as an initialised model for next round's " +"boosting." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"To do this, we first customise a :code:`ClientManager` in " -":code:`server_utils.py`:" +"To do this, we first customise a :code:`ClientManager` in :code:" +"`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"The customised :code:`ClientManager` samples all available clients in " -"each FL round based on the order of connection to the server. Then, we " -"define a new strategy :code:`FedXgbCyclic` in " -":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " -"select only one client in given round and pass the received model to next" -" client." +"The customised :code:`ClientManager` samples all available clients in each " +"FL round based on the order of connection to the server. Then, we define a " +"new strategy :code:`FedXgbCyclic` in :code:`flwr.server.strategy." +"fedxgb_cyclic.py`, in order to sequentially select only one client in given " +"round and pass the received model to next client." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" "Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model" -" by overriding :code:`aggregate_fit`." +"Instead, we just make a copy of the received client model as global model by " +"overriding :code:`aggregate_fit`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" -" methods ensure the clients to be sequentially selected given FL round:" +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate` " +"methods ensure the clients to be sequentially selected given FL round:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:757 @@ -21324,15 +21575,16 @@ msgstr "定制数据分区" #: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" -" to instantiate the data partitioner based on the given " -":code:`num_partitions` and :code:`partitioner_type`. Currently, we " -"provide four supported partitioner type to simulate the uniformity/non-" -"uniformity in data quantity (uniform, linear, square, exponential)." +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner` to " +"instantiate the data partitioner based on the given :code:`num_partitions` " +"and :code:`partitioner_type`. Currently, we provide four supported " +"partitioner type to simulate the uniformity/non-uniformity in data quantity " +"(uniform, linear, square, exponential)." msgstr "" -"在 :code:`dataset.py` 中,我们有一个函数 :code:`instantiate_partitioner` 来根据给定的 " -":code:`num_partitions` 和 :code:`partitioner_type` " -"来实例化数据分区器。目前,我们提供四种支持的分区器类型(均匀、线性、正方形、指数)来模拟数据量的均匀性/非均匀性。" +"在 :code:`dataset.py` 中,我们有一个函数 :code:`instantiate_partitioner` 来根" +"据给定的 :code:`num_partitions` 和 :code:`partitioner_type` 来实例化数据分区" +"器。目前,我们提供四种支持的分区器类型(均匀、线性、正方形、指数)来模拟数据" +"量的均匀性/非均匀性。" #: ../../source/tutorial-quickstart-xgboost.rst:790 msgid "Customised centralised/distributed evaluation" @@ -21341,29 +21593,29 @@ msgstr "定制的集中/分布式评估" #: ../../source/tutorial-quickstart-xgboost.rst:792 #, fuzzy msgid "" -"To facilitate centralised evaluation, we define a function in " -":code:`server_utils.py`:" +"To facilitate centralised evaluation, we define a function in :code:" +"`server_utils.py`:" msgstr "为便于集中评估,我们在 :code:`server.py` 中定义了一个函数:" #: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"This function returns a evaluation function which instantiates a " -":code:`Booster` object and loads the global model weights to it. The " -"evaluation is conducted by calling :code:`eval_set()` method, and the " -"tested AUC value is reported." +"This function returns a evaluation function which instantiates a :code:" +"`Booster` object and loads the global model weights to it. The evaluation is " +"conducted by calling :code:`eval_set()` method, and the tested AUC value is " +"reported." msgstr "" -"此函数返回一个评估函数,该函数实例化一个 :code:`Booster` 对象,并向其加载全局模型参数。评估通过调用 " -":code:`eval_set()` 方法进行,并报告测试的 AUC 值。" +"此函数返回一个评估函数,该函数实例化一个 :code:`Booster` 对象,并向其加载全局" +"模型参数。评估通过调用 :code:`eval_set()` 方法进行,并报告测试的 AUC 值。" #: ../../source/tutorial-quickstart-xgboost.rst:827 #, fuzzy msgid "" -"As for distributed evaluation on the clients, it's same as the quick-" -"start example by overriding the :code:`evaluate()` method insides the " -":code:`XgbClient` class in :code:`client_utils.py`." +"As for distributed evaluation on the clients, it's same as the quick-start " +"example by overriding the :code:`evaluate()` method insides the :code:" +"`XgbClient` class in :code:`client_utils.py`." msgstr "" -"至于客户端上的分布式评估,与快速启动示例相同,通过覆盖 :code:`client.py` 中 :code:`XgbClient` 类内部的 " -":code:`evaluate()` 方法。" +"至于客户端上的分布式评估,与快速启动示例相同,通过覆盖 :code:`client.py` 中 :" +"code:`XgbClient` 类内部的 :code:`evaluate()` 方法。" #: ../../source/tutorial-quickstart-xgboost.rst:831 #, fuzzy @@ -21373,21 +21625,21 @@ msgstr "运行模拟" #: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a" -" single machine or a cluster of machines." +"capabilities of Flower to simulate federated XGBoost training on either a " +"single machine or a cluster of machines." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"After importing all required packages, we define a :code:`main()` " -"function to perform the simulation process:" +"After importing all required packages, we define a :code:`main()` function " +"to perform the simulation process:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" "We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, " -"the clients won't need to pre-process their partitions again." +"processed data is stored in a :code:`list`. After the simulation begins, the " +"clients won't need to pre-process their partitions again." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:924 @@ -21396,8 +21648,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"After that, we start the simulation by calling " -":code:`fl.simulation.start_simulation`:" +"After that, we start the simulation by calling :code:`fl.simulation." +"start_simulation`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:995 @@ -21413,22 +21665,25 @@ msgstr "参数解析器" #: ../../source/tutorial-quickstart-xgboost.rst:1040 #, fuzzy msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server " -"and simulation, allowing users to specify different experimental " -"settings. Let's first see the sever side:" -msgstr "在 :code:`utils.py` 中,我们定义了客户端和服务器端的参数解析器,允许用户指定不同的实验设置。让我们先看看服务器端:" +"In :code:`utils.py`, we define the arguments parsers for clients, server and " +"simulation, allowing users to specify different experimental settings. Let's " +"first see the sever side:" +msgstr "" +"在 :code:`utils.py` 中,我们定义了客户端和服务器端的参数解析器,允许用户指定" +"不同的实验设置。让我们先看看服务器端:" #: ../../source/tutorial-quickstart-xgboost.rst:1086 #, fuzzy msgid "" "This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and" -" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" -" will do centralised evaluation and all functionalities for client " -"evaluation will be disabled." +"clients / FL rounds / participating clients / clients for evaluation, and " +"evaluation fashion. Note that with :code:`--centralised-eval`, the sever " +"will do centralised evaluation and all functionalities for client evaluation " +"will be disabled." msgstr "" -"这允许用户指定总客户数/FL 轮数/参与客户数/评估客户数以及评估方式。请注意,如果使用 :code:`--centralised-" -"eval`,服务器将进行集中评估,客户端评估的所有功能将被禁用。" +"这允许用户指定总客户数/FL 轮数/参与客户数/评估客户数以及评估方式。请注意,如" +"果使用 :code:`--centralised-eval`,服务器将进行集中评估,客户端评估的所有功能" +"将被禁用。" #: ../../source/tutorial-quickstart-xgboost.rst:1090 msgid "Then, the argument parser on client side:" @@ -21437,12 +21692,13 @@ msgstr "然后是客户端的参数解析器:" #: ../../source/tutorial-quickstart-xgboost.rst:1144 #, fuzzy msgid "" -"This defines various options for client data partitioning. Besides, " -"clients also have an option to conduct evaluation on centralised test set" -" by setting :code:`--centralised-eval`, as well as an option to perform " -"scaled learning rate based on the number of clients by setting :code" -":`--scaled-lr`." -msgstr "这定义了客户端数据分区的各种选项。此外,通过设置 :code:`-centralised-eval`,客户端还可以选择在集中测试集上进行评估。" +"This defines various options for client data partitioning. Besides, clients " +"also have an option to conduct evaluation on centralised test set by " +"setting :code:`--centralised-eval`, as well as an option to perform scaled " +"learning rate based on the number of clients by setting :code:`--scaled-lr`." +msgstr "" +"这定义了客户端数据分区的各种选项。此外,通过设置 :code:`-centralised-eval`," +"客户端还可以选择在集中测试集上进行评估。" #: ../../source/tutorial-quickstart-xgboost.rst:1148 msgid "We also have an argument parser for simulation:" @@ -21459,10 +21715,12 @@ msgstr "命令示例" #: ../../source/tutorial-quickstart-xgboost.rst:1231 #, fuzzy msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 " -"clients with exponential distribution for 50 rounds, we first start the " -"server as below:" -msgstr "为了在 5 个客户端上进行 50 轮指数分布的集中评估实验,我们首先启动服务器,如下所示:" +"To run a centralised evaluated experiment with bagging strategy on 5 clients " +"with exponential distribution for 50 rounds, we first start the server as " +"below:" +msgstr "" +"为了在 5 个客户端上进行 50 轮指数分布的集中评估实验,我们首先启动服务器,如下" +"所示:" #: ../../source/tutorial-quickstart-xgboost.rst:1238 msgid "Then, on each client terminal, we start the clients:" @@ -21475,12 +21733,13 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1250 #, fuzzy msgid "" -"The full `code `_ for this comprehensive example can be found in" -" :code:`examples/xgboost-comprehensive`." +"The full `code `_ for this comprehensive example can be found in :code:" +"`examples/xgboost-comprehensive`." msgstr "" -"此综合示例的全部`源代码 `_ 可在 :code:`examples/xgboost-comprehensive` 中找到。" +"此综合示例的全部`源代码 `_ 可在 :code:`examples/xgboost-comprehensive` 中找" +"到。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 msgid "Build a strategy from scratch" @@ -21490,42 +21749,43 @@ msgstr "从零开始制定策略" msgid "" "Welcome to the third part of the Flower federated learning tutorial. In " "previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies " -"can be used to customize the execution on both the server and the clients" -" (`part 2 `__)." -msgstr "" -"欢迎来到 Flower 联邦学习教程的第三部分。在本教程的前几部分,我们介绍了 PyTorch 和 Flower 的联邦学习(`part 1 " -"`__),并学习了如何使用策略来定制服务器和客户端的执行(`part 2 " -"`__)。" +"PyTorch and Flower (`part 1 `__) and we learned how strategies can be " +"used to customize the execution on both the server and the clients (`part 2 " +"`__)." +msgstr "" +"欢迎来到 Flower 联邦学习教程的第三部分。在本教程的前几部分,我们介绍了 " +"PyTorch 和 Flower 的联邦学习(`part 1 `__),并学习了如何使用策略来定" +"制服务器和客户端的执行(`part 2 `__)。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"In this notebook, we'll continue to customize the federated learning " -"system we built previously by creating a custom version of FedAvg (again," -" using `Flower `__ and `PyTorch " -"`__)." +"In this notebook, we'll continue to customize the federated learning system " +"we built previously by creating a custom version of FedAvg (again, using " +"`Flower `__ and `PyTorch `__)." msgstr "" -"在本笔记中,我们将通过创建 FedAvg 的自定义版本(再次使用 `Flower `__ 和 " -"`PyTorch `__),继续定制我们之前构建的联邦学习系统。" +"在本笔记中,我们将通过创建 FedAvg 的自定义版本(再次使用 `Flower `__ 和 `PyTorch `__),继续定制我们之前构建" +"的联邦学习系统。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the Flower community on Slack to connect, ask questions, and get help: " -"`Join Slack `__ 🌼 We'd love to hear from " -"you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"Flower community on Slack to connect, ask questions, and get help: `Join " +"Slack `__ 🌼 We'd love to hear from you in the " +"``#introductions`` channel! And if anything is unclear, head over to the " +"``#questions`` channel." msgstr "" -"`Star Flower on GitHub `__ ⭐️ 并加入 Slack " -"上的 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 " -"我们希望在 ``#introductions`` 频道听到您的声音!如果有任何不清楚的地方,请访问 ``#questions`` 频道。" +"`Star Flower on GitHub `__ ⭐️ 并加入 Slack 上" +"的 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何" +"不清楚的地方,请访问 ``#questions`` 频道。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 msgid "Let's build a new ``Strategy`` from scratch!" @@ -21570,19 +21830,20 @@ msgstr "现在我们已经安装了所有依赖项,可以导入本教程所需 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " -"GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." -msgstr "" -"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类型 > 硬件加速: GPU > " -"保存``)。但请注意,Google Colab 并非总能提供 GPU 加速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 " -"``DEVICE = torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU " -"加速,你应该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware acclerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." +msgstr "" +"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类" +"型 > 硬件加速: GPU > 保存``)。但请注意,Google Colab 并非总能提供 GPU 加" +"速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 ``DEVICE = " +"torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU 加速,你应" +"该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 @@ -21593,15 +21854,16 @@ msgstr "数据加载" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``. We introduce a new parameter" -" ``num_clients`` which allows us to call ``load_datasets`` with different" -" numbers of clients." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``. We introduce a new parameter " +"``num_clients`` which allows us to call ``load_datasets`` with different " +"numbers of clients." msgstr "" -"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 " -"个较小的数据集(每个数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` 中。我们引入了一个新参数 " -"``num_clients``,它允许我们使用不同数量的客户端调用 ``load_datasets``。" +"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 个较小的数据集(每" +"个数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` " +"中。我们引入了一个新参数 ``num_clients``,它允许我们使用不同数量的客户端调用 " +"``load_datasets``。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 @@ -21613,9 +21875,11 @@ msgstr "模型培训/评估" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"Let's continue with the usual model definition (including " -"``set_parameters`` and ``get_parameters``), training and test functions:" -msgstr "让我们继续使用常见的模型定义(包括 `set_parameters` 和 `get_parameters`)、训练和测试函数:" +"Let's continue with the usual model definition (including ``set_parameters`` " +"and ``get_parameters``), training and test functions:" +msgstr "" +"让我们继续使用常见的模型定义(包括 `set_parameters` 和 `get_parameters`)、训" +"练和测试函数:" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 @@ -21625,14 +21889,14 @@ msgstr "Flower 客户端" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"To implement the Flower client, we (again) create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " -"``cid`` to the client and use it log additional details:" +"To implement the Flower client, we (again) create a subclass of ``flwr." +"client.NumPyClient`` and implement the three methods ``get_parameters``, " +"``fit``, and ``evaluate``. Here, we also pass the ``cid`` to the client and " +"use it log additional details:" msgstr "" -"为了实现 Flower 客户端,我们(再次)创建了 ``flwr.client.NumPyClient`` 的子类,并实现了 " -"``get_parameters``、``fit`` 和 ``evaluate``三个方法。在这里,我们还将 ``cid`` " -"传递给客户端,并使用它记录其他详细信息:" +"为了实现 Flower 客户端,我们(再次)创建了 ``flwr.client.NumPyClient`` 的子" +"类,并实现了 ``get_parameters``、``fit`` 和 ``evaluate``三个方法。在这里,我" +"们还将 ``cid`` 传递给客户端,并使用它记录其他详细信息:" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 msgid "Let's test what we have so far before we continue:" @@ -21644,14 +21908,15 @@ msgstr "从零开始构建策略" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher" -" learning rate (potentially also other hyperparameters) to the optimizer " -"of a fraction of the clients. We will keep the sampling of the clients as" -" it is in ``FedAvg`` and then change the configuration dictionary (one of" -" the ``FitIns`` attributes)." +"Let’s overwrite the ``configure_fit`` method such that it passes a higher " +"learning rate (potentially also other hyperparameters) to the optimizer of a " +"fraction of the clients. We will keep the sampling of the clients as it is " +"in ``FedAvg`` and then change the configuration dictionary (one of the " +"``FitIns`` attributes)." msgstr "" -"让我们重写 ``configure_fit`` 方法,使其向一部分客户的优化器传递更高的学习率(可能还有其他超参数)。我们将保持 " -"``FedAvg`` 中的客户端采样,然后更改配置字典(``FitIns`` 属性之一)。" +"让我们重写 ``configure_fit`` 方法,使其向一部分客户的优化器传递更高的学习率" +"(可能还有其他超参数)。我们将保持 ``FedAvg`` 中的客户端采样,然后更改配置字" +"典(``FitIns`` 属性之一)。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 msgid "" @@ -21667,17 +21932,18 @@ msgstr "回顾" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom" -" strategy enables granular control over client node configuration, result" -" aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``." -" To make custom strategies even more powerful, you can pass custom " -"functions to the constructor of your new class (``__init__``) and then " -"call these functions whenever needed." +"In this notebook, we’ve seen how to implement a custom strategy. A custom " +"strategy enables granular control over client node configuration, result " +"aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``. To " +"make custom strategies even more powerful, you can pass custom functions to " +"the constructor of your new class (``__init__``) and then call these " +"functions whenever needed." msgstr "" -"在本笔记中,我们了解了如何实施自定义策略。自定义策略可以对客户端节点配置、结果聚合等进行细粒度控制。要定义自定义策略,只需覆盖(抽象)基类 " -"``Strategy`` " -"的抽象方法即可。为使自定义策略更加强大,您可以将自定义函数传递给新类的构造函数(`__init__``),然后在需要时调用这些函数。" +"在本笔记中,我们了解了如何实施自定义策略。自定义策略可以对客户端节点配置、结" +"果聚合等进行细粒度控制。要定义自定义策略,只需覆盖(抽象)基类 ``Strategy`` " +"的抽象方法即可。为使自定义策略更加强大,您可以将自定义函数传递给新类的构造函" +"数(`__init__``),然后在需要时调用这些函数。" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 @@ -21685,11 +21951,11 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"Before you continue, make sure to join the Flower community on Slack: " -"`Join Slack `__" +"Before you continue, make sure to join the Flower community on Slack: `Join " +"Slack `__" msgstr "" -"在继续之前,请务必加入 Slack 上的 Flower 社区:`Join Slack `__" +"在继续之前,请务必加入 Slack 上的 Flower 社区:`Join Slack `__" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 @@ -21697,19 +21963,21 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd " -"also love to hear who you are in ``#introductions``!" -msgstr "如果您需要帮助,我们有专门的 ``#questions`` 频道,但我们也很乐意在 ``#introductions`` 中了解您是谁!" +"There's a dedicated ``#questions`` channel if you need help, but we'd also " +"love to hear who you are in ``#introductions``!" +msgstr "" +"如果您需要帮助,我们有专门的 ``#questions`` 频道,但我们也很乐意在 " +"``#introductions`` 中了解您是谁!" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 " -"`__ introduces ``Client``, the flexible API underlying " -"``NumPyClient``." +"The `Flower Federated Learning Tutorial - Part 4 `__ introduces " +"``Client``, the flexible API underlying ``NumPyClient``." msgstr "" -"Flower联邦学习教程 - 第4部分 `__ 介绍了``Client``,它是``NumPyClient``底层的灵活应用程序接口。" +"Flower联邦学习教程 - 第4部分 `__ 介绍了``Client``,它是``NumPyClient``底" +"层的灵活应用程序接口。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 msgid "Customize the client" @@ -21717,37 +21985,39 @@ msgstr "自定义客户端" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In " -"the previous parts of this tutorial, we introduced federated learning " -"with PyTorch and Flower (`part 1 `__), we learned how " -"strategies can be used to customize the execution on both the server and " -"the clients (`part 2 `__), and we built our own " -"custom strategy from scratch (`part 3 `__)." -msgstr "" -"欢迎来到 Flower 联邦学习教程的第四部分。在本教程的前几部分中,我们介绍了 PyTorch 和 Flower 的联邦学习(`part 1 " -"`__),了解了如何使用策略来定制服务器和客户端的执行(`part 2 " -"`__),并从头开始构建了我们自己的定制策略(`part 3 " -"`__)。" +"Welcome to the fourth part of the Flower federated learning tutorial. In the " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__), we learned how strategies can be used " +"to customize the execution on both the server and the clients (`part 2 " +"`__), and we built our own custom strategy from scratch (`part " +"3 `__)." +msgstr "" +"欢迎来到 Flower 联邦学习教程的第四部分。在本教程的前几部分中,我们介绍了 " +"PyTorch 和 Flower 的联邦学习(`part 1 `__),了解了如何使用策略来定制" +"服务器和客户端的执行(`part 2 `__),并从头开始构建了我们自己的" +"定制策略(`part 3 `__)。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new " -"baseclass for building clients, simply named ``Client``. In previous " -"parts of this tutorial, we've based our client on ``NumPyClient``, a " -"convenience class which makes it easy to work with machine learning " -"libraries that have good NumPy interoperability. With ``Client``, we gain" -" a lot of flexibility that we didn't have before, but we'll also have to " -"do a few things the we didn't have to do before." +"In this notebook, we revisit ``NumPyClient`` and introduce a new baseclass " +"for building clients, simply named ``Client``. In previous parts of this " +"tutorial, we've based our client on ``NumPyClient``, a convenience class " +"which makes it easy to work with machine learning libraries that have good " +"NumPy interoperability. With ``Client``, we gain a lot of flexibility that " +"we didn't have before, but we'll also have to do a few things the we didn't " +"have to do before." msgstr "" -"在本笔记中,我们将重温 ``NumPyClient`` 并引入一个用于构建客户端的新基类,简单命名为 " -"``Client``。在本教程的前几部分中,我们的客户端基于``NumPyClient``,这是一个便捷类,可以让我们轻松地与具有良好 NumPy" -" 互操作性的机器学习库协同工作。有了 ``Client``,我们获得了很多以前没有的灵活性,但我们也必须做一些以前不需要做的事情。" +"在本笔记中,我们将重温 ``NumPyClient`` 并引入一个用于构建客户端的新基类,简单" +"命名为 ``Client``。在本教程的前几部分中,我们的客户端基于``NumPyClient``,这" +"是一个便捷类,可以让我们轻松地与具有良好 NumPy 互操作性的机器学习库协同工作。" +"有了 ``Client``,我们获得了很多以前没有的灵活性,但我们也必须做一些以前不需要" +"做的事情。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 msgid "" @@ -21762,12 +22032,12 @@ msgstr "步骤 0:准备工作" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``." msgstr "" -"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成十个较小的数据集(每个数据集又分为训练集和验证集),并将所有数据都封装在各自的 " -"``DataLoader`` 中。" +"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成十个较小的数据集(每个" +"数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` 中。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 msgid "Step 1: Revisiting NumPyClient" @@ -21775,14 +22045,14 @@ msgstr "步骤 1:重温 NumPyClient" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"So far, we've implemented our client by subclassing " -"``flwr.client.NumPyClient``. The three methods we implemented are " -"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " -"creation of instances of this class in a function called ``client_fn``:" +"So far, we've implemented our client by subclassing ``flwr.client." +"NumPyClient``. The three methods we implemented are ``get_parameters``, " +"``fit``, and ``evaluate``. Finally, we wrap the creation of instances of " +"this class in a function called ``client_fn``:" msgstr "" -"到目前为止,我们通过子类化 ``flwr.client.NumPyClient`` " -"实现了我们的客户端。我们实现了三个方法:``get_parameters``, ``fit`, 和``evaluate``。最后,我们用一个名为 " -"``client_fn`` 的函数来创建该类的实例:" +"到目前为止,我们通过子类化 ``flwr.client.NumPyClient`` 实现了我们的客户端。我" +"们实现了三个方法:``get_parameters``, ``fit`, 和``evaluate``。最后,我们用一" +"个名为 ``client_fn`` 的函数来创建该类的实例:" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 msgid "" @@ -21791,8 +22061,9 @@ msgid "" "``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " "``numpyclient_fn``. Let's run it to see the output we get:" msgstr "" -"我们以前见过这种情况,目前没有什么新东西。与之前的笔记相比,唯一*小*的不同是命名,我们把 ``FlowerClient`` 改成了 " -"``FlowerNumPyClient``,把 `client_fn` 改成了 ``numpyclient_fn``。让我们运行它看看输出结果:" +"我们以前见过这种情况,目前没有什么新东西。与之前的笔记相比,唯一*小*的不同是" +"命名,我们把 ``FlowerClient`` 改成了 ``FlowerNumPyClient``,把 `client_fn` 改" +"成了 ``numpyclient_fn``。让我们运行它看看输出结果:" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 msgid "" @@ -21805,32 +22076,32 @@ msgid "" "Let's dive a little bit deeper and discuss how Flower executes this " "simulation. Whenever a client is selected to do some work, " "``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and " -"the data)." +"instance of our ``FlowerNumPyClient`` (along with loading the model and the " +"data)." msgstr "" -"让我们再深入一点,讨论一下 Flower 是如何执行模拟的。每当一个客户端被选中进行工作时,`start_simulation`` 就会调用函数 " -"`numpyclient_fn` 来创建我们的 ``FlowerNumPyClient`` 实例(同时加载模型和数据)。" +"让我们再深入一点,讨论一下 Flower 是如何执行模拟的。每当一个客户端被选中进行" +"工作时,`start_simulation`` 就会调用函数 `numpyclient_fn` 来创建我们的 " +"``FlowerNumPyClient`` 实例(同时加载模型和数据)。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" "But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " -"makes it look like a subclass of ``flwr.client.Client``, not " -"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " -"know how to handle ``NumPyClient``'s, it only knows how to handle " -"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " -"top of ``Client``." -msgstr "" -"但令人惊讶的部分也许就在这里: Flower 实际上并不直接使用 ``FlowerNumPyClient`` " -"对象。相反,它封装了该对象,使其看起来像 ``flwr.client.Client`` 的子类,而不是 " -"``flwr.client.NumPyClient``。事实上,Flower 核心框架不知道如何处理 " -"``NumPyClient``,它只知道如何处理 ``Client``。``NumPyClient`` " +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to makes " +"it look like a subclass of ``flwr.client.Client``, not ``flwr.client." +"NumPyClient``. In fact, the Flower core framework doesn't know how to handle " +"``NumPyClient``'s, it only knows how to handle ``Client``'s. ``NumPyClient`` " +"is just a convenience abstraction built on top of ``Client``." +msgstr "" +"但令人惊讶的部分也许就在这里: Flower 实际上并不直接使用 " +"``FlowerNumPyClient`` 对象。相反,它封装了该对象,使其看起来像 ``flwr.client." +"Client`` 的子类,而不是 ``flwr.client.NumPyClient``。事实上,Flower 核心框架" +"不知道如何处理 ``NumPyClient``,它只知道如何处理 ``Client``。``NumPyClient`` " "只是建立在``Client``之上的便捷抽象类。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on " -"top of ``Client``." +"Instead of building on top of ``NumPyClient``, we can directly build on top " +"of ``Client``." msgstr "与其在 ``NumPyClient`` 上构建,我们可以直接在 ``Client`` 上构建。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 @@ -21839,70 +22110,80 @@ msgstr "步骤 2:从 ``NumPyClient`` 移至 ``Client``" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 msgid "" -"Let's try to do the same thing using ``Client`` instead of " -"``NumPyClient``." +"Let's try to do the same thing using ``Client`` instead of ``NumPyClient``." msgstr "让我们尝试使用 ``Client`` 代替 ``NumPyClient`` 做同样的事情。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta " -"make sure our new ``Client``-based client works, right?" -msgstr "在详细讨论代码之前,让我们试着运行它!必须确保我们基于 ``Client`` 的新客户端能正常运行,对吗?" +"Before we discuss the code in more detail, let's try to run it! Gotta make " +"sure our new ``Client``-based client works, right?" +msgstr "" +"在详细讨论代码之前,让我们试着运行它!必须确保我们基于 ``Client`` 的新客户端" +"能正常运行,对吗?" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 msgid "" "That's it, we're now using ``Client``. It probably looks similar to what " "we've done with ``NumPyClient``. So what's the difference?" -msgstr "就是这样,我们现在开始使用 ``Client``。它看起来可能与我们使用 ``NumPyClient`` 所做的类似。那么有什么不同呢?" +msgstr "" +"就是这样,我们现在开始使用 ``Client``。它看起来可能与我们使用 " +"``NumPyClient`` 所做的类似。那么有什么不同呢?" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"First of all, it's more code. But why? The difference comes from the fact " +"that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the network, " +"it eventually needs to turn these parameters into ``bytes``. Turning " +"parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " "serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." -msgstr "" -"首先,它的代码更多。但为什么呢?区别在于 ``Client`` 希望我们处理参数的序列化和反序列化。Flower " -"要想通过网络发送参数,最终需要将这些参数转化为 ``字节``。把参数(例如 NumPy 的 ``ndarray`` " -"参数)变成原始字节叫做序列化。将原始字节转换成更有用的东西(如 NumPy ``ndarray`)称为反序列化。Flower " -"需要同时做这两件事:它需要在服务器端序列化参数并将其发送到客户端,客户端需要反序列化参数以便将其用于本地训练,然后再次序列化更新后的参数并将其发送回服务器,服务器(最后)再次反序列化参数以便将其与从其他客户端接收到的更新汇总在一起。" +"``ndarray``'s) is called deserialization. Flower needs to do both: it needs " +"to serialize parameters on the server-side and send them to the client, the " +"client needs to deserialize them to use them for local training, and then " +"serialize the updated parameters again to send them back to the server, " +"which (finally!) deserializes them again in order to aggregate them with the " +"updates received from other clients." +msgstr "" +"首先,它的代码更多。但为什么呢?区别在于 ``Client`` 希望我们处理参数的序列化" +"和反序列化。Flower 要想通过网络发送参数,最终需要将这些参数转化为 ``字节``。" +"把参数(例如 NumPy 的 ``ndarray`` 参数)变成原始字节叫做序列化。将原始字节转" +"换成更有用的东西(如 NumPy ``ndarray`)称为反序列化。Flower 需要同时做这两件" +"事:它需要在服务器端序列化参数并将其发送到客户端,客户端需要反序列化参数以便" +"将其用于本地训练,然后再次序列化更新后的参数并将其发送回服务器,服务器(最" +"后)再次反序列化参数以便将其与从其他客户端接收到的更新汇总在一起。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" "The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It " -"can do so because it expects you to return parameters as NumPy ndarray's," -" and it knows how to handle these. This makes working with machine " -"learning libraries that have good NumPy support (most of them) a breeze." +"NumPyClient takes care of serialization and deserialization for you. It can " +"do so because it expects you to return parameters as NumPy ndarray's, and it " +"knows how to handle these. This makes working with machine learning " +"libraries that have good NumPy support (most of them) a breeze." msgstr "" -"Client 与 NumPyClient 之间的唯一**真正区别在于,NumPyClient " -"会为你处理序列化和反序列化。NumPyClient之所以能做到这一点,是因为它预计你会以NumPy " -"ndarray的形式返回参数,而且它知道如何处理这些参数。这使得与具有良好 NumPy 支持的大多数机器学习库一起工作变得轻而易举。" +"Client 与 NumPyClient 之间的唯一**真正区别在于,NumPyClient 会为你处理序列化" +"和反序列化。NumPyClient之所以能做到这一点,是因为它预计你会以NumPy ndarray的" +"形式返回参数,而且它知道如何处理这些参数。这使得与具有良好 NumPy 支持的大多数" +"机器学习库一起工作变得轻而易举。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"In terms of API, there's one major difference: all methods in Client take " +"exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return exactly " +"one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " "``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." -msgstr "" -"在 API 方面,有一个主要区别:Client 中的所有方法都只接受一个参数(例如,``Client.fit`` 中的 " -"``FitIns``),并只返回一个值(例如,``Client.fit`` 中的 " -"``FitRes``)。另一方面,``NumPyClient``中的方法有多个参数(例如,``NumPyClient.fit``中的``parameters``和``config``)和多个返回值(例如,``NumPyClient.fit``中的``parameters``、``num_example``和``metrics``)。在" -" ``Client`` 中的这些 ``*Ins`` 和 ``*Res`` 对象封装了你在 ``NumPyClient`` 中习惯使用的所有单个值。" +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return " +"values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These ``*Ins`` " +"and ``*Res`` objects in ``Client`` wrap all the individual values you're " +"used to from ``NumPyClient``." +msgstr "" +"在 API 方面,有一个主要区别:Client 中的所有方法都只接受一个参数(例如," +"``Client.fit`` 中的 ``FitIns``),并只返回一个值(例如,``Client.fit`` 中的 " +"``FitRes``)。另一方面,``NumPyClient``中的方法有多个参数(例如," +"``NumPyClient.fit``中的``parameters``和``config``)和多个返回值(例如," +"``NumPyClient.fit``中的``parameters``、``num_example``和``metrics``)。在 " +"``Client`` 中的这些 ``*Ins`` 和 ``*Res`` 对象封装了你在 ``NumPyClient`` 中习" +"惯使用的所有单个值。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 msgid "Step 3: Custom serialization" @@ -21918,20 +22199,22 @@ msgstr "下面我们将通过一个简单的示例来探讨如何实现自定义 msgid "" "But first what is serialization? Serialization is just the process of " "converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an " -"object. This is very useful for network communication. Indeed, without " +"deserialization is the process of converting raw bytes back into an object. " +"This is very useful for network communication. Indeed, without " "serialization, you could not just a Python object through the internet." msgstr "" -"首先,什么是序列化?序列化只是将对象转换为原始字节的过程,同样重要的是,反序列化是将原始字节转换回对象的过程。这对网络通信非常有用。事实上,如果没有序列化,你就无法通过互联网传输一个" -" Python 对象。" +"首先,什么是序列化?序列化只是将对象转换为原始字节的过程,同样重要的是,反序" +"列化是将原始字节转换回对象的过程。这对网络通信非常有用。事实上,如果没有序列" +"化,你就无法通过互联网传输一个 Python 对象。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 msgid "" -"Federated Learning relies heavily on internet communication for training " -"by sending Python objects back and forth between the clients and the " -"server. This means that serialization is an essential part of Federated " -"Learning." -msgstr "通过在客户端和服务器之间来回发送 Python 对象,联合学习在很大程度上依赖于互联网通信进行训练。这意味着序列化是联邦学习的重要组成部分。" +"Federated Learning relies heavily on internet communication for training by " +"sending Python objects back and forth between the clients and the server. " +"This means that serialization is an essential part of Federated Learning." +msgstr "" +"通过在客户端和服务器之间来回发送 Python 对象,联合学习在很大程度上依赖于互联" +"网通信进行训练。这意味着序列化是联邦学习的重要组成部分。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 msgid "" @@ -21943,9 +22226,10 @@ msgid "" "entries), converting them to a sparse matrix can greatly improve their " "bytesize." msgstr "" -"在下面的章节中,我们将编写一个基本示例,在发送包含参数的 ``ndarray`` 前,我们将首先把 ``ndarray`` " -"转换为稀疏矩阵,而不是发送序列化版本。这种技术可以用来节省带宽,因为在某些情况下,模型的参数是稀疏的(包含许多 0 " -"条目),将它们转换成稀疏矩阵可以大大提高它们的字节数。" +"在下面的章节中,我们将编写一个基本示例,在发送包含参数的 ``ndarray`` 前,我们" +"将首先把 ``ndarray`` 转换为稀疏矩阵,而不是发送序列化版本。这种技术可以用来节" +"省带宽,因为在某些情况下,模型的参数是稀疏的(包含许多 0 条目),将它们转换成" +"稀疏矩阵可以大大提高它们的字节数。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 msgid "Our custom serialization/deserialization functions" @@ -21953,17 +22237,18 @@ msgstr "我们的定制序列化/反序列化功能" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"This is where the real serialization/deserialization will happen, " -"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"This is where the real serialization/deserialization will happen, especially " +"in ``ndarray_to_sparse_bytes`` for serialization and " "``sparse_bytes_to_ndarray`` for deserialization." msgstr "" -"这才是真正的序列化/反序列化,尤其是在用于序列化的 ``ndarray_too_sparse_bytes`` 和用于反序列化的 " -"``sparse_bytes_too_ndarray`` 中。" +"这才是真正的序列化/反序列化,尤其是在用于序列化的 " +"``ndarray_too_sparse_bytes`` 和用于反序列化的 ``sparse_bytes_too_ndarray`` " +"中。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert " -"our arrays." +"Note that we imported the ``scipy.sparse`` library in order to convert our " +"arrays." msgstr "请注意,为了转换数组,我们导入了 ``scipy.sparse`` 库。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 @@ -21972,34 +22257,35 @@ msgstr "客户端" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " -"will just have to call our custom functions in our " -"``flwr.client.Client``." -msgstr "为了能够将我们的 ``ndarray`` 序列化为稀疏参数,我们只需在 ``flwr.client.Client`` 中调用我们的自定义函数。" +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we will " +"just have to call our custom functions in our ``flwr.client.Client``." +msgstr "" +"为了能够将我们的 ``ndarray`` 序列化为稀疏参数,我们只需在 ``flwr.client." +"Client`` 中调用我们的自定义函数。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 msgid "" "Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` " -"defined above." +"from our network using our custom ``ndarrays_to_sparse_parameters`` defined " +"above." msgstr "" -"事实上,在 `get_parameters` 中,我们需要使用上文定义的自定义 `ndarrays_too_sparse_parameters` " -"序列化从网络中获取的参数。" +"事实上,在 `get_parameters` 中,我们需要使用上文定义的自定义 " +"`ndarrays_too_sparse_parameters` 序列化从网络中获取的参数。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" "In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we " -"need to serialize our local results with " -"``ndarrays_to_sparse_parameters``." +"server using our custom ``sparse_parameters_to_ndarrays`` and then we need " +"to serialize our local results with ``ndarrays_to_sparse_parameters``." msgstr "" -"在 ``fit`` 中,我们首先需要使用自定义的 ``sparse_parameters_to_ndarrays`` " -"反序列化来自服务器的参数,然后使用 ``ndarrays_to_sparse_parameters`` 序列化本地结果。" +"在 ``fit`` 中,我们首先需要使用自定义的 ``sparse_parameters_to_ndarrays`` 反" +"序列化来自服务器的参数,然后使用 ``ndarrays_to_sparse_parameters`` 序列化本地" +"结果。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters " -"with our custom function." +"In ``evaluate``, we will only need to deserialize the global parameters with " +"our custom function." msgstr "在 ``evaluate`` 中,我们只需要用自定义函数反序列化全局参数。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 @@ -22008,14 +22294,14 @@ msgstr "服务器端" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change " -"the serialization and deserialization here, we only need to reimplement " -"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" -" functions of the strategy will be inherited from the super class " -"``FedAvg``." +"For this example, we will just use ``FedAvg`` as a strategy. To change the " +"serialization and deserialization here, we only need to reimplement the " +"``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other " +"functions of the strategy will be inherited from the super class ``FedAvg``." msgstr "" -"在本例中,我们将只使用 ``FedAvg`` 作为策略。要改变这里的序列化和反序列化,我们只需重新实现 ``FedAvg`` 的 " -"``evaluate`` 和 ``aggregate_fit`` 函数。策略的其他函数将从超类 ``FedAvg`` 继承。" +"在本例中,我们将只使用 ``FedAvg`` 作为策略。要改变这里的序列化和反序列化,我" +"们只需重新实现 ``FedAvg`` 的 ``evaluate`` 和 ``aggregate_fit`` 函数。策略的其" +"他函数将从超类 ``FedAvg`` 继承。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 msgid "As you can see only one line as change in ``evaluate``:" @@ -22039,22 +22325,27 @@ msgstr "现在我们可以运行自定义序列化示例!" msgid "" "In this part of the tutorial, we've seen how we can build clients by " "subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine " -"learning libraries that have good NumPy interoperability. ``Client`` is a" -" more flexible abstraction that allows us to do things that are not " -"possible in ``NumPyClient``. In order to do so, it requires us to handle " -"parameter serialization and deserialization ourselves." -msgstr "" -"在本部分教程中,我们已经了解了如何通过子类化 ``NumPyClient`` 或 ``Client`` 来构建客户端。NumPyClient " -"\"是一个便捷的抽象类,可以让我们更容易地与具有良好NumPy互操作性的机器学习库一起工作。``Client``是一个更灵活的抽象类,允许我们做一些在`NumPyClient``中做不到的事情。为此,它要求我们自己处理参数序列化和反序列化。" +"convenience abstraction that makes it easier to work with machine learning " +"libraries that have good NumPy interoperability. ``Client`` is a more " +"flexible abstraction that allows us to do things that are not possible in " +"``NumPyClient``. In order to do so, it requires us to handle parameter " +"serialization and deserialization ourselves." +msgstr "" +"在本部分教程中,我们已经了解了如何通过子类化 ``NumPyClient`` 或 ``Client`` 来" +"构建客户端。NumPyClient \"是一个便捷的抽象类,可以让我们更容易地与具有良好" +"NumPy互操作性的机器学习库一起工作。``Client``是一个更灵活的抽象类,允许我们做" +"一些在`NumPyClient``中做不到的事情。为此,它要求我们自己处理参数序列化和反序" +"列化。" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"This is the final part of the Flower tutorial (for now!), " -"congratulations! You're now well equipped to understand the rest of the " -"documentation. There are many topics we didn't cover in the tutorial, we " -"recommend the following resources:" -msgstr "这暂时是 Flower 教程的最后一部分,恭喜您!您现在已经具备了理解其余文档的能力。本教程还有许多内容没有涉及,我们推荐您参考以下资源:" +"This is the final part of the Flower tutorial (for now!), congratulations! " +"You're now well equipped to understand the rest of the documentation. There " +"are many topics we didn't cover in the tutorial, we recommend the following " +"resources:" +msgstr "" +"这暂时是 Flower 教程的最后一部分,恭喜您!您现在已经具备了理解其余文档的能" +"力。本教程还有许多内容没有涉及,我们推荐您参考以下资源:" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 msgid "`Read Flower Docs `__" @@ -22062,21 +22353,24 @@ msgstr "阅读Flower文档 `__" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"`Check out Flower Code Examples " -"`__" -msgstr "查看 Flower 代码示例 `__" +"`Check out Flower Code Examples `__" +msgstr "" +"查看 Flower 代码示例 `__" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"`Use Flower Baselines for your research " -"`__" -msgstr "使用 \"Flower Baselines \"进行研究 `__" +"`Use Flower Baselines for your research `__" +msgstr "" +"使用 \"Flower Baselines \"进行研究 `__" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"`Watch Flower Summit 2023 videos `__" -msgstr "观看 2023 年Flower峰会视频 `__" +"`Watch Flower Summit 2023 videos `__" +msgstr "" +"观看 2023 年Flower峰会视频 `__" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 msgid "Get started with Flower" @@ -22091,13 +22385,13 @@ msgstr "欢迎阅读Flower联邦学习教程!" #, fuzzy msgid "" "In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In " -"part 1, we use PyTorch for the model training pipeline and data loading. " -"In part 2, we continue to federate the PyTorch-based pipeline using " -"Flower." +"`Flower Datasets `__ and PyTorch. In part " +"1, we use PyTorch for the model training pipeline and data loading. In part " +"2, we continue to federate the PyTorch-based pipeline using Flower." msgstr "" -"在本笔记中,我们将使用 Flower 和 PyTorch 构建一个联邦学习系统。在第一部分中,我们使用 PyTorch " -"进行模型训练和数据加载。在第二部分中,我们将继续使用 Flower 联邦化基于 PyTorch 的框架。" +"在本笔记中,我们将使用 Flower 和 PyTorch 构建一个联邦学习系统。在第一部分中," +"我们使用 PyTorch 进行模型训练和数据加载。在第二部分中,我们将继续使用 Flower " +"联邦化基于 PyTorch 的框架。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 msgid "Let's get stated!" @@ -22113,26 +22407,28 @@ msgstr "在开始编写实际代码之前,让我们先确保我们已经准备 #, fuzzy msgid "" "Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " -"(``flwr``):" -msgstr "接下来,我们为 PyTorch(`torch`` 和`torchvision``)和 Flower(`flwr`)安装必要的软件包:" +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower (``flwr``):" +msgstr "" +"接下来,我们为 PyTorch(`torch`` 和`torchvision``)和 Flower(`flwr`)安装必" +"要的软件包:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 #, fuzzy msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" -" GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware accelerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." msgstr "" -"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类型 > 硬件加速: GPU > " -"保存``)。但请注意,Google Colab 并非总能提供 GPU 加速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 " -"``DEVICE = torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU " -"加速,你应该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" +"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类" +"型 > 硬件加速: GPU > 保存``)。但请注意,Google Colab 并非总能提供 GPU 加" +"速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 ``DEVICE = " +"torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU 加速,你应" +"该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 msgid "Loading the data" @@ -22141,77 +22437,86 @@ msgstr "加载数据" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 #, fuzzy msgid "" -"Federated learning can be applied to many different types of tasks across" -" different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular " -"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " -"distinguish between images from ten different classes: 'airplane', " -"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " -"'truck'." +"Federated learning can be applied to many different types of tasks across " +"different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular CIFAR-10 " +"dataset. CIFAR-10 can be used to train image classifiers that distinguish " +"between images from ten different classes: 'airplane', 'automobile', 'bird', " +"'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and 'truck'." msgstr "" -"联邦学习可应用于不同领域的多种不同类型任务。在本教程中,我们将通过在流行的 CIFAR-10 数据集上训练一个简单的卷积神经网络 (CNN) " -"来介绍联合学习。CIFAR-10 可用于训练图像分类器,以区分来自十个不同类别的图像:" +"联邦学习可应用于不同领域的多种不同类型任务。在本教程中,我们将通过在流行的 " +"CIFAR-10 数据集上训练一个简单的卷积神经网络 (CNN) 来介绍联合学习。CIFAR-10 可" +"用于训练图像分类器,以区分来自十个不同类别的图像:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" "We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the" -" original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely " -"for experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the " -"data is naturally partitioned)." -msgstr "" -"我们通过将原始 CIFAR-10 数据集拆分成多个分区来模拟来自多个组织的多个数据集(也称为联邦学习中的 \"跨分区 " -"\"设置)。每个分区代表一个组织的数据。我们这样做纯粹是为了实验目的,在现实世界中不需要拆分数据,因为每个组织都已经有了自己的数据(所以数据是自然分区的)。" +"called the \"cross-silo\" setting in federated learning) by splitting the " +"original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely for " +"experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the data " +"is naturally partitioned)." +msgstr "" +"我们通过将原始 CIFAR-10 数据集拆分成多个分区来模拟来自多个组织的多个数据集" +"(也称为联邦学习中的 \"跨分区 \"设置)。每个分区代表一个组织的数据。我们这样" +"做纯粹是为了实验目的,在现实世界中不需要拆分数据,因为每个组织都已经有了自己" +"的数据(所以数据是自然分区的)。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 #, fuzzy msgid "" -"Each organization will act as a client in the federated learning system. " -"So having ten organizations participate in a federation means having ten " +"Each organization will act as a client in the federated learning system. So " +"having ten organizations participate in a federation means having ten " "clients connected to the federated learning server." -msgstr "每个组织都将充当联邦学习系统中的客户端。因此,有十个组织参与联邦学习,就意味着有十个客户端连接到联邦学习服务器:" +msgstr "" +"每个组织都将充当联邦学习系统中的客户端。因此,有十个组织参与联邦学习,就意味" +"着有十个客户端连接到联邦学习服务器:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 msgid "" "Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training " -"and test set for each edge device and wrap each of them into a PyTorch " +"datasets`` that partitions the CIFAR-10. We will create small training and " +"test set for each edge device and wrap each of them into a PyTorch " "``DataLoader``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 msgid "" "We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten " -"different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4500 training examples and 500 validation examples. There's also a " -"single ``testloader`` (we did not split the test set). Again, this is " -"only necessary for building research or educational systems, actual " -"federated learning systems have their data naturally distributed across " -"multiple partitions." -msgstr "" -"现在,我们有一个包含十个训练集和十个验证集(`trainloaders`` 和`valloaders``)的列表,代表十个不同组织的数据。每对 " -"``trainloader``/``valloader`` 都包含 4500 个训练示例和 500 个验证数据。还有一个单独的 " -"``测试加载器``(我们没有拆分测试集)。同样,这只有在构建研究或教育系统时才有必要,实际的联邦学习系统的数据自然分布在多个分区中。" +"(``trainloaders`` and ``valloaders``) representing the data of ten different " +"organizations. Each ``trainloader``/``valloader`` pair contains 4500 " +"training examples and 500 validation examples. There's also a single " +"``testloader`` (we did not split the test set). Again, this is only " +"necessary for building research or educational systems, actual federated " +"learning systems have their data naturally distributed across multiple " +"partitions." +msgstr "" +"现在,我们有一个包含十个训练集和十个验证集(`trainloaders`` 和`valloaders``)" +"的列表,代表十个不同组织的数据。每对 ``trainloader``/``valloader`` 都包含 " +"4500 个训练示例和 500 个验证数据。还有一个单独的 ``测试加载器``(我们没有拆分" +"测试集)。同样,这只有在构建研究或教育系统时才有必要,实际的联邦学习系统的数" +"据自然分布在多个分区中。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 msgid "" "Let's take a look at the first batch of images and labels in the first " "training set (i.e., ``trainloaders[0]``) before we move on:" -msgstr "在继续之前,让我们先看看第一个训练集中的第一批图像和标签(即 ``trainloaders[0]``):" +msgstr "" +"在继续之前,让我们先看看第一个训练集中的第一批图像和标签(即 " +"``trainloaders[0]``):" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 msgid "" "The output above shows a random batch of images from the first " "``trainloader`` in our list of ten ``trainloaders``. It also prints the " "labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another " -"batch of images." +"we've seen above). If you run the cell again, you should see another batch " +"of images." msgstr "" -"上面的输出显示了来自十个 \"trainloader \"列表中第一个 \"trainloader " -"\"的随机图像。它还打印了与每幅图像相关的标签(即我们上面看到的十个可能标签之一)。如果您再次运行该单元,应该会看到另一批图像。" +"上面的输出显示了来自十个 \"trainloader \"列表中第一个 \"trainloader \"的随机" +"图像。它还打印了与每幅图像相关的标签(即我们上面看到的十个可能标签之一)。如" +"果您再次运行该单元,应该会看到另一批图像。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 msgid "Step 1: Centralized Training with PyTorch" @@ -22223,12 +22528,12 @@ msgid "" "network. This introduction assumes basic familiarity with PyTorch, so it " "doesn't cover the PyTorch-related aspects in full detail. If you want to " "dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ " -"`__." +"MINUTE BLITZ `__." msgstr "" -"接下来,我们将使用 PyTorch 来定义一个简单的卷积神经网络。本介绍假定您对 PyTorch 有基本的了解,因此不会详细介绍与 PyTorch" -" 相关的内容。如果你想更深入地了解 PyTorch,我们推荐你阅读 `DEEP LEARNING WITH PYTORCH: a 60 " -"minute blitz " +"接下来,我们将使用 PyTorch 来定义一个简单的卷积神经网络。本介绍假定您对 " +"PyTorch 有基本的了解,因此不会详细介绍与 PyTorch 相关的内容。如果你想更深入地" +"了解 PyTorch,我们推荐你阅读 `DEEP LEARNING WITH PYTORCH: a 60 minute blitz " "`__。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 @@ -22237,13 +22542,13 @@ msgstr "定义模型" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"We use the simple CNN described in the `PyTorch tutorial " -"`__:" +"We use the simple CNN described in the `PyTorch tutorial `__:" msgstr "" -"我们使用` PyTorch 教程 " -"`__ 中描述的简单 CNN:" +"我们使用` PyTorch 教程 `__ 中描述的简单 " +"CNN:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 msgid "Let's continue with the usual training and test functions:" @@ -22256,23 +22561,27 @@ msgstr "训练模型" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" "We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train " -"the model on the dataset of one of our organizations " -"(``trainloaders[0]``). This simulates the reality of most machine " -"learning projects today: each organization has their own data and trains " -"models only on this internal data:" -msgstr "现在我们拥有了所需的所有基本构件:数据集、模型、训练函数和测试函数。让我们把它们放在一起,在我们其中一个组织的数据集(``trainloaders[0]``)上训练模型。这模拟了当今大多数机器学习项目的实际情况:每个组织都有自己的数据,并且只在这些内部数据上训练模型:" +"training function, and a test function. Let's put them together to train the " +"model on the dataset of one of our organizations (``trainloaders[0]``). This " +"simulates the reality of most machine learning projects today: each " +"organization has their own data and trains models only on this internal data:" +msgstr "" +"现在我们拥有了所需的所有基本构件:数据集、模型、训练函数和测试函数。让我们把" +"它们放在一起,在我们其中一个组织的数据集(``trainloaders[0]``)上训练模型。这" +"模拟了当今大多数机器学习项目的实际情况:每个组织都有自己的数据,并且只在这些" +"内部数据上训练模型:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " -"in a test set accuracy of about 41%, which is not good, but at the same " -"time, it doesn't really matter for the purposes of this tutorial. The " -"intent was just to show a simplistic centralized training pipeline that " -"sets the stage for what comes next - federated learning!" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result in " +"a test set accuracy of about 41%, which is not good, but at the same time, " +"it doesn't really matter for the purposes of this tutorial. The intent was " +"just to show a simplistic centralized training pipeline that sets the stage " +"for what comes next - federated learning!" msgstr "" "在我们的 CIFAR-10 分片上对简单 CNN 进行 5 个遍历的训练后,测试集的准确率应为 " -"41%,这并不理想,但同时对本教程而言也并不重要。我们只是想展示一个简单的集中式训练流程,为接下来的联邦学习做好铺垫!" +"41%,这并不理想,但同时对本教程而言也并不重要。我们只是想展示一个简单的集中式" +"训练流程,为接下来的联邦学习做好铺垫!" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 msgid "Step 2: Federated Learning with Flower" @@ -22280,14 +22589,15 @@ msgstr "步骤 2:使用 Flower 联邦学习" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was " -"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." -" Next, we'll simulate a situation where we have multiple datasets in " -"multiple organizations and where we train a model over these " -"organizations using federated learning." +"Step 1 demonstrated a simple centralized training pipeline. All data was in " +"one place (i.e., a single ``trainloader`` and a single ``valloader``). Next, " +"we'll simulate a situation where we have multiple datasets in multiple " +"organizations and where we train a model over these organizations using " +"federated learning." msgstr "" -"步骤 1 演示了一个简单的集中式训练流程。所有数据都在一个地方(即一个 \"trainloader \"和一个 " -"\"valloader\")。接下来,我们将模拟在多个组织中拥有多个数据集的情况,并使用联邦学习在这些组织中训练一个模型。" +"步骤 1 演示了一个简单的集中式训练流程。所有数据都在一个地方(即一个 " +"\"trainloader \"和一个 \"valloader\")。接下来,我们将模拟在多个组织中拥有多" +"个数据集的情况,并使用联邦学习在这些组织中训练一个模型。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 msgid "Updating model parameters" @@ -22295,35 +22605,40 @@ msgstr "更新模型参数" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"In federated learning, the server sends the global model parameters to " -"the client, and the client updates the local model with the parameters " -"received from the server. It then trains the model on the local data " -"(which changes the model parameters locally) and sends the " -"updated/changed model parameters back to the server (or, alternatively, " -"it sends just the gradients back to the server, not the full model " -"parameters)." -msgstr "在联邦学习中,服务器将全局模型参数发送给客户端,客户端根据从服务器接收到的参数更新本地模型。然后,客户端根据本地数据对模型进行训练(在本地更改模型参数),并将更新/更改后的模型参数发回服务器(或者,客户端只将梯度参数发回服务器,而不是全部模型参数)。" +"In federated learning, the server sends the global model parameters to the " +"client, and the client updates the local model with the parameters received " +"from the server. It then trains the model on the local data (which changes " +"the model parameters locally) and sends the updated/changed model parameters " +"back to the server (or, alternatively, it sends just the gradients back to " +"the server, not the full model parameters)." +msgstr "" +"在联邦学习中,服务器将全局模型参数发送给客户端,客户端根据从服务器接收到的参" +"数更新本地模型。然后,客户端根据本地数据对模型进行训练(在本地更改模型参" +"数),并将更新/更改后的模型参数发回服务器(或者,客户端只将梯度参数发回服务" +"器,而不是全部模型参数)。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" "We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the" -" local model: ``set_parameters`` and ``get_parameters``. The following " -"two functions do just that for the PyTorch model above." +"received from the server and to get the updated model parameters from the " +"local model: ``set_parameters`` and ``get_parameters``. The following two " +"functions do just that for the PyTorch model above." msgstr "" -"我们需要两个辅助函数,用从服务器接收到的参数更新本地模型,并从本地模型获取更新后的模型参数:`` " -"set_parameters```和`get_parameters``。下面两个函数就是为上面的 PyTorch 模型做这些工作的。" +"我们需要两个辅助函数,用从服务器接收到的参数更新本地模型,并从本地模型获取更" +"新后的模型参数:`` set_parameters```和`get_parameters``。下面两个函数就是为上" +"面的 PyTorch 模型做这些工作的。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 msgid "" -"The details of how this works are not really important here (feel free to" -" consult the PyTorch documentation if you want to learn more). In " -"essence, we use ``state_dict`` to access PyTorch model parameter tensors." -" The parameter tensors are then converted to/from a list of NumPy " -"ndarray's (which Flower knows how to serialize/deserialize):" +"The details of how this works are not really important here (feel free to " +"consult the PyTorch documentation if you want to learn more). In essence, we " +"use ``state_dict`` to access PyTorch model parameter tensors. The parameter " +"tensors are then converted to/from a list of NumPy ndarray's (which Flower " +"knows how to serialize/deserialize):" msgstr "" -"在这里,如何工作的细节并不重要(如果你想了解更多,请随时查阅 PyTorch 文档)。本质上,我们使用 ``state_dict`` 访问 " -"PyTorch 模型参数张量。然后,参数张量会被转换成/转换成 NumPy ndarray 列表(Flower 知道如何序列化/反序列化):" +"在这里,如何工作的细节并不重要(如果你想了解更多,请随时查阅 PyTorch 文档)。" +"本质上,我们使用 ``state_dict`` 访问 PyTorch 模型参数张量。然后,参数张量会被" +"转换成/转换成 NumPy ndarray 列表(Flower 知道如何序列化/反序列化):" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 msgid "Implementing a Flower client" @@ -22331,25 +22646,25 @@ msgstr "实现 Flower 客户端" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"With that out of the way, let's move on to the interesting part. " -"Federated learning systems consist of a server and multiple clients. In " -"Flower, we create clients by implementing subclasses of " -"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " -"``NumPyClient`` in this tutorial because it is easier to implement and " -"requires us to write less boilerplate." +"With that out of the way, let's move on to the interesting part. Federated " +"learning systems consist of a server and multiple clients. In Flower, we " +"create clients by implementing subclasses of ``flwr.client.Client`` or " +"``flwr.client.NumPyClient``. We use ``NumPyClient`` in this tutorial because " +"it is easier to implement and requires us to write less boilerplate." msgstr "" -"说完这些,让我们进入有趣的部分。联邦学习系统由一个服务器和多个客户端组成。在 Flower 中,我们通过实现 " -"``flwr.client.Client`` 或 ``flwr.client.NumPyClient`` " -"的子类来创建客户端。在本教程中,我们使用``NumPyClient``,因为它更容易实现,需要我们编写的模板也更少。" +"说完这些,让我们进入有趣的部分。联邦学习系统由一个服务器和多个客户端组成。在 " +"Flower 中,我们通过实现 ``flwr.client.Client`` 或 ``flwr.client." +"NumPyClient`` 的子类来创建客户端。在本教程中,我们使用``NumPyClient``,因为它" +"更容易实现,需要我们编写的模板也更少。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"To implement the Flower client, we create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``:" +"To implement the Flower client, we create a subclass of ``flwr.client." +"NumPyClient`` and implement the three methods ``get_parameters``, ``fit``, " +"and ``evaluate``:" msgstr "" -"为实现 Flower 客户端,我们创建了 ``flwr.client.NumPyClient`` 的子类,并实现了 " -"``get_parameters``、``fit`` 和``evaluate`` 三个方法:" +"为实现 Flower 客户端,我们创建了 ``flwr.client.NumPyClient`` 的子类,并实现" +"了 ``get_parameters``、``fit`` 和``evaluate`` 三个方法:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 msgid "``get_parameters``: Return the current local model parameters" @@ -22358,16 +22673,19 @@ msgstr "``get_parameters``: 返回当前本地模型参数" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" "``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters " -"to the server" -msgstr "``fit``: 从服务器接收模型参数,在本地数据上训练模型参数,并将(更新的)模型参数返回服务器" +"parameters on the local data, and return the (updated) model parameters to " +"the server" +msgstr "" +"``fit``: 从服务器接收模型参数,在本地数据上训练模型参数,并将(更新的)模型" +"参数返回服务器" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the " -"model parameters on the local data, and return the evaluation result to " -"the server" -msgstr "``evaluate ``: 从服务器接收模型参数,在本地数据上评估模型参数,并将评估结果返回服务器" +"``evaluate``: Receive model parameters from the server, evaluate the model " +"parameters on the local data, and return the evaluation result to the server" +msgstr "" +"``evaluate ``: 从服务器接收模型参数,在本地数据上评估模型参数,并将评估结果" +"返回服务器" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 msgid "" @@ -22375,29 +22693,29 @@ msgid "" "components for model training and evaluation. Let's see a simple Flower " "client implementation that brings everything together:" msgstr "" -"我们提到,我们的客户端将使用之前定义的 PyTorch 组件进行模型训练和评估。让我们来看看一个简单的 Flower " -"客户端实现,它将一切都整合在一起:" +"我们提到,我们的客户端将使用之前定义的 PyTorch 组件进行模型训练和评估。让我们" +"来看看一个简单的 Flower 客户端实现,它将一切都整合在一起:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" "Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." -msgstr "" -"我们的类 ``FlowerClient`` 定义了本地训练/评估的执行方式,并允许 Flower 通过 ``fit`` 和 " -"``evaluate`` 调用本地训练/评估。每个 ``FlowerClient`` " -"实例都代表联邦学习系统中的*单个客户端*。联邦学习系统有多个客户端(否则就没有什么可联邦的),因此每个客户端都将由自己的 " -"``FlowerClient`` 实例来代表。例如,如果我们的工作负载中有三个客户端,那么我们就会有三个 ``FlowerClient`` " -"实例。当服务器选择特定客户端进行训练时,Flower 会调用相应实例上的 ``FlowerClient.fit`` (评估时调用 " -"``FlowerClient.evaluate``)。" +"performed and allows Flower to call the local training/evaluation through " +"``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a " +"*single client* in our federated learning system. Federated learning systems " +"have multiple clients (otherwise, there's not much to federate), so each " +"client will be represented by its own instance of ``FlowerClient``. If we " +"have, for example, three clients in our workload, then we'd have three " +"instances of ``FlowerClient``. Flower calls ``FlowerClient.fit`` on the " +"respective instance when the server selects a particular client for training " +"(and ``FlowerClient.evaluate`` for evaluation)." +msgstr "" +"我们的类 ``FlowerClient`` 定义了本地训练/评估的执行方式,并允许 Flower 通过 " +"``fit`` 和 ``evaluate`` 调用本地训练/评估。每个 ``FlowerClient`` 实例都代表联" +"邦学习系统中的*单个客户端*。联邦学习系统有多个客户端(否则就没有什么可联邦" +"的),因此每个客户端都将由自己的 ``FlowerClient`` 实例来代表。例如,如果我们" +"的工作负载中有三个客户端,那么我们就会有三个 ``FlowerClient`` 实例。当服务器" +"选择特定客户端进行训练时,Flower 会调用相应实例上的 ``FlowerClient.fit`` (评" +"估时调用 ``FlowerClient.evaluate``)。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 msgid "Using the Virtual Client Engine" @@ -22405,17 +22723,18 @@ msgstr "使用虚拟客户端引擎" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In this notebook, we want to simulate a federated learning system with 10" -" clients on a single machine. This means that the server and all 10 " -"clients will live on a single machine and share resources such as CPU, " -"GPU, and memory. Having 10 clients would mean having 10 instances of " -"``FlowerClient`` in memory. Doing this on a single machine can quickly " -"exhaust the available memory resources, even if only a subset of these " -"clients participates in a single round of federated learning." +"In this notebook, we want to simulate a federated learning system with 10 " +"clients on a single machine. This means that the server and all 10 clients " +"will live on a single machine and share resources such as CPU, GPU, and " +"memory. Having 10 clients would mean having 10 instances of ``FlowerClient`` " +"in memory. Doing this on a single machine can quickly exhaust the available " +"memory resources, even if only a subset of these clients participates in a " +"single round of federated learning." msgstr "" -"在本笔记中,我们要模拟一个联邦学习系统,在一台机器上有 10 个客户端。这意味着服务器和所有 10 个客户端都将位于一台机器上,并共享 " -"CPU、GPU 和内存等资源。有 10 个客户端就意味着内存中有 10 个 ``FlowerClient`` " -"实例。在单台机器上这样做会很快耗尽可用的内存资源,即使这些客户端中只有一个子集参与了一轮联邦学习。" +"在本笔记中,我们要模拟一个联邦学习系统,在一台机器上有 10 个客户端。这意味着" +"服务器和所有 10 个客户端都将位于一台机器上,并共享 CPU、GPU 和内存等资源。有 " +"10 个客户端就意味着内存中有 10 个 ``FlowerClient`` 实例。在单台机器上这样做会" +"很快耗尽可用的内存资源,即使这些客户端中只有一个子集参与了一轮联邦学习。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 msgid "" @@ -22423,21 +22742,23 @@ msgid "" "multiple machines, Flower, therefore, provides special simulation " "capabilities that create ``FlowerClient`` instances only when they are " "actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" -msgstr "" -"除了服务器和客户端在多台机器上运行的常规功能外,Flower 还提供了特殊的模拟功能,即只有在训练或评估实际需要时才创建 " -"``FlowerClient`` 实例。为了让 Flower 框架能在必要时创建客户端,我们需要实现一个名为 ``client_fn`` " -"的函数,它能按需创建一个 ``FlowerClient`` 实例。每当 Flower 需要一个特定的客户端实例来调用 ``fit`` 或 " -"``evaluate`` 时,它就会调用 " -"``client_fn``(这些实例在使用后通常会被丢弃,因此它们不应保留任何本地状态)。客户端由一个客户端 ID 或简短的 ``cid`` " -"标识。例如,可以使用 ``cid`` 为不同的客户端加载不同的本地数据分区,如下所示:" +"framework to create clients when necessary, we need to implement a function " +"called ``client_fn`` that creates a ``FlowerClient`` instance on demand. " +"Flower calls ``client_fn`` whenever it needs an instance of one particular " +"client to call ``fit`` or ``evaluate`` (those instances are usually " +"discarded after use, so they should not keep any local state). Clients are " +"identified by a client ID, or short ``cid``. The ``cid`` can be used, for " +"example, to load different local data partitions for different clients, as " +"can be seen below:" +msgstr "" +"除了服务器和客户端在多台机器上运行的常规功能外,Flower 还提供了特殊的模拟功" +"能,即只有在训练或评估实际需要时才创建 ``FlowerClient`` 实例。为了让 Flower " +"框架能在必要时创建客户端,我们需要实现一个名为 ``client_fn`` 的函数,它能按需" +"创建一个 ``FlowerClient`` 实例。每当 Flower 需要一个特定的客户端实例来调用 " +"``fit`` 或 ``evaluate`` 时,它就会调用 ``client_fn``(这些实例在使用后通常会" +"被丢弃,因此它们不应保留任何本地状态)。客户端由一个客户端 ID 或简短的 " +"``cid`` 标识。例如,可以使用 ``cid`` 为不同的客户端加载不同的本地数据分区,如" +"下所示:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 msgid "Starting the training" @@ -22445,40 +22766,43 @@ msgstr "开始训练" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"We now have the class ``FlowerClient`` which defines client-side " -"training/evaluation and ``client_fn`` which allows Flower to create " -"``FlowerClient`` instances whenever it needs to call ``fit`` or " -"``evaluate`` on one particular client. The last step is to start the " -"actual simulation using ``flwr.simulation.start_simulation``." +"We now have the class ``FlowerClient`` which defines client-side training/" +"evaluation and ``client_fn`` which allows Flower to create ``FlowerClient`` " +"instances whenever it needs to call ``fit`` or ``evaluate`` on one " +"particular client. The last step is to start the actual simulation using " +"``flwr.simulation.start_simulation``." msgstr "" -"现在我们有了定义客户端训练/评估的类 ``FlowerClient`` 和允许 Flower 在需要调用某个客户端的 ``fit` 或 " -"``evaluate` 时创建 ``FlowerClient`` 实例的 ``client_fn` 类。最后一步是使用 " -"``flwr.simulation.start_simulation`` 启动实际模拟。" +"现在我们有了定义客户端训练/评估的类 ``FlowerClient`` 和允许 Flower 在需要调用" +"某个客户端的 ``fit` 或 ``evaluate` 时创建 ``FlowerClient`` 实例的 " +"``client_fn` 类。最后一步是使用 ``flwr.simulation.start_simulation`` 启动实际" +"模拟。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 msgid "" "The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the " -"number of clients to simulate (``num_clients``), the number of federated " -"learning rounds (``num_rounds``), and the strategy. The strategy " -"encapsulates the federated learning approach/algorithm, for example, " -"*Federated Averaging* (FedAvg)." +"them the ``client_fn`` used to create ``FlowerClient`` instances, the number " +"of clients to simulate (``num_clients``), the number of federated learning " +"rounds (``num_rounds``), and the strategy. The strategy encapsulates the " +"federated learning approach/algorithm, for example, *Federated Averaging* " +"(FedAvg)." msgstr "" -"函数 ``start_simulation`` 接受许多参数,其中包括用于创建 ``FlowerClient`` 实例的 " -"``client_fn``、要模拟的客户端数量(``num_clients``)、联邦学习轮数(``num_rounds``)和策略。策略封装了联邦学习方法/算法,例如*联邦平均*" -" (FedAvg)。" +"函数 ``start_simulation`` 接受许多参数,其中包括用于创建 ``FlowerClient`` 实" +"例的 ``client_fn``、要模拟的客户端数量(``num_clients``)、联邦学习轮数" +"(``num_rounds``)和策略。策略封装了联邦学习方法/算法,例如*联邦平均* " +"(FedAvg)。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" "Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated" -" learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last " -"step is the actual call to ``start_simulation`` which - you guessed it - " -"starts the simulation:" +"strategy implementations to customize nearly all aspects of the federated " +"learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last step " +"is the actual call to ``start_simulation`` which - you guessed it - starts " +"the simulation:" msgstr "" -"Flower 有许多内置策略,但我们也可以使用自己的策略实现来定制联邦学习方法的几乎所有方面。在本例中,我们使用内置的 ``FedAvg`` " -"实现,并使用一些基本参数对其进行定制。最后一步是实际调用 ``start_simulation``开始模拟:" +"Flower 有许多内置策略,但我们也可以使用自己的策略实现来定制联邦学习方法的几乎" +"所有方面。在本例中,我们使用内置的 ``FedAvg`` 实现,并使用一些基本参数对其进" +"行定制。最后一步是实际调用 ``start_simulation``开始模拟:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 msgid "Behind the scenes" @@ -22491,26 +22815,28 @@ msgstr "那么它是如何工作的呢?Flower 如何进行模拟?" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 #, python-format msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 " -"clients (``num_clients=10``). Flower then goes ahead an asks the " -"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " -"select 100% of the available clients (``fraction_fit=1.0``), so it goes " -"ahead and selects 10 random clients (i.e., 100% of 10)." +"When we call ``start_simulation``, we tell Flower that there are 10 clients " +"(``num_clients=10``). Flower then goes ahead an asks the ``FedAvg`` strategy " +"to select clients. ``FedAvg`` knows that it should select 100% of the " +"available clients (``fraction_fit=1.0``), so it goes ahead and selects 10 " +"random clients (i.e., 100% of 10)." msgstr "" -"当我们调用 ``start_simulation`` 时,我们会告诉 Flower 有 10 " -"个客户(`num_clients=10``)。然后,Flower 会要求 ``FedAvg`` 策略选择客户。``FedAvg`` 知道它应该选择" -" 100%的可用客户(``fraction_fit=1.0``),所以它会随机选择 10 个客户(即 10 的 100%)。" +"当我们调用 ``start_simulation`` 时,我们会告诉 Flower 有 10 个客户" +"(`num_clients=10``)。然后,Flower 会要求 ``FedAvg`` 策略选择客户。" +"``FedAvg`` 知道它应该选择 100%的可用客户(``fraction_fit=1.0``),所以它会随" +"机选择 10 个客户(即 10 的 100%)。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 msgid "" -"Flower then asks the selected 10 clients to train the model. When the " -"server receives the model parameter updates from the clients, it hands " -"those updates over to the strategy (*FedAvg*) for aggregation. The " -"strategy aggregates those updates and returns the new global model, which" -" then gets used in the next round of federated learning." +"Flower then asks the selected 10 clients to train the model. When the server " +"receives the model parameter updates from the clients, it hands those " +"updates over to the strategy (*FedAvg*) for aggregation. The strategy " +"aggregates those updates and returns the new global model, which then gets " +"used in the next round of federated learning." msgstr "" -"然后,Flower 会要求选定的 10 " -"个客户端对模型进行训练。服务器收到客户端的模型参数更新后,会将这些更新交给策略(*FedAvg*)进行聚合。策略会聚合这些更新并返回新的全局模型,然后将其用于下一轮联邦学习。" +"然后,Flower 会要求选定的 10 个客户端对模型进行训练。服务器收到客户端的模型参" +"数更新后,会将这些更新交给策略(*FedAvg*)进行聚合。策略会聚合这些更新并返回" +"新的全局模型,然后将其用于下一轮联邦学习。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 msgid "Where's the accuracy?" @@ -22518,67 +22844,75 @@ msgstr "准确度在哪里找?" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` " -"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"You may have noticed that all metrics except for ``losses_distributed`` are " +"empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" msgstr "" -"您可能已经注意到,除了 ``losses_distributed`` 以外,所有指标都是空的。{\"准确度\": " -"float(准确度)}``去哪儿了?" +"您可能已经注意到,除了 ``losses_distributed`` 以外,所有指标都是空的。{\"准确" +"度\": float(准确度)}``去哪儿了?" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 msgid "" -"Flower can automatically aggregate losses returned by individual clients," -" but it cannot do the same for metrics in the generic metrics dictionary " -"(the one with the ``accuracy`` key). Metrics dictionaries can contain " -"very different kinds of metrics and even key/value pairs that are not " -"metrics at all, so the framework does not (and can not) know how to " -"handle these automatically." +"Flower can automatically aggregate losses returned by individual clients, " +"but it cannot do the same for metrics in the generic metrics dictionary (the " +"one with the ``accuracy`` key). Metrics dictionaries can contain very " +"different kinds of metrics and even key/value pairs that are not metrics at " +"all, so the framework does not (and can not) know how to handle these " +"automatically." msgstr "" -"Flower 可以自动汇总单个客户端返回的损失值,但无法对通用度量字典中的度量进行同样的处理(即带有 \"准确度 " -"\"键的度量字典)。度量值字典可以包含非常不同种类的度量值,甚至包含根本不是度量值的键/值对,因此框架不知道(也无法知道)如何自动处理这些度量值。" +"Flower 可以自动汇总单个客户端返回的损失值,但无法对通用度量字典中的度量进行同" +"样的处理(即带有 \"准确度 \"键的度量字典)。度量值字典可以包含非常不同种类的" +"度量值,甚至包含根本不是度量值的键/值对,因此框架不知道(也无法知道)如何自动" +"处理这些度量值。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 msgid "" -"As users, we need to tell the framework how to handle/aggregate these " -"custom metrics, and we do so by passing metric aggregation functions to " -"the strategy. The strategy will then call these functions whenever it " -"receives fit or evaluate metrics from clients. The two possible functions" -" are ``fit_metrics_aggregation_fn`` and " -"``evaluate_metrics_aggregation_fn``." +"As users, we need to tell the framework how to handle/aggregate these custom " +"metrics, and we do so by passing metric aggregation functions to the " +"strategy. The strategy will then call these functions whenever it receives " +"fit or evaluate metrics from clients. The two possible functions are " +"``fit_metrics_aggregation_fn`` and ``evaluate_metrics_aggregation_fn``." msgstr "" -"作为用户,我们需要告诉框架如何处理/聚合这些自定义指标,为此,我们将指标聚合函数传递给策略。然后,只要从客户端接收到拟合或评估指标,策略就会调用这些函数。两个可能的函数是" -" ``fit_metrics_aggregation_fn`` 和 ``evaluate_metrics_aggregation_fn``。" +"作为用户,我们需要告诉框架如何处理/聚合这些自定义指标,为此,我们将指标聚合函" +"数传递给策略。然后,只要从客户端接收到拟合或评估指标,策略就会调用这些函数。" +"两个可能的函数是 ``fit_metrics_aggregation_fn`` 和 " +"``evaluate_metrics_aggregation_fn``。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 msgid "" "Let's create a simple weighted averaging function to aggregate the " "``accuracy`` metric we return from ``evaluate``:" -msgstr "让我们创建一个简单的加权平均函数来汇总从 ``evaluate`` 返回的 ``accuracy`` 指标:" +msgstr "" +"让我们创建一个简单的加权平均函数来汇总从 ``evaluate`` 返回的 ``accuracy`` 指" +"标:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 msgid "" "The only thing left to do is to tell the strategy to call this function " "whenever it receives evaluation metric dictionaries from the clients:" -msgstr "剩下要做的就是告诉策略,每当它从客户端接收到评估度量字典时,都要调用这个函数:" +msgstr "" +"剩下要做的就是告诉策略,每当它从客户端接收到评估度量字典时,都要调用这个函" +"数:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 msgid "" "We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom" -" evaluation metrics and calculates a single ``accuracy`` metric across " -"all clients on the server side." +"evaluation. It uses the ``weighted_average`` function to aggregate custom " +"evaluation metrics and calculates a single ``accuracy`` metric across all " +"clients on the server side." msgstr "" -"我们现在有了一个完整的系统,可以执行联邦训练和联邦评估。它使用 ``weighted_average`` " -"函数汇总自定义评估指标,并在服务器端计算所有客户端的单一 ``accuracy`` 指标。" +"我们现在有了一个完整的系统,可以执行联邦训练和联邦评估。它使用 " +"``weighted_average`` 函数汇总自定义评估指标,并在服务器端计算所有客户端的单" +"一 ``accuracy`` 指标。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 msgid "" "The other two categories of metrics (``losses_centralized`` and " "``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial " -"will cover centralized evaluation." +"centralized evaluation is being used. Part two of the Flower tutorial will " +"cover centralized evaluation." msgstr "" -"其他两类指标(`losses_centralized`` 和 " -"`metrics_centralized`)仍然是空的,因为它们只适用于集中评估。Flower 教程的第二部分将介绍集中式评估。" +"其他两类指标(`losses_centralized`` 和 `metrics_centralized`)仍然是空的,因" +"为它们只适用于集中评估。Flower 教程的第二部分将介绍集中式评估。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 @@ -22587,34 +22921,39 @@ msgstr "结束语" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 msgid "" -"Congratulations, you just trained a convolutional neural network, " -"federated over 10 clients! With that, you understand the basics of " -"federated learning with Flower. The same approach you've seen can be used" -" with other machine learning frameworks (not just PyTorch) and tasks (not" -" just CIFAR-10 images classification), for example NLP with Hugging Face " -"Transformers or speech with SpeechBrain." +"Congratulations, you just trained a convolutional neural network, federated " +"over 10 clients! With that, you understand the basics of federated learning " +"with Flower. The same approach you've seen can be used with other machine " +"learning frameworks (not just PyTorch) and tasks (not just CIFAR-10 images " +"classification), for example NLP with Hugging Face Transformers or speech " +"with SpeechBrain." msgstr "" -"恭喜您,你刚刚训练了一个由 10 个客户端组成的卷积神经网络!这样,你就了解了使用 Flower " -"进行联邦学习的基础知识。你所看到的方法同样适用于其他机器学习框架(不只是 PyTorch)和任务(不只是 CIFAR-10 图像分类),例如使用 " -"Hugging Face Transformers 的 NLP 或使用 SpeechBrain 的语音。" +"恭喜您,你刚刚训练了一个由 10 个客户端组成的卷积神经网络!这样,你就了解了使" +"用 Flower 进行联邦学习的基础知识。你所看到的方法同样适用于其他机器学习框架" +"(不只是 PyTorch)和任务(不只是 CIFAR-10 图像分类),例如使用 Hugging Face " +"Transformers 的 NLP 或使用 SpeechBrain 的语音。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. " -"Want to customize your strategy? Initialize parameters on the server " -"side? Or evaluate the aggregated model on the server side? We'll cover " -"all this and more in the next tutorial." -msgstr "在下一个笔记中,我们将介绍一些更先进的概念。想定制你的策略吗?在服务器端初始化参数?或者在服务器端评估聚合模型?我们将在下一个教程中介绍所有这些内容以及更多。" +"In the next notebook, we're going to cover some more advanced concepts. Want " +"to customize your strategy? Initialize parameters on the server side? Or " +"evaluate the aggregated model on the server side? We'll cover all this and " +"more in the next tutorial." +msgstr "" +"在下一个笔记中,我们将介绍一些更先进的概念。想定制你的策略吗?在服务器端初始" +"化参数?或者在服务器端评估聚合模型?我们将在下一个教程中介绍所有这些内容以及" +"更多。" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 " -"`__ goes into more depth about strategies and all " -"the advanced things you can build with them." +"The `Flower Federated Learning Tutorial - Part 2 `__ goes " +"into more depth about strategies and all the advanced things you can build " +"with them." msgstr "" -"`Flower 联邦学习教程 - 第 2 部分 `__ 更深入地介绍了策略以及可以使用策略构建的所有高级功能。" +"`Flower 联邦学习教程 - 第 2 部分 `__ 更深入地介绍了策略以及可以" +"使用策略构建的所有高级功能。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 msgid "Use a federated learning strategy" @@ -22623,22 +22962,22 @@ msgstr "使用联邦学习策略" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 msgid "" "Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and" -" Flower (`part 1 `__)." +"parts of this tutorial, we introduced federated learning with PyTorch and " +"Flower (`part 1 `__)." msgstr "" -"欢迎来到联邦学习教程的下一部分。在本教程的前几部分,我们介绍了使用 PyTorch 和 Flower 进行联邦学习(`第 1 部分 " -"`___)。" +"欢迎来到联邦学习教程的下一部分。在本教程的前几部分,我们介绍了使用 PyTorch " +"和 Flower 进行联邦学习(`第 1 部分 `___)。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 msgid "" -"In this notebook, we'll begin to customize the federated learning system " -"we built in the introductory notebook (again, using `Flower " -"`__ and `PyTorch `__)." +"In this notebook, we'll begin to customize the federated learning system we " +"built in the introductory notebook (again, using `Flower `__ and `PyTorch `__)." msgstr "" -"在本笔记中,我们将开始定制在入门笔记中构建的联邦学习系统(再次使用 `Flower `__ 和 " -"`PyTorch `__)。" +"在本笔记中,我们将开始定制在入门笔记中构建的联邦学习系统(再次使用 `Flower " +"`__ 和 `PyTorch `__)。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 msgid "Let's move beyond FedAvg with Flower strategies!" @@ -22651,9 +22990,11 @@ msgstr "策略定制" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 msgid "" "So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of " -"new features." -msgstr "到目前为止,如果您已经阅读过入门笔记本,那么一切都应该很熟悉了。接下来,我们将介绍一些新功能。" +"introductory notebook. With that, we're ready to introduce a number of new " +"features." +msgstr "" +"到目前为止,如果您已经阅读过入门笔记本,那么一切都应该很熟悉了。接下来,我们" +"将介绍一些新功能。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 msgid "Server-side parameter **initialization**" @@ -22661,24 +23002,25 @@ msgstr "服务器端参数 **初始化**" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 msgid "" -"Flower, by default, initializes the global model by asking one random " -"client for the initial parameters. In many cases, we want more control " -"over parameter initialization though. Flower therefore allows you to " -"directly pass the initial parameters to the Strategy:" +"Flower, by default, initializes the global model by asking one random client " +"for the initial parameters. In many cases, we want more control over " +"parameter initialization though. Flower therefore allows you to directly " +"pass the initial parameters to the Strategy:" msgstr "" -"默认情况下,Flower 会通过向一个随机客户端询问初始参数来初始化全局模型。但在许多情况下,我们需要对参数初始化进行更多控制。因此,Flower" -" 允许您直接将初始参数传递给策略:" +"默认情况下,Flower 会通过向一个随机客户端询问初始参数来初始化全局模型。但在许" +"多情况下,我们需要对参数初始化进行更多控制。因此,Flower 允许您直接将初始参数" +"传递给策略:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" -" from asking one of the clients for the initial parameters. If we look " +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower " +"from asking one of the clients for the initial parameters. If we look " "closely, we can see that the logs do not show any calls to the " "``FlowerClient.get_parameters`` method." msgstr "" -"向 ``FedAvg`` 策略传递 ``initial_parameters`` 可以防止 Flower " -"向其中一个客户端询问初始参数。如果我们仔细观察,就会发现日志中没有显示对 ``FlowerClient.get_parameters`` " -"方法的任何调用。" +"向 ``FedAvg`` 策略传递 ``initial_parameters`` 可以防止 Flower 向其中一个客户" +"端询问初始参数。如果我们仔细观察,就会发现日志中没有显示对 ``FlowerClient." +"get_parameters`` 方法的任何调用。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 msgid "Starting with a customized strategy" @@ -22686,20 +23028,23 @@ msgstr "从定制战略开始" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number " -"of arguments, amongst them the ``client_fn`` used to create " -"``FlowerClient`` instances, the number of clients to simulate " -"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +"We've seen the function ``start_simulation`` before. It accepts a number of " +"arguments, amongst them the ``client_fn`` used to create ``FlowerClient`` " +"instances, the number of clients to simulate ``num_clients``, the number of " +"rounds ``num_rounds``, and the strategy." msgstr "" -"我们以前见过函数 ``start_simulation``。它接受许多参数,其中包括用于创建 ``FlowerClient`` 实例的 " -"``client_fn``、要模拟的客户数量 ``num_clients``、回合数 ``num_rounds``和策略。" +"我们以前见过函数 ``start_simulation``。它接受许多参数,其中包括用于创建 " +"``FlowerClient`` 实例的 ``client_fn``、要模拟的客户数量 ``num_clients``、回合" +"数 ``num_rounds``和策略。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 msgid "" "The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " -"strategy this time:" -msgstr "该策略封装了联邦学习方法/算法,例如`FedAvg``或`FedAdagrad``。这次让我们尝试使用不同的策略:" +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different strategy " +"this time:" +msgstr "" +"该策略封装了联邦学习方法/算法,例如`FedAvg``或`FedAdagrad``。这次让我们尝试使" +"用不同的策略:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 msgid "Server-side parameter **evaluation**" @@ -22707,46 +23052,59 @@ msgstr "服务器端参数**评估**" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the " -"client-side. Client-side and server-side evaluation are similar in some " -"ways, but different in others." -msgstr "Flower 可以在服务器端或客户端评估聚合模型。客户端和服务器端评估在某些方面相似,但也有不同之处。" +"Flower can evaluate the aggregated model on the server-side or on the client-" +"side. Client-side and server-side evaluation are similar in some ways, but " +"different in others." +msgstr "" +"Flower 可以在服务器端或客户端评估聚合模型。客户端和服务器端评估在某些方面相" +"似,但也有不同之处。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 msgid "" "**Centralized Evaluation** (or *server-side evaluation*) is conceptually " "simple: it works the same way that evaluation in centralized machine " "learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly " -"aggregated model after each round of training without having to send the " -"model to clients. We're also fortunate in the sense that our entire " -"evaluation dataset is available at all times." -msgstr "**集中评估**(或*服务器端评估*)在概念上很简单:它的工作方式与集中式机器学习中的评估方式相同。如果有一个服务器端数据集可用于评估目的,那就太好了。我们可以在每一轮训练后对新聚合的模型进行评估,而无需将模型发送给客户端。我们也很幸运,因为我们的整个评估数据集随时可用。" +"evaluation purposes, then that's great. We can evaluate the newly aggregated " +"model after each round of training without having to send the model to " +"clients. We're also fortunate in the sense that our entire evaluation " +"dataset is available at all times." +msgstr "" +"**集中评估**(或*服务器端评估*)在概念上很简单:它的工作方式与集中式机器学习" +"中的评估方式相同。如果有一个服务器端数据集可用于评估目的,那就太好了。我们可" +"以在每一轮训练后对新聚合的模型进行评估,而无需将模型发送给客户端。我们也很幸" +"运,因为我们的整个评估数据集随时可用。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, " -"but also more powerful: it doesn't require a centralized dataset and " -"allows us to evaluate models over a larger set of data, which often " -"yields more realistic evaluation results. In fact, many scenarios require" -" us to use **Federated Evaluation** if we want to get representative " -"evaluation results at all. But this power comes at a cost: once we start " -"to evaluate on the client side, we should be aware that our evaluation " -"dataset can change over consecutive rounds of learning if those clients " -"are not always available. Moreover, the dataset held by each client can " -"also change over consecutive rounds. This can lead to evaluation results " -"that are not stable, so even if we would not change the model, we'd see " -"our evaluation results fluctuate over consecutive rounds." -msgstr "**联邦评估**(或*客户端评估*)更为复杂,但也更为强大:它不需要集中的数据集,允许我们在更大的数据集上对模型进行评估,这通常会产生更真实的评估结果。事实上,如果我们想得到有代表性的评估结果,很多情况下都需要使用**联邦评估**。但是,这种能力是有代价的:一旦我们开始在客户端进行评估,我们就应该意识到,如果这些客户端并不总是可用,我们的评估数据集可能会在连续几轮学习中发生变化。此外,每个客户端所拥有的数据集也可能在连续几轮学习中发生变化。这可能会导致评估结果不稳定,因此即使我们不改变模型,也会看到评估结果在连续几轮中波动。" +"**Federated Evaluation** (or *client-side evaluation*) is more complex, but " +"also more powerful: it doesn't require a centralized dataset and allows us " +"to evaluate models over a larger set of data, which often yields more " +"realistic evaluation results. In fact, many scenarios require us to use " +"**Federated Evaluation** if we want to get representative evaluation results " +"at all. But this power comes at a cost: once we start to evaluate on the " +"client side, we should be aware that our evaluation dataset can change over " +"consecutive rounds of learning if those clients are not always available. " +"Moreover, the dataset held by each client can also change over consecutive " +"rounds. This can lead to evaluation results that are not stable, so even if " +"we would not change the model, we'd see our evaluation results fluctuate " +"over consecutive rounds." +msgstr "" +"**联邦评估**(或*客户端评估*)更为复杂,但也更为强大:它不需要集中的数据集," +"允许我们在更大的数据集上对模型进行评估,这通常会产生更真实的评估结果。事实" +"上,如果我们想得到有代表性的评估结果,很多情况下都需要使用**联邦评估**。但" +"是,这种能力是有代价的:一旦我们开始在客户端进行评估,我们就应该意识到,如果" +"这些客户端并不总是可用,我们的评估数据集可能会在连续几轮学习中发生变化。此" +"外,每个客户端所拥有的数据集也可能在连续几轮学习中发生变化。这可能会导致评估" +"结果不稳定,因此即使我们不改变模型,也会看到评估结果在连续几轮中波动。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 msgid "" "We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " -"how we can evaluate aggregated model parameters on the server-side:" +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see how " +"we can evaluate aggregated model parameters on the server-side:" msgstr "" -"我们已经了解了联邦评估如何在客户端工作(即通过在 ``FlowerClient`` 中实现 ``evaluate`` " -"方法)。现在让我们看看如何在服务器端评估聚合模型参数:" +"我们已经了解了联邦评估如何在客户端工作(即通过在 ``FlowerClient`` 中实现 " +"``evaluate`` 方法)。现在让我们看看如何在服务器端评估聚合模型参数:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 msgid "Sending/receiving arbitrary values to/from clients" @@ -22754,63 +23112,66 @@ msgstr "向/从客户端发送/接收任意值" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 msgid "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" -msgstr "" -"在某些情况下,我们希望从服务器端配置客户端的执行(训练、评估)。其中一个例子就是服务器要求客户端训练一定数量的本地遍历。Flower " -"提供了一种使用字典从服务器向客户端发送配置值的方法。让我们来看一个例子:客户端通过 ``fit`` 中的 ``config`` " -"参数从服务器接收配置值(``evaluate`` 中也有 ``config`` 参数)。``fit`` 方法通过 ``config`` " -"参数接收配置字典,然后从字典中读取值。在本例中,它读取了 ``server_round`` 和 " -"``local_epochs``,并使用这些值来改进日志记录和配置本地训练遍历的数量:" +"In some situations, we want to configure client-side execution (training, " +"evaluation) from the server-side. One example for that is the server asking " +"the clients to train for a certain number of local epochs. Flower provides a " +"way to send configuration values from the server to the clients using a " +"dictionary. Let's look at an example where the clients receive values from " +"the server through the ``config`` parameter in ``fit`` (``config`` is also " +"available in ``evaluate``). The ``fit`` method receives the configuration " +"dictionary through the ``config`` parameter and can then read values from " +"this dictionary. In this example, it reads ``server_round`` and " +"``local_epochs`` and uses those values to improve the logging and configure " +"the number of local training epochs:" +msgstr "" +"在某些情况下,我们希望从服务器端配置客户端的执行(训练、评估)。其中一个例子" +"就是服务器要求客户端训练一定数量的本地遍历。Flower 提供了一种使用字典从服务器" +"向客户端发送配置值的方法。让我们来看一个例子:客户端通过 ``fit`` 中的 " +"``config`` 参数从服务器接收配置值(``evaluate`` 中也有 ``config`` 参数)。" +"``fit`` 方法通过 ``config`` 参数接收配置字典,然后从字典中读取值。在本例中," +"它读取了 ``server_round`` 和 ``local_epochs``,并使用这些值来改进日志记录和配" +"置本地训练遍历的数量:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 msgid "" -"So how can we send this config dictionary from server to clients? The " -"built-in Flower Strategies provide way to do this, and it works similarly" -" to the way server-side evaluation works. We provide a function to the " -"strategy, and the strategy calls this function for every round of " -"federated learning:" +"So how can we send this config dictionary from server to clients? The built-" +"in Flower Strategies provide way to do this, and it works similarly to the " +"way server-side evaluation works. We provide a function to the strategy, and " +"the strategy calls this function for every round of federated learning:" msgstr "" "那么,如何将配置字典从服务器发送到客户端呢?内置的 \"Flower策略\"(Flower " -"Strategies)提供了这样的方法,其工作原理与服务器端评估的工作原理类似。我们为策略提供一个函数,策略会在每一轮联邦学习中调用这个函数:" +"Strategies)提供了这样的方法,其工作原理与服务器端评估的工作原理类似。我们为" +"策略提供一个函数,策略会在每一轮联邦学习中调用这个函数:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before " -"starting the simulation:" +"Next, we'll just pass this function to the FedAvg strategy before starting " +"the simulation:" msgstr "接下来,我们只需在开始模拟前将此函数传递给 FedAvg 策略即可:" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 msgid "" -"As we can see, the client logs now include the current round of federated" -" learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second" -" round of federated learning, and then for two epochs during the third " -"round." +"As we can see, the client logs now include the current round of federated " +"learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second " +"round of federated learning, and then for two epochs during the third round." msgstr "" -"我们可以看到,客户端日志现在包含了当前一轮的联邦学习(从 ``config`` " -"字典中读取)。我们还可以将本地训练配置为在第一轮和第二轮联邦学习期间运行一个遍历,然后在第三轮联邦学习期间运行两个遍历。" +"我们可以看到,客户端日志现在包含了当前一轮的联邦学习(从 ``config`` 字典中读" +"取)。我们还可以将本地训练配置为在第一轮和第二轮联邦学习期间运行一个遍历,然" +"后在第三轮联邦学习期间运行两个遍历。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 msgid "" "Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " -"used this concept throughout this notebook without mentioning it " -"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" -" key/value pair as the third return value in ``evaluate``." +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and used " +"this concept throughout this notebook without mentioning it explicitly: our " +"``FlowerClient`` returns a dictionary containing a custom key/value pair as " +"the third return value in ``evaluate``." msgstr "" -"客户端还可以向服务器返回任意值。为此,它们会从 ``fit`` 和/或 ``evaluate`` " -"返回一个字典。我们在本笔记中看到并使用了这一概念,但并未明确提及:我们的 ``FlowerClient`` 返回一个包含自定义键/值对的字典,作为" -" ``evaluate`` 中的第三个返回值。" +"客户端还可以向服务器返回任意值。为此,它们会从 ``fit`` 和/或 ``evaluate`` 返" +"回一个字典。我们在本笔记中看到并使用了这一概念,但并未明确提及:我们的 " +"``FlowerClient`` 返回一个包含自定义键/值对的字典,作为 ``evaluate`` 中的第三" +"个返回值。" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 msgid "Scaling federated learning" @@ -22826,19 +23187,19 @@ msgstr "作为本笔记的最后一步,让我们看看如何使用 Flower 对 #, python-format msgid "" "We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is " -"quite small, we should probably train the model a bit longer, so we " -"configure the clients to perform 3 local training epochs. We should also " -"adjust the fraction of clients selected for training during each round " -"(we don't want all 1000 clients participating in every round), so we " -"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " -"available clients (so 50 clients) will be selected for training each " -"round:" -msgstr "" -"现在我们有 1000 个分区,每个分区有 45 个训练数据和 5 " -"个验证数据。鉴于每个客户端上的训练示例数量较少,我们可能需要对模型进行更长时间的训练,因此我们将客户端配置为执行 3 " -"个本地训练遍历。我们还应该调整每轮训练中被选中的客户端的比例(我们不希望每轮训练都有 1000 个客户端参与),因此我们将 " -"``fraction_fit`` 调整为 ``0.05``,这意味着每轮训练只选中 5%的可用客户端(即 50 个客户端):" +"examples. Given that the number of training examples on each client is quite " +"small, we should probably train the model a bit longer, so we configure the " +"clients to perform 3 local training epochs. We should also adjust the " +"fraction of clients selected for training during each round (we don't want " +"all 1000 clients participating in every round), so we adjust " +"``fraction_fit`` to ``0.05``, which means that only 5% of available clients " +"(so 50 clients) will be selected for training each round:" +msgstr "" +"现在我们有 1000 个分区,每个分区有 45 个训练数据和 5 个验证数据。鉴于每个客户" +"端上的训练示例数量较少,我们可能需要对模型进行更长时间的训练,因此我们将客户" +"端配置为执行 3 个本地训练遍历。我们还应该调整每轮训练中被选中的客户端的比例" +"(我们不希望每轮训练都有 1000 个客户端参与),因此我们将 ``fraction_fit`` 调" +"整为 ``0.05``,这意味着每轮训练只选中 5%的可用客户端(即 50 个客户端):" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 msgid "" @@ -22846,29 +23207,33 @@ msgid "" "customizing the strategy, initializing parameters on the server side, " "choosing a different strategy, and evaluating models on the server-side. " "That's quite a bit of flexibility with so little code, right?" -msgstr "在本笔记中,我们看到了如何通过自定义策略、在服务器端初始化参数、选择不同的策略以及在服务器端评估模型来逐步增强我们的系统。用这么少的代码就能实现这么大的灵活性,不是吗?" +msgstr "" +"在本笔记中,我们看到了如何通过自定义策略、在服务器端初始化参数、选择不同的策" +"略以及在服务器端评估模型来逐步增强我们的系统。用这么少的代码就能实现这么大的" +"灵活性,不是吗?" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 msgid "" -"In the later sections, we've seen how we can communicate arbitrary values" -" between server and clients to fully customize client-side execution. " -"With that capability, we built a large-scale Federated Learning " -"simulation using the Flower Virtual Client Engine and ran an experiment " -"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +"In the later sections, we've seen how we can communicate arbitrary values " +"between server and clients to fully customize client-side execution. With " +"that capability, we built a large-scale Federated Learning simulation using " +"the Flower Virtual Client Engine and ran an experiment involving 1000 " +"clients in the same workload - all in a Jupyter Notebook!" msgstr "" -"在后面的章节中,我们将看到如何在服务器和客户端之间传递任意值,以完全自定义客户端执行。有了这种能力,我们使用 Flower " -"虚拟客户端引擎构建了一个大规模的联邦学习模拟,并在 Jupyter Notebook 中进行了一次实验,在相同的工作负载中运行了 1000 " -"个客户端!" +"在后面的章节中,我们将看到如何在服务器和客户端之间传递任意值,以完全自定义客" +"户端执行。有了这种能力,我们使用 Flower 虚拟客户端引擎构建了一个大规模的联邦" +"学习模拟,并在 Jupyter Notebook 中进行了一次实验,在相同的工作负载中运行了 " +"1000 个客户端!" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 " -"`__ shows how to build a fully custom ``Strategy`` from " -"scratch." +"The `Flower Federated Learning Tutorial - Part 3 `__ shows how " +"to build a fully custom ``Strategy`` from scratch." msgstr "" "`Flower 联邦学习教程 - 第 3 部分 `__ 展示了如何从头开始构建完全自定义的 \"策略\"。" +"build-a-strategy-from-scratch-pytorch.html>`__ 展示了如何从头开始构建完全自定" +"义的 \"策略\"。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 msgid "What is Federated Learning?" @@ -22878,30 +23243,34 @@ msgstr "什么是联邦学习?" msgid "" "In this tutorial, you will learn what federated learning is, build your " "first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated " -"learning systems that approach the current state of the art in the field." +"parts of the tutorial, you will be able to build advanced federated learning " +"systems that approach the current state of the art in the field." msgstr "" -"在本教程中,你将了解什么是联邦学习,用 Flower " -"搭建第一个系统,并逐步对其进行扩展。如果你能完成本教程的所有部分,你就能构建高级的联邦学习系统,从而接近该领域当前的技术水平。" +"在本教程中,你将了解什么是联邦学习,用 Flower 搭建第一个系统,并逐步对其进行" +"扩展。如果你能完成本教程的所有部分,你就能构建高级的联邦学习系统,从而接近该" +"领域当前的技术水平。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " -"federated learning. Only a basic understanding of data science and Python" -" programming is assumed." -msgstr "🧑‍🏫 本教程从零开始,不要求熟悉联邦学习。仅假定对数据科学和 Python 编程有基本了解。" +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with federated " +"learning. Only a basic understanding of data science and Python programming " +"is assumed." +msgstr "" +"🧑‍🏫 本教程从零开始,不要求熟悉联邦学习。仅假定对数据科学和 Python 编程有基本" +"了解。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the open-source Flower community on Slack to connect, ask questions, and " -"get help: `Join Slack `__ 🌼 We'd love to " -"hear from you in the ``#introductions`` channel! And if anything is " -"unclear, head over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"open-source Flower community on Slack to connect, ask questions, and get " +"help: `Join Slack `__ 🌼 We'd love to hear " +"from you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" -"`Star Flower on GitHub `__ ⭐️ 并加入 Slack " -"上的开源 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼" -" 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何不清楚的地方,请访问 ``#questions`` 频道。" +"`Star Flower on GitHub `__ ⭐️ 并加入 Slack 上" +"的开源 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何" +"不清楚的地方,请访问 ``#questions`` 频道。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 msgid "Let's get started!" @@ -22913,16 +23282,19 @@ msgstr "经典机器学习" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how " -"most machine learning works today." -msgstr "在开始讨论联邦学习之前,让我们先快速回顾一下目前大多数机器学习的工作原理。" +"Before we begin to discuss federated learning, let us quickly recap how most " +"machine learning works today." +msgstr "" +"在开始讨论联邦学习之前,让我们先快速回顾一下目前大多数机器学习的工作原理。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 msgid "" -"In machine learning, we have a model, and we have data. The model could " -"be a neural network (as depicted here), or something else, like classical" -" linear regression." -msgstr "在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可以是其他东西,比如经典的线性回归。" +"In machine learning, we have a model, and we have data. The model could be a " +"neural network (as depicted here), or something else, like classical linear " +"regression." +msgstr "" +"在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可" +"以是其他东西,比如经典的线性回归。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 msgid "|2b5c62c529f6416f840c594cce062fbb|" @@ -22934,10 +23306,12 @@ msgstr "模型和数据" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 msgid "" -"We train the model using the data to perform a useful task. A task could " -"be to detect objects in images, transcribe an audio recording, or play a " -"game like Go." -msgstr "我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转录音频或玩围棋等游戏。" +"We train the model using the data to perform a useful task. A task could be " +"to detect objects in images, transcribe an audio recording, or play a game " +"like Go." +msgstr "" +"我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转" +"录音频或玩围棋等游戏。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 msgid "|90b334680cb7467d9a04d39b8e8dca9f|" @@ -22949,16 +23323,19 @@ msgstr "使用数据训练模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 msgid "" -"Now, in practice, the training data we work with doesn't originate on the" -" machine we train the model on. It gets created somewhere else." -msgstr "实际上,我们使用的训练数据并不来自我们训练模型的机器。它是在其他地方创建的。" +"Now, in practice, the training data we work with doesn't originate on the " +"machine we train the model on. It gets created somewhere else." +msgstr "" +"实际上,我们使用的训练数据并不来自我们训练模型的机器。它是在其他地方创建的。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 msgid "" "It originates on a smartphone by the user interacting with an app, a car " "collecting sensor data, a laptop receiving input via the keyboard, or a " "smart speaker listening to someone trying to sing a song." -msgstr "它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键盘输入的接收,或者智能扬声器上某人试着唱的歌。" +msgstr "" +"它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键" +"盘输入的接收,或者智能扬声器上某人试着唱的歌。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 msgid "|65764ceee89f4335bfd93fd0b115e831|" @@ -22971,12 +23348,12 @@ msgstr "手机上的数据" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 msgid "" "What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running" -" the same app. But it could also be several organizations, all generating" -" data for the same task." +"just one place, it's many places. It could be several devices all running " +"the same app. But it could also be several organizations, all generating " +"data for the same task." msgstr "" -"值得一提的是,这个 \"其他地方 " -"\"通常不只是一个地方,而是很多地方。它可能是多个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" +"值得一提的是,这个 \"其他地方 \"通常不只是一个地方,而是很多地方。它可能是多" +"个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" @@ -22988,11 +23365,12 @@ msgstr "数据存在于多种设备中" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 msgid "" -"So to use machine learning, or any kind of data analysis, the approach " -"that has been used in the past was to collect all data on a central " -"server. This server can be somewhere in a data center, or somewhere in " -"the cloud." -msgstr "因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" +"So to use machine learning, or any kind of data analysis, the approach that " +"has been used in the past was to collect all data on a central server. This " +"server can be somewhere in a data center, or somewhere in the cloud." +msgstr "" +"因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集" +"所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 msgid "|11e95ac83a8548d8b3505b4663187d07|" @@ -23007,7 +23385,9 @@ msgid "" "Once all the data is collected in one place, we can finally use machine " "learning algorithms to train our model on the data. This is the machine " "learning approach that we've basically always relied on." -msgstr "一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模型。这就是我们基本上一直依赖的机器学习方法。" +msgstr "" +"一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模" +"型。这就是我们基本上一直依赖的机器学习方法。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 msgid "|1dab2f3a23674abc8a6731f20fa10730|" @@ -23023,11 +23403,13 @@ msgstr "经典机器学习面临的挑战" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 msgid "" -"The classic machine learning approach we've just seen can be used in some" -" cases. Great examples include categorizing holiday photos, or analyzing " -"web traffic. Cases, where all the data is naturally available on a " -"centralized server." -msgstr "我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" +"The classic machine learning approach we've just seen can be used in some " +"cases. Great examples include categorizing holiday photos, or analyzing web " +"traffic. Cases, where all the data is naturally available on a centralized " +"server." +msgstr "" +"我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片" +"进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 msgid "|7f0ee162da38450788493a21627306f7|" @@ -23039,10 +23421,12 @@ msgstr "可集中管理" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 msgid "" -"But the approach can not be used in many other cases. Cases, where the " -"data is not available on a centralized server, or cases where the data " -"available on one server is not enough to train a good model." -msgstr "但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器上的数据不足以训练出一个好的模型。" +"But the approach can not be used in many other cases. Cases, where the data " +"is not available on a centralized server, or cases where the data available " +"on one server is not enough to train a good model." +msgstr "" +"但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器" +"上的数据不足以训练出一个好的模型。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" @@ -23054,10 +23438,12 @@ msgstr "无法集中" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 msgid "" -"There are many reasons why the classic centralized machine learning " -"approach does not work for a large number of highly important real-world " -"use cases. Those reasons include:" -msgstr "传统的集中式机器学习方法无法满足现实世界中大量极为重要的使用案例,原因有很多。这些原因包括:" +"There are many reasons why the classic centralized machine learning approach " +"does not work for a large number of highly important real-world use cases. " +"Those reasons include:" +msgstr "" +"传统的集中式机器学习方法无法满足现实世界中大量极为重要的使用案例,原因有很" +"多。这些原因包括:" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 msgid "" @@ -23066,39 +23452,48 @@ msgid "" "(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " "(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " "protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own " -"users' data for artificial intelligence training because those users live" -" in different parts of the world, and their data is governed by different" -" data protection regulations." -msgstr "" -"**法规**: " -"GDPR(欧洲)、CCPA(加利福尼亚)、PIPEDA(加拿大)、LGPD(巴西)、PDPL(阿根廷)、KVKK(土耳其)、POPI(南非)、FSS(俄罗斯)、CDPR(中国)、PDPB(印度)、PIPA(韩国)、APPI(日本)、PDP(印度尼西亚)、PDPA(新加坡)、APP(澳大利亚)等法规保护敏感数据不被移动。事实上,这些法规有时甚至会阻止单个组织将自己的用户数据用于人工智能培训,因为这些用户生活在世界不同地区,他们的数据受不同的数据保护法规管辖。" +"sometimes even prevent single organizations from combining their own users' " +"data for artificial intelligence training because those users live in " +"different parts of the world, and their data is governed by different data " +"protection regulations." +msgstr "" +"**法规**: GDPR(欧洲)、CCPA(加利福尼亚)、PIPEDA(加拿大)、LGPD(巴西)、" +"PDPL(阿根廷)、KVKK(土耳其)、POPI(南非)、FSS(俄罗斯)、CDPR(中国)、" +"PDPB(印度)、PIPA(韩国)、APPI(日本)、PDP(印度尼西亚)、PDPA(新加坡)、" +"APP(澳大利亚)等法规保护敏感数据不被移动。事实上,这些法规有时甚至会阻止单个" +"组织将自己的用户数据用于人工智能培训,因为这些用户生活在世界不同地区,他们的" +"数据受不同的数据保护法规管辖。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 msgid "" -"**User preference**: In addition to regulation, there are use cases where" -" users just expect that no data leaves their device, ever. If you type " -"your passwords and credit card info into the digital keyboard of your " -"phone, you don't expect those passwords to end up on the server of the " -"company that developed that keyboard, do you? In fact, that use case was " -"the reason federated learning was invented in the first place." +"**User preference**: In addition to regulation, there are use cases where " +"users just expect that no data leaves their device, ever. If you type your " +"passwords and credit card info into the digital keyboard of your phone, you " +"don't expect those passwords to end up on the server of the company that " +"developed that keyboard, do you? In fact, that use case was the reason " +"federated learning was invented in the first place." msgstr "" -"**用户偏好**: " -"除了法规之外,在一些使用案例中,用户只是希望数据永远不会离开他们的设备。如果你在手机的数字键盘上输入密码和信用卡信息,你不会希望这些密码最终出现在开发该键盘的公司的服务器上吧?事实上,这种用例正是联邦学习发明的初衷。" +"**用户偏好**: 除了法规之外,在一些使用案例中,用户只是希望数据永远不会离开他" +"们的设备。如果你在手机的数字键盘上输入密码和信用卡信息,你不会希望这些密码最" +"终出现在开发该键盘的公司的服务器上吧?事实上,这种用例正是联邦学习发明的初" +"衷。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data " -"volume that it is neither feasible nor economic to collect all the data " -"(due to, for example, bandwidth or communication efficiency). Think about" -" a national rail service with hundreds of train stations across the " -"country. If each of these train stations is outfitted with a number of " -"security cameras, the volume of raw on-device data they produce requires " -"incredibly powerful and exceedingly expensive infrastructure to process " -"and store. And most of the data isn't even useful." -msgstr "" -"**数据量**: " -"有些传感器(如摄像头)产生的数据量很大,收集所有数据既不可行,也不经济(例如,由于带宽或通信效率的原因)。试想一下全国铁路服务,全国有数百个火车站。如果每个火车站都安装了许多安全摄像头,那么它们所产生的大量原始设备数据就需要功能强大且极其昂贵的基础设施来处理和存储。而大部分数据甚至都是无用的。" +"**Data volume**: Some sensors, like cameras, produce such a high data volume " +"that it is neither feasible nor economic to collect all the data (due to, " +"for example, bandwidth or communication efficiency). Think about a national " +"rail service with hundreds of train stations across the country. If each of " +"these train stations is outfitted with a number of security cameras, the " +"volume of raw on-device data they produce requires incredibly powerful and " +"exceedingly expensive infrastructure to process and store. And most of the " +"data isn't even useful." +msgstr "" +"**数据量**: 有些传感器(如摄像头)产生的数据量很大,收集所有数据既不可行,也" +"不经济(例如,由于带宽或通信效率的原因)。试想一下全国铁路服务,全国有数百个" +"火车站。如果每个火车站都安装了许多安全摄像头,那么它们所产生的大量原始设备数" +"据就需要功能强大且极其昂贵的基础设施来处理和存储。而大部分数据甚至都是无用" +"的。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 msgid "Examples where centralized machine learning does not work include:" @@ -23112,8 +23507,7 @@ msgstr "用多家医院的敏感医疗记录训练癌症检测模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 msgid "" -"Financial information from different organizations to detect financial " -"fraud" +"Financial information from different organizations to detect financial fraud" msgstr "不同组织的财务信息,以侦查财务欺诈行为" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 @@ -23126,16 +23520,18 @@ msgstr "端到端加密信息可训练出更好的自动完成模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 msgid "" -"The popularity of privacy-enhancing systems like the `Brave " -"`__ browser or the `Signal `__ " -"messenger shows that users care about privacy. In fact, they choose the " -"privacy-enhancing version over other alternatives, if such an alternative" -" exists. But what can we do to apply machine learning and data science to" -" these cases to utilize private data? After all, these are all areas that" -" would benefit significantly from recent advances in AI." +"The popularity of privacy-enhancing systems like the `Brave `__ browser or the `Signal `__ messenger shows " +"that users care about privacy. In fact, they choose the privacy-enhancing " +"version over other alternatives, if such an alternative exists. But what can " +"we do to apply machine learning and data science to these cases to utilize " +"private data? After all, these are all areas that would benefit " +"significantly from recent advances in AI." msgstr "" -"像 `Brave `__浏览器或 `Signal " -"`__信息管理器这样的隐私增强系统的流行表明,用户关心隐私。事实上,他们会选择隐私性更好的产品。但是,我们能做些什么来将机器学习和数据科学应用到这些情况中,以利用隐私数据呢?毕竟,这些领域都将从人工智能的最新进展中受益匪浅。" +"像 `Brave `__浏览器或 `Signal `__信" +"息管理器这样的隐私增强系统的流行表明,用户关心隐私。事实上,他们会选择隐私性" +"更好的产品。但是,我们能做些什么来将机器学习和数据科学应用到这些情况中,以利" +"用隐私数据呢?毕竟,这些领域都将从人工智能的最新进展中受益匪浅。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 msgid "Federated learning" @@ -23144,10 +23540,11 @@ msgstr "联邦学习" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 msgid "" "Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead " -"of moving the data to the training. Here's the single-sentence " -"explanation:" -msgstr "联邦学习简单地颠覆了这种方法。它通过将训练转移到数据上,而不是将数据转移到训练上,在分布式数据上实现机器学习。下面是一句话的解释:" +"learning on distributed data by moving the training to the data, instead of " +"moving the data to the training. Here's the single-sentence explanation:" +msgstr "" +"联邦学习简单地颠覆了这种方法。它通过将训练转移到数据上,而不是将数据转移到训" +"练上,在分布式数据上实现机器学习。下面是一句话的解释:" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 msgid "Central machine learning: move the data to the computation" @@ -23159,22 +23556,28 @@ msgstr "联邦式(机器)学习:将计算转移到数据上" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 msgid "" -"By doing so, it enables us to use machine learning (and other data " -"science approaches) in areas where it wasn't possible before. We can now " -"train excellent medical AI models by enabling different hospitals to work" -" together. We can solve financial fraud by training AI models on the data" -" of different financial institutions. We can build novel privacy-" -"enhancing applications (such as secure messaging) that have better built-" -"in AI than their non-privacy-enhancing alternatives. And those are just a" -" few of the examples that come to mind. As we deploy federated learning, " -"we discover more and more areas that can suddenly be reinvented because " -"they now have access to vast amounts of previously inaccessible data." -msgstr "这样,我们就能在以前不可能的领域使用机器学习(和其他数据科学方法)。现在,我们可以通过让不同的医院协同工作来训练优秀的医疗人工智能模型。我们可以通过在不同金融机构的数据上训练人工智能模型来解决金融欺诈问题。我们可以构建新颖的隐私增强型应用(如安全信息),其内置的人工智能比非隐私增强型应用更好。以上只是我想到的几个例子。随着联邦学习的部署,我们会发现越来越多的领域可以突然重获新生,因为它们现在可以访问大量以前无法访问的数据。" +"By doing so, it enables us to use machine learning (and other data science " +"approaches) in areas where it wasn't possible before. We can now train " +"excellent medical AI models by enabling different hospitals to work " +"together. We can solve financial fraud by training AI models on the data of " +"different financial institutions. We can build novel privacy-enhancing " +"applications (such as secure messaging) that have better built-in AI than " +"their non-privacy-enhancing alternatives. And those are just a few of the " +"examples that come to mind. As we deploy federated learning, we discover " +"more and more areas that can suddenly be reinvented because they now have " +"access to vast amounts of previously inaccessible data." +msgstr "" +"这样,我们就能在以前不可能的领域使用机器学习(和其他数据科学方法)。现在,我" +"们可以通过让不同的医院协同工作来训练优秀的医疗人工智能模型。我们可以通过在不" +"同金融机构的数据上训练人工智能模型来解决金融欺诈问题。我们可以构建新颖的隐私" +"增强型应用(如安全信息),其内置的人工智能比非隐私增强型应用更好。以上只是我" +"想到的几个例子。随着联邦学习的部署,我们会发现越来越多的领域可以突然重获新" +"生,因为它们现在可以访问大量以前无法访问的数据。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 msgid "" -"So how does federated learning work, exactly? Let's start with an " -"intuitive explanation." +"So how does federated learning work, exactly? Let's start with an intuitive " +"explanation." msgstr "那么,联邦学习究竟是如何运作的呢?让我们从直观的解释开始。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 @@ -23187,10 +23590,12 @@ msgstr "步骤 0:初始化全局模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 msgid "" -"We start by initializing the model on the server. This is exactly the " -"same in classic centralized learning: we initialize the model parameters," -" either randomly or from a previously saved checkpoint." -msgstr "我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前保存的检查点初始化模型参数。" +"We start by initializing the model on the server. This is exactly the same " +"in classic centralized learning: we initialize the model parameters, either " +"randomly or from a previously saved checkpoint." +msgstr "" +"我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前" +"保存的检查点初始化模型参数。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 msgid "|5b1408eec0d746cdb91162a9107b6089|" @@ -23202,19 +23607,23 @@ msgstr "初始化全局模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client" -" nodes)" +"Step 1: Send model to a number of connected organizations/devices (client " +"nodes)" msgstr "第 1 步:将模型发送到多个连接的组织/设备(客户节点)" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 msgid "" "Next, we send the parameters of the global model to the connected client " "nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts " -"their local training using the same model parameters. We often use only a" -" few of the connected nodes instead of all nodes. The reason for this is " -"that selecting more and more client nodes has diminishing returns." -msgstr "接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户端节点会导致收益递减。" +"organizations). This is to ensure that each participating node starts their " +"local training using the same model parameters. We often use only a few of " +"the connected nodes instead of all nodes. The reason for this is that " +"selecting more and more client nodes has diminishing returns." +msgstr "" +"接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或" +"企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我" +"们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户" +"端节点会导致收益递减。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" @@ -23226,21 +23635,23 @@ msgstr "发送全局模型" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 msgid "" -"Step 2: Train model locally on the data of each organization/device " -"(client node)" +"Step 2: Train model locally on the data of each organization/device (client " +"node)" msgstr "步骤 2:在本地对每个机构/设备(客户端节点)的数据进行模型训练" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 msgid "" -"Now that all (selected) client nodes have the latest version of the " -"global model parameters, they start the local training. They use their " -"own local dataset to train their own local model. They don't train the " -"model until full convergence, but they only train for a little while. " -"This could be as little as one epoch on the local data, or even just a " -"few steps (mini-batches)." +"Now that all (selected) client nodes have the latest version of the global " +"model parameters, they start the local training. They use their own local " +"dataset to train their own local model. They don't train the model until " +"full convergence, but they only train for a little while. This could be as " +"little as one epoch on the local data, or even just a few steps (mini-" +"batches)." msgstr "" -"现在,所有(选定的)客户端节点都有了最新版本的全局模型参数,它们开始进行本地训练。它们使用自己的本地数据集来训练自己的本地模型。它们不会一直训练到模型完全收敛为止,而只是训练一小段时间。这可能只是本地数据上的一个遍历,甚至只是几个步骤" -"(mini-batches)。" +"现在,所有(选定的)客户端节点都有了最新版本的全局模型参数,它们开始进行本地" +"训练。它们使用自己的本地数据集来训练自己的本地模型。它们不会一直训练到模型完" +"全收敛为止,而只是训练一小段时间。这可能只是本地数据上的一个遍历,甚至只是几" +"个步骤(mini-batches)。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" @@ -23256,14 +23667,17 @@ msgstr "步骤 3:将模型参数更新返回服务器" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 msgid "" -"After local training, each client node has a slightly different version " -"of the model parameters they originally received. The parameters are all " +"After local training, each client node has a slightly different version of " +"the model parameters they originally received. The parameters are all " "different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the " -"server. The model updates they send can either be the full model " -"parameters or just the gradients that were accumulated during local " -"training." -msgstr "经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同,是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练过程中积累的梯度。" +"dataset. The client nodes then send those model updates back to the server. " +"The model updates they send can either be the full model parameters or just " +"the gradients that were accumulated during local training." +msgstr "" +"经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同," +"是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型" +"更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练" +"过程中积累的梯度。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 msgid "|ec1fe880237247e0975f52766775ab84|" @@ -23280,36 +23694,38 @@ msgstr "步骤 4:将模型更新聚合到新的全局模型中" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 msgid "" "The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of " -"the original global model, each trained on the local data of one client. " -"But didn't we want to have one model that contains the learnings from the" -" data of all 100 client nodes?" +"selected 100 client nodes, it now has 100 slightly different versions of the " +"original global model, each trained on the local data of one client. But " +"didn't we want to have one model that contains the learnings from the data " +"of all 100 client nodes?" msgstr "" -"服务器从选定的客户端节点接收模型更新。如果服务器选择了 100 个客户端节点,那么它现在就拥有 100 " -"个略有不同的原始全局模型版本,每个版本都是根据一个客户端的本地数据训练出来的。难道我们不希望有一个包含所有 100 个客户节点数据的模型吗?" +"服务器从选定的客户端节点接收模型更新。如果服务器选择了 100 个客户端节点,那么" +"它现在就拥有 100 个略有不同的原始全局模型版本,每个版本都是根据一个客户端的本" +"地数据训练出来的。难道我们不希望有一个包含所有 100 个客户节点数据的模型吗?" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 msgid "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." -msgstr "" -"为了得到一个单一的模型,我们必须将从客户端节点收到的所有模型更新合并起来。这个过程称为*聚合*,有许多不同的方法。最基本的方法称为 " -"*Federated Averaging* (`McMahan等人,2016 " -"`__),通常缩写为*FedAvg*。*FedAvg* 可以把100 " -"个模型更新进行平均。更准确地说,它取的是模型更新的*加权平均值*,根据每个客户端用于训练的数据数量进行加权。加权对于确保每个数据示例对生成的全局模型具有相同的" -" \"影响 \"非常重要。如果一个客户端有 10 个数据点,而另一个客户有 100 个数据点,那么在不加权的情况下,10 个示例对全局模型的影响是" -" 100 个示例的 10 倍。" +"In order to get one single model, we have to combine all the model updates " +"we received from the client nodes. This process is called *aggregation*, and " +"there are many different ways to do it. The most basic way to do it is " +"called *Federated Averaging* (`McMahan et al., 2016 `__), often abbreviated as *FedAvg*. *FedAvg* takes the 100 " +"model updates and, as the name suggests, averages them. To be more precise, " +"it takes the *weighted average* of the model updates, weighted by the number " +"of examples each client used for training. The weighting is important to " +"make sure that each data example has the same \"influence\" on the resulting " +"global model. If one client has 10 examples, and another client has 100 " +"examples, then - without weighting - each of the 10 examples would influence " +"the global model ten times as much as each of the 100 examples." +msgstr "" +"为了得到一个单一的模型,我们必须将从客户端节点收到的所有模型更新合并起来。这" +"个过程称为*聚合*,有许多不同的方法。最基本的方法称为 *Federated Averaging* " +"(`McMahan等人,2016 `__),通常缩写为" +"*FedAvg*。*FedAvg* 可以把100 个模型更新进行平均。更准确地说,它取的是模型更新" +"的*加权平均值*,根据每个客户端用于训练的数据数量进行加权。加权对于确保每个数" +"据示例对生成的全局模型具有相同的 \"影响 \"非常重要。如果一个客户端有 10 个数" +"据点,而另一个客户有 100 个数据点,那么在不加权的情况下,10 个示例对全局模型" +"的影响是 100 个示例的 10 倍。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" @@ -23326,50 +23742,54 @@ msgstr "步骤 5:重复步骤 1 至 4,直至模型收敛" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 msgid "" "Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step " -"1), the client nodes train on their local data (step 2), they send their " -"updated models to the server (step 3), and the server then aggregates the" -" model updates to get a new version of the global model (step 4)." +"global model parameters get sent to the participating client nodes (step 1), " +"the client nodes train on their local data (step 2), they send their updated " +"models to the server (step 3), and the server then aggregates the model " +"updates to get a new version of the global model (step 4)." msgstr "" -"步骤 1 至 4 就是我们所说的单轮联邦学习。全局模型参数被发送到参与的客户端节点(第 1 步),客户端节点对其本地数据进行训练(第 2 " -"步),然后将更新后的模型发送到服务器(第 3 步),服务器汇总模型更新,得到新版本的全局模型(第 4 步)。" +"步骤 1 至 4 就是我们所说的单轮联邦学习。全局模型参数被发送到参与的客户端节点" +"(第 1 步),客户端节点对其本地数据进行训练(第 2 步),然后将更新后的模型发" +"送到服务器(第 3 步),服务器汇总模型更新,得到新版本的全局模型(第 4 步)。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 msgid "" -"During a single round, each client node that participates in that " -"iteration only trains for a little while. This means that after the " -"aggregation step (step 4), we have a model that has been trained on all " -"the data of all participating client nodes, but only for a little while. " -"We then have to repeat this training process over and over again to " -"eventually arrive at a fully trained model that performs well across the " -"data of all client nodes." +"During a single round, each client node that participates in that iteration " +"only trains for a little while. This means that after the aggregation step " +"(step 4), we have a model that has been trained on all the data of all " +"participating client nodes, but only for a little while. We then have to " +"repeat this training process over and over again to eventually arrive at a " +"fully trained model that performs well across the data of all client nodes." msgstr "" -"在一轮迭代中,每个参与迭代的客户节点只训练一小段时间。这意味着,在聚合步骤(步骤 " -"4)之后,我们的模型已经在所有参与的客户节点的所有数据上训练过了,但只训练了一小会儿。然后,我们必须一次又一次地重复这一训练过程,最终得到一个经过全面训练的模型,该模型在所有客户节点的数据中都表现良好。" +"在一轮迭代中,每个参与迭代的客户节点只训练一小段时间。这意味着,在聚合步骤" +"(步骤 4)之后,我们的模型已经在所有参与的客户节点的所有数据上训练过了,但只" +"训练了一小会儿。然后,我们必须一次又一次地重复这一训练过程,最终得到一个经过" +"全面训练的模型,该模型在所有客户节点的数据中都表现良好。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 msgid "" "Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning" -" in a nutshell. In later parts of this tutorial, we will go into more " -"detail. Interesting questions include: How can we select the best client " -"nodes that should participate in the next round? What's the best way to " -"aggregate model updates? How can we handle failing client nodes " -"(stragglers)?" +"There's a lot more to discuss, of course, but that was federated learning in " +"a nutshell. In later parts of this tutorial, we will go into more detail. " +"Interesting questions include: How can we select the best client nodes that " +"should participate in the next round? What's the best way to aggregate model " +"updates? How can we handle failing client nodes (stragglers)?" msgstr "" -"恭喜您,现在您已经了解了联邦学习的基础知识。当然,要讨论的内容还有很多,但这只是联邦学习的一个缩影。在本教程的后半部分,我们将进行更详细的介绍。有趣的问题包括" -" 我们如何选择最好的客户端节点参与下一轮学习?聚合模型更新的最佳方法是什么?如何处理失败的客户端节点(落伍者)?" +"恭喜您,现在您已经了解了联邦学习的基础知识。当然,要讨论的内容还有很多,但这" +"只是联邦学习的一个缩影。在本教程的后半部分,我们将进行更详细的介绍。有趣的问" +"题包括 我们如何选择最好的客户端节点参与下一轮学习?聚合模型更新的最佳方法是什" +"么?如何处理失败的客户端节点(落伍者)?" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 msgid "" -"Just like we can train a model on the decentralized data of different " -"client nodes, we can also evaluate the model on that data to receive " -"valuable metrics. This is called federated evaluation, sometimes " -"abbreviated as FE. In fact, federated evaluation is an integral part of " -"most federated learning systems." +"Just like we can train a model on the decentralized data of different client " +"nodes, we can also evaluate the model on that data to receive valuable " +"metrics. This is called federated evaluation, sometimes abbreviated as FE. " +"In fact, federated evaluation is an integral part of most federated learning " +"systems." msgstr "" -"就像我们可以在不同客户节点的分散数据上训练一个模型一样,我们也可以在这些数据上对模型进行评估,以获得有价值的指标。这就是所谓的联邦评估,有时简称为" -" FE。事实上,联邦评估是大多数联邦学习系统不可或缺的一部分。" +"就像我们可以在不同客户节点的分散数据上训练一个模型一样,我们也可以在这些数据" +"上对模型进行评估,以获得有价值的指标。这就是所谓的联邦评估,有时简称为 FE。事" +"实上,联邦评估是大多数联邦学习系统不可或缺的一部分。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 msgid "Federated analytics" @@ -23377,28 +23797,33 @@ msgstr "联邦分析" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 msgid "" -"In many cases, machine learning isn't necessary to derive value from " -"data. Data analysis can yield valuable insights, but again, there's often" -" not enough data to get a clear answer. What's the average age at which " -"people develop a certain type of health condition? Federated analytics " -"enables such queries over multiple client nodes. It is usually used in " -"conjunction with other privacy-enhancing technologies like secure " -"aggregation to prevent the server from seeing the results submitted by " -"individual client nodes." -msgstr "在很多情况下,机器学习并不是从数据中获取价值的必要条件。数据分析可以产生有价值的见解,但同样,往往没有足够的数据来获得明确的答案。人们患某种健康疾病的平均年龄是多少?联邦分析可以通过多个客户端节点进行此类查询。它通常与安全聚合等其他隐私增强技术结合使用,以防止服务器看到单个客户端节点提交的结果。" +"In many cases, machine learning isn't necessary to derive value from data. " +"Data analysis can yield valuable insights, but again, there's often not " +"enough data to get a clear answer. What's the average age at which people " +"develop a certain type of health condition? Federated analytics enables such " +"queries over multiple client nodes. It is usually used in conjunction with " +"other privacy-enhancing technologies like secure aggregation to prevent the " +"server from seeing the results submitted by individual client nodes." +msgstr "" +"在很多情况下,机器学习并不是从数据中获取价值的必要条件。数据分析可以产生有价" +"值的见解,但同样,往往没有足够的数据来获得明确的答案。人们患某种健康疾病的平" +"均年龄是多少?联邦分析可以通过多个客户端节点进行此类查询。它通常与安全聚合等" +"其他隐私增强技术结合使用,以防止服务器看到单个客户端节点提交的结果。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 msgid "" "Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and " -"sharing statistical data, ensuring the privacy of individual " -"participants. DP achieves this by adding statistical noise to the model " -"updates, ensuring any individual participants’ information cannot be " -"distinguished or re-identified. This technique can be considered an " -"optimization that provides a quantifiable privacy protection measure." -msgstr "" -"差分隐私(DP)经常在联邦学习中被提及。这是一种在分析和共享统计数据时使用的隐私保护方法,可确保单个参与者的隐私。DP " -"通过在模型更新中添加统计噪声来实现这一目的,确保任何个体参与者的信息都无法被区分或重新识别。这种技术可被视为一种优化,提供了一种可量化的隐私保护措施。" +"Learning. It is a privacy-preserving method used when analyzing and sharing " +"statistical data, ensuring the privacy of individual participants. DP " +"achieves this by adding statistical noise to the model updates, ensuring any " +"individual participants’ information cannot be distinguished or re-" +"identified. This technique can be considered an optimization that provides a " +"quantifiable privacy protection measure." +msgstr "" +"差分隐私(DP)经常在联邦学习中被提及。这是一种在分析和共享统计数据时使用的隐" +"私保护方法,可确保单个参与者的隐私。DP 通过在模型更新中添加统计噪声来实现这一" +"目的,确保任何个体参与者的信息都无法被区分或重新识别。这种技术可被视为一种优" +"化,提供了一种可量化的隐私保护措施。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 msgid "Flower" @@ -23406,17 +23831,18 @@ msgstr "Flower" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 msgid "" -"Federated learning, federated evaluation, and federated analytics require" -" infrastructure to move machine learning models back and forth, train and" -" evaluate them on local data, and then aggregate the updated models. " -"Flower provides the infrastructure to do exactly that in an easy, " -"scalable, and secure way. In short, Flower presents a unified approach to" -" federated learning, analytics, and evaluation. It allows the user to " -"federate any workload, any ML framework, and any programming language." +"Federated learning, federated evaluation, and federated analytics require " +"infrastructure to move machine learning models back and forth, train and " +"evaluate them on local data, and then aggregate the updated models. Flower " +"provides the infrastructure to do exactly that in an easy, scalable, and " +"secure way. In short, Flower presents a unified approach to federated " +"learning, analytics, and evaluation. It allows the user to federate any " +"workload, any ML framework, and any programming language." msgstr "" -"联邦学习、联邦评估和联邦分析需要基础框架来来回移动机器学习模型,在本地数据上对其进行训练和评估,然后汇总更新的模型。Flower " -"提供的基础架构正是以简单、可扩展和安全的方式实现这些目标的。简而言之,Flower " -"为联邦学习、分析和评估提供了一种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" +"联邦学习、联邦评估和联邦分析需要基础框架来来回移动机器学习模型,在本地数据上" +"对其进行训练和评估,然后汇总更新的模型。Flower 提供的基础架构正是以简单、可扩" +"展和安全的方式实现这些目标的。简而言之,Flower 为联邦学习、分析和评估提供了一" +"种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 msgid "|ff726bc5505e432388ee2fdd6ef420b9|" @@ -23424,92 +23850,84 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal" -" computer, roomba, and phone)" -msgstr "Flower联邦学习服务器和客户端节点(汽车、滑板车、个人电脑、roomba 和电话)" +"Flower federated learning server and client nodes (car, scooter, personal " +"computer, roomba, and phone)" +msgstr "" +"Flower联邦学习服务器和客户端节点(汽车、滑板车、个人电脑、roomba 和电话)" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 msgid "" -"Congratulations, you just learned the basics of federated learning and " -"how it relates to the classic (centralized) machine learning!" -msgstr "恭喜您,您刚刚了解了联邦学习的基础知识,以及它与传统(集中式)机器学习的关系!" +"Congratulations, you just learned the basics of federated learning and how " +"it relates to the classic (centralized) machine learning!" +msgstr "" +"恭喜您,您刚刚了解了联邦学习的基础知识,以及它与传统(集中式)机器学习的关" +"系!" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 msgid "" -"In the next part of this tutorial, we are going to build a first " -"federated learning system with Flower." +"In the next part of this tutorial, we are going to build a first federated " +"learning system with Flower." msgstr "在本教程的下一部分,我们将用 Flower 建立第一个联邦学习系统。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 msgid "" -"The `Flower Federated Learning Tutorial - Part 1 " -"`__ shows how to build a simple federated learning system " -"with PyTorch and Flower." +"The `Flower Federated Learning Tutorial - Part 1 `__ shows how to " +"build a simple federated learning system with PyTorch and Flower." msgstr "" -"`Flower 联邦学习教程 - 第 1 部分 `__ 展示了如何使用 PyTorch 和 Flower " -"构建一个简单的联邦学习系统。" +"`Flower 联邦学习教程 - 第 1 部分 `__ 展示了如何使用 PyTorch 和 Flower 构" +"建一个简单的联邦学习系统。" #~ msgid "Before the release" #~ msgstr "发布前" #~ msgid "" -#~ "Update the changelog (``changelog.md``) with" -#~ " all relevant changes that happened " -#~ "after the last release. If the " -#~ "last release was tagged ``v1.2.0``, you" -#~ " can use the following URL to " -#~ "see all commits that got merged " -#~ "into ``main`` since then:" +#~ "Update the changelog (``changelog.md``) with all relevant changes that " +#~ "happened after the last release. If the last release was tagged " +#~ "``v1.2.0``, you can use the following URL to see all commits that got " +#~ "merged into ``main`` since then:" #~ msgstr "" -#~ "更新更新日志 (``changelog.md``),加入上次发布后发生的所有相关变更。如果上次发布的版本被标记为 " -#~ "``v1.2.0``,则可以使用以下 URL 查看此后合并到 ``main`` 的所有提交:" +#~ "更新更新日志 (``changelog.md``),加入上次发布后发生的所有相关变更。如果上" +#~ "次发布的版本被标记为 ``v1.2.0``,则可以使用以下 URL 查看此后合并到 " +#~ "``main`` 的所有提交:" #~ msgid "" -#~ "`GitHub: Compare v1.2.0...main " -#~ "`_" +#~ "`GitHub: Compare v1.2.0...main `_" #~ msgstr "" -#~ "`GitHub: Compare v1.2.0...main " -#~ "`_" +#~ "`GitHub: Compare v1.2.0...main `_" #~ msgid "" -#~ "Thank the authors who contributed since" -#~ " the last release. This can be " -#~ "done by running the ``./dev/add-" -#~ "shortlog.sh`` convenience script (it can " -#~ "be ran multiple times and will " -#~ "update the names in the list if" -#~ " new contributors were added in the" -#~ " meantime)." +#~ "Thank the authors who contributed since the last release. This can be " +#~ "done by running the ``./dev/add-shortlog.sh`` convenience script (it can " +#~ "be ran multiple times and will update the names in the list if new " +#~ "contributors were added in the meantime)." #~ msgstr "" #~ "感谢自上次发布以来做出贡献的作者。可以通过运行 ``./dev/add-shortlog.sh`` " -#~ "方便脚本来完成(可以多次运行,如果在此期间有新的贡献者加入,则会更新列表中的名字)。" +#~ "方便脚本来完成(可以多次运行,如果在此期间有新的贡献者加入,则会更新列表中" +#~ "的名字)。" #~ msgid "" -#~ "Update the ``changelog.md`` section header " -#~ "``Unreleased`` to contain the version " -#~ "number and date for the release " -#~ "you are building. Create a pull " +#~ "Update the ``changelog.md`` section header ``Unreleased`` to contain the " +#~ "version number and date for the release you are building. Create a pull " #~ "request with the change." #~ msgstr "" -#~ "更新 ``changelog.md`` 部分的标题 ``Unreleased`` " -#~ "以包含你正在构建的版本的版本号和日期。创建一个包含更改的拉取请求。" +#~ "更新 ``changelog.md`` 部分的标题 ``Unreleased`` 以包含你正在构建的版本的版" +#~ "本号和日期。创建一个包含更改的拉取请求。" #~ msgid "" -#~ "Second, create a virtual environment " -#~ "(and activate it). If you chose to" -#~ " use :code:`pyenv` (with the :code" -#~ ":`pyenv-virtualenv` plugin) and already " -#~ "have it installed , you can use" -#~ " the following convenience script (by " -#~ "default it will use :code:`Python " -#~ "3.8.17`, but you can change it by" -#~ " providing a specific :code:``)::" +#~ "Second, create a virtual environment (and activate it). If you chose to " +#~ "use :code:`pyenv` (with the :code:`pyenv-virtualenv` plugin) and already " +#~ "have it installed , you can use the following convenience script (by " +#~ "default it will use :code:`Python 3.8.17`, but you can change it by " +#~ "providing a specific :code:``)::" #~ msgstr "" -#~ "其次,创建虚拟环境(并激活它)。如果您选择使用 :code:`pyenv`(使用 :code:`pyenv-" -#~ "virtualenv`插件),并且已经安装了该插件,则可以使用下面的便捷脚本(默认情况下使用 " -#~ ":code:`Python3.8.17`,但您可以通过提供特定的 :code:`<版本>`来更改)::" +#~ "其次,创建虚拟环境(并激活它)。如果您选择使用 :code:`pyenv`(使用 :code:" +#~ "`pyenv-virtualenv`插件),并且已经安装了该插件,则可以使用下面的便捷脚本" +#~ "(默认情况下使用 :code:`Python3.8.17`,但您可以通过提供特定的 :code:`<版本" +#~ ">`来更改)::" #~ msgid "flwr (Python API reference)" #~ msgstr "flwr(Python API 参考)" @@ -23602,88 +24020,69 @@ msgstr "" #~ msgstr "server.strategy.DPFedAvgAdaptive" #~ msgid "" -#~ "**Fix the incorrect return types of " -#~ "Strategy** " -#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" +#~ "**Fix the incorrect return types of Strategy** ([#2432](https://github." +#~ "com/adap/flower/pull/2432/files))" #~ msgstr "" -#~ "**修复策略的错误返回类型** " -#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" +#~ "**修复策略的错误返回类型** ([#2432](https://github.com/adap/flower/" +#~ "pull/2432/files))" #~ msgid "" -#~ "The types of the return values in" -#~ " the docstrings in two methods " -#~ "(`aggregate_fit` and `aggregate_evaluate`) now " -#~ "match the hint types in the code." +#~ "The types of the return values in the docstrings in two methods " +#~ "(`aggregate_fit` and `aggregate_evaluate`) now match the hint types in " +#~ "the code." #~ msgstr "" -#~ "两个方法(\"aggregate_fit \"和 " -#~ "\"aggregate_evaluate\")的文档说明中的返回值类型现在与代码中的提示类型一致。" +#~ "两个方法(\"aggregate_fit \"和 \"aggregate_evaluate\")的文档说明中的返回" +#~ "值类型现在与代码中的提示类型一致。" #~ msgid "" -#~ "**Update Flower Examples** " -#~ "([#2384](https://github.com/adap/flower/pull/2384),[#2425](https://github.com/adap/flower/pull/2425)," -#~ " [#2526](https://github.com/adap/flower/pull/2526))" +#~ "**Update Flower Examples** ([#2384](https://github.com/adap/flower/" +#~ "pull/2384),[#2425](https://github.com/adap/flower/pull/2425), [#2526]" +#~ "(https://github.com/adap/flower/pull/2526))" #~ msgstr "" -#~ "** 更新 Flower Examples** " -#~ "([#2384](https://github.com/adap/flower/pull/2384),[#2425](https://github.com/adap/flower/pull/2425)," -#~ " [#2526](https://github.com/adap/flower/pull/2526))" +#~ "** 更新 Flower Examples** ([#2384](https://github.com/adap/flower/" +#~ "pull/2384),[#2425](https://github.com/adap/flower/pull/2425), [#2526]" +#~ "(https://github.com/adap/flower/pull/2526))" #~ msgid "" -#~ "That's it for the client. We only" -#~ " have to implement :code:`Client` or " -#~ ":code:`NumPyClient` and call " -#~ ":code:`fl.client.start_client()`. The string " -#~ ":code:`\"0.0.0.0:8080\"` tells the client " -#~ "which server to connect to. In our" -#~ " case we can run the server and" -#~ " the client on the same machine, " -#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" -#~ " we run a truly federated workload" -#~ " with the server and clients running" -#~ " on different machines, all that " -#~ "needs to change is the " -#~ ":code:`server_address` we pass to the " -#~ "client." +#~ "That's it for the client. We only have to implement :code:`Client` or :" +#~ "code:`NumPyClient` and call :code:`fl.client.start_client()`. The string :" +#~ "code:`\"0.0.0.0:8080\"` tells the client which server to connect to. In " +#~ "our case we can run the server and the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If we run a truly federated " +#~ "workload with the server and clients running on different machines, all " +#~ "that needs to change is the :code:`server_address` we pass to the client." #~ msgstr "" -#~ "对于客户端就需要做这么多。我们仅需要实现 " -#~ ":code:`Client`或者:code:`NumPyClient`然后调用:code:`fl.client.start_client()`。字符串" -#~ " :code:`\"0.0.0.0:8080\"` " -#~ "告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同一台机器上运行服务器和客户端,因此我们使用:code:`\"0.0.0.0:8080\"`。如果我们运行真正联邦学习的工作负载,服务器和客户端在不同的机器上运行,则需要更改的只是我们传递给客户端的" -#~ " server_address 。" +#~ "对于客户端就需要做这么多。我们仅需要实现 :code:`Client`或者:code:" +#~ "`NumPyClient`然后调用:code:`fl.client.start_client()`。字符串 :code:" +#~ "`\"0.0.0.0:8080\"` 告诉客户端要连接到哪个服务器。在我们的例子中,我们可以" +#~ "在同一台机器上运行服务器和客户端,因此我们使用:code:`\"0.0.0.0:8080\"`。如" +#~ "果我们运行真正联邦学习的工作负载,服务器和客户端在不同的机器上运行,则需要" +#~ "更改的只是我们传递给客户端的 server_address 。" #~ msgid "" -#~ "That's it for the client. We only" -#~ " have to implement :code:`Client` or " -#~ ":code:`NumPyClient` and call " -#~ ":code:`fl.client.start_client()`. The string " -#~ ":code:`\"[::]:8080\"` tells the client which" -#~ " server to connect to. In our " -#~ "case we can run the server and " -#~ "the client on the same machine, " -#~ "therefore we use :code:`\"[::]:8080\"`. If " -#~ "we run a truly federated workload " -#~ "with the server and clients running " -#~ "on different machines, all that needs" -#~ " to change is the :code:`server_address`" -#~ " we point the client at." +#~ "That's it for the client. We only have to implement :code:`Client` or :" +#~ "code:`NumPyClient` and call :code:`fl.client.start_client()`. The string :" +#~ "code:`\"[::]:8080\"` tells the client which server to connect to. In our " +#~ "case we can run the server and the client on the same machine, therefore " +#~ "we use :code:`\"[::]:8080\"`. If we run a truly federated workload with " +#~ "the server and clients running on different machines, all that needs to " +#~ "change is the :code:`server_address` we point the client at." #~ msgstr "" -#~ "对于客户来说就是这样了。我们只需实现 :code:`Client` 或 " -#~ ":code:`NumPyClient` 并调用:code:`fl.client.start_client()` " -#~ "即可。字符串 :code:`\"[::]:8080\"` " -#~ "告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " -#~ ":code:`\"[::]:8080\"`。如果我们运行真正联邦的工作负载,服务器和客户端运行在不同的机器上,则需要更改的只是我们指向客户端的" -#~ " server_address 。" +#~ "对于客户来说就是这样了。我们只需实现 :code:`Client` 或 :code:" +#~ "`NumPyClient` 并调用:code:`fl.client.start_client()` 即可。字符串 :code:" +#~ "`\"[::]:8080\"` 告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同" +#~ "一台机器上运行服务器和客户端,因此我们使用 :code:`\"[::]:8080\"`。如果我们" +#~ "运行真正联邦的工作负载,服务器和客户端运行在不同的机器上,则需要更改的只是" +#~ "我们指向客户端的 server_address 。" #~ msgid "" -#~ "Let's now load the CIFAR-10 training " -#~ "and test set, partition them into " -#~ "ten smaller datasets (each split into" -#~ " training and validation set), and " -#~ "wrap the resulting partitions by " -#~ "creating a PyTorch ``DataLoader`` for " +#~ "Let's now load the CIFAR-10 training and test set, partition them into " +#~ "ten smaller datasets (each split into training and validation set), and " +#~ "wrap the resulting partitions by creating a PyTorch ``DataLoader`` for " #~ "each of them:" #~ msgstr "" -#~ "现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 " -#~ "个较小的数据集(每个数据集又分为训练集和验证集),并通过为每个数据集创建 PyTorch " +#~ "现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 个较小的数据集" +#~ "(每个数据集又分为训练集和验证集),并通过为每个数据集创建 PyTorch " #~ "``DataLoader`` 来包装由此产生的分割集:" #~ msgid "|e1dd4b4129b040bea23a894266227080|" @@ -23732,169 +24131,127 @@ msgstr "" #~ msgstr "上传 whl(例如 ``flwr-1.6.0-py3-none-any.whl``)" #~ msgid "" -#~ "Change ``!pip install -q 'flwr[simulation]'" -#~ " torch torchvision matplotlib`` to ``!pip" -#~ " install -q 'flwr-1.6.0-py3-none-" -#~ "any.whl[simulation]' torch torchvision matplotlib``" -#~ msgstr "" -#~ "将``!pip install -q 'flwr[simulation]' torch" -#~ " torchvision matplotlib``更改为``!pip install -q " -#~ "'flwr-1.6.0-py3-none-any.whl[simulation]' torch " -#~ "torch torchvision matplotlib``" - -#~ msgid "" -#~ "All that's left to do it to " -#~ "define a function that loads both " -#~ "model and data, creates a " -#~ ":code:`CifarClient`, and starts this client." -#~ " You load your data and model " -#~ "by using :code:`cifar.py`. Start " -#~ ":code:`CifarClient` with the function " -#~ ":code:`fl.client.start_numpy_client()` by pointing " -#~ "it at the same IP address we " -#~ "used in :code:`server.py`:" -#~ msgstr "" -#~ "剩下要做的就是定义一个加载模型和数据的函数,创建一个 :code:`CifarClient` 并启动该客户端。使用" -#~ " :code:`cifar.py` 加载数据和模型。使用函数 " -#~ ":code:`fl.client.start_numpy_client()` 启动 " -#~ ":code:`CifarClient`,将其指向我们在 :code:`server.py` 中使用的相同 " -#~ "IP 地址:" - -#~ msgid "" -#~ "The :code:`VirtualClientEngine` schedules, launches" -#~ " and manages `virtual` clients. These " -#~ "clients are identical to `non-virtual`" -#~ " clients (i.e. the ones you launch" -#~ " via the command `flwr.client.start_numpy_client" -#~ " `_)" -#~ " in the sense that they can be" -#~ " configure by creating a class " -#~ "inheriting, for example, from " -#~ "`flwr.client.NumPyClient `_ and therefore " -#~ "behave in an identical way. In " -#~ "addition to that, clients managed by " -#~ "the :code:`VirtualClientEngine` are:" +#~ "Change ``!pip install -q 'flwr[simulation]' torch torchvision " +#~ "matplotlib`` to ``!pip install -q 'flwr-1.6.0-py3-none-any." +#~ "whl[simulation]' torch torchvision matplotlib``" #~ msgstr "" -#~ "代码:`VirtualClientEngine`调度、启动和管理`虚拟`客户端。这些客户端与 \"非虚拟 " -#~ "\"客户端(即通过命令 `flwr.client.start_numpy_client `_启动的客户端)完全相同,它们可以通过创建一个继承自 \"flwr.client.NumPyClient " -#~ "`_\" " -#~ "的类来配置,因此行为方式也完全相同。除此之外,由 :code:`VirtualClientEngine` " -#~ "管理的客户端还包括:" +#~ "将``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``更改" +#~ "为``!pip install -q 'flwr-1.6.0-py3-none-any.whl[simulation]' torch torch " +#~ "torchvision matplotlib``" #~ msgid "" -#~ "Please follow the first section on " -#~ "`Run Flower using Docker " -#~ "`_ which covers this" -#~ " step in more detail." +#~ "All that's left to do it to define a function that loads both model and " +#~ "data, creates a :code:`CifarClient`, and starts this client. You load " +#~ "your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " +#~ "with the function :code:`fl.client.start_numpy_client()` by pointing it " +#~ "at the same IP address we used in :code:`server.py`:" #~ msgstr "" +#~ "剩下要做的就是定义一个加载模型和数据的函数,创建一个 :code:`CifarClient` " +#~ "并启动该客户端。使用 :code:`cifar.py` 加载数据和模型。使用函数 :code:`fl." +#~ "client.start_numpy_client()` 启动 :code:`CifarClient`,将其指向我们在 :" +#~ "code:`server.py` 中使用的相同 IP 地址:" #~ msgid "" -#~ "If the section is completely empty " -#~ "(without any token) or non-existant, " -#~ "the changelog will just contain the " -#~ "title of the PR for the changelog" -#~ " entry, without any description." +#~ "The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " +#~ "clients. These clients are identical to `non-virtual` clients (i.e. the " +#~ "ones you launch via the command `flwr.client.start_numpy_client `_) in the sense that they can be configure " +#~ "by creating a class inheriting, for example, from `flwr.client." +#~ "NumPyClient `_ and therefore " +#~ "behave in an identical way. In addition to that, clients managed by the :" +#~ "code:`VirtualClientEngine` are:" #~ msgstr "" +#~ "代码:`VirtualClientEngine`调度、启动和管理`虚拟`客户端。这些客户端与 \"非" +#~ "虚拟 \"客户端(即通过命令 `flwr.client.start_numpy_client `_启动的客户端)完全相同,它们可以通过创建一个继承" +#~ "自 \"flwr.client.NumPyClient `_\" 的类来配置,因此行为方式也完全相同。除此之外,由 :code:" +#~ "`VirtualClientEngine` 管理的客户端还包括:" #~ msgid "Example: Walk-Through PyTorch & MNIST" #~ msgstr "实例: PyTorch 和 MNIST 的演练" #~ msgid "" -#~ "In this tutorial we will learn, " -#~ "how to train a Convolutional Neural " -#~ "Network on MNIST using Flower and " -#~ "PyTorch." -#~ msgstr "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 MNIST 上训练卷积神经网络。" +#~ "In this tutorial we will learn, how to train a Convolutional Neural " +#~ "Network on MNIST using Flower and PyTorch." +#~ msgstr "" +#~ "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 MNIST 上训练卷积神经网" +#~ "络。" #~ msgid "" -#~ "Since we want to use PyTorch to" -#~ " solve a computer vision task, let's" -#~ " go ahead an install PyTorch and " -#~ "the **torchvision** library:" -#~ msgstr "我们想用 PyTorch 来做计算机视觉任务,需要先安装 PyTorch 和 **torchvision** 库:" +#~ "Since we want to use PyTorch to solve a computer vision task, let's go " +#~ "ahead an install PyTorch and the **torchvision** library:" +#~ msgstr "" +#~ "我们想用 PyTorch 来做计算机视觉任务,需要先安装 PyTorch 和 " +#~ "**torchvision** 库:" #~ msgid "Ready... Set... Train!" #~ msgstr "准备...设置...训练!" #~ msgid "" -#~ "Now that we have all our " -#~ "dependencies installed, let's run a " -#~ "simple distributed training with two " -#~ "clients and one server. Our training " -#~ "procedure and network architecture are " -#~ "based on PyTorch's `Basic MNIST Example" -#~ " `_. " -#~ "This will allow you see how easy" -#~ " it is to wrap your code with" -#~ " Flower and begin training in a " -#~ "federated way. We provide you with " -#~ "two helper scripts, namely *run-" -#~ "server.sh*, and *run-clients.sh*. Don't " -#~ "be afraid to look inside, they are" -#~ " simple enough =)." +#~ "Now that we have all our dependencies installed, let's run a simple " +#~ "distributed training with two clients and one server. Our training " +#~ "procedure and network architecture are based on PyTorch's `Basic MNIST " +#~ "Example `_. This " +#~ "will allow you see how easy it is to wrap your code with Flower and begin " +#~ "training in a federated way. We provide you with two helper scripts, " +#~ "namely *run-server.sh*, and *run-clients.sh*. Don't be afraid to look " +#~ "inside, they are simple enough =)." #~ msgstr "" -#~ "现在我们已经安装了所有的依赖包,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练过程和网络架构基于 " -#~ "PyTorch 的 `Basic MNIST Example " -#~ "`_。您会发现用 " -#~ "Flower 来封装您的代码并进行联邦学习训练是多么容易。我们为您提供了两个辅助脚本,即 *run-" -#~ "server.sh* 和 *run-clients.sh*。别害怕,它们很简单 =)。" +#~ "现在我们已经安装了所有的依赖包,让我们用两个客户端和一个服务器来运行一个简" +#~ "单的分布式训练。我们的训练过程和网络架构基于 PyTorch 的 `Basic MNIST " +#~ "Example `_。您会发" +#~ "现用 Flower 来封装您的代码并进行联邦学习训练是多么容易。我们为您提供了两个" +#~ "辅助脚本,即 *run-server.sh* 和 *run-clients.sh*。别害怕,它们很简单 =)。" #~ msgid "" -#~ "Go ahead and launch on a terminal" -#~ " the *run-server.sh* script first as" -#~ " follows:" +#~ "Go ahead and launch on a terminal the *run-server.sh* script first as " +#~ "follows:" #~ msgstr "首先在终端上启动 *run-server.sh* 脚本,如下所示:" -#~ msgid "Now that the server is up and running, go ahead and launch the clients." +#~ msgid "" +#~ "Now that the server is up and running, go ahead and launch the clients." #~ msgstr "现在服务器已经启动并运行,请继续启动客户端。" #~ msgid "" -#~ "Et voilà! You should be seeing the" -#~ " training procedure and, after a few" -#~ " iterations, the test accuracy for " -#~ "each client." -#~ msgstr "然后就可以了!您应该能看到训练过程,以及经过几次反复后,每个客户端的测试准确率。" +#~ "Et voilà! You should be seeing the training procedure and, after a few " +#~ "iterations, the test accuracy for each client." +#~ msgstr "" +#~ "然后就可以了!您应该能看到训练过程,以及经过几次反复后,每个客户端的测试准" +#~ "确率。" #~ msgid "Now, let's see what is really happening inside." #~ msgstr "现在,让我们看看里面到底发生了什么。" #~ msgid "" -#~ "Inside the server helper script *run-" -#~ "server.sh* you will find the following" -#~ " code that basically runs the " -#~ ":code:`server.py`" -#~ msgstr "在服务器辅助脚本 *run-server.sh* 中,你可以找到以下代码,这些代码基本上都是运行 :code:`server.py` 的代码" +#~ "Inside the server helper script *run-server.sh* you will find the " +#~ "following code that basically runs the :code:`server.py`" +#~ msgstr "" +#~ "在服务器辅助脚本 *run-server.sh* 中,你可以找到以下代码,这些代码基本上都" +#~ "是运行 :code:`server.py` 的代码" #~ msgid "" -#~ "We can go a bit deeper and " -#~ "see that :code:`server.py` simply launches " -#~ "a server that will coordinate three " -#~ "rounds of training. Flower Servers are" -#~ " very customizable, but for simple " -#~ "workloads, we can start a server " -#~ "using the :ref:`start_server ` function and leave " -#~ "all the configuration possibilities at " -#~ "their default values, as seen below." +#~ "We can go a bit deeper and see that :code:`server.py` simply launches a " +#~ "server that will coordinate three rounds of training. Flower Servers are " +#~ "very customizable, but for simple workloads, we can start a server using " +#~ "the :ref:`start_server ` function and " +#~ "leave all the configuration possibilities at their default values, as " +#~ "seen below." #~ msgstr "" -#~ "我们可以再深入一点,:code:`server.py` 只是启动了一个服务器,该服务器将协调三轮训练。Flower " -#~ "服务器是非常容易修改的,但对于简单的工作,我们可以使用 :ref:`start_server `函数启动服务器,并将所有可能的配置保留为默认值,如下所示。" +#~ "我们可以再深入一点,:code:`server.py` 只是启动了一个服务器,该服务器将协调" +#~ "三轮训练。Flower 服务器是非常容易修改的,但对于简单的工作,我们可以使用 :" +#~ "ref:`start_server `函数启动服务器,并将所" +#~ "有可能的配置保留为默认值,如下所示。" #~ msgid "" -#~ "Next, let's take a look at the " -#~ "*run-clients.sh* file. You will see " -#~ "that it contains the main loop " -#~ "that starts a set of *clients*." -#~ msgstr "接下来,让我们看看 *run-clients.sh* 文件。您会看到它包含了用来启动多个 *客户端* 的代码。" +#~ "Next, let's take a look at the *run-clients.sh* file. You will see that " +#~ "it contains the main loop that starts a set of *clients*." +#~ msgstr "" +#~ "接下来,让我们看看 *run-clients.sh* 文件。您会看到它包含了用来启动多个 *客" +#~ "户端* 的代码。" #~ msgid "" -#~ "**cid**: is the client ID. It is" -#~ " an integer that uniquely identifies " +#~ "**cid**: is the client ID. It is an integer that uniquely identifies " #~ "client identifier." #~ msgstr "**cid**:是客户 ID。它是一个整数,可唯一标识客户标识符。" @@ -23902,169 +24259,140 @@ msgstr "" #~ msgstr "**sever_address**: 标识服务器 IP 和端口的字符串。" #~ msgid "" -#~ "**nb_clients**: This defines the number " -#~ "of clients being created. This piece " -#~ "of information is not required by " -#~ "the client, but it helps us " -#~ "partition the original MNIST dataset to" -#~ " make sure that every client is " -#~ "working on unique subsets of both " -#~ "*training* and *test* sets." +#~ "**nb_clients**: This defines the number of clients being created. This " +#~ "piece of information is not required by the client, but it helps us " +#~ "partition the original MNIST dataset to make sure that every client is " +#~ "working on unique subsets of both *training* and *test* sets." #~ msgstr "" -#~ "**nb_clients**: 这定义了正在创建的客户端数量。客户端并不需要这一信息,但它有助于我们对原始 " -#~ "MNIST 数据集进行划分,以确保每个客户端都在 *training* 和 *test*" -#~ " 数据集上有独立的数据。" +#~ "**nb_clients**: 这定义了正在创建的客户端数量。客户端并不需要这一信息,但" +#~ "它有助于我们对原始 MNIST 数据集进行划分,以确保每个客户端都在 *training* " +#~ "和 *test* 数据集上有独立的数据。" #~ msgid "" -#~ "Again, we can go deeper and look" -#~ " inside :code:`flwr_example/quickstart-" -#~ "pytorch/client.py`. After going through the" -#~ " argument parsing code at the " -#~ "beginning of our :code:`main` function, " -#~ "you will find a call to " -#~ ":code:`mnist.load_data`. This function is " -#~ "responsible for partitioning the original " -#~ "MNIST datasets (*training* and *test*) " -#~ "and returning a :code:`torch.utils.data.DataLoader`" -#~ " s for each of them. We then" -#~ " instantiate a :code:`PytorchMNISTClient` object" -#~ " with our client ID, our DataLoaders," -#~ " the number of epochs in each " -#~ "round, and which device we want to" -#~ " use for training (CPU or GPU)." +#~ "Again, we can go deeper and look inside :code:`flwr_example/quickstart-" +#~ "pytorch/client.py`. After going through the argument parsing code at the " +#~ "beginning of our :code:`main` function, you will find a call to :code:" +#~ "`mnist.load_data`. This function is responsible for partitioning the " +#~ "original MNIST datasets (*training* and *test*) and returning a :code:" +#~ "`torch.utils.data.DataLoader` s for each of them. We then instantiate a :" +#~ "code:`PytorchMNISTClient` object with our client ID, our DataLoaders, the " +#~ "number of epochs in each round, and which device we want to use for " +#~ "training (CPU or GPU)." #~ msgstr "" -#~ "我们可以深入看一下 :code:`flwr_example/quickstart-" -#~ "pytorch/client.py`。查看 :code:`main` 函数开头的参数解析代码后,你会发现一个对" -#~ " :code:`mnist.load_data` 的调用。该函数负责分割原始 MNIST " -#~ "数据集(*training* 和 *test*),并为每个数据集返回一个 " -#~ ":code:`torch.utils.data.DataLoader` 。然后,我们实例化一个 " -#~ ":code:`PytorchMNISTClient` 对象,其中包含我们的客户端 ID、 " -#~ "DataLoader、每一轮中的遍历数,以及我们希望用于训练的设备(CPU 或 GPU)。" +#~ "我们可以深入看一下 :code:`flwr_example/quickstart-pytorch/client.py`。查" +#~ "看 :code:`main` 函数开头的参数解析代码后,你会发现一个对 :code:`mnist." +#~ "load_data` 的调用。该函数负责分割原始 MNIST 数据集(*training* 和 " +#~ "*test*),并为每个数据集返回一个 :code:`torch.utils.data.DataLoader` 。然" +#~ "后,我们实例化一个 :code:`PytorchMNISTClient` 对象,其中包含我们的客户端 " +#~ "ID、 DataLoader、每一轮中的遍历数,以及我们希望用于训练的设备(CPU 或 " +#~ "GPU)。" #~ msgid "" -#~ "The :code:`PytorchMNISTClient` object when " -#~ "finally passed to :code:`fl.client.start_client` " -#~ "along with the server's address as " -#~ "the training process begins." +#~ "The :code:`PytorchMNISTClient` object when finally passed to :code:`fl." +#~ "client.start_client` along with the server's address as the training " +#~ "process begins." #~ msgstr "" -#~ "当训练过程开始时,:code:`PytorchMNISTClient` 对象会连同服务器地址一起传递给 " -#~ ":code:`fl.client.start_client`。" +#~ "当训练过程开始时,:code:`PytorchMNISTClient` 对象会连同服务器地址一起传递" +#~ "给 :code:`fl.client.start_client`。" #~ msgid "A Closer Look" #~ msgstr "仔细看一下" #~ msgid "" -#~ "Now, let's look closely into the " -#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" -#~ ".quickstart-pytorch.mnist` and see what it" -#~ " is doing:" +#~ "Now, let's look closely into the :code:`PytorchMNISTClient` inside :code:" +#~ "`flwr_example.quickstart-pytorch.mnist` and see what it is doing:" #~ msgstr "" -#~ "现在,让我们仔细研究一下 :code:`flwr_example.quickstart-pytorch.mnist`" -#~ " 中的 :code:`PytorchMNISTClient`,看看它在做什么:" +#~ "现在,让我们仔细研究一下 :code:`flwr_example.quickstart-pytorch.mnist` 中" +#~ "的 :code:`PytorchMNISTClient`,看看它在做什么:" #~ msgid "" -#~ "The first thing to notice is that" -#~ " :code:`PytorchMNISTClient` instantiates a CNN" -#~ " model inside its constructor" -#~ msgstr "首先要注意的是 :code:`PytorchMNISTClient` 在其构造函数中实例化了一个 CNN 模型" +#~ "The first thing to notice is that :code:`PytorchMNISTClient` instantiates " +#~ "a CNN model inside its constructor" +#~ msgstr "" +#~ "首先要注意的是 :code:`PytorchMNISTClient` 在其构造函数中实例化了一个 CNN " +#~ "模型" #~ msgid "" -#~ "The code for the CNN is available" -#~ " under :code:`quickstart-pytorch.mnist` and " -#~ "it is reproduced below. It is the" -#~ " same network found in `Basic MNIST" -#~ " Example " -#~ "`_." +#~ "The code for the CNN is available under :code:`quickstart-pytorch.mnist` " +#~ "and it is reproduced below. It is the same network found in `Basic MNIST " +#~ "Example `_." #~ msgstr "" -#~ "CNN 的代码可在 :code:`quickstart-pytorch.mnist` " -#~ "下找到,现复制如下。它与 `Basic MNIST Example " -#~ "`_中的网络相同。" +#~ "CNN 的代码可在 :code:`quickstart-pytorch.mnist` 下找到,现复制如下。它与 " +#~ "`Basic MNIST Example `_中的网络相同。" #~ msgid "" -#~ "The second thing to notice is that" -#~ " :code:`PytorchMNISTClient` class inherits from" -#~ " the :code:`fl.client.Client`, and hence it" -#~ " must implement the following methods:" +#~ "The second thing to notice is that :code:`PytorchMNISTClient` class " +#~ "inherits from the :code:`fl.client.Client`, and hence it must implement " +#~ "the following methods:" #~ msgstr "" -#~ "第二件要注意的事是 :code:`PytorchMNISTClient` 类继承自 " -#~ ":code:`fl.client.Client`,因此它必须实现以下方法:" +#~ "第二件要注意的事是 :code:`PytorchMNISTClient` 类继承自 :code:`fl.client." +#~ "Client`,因此它必须实现以下方法:" #~ msgid "" -#~ "When comparing the abstract class to " -#~ "its derived class :code:`PytorchMNISTClient` " -#~ "you will notice that :code:`fit` calls" -#~ " a :code:`train` function and that " -#~ ":code:`evaluate` calls a :code:`test`: " -#~ "function." +#~ "When comparing the abstract class to its derived class :code:" +#~ "`PytorchMNISTClient` you will notice that :code:`fit` calls a :code:" +#~ "`train` function and that :code:`evaluate` calls a :code:`test`: function." #~ msgstr "" -#~ "将抽象类与其派生类 :code:`PytorchMNISTClient` 进行比较时,您会发现 " -#~ ":code:`fit` 调用了一个 :code:`train` 函数,而 " -#~ ":code:`evaluate` 则调用了一个 :code:`test`: 函数。" +#~ "将抽象类与其派生类 :code:`PytorchMNISTClient` 进行比较时,您会发现 :code:" +#~ "`fit` 调用了一个 :code:`train` 函数,而 :code:`evaluate` 则调用了一个 :" +#~ "code:`test`: 函数。" #~ msgid "" -#~ "These functions can both be found " -#~ "inside the same :code:`quickstart-" +#~ "These functions can both be found inside the same :code:`quickstart-" #~ "pytorch.mnist` module:" -#~ msgstr "这些函数都可以在同一个 :code:`quickstart-pytorch.mnist` 模块中找到:" +#~ msgstr "" +#~ "这些函数都可以在同一个 :code:`quickstart-pytorch.mnist` 模块中找到:" #~ msgid "" -#~ "Observe that these functions encapsulate " -#~ "regular training and test loops and " -#~ "provide :code:`fit` and :code:`evaluate` with" -#~ " final statistics for each round. You" -#~ " could substitute them with your " -#~ "custom train and test loops and " -#~ "change the network architecture, and the" -#~ " entire example would still work " -#~ "flawlessly. As a matter of fact, " -#~ "why not try and modify the code" -#~ " to an example of your liking?" +#~ "Observe that these functions encapsulate regular training and test loops " +#~ "and provide :code:`fit` and :code:`evaluate` with final statistics for " +#~ "each round. You could substitute them with your custom train and test " +#~ "loops and change the network architecture, and the entire example would " +#~ "still work flawlessly. As a matter of fact, why not try and modify the " +#~ "code to an example of your liking?" #~ msgstr "" -#~ "请注意,这些函数封装了常规的训练和测试循环,并为 :code:`fit` 和 " -#~ ":code:`evaluate` " -#~ "提供了每轮的最终统计数据。您可以用自定义的训练和测试循环来替代它们,并改变网络结构,整个示例仍然可以完美运行。事实上,为什么不按照自己的喜好修改代码呢?" +#~ "请注意,这些函数封装了常规的训练和测试循环,并为 :code:`fit` 和 :code:" +#~ "`evaluate` 提供了每轮的最终统计数据。您可以用自定义的训练和测试循环来替代" +#~ "它们,并改变网络结构,整个示例仍然可以完美运行。事实上,为什么不按照自己的" +#~ "喜好修改代码呢?" #~ msgid "Give It a Try" #~ msgstr "试试看" #~ msgid "" -#~ "Looking through the quickstart code " -#~ "description above will have given a " -#~ "good understanding of how *clients* and" -#~ " *servers* work in Flower, how to " -#~ "run a simple experiment, and the " -#~ "internals of a client wrapper. Here " -#~ "are a few things you could try " -#~ "on your own and get more " -#~ "experience with Flower:" +#~ "Looking through the quickstart code description above will have given a " +#~ "good understanding of how *clients* and *servers* work in Flower, how to " +#~ "run a simple experiment, and the internals of a client wrapper. Here are " +#~ "a few things you could try on your own and get more experience with " +#~ "Flower:" #~ msgstr "" -#~ "通过上面的快速入门代码描述,你将对 Flower " -#~ "中*客户端*和*服务器*的工作方式、如何运行一个简单的实验以及客户端封装器的内部结构有一个很好的了解。您可以自己尝试以下内容,以获得更多使用" -#~ " Flower 的经验:" +#~ "通过上面的快速入门代码描述,你将对 Flower 中*客户端*和*服务器*的工作方式、" +#~ "如何运行一个简单的实验以及客户端封装器的内部结构有一个很好的了解。您可以自" +#~ "己尝试以下内容,以获得更多使用 Flower 的经验:" #~ msgid "" -#~ "Try and change :code:`PytorchMNISTClient` so" -#~ " it can accept different architectures." +#~ "Try and change :code:`PytorchMNISTClient` so it can accept different " +#~ "architectures." #~ msgstr "尝试修改 :code:`PytorchMNISTClient`,使其可以接受不同的架构。" #~ msgid "" -#~ "Modify the :code:`train` function so " -#~ "that it accepts different optimizers" +#~ "Modify the :code:`train` function so that it accepts different optimizers" #~ msgstr "修改 :code:`train` 函数,使其接受不同的优化器" #~ msgid "" -#~ "Modify the :code:`test` function so that" -#~ " it proves not only the top-1 " -#~ "(regular accuracy) but also the top-5" -#~ " accuracy?" -#~ msgstr "修改 :code:`test` 函数,使其不仅能输出前 1 名(常规精确度),还能证明前 5 名的精确度?" +#~ "Modify the :code:`test` function so that it proves not only the top-1 " +#~ "(regular accuracy) but also the top-5 accuracy?" +#~ msgstr "" +#~ "修改 :code:`test` 函数,使其不仅能输出前 1 名(常规精确度),还能证明前 5 " +#~ "名的精确度?" #~ msgid "" -#~ "Go larger! Try to adapt the code" -#~ " to larger images and datasets. Why" -#~ " not try training on ImageNet with" -#~ " a ResNet-50?" -#~ msgstr "让我们尝试让代码适应更大的图像和数据集。为什么不尝试使用 ResNet-50 在 ImageNet 上进行训练呢?" +#~ "Go larger! Try to adapt the code to larger images and datasets. Why not " +#~ "try training on ImageNet with a ResNet-50?" +#~ msgstr "" +#~ "让我们尝试让代码适应更大的图像和数据集。为什么不尝试使用 ResNet-50 在 " +#~ "ImageNet 上进行训练呢?" #~ msgid "You are ready now. Enjoy learning in a federated way!" #~ msgstr "您现在已经准备就绪。尽情享受联邦学习的乐趣吧!" @@ -24073,127 +24401,112 @@ msgstr "" #~ msgstr "差别隐私" #~ msgid "" -#~ "Flower provides differential privacy (DP) " -#~ "wrapper classes for the easy integration" -#~ " of the central DP guarantees " -#~ "provided by DP-FedAvg into training " -#~ "pipelines defined in any of the " -#~ "various ML frameworks that Flower is " -#~ "compatible with." +#~ "Flower provides differential privacy (DP) wrapper classes for the easy " +#~ "integration of the central DP guarantees provided by DP-FedAvg into " +#~ "training pipelines defined in any of the various ML frameworks that " +#~ "Flower is compatible with." #~ msgstr "" -#~ "Flower 提供了差分隐私 (DP) 封装类,可将 DP-FedAvg " -#~ "提供的核心 DP 轻松集成到 Flower 兼容的各种 ML " -#~ "框架中定义的训练模式中。" +#~ "Flower 提供了差分隐私 (DP) 封装类,可将 DP-FedAvg 提供的核心 DP 轻松集成" +#~ "到 Flower 兼容的各种 ML 框架中定义的训练模式中。" #~ msgid "" -#~ "Please note that these components are" -#~ " still experimental; the correct " -#~ "configuration of DP for a specific " -#~ "task is still an unsolved problem." -#~ msgstr "请注意,这些组件仍处于试验阶段,如何为特定任务正确配置 DP 仍是一个尚未解决的问题。" +#~ "Please note that these components are still experimental; the correct " +#~ "configuration of DP for a specific task is still an unsolved problem." +#~ msgstr "" +#~ "请注意,这些组件仍处于试验阶段,如何为特定任务正确配置 DP 仍是一个尚未解决" +#~ "的问题。" #~ msgid "" -#~ "The name DP-FedAvg is misleading " -#~ "since it can be applied on top " -#~ "of any FL algorithm that conforms " -#~ "to the general structure prescribed by" -#~ " the FedOpt family of algorithms." -#~ msgstr "DP-FedAvg 这个名称容易引起误解,因为它可以应用于任何符合 FedOpt 系列算法规定的一般结构的 FL 算法之上。" +#~ "The name DP-FedAvg is misleading since it can be applied on top of any FL " +#~ "algorithm that conforms to the general structure prescribed by the FedOpt " +#~ "family of algorithms." +#~ msgstr "" +#~ "DP-FedAvg 这个名称容易引起误解,因为它可以应用于任何符合 FedOpt 系列算法规" +#~ "定的一般结构的 FL 算法之上。" #~ msgid "DP-FedAvg" #~ msgstr "DP-FedAvg" #~ msgid "" -#~ "DP-FedAvg, originally proposed by " -#~ "McMahan et al. [mcmahan]_ and extended" -#~ " by Andrew et al. [andrew]_, is " -#~ "essentially FedAvg with the following " +#~ "DP-FedAvg, originally proposed by McMahan et al. [mcmahan]_ and extended " +#~ "by Andrew et al. [andrew]_, is essentially FedAvg with the following " #~ "modifications." #~ msgstr "DP-FedAvg 最初由McMahan等人提出,并由Andrew等人加以扩展。" #~ msgid "" -#~ "**Clipping** : The influence of each " -#~ "client's update is bounded by clipping" -#~ " it. This is achieved by enforcing" -#~ " a cap on the L2 norm of " -#~ "the update, scaling it down if " -#~ "needed." -#~ msgstr "**裁剪** : 裁剪会影响到每个客户端的模型参数。具体做法是对参数的 L2 准则设置上限,必要时将其缩减。" +#~ "**Clipping** : The influence of each client's update is bounded by " +#~ "clipping it. This is achieved by enforcing a cap on the L2 norm of the " +#~ "update, scaling it down if needed." +#~ msgstr "" +#~ "**裁剪** : 裁剪会影响到每个客户端的模型参数。具体做法是对参数的 L2 准则设" +#~ "置上限,必要时将其缩减。" #~ msgid "" -#~ "**Noising** : Gaussian noise, calibrated " -#~ "to the clipping threshold, is added " -#~ "to the average computed at the " -#~ "server." -#~ msgstr "**噪声** : 在服务器计算出的平均值中加入高斯噪声,该噪声根据剪切阈值进行校准。" +#~ "**Noising** : Gaussian noise, calibrated to the clipping threshold, is " +#~ "added to the average computed at the server." +#~ msgstr "" +#~ "**噪声** : 在服务器计算出的平均值中加入高斯噪声,该噪声根据剪切阈值进行校" +#~ "准。" #~ msgid "" -#~ "The distribution of the update norm " -#~ "has been shown to vary from " -#~ "task-to-task and to evolve as " -#~ "training progresses. This variability is " -#~ "crucial in understanding its impact on" -#~ " differential privacy guarantees, emphasizing " -#~ "the need for an adaptive approach " -#~ "[andrew]_ that continuously adjusts the " -#~ "clipping threshold to track a " -#~ "prespecified quantile of the update norm" -#~ " distribution." -#~ msgstr "事实证明,参数更新准则的分布会随着任务的不同而变化,并随着训练的进展而演变。因此,我们采用了一种自适应方法,该方法会不断调整剪切阈值,以跟踪参数更新准则分布的预设量化值。" +#~ "The distribution of the update norm has been shown to vary from task-to-" +#~ "task and to evolve as training progresses. This variability is crucial in " +#~ "understanding its impact on differential privacy guarantees, emphasizing " +#~ "the need for an adaptive approach [andrew]_ that continuously adjusts the " +#~ "clipping threshold to track a prespecified quantile of the update norm " +#~ "distribution." +#~ msgstr "" +#~ "事实证明,参数更新准则的分布会随着任务的不同而变化,并随着训练的进展而演" +#~ "变。因此,我们采用了一种自适应方法,该方法会不断调整剪切阈值,以跟踪参数更" +#~ "新准则分布的预设量化值。" #~ msgid "Simplifying Assumptions" #~ msgstr "简化假设" #~ msgid "" -#~ "We make (and attempt to enforce) a" -#~ " number of assumptions that must be" -#~ " satisfied to ensure that the " -#~ "training process actually realizes the " -#~ ":math:`(\\epsilon, \\delta)` guarantees the " -#~ "user has in mind when configuring " +#~ "We make (and attempt to enforce) a number of assumptions that must be " +#~ "satisfied to ensure that the training process actually realizes the :math:" +#~ "`(\\epsilon, \\delta)` guarantees the user has in mind when configuring " #~ "the setup." #~ msgstr "" -#~ "我们提出(并试图执行)了一系列必须满足的假设,以确保训练过程真正实现用户在配置设置时所定的 " -#~ ":math:`(\\epsilon,\\delta)` 。" +#~ "我们提出(并试图执行)了一系列必须满足的假设,以确保训练过程真正实现用户在" +#~ "配置设置时所定的 :math:`(\\epsilon,\\delta)` 。" #~ msgid "" -#~ "**Fixed-size subsampling** :Fixed-size " -#~ "subsamples of the clients must be " -#~ "taken at each round, as opposed to" -#~ " variable-sized Poisson subsamples." -#~ msgstr "** 固定大小的子样本** :与可变大小的泊松分布子样本相比,每轮必须抽取固定大小的客户端子样本。" +#~ "**Fixed-size subsampling** :Fixed-size subsamples of the clients must be " +#~ "taken at each round, as opposed to variable-sized Poisson subsamples." +#~ msgstr "" +#~ "** 固定大小的子样本** :与可变大小的泊松分布子样本相比,每轮必须抽取固定大" +#~ "小的客户端子样本。" #~ msgid "" -#~ "**Unweighted averaging** : The contributions" -#~ " from all the clients must weighted" -#~ " equally in the aggregate to " -#~ "eliminate the requirement for the server" -#~ " to know in advance the sum of" -#~ " the weights of all clients available" -#~ " for selection." -#~ msgstr "**非加权平均**: 所有客户端的贡献必须加权相等,这样服务器就不需要事先知道所有客户的权重总和。" +#~ "**Unweighted averaging** : The contributions from all the clients must " +#~ "weighted equally in the aggregate to eliminate the requirement for the " +#~ "server to know in advance the sum of the weights of all clients available " +#~ "for selection." +#~ msgstr "" +#~ "**非加权平均**: 所有客户端的贡献必须加权相等,这样服务器就不需要事先知道" +#~ "所有客户的权重总和。" #~ msgid "" -#~ "**No client failures** : The set " -#~ "of available clients must stay constant" -#~ " across all rounds of training. In" -#~ " other words, clients cannot drop out" -#~ " or fail." -#~ msgstr "**没有失败的客户端** : 在各轮训练中,可用客户端的数量必须保持不变。换句话说,客户端不能退出或失败。" +#~ "**No client failures** : The set of available clients must stay constant " +#~ "across all rounds of training. In other words, clients cannot drop out or " +#~ "fail." +#~ msgstr "" +#~ "**没有失败的客户端** : 在各轮训练中,可用客户端的数量必须保持不变。换句话" +#~ "说,客户端不能退出或失败。" #~ msgid "" -#~ "The first two are useful for " -#~ "eliminating a multitude of complications " -#~ "associated with calibrating the noise to" -#~ " the clipping threshold, while the " -#~ "third one is required to comply " -#~ "with the assumptions of the privacy " +#~ "The first two are useful for eliminating a multitude of complications " +#~ "associated with calibrating the noise to the clipping threshold, while " +#~ "the third one is required to comply with the assumptions of the privacy " #~ "analysis." -#~ msgstr "前两种方法有助于消除将噪声校准为削波阈值所带来的诸多复杂问题,而第三种方法则需要符合隐私分析的假设。" +#~ msgstr "" +#~ "前两种方法有助于消除将噪声校准为削波阈值所带来的诸多复杂问题,而第三种方法" +#~ "则需要符合隐私分析的假设。" #~ msgid "" -#~ "These restrictions are in line with " -#~ "constraints imposed by Andrew et al. " +#~ "These restrictions are in line with constraints imposed by Andrew et al. " #~ "[andrew]_." #~ msgstr "这些限制与 Andrew 等人所施加的限制一致。" @@ -24201,299 +24514,219 @@ msgstr "" #~ msgstr "可定制的噪声注入" #~ msgid "" -#~ "In contrast to other implementations " -#~ "where the addition of noise is " -#~ "performed at the server, you can " -#~ "configure the site of noise injection" -#~ " to better match your threat model." -#~ " We provide users with the " -#~ "flexibility to set up the training " -#~ "such that each client independently adds" -#~ " a small amount of noise to the" -#~ " clipped update, with the result that" -#~ " simply aggregating the noisy updates " -#~ "is equivalent to the explicit addition" -#~ " of noise to the non-noisy " -#~ "aggregate at the server." -#~ msgstr "与其他在服务器上添加噪声的实现方法不同,您可以配置噪声注入的位置,以便更好地匹配您的威胁模型。我们为用户提供了设置训练的灵活性,使每个客户端都能独立地为剪切参数更新添加少量噪声,这样,只需聚合噪声更新,就相当于在服务器上为非噪声聚合添加噪声了。" +#~ "In contrast to other implementations where the addition of noise is " +#~ "performed at the server, you can configure the site of noise injection to " +#~ "better match your threat model. We provide users with the flexibility to " +#~ "set up the training such that each client independently adds a small " +#~ "amount of noise to the clipped update, with the result that simply " +#~ "aggregating the noisy updates is equivalent to the explicit addition of " +#~ "noise to the non-noisy aggregate at the server." +#~ msgstr "" +#~ "与其他在服务器上添加噪声的实现方法不同,您可以配置噪声注入的位置,以便更好" +#~ "地匹配您的威胁模型。我们为用户提供了设置训练的灵活性,使每个客户端都能独立" +#~ "地为剪切参数更新添加少量噪声,这样,只需聚合噪声更新,就相当于在服务器上为" +#~ "非噪声聚合添加噪声了。" #~ msgid "" -#~ "To be precise, if we let :math:`m`" -#~ " be the number of clients sampled " -#~ "each round and :math:`\\sigma_\\Delta` be " -#~ "the scale of the total Gaussian " -#~ "noise that needs to be added to" -#~ " the sum of the model updates, " -#~ "we can use simple maths to show" -#~ " that this is equivalent to each " -#~ "client adding noise with scale " -#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ "To be precise, if we let :math:`m` be the number of clients sampled each " +#~ "round and :math:`\\sigma_\\Delta` be the scale of the total Gaussian " +#~ "noise that needs to be added to the sum of the model updates, we can use " +#~ "simple maths to show that this is equivalent to each client adding noise " +#~ "with scale :math:`\\sigma_\\Delta/\\sqrt{m}`." #~ msgstr "" -#~ "准确地说,我们假设每轮采样的客户端数量为:math:`m`,:math:`\\sigma_\\Delta` " -#~ "为需要添加到模型更新总和中的总高斯噪声的规模,我们就可以用简单的数学方法证明了,这相当于每个客户端都添加了规模为 " -#~ ":math:`\\sigma_\\Delta/\\sqrt{m}` 的噪声。" +#~ "准确地说,我们假设每轮采样的客户端数量为:math:`m`,:math:" +#~ "`\\sigma_\\Delta` 为需要添加到模型更新总和中的总高斯噪声的规模,我们就可以" +#~ "用简单的数学方法证明了,这相当于每个客户端都添加了规模为 :math:" +#~ "`\\sigma_\\Delta/\\sqrt{m}` 的噪声。" #~ msgid "Wrapper-based approach" #~ msgstr "基于封装的方法" #~ msgid "" -#~ "Introducing DP to an existing workload" -#~ " can be thought of as adding an" -#~ " extra layer of security around it." -#~ " This inspired us to provide the " -#~ "additional server and client-side logic" -#~ " needed to make the training process" -#~ " differentially private as wrappers for " -#~ "instances of the :code:`Strategy` and " -#~ ":code:`NumPyClient` abstract classes respectively." -#~ " This wrapper-based approach has the" -#~ " advantage of being easily composable " -#~ "with other wrappers that someone might" -#~ " contribute to the Flower library in" -#~ " the future, e.g., for secure " -#~ "aggregation. Using Inheritance instead can " -#~ "be tedious because that would require" -#~ " the creation of new sub- classes " -#~ "every time a new class implementing " -#~ ":code:`Strategy` or :code:`NumPyClient` is " +#~ "Introducing DP to an existing workload can be thought of as adding an " +#~ "extra layer of security around it. This inspired us to provide the " +#~ "additional server and client-side logic needed to make the training " +#~ "process differentially private as wrappers for instances of the :code:" +#~ "`Strategy` and :code:`NumPyClient` abstract classes respectively. This " +#~ "wrapper-based approach has the advantage of being easily composable with " +#~ "other wrappers that someone might contribute to the Flower library in the " +#~ "future, e.g., for secure aggregation. Using Inheritance instead can be " +#~ "tedious because that would require the creation of new sub- classes every " +#~ "time a new class implementing :code:`Strategy` or :code:`NumPyClient` is " #~ "defined." #~ msgstr "" -#~ "在现有工作负载中引入 DP " -#~ "可以被认为是在其周围增加了一层额外的安全性。受此启发,我们提供了额外的服务器端和客户端逻辑,分别作为 " -#~ ":code:`Strategy` 和 :code:`NumPyClient` " -#~ "抽象类实例的封装器,使训练过程具有不同的隐私性。这种基于封装器的方法的优点是可以很容易地与将来有人贡献给 Flower " -#~ "的其他封装器(例如用于安全聚合的封装器)进行组合。使用继承可能会比较繁琐,因为每次定义实现 :code:`Strategy`" -#~ " 或 :code:`NumPyClient` 的新类时,都需要创建新的子类。" +#~ "在现有工作负载中引入 DP 可以被认为是在其周围增加了一层额外的安全性。受此启" +#~ "发,我们提供了额外的服务器端和客户端逻辑,分别作为 :code:`Strategy` 和 :" +#~ "code:`NumPyClient` 抽象类实例的封装器,使训练过程具有不同的隐私性。这种基" +#~ "于封装器的方法的优点是可以很容易地与将来有人贡献给 Flower 的其他封装器(例" +#~ "如用于安全聚合的封装器)进行组合。使用继承可能会比较繁琐,因为每次定义实" +#~ "现 :code:`Strategy` 或 :code:`NumPyClient` 的新类时,都需要创建新的子类。" #~ msgid "" -#~ "The first version of our solution " -#~ "was to define a decorator whose " -#~ "constructor accepted, among other things, " -#~ "a boolean-valued variable indicating " -#~ "whether adaptive clipping was to be " -#~ "enabled or not. We quickly realized " -#~ "that this would clutter its " -#~ ":code:`__init__()` function with variables " -#~ "corresponding to hyperparameters of adaptive" -#~ " clipping that would remain unused " -#~ "when it was disabled. A cleaner " -#~ "implementation could be achieved by " -#~ "splitting the functionality into two " -#~ "decorators, :code:`DPFedAvgFixed` and " -#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" -#~ " classing the former. The constructors " -#~ "for both classes accept a boolean " -#~ "parameter :code:`server_side_noising`, which, as " -#~ "the name suggests, determines where " -#~ "noising is to be performed." +#~ "The first version of our solution was to define a decorator whose " +#~ "constructor accepted, among other things, a boolean-valued variable " +#~ "indicating whether adaptive clipping was to be enabled or not. We quickly " +#~ "realized that this would clutter its :code:`__init__()` function with " +#~ "variables corresponding to hyperparameters of adaptive clipping that " +#~ "would remain unused when it was disabled. A cleaner implementation could " +#~ "be achieved by splitting the functionality into two decorators, :code:" +#~ "`DPFedAvgFixed` and :code:`DPFedAvgAdaptive`, with the latter sub- " +#~ "classing the former. The constructors for both classes accept a boolean " +#~ "parameter :code:`server_side_noising`, which, as the name suggests, " +#~ "determines where noising is to be performed." #~ msgstr "" -#~ "我们的第一版解决方案是定义一个装饰器,其构造函数接受一个布尔值变量,表示是否启用自适应剪裁。我们很快意识到,这样会使其 " -#~ ":code:`__init__()` " -#~ "函数中与自适应裁剪超参数相对应的变量变得杂乱无章,而这些变量在自适应裁剪被禁用时将保持未使用状态。要实现更简洁的功能,可以将该功能拆分为两个装饰器,即" -#~ " :code:`DPFedAvgFixed` 和 " -#~ ":code:`DPFedAvgAdaptive`,后者是前者的子类。这两个类的构造函数都接受一个布尔参数 " -#~ ":code:`server_side_noising`,顾名思义,它决定了在哪里加噪声。" +#~ "我们的第一版解决方案是定义一个装饰器,其构造函数接受一个布尔值变量,表示是" +#~ "否启用自适应剪裁。我们很快意识到,这样会使其 :code:`__init__()` 函数中与自" +#~ "适应裁剪超参数相对应的变量变得杂乱无章,而这些变量在自适应裁剪被禁用时将保" +#~ "持未使用状态。要实现更简洁的功能,可以将该功能拆分为两个装饰器,即 :code:" +#~ "`DPFedAvgFixed` 和 :code:`DPFedAvgAdaptive`,后者是前者的子类。这两个类的" +#~ "构造函数都接受一个布尔参数 :code:`server_side_noising`,顾名思义,它决定了" +#~ "在哪里加噪声。" #~ msgid "" -#~ "The server-side capabilities required " -#~ "for the original version of DP-" -#~ "FedAvg, i.e., the one which performed" -#~ " fixed clipping, can be completely " -#~ "captured with the help of wrapper " -#~ "logic for just the following two " -#~ "methods of the :code:`Strategy` abstract " -#~ "class." +#~ "The server-side capabilities required for the original version of DP-" +#~ "FedAvg, i.e., the one which performed fixed clipping, can be completely " +#~ "captured with the help of wrapper logic for just the following two " +#~ "methods of the :code:`Strategy` abstract class." #~ msgstr "" #~ "只需对 :code:`Strategy` 抽象类的以下两个方法进行封装,就能完全捕获 DP-" #~ "FedAvg 原始版本(即执行固定剪裁的版本)所需的服务器端功能。" #~ msgid "" -#~ ":code:`configure_fit()` : The config " -#~ "dictionary being sent by the wrapped " -#~ ":code:`Strategy` to each client needs to" -#~ " be augmented with an additional " -#~ "value equal to the clipping threshold" -#~ " (keyed under :code:`dpfedavg_clip_norm`) and," -#~ " if :code:`server_side_noising=true`, another one" -#~ " equal to the scale of the " -#~ "Gaussian noise that needs to be " -#~ "added at the client (keyed under " -#~ ":code:`dpfedavg_noise_stddev`). This entails " -#~ "*post*-processing of the results returned " -#~ "by the wrappee's implementation of " -#~ ":code:`configure_fit()`." +#~ ":code:`configure_fit()` : The config dictionary being sent by the " +#~ "wrapped :code:`Strategy` to each client needs to be augmented with an " +#~ "additional value equal to the clipping threshold (keyed under :code:" +#~ "`dpfedavg_clip_norm`) and, if :code:`server_side_noising=true`, another " +#~ "one equal to the scale of the Gaussian noise that needs to be added at " +#~ "the client (keyed under :code:`dpfedavg_noise_stddev`). This entails " +#~ "*post*-processing of the results returned by the wrappee's implementation " +#~ "of :code:`configure_fit()`." #~ msgstr "" -#~ ":code:`configure_fit()` :由封装的 :code:`Strategy` " -#~ "发送到每个客户端的配置字典需要使用等于裁剪阈值的附加值(在 :code:`dpfedavg_clip_norm` " -#~ "下键入)进行扩充。并且,如果 " -#~ "server_side_noising=true,则另一个值等于需要在客户端添加的高斯噪声的大小(在 " -#~ "dpfedavg_noise_stddev 下键入)。这需要对封装后的configure_fit() " -#~ "所返回的结果进行后处理。" +#~ ":code:`configure_fit()` :由封装的 :code:`Strategy` 发送到每个客户端的配置" +#~ "字典需要使用等于裁剪阈值的附加值(在 :code:`dpfedavg_clip_norm` 下键入)进" +#~ "行扩充。并且,如果 server_side_noising=true,则另一个值等于需要在客户端添" +#~ "加的高斯噪声的大小(在 dpfedavg_noise_stddev 下键入)。这需要对封装后的" +#~ "configure_fit() 所返回的结果进行后处理。" #~ msgid "" -#~ ":code:`aggregate_fit()`: We check whether any" -#~ " of the sampled clients dropped out" -#~ " or failed to upload an update " -#~ "before the round timed out. In " -#~ "that case, we need to abort the" -#~ " current round, discarding any successful" -#~ " updates that were received, and move" -#~ " on to the next one. On the " -#~ "other hand, if all clients responded " -#~ "successfully, we must force the " -#~ "averaging of the updates to happen " -#~ "in an unweighted manner by intercepting" -#~ " the :code:`parameters` field of " -#~ ":code:`FitRes` for each received update " -#~ "and setting it to 1. Furthermore, " -#~ "if :code:`server_side_noising=true`, each update " -#~ "is perturbed with an amount of " -#~ "noise equal to what it would have" -#~ " been subjected to had client-side" -#~ " noising being enabled. This entails " -#~ "*pre*-processing of the arguments to " -#~ "this method before passing them on " -#~ "to the wrappee's implementation of " -#~ ":code:`aggregate_fit()`." +#~ ":code:`aggregate_fit()`: We check whether any of the sampled clients " +#~ "dropped out or failed to upload an update before the round timed out. In " +#~ "that case, we need to abort the current round, discarding any successful " +#~ "updates that were received, and move on to the next one. On the other " +#~ "hand, if all clients responded successfully, we must force the averaging " +#~ "of the updates to happen in an unweighted manner by intercepting the :" +#~ "code:`parameters` field of :code:`FitRes` for each received update and " +#~ "setting it to 1. Furthermore, if :code:`server_side_noising=true`, each " +#~ "update is perturbed with an amount of noise equal to what it would have " +#~ "been subjected to had client-side noising being enabled. This entails " +#~ "*pre*-processing of the arguments to this method before passing them on " +#~ "to the wrappee's implementation of :code:`aggregate_fit()`." #~ msgstr "" -#~ ":code:`aggregate_fit()`: " -#~ "我们会检查是否有任何客户端在本轮超时前退出或未能上传参数更新。在这种情况下,我们需要中止当前一轮,丢弃已收到的所有参数更新,然后继续下一轮。另一方面,如果所有客户端都成功响应,我们就必须通过拦截" -#~ " :code:`FitRes` 的 :code:`parameters` 字段并将其设置为 " -#~ "1,强制以不加权的方式平均更新。此外,如果 " -#~ ":code:`server_side_noising=true`,每次更新都会受到一定量的噪声扰动,其扰动量相当于启用客户端噪声时的扰动量。" -#~ " 这就需要在将本方法的参数传递给封装的 :code:`aggregate_fit()` " -#~ "之前,对参数进行*预*处理。" +#~ ":code:`aggregate_fit()`: 我们会检查是否有任何客户端在本轮超时前退出或未能" +#~ "上传参数更新。在这种情况下,我们需要中止当前一轮,丢弃已收到的所有参数更" +#~ "新,然后继续下一轮。另一方面,如果所有客户端都成功响应,我们就必须通过拦" +#~ "截 :code:`FitRes` 的 :code:`parameters` 字段并将其设置为 1,强制以不加权的" +#~ "方式平均更新。此外,如果 :code:`server_side_noising=true`,每次更新都会受" +#~ "到一定量的噪声扰动,其扰动量相当于启用客户端噪声时的扰动量。 这就需要在将" +#~ "本方法的参数传递给封装的 :code:`aggregate_fit()` 之前,对参数进行*预*处" +#~ "理。" #~ msgid "" -#~ "We can't directly change the aggregation" -#~ " function of the wrapped strategy to" -#~ " force it to add noise to the" -#~ " aggregate, hence we simulate client-" -#~ "side noising to implement server-side" -#~ " noising." -#~ msgstr "我们无法直接改变封装策略的聚合函数,迫使它在聚合中添加噪声,因此我们模拟客户端噪声来实现服务器端噪声。" +#~ "We can't directly change the aggregation function of the wrapped strategy " +#~ "to force it to add noise to the aggregate, hence we simulate client-side " +#~ "noising to implement server-side noising." +#~ msgstr "" +#~ "我们无法直接改变封装策略的聚合函数,迫使它在聚合中添加噪声,因此我们模拟客" +#~ "户端噪声来实现服务器端噪声。" #~ msgid "" -#~ "These changes have been put together " -#~ "into a class called :code:`DPFedAvgFixed`, " -#~ "whose constructor accepts the strategy " -#~ "being decorated, the clipping threshold " -#~ "and the number of clients sampled " -#~ "every round as compulsory arguments. The" -#~ " user is expected to specify the " -#~ "clipping threshold since the order of" -#~ " magnitude of the update norms is " -#~ "highly dependent on the model being " -#~ "trained and providing a default value" -#~ " would be misleading. The number of" -#~ " clients sampled at every round is" -#~ " required to calculate the amount of" -#~ " noise that must be added to " -#~ "each individual update, either by the" -#~ " server or the clients." +#~ "These changes have been put together into a class called :code:" +#~ "`DPFedAvgFixed`, whose constructor accepts the strategy being decorated, " +#~ "the clipping threshold and the number of clients sampled every round as " +#~ "compulsory arguments. The user is expected to specify the clipping " +#~ "threshold since the order of magnitude of the update norms is highly " +#~ "dependent on the model being trained and providing a default value would " +#~ "be misleading. The number of clients sampled at every round is required " +#~ "to calculate the amount of noise that must be added to each individual " +#~ "update, either by the server or the clients." #~ msgstr "" -#~ "这些变化被整合到一个名为 :code:`DPFedAvgFixed` " -#~ "的类中,其构造函数接受被装饰的策略、剪切阈值和每轮采样的客户数作为必选参数。用户需要指定剪切阈值,因为参数更新规范的数量级在很大程度上取决于正在训练的模型,提供默认值会产生误导。每轮采样的客户端数量是计算服务器或客户在每次参数更新时添加的噪音量所必需的。" +#~ "这些变化被整合到一个名为 :code:`DPFedAvgFixed` 的类中,其构造函数接受被装" +#~ "饰的策略、剪切阈值和每轮采样的客户数作为必选参数。用户需要指定剪切阈值,因" +#~ "为参数更新规范的数量级在很大程度上取决于正在训练的模型,提供默认值会产生误" +#~ "导。每轮采样的客户端数量是计算服务器或客户在每次参数更新时添加的噪音量所必" +#~ "需的。" #~ msgid "" -#~ "The additional functionality required to " -#~ "facilitate adaptive clipping has been " -#~ "provided in :code:`DPFedAvgAdaptive`, a " -#~ "subclass of :code:`DPFedAvgFixed`. It " -#~ "overrides the above-mentioned methods to" -#~ " do the following." +#~ "The additional functionality required to facilitate adaptive clipping has " +#~ "been provided in :code:`DPFedAvgAdaptive`, a subclass of :code:" +#~ "`DPFedAvgFixed`. It overrides the above-mentioned methods to do the " +#~ "following." #~ msgstr "" -#~ "自适应剪裁所需的附加功能在 :code:`DPFedAvgAdaptive` 中提供,其是 " -#~ ":code:`DPFedAvgFixed` 的子类。它重写了上述方法,以实现以下功能。" +#~ "自适应剪裁所需的附加功能在 :code:`DPFedAvgAdaptive` 中提供,其是 :code:" +#~ "`DPFedAvgFixed` 的子类。它重写了上述方法,以实现以下功能。" #~ msgid "" -#~ ":code:`configure_fit()` : It intercepts the" -#~ " config dict returned by " -#~ ":code:`super.configure_fit()` to add the " -#~ "key-value pair " -#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " -#~ "which the client interprets as an " -#~ "instruction to include an indicator bit" -#~ " (1 if update norm <= clipping " -#~ "threshold, 0 otherwise) in the results" -#~ " returned by it." +#~ ":code:`configure_fit()` : It intercepts the config dict returned by :code:" +#~ "`super.configure_fit()` to add the key-value pair :code:" +#~ "`dpfedavg_adaptive_clip_enabled:True` to it, which the client interprets " +#~ "as an instruction to include an indicator bit (1 if update norm <= " +#~ "clipping threshold, 0 otherwise) in the results returned by it." #~ msgstr "" -#~ ":code:`configure_fit()`:它截取由 :code:`super.configure_fit()` " -#~ "返回的 config 字典,并在其中添加键-值对 " -#~ ":code:`dpfedavg_adaptive_clip_enabled:True\",客户端将其解释为在返回结果中包含一个指示位(如果参数更新范式" -#~ " <= 剪裁阈值,则为 1,否则为 0)的指令。" +#~ ":code:`configure_fit()`:它截取由 :code:`super.configure_fit()` 返回的 " +#~ "config 字典,并在其中添加键-值对 :code:`dpfedavg_adaptive_clip_enabled:" +#~ "True\",客户端将其解释为在返回结果中包含一个指示位(如果参数更新范式 <= 剪" +#~ "裁阈值,则为 1,否则为 0)的指令。" #~ msgid "" -#~ ":code:`aggregate_fit()` : It follows a " -#~ "call to :code:`super.aggregate_fit()` with one" -#~ " to :code:`__update_clip_norm__()`, a procedure" -#~ " which adjusts the clipping threshold " -#~ "on the basis of the indicator bits" -#~ " received from the sampled clients." -#~ msgstr ":code:`aggregate_fit()`:在调用:code:`super.aggregate_fit()`后,再调用:code:`__update_clip_norm__()`,该过程根据从采样客户端接收到的指示位调整裁剪阈值。" +#~ ":code:`aggregate_fit()` : It follows a call to :code:`super." +#~ "aggregate_fit()` with one to :code:`__update_clip_norm__()`, a procedure " +#~ "which adjusts the clipping threshold on the basis of the indicator bits " +#~ "received from the sampled clients." +#~ msgstr "" +#~ ":code:`aggregate_fit()`:在调用:code:`super.aggregate_fit()`后,再调用:" +#~ "code:`__update_clip_norm__()`,该过程根据从采样客户端接收到的指示位调整裁" +#~ "剪阈值。" #~ msgid "" -#~ "The client-side capabilities required " -#~ "can be completely captured through " -#~ "wrapper logic for just the :code:`fit()`" -#~ " method of the :code:`NumPyClient` abstract" -#~ " class. To be precise, we need " -#~ "to *post-process* the update computed" -#~ " by the wrapped client to clip " -#~ "it, if necessary, to the threshold " -#~ "value supplied by the server as " -#~ "part of the config dictionary. In " -#~ "addition to this, it may need to" -#~ " perform some extra work if either" -#~ " (or both) of the following keys " -#~ "are also present in the dict." +#~ "The client-side capabilities required can be completely captured through " +#~ "wrapper logic for just the :code:`fit()` method of the :code:" +#~ "`NumPyClient` abstract class. To be precise, we need to *post-process* " +#~ "the update computed by the wrapped client to clip it, if necessary, to " +#~ "the threshold value supplied by the server as part of the config " +#~ "dictionary. In addition to this, it may need to perform some extra work " +#~ "if either (or both) of the following keys are also present in the dict." #~ msgstr "" -#~ "客户端所需的功能完全可以通过 :code:`NumPyClient` 抽象类的 " -#~ ":code:`fit()` " -#~ "方法的封装逻辑来实现。准确地说,我们需要对封装客户端计算的参数更新进行处理,以便在必要时将其剪切到服务器作为配置字典的一部分提供的阈值。除此之外,如果配置字典中还存在以下任一(或两个)键,客户端可能还需要执行一些额外的工作。" +#~ "客户端所需的功能完全可以通过 :code:`NumPyClient` 抽象类的 :code:`fit()` 方" +#~ "法的封装逻辑来实现。准确地说,我们需要对封装客户端计算的参数更新进行处理," +#~ "以便在必要时将其剪切到服务器作为配置字典的一部分提供的阈值。除此之外,如果" +#~ "配置字典中还存在以下任一(或两个)键,客户端可能还需要执行一些额外的工作。" #~ msgid "" -#~ ":code:`dpfedavg_noise_stddev` : Generate and " -#~ "add the specified amount of noise " -#~ "to the clipped update." -#~ msgstr "code:`dpfedavg_noise_stddev`:生成并在剪切参数更新中添加指定数量的噪声。" +#~ ":code:`dpfedavg_noise_stddev` : Generate and add the specified amount of " +#~ "noise to the clipped update." +#~ msgstr "" +#~ "code:`dpfedavg_noise_stddev`:生成并在剪切参数更新中添加指定数量的噪声。" #~ msgid "" -#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" -#~ " metrics dict in the :code:`FitRes` " -#~ "object being returned to the server " -#~ "with an indicator bit, calculated as " -#~ "described earlier." +#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the metrics dict in the :" +#~ "code:`FitRes` object being returned to the server with an indicator bit, " +#~ "calculated as described earlier." #~ msgstr "" -#~ ":code:`dpfedavg_adaptive_clip_enabled`:在返回给服务器的 :code:`FitRes`" -#~ " 对象中的度量值字典中增加一个指标位,计算方法如前所述。" +#~ ":code:`dpfedavg_adaptive_clip_enabled`:在返回给服务器的 :code:`FitRes` 对" +#~ "象中的度量值字典中增加一个指标位,计算方法如前所述。" #~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" #~ msgstr "进行 :math:`(epsilon, \\delta)` 分析" #~ msgid "" -#~ "Assume you have trained for :math:`n`" -#~ " rounds with sampling fraction :math:`q`" -#~ " and noise multiplier :math:`z`. In " -#~ "order to calculate the :math:`\\epsilon` " -#~ "value this would result in for a" -#~ " particular :math:`\\delta`, the following " -#~ "script may be used." -#~ msgstr "" -#~ "假设您已经训练了 :math:`n` 轮,采样比例为 :math:`q`,噪声乘数为 " -#~ ":math:`z`。为了计算特定 :math:`\\delta` 的 :math:`epsilon`" -#~ " 值,可以使用下面的脚本。" - -#~ msgid "Enjoy building more robust and flexible ``ClientApp``s with mods!" -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`ClientApp `\\ " -#~ "\\(client\\_fn\\[\\, mods\\]\\)" -#~ msgstr "" - -#~ msgid ":py:obj:`flwr.server.driver `\\" +#~ "Assume you have trained for :math:`n` rounds with sampling fraction :math:" +#~ "`q` and noise multiplier :math:`z`. In order to calculate the :math:" +#~ "`\\epsilon` value this would result in for a particular :math:`\\delta`, " +#~ "the following script may be used." #~ msgstr "" +#~ "假设您已经训练了 :math:`n` 轮,采样比例为 :math:`q`,噪声乘数为 :math:" +#~ "`z`。为了计算特定 :math:`\\delta` 的 :math:`epsilon` 值,可以使用下面的脚" +#~ "本。" #~ msgid "Flower driver SDK." #~ msgstr "Flower 服务器。" @@ -24501,100 +24734,24 @@ msgstr "" #~ msgid "driver" #~ msgstr "服务器" -#~ msgid "" -#~ ":py:obj:`start_driver `\\ " -#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`Driver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`GrpcDriver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" -#~ msgstr "" - -#~ msgid "`GrpcDriver` provides access to the gRPC Driver API/service." -#~ msgstr "" - -#~ msgid ":py:obj:`get_nodes `\\ \\(\\)" -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(task\\_ids\\)" -#~ msgstr "" - #~ msgid "Get task results." #~ msgstr "汇总训练结果。" -#~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ " -#~ "\\(task\\_ins\\_list\\)" -#~ msgstr "" - -#~ msgid "Schedule tasks." -#~ msgstr "" - -#~ msgid "GrpcDriver" -#~ msgstr "" - -#~ msgid ":py:obj:`connect `\\ \\(\\)" -#~ msgstr "" - -#~ msgid "Connect to the Driver API." -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`create_run " -#~ "`\\ \\(req\\)" -#~ msgstr "" - #~ msgid "Request for run ID." #~ msgstr "Flower 基线申请" -#~ msgid "" -#~ ":py:obj:`disconnect " -#~ "`\\ \\(\\)" -#~ msgstr "" - -#~ msgid "Disconnect from the Driver API." -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`get_nodes `\\" -#~ " \\(req\\)" -#~ msgstr "" - #~ msgid "Get client IDs." #~ msgstr "返回客户端(本身)。" #~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(req\\)" -#~ msgstr "" - -#~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ \\(req\\)" -#~ msgstr "" - -#~ msgid "" -#~ "Flower usage examples used to be " -#~ "bundled with Flower in a package " -#~ "called ``flwr_example``. We are migrating " -#~ "those examples to standalone projects to" -#~ " make them easier to use. All " -#~ "new examples are based in the " -#~ "directory `examples " -#~ "`_." +#~ "Flower usage examples used to be bundled with Flower in a package called " +#~ "``flwr_example``. We are migrating those examples to standalone projects " +#~ "to make them easier to use. All new examples are based in the directory " +#~ "`examples `_." #~ msgstr "" -#~ "Flower 的使用示例曾与 Flower 捆绑在一个名为 ``flwr_example``" -#~ " 的软件包中。我们正在将这些示例迁移到独立项目中,以使它们更易于使用。所有新示例都位于目录 `examples " -#~ "`_。" +#~ "Flower 的使用示例曾与 Flower 捆绑在一个名为 ``flwr_example`` 的软件包中。" +#~ "我们正在将这些示例迁移到独立项目中,以使它们更易于使用。所有新示例都位于目" +#~ "录 `examples `_。" #~ msgid "Quickstart TensorFlow/Keras" #~ msgstr "快速入门 TensorFlow/Keras" @@ -24603,30 +24760,25 @@ msgstr "" #~ msgstr "传统示例 (`flwr_example`)" #~ msgid "" -#~ "The useage examples in `flwr_example` " -#~ "are deprecated and will be removed " -#~ "in the future. New examples are " -#~ "provided as standalone projects in " +#~ "The useage examples in `flwr_example` are deprecated and will be removed " +#~ "in the future. New examples are provided as standalone projects in " #~ "`examples `_." #~ msgstr "" -#~ "在 `flwr_example` 中的使用示例已被弃用,今后将被移除。新示例将作为独立项目在 " -#~ "`examples `_" -#~ " 中提供。" +#~ "在 `flwr_example` 中的使用示例已被弃用,今后将被移除。新示例将作为独立项目" +#~ "在 `examples `_ 中提" +#~ "供。" #~ msgid "Extra Dependencies" #~ msgstr "额外依赖" #~ msgid "" -#~ "The core Flower framework keeps a " -#~ "minimal set of dependencies. The " -#~ "examples demonstrate Flower in the " -#~ "context of different machine learning " -#~ "frameworks, so additional dependencies need" -#~ " to be installed before an example" -#~ " can be run." +#~ "The core Flower framework keeps a minimal set of dependencies. The " +#~ "examples demonstrate Flower in the context of different machine learning " +#~ "frameworks, so additional dependencies need to be installed before an " +#~ "example can be run." #~ msgstr "" -#~ "Flower 核心框架只保留了最低限度的依赖项。这些示例在不同机器学习框架的背景下演示了 " -#~ "Flower,因此在运行示例之前需要安装额外的依赖项。" +#~ "Flower 核心框架只保留了最低限度的依赖项。这些示例在不同机器学习框架的背景" +#~ "下演示了 Flower,因此在运行示例之前需要安装额外的依赖项。" #~ msgid "For PyTorch examples::" #~ msgstr "PyTorch 示例::" @@ -24638,39 +24790,34 @@ msgstr "" #~ msgstr "PyTorch 和 TensorFlow 示例::" #~ msgid "" -#~ "Please consult :code:`pyproject.toml` for a" -#~ " full list of possible extras " +#~ "Please consult :code:`pyproject.toml` for a full list of possible extras " #~ "(section :code:`[tool.poetry.extras]`)." #~ msgstr "" -#~ "请参阅 :code:`pyproject.toml`,了解可能的 extras 的完整列表(章节 " -#~ ":code:`[tool.poems.extras]`)。" +#~ "请参阅 :code:`pyproject.toml`,了解可能的 extras 的完整列表(章节 :code:" +#~ "`[tool.poems.extras]`)。" #~ msgid "PyTorch Examples" #~ msgstr "PyTorch 示例" #~ msgid "" -#~ "Our PyTorch examples are based on " -#~ "PyTorch 1.7. They should work with " -#~ "other releases as well. So far, we" -#~ " provide the following examples." -#~ msgstr "我们的 PyTorch 示例基于 PyTorch 1.7。它们应该也能在其他版本中使用。到目前为止,我们提供了以下示例。" +#~ "Our PyTorch examples are based on PyTorch 1.7. They should work with " +#~ "other releases as well. So far, we provide the following examples." +#~ msgstr "" +#~ "我们的 PyTorch 示例基于 PyTorch 1.7。它们应该也能在其他版本中使用。到目前" +#~ "为止,我们提供了以下示例。" #~ msgid "CIFAR-10 Image Classification" #~ msgstr "CIFAR-10 图像分类" #~ msgid "" -#~ "`CIFAR-10 and CIFAR-100 " -#~ "`_ are " -#~ "popular RGB image datasets. The Flower" -#~ " CIFAR-10 example uses PyTorch to " -#~ "train a simple CNN classifier in a" -#~ " federated learning setup with two " +#~ "`CIFAR-10 and CIFAR-100 `_ " +#~ "are popular RGB image datasets. The Flower CIFAR-10 example uses PyTorch " +#~ "to train a simple CNN classifier in a federated learning setup with two " #~ "clients." #~ msgstr "" -#~ "CIFAR-10 和 CIFAR-100 " -#~ "``_ 是流行的 RGB" -#~ " 图像数据集。Flower CIFAR-10 示例使用 PyTorch " -#~ "在有两个客户端的联邦学习设置中训练一个简单的 CNN 分类器。" +#~ "CIFAR-10 和 CIFAR-100 ``_ 是" +#~ "流行的 RGB 图像数据集。Flower CIFAR-10 示例使用 PyTorch 在有两个客户端的联" +#~ "邦学习设置中训练一个简单的 CNN 分类器。" #~ msgid "First, start a Flower server:" #~ msgstr "首先,启动 Flower 服务器:" @@ -24691,16 +24838,13 @@ msgstr "" #~ msgstr "ImageNet-2012 图像分类" #~ msgid "" -#~ "`ImageNet-2012 `_ is " -#~ "one of the major computer vision " -#~ "datasets. The Flower ImageNet example " -#~ "uses PyTorch to train a ResNet-18 " -#~ "classifier in a federated learning setup" -#~ " with ten clients." +#~ "`ImageNet-2012 `_ is one of the major computer " +#~ "vision datasets. The Flower ImageNet example uses PyTorch to train a " +#~ "ResNet-18 classifier in a federated learning setup with ten clients." #~ msgstr "" -#~ "ImageNet-2012 `_ " -#~ "是主要的计算机视觉数据集之一。Flower ImageNet 示例使用 PyTorch " -#~ "在有十个客户端的联邦学习设置中训练 ResNet-18 分类器。" +#~ "ImageNet-2012 `_ 是主要的计算机视觉数据集之一。" +#~ "Flower ImageNet 示例使用 PyTorch 在有十个客户端的联邦学习设置中训练 " +#~ "ResNet-18 分类器。" #~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" #~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" @@ -24715,27 +24859,26 @@ msgstr "" #~ msgstr "TensorFlow 示例" #~ msgid "" -#~ "Our TensorFlow examples are based on " -#~ "TensorFlow 2.0 or newer. So far, " -#~ "we provide the following examples." -#~ msgstr "我们的 TensorFlow 示例基于 TensorFlow 2.0 或更新版本。到目前为止,我们提供了以下示例。" +#~ "Our TensorFlow examples are based on TensorFlow 2.0 or newer. So far, we " +#~ "provide the following examples." +#~ msgstr "" +#~ "我们的 TensorFlow 示例基于 TensorFlow 2.0 或更新版本。到目前为止,我们提供" +#~ "了以下示例。" #~ msgid "Fashion-MNIST Image Classification" #~ msgstr "Fashion-MNIST 图像分类" #~ msgid "" -#~ "`Fashion-MNIST `_ is often used as " -#~ "the \"Hello, world!\" of machine " -#~ "learning. We follow this tradition and" -#~ " provide an example which samples " -#~ "random local datasets from Fashion-MNIST" -#~ " and trains a simple image " -#~ "classification model over those partitions." +#~ "`Fashion-MNIST `_ is " +#~ "often used as the \"Hello, world!\" of machine learning. We follow this " +#~ "tradition and provide an example which samples random local datasets from " +#~ "Fashion-MNIST and trains a simple image classification model over those " +#~ "partitions." #~ msgstr "" -#~ "`Fashion-MNIST `_ 经常被用作机器学习的 \"你好,世界!\"。我们遵循这一传统" -#~ ",提供了一个从Fashion-MNIST 中随机抽样本地数据集的示例,并在这些分区上训练一个简单的图像分类模型。" +#~ "`Fashion-MNIST `_ 经常被" +#~ "用作机器学习的 \"你好,世界!\"。我们遵循这一传统,提供了一个从Fashion-" +#~ "MNIST 中随机抽样本地数据集的示例,并在这些分区上训练一个简单的图像分类模" +#~ "型。" #~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" #~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" @@ -24744,59 +24887,7 @@ msgstr "" #~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" #~ msgid "" -#~ "For more details, see " -#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." -#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/tensorflow_fashion_mnist`。" - -#~ msgid "" -#~ "MXNet is no longer maintained and " -#~ "has been moved into `Attic " -#~ "`_. As a " -#~ "result, we would encourage you to " -#~ "use other ML frameworks alongise Flower," -#~ " for example, PyTorch. This tutorial " -#~ "might be removed in future versions " -#~ "of Flower." -#~ msgstr "" - -#~ msgid "|31e4b1afa87c4b968327bbeafbf184d4|" -#~ msgstr "" - -#~ msgid "|c9d935b4284e4c389a33d86b33e07c0a|" -#~ msgstr "" - -#~ msgid "|00727b5faffb468f84dd1b03ded88638|" -#~ msgstr "" - -#~ msgid "|daf0cf0ff4c24fd29439af78416cf47b|" -#~ msgstr "" - -#~ msgid "|9f093007080d471d94ca90d3e9fde9b6|" -#~ msgstr "" - -#~ msgid "|46a26e6150e0479fbd3dfd655f36eb13|" -#~ msgstr "" - -#~ msgid "|3daba297595c4c7fb845d90404a6179a|" -#~ msgstr "" - -#~ msgid "|5769874fa9c4455b80b2efda850d39d7|" -#~ msgstr "" - -#~ msgid "|ba47ffb421814b0f8f9fa5719093d839|" -#~ msgstr "" - -#~ msgid "|aeac5bf79cbf497082e979834717e01b|" -#~ msgstr "" - -#~ msgid "|ce27ed4bbe95459dba016afc42486ba2|" -#~ msgstr "" - -#~ msgid "|ae94a7f71dda443cbec2385751427d41|" -#~ msgstr "" - -#~ msgid "|e61fce4d43d243e7bb08bdde97d81ce6|" -#~ msgstr "" - -#~ msgid "|08cb60859b07461588fe44e55810b050|" +#~ "For more details, see :code:`src/py/flwr_example/" +#~ "tensorflow_fashion_mnist`." #~ msgstr "" +#~ "更多详情,请参阅 :code:`src/py/flwr_example/tensorflow_fashion_mnist`。" From 3e62d167a4c556b40f34decbcbb5553e20f8615f Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Tue, 28 May 2024 14:55:16 +0200 Subject: [PATCH 024/124] docs(framework) Add section about root user in Docker (#3520) Signed-off-by: Robert Steiner --- doc/source/how-to-run-flower-using-docker.rst | 57 ++++++++++++++++--- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index 9b1f16bba610..5812066f59de 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -2,7 +2,8 @@ Run Flower using Docker ======================= The simplest way to get started with Flower is by using the pre-made Docker images, which you can -find on `Docker Hub `__. +find on `Docker Hub `__. Supported architectures include ``amd64`` +and ``arm64v8``. Before you start, make sure that the Docker daemon is running: @@ -165,9 +166,9 @@ is located. In the file, we list all the dependencies that the ClientApp require .. code-block:: - flwr-datasets[vision]>=0.0.2,<1.0.0 - torch==2.1.1 - torchvision==0.16.1 + flwr-datasets[vision]>=0.1.0,<1.0.0 + torch==2.2.1 + torchvision==0.17.1 tqdm==4.66.3 .. important:: @@ -188,7 +189,7 @@ The ``Dockerfile.supernode`` contains the instructions that assemble the SuperNo WORKDIR /app COPY requirements.txt . - RUN python -m pip install -U --no-cache-dir -r requirements.txt && pyenv rehash + RUN python -m pip install -U --no-cache-dir -r requirements.txt COPY client.py ./ ENTRYPOINT ["flower-client-app", "client:app"] @@ -267,7 +268,7 @@ certificate within the container. Use the ``--certificates`` flag when starting .. code-block:: bash - $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 client:app \ + $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 \ --server 192.168.1.100:9092 \ --certificates ca.crt @@ -382,19 +383,57 @@ certificate within the container. Use the ``--certificates`` flag when starting .. code-block:: bash - $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 client:app \ + $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 \ --server 192.168.1.100:9091 \ --certificates ca.crt Advanced Docker options ----------------------- +Run with root user privileges +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Flower Docker images, by default, run with a non-root user (username/groupname: ``app``, +UID/GID: ``49999``). Using root user is not recommended unless it is necessary for specific +tasks during the build process. Always make sure to run the container as a non-root user in +production to maintain security best practices. + +**Run a container with root user privileges** + +Run the Docker image with the ``-u`` flag and specify ``root`` as the username: + +.. code-block:: bash + + $ docker run --rm -u root flwr/superlink:1.8.0 + +This command will run the Docker container with root user privileges. + +**Run the build process with root user privileges** + +If you want to switch to the root user during the build process of the Docker image to install +missing system dependencies, you can use the ``USER root`` directive within your Dockerfile. + +.. code-block:: dockerfile + + FROM flwr/supernode:1.8.0 + + # Switch to root user + USER root + + # Install missing dependencies (requires root access) + RUN apt-get update && apt-get install -y + + # Switch back to non-root user app + USER app + + # Continue with your Docker image build process + ... + Using a different Flower version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you want to use a different version of Flower, for example Flower nightly, you can do so by -changing the tag. All available versions are on -`Docker Hub `__. +changing the tag. All available versions are on `Docker Hub `__. Pinning a Docker image to a specific version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 380435cd621297dc13bc7488820ae509cc3b8f55 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Tue, 28 May 2024 15:02:48 +0200 Subject: [PATCH 025/124] docs(framework:skip) Update translation source strings (#3519) --- doc/locales/fr/LC_MESSAGES/framework-docs.po | 29097 +++++++++------- doc/locales/fr/LC_MESSAGES/sphinx.po | 17 +- doc/locales/ko/LC_MESSAGES/framework-docs.po | 1372 +- doc/locales/ko/LC_MESSAGES/sphinx.po | 9 +- .../pt_BR/LC_MESSAGES/framework-docs.po | 21145 ++++++----- doc/locales/pt_BR/LC_MESSAGES/sphinx.po | 9 +- .../zh_Hans/LC_MESSAGES/framework-docs.po | 27763 ++++++++------- doc/locales/zh_Hans/LC_MESSAGES/sphinx.po | 9 +- 8 files changed, 43505 insertions(+), 35916 deletions(-) diff --git a/doc/locales/fr/LC_MESSAGES/framework-docs.po b/doc/locales/fr/LC_MESSAGES/framework-docs.po index 80222e5409d2..67edf687bbbe 100644 --- a/doc/locales/fr/LC_MESSAGES/framework-docs.po +++ b/doc/locales/fr/LC_MESSAGES/framework-docs.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower Docs\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-03-15 14:23+0000\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: 2023-09-05 17:54+0000\n" "Last-Translator: Charles Beauville \n" "Language: fr\n" @@ -13,7 +13,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.14.0\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" @@ -60,11 +60,11 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:4 msgid "" "Flower provides pre-made docker images on `Docker Hub " -"`_ that include all necessary " -"dependencies for running the server. You can also build your own custom " -"docker images from scratch with a different version of Python or Ubuntu " -"if that is what you need. In this guide, we will explain what images " -"exist and how to build them locally." +"`_ that include all necessary dependencies" +" for running the SuperLink. You can also build your own custom docker " +"images from scratch with a different version of Python or Ubuntu if that " +"is what you need. In this guide, we will explain what images exist and " +"how to build them locally." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:9 @@ -79,10 +79,12 @@ msgid "Clone the flower repository." msgstr "**Fourche le dépôt de Flower**" #: ../../source/contributor-how-to-build-docker-images.rst:17 +#: ../../source/how-to-run-flower-using-docker.rst:144 msgid "Verify the Docker daemon is running." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:19 +#: ../../source/how-to-run-flower-using-docker.rst:146 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." @@ -90,12 +92,11 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:23 msgid "" -"Currently, Flower provides two images, a base image and a server image. " -"There will also be a client image soon. The base image, as the name " -"suggests, contains basic dependencies that both the server and the client" -" need. This includes system dependencies, Python and Python tools. The " -"server image is based on the base image, but it additionally installs the" -" Flower server using ``pip``." +"Currently, Flower provides two images, a ``base`` image and a " +"``superlink`` image. The base image, as the name suggests, contains basic" +" dependencies that the SuperLink needs. This includes system " +"dependencies, Python and Python tools. The SuperLink image is based on " +"the base image, but it additionally installs the SuperLink using ``pip``." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:28 @@ -107,13 +108,13 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:31 msgid "" -"Both, base and server image are configured via build arguments. Through " -"build arguments, we can make our build more flexible. For example, in the" -" base image, we can specify the version of Python to install using the " -"``PYTHON_VERSION`` build argument. Some of the build arguments have " -"default values, others must be specified when building the image. All " -"available build arguments for each image are listed in one of the tables " -"below." +"Both, base and SuperLink image are configured via build arguments. " +"Through build arguments, we can make our build more flexible. For " +"example, in the base image, we can specify the version of Python to " +"install using the ``PYTHON_VERSION`` build argument. Some of the build " +"arguments have default values, others must be specified when building the" +" image. All available build arguments for each image are listed in one of" +" the tables below." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:38 @@ -146,6 +147,7 @@ msgid "Example" msgstr "Exemples de PyTorch" #: ../../source/contributor-how-to-build-docker-images.rst:48 +#: ../../source/contributor-how-to-build-docker-images.rst:94 #, fuzzy msgid "``PYTHON_VERSION``" msgstr "Version Python" @@ -157,7 +159,7 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 #: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:100 +#: ../../source/contributor-how-to-build-docker-images.rst:108 #, fuzzy msgid "Yes" msgstr "Types" @@ -194,6 +196,7 @@ msgid "``69.0.2``" msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-build-docker-images.rst:60 +#: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "``UBUNTU_VERSION``" msgstr "" @@ -220,7 +223,7 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:80 #, fuzzy -msgid "Building the server image" +msgid "Building the SuperLink image" msgstr "Démarrer le serveur" #: ../../source/contributor-how-to-build-docker-images.rst:90 @@ -232,57 +235,74 @@ msgid "The repository name of the base image." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:92 -msgid "Defaults to ``flwr/server``." +msgid "Defaults to ``flwr/base``." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:94 -msgid "``BASE_IMAGE_TAG``" +#: ../../source/contributor-how-to-build-docker-images.rst:95 +#, fuzzy +msgid "The Python version of the base image." +msgstr "Évaluer la réponse d'un client." + +#: ../../source/contributor-how-to-build-docker-images.rst:96 +msgid "Defaults to ``py3.11``." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:95 -msgid "The image tag of the base image." +#: ../../source/contributor-how-to-build-docker-images.rst:99 +#, fuzzy +msgid "The Ubuntu version of the base image." +msgstr "Chargement des données" + +#: ../../source/contributor-how-to-build-docker-images.rst:100 +msgid "Defaults to ``ubuntu22.04``." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:96 -msgid "Defaults to ``py3.11-ubuntu22.04``." +#: ../../source/contributor-how-to-build-docker-images.rst:102 +msgid "``FLWR_PACKAGE``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:98 +#: ../../source/contributor-how-to-build-docker-images.rst:103 +msgid "The PyPI package to install." +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:104 +#, fuzzy +msgid "Defaults to ``flwr``." +msgstr "Flux de travail" + +#: ../../source/contributor-how-to-build-docker-images.rst:106 msgid "``FLWR_VERSION``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:99 +#: ../../source/contributor-how-to-build-docker-images.rst:107 msgid "Version of Flower to be installed." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:101 +#: ../../source/contributor-how-to-build-docker-images.rst:109 #, fuzzy -msgid "``1.7.0``" +msgid "``1.8.0``" msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 +#: ../../source/contributor-how-to-build-docker-images.rst:112 msgid "" -"The following example creates a server image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.7.0:" +"The following example creates a SuperLink image with the official Flower " +"base image py3.11-ubuntu22.04 and Flower 1.8.0:" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:114 +#: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" -"The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that" -" the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " +"that the build arguments as well as the name and tag can be adapted to " +"your needs. These values serve as examples only." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:117 +#: ../../source/contributor-how-to-build-docker-images.rst:125 msgid "" "If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY`` and " -"``BASE_IMAGE_TAG`` build arguments. The value of ``BASE_REPOSITORY`` must" -" match the name of your image and the value of ``BASE_IMAGE_TAG`` must " -"match the tag of your image." +"base image, all you need to do is set the ``BASE_REPOSITORY``, " +"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:131 +#: ../../source/contributor-how-to-build-docker-images.rst:138 msgid "After creating the image, we can test whether the image is working:" msgstr "" @@ -829,17 +849,19 @@ msgid "Open Jupyter Notebooks on Google Colab" msgstr "Ouvre les carnets Jupyter sur Google Colab" #: ../../source/contributor-how-to-install-development-versions.rst:51 +#, fuzzy msgid "" -"Open the notebook ``doc/source/tutorial-get-started-with-flower-" +"Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" "pytorch.ipynb``:" msgstr "" "Ouvrir le notebook ``doc/source/tutorial/Flower-1-Intro-to-FL-" "PyTorch.ipynb`` :" #: ../../source/contributor-how-to-install-development-versions.rst:53 +#, fuzzy msgid "" "https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-get-started-with-flower-pytorch.ipynb" +"/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" "https://colab.research.google.com/github/adap/flower/blob/main/doc/source" "/tutorial-get-started-with-flower-pytorch.ipynb" @@ -854,9 +876,10 @@ msgstr "" " :" #: ../../source/contributor-how-to-install-development-versions.rst:57 +#, fuzzy msgid "" "https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" +"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" "https://colab.research.google.com/github/adap/flower/blob/branch-" "name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" @@ -1115,10 +1138,19 @@ msgstr "" "nous recommandons `Python 3.8 `_." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 -msgid "Virutualenv with Pyenv/Virtualenv" +msgid "" +"Due to a known incompatibility with `ray " +"`_, we currently recommend utilizing at " +"most `Python 3.11 `_ for running Flower " +"simulations." +msgstr "" + +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 +#, fuzzy +msgid "Virtualenv with Pyenv/Virtualenv" msgstr "Virutualenv avec Pyenv/Virtualenv" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:16 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" "One of the recommended virtual environment is `pyenv " "`_/`virtualenv `_ pour plus de " "détails." -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:18 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 #, fuzzy msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " @@ -1140,19 +1172,19 @@ msgstr "" "Une fois Pyenv mis en place, tu peux l'utiliser pour installer `Python " "Version 3.7 `_ ou supérieure :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:24 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:29 msgid "Create the virtualenv with:" msgstr "Crée le virtualenv avec :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:31 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:36 msgid "Activate the virtualenv by running the following command:" msgstr "Active la virtualenv en exécutant la commande suivante :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:39 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:44 msgid "Virtualenv with Poetry" msgstr "Virtualenv et la poésie" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:41 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" "The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " @@ -1162,7 +1194,7 @@ msgstr "" "poetry.org/docs/>`_ pour gérer les dépendances. Après l'installation de " "Poetry, il te suffit de créer un environnement virtuel avec :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:47 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" "If you open a new terminal you can activate the previously created " "virtual environment with the following command:" @@ -1170,11 +1202,11 @@ msgstr "" "Si tu ouvres un nouveau terminal, tu peux activer l'environnement virtuel" " précédemment créé avec la commande suivante :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:55 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 msgid "Virtualenv with Anaconda" msgstr "Virtualenv avec Anaconda" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:57 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" "If you prefer to use Anaconda for your virtual environment then install " "and setup the `conda `_. Après l'avoir configuré, tu peux créer un " "environnement virtuel avec :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:63 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:68 msgid "and activate the virtual environment with:" msgstr "et active l'environnement virtuel avec :" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:71 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:76 msgid "And then?" msgstr "Et ensuite ?" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:73 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" "As soon as you created your virtual environment you clone one of the " "`Flower examples `_." @@ -1222,7 +1254,7 @@ msgstr "" "reStructuredText (fichiers `.rst`) et Markdown (fichiers `.md`)." #: ../../source/contributor-how-to-write-documentation.rst:10 -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 #, fuzzy msgid "" "Note that, in order to build the documentation locally (with ``poetry run" @@ -1804,7 +1836,7 @@ msgstr "" msgid "Creating and merging a pull request (PR)" msgstr "Créer et fusionner une pull request (PR)" -#: ../../source/contributor-tutorial-contribute-on-github.rst:205 +#: ../../source/contributor-tutorial-contribute-on-github.rst:206 msgid "**Create the PR**" msgstr "**Créer le PR**" @@ -1848,6 +1880,13 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" +"The title should be changed to adhere to the :ref:`pr_title_format` " +"guidelines, otherwise it won't be possible to merge the PR. So in this " +"case, a correct title might be ``docs(framework:skip) Fix typos``." +msgstr "" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:196 +msgid "" "The input box in the middle is there for you to describe what your PR " "does and to link it to existing issues. We have placed comments (that " "won't be rendered once the PR is opened) to guide you through the " @@ -1858,16 +1897,11 @@ msgstr "" "commentaires (qui ne seront pas rendus une fois le PR ouvert) pour te " "guider tout au long du processus." -#: ../../source/contributor-tutorial-contribute-on-github.rst:196 -msgid "" -"It is important to follow the instructions described in comments. For " -"instance, in order to not break how our changelog system works, you " -"should read the information above the ``Changelog entry`` section " -"carefully. You can also checkout some examples and details in the " -":ref:`changelogentry` appendix." +#: ../../source/contributor-tutorial-contribute-on-github.rst:199 +msgid "It is important to follow the instructions described in comments." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:200 +#: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " "reviewers that a new PR has been opened and that they should look over it" @@ -1877,7 +1911,7 @@ msgstr "" "qui informera les réviseurs qu'un nouveau PR a été ouvert et qu'ils " "doivent le consulter pour le fusionner ou demander des modifications." -#: ../../source/contributor-tutorial-contribute-on-github.rst:203 +#: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" "If your PR is not yet ready for review, and you don't want to notify " "anyone, you have the option to create a draft pull request:" @@ -1886,11 +1920,11 @@ msgstr "" " personne, tu as la possibilité de créer un brouillon de demande de " "traction :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "**Making new changes**" msgstr "**Faire de nouveaux changements**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " "commits to it the same way we did before, by making changes to the branch" @@ -1900,11 +1934,11 @@ msgstr "" "toujours y pousser de nouveaux commits de la même manière qu'auparavant, " "en apportant des modifications à la branche associée au PR." -#: ../../source/contributor-tutorial-contribute-on-github.rst:230 +#: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" msgstr "**Review the PR**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:211 +#: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" "Once the PR has been opened or once the draft PR has been marked as " "ready, a review from code owners will be automatically requested:" @@ -1913,7 +1947,7 @@ msgstr "" " étant prêt, une révision des propriétaires de code sera automatiquement " "demandée :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:215 +#: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" "Code owners will then look into the code, ask questions, request changes " "or validate the PR." @@ -1921,11 +1955,11 @@ msgstr "" "Les propriétaires du code vont alors se pencher sur le code, poser des " "questions, demander des modifications ou valider le RP." -#: ../../source/contributor-tutorial-contribute-on-github.rst:217 +#: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." msgstr "La fusion sera bloquée s'il y a des changements demandés en cours." -#: ../../source/contributor-tutorial-contribute-on-github.rst:221 +#: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" "To resolve them, just push the necessary changes to the branch associated" " with the PR:" @@ -1933,11 +1967,11 @@ msgstr "" "Pour les résoudre, il suffit de pousser les changements nécessaires vers " "la branche associée au PR :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:225 +#: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" msgstr "Et résous la conversation :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:229 +#: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" "Once all the conversations have been resolved, you can re-request a " "review." @@ -1945,11 +1979,11 @@ msgstr "" "Une fois que toutes les conversations ont été résolues, tu peux " "redemander un examen." -#: ../../source/contributor-tutorial-contribute-on-github.rst:250 +#: ../../source/contributor-tutorial-contribute-on-github.rst:251 msgid "**Once the PR is merged**" msgstr "**Une fois que le PR est fusionné**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:233 +#: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" "If all the automatic tests have passed and reviewers have no more changes" " to request, they can approve the PR and merge it." @@ -1958,7 +1992,7 @@ msgstr "" " de modifications à demander, ils peuvent approuver le PR et le " "fusionner." -#: ../../source/contributor-tutorial-contribute-on-github.rst:237 +#: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" @@ -1967,19 +2001,19 @@ msgstr "" "(un bouton devrait apparaître pour le faire) et aussi la supprimer " "localement en faisant :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:244 +#: ../../source/contributor-tutorial-contribute-on-github.rst:245 msgid "Then you should update your forked repository by doing:" msgstr "Ensuite, tu dois mettre à jour ton dépôt forké en faisant :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:253 +#: ../../source/contributor-tutorial-contribute-on-github.rst:254 msgid "Example of first contribution" msgstr "Exemple de première contribution" -#: ../../source/contributor-tutorial-contribute-on-github.rst:256 +#: ../../source/contributor-tutorial-contribute-on-github.rst:257 msgid "Problem" msgstr "Problème" -#: ../../source/contributor-tutorial-contribute-on-github.rst:258 +#: ../../source/contributor-tutorial-contribute-on-github.rst:259 #, fuzzy msgid "" "For our documentation, we've started to use the `Diàtaxis framework " @@ -1988,7 +2022,7 @@ msgstr "" "Pour notre documentation, nous avons commencé à utiliser le cadre " "`Diàtaxis `_." -#: ../../source/contributor-tutorial-contribute-on-github.rst:260 +#: ../../source/contributor-tutorial-contribute-on-github.rst:261 #, fuzzy msgid "" "Our \"How to\" guides should have titles that continue the sentence \"How" @@ -1998,7 +2032,7 @@ msgstr "" "la phrase \"Comment faire pour...\", par exemple, \"Comment passer à " "Flower 1.0\"." -#: ../../source/contributor-tutorial-contribute-on-github.rst:262 +#: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." @@ -2007,7 +2041,7 @@ msgstr "" "changer leur titre est (malheureusement) plus compliqué qu'on ne le " "pense." -#: ../../source/contributor-tutorial-contribute-on-github.rst:264 +#: ../../source/contributor-tutorial-contribute-on-github.rst:265 #, fuzzy msgid "" "This issue is about changing the title of a doc from present continuous " @@ -2016,7 +2050,7 @@ msgstr "" "Cette question porte sur le changement du titre d'un document du présent " "continu au présent simple." -#: ../../source/contributor-tutorial-contribute-on-github.rst:266 +#: ../../source/contributor-tutorial-contribute-on-github.rst:267 #, fuzzy msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " @@ -2026,21 +2060,21 @@ msgstr "" "remplacé par \"Sauvegarder la progression\". Est-ce que cela passe notre " "contrôle ?" -#: ../../source/contributor-tutorial-contribute-on-github.rst:268 +#: ../../source/contributor-tutorial-contribute-on-github.rst:269 #, fuzzy msgid "Before: \"How to saving progress\" ❌" msgstr "Avant : \"Comment sauvegarder les progrès\" ❌" -#: ../../source/contributor-tutorial-contribute-on-github.rst:270 +#: ../../source/contributor-tutorial-contribute-on-github.rst:271 #, fuzzy msgid "After: \"How to save progress\" ✅" msgstr "Après : \"Comment sauvegarder la progression\" ✅" -#: ../../source/contributor-tutorial-contribute-on-github.rst:273 +#: ../../source/contributor-tutorial-contribute-on-github.rst:274 msgid "Solution" msgstr "Solution" -#: ../../source/contributor-tutorial-contribute-on-github.rst:275 +#: ../../source/contributor-tutorial-contribute-on-github.rst:276 #, fuzzy msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " @@ -2050,12 +2084,12 @@ msgstr "" "configuration de bout en bout. Après avoir cloné et configuré le repo " "Flower, voici ce que tu dois faire :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:277 +#: ../../source/contributor-tutorial-contribute-on-github.rst:278 #, fuzzy msgid "Find the source file in ``doc/source``" msgstr "Trouve le fichier source dans `doc/source`" -#: ../../source/contributor-tutorial-contribute-on-github.rst:278 +#: ../../source/contributor-tutorial-contribute-on-github.rst:279 #, fuzzy msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " @@ -2064,7 +2098,7 @@ msgstr "" "Effectue la modification dans le fichier `.rst` (attention, les tirets " "sous le titre doivent être de la même longueur que le titre lui-même)" -#: ../../source/contributor-tutorial-contribute-on-github.rst:279 +#: ../../source/contributor-tutorial-contribute-on-github.rst:280 #, fuzzy msgid "" "Build the docs and `check the result `_" -#: ../../source/contributor-tutorial-contribute-on-github.rst:282 +#: ../../source/contributor-tutorial-contribute-on-github.rst:283 msgid "Rename file" msgstr "Renommer le fichier" -#: ../../source/contributor-tutorial-contribute-on-github.rst:284 +#: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" "You might have noticed that the file name still reflects the old wording." " If we just change the file, then we break all existing links to it - it " @@ -2090,22 +2124,22 @@ msgstr "" "important** d'éviter cela, car briser des liens peut nuire à notre " "classement dans les moteurs de recherche." -#: ../../source/contributor-tutorial-contribute-on-github.rst:287 +#: ../../source/contributor-tutorial-contribute-on-github.rst:288 #, fuzzy msgid "Here's how to change the file name:" msgstr "Voici comment changer le nom du fichier :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:289 +#: ../../source/contributor-tutorial-contribute-on-github.rst:290 #, fuzzy msgid "Change the file name to ``save-progress.rst``" msgstr "Change le nom du fichier en `save-progress.rst`" -#: ../../source/contributor-tutorial-contribute-on-github.rst:290 +#: ../../source/contributor-tutorial-contribute-on-github.rst:291 #, fuzzy msgid "Add a redirect rule to ``doc/source/conf.py``" msgstr "Ajouter une règle de redirection à `doc/source/conf.py`" -#: ../../source/contributor-tutorial-contribute-on-github.rst:292 +#: ../../source/contributor-tutorial-contribute-on-github.rst:293 #, fuzzy msgid "" "This will cause a redirect from ``saving-progress.html`` to ``save-" @@ -2114,11 +2148,11 @@ msgstr "" "Cela entraînera une redirection de `saving-progress.html` vers `save-" "progress.html`, les anciens liens continueront à fonctionner." -#: ../../source/contributor-tutorial-contribute-on-github.rst:295 +#: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" msgstr "Applique les changements dans le fichier d'index" -#: ../../source/contributor-tutorial-contribute-on-github.rst:297 +#: ../../source/contributor-tutorial-contribute-on-github.rst:298 #, fuzzy msgid "" "For the lateral navigation bar to work properly, it is very important to " @@ -2129,16 +2163,16 @@ msgstr "" "très important de mettre également à jour le fichier `index.rst`. C'est " "là que nous définissons toute l'arborescence de la barre de navigation." -#: ../../source/contributor-tutorial-contribute-on-github.rst:300 +#: ../../source/contributor-tutorial-contribute-on-github.rst:301 #, fuzzy msgid "Find and modify the file name in ``index.rst``" msgstr "Trouve et modifie le nom du fichier dans `index.rst`" -#: ../../source/contributor-tutorial-contribute-on-github.rst:303 +#: ../../source/contributor-tutorial-contribute-on-github.rst:304 msgid "Open PR" msgstr "Open PR" -#: ../../source/contributor-tutorial-contribute-on-github.rst:305 +#: ../../source/contributor-tutorial-contribute-on-github.rst:306 #, fuzzy msgid "" "Commit the changes (commit messages are always imperative: \"Do " @@ -2147,120 +2181,27 @@ msgstr "" "Valide les modifications (les messages de validation sont toujours " "impératifs : \"Fais quelque chose\", dans ce cas \"Modifie...\")" -#: ../../source/contributor-tutorial-contribute-on-github.rst:306 +#: ../../source/contributor-tutorial-contribute-on-github.rst:307 msgid "Push the changes to your fork" msgstr "Transmets les changements à ta fourchette" -#: ../../source/contributor-tutorial-contribute-on-github.rst:307 -msgid "Open a PR (as shown above)" -msgstr "Ouvre un RP (comme indiqué ci-dessus)" - #: ../../source/contributor-tutorial-contribute-on-github.rst:308 +msgid "" +"Open a PR (as shown above) with title ``docs(framework) Update how-to " +"guide title``" +msgstr "" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" msgstr "Attends qu'elle soit approuvée !" -#: ../../source/contributor-tutorial-contribute-on-github.rst:309 +#: ../../source/contributor-tutorial-contribute-on-github.rst:310 msgid "Congrats! 🥳 You're now officially a Flower contributor!" msgstr "" "Félicitations 🥳 Tu es désormais officiellement une contributrice de " "Flower !" -#: ../../source/contributor-tutorial-contribute-on-github.rst:313 -msgid "How to write a good PR title" -msgstr "Comment écrire un bon titre de PR" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:315 -msgid "" -"A well-crafted PR title helps team members quickly understand the purpose" -" and scope of the changes being proposed. Here's a guide to help you " -"write a good GitHub PR title:" -msgstr "" -"Un titre de PR bien choisi permet aux autres développeurs de rapidement " -"comprendre l'intérêt et le scope des changements proposés. Voici un guide" -" pour vous aider à écrire des bons titres de PR :" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:317 -msgid "" -"1. Be Clear and Concise: Provide a clear summary of the changes in a " -"concise manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" " -"\"Update,\" or \"Fix\" to indicate the purpose. 1. Include Relevant " -"Information: Mention the affected feature or module for context. 1. Keep " -"it Short: Avoid lengthy titles for easy readability. 1. Use Proper " -"Capitalization and Punctuation: Follow grammar rules for clarity." -msgstr "" -"1. Soyez clair et concis : Donnez un résumé clair des changements de " -"manière concise. 1. Utilisez des verbes actionnables : Commencez par des " -"verbes comme \"Add\", \"Update\", ou \"Fix\" pour indiquer le but. 1. " -"Inclure des renseignements pertinents : Mentionner la caractéristique ou " -"le module concerné pour le contexte. 1. Gardez le court : Évitez les " -"longs titres pour une lisibilité facile. 1. Utiliser une bonne " -"capitalisation et une ponctuation : Suivre les règles de grammaire pour " -"la clarté." - -#: ../../source/contributor-tutorial-contribute-on-github.rst:323 -msgid "" -"Let's start with a few examples for titles that should be avoided because" -" they do not provide meaningful information:" -msgstr "" -"Commençons par quelques exemples de titres qui devraient être évités " -"parce qu'ils ne fournissent pas d'information significative :" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:325 -msgid "Implement Algorithm" -msgstr "Implement Algorithm" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:326 -msgid "Database" -msgstr "Database" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:327 -msgid "Add my_new_file.py to codebase" -msgstr "Add my_new_file.py to codebase" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:328 -msgid "Improve code in module" -msgstr "Improve code in module" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:329 -msgid "Change SomeModule" -msgstr "Change SomeModule" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:331 -msgid "" -"Here are a few positive examples which provide helpful information " -"without repeating how they do it, as that is already visible in the " -"\"Files changed\" section of the PR:" -msgstr "" -"Voici quelques bons exemples qui fournissent de l'information utile sans " -"répéter comment ils le font, comme cela est déjà visible dans la section " -"\"Files changed\" de la PR :" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:333 -msgid "Update docs banner to mention Flower Summit 2023" -msgstr "Update docs banner to mention Flower Summit 2023" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:334 -msgid "Remove unnecessary XGBoost dependency" -msgstr "Remove unnecessary XGBoost dependency" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:335 -msgid "Remove redundant attributes in strategies subclassing FedAvg" -msgstr "Remove redundant attributes in strategies subclassing FedAvg" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:336 -#, fuzzy -msgid "Add CI job to deploy the staging system when the ``main`` branch changes" -msgstr "Add CI job to deploy the staging system when the `main` branch changes" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:337 -msgid "" -"Add new amazing library which will be used to improve the simulation " -"engine" -msgstr "" -"Add new amazing library which will be used to improve the simulation " -"engine" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#: ../../source/contributor-tutorial-contribute-on-github.rst:314 #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:548 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:946 #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:727 @@ -2269,7 +2210,7 @@ msgstr "" msgid "Next steps" msgstr "Prochaines étapes" -#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +#: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" "Once you have made your first PR, and want to contribute more, be sure to" " check out the following :" @@ -2277,7 +2218,7 @@ msgstr "" "Une fois que tu auras fait ton premier RP, et que tu voudras contribuer " "davantage, ne manque pas de consulter les sites suivants :" -#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +#: ../../source/contributor-tutorial-contribute-on-github.rst:318 #, fuzzy msgid "" ":doc:`Good first contributions `_, où vous devriez " "particulièrement regarder les contributions :code:`baselines`." -#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +#: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 msgid "Appendix" msgstr "Annexe" -#: ../../source/contributor-tutorial-contribute-on-github.rst:354 -#, fuzzy -msgid "Changelog entry" -msgstr "Changelog" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:356 -msgid "" -"When opening a new PR, inside its description, there should be a " -"``Changelog entry`` header." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:358 -msgid "" -"Above this header you should see the following comment that explains how " -"to write your changelog entry:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:360 -msgid "" -"Inside the following 'Changelog entry' section, you should put the " -"description of your changes that will be added to the changelog alongside" -" your PR title." +#: ../../source/contributor-tutorial-contribute-on-github.rst:327 +msgid "PR title format" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:363 -msgid "" -"If the section is completely empty (without any token) or non-existent, " -"the changelog will just contain the title of the PR for the changelog " -"entry, without any description." +#: ../../source/contributor-tutorial-contribute-on-github.rst:329 +msgid "We enforce the following PR title format:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:366 +#: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"If the section contains some text other than tokens, it will use it to " -"add a description to the change." +"(or ``(:skip) `` to ignore the PR in the " +"changelog)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:368 +#: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"If the section contains one of the following tokens it will ignore any " -"other text and put the PR under the corresponding section of the " -"changelog:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:370 -msgid " is for classifying a PR as a general improvement." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:372 -msgid " is to not add the PR to the changelog" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:374 -msgid " is to add a general baselines change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:376 -msgid " is to add a general examples change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:378 -msgid " is to add a general sdk change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:380 -msgid " is to add a general simulations change to the PR" +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " +"break}``, ```` should be in ``{framework, baselines, datasets, " +"examples, or '*' when modifying multiple projects which requires the " +"':skip' flag to be used}``, and ```` starts with a capitalised " +"verb in the imperative mood." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:382 -msgid "Note that only one token should be used." -msgstr "" +#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#, fuzzy +msgid "Valid examples:" +msgstr "Exemples de PyTorch" -#: ../../source/contributor-tutorial-contribute-on-github.rst:384 -msgid "" -"Its content must have a specific format. We will break down what each " -"possibility does:" +#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +msgid "``feat(framework) Add flwr build CLI command``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:386 -msgid "" -"If the ``### Changelog entry`` section contains nothing or doesn't exist," -" the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:344 +msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:390 -msgid "" -"If the ``### Changelog entry`` section contains a description (and no " -"token), the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +msgid "``ci(*:skip) Enforce PR title format``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:396 -msgid "" -"If the ``### Changelog entry`` section contains ````, nothing will " -"change in the changelog." -msgstr "" +#: ../../source/contributor-tutorial-contribute-on-github.rst:347 +#, fuzzy +msgid "Invalid examples:" +msgstr "Exemples de PyTorch" -#: ../../source/contributor-tutorial-contribute-on-github.rst:398 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:402 +#: ../../source/contributor-tutorial-contribute-on-github.rst:350 msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +"``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " +"``*``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:406 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:351 +msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:410 -msgid "" -"If the ``### Changelog entry`` section contains ````, the following " -"text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:352 +msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:414 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:353 +msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:418 -msgid "" -"Note that only one token must be provided, otherwise, only the first " -"action (in the order listed above), will be performed." +#: ../../source/contributor-tutorial-contribute-on-github.rst:354 +msgid "``Add flwr build CLI command.`` (missing ``()``)" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 @@ -2430,6 +2310,7 @@ msgid "Get started as a contributor" msgstr "Devenez un·e contributeur·ice" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 +#: ../../source/how-to-run-flower-using-docker.rst:132 msgid "Prerequisites" msgstr "Prérequis" @@ -2589,10 +2470,55 @@ msgid "Run Linters and Tests" msgstr "Vérifier le format et tester le code" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:106 +msgid "Add a pre-commit hook" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 +msgid "" +"Developers may integrate a pre-commit hook into their workflow utilizing " +"the `pre-commit `_ library. The pre-" +"commit hook is configured to execute two primary operations: " +"``./dev/format.sh`` and ``./dev/test.sh`` scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 +msgid "There are multiple ways developers can use this:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 +msgid "Install the pre-commit hook to your local git directory by simply running:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 +msgid "" +"Each ``git commit`` will trigger the execution of formatting and " +"linting/test scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 +msgid "" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " +"commit`` command. ::" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 +msgid "" +"For developers who prefer not to install the hook permanently, it is " +"possible to execute a one-time check prior to committing changes by using" +" the following command:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 +msgid "" +"This executes the formatting and linting checks/tests on all the files " +"without modifying the default behavior of ``git commit``." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 msgid "Run Github Actions (CI) locally" msgstr "Exécuter les GitHub Actions (CI) localement" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 #, fuzzy msgid "" "Developers could run the full set of Github Actions workflows under their" @@ -2606,7 +2532,7 @@ msgstr "" "fois installé, exécuter la commande suivante dans le dossier principale " "de Flower :" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:115 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 msgid "" "The Flower default workflow would run by setting up the required Docker " "machines underneath." @@ -2614,12 +2540,12 @@ msgstr "" "Le workflow par défaut de Flower sera exécuté en configurant les machines" " Docker requises en arrière plan." -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:120 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:147 #, fuzzy msgid "Build Release" msgstr "Inédit" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:122 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" "Flower uses Poetry to build releases. The necessary command is wrapped in" " a simple script::" @@ -2627,7 +2553,7 @@ msgstr "" "Flower utilise Poetry pour construire les nouvelles versions. La commande" " nécessaire est comprise dans un script simple ::" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:127 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" "The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" " the :code:`/dist` subdirectory." @@ -2635,19 +2561,19 @@ msgstr "" "Les versions résultantes :code:`.whl` et :code:`.tar.gz` seront stockées " "dans le sous-répertoire:code:`/dist`." -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:132 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 #, fuzzy msgid "Build Documentation" msgstr "Amélioration de la documentation" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:134 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" "Flower's documentation uses `Sphinx `_. " "There's no convenience script to re-build the documentation yet, but it's" " pretty easy::" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:140 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 msgid "This will generate HTML documentation in ``doc/build/html``." msgstr "" @@ -2788,7 +2714,6 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 -#: ../../source/example-mxnet-walk-through.rst:356 #: ../../source/example-pytorch-from-centralized-to-federated.rst:310 #: ../../source/tutorial-quickstart-jax.rst:283 msgid "Next Steps" @@ -3002,7 +2927,6 @@ msgstr "" "opération pour plusieurs tours." #: ../../source/example-jax-from-centralized-to-federated.rst:123 -#: ../../source/example-mxnet-walk-through.rst:204 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" @@ -3018,7 +2942,6 @@ msgstr "" "d'apprentissage fédéré." #: ../../source/example-jax-from-centralized-to-federated.rst:133 -#: ../../source/example-mxnet-walk-through.rst:214 #: ../../source/example-pytorch-from-centralized-to-federated.rst:191 #: ../../source/tutorial-quickstart-jax.rst:139 msgid "We can already start the *server*:" @@ -3065,13 +2988,11 @@ msgstr "" "pour tester le modèle :" #: ../../source/example-jax-from-centralized-to-federated.rst:161 -#: ../../source/example-mxnet-walk-through.rst:242 #: ../../source/tutorial-quickstart-jax.rst:167 msgid ":code:`set_parameters (optional)`" msgstr ":code:`set_parameters (optional)`" #: ../../source/example-jax-from-centralized-to-federated.rst:160 -#: ../../source/example-mxnet-walk-through.rst:241 #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" @@ -3085,7 +3006,6 @@ msgid "transform parameters to NumPy :code:`ndarray`'s" msgstr "transforme les paramètres en NumPy :code:`ndarray`'s" #: ../../source/example-jax-from-centralized-to-federated.rst:162 -#: ../../source/example-mxnet-walk-through.rst:243 #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" @@ -3096,17 +3016,14 @@ msgstr "" ":code:`ndarray`'s (pensez à la liste des couches du réseau neuronal)" #: ../../source/example-jax-from-centralized-to-federated.rst:163 -#: ../../source/example-mxnet-walk-through.rst:244 #: ../../source/example-pytorch-from-centralized-to-federated.rst:221 #: ../../source/tutorial-quickstart-jax.rst:169 -#: ../../source/tutorial-quickstart-mxnet.rst:171 #: ../../source/tutorial-quickstart-pytorch.rst:155 -#: ../../source/tutorial-quickstart-scikitlearn.rst:108 +#: ../../source/tutorial-quickstart-scikitlearn.rst:118 msgid ":code:`get_parameters`" msgstr ":code:`get_parameters`" #: ../../source/example-jax-from-centralized-to-federated.rst:164 -#: ../../source/example-mxnet-walk-through.rst:245 #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" @@ -3118,19 +3035,15 @@ msgstr "" ":code:`flwr.client.NumPyClient` attend)" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 -#: ../../source/tutorial-quickstart-mxnet.rst:177 #: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 msgid ":code:`fit`" msgstr ":code:`fit`" #: ../../source/example-jax-from-centralized-to-federated.rst:166 #: ../../source/example-jax-from-centralized-to-federated.rst:170 -#: ../../source/example-mxnet-walk-through.rst:247 -#: ../../source/example-mxnet-walk-through.rst:251 #: ../../source/example-pytorch-from-centralized-to-federated.rst:224 #: ../../source/example-pytorch-from-centralized-to-federated.rst:228 #: ../../source/tutorial-quickstart-jax.rst:172 @@ -3143,7 +3056,6 @@ msgstr "" " serveur" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 msgid "train the model on the local training set" @@ -3157,17 +3069,14 @@ msgstr "" "serveur" #: ../../source/example-jax-from-centralized-to-federated.rst:172 -#: ../../source/example-mxnet-walk-through.rst:253 #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 #: ../../source/tutorial-quickstart-jax.rst:178 -#: ../../source/tutorial-quickstart-mxnet.rst:180 #: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 msgid ":code:`evaluate`" msgstr ":code:`évaluer`" #: ../../source/example-jax-from-centralized-to-federated.rst:171 -#: ../../source/example-mxnet-walk-through.rst:252 #: ../../source/example-pytorch-from-centralized-to-federated.rst:229 #: ../../source/tutorial-quickstart-jax.rst:177 msgid "evaluate the updated model on the local test set" @@ -3215,7 +3124,6 @@ msgid "Having defined the federation process, we can run it." msgstr "Après avoir défini le processus de fédération, nous pouvons l'exécuter." #: ../../source/example-jax-from-centralized-to-federated.rst:268 -#: ../../source/example-mxnet-walk-through.rst:347 #: ../../source/example-pytorch-from-centralized-to-federated.rst:301 #: ../../source/tutorial-quickstart-jax.rst:274 msgid "And that's it. You can now open two additional terminal windows and run" @@ -3260,417 +3168,112 @@ msgstr "" " modèle plus sophistiqué ou un ensemble de données différent ? Pourquoi " "ne pas ajouter d'autres clients ?" -#: ../../source/example-mxnet-walk-through.rst:2 -msgid "Example: MXNet - Run MXNet Federated" -msgstr "Exemple : MXNet - Exécuter MXNet Federated" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:2 +msgid "Example: PyTorch - From Centralized To Federated" +msgstr "Exemple : PyTorch - De la centralisation à la fédération" -#: ../../source/example-mxnet-walk-through.rst:4 -#, fuzzy +#: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" "This tutorial will show you how to use Flower to build a federated " -"version of an existing MXNet workload. We are using MXNet to train a " -"Sequential model on the MNIST dataset. We will structure the example " -"similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. MXNet and PyTorch are very " -"similar and a very good comparison between MXNet and PyTorch is given " -"`here `_. First, we build a centralized " -"training approach based on the `Handwritten Digit Recognition " -"`_" -" tutorial. Then, we build upon the centralized training code to run the " +"version of an existing machine learning workload. We are using PyTorch to" +" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " +"introduce this machine learning task with a centralized training approach" +" based on the `Deep Learning with PyTorch " +"`_ " +"tutorial. Then, we build upon the centralized training code to run the " "training in a federated fashion." msgstr "" "Ce tutoriel te montrera comment utiliser Flower pour construire une " -"version fédérée d'une charge de travail MXNet existante. Nous utilisons " -"MXNet pour former un modèle séquentiel sur l'ensemble de données MNIST. " -"Nous structurerons l'exemple de la même manière que notre présentation " -"`PyTorch - De la centralisation à la fédération " -"`_. MXNet et PyTorch sont très similaires et une" -" très bonne comparaison entre MXNet et PyTorch est donnée ici " -"`_. Tout d'abord, nous " -"construisons une approche de formation centralisée basée sur le tutoriel " -"`Handandwritten Digit Recognition " -"`_." -" Ensuite, nous nous basons sur le code de formation centralisé pour " -"exécuter la formation de manière fédérée." +"version fédérée d'une charge de travail d'apprentissage automatique " +"existante. Nous utilisons PyTorch pour entraîner un réseau neuronal " +"convolutif sur l'ensemble de données CIFAR-10. Tout d'abord, nous " +"présentons cette tâche d'apprentissage automatique avec une approche " +"d'entraînement centralisée basée sur le tutoriel `Deep Learning with " +"PyTorch " +"`_. " +"Ensuite, nous nous appuyons sur le code d'entraînement centralisé pour " +"exécuter l'entraînement de manière fédérée." -#: ../../source/example-mxnet-walk-through.rst:10 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"Before we start setting up our MXNet example, we install the " -":code:`mxnet` and :code:`flwr` packages:" +"We begin with a brief description of the centralized CNN training code. " +"If you want a more in-depth explanation of what's going on then have a " +"look at the official `PyTorch tutorial " +"`_." msgstr "" -"Avant de commencer à configurer notre exemple MXNet, nous installons les " -"paquets :code:`mxnet` et :code:`flwr` :" - -#: ../../source/example-mxnet-walk-through.rst:19 -msgid "MNIST Training with MXNet" -msgstr "Formation MNIST avec MXNet" +"Nous commençons par une brève description du code d'entraînement CNN " +"centralisé. Si tu veux une explication plus approfondie de ce qui se " +"passe, jette un coup d'œil au tutoriel officiel `PyTorch " +"`_." -#: ../../source/example-mxnet-walk-through.rst:21 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Sequential` model. If you want a more in-depth explanation of" -" what's going on then have a look at the official `MXNet tutorial " -"`_." +"Let's create a new file called :code:`cifar.py` with all the components " +"required for a traditional (centralized) training on CIFAR-10. First, all" +" required packages (such as :code:`torch` and :code:`torchvision`) need " +"to be imported. You can see that we do not import any package for " +"federated learning. You can keep all these imports as they are even when " +"we add the federated learning components at a later point." msgstr "" -"Nous commençons par une brève description du code d'entraînement " -"centralisé basé sur un modèle :code:`Sequential`. Si tu veux une " -"explication plus approfondie de ce qui se passe, jette un coup d'œil au " -"tutoriel officiel `MXNet " -"`_." +"Créons un nouveau fichier appelé :code:`cifar.py` avec tous les " +"composants requis pour une formation traditionnelle (centralisée) sur le " +"CIFAR-10. Tout d'abord, tous les paquets requis (tels que :code:`torch` " +"et :code:`torchvision`) doivent être importés. Tu peux voir que nous " +"n'importons aucun paquet pour l'apprentissage fédéré. Tu peux conserver " +"toutes ces importations telles quelles même lorsque nous ajouterons les " +"composants d'apprentissage fédéré à un moment ultérieur." -#: ../../source/example-mxnet-walk-through.rst:24 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" -"Let's create a new file called:code:`mxnet_mnist.py` with all the " -"components required for a traditional (centralized) MNIST training. " -"First, the MXNet package :code:`mxnet` needs to be imported. You can see " -"that we do not yet import the :code:`flwr` package for federated " -"learning. This will be done later." -msgstr "" -"Créons un nouveau fichier appelé :code:`mxnet_mnist.py` avec tous les " -"composants requis pour un apprentissage MNIST traditionnel (centralisé). " -"Tout d'abord, le package MXNet :code:`mxnet` doit être importé. Tu peux " -"voir que nous n'avons pas encore importé le package :code:`flwr` pour " -"l'apprentissage fédéré. Cela sera fait plus tard." - -#: ../../source/example-mxnet-walk-through.rst:42 -msgid "The :code:`load_data()` function loads the MNIST training and test sets." +"As already mentioned we will use the CIFAR-10 dataset for this machine " +"learning workload. The model architecture (a very simple Convolutional " +"Neural Network) is defined in :code:`class Net()`." msgstr "" -"La fonction :code:`load_data()` charge les ensembles d'entraînement et de" -" test MNIST." +"Comme nous l'avons déjà mentionné, nous utiliserons l'ensemble de données" +" CIFAR-10 pour cette charge de travail d'apprentissage automatique. " +"L'architecture du modèle (un réseau neuronal convolutif très simple) est " +"définie dans :code:`class Net()`." -#: ../../source/example-mxnet-walk-through.rst:57 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"As already mentioned, we will use the MNIST dataset for this machine " -"learning workload. The model architecture (a very simple " -":code:`Sequential` model) is defined in :code:`model()`." +"The :code:`load_data()` function loads the CIFAR-10 training and test " +"sets. The :code:`transform` normalized the data after loading." msgstr "" -"Comme nous l'avons déjà mentionné, nous utiliserons l'ensemble de données" -" MNIST pour cette charge de travail d'apprentissage automatique. " -"L'architecture du modèle (un modèle :code:`Séquentiel` très simple) est " -"définie dans :code:`model()`." +"La fonction :code:`load_data()` charge les ensembles d'entraînement et de" +" test CIFAR-10. La fonction :code:`transform` normalise les données après" +" leur chargement." -#: ../../source/example-mxnet-walk-through.rst:70 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" "We now need to define the training (function :code:`train()`) which loops" -" over the training set and measures the loss for each batch of training " -"examples." +" over the training set, measures the loss, backpropagates it, and then " +"takes one optimizer step for each batch of training examples." msgstr "" "Nous devons maintenant définir la formation (fonction :code:`train()`) " -"qui passe en boucle sur l'ensemble de la formation et mesure la perte " -"pour chaque lot d'exemples de formation." +"qui passe en boucle sur l'ensemble de la formation, mesure la perte, la " +"rétropropage, puis effectue une étape d'optimisation pour chaque lot " +"d'exemples de formation." -#: ../../source/example-mxnet-walk-through.rst:123 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in function :code:`test()`. The " -"function loops over all test samples and measures the loss and accuracy " -"of the model based on the test dataset." +"The evaluation of the model is defined in the function :code:`test()`. " +"The function loops over all test samples and measures the loss of the " +"model based on the test dataset." msgstr "" -"L'évaluation du modèle est définie dans la fonction :code:`test()`. Cette" -" fonction passe en boucle sur tous les échantillons de test et mesure la " -"perte et la précision du modèle en fonction de l'ensemble des données de " -"test." +"L'évaluation du modèle est définie dans la fonction :code:`test()`. La " +"fonction boucle sur tous les échantillons de test et mesure la perte du " +"modèle en fonction de l'ensemble des données de test." -#: ../../source/example-mxnet-walk-through.rst:158 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model on MNIST. " -"Note that the GPU/CPU device for the training and testing is defined " -"within the :code:`ctx` (context)." +"evaluation we can put everything together and train our CNN on CIFAR-10." msgstr "" "Après avoir défini le chargement des données, l'architecture du modèle, " -"l'entraînement et l'évaluation, nous pouvons tout assembler et entraîner " -"notre modèle sur MNIST. Note que le dispositif GPU/CPU pour " -"l'entraînement et le test est défini dans le :code:`ctx` (contexte)." - -#: ../../source/example-mxnet-walk-through.rst:184 -msgid "You can now run your (centralized) MXNet machine learning workload:" -msgstr "" -"Tu peux maintenant exécuter ta charge de travail (centralisée) " -"d'apprentissage automatique MXNet :" +"la formation et l'évaluation, nous pouvons tout mettre ensemble et former" +" notre CNN sur CIFAR-10." -#: ../../source/example-mxnet-walk-through.rst:190 -msgid "" -"So far this should all look fairly familiar if you've used MXNet (or even" -" PyTorch) before. Let's take the next step and use what we've built to " -"create a simple federated learning system consisting of one server and " -"two clients." -msgstr "" -"Jusqu'à présent, tout cela devrait te sembler assez familier si tu as " -"déjà utilisé MXNet (ou même PyTorch). Passons à l'étape suivante et " -"utilisons ce que nous avons construit pour créer un simple système " -"d'apprentissage fédéré composé d'un serveur et de deux clients." - -#: ../../source/example-mxnet-walk-through.rst:194 -msgid "MXNet meets Flower" -msgstr "MXNet rencontre Flower" - -#: ../../source/example-mxnet-walk-through.rst:196 -msgid "" -"So far, it was not easily possible to use MXNet workloads for federated " -"learning because federated learning is not supported in MXNet. Since " -"Flower is fully agnostic towards the underlying machine learning " -"framework, it can be used to federated arbitrary machine learning " -"workloads. This section will show you how Flower can be used to federate " -"our centralized MXNet workload." -msgstr "" -"Jusqu'à présent, il n'était pas facile d'utiliser les charges de travail " -"MXNet pour l'apprentissage fédéré car l'apprentissage fédéré n'est pas " -"pris en charge dans MXNet. Comme Flower est totalement agnostique " -"vis-à-vis du cadre d'apprentissage automatique sous-jacent, il peut être " -"utilisé pour fédérer des charges de travail d'apprentissage automatique " -"arbitraires. Cette section te montrera comment Flower peut être utilisé " -"pour fédérer notre charge de travail MXNet centralisée." - -#: ../../source/example-mxnet-walk-through.rst:198 -msgid "" -"The concept to federate an existing workload is always the same and easy " -"to understand. We have to start a *server* and then use the code in " -":code:`mxnet_mnist.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." -msgstr "" -"Le concept pour fédérer une charge de travail existante est toujours le " -"même et facile à comprendre. Nous devons démarrer un *serveur* et ensuite" -" utiliser le code dans :code:`mxnet_mnist.py` pour les *clients* qui sont" -" connectés au *serveur*. Le *serveur* envoie les paramètres du modèle aux" -" clients. Les *clients* exécutent la formation et mettent à jour les " -"paramètres. Les paramètres mis à jour sont renvoyés au *serveur* qui fait" -" la moyenne de toutes les mises à jour de paramètres reçues. Ceci décrit " -"un tour du processus d'apprentissage fédéré et nous répétons cette " -"opération pour plusieurs tours." - -#: ../../source/example-mxnet-walk-through.rst:220 -msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined MXNet training in :code:`mxnet_mnist.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`mxnet` to " -"update the parameters on our MXNet model:" -msgstr "" -"Enfin, nous allons définir la logique de notre *client* dans " -":code:`client.py` et nous appuyer sur l'entraînement MXNet défini " -"précédemment dans :code:`mxnet_mnist.py`. Notre *client* doit importer " -":code:`flwr`, mais aussi :code:`mxnet` pour mettre à jour les paramètres " -"de notre modèle MXNet :" - -#: ../../source/example-mxnet-walk-through.rst:235 -msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or MXNet) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs " -"to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" -msgstr "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or MXNet) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs " -"to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" - -#: ../../source/example-mxnet-walk-through.rst:242 -msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" -msgstr "transforme les :code:`NDArray` du MXNet en :code:`ndarray` de NumPy" - -#: ../../source/example-mxnet-walk-through.rst:249 -#: ../../source/example-pytorch-from-centralized-to-federated.rst:226 -msgid "get the updated local model weights and return them to the server" -msgstr "récupère les poids du modèle local mis à jour et les renvoie au serveur" - -#: ../../source/example-mxnet-walk-through.rst:253 -#: ../../source/example-pytorch-from-centralized-to-federated.rst:230 -msgid "return the local loss and accuracy to the server" -msgstr "renvoie la perte locale et la précision au serveur" - -#: ../../source/example-mxnet-walk-through.rst:255 -msgid "" -"The challenging part is to transform the MXNet parameters from " -":code:`NDArray` to :code:`NumPy Arrays` to make it readable for Flower." -msgstr "" -"La partie la plus difficile est de transformer les paramètres MXNet de " -":code:`NDArray` en :code:`NumPy Arrays` pour les rendre lisibles pour " -"Flower." - -#: ../../source/example-mxnet-walk-through.rst:257 -msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`mxnet_mnist.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." -msgstr "" -"Les deux méthodes :code:`NumPyClient` :code:`fit` et :code:`evaluate` " -"utilisent les fonctions :code:`train()` et :code:`test()` définies " -"précédemment dans :code:`mxnet_mnist.py`. Ce que nous faisons vraiment " -"ici, c'est que nous indiquons à Flower, par le biais de notre sous-classe" -" :code:`NumPyClient`, laquelle de nos fonctions déjà définies doit être " -"appelée pour l'entraînement et l'évaluation. Nous avons inclus des " -"annotations de type pour te donner une meilleure compréhension des types " -"de données qui sont transmis." - -#: ../../source/example-mxnet-walk-through.rst:319 -msgid "" -"Having defined data loading, model architecture, training, and evaluation" -" we can put everything together and train our :code:`Sequential` model on" -" MNIST." -msgstr "" -"Après avoir défini le chargement des données, l'architecture du modèle, " -"la formation et l'évaluation, nous pouvons tout rassembler et former " -"notre modèle :code:`Sequential` sur MNIST." - -#: ../../source/example-mxnet-walk-through.rst:353 -msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your MXNet project run federated learning across two clients." -" Congratulations!" -msgstr "" -"dans chaque fenêtre (assure-toi que le serveur est toujours en cours " -"d'exécution avant de le faire) et tu verras ton projet MXNet exécuter " -"l'apprentissage fédéré sur deux clients. Félicitations !" - -#: ../../source/example-mxnet-walk-through.rst:358 -#, fuzzy -msgid "" -"The full source code for this example: `MXNet: From Centralized To " -"Federated (Code) `_. Our example is of course " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using a CNN or using a different dataset? How about " -"adding more clients?" -msgstr "" -"Le code source complet de cet exemple : `MXNet : From Centralized To " -"Federated (Code) `_. Notre exemple est bien sûr un " -"peu trop simplifié parce que les deux clients chargent exactement le même" -" ensemble de données, ce qui n'est pas réaliste. Tu es maintenant prêt à " -"explorer ce sujet plus en profondeur. Pourquoi ne pas utiliser un CNN ou " -"un ensemble de données différent ? Pourquoi ne pas ajouter d'autres " -"clients ?" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:2 -msgid "Example: PyTorch - From Centralized To Federated" -msgstr "Exemple : PyTorch - De la centralisation à la fédération" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:4 -msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload. We are using PyTorch to" -" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " -"introduce this machine learning task with a centralized training approach" -" based on the `Deep Learning with PyTorch " -"`_ " -"tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." -msgstr "" -"Ce tutoriel te montrera comment utiliser Flower pour construire une " -"version fédérée d'une charge de travail d'apprentissage automatique " -"existante. Nous utilisons PyTorch pour entraîner un réseau neuronal " -"convolutif sur l'ensemble de données CIFAR-10. Tout d'abord, nous " -"présentons cette tâche d'apprentissage automatique avec une approche " -"d'entraînement centralisée basée sur le tutoriel `Deep Learning with " -"PyTorch " -"`_. " -"Ensuite, nous nous appuyons sur le code d'entraînement centralisé pour " -"exécuter l'entraînement de manière fédérée." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:12 -msgid "" -"We begin with a brief description of the centralized CNN training code. " -"If you want a more in-depth explanation of what's going on then have a " -"look at the official `PyTorch tutorial " -"`_." -msgstr "" -"Nous commençons par une brève description du code d'entraînement CNN " -"centralisé. Si tu veux une explication plus approfondie de ce qui se " -"passe, jette un coup d'œil au tutoriel officiel `PyTorch " -"`_." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:15 -msgid "" -"Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all" -" required packages (such as :code:`torch` and :code:`torchvision`) need " -"to be imported. You can see that we do not import any package for " -"federated learning. You can keep all these imports as they are even when " -"we add the federated learning components at a later point." -msgstr "" -"Créons un nouveau fichier appelé :code:`cifar.py` avec tous les " -"composants requis pour une formation traditionnelle (centralisée) sur le " -"CIFAR-10. Tout d'abord, tous les paquets requis (tels que :code:`torch` " -"et :code:`torchvision`) doivent être importés. Tu peux voir que nous " -"n'importons aucun paquet pour l'apprentissage fédéré. Tu peux conserver " -"toutes ces importations telles quelles même lorsque nous ajouterons les " -"composants d'apprentissage fédéré à un moment ultérieur." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:32 -msgid "" -"As already mentioned we will use the CIFAR-10 dataset for this machine " -"learning workload. The model architecture (a very simple Convolutional " -"Neural Network) is defined in :code:`class Net()`." -msgstr "" -"Comme nous l'avons déjà mentionné, nous utiliserons l'ensemble de données" -" CIFAR-10 pour cette charge de travail d'apprentissage automatique. " -"L'architecture du modèle (un réseau neuronal convolutif très simple) est " -"définie dans :code:`class Net()`." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:56 -msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test " -"sets. The :code:`transform` normalized the data after loading." -msgstr "" -"La fonction :code:`load_data()` charge les ensembles d'entraînement et de" -" test CIFAR-10. La fonction :code:`transform` normalise les données après" -" leur chargement." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:74 -msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set, measures the loss, backpropagates it, and then " -"takes one optimizer step for each batch of training examples." -msgstr "" -"Nous devons maintenant définir la formation (fonction :code:`train()`) " -"qui passe en boucle sur l'ensemble de la formation, mesure la perte, la " -"rétropropage, puis effectue une étape d'optimisation pour chaque lot " -"d'exemples de formation." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:76 -msgid "" -"The evaluation of the model is defined in the function :code:`test()`. " -"The function loops over all test samples and measures the loss of the " -"model based on the test dataset." -msgstr "" -"L'évaluation du modèle est définie dans la fonction :code:`test()`. La " -"fonction boucle sur tous les échantillons de test et mesure la perte du " -"modèle en fonction de l'ensemble des données de test." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:136 -msgid "" -"Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "" -"Après avoir défini le chargement des données, l'architecture du modèle, " -"la formation et l'évaluation, nous pouvons tout mettre ensemble et former" -" notre CNN sur CIFAR-10." - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:163 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" "So far, this should all look fairly familiar if you've used PyTorch " "before. Let's take the next step and use what we've built to create a " @@ -3770,6 +3373,14 @@ msgstr "" msgid ":code:`set_parameters`" msgstr ":code:`set_parameters`" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:226 +msgid "get the updated local model weights and return them to the server" +msgstr "récupère les poids du modèle local mis à jour et les renvoie au serveur" + +#: ../../source/example-pytorch-from-centralized-to-federated.rst:230 +msgid "return the local loss and accuracy to the server" +msgstr "renvoie la perte locale et la précision au serveur" + #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" "The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" @@ -4923,75 +4534,235 @@ msgstr "" "Le serveur peut alors utiliser une stratégie personnalisée pour agréger " "les mesures fournies dans ces dictionnaires :" -#: ../../source/how-to-configure-clients.rst:2 -#, fuzzy -msgid "Configure clients" -msgstr "Configurer les clients" +#: ../../source/how-to-authenticate-supernodes.rst:2 +msgid "Authenticate SuperNodes" +msgstr "" -#: ../../source/how-to-configure-clients.rst:4 +#: ../../source/how-to-authenticate-supernodes.rst:4 msgid "" -"Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are," -" for example, a popular way to control client-side hyperparameters from " -"the server." +"Flower has built-in support for authenticated SuperNodes that you can use" +" to verify the identities of each SuperNode connecting to a SuperLink. " +"Flower node authentication works similar to how GitHub SSH authentication" +" works:" msgstr "" -"En plus des paramètres du modèle, Flower peut envoyer des valeurs de " -"configuration aux clients. Les valeurs de configuration peuvent être " -"utilisées à diverses fins. Elles constituent, par exemple, un moyen " -"populaire de contrôler les hyperparamètres côté client à partir du " -"serveur." -#: ../../source/how-to-configure-clients.rst:7 -msgid "Configuration values" -msgstr "Valeurs de configuration" +#: ../../source/how-to-authenticate-supernodes.rst:7 +msgid "SuperLink (server) stores a list of known (client) node public keys" +msgstr "" -#: ../../source/how-to-configure-clients.rst:9 +#: ../../source/how-to-authenticate-supernodes.rst:8 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys " -"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " -"float), ``int``, or ``str`` (or equivalent types in different languages)." -" Here is an example of a configuration dictionary in Python:" +"Using ECDH, both SuperNode and SuperLink independently derive a shared " +"secret" msgstr "" -"Les valeurs de configuration sont représentées sous forme de dictionnaire" -" avec des clés `str`` et des valeurs de type `bool`, `bytes`, `double` " -"(float de précision 64 bits), `int`, ou `str` (ou des types équivalents " -"dans d'autres langages). Voici un exemple de dictionnaire de " -"configuration en Python :" -#: ../../source/how-to-configure-clients.rst:20 +#: ../../source/how-to-authenticate-supernodes.rst:9 msgid "" -"Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client " -"using gRPC, and then deserializes them back to Python dictionaries." +"Shared secret is used to compute the HMAC value of the message sent from " +"SuperNode to SuperLink as a token" msgstr "" -"Flower sérialise ces dictionnaires de configuration (ou *config dict* en " -"abrégé) dans leur représentation ProtoBuf, les transporte vers le client " -"à l'aide de gRPC, puis les désérialise à nouveau en dictionnaires Python." -#: ../../source/how-to-configure-clients.rst:24 +#: ../../source/how-to-authenticate-supernodes.rst:10 +msgid "SuperLink verifies the token" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:12 +#, fuzzy msgid "" -"Currently, there is no support for directly sending collection types " -"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " -"dictionaries. There are several workarounds to send collections as values" -" by converting them to one of the supported value types (and converting " -"them back on the client-side)." +"We recommend you to check out the complete `code example " +"`_ demonstrating federated learning with Flower in an " +"authenticated setting." msgstr "" -"Actuellement, il n'est pas possible d'envoyer directement des types de " -"collections (par exemple, ``Set``, ``List``, ``Map``) en tant que valeurs" -" dans les dictionnaires de configuration. Il existe plusieurs solutions " -"pour envoyer des collections en tant que valeurs en les convertissant en " -"l'un des types de valeurs pris en charge (et en les reconvertissant du " -"côté client)." +"Réfère-toi à l'exemple de code complet " +"`_ " +"pour en savoir plus." -#: ../../source/how-to-configure-clients.rst:26 +#: ../../source/how-to-authenticate-supernodes.rst:15 msgid "" -"One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and" -" then convert the JSON string back to a list of floating-point numbers on" -" the client." +"This guide covers a preview feature that might change in future versions " +"of Flower." msgstr "" -"On peut, par exemple, convertir une liste de nombres à virgule flottante " -"en une chaîne JSON, puis envoyer la chaîne JSON à l'aide du dictionnaire " + +#: ../../source/how-to-authenticate-supernodes.rst:18 +msgid "" +"For increased security, node authentication can only be used when " +"encrypted connections (SSL/TLS) are enabled." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:21 +msgid "Enable node authentication in :code:`SuperLink`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:23 +msgid "" +"To enable node authentication, first you need to configure SSL/TLS " +"connections to secure the SuperLink<>SuperNode communication. You can " +"find the complete guide `here `_. After configuring secure connections, you" +" can enable client authentication in a long-running Flower " +":code:`SuperLink`. Use the following terminal command to start a Flower " +":code:`SuperNode` that has both secure connections and node " +"authentication enabled:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:36 +msgid "Let's break down the authentication flags:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:38 +msgid "" +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " +"file storing all known node public keys. You need to store all known node" +" public keys that are allowed to participate in a federation in one CSV " +"file (:code:`.csv`)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:40 +msgid "" +"A valid CSV file storing known node public keys should list the keys in " +"OpenSSH format, separated by commas and without any comments. For an " +"example, refer to our code sample, which contains a CSV file with two " +"known node public keys." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:42 +msgid "" +"The second and third flags :code:`--auth-superlink-private-key` and :code" +":`--auth-superlink-public-key` expect paths to the server's private and " +"public keys. For development purposes, you can generate a private and " +"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:45 +msgid "" +"In Flower 1.9, there is no support for dynamically removing, editing, or " +"adding known node public keys to the SuperLink. To change the set of " +"known nodes, you need to shut the server down, edit the CSV file, and " +"start the server again. Support for dynamically changing the set of known" +" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:51 +msgid "Enable node authentication in :code:`SuperNode`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:53 +msgid "" +"Similar to the long-running Flower server (:code:`SuperLink`), you can " +"easily enable node authentication in the long-running Flower client " +"(:code:`SuperNode`). Use the following terminal command to start an " +"authenticated :code:`SuperNode`:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:64 +msgid "" +"The :code:`--auth-supernode-private-key` flag expects a path to the " +"node's private key file and the :code:`--auth-supernode-public-key` flag " +"expects a path to the node's public key file. For development purposes, " +"you can generate a private and public key pair using :code:`ssh-keygen -t" +" ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:68 +msgid "Security notice" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:70 +msgid "" +"The system's security relies on the credentials of the SuperLink and each" +" SuperNode. Therefore, it is imperative to safeguard and safely store the" +" credentials to avoid security risks such as Public Key Infrastructure " +"(PKI) impersonation attacks. The node authentication mechanism also " +"involves human interaction, so please ensure that all of the " +"communication is done in a secure manner, using trusted communication " +"methods." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:75 +#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-use-built-in-mods.rst:85 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 +msgid "Conclusion" +msgstr "Conclusion" + +#: ../../source/how-to-authenticate-supernodes.rst:77 +msgid "" +"You should now have learned how to start a long-running Flower server " +"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " +"authentication enabled. You should also know the significance of the " +"private key and store it safely to minimize security risks." +msgstr "" + +#: ../../source/how-to-configure-clients.rst:2 +#, fuzzy +msgid "Configure clients" +msgstr "Configurer les clients" + +#: ../../source/how-to-configure-clients.rst:4 +msgid "" +"Along with model parameters, Flower can send configuration values to " +"clients. Configuration values can be used for various purposes. They are," +" for example, a popular way to control client-side hyperparameters from " +"the server." +msgstr "" +"En plus des paramètres du modèle, Flower peut envoyer des valeurs de " +"configuration aux clients. Les valeurs de configuration peuvent être " +"utilisées à diverses fins. Elles constituent, par exemple, un moyen " +"populaire de contrôler les hyperparamètres côté client à partir du " +"serveur." + +#: ../../source/how-to-configure-clients.rst:7 +msgid "Configuration values" +msgstr "Valeurs de configuration" + +#: ../../source/how-to-configure-clients.rst:9 +msgid "" +"Configuration values are represented as a dictionary with ``str`` keys " +"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " +"float), ``int``, or ``str`` (or equivalent types in different languages)." +" Here is an example of a configuration dictionary in Python:" +msgstr "" +"Les valeurs de configuration sont représentées sous forme de dictionnaire" +" avec des clés `str`` et des valeurs de type `bool`, `bytes`, `double` " +"(float de précision 64 bits), `int`, ou `str` (ou des types équivalents " +"dans d'autres langages). Voici un exemple de dictionnaire de " +"configuration en Python :" + +#: ../../source/how-to-configure-clients.rst:20 +msgid "" +"Flower serializes these configuration dictionaries (or *config dict* for " +"short) to their ProtoBuf representation, transports them to the client " +"using gRPC, and then deserializes them back to Python dictionaries." +msgstr "" +"Flower sérialise ces dictionnaires de configuration (ou *config dict* en " +"abrégé) dans leur représentation ProtoBuf, les transporte vers le client " +"à l'aide de gRPC, puis les désérialise à nouveau en dictionnaires Python." + +#: ../../source/how-to-configure-clients.rst:24 +msgid "" +"Currently, there is no support for directly sending collection types " +"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " +"dictionaries. There are several workarounds to send collections as values" +" by converting them to one of the supported value types (and converting " +"them back on the client-side)." +msgstr "" +"Actuellement, il n'est pas possible d'envoyer directement des types de " +"collections (par exemple, ``Set``, ``List``, ``Map``) en tant que valeurs" +" dans les dictionnaires de configuration. Il existe plusieurs solutions " +"pour envoyer des collections en tant que valeurs en les convertissant en " +"l'un des types de valeurs pris en charge (et en les reconvertissant du " +"côté client)." + +#: ../../source/how-to-configure-clients.rst:26 +msgid "" +"One can, for example, convert a list of floating-point numbers to a JSON " +"string, then send the JSON string using the configuration dictionary, and" +" then convert the JSON string back to a list of floating-point numbers on" +" the client." +msgstr "" +"On peut, par exemple, convertir une liste de nombres à virgule flottante " +"en une chaîne JSON, puis envoyer la chaîne JSON à l'aide du dictionnaire " "de configuration, et enfin reconvertir la chaîne JSON en une liste de " "nombres à virgule flottante sur le client." @@ -5197,9 +4968,11 @@ msgid "Enable SSL connections" msgstr "Collecte centralisée des données" #: ../../source/how-to-enable-ssl-connections.rst:4 +#, fuzzy msgid "" -"This guide describes how to a SSL-enabled secure Flower server can be " -"started and how a Flower client can establish a secure connections to it." +"This guide describes how to a SSL-enabled secure Flower server " +"(:code:`SuperLink`) can be started and how a Flower client " +"(:code:`SuperNode`) can establish a secure connections to it." msgstr "" "Ce guide décrit comment démarrer un serveur Flower sécurisé par SSL et " "comment un client Flower peut établir une connexion sécurisée avec lui." @@ -5216,11 +4989,12 @@ msgstr "" "tensorflow>`_." #: ../../source/how-to-enable-ssl-connections.rst:10 +#, fuzzy msgid "" -"The code example comes with a README.md file which will explain how to " -"start it. Although it is already SSL-enabled, it might be less " -"descriptive on how. Stick to this guide for a deeper introduction to the " -"topic." +"The code example comes with a :code:`README.md` file which explains how " +"to start it. Although it is already SSL-enabled, it might be less " +"descriptive on how it does so. Stick to this guide for a deeper " +"introduction to the topic." msgstr "" "L'exemple de code est accompagné d'un fichier README.md qui t'expliquera " "comment le démarrer. Bien qu'il soit déjà activé par SSL, il peut être " @@ -5238,7 +5012,7 @@ msgid "" "server and client. For the purpose of this guide we are going to generate" " self-signed certificates. As this can become quite complex we are going " "to ask you to run the script in :code:`examples/advanced-" -"tensorflow/certificates/generate.sh`" +"tensorflow/certificates/generate.sh` with the following command sequence:" msgstr "" "L'utilisation de connexions compatibles avec le protocole SSL nécessite " "que des certificats soient transmis au serveur et au client. Pour les " @@ -5247,11 +5021,7 @@ msgstr "" "d'exécuter le script dans :code:`examples/advanced-" "tensorflow/certificates/generate.sh`" -#: ../../source/how-to-enable-ssl-connections.rst:23 -msgid "with the following command sequence:" -msgstr "avec la séquence de commandes suivante :" - -#: ../../source/how-to-enable-ssl-connections.rst:30 +#: ../../source/how-to-enable-ssl-connections.rst:29 #, fuzzy msgid "" "This will generate the certificates in :code:`examples/advanced-" @@ -5260,98 +5030,84 @@ msgstr "" "Cela générera les certificats dans :code:`examples/advanced-" "tensorflow/.cache/certificates`." -#: ../../source/how-to-enable-ssl-connections.rst:32 +#: ../../source/how-to-enable-ssl-connections.rst:31 +#, fuzzy msgid "" -"The approach how the SSL certificates are generated in this example can " -"serve as an inspiration and starting point but should not be taken as " -"complete for production environments. Please refer to other sources " -"regarding the issue of correctly generating certificates for production " -"environments." +"The approach for generating SSL certificates in the context of this " +"example can serve as an inspiration and starting point, but it should not" +" be used as a reference for production environments. Please refer to " +"other sources regarding the issue of correctly generating certificates " +"for production environments. For non-critical prototyping or research " +"projects, it might be sufficient to use the self-signed certificates " +"generated using the scripts mentioned in this guide." msgstr "" "L'approche de la génération des certificats SSL dans cet exemple peut " "servir d'inspiration et de point de départ, mais ne doit pas être " "considérée comme complète pour les environnements de production." -#: ../../source/how-to-enable-ssl-connections.rst:36 -msgid "" -"In case you are a researcher you might be just fine using the self-signed" -" certificates generated using the scripts which are part of this guide." -msgstr "" -"Si tu es un chercheur, tu peux très bien utiliser les certificats auto-" -"signés générés à l'aide des scripts qui font partie de ce guide." +#: ../../source/how-to-enable-ssl-connections.rst:39 +#, fuzzy +msgid "Server (SuperLink)" +msgstr "flower-superlink" #: ../../source/how-to-enable-ssl-connections.rst:41 -#: ../../source/ref-api/flwr.server.Server.rst:2 -msgid "Server" -msgstr "Serveur" - -#: ../../source/how-to-enable-ssl-connections.rst:43 +#, fuzzy msgid "" -"We are now going to show how to write a sever which uses the previously " -"generated scripts." +"Use the following terminal command to start a sever (SuperLink) that uses" +" the previously generated certificates:" msgstr "" -"Nous allons maintenant montrer comment écrire un serveur qui utilise les " -"scripts générés précédemment." +"Nous allons maintenant montrer comment écrire un client qui utilise les " +"scripts générés précédemment :" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:47 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates. :code:`Path` can be used to easily read the contents of " -"those files into byte strings, which is the data type " -":code:`start_server` expects." +"certificates paths: CA certificate, server certificate and server private" +" key." msgstr "" -"Lorsqu'il fournit des certificats, le serveur attend un tuple de trois " -"certificats. :code:`Path` peut être utilisé pour lire facilement le " -"contenu de ces fichiers en chaînes d'octets, ce qui est le type de " -"données attendu par :code:`start_server`." -#: ../../source/how-to-enable-ssl-connections.rst:65 -#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 -#: ../../source/ref-api/flwr.client.Client.rst:2 -msgid "Client" -msgstr "Client" +#: ../../source/how-to-enable-ssl-connections.rst:51 +#, fuzzy +msgid "Client (SuperNode)" +msgstr "Codes d'état du client." -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:53 +#, fuzzy msgid "" -"We are now going to show how to write a client which uses the previously " -"generated scripts:" +"Use the following terminal command to start a client (SuperNode) that " +"uses the previously generated certificates:" msgstr "" "Nous allons maintenant montrer comment écrire un client qui utilise les " "scripts générés précédemment :" -#: ../../source/how-to-enable-ssl-connections.rst:84 +#: ../../source/how-to-enable-ssl-connections.rst:61 +#, fuzzy msgid "" -"When setting :code:`root_certificates`, the client expects the PEM-" -"encoded root certificates as a byte string. We are again using " -":code:`Path` to simplify reading those as byte strings." +"When setting :code:`root_certificates`, the client expects a file path to" +" PEM-encoded root certificates." msgstr "" "En définissant :code:`root_certificates`, le client s'attend à recevoir " "les certificats racine codés en PEM sous forme de chaîne d'octets. Nous " "utilisons à nouveau :code:`Path` pour simplifier la lecture de ces " "certificats sous forme de chaînes d'octets." -#: ../../source/how-to-enable-ssl-connections.rst:89 -#: ../../source/how-to-use-built-in-mods.rst:85 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 -msgid "Conclusion" -msgstr "Conclusion" - -#: ../../source/how-to-enable-ssl-connections.rst:91 +#: ../../source/how-to-enable-ssl-connections.rst:67 +#, fuzzy msgid "" "You should now have learned how to generate self-signed certificates " -"using the given script, start a SSL-enabled server, and have a client " +"using the given script, start an SSL-enabled server and have a client " "establish a secure connection to it." msgstr "" "Tu devrais maintenant avoir appris à générer des certificats auto-signés " "à l'aide du script donné, à démarrer un serveur compatible SSL et à " "demander à un client d'établir une connexion sécurisée avec lui." -#: ../../source/how-to-enable-ssl-connections.rst:96 +#: ../../source/how-to-enable-ssl-connections.rst:72 #, fuzzy msgid "Additional resources" msgstr "Ressources supplémentaires" -#: ../../source/how-to-enable-ssl-connections.rst:98 +#: ../../source/how-to-enable-ssl-connections.rst:74 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" @@ -5359,11 +5115,11 @@ msgstr "" "Ces sources supplémentaires peuvent être pertinentes si tu souhaites " "approfondir le sujet des certificats :" -#: ../../source/how-to-enable-ssl-connections.rst:100 +#: ../../source/how-to-enable-ssl-connections.rst:76 msgid "`Let's Encrypt `_" msgstr "`Let's Encrypt `_" -#: ../../source/how-to-enable-ssl-connections.rst:101 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "`certbot `_" msgstr "`certbot `_" @@ -5760,6 +5516,7 @@ msgid "Install stable release" msgstr "Installe la version stable" #: ../../source/how-to-install-flower.rst:15 +#: ../../source/how-to-upgrade-to-flower-next.rst:46 msgid "Using pip" msgstr "" @@ -6204,7 +5961,7 @@ msgstr "" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`_." +"`__." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:7 @@ -6227,245 +5984,562 @@ msgid "" "official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:25 +#: ../../source/how-to-run-flower-using-docker.rst:26 +msgid "" +"To ensure optimal performance and compatibility, the SuperLink, SuperNode" +" and ServerApp image must have the same version when running together. " +"This guarantees seamless integration and avoids potential conflicts or " +"issues that may arise from using different versions." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:31 #, fuzzy -msgid "Flower server" -msgstr "Serveur de Flower" +msgid "Flower SuperLink" +msgstr "flower-superlink" -#: ../../source/how-to-run-flower-using-docker.rst:28 +#: ../../source/how-to-run-flower-using-docker.rst:34 #, fuzzy msgid "Quickstart" msgstr "Démarrage rapide de JAX" -#: ../../source/how-to-run-flower-using-docker.rst:30 +#: ../../source/how-to-run-flower-using-docker.rst:36 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:37 +#: ../../source/how-to-run-flower-using-docker.rst:42 msgid "" -"The command will pull the Docker image with the tag " -"``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. The tag contains the " -"information which Flower, Python and Ubuntu is used. In this case, it " -"uses Flower 1.7.0, Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells " -"Docker to remove the container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker " +"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " +"The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:44 +#: ../../source/how-to-run-flower-using-docker.rst:48 msgid "" -"By default, the Flower server keeps state in-memory. When using the " +"By default, the Flower SuperLink keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " "starts. We will show below how to save the state in a file on your host " "system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:52 msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " "allowing you to access the Driver API on ``http://localhost:9091`` and " "the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " -"after the tag is passed to the Flower server. Here, we are passing the " -"flag ``--insecure``." +"after the tag is passed to the Flower SuperLink. Here, we are passing the" +" flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:55 +#: ../../source/how-to-run-flower-using-docker.rst:59 +#: ../../source/how-to-run-flower-using-docker.rst:238 +#: ../../source/how-to-run-flower-using-docker.rst:354 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " "recommend enabling `SSL `_ when " +"flower-using-docker.html#enabling-ssl-for-secure-connections>`__ when " "deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:64 msgid "" -"You can use ``--help`` to view all available flags that the server " +"You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:67 +#: ../../source/how-to-run-flower-using-docker.rst:71 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:69 +#: ../../source/how-to-run-flower-using-docker.rst:73 msgid "" -"If you want to persist the state of the server on your host system, all " -"you need to do is specify a path where you want to save the file on your " -"host system and a name for the database file. In the example below, we " -"tell Docker via the flag ``-v`` to mount the user's home directory " -"(``~/`` on your host) into the ``/app/`` directory of the container. " -"Furthermore, we use the flag ``--database`` to specify the name of the " -"database file." +"If you want to persist the state of the SuperLink on your host system, " +"all you need to do is specify a path where you want to save the file on " +"your host system and a name for the database file. In the example below, " +"we tell Docker via the flag ``--volume`` to mount the user's home " +"directory (``~/`` on your host) into the ``/app/`` directory of the " +"container. Furthermore, we use the flag ``--database`` to specify the " +"name of the database file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:82 +#: ../../source/how-to-run-flower-using-docker.rst:86 msgid "" -"As soon as the server starts, the file ``state.db`` is created in the " +"As soon as the SuperLink starts, the file ``state.db`` is created in the " "user's home directory on your host system. If the file already exists, " -"the server tries to restore the state from the file. To start the server " -"with an empty database, simply remove the ``state.db`` file." +"the SuperLink tries to restore the state from the file. To start the " +"SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:87 +#: ../../source/how-to-run-flower-using-docker.rst:91 +#: ../../source/how-to-run-flower-using-docker.rst:260 +#: ../../source/how-to-run-flower-using-docker.rst:375 #, fuzzy msgid "Enabling SSL for secure connections" msgstr "Collecte centralisée des données" -#: ../../source/how-to-run-flower-using-docker.rst:89 +#: ../../source/how-to-run-flower-using-docker.rst:93 msgid "" -"To enable SSL, you will need a CA certificate, a server certificate and a" -" server private key." +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" +"encoded private key and a PEM-encoded certificate chain." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:92 +#: ../../source/how-to-run-flower-using-docker.rst:97 msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `_ page contains a section that " -"will guide you through the process." +"enable-ssl-connections.html#certificates>`__ page contains a section that" +" will guide you through the process." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:96 +#: ../../source/how-to-run-flower-using-docker.rst:101 msgid "" "Assuming all files we need are in the local ``certificates`` directory, " -"we can use the flag ``-v`` to mount the local directory into the " -"``/app/`` directory of the container. This allows the server to access " -"the files within the container. Finally, we pass the names of the " -"certificates to the server with the ``--certificates`` flag." +"we can use the flag ``--volume`` to mount the local directory into the " +"``/app/`` directory of the container. This allows the SuperLink to access" +" the files within the container. Finally, we pass the names of the " +"certificates to the SuperLink with the ``--certificates`` flag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:108 -msgid "Using a different Flower or Python version" -msgstr "" +#: ../../source/how-to-run-flower-using-docker.rst:113 +#, fuzzy +msgid "Flower SuperNode" +msgstr "Serveur de Flower" -#: ../../source/how-to-run-flower-using-docker.rst:110 +#: ../../source/how-to-run-flower-using-docker.rst:115 msgid "" -"If you want to use a different version of Flower or Python, you can do so" -" by changing the tag. All versions we provide are available on `Docker " -"Hub `_." +"The SuperNode Docker image comes with a pre-installed version of Flower " +"and serves as a base for building your own SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:114 -msgid "Pinning a Docker image to a specific version" +#: ../../source/how-to-run-flower-using-docker.rst:120 +msgid "" +"The SuperNode Docker image currently works only with the 1.9.0-nightly " +"release. A stable version will be available when Flower 1.9.0 (stable) " +"gets released (ETA: May). A SuperNode nightly image must be paired with " +"the corresponding SuperLink and ServerApp nightly images released on the " +"same day. To ensure the versions are in sync, using the concrete tag, " +"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:116 +#: ../../source/how-to-run-flower-using-docker.rst:126 msgid "" -"It may happen that we update the images behind the tags. Such updates " -"usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that " -"you always use the same image, you can specify the hash of the image " -"instead of the tag." +"We will use the ``quickstart-pytorch`` example, which you can find in the" +" Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:121 +#: ../../source/how-to-run-flower-using-docker.rst:134 msgid "" -"The following command returns the current image hash referenced by the " -"``server:1.7.0-py3.11-ubuntu22.04`` tag:" +"Before we can start, we need to meet a few prerequisites in our local " +"development environment. You can skip the first part if you want to run " +"your ClientApp instead of the ``quickstart-pytorch`` example." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:128 -msgid "Next, we can pin the hash when running a new server container:" +#: ../../source/how-to-run-flower-using-docker.rst:138 +#, fuzzy +msgid "Clone the Flower repository." +msgstr "**Fourche le dépôt de Flower**" + +#: ../../source/how-to-run-flower-using-docker.rst:152 +msgid "Creating a SuperNode Dockerfile" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:137 -#, fuzzy -msgid "Setting environment variables" -msgstr "Mise en place de l'environnement de codage" +#: ../../source/how-to-run-flower-using-docker.rst:154 +#: ../../source/how-to-run-flower-using-docker.rst:289 +msgid "Let's assume the following project layout:" +msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:139 +#: ../../source/how-to-run-flower-using-docker.rst:163 msgid "" -"To set a variable inside a Docker container, you can use the ``-e " -"=`` flag." +"First, we need to create a ``requirements.txt`` file in the directory " +"where the ``ClientApp`` code is located. In the file, we list all the " +"dependencies that the ClientApp requires." msgstr "" -#: ../../source/how-to-run-simulations.rst:2 -#, fuzzy -msgid "Run simulations" -msgstr "Simulation de moniteur" +#: ../../source/how-to-run-flower-using-docker.rst:175 +msgid "" +"Note that `flwr `__ is already installed " +"in the ``flwr/supernode`` base image, so you only need to include other " +"package dependencies in your ``requirements.txt``, such as ``torch``, " +"``tensorflow``, etc." +msgstr "" -#: ../../source/how-to-run-simulations.rst:8 +#: ../../source/how-to-run-flower-using-docker.rst:179 msgid "" -"Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients " -"but without having to source, configure and mange a large number of " -"physical devices; you might want to run your FL workloads as fast as " -"possible on the compute systems you have access to without having to go " -"through a complex setup process; you might want to validate your " -"algorithm on different scenarios at varying levels of data and system " -"heterogeneity, client availability, privacy budgets, etc. These are among" -" some of the use-cases where simulating FL workloads makes sense. Flower " -"can accommodate these scenarios by means of its `VirtualClientEngine " -"`_ or " -"VCE." +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.supernode`` in ``examples" +"/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-simulations.rst:10 +#: ../../source/how-to-run-flower-using-docker.rst:182 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" -" clients. These clients are identical to `non-virtual` clients (i.e. the " -"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " -"creating a class inheriting, for example, from `flwr.client.NumPyClient " -"`_ and therefore behave in an " -"identical way. In addition to that, clients managed by the " -":code:`VirtualClientEngine` are:" +"The ``Dockerfile.supernode`` contains the instructions that assemble the " +"SuperNode image." msgstr "" -#: ../../source/how-to-run-simulations.rst:12 +#: ../../source/how-to-run-flower-using-docker.rst:196 msgid "" -"resource-aware: this means that each client gets assigned a portion of " -"the compute and memory on your system. You as a user can control this at " -"the beginning of the simulation and allows you to control the degree of " -"parallelism of your Flower FL simulation. The fewer the resources per " -"client, the more clients can run concurrently on the same hardware." +"In the first two lines, we instruct Docker to use the SuperNode image " +"tagged ``nightly`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. Next, we install the ClientApp dependencies by copying the " +"``requirements.txt`` file into the image and run ``pip install``. In the " +"last two lines, we copy the ``client.py`` module into the image and set " +"the entry point to ``flower-client-app`` with the argument " +"``client:app``. The argument is the object reference of the ClientApp " +"(``:``) that will be run inside the ClientApp." msgstr "" -#: ../../source/how-to-run-simulations.rst:13 +#: ../../source/how-to-run-flower-using-docker.rst:205 +#, fuzzy +msgid "Building the SuperNode Docker image" +msgstr "Démarrer le serveur" + +#: ../../source/how-to-run-flower-using-docker.rst:207 msgid "" -"self-managed: this means that you as a user do not need to launch clients" -" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " -"internals." +"Next, we build the SuperNode Docker image by running the following " +"command in the directory where Dockerfile and ClientApp code are located." msgstr "" -#: ../../source/how-to-run-simulations.rst:14 +#: ../../source/how-to-run-flower-using-docker.rst:214 msgid "" -"ephemeral: this means that a client is only materialized when it is " -"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," -" releasing the resources it was assigned and allowing in this way other " -"clients to participate." +"We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." msgstr "" -#: ../../source/how-to-run-simulations.rst:16 +#: ../../source/how-to-run-flower-using-docker.rst:219 +#, fuzzy +msgid "Running the SuperNode Docker image" +msgstr "Démarrer le serveur" + +#: ../../source/how-to-run-flower-using-docker.rst:221 +msgid "Now that we have built the SuperNode image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:229 +#: ../../source/how-to-run-flower-using-docker.rst:345 +msgid "Let's break down each part of this command:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:231 +#: ../../source/how-to-run-flower-using-docker.rst:347 +msgid "``docker run``: This is the command to run a new Docker container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:232 +#: ../../source/how-to-run-flower-using-docker.rst:348 msgid "" -"The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " -"`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " -"of `Actors `_ to " -"spawn `virtual` clients and run their workload." +"``--rm``: This option specifies that the container should be " +"automatically removed when it stops." msgstr "" -#: ../../source/how-to-run-simulations.rst:20 -msgid "Launch your Flower simulation" +#: ../../source/how-to-run-flower-using-docker.rst:233 +msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "" -#: ../../source/how-to-run-simulations.rst:22 +#: ../../source/how-to-run-flower-using-docker.rst:234 +#: ../../source/how-to-run-flower-using-docker.rst:350 +msgid "``--insecure``: This option enables insecure communication." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst msgid "" -"Running Flower simulations still require you to define your client class," -" a strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your " -"simulation is done with `start_simulation `_ and a minimal example looks" -" as follows:" +"``--server 192.168.1.100:9092``: This option specifies the address of the" +" SuperLinks Fleet" msgstr "" -#: ../../source/how-to-run-simulations.rst:44 -#, fuzzy -msgid "VirtualClientEngine resources" -msgstr "Moteur de client virtuel" +#: ../../source/how-to-run-flower-using-docker.rst +msgid "API to connect to. Remember to update it with your SuperLink IP." +msgstr "" -#: ../../source/how-to-run-simulations.rst:45 +#: ../../source/how-to-run-flower-using-docker.rst:248 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your SuperNodes." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:252 +msgid "" +"Any argument that comes after the tag is passed to the Flower SuperNode " +"binary. To see all available flags that the SuperNode supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:262 +msgid "" +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your SuperNode container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:264 +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the SuperNode to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:275 +#, fuzzy +msgid "Flower ServerApp" +msgstr "Serveur de Flower" + +#: ../../source/how-to-run-flower-using-docker.rst:277 +msgid "" +"The procedure for building and running a ServerApp image is almost " +"identical to the SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:279 +msgid "" +"Similar to the SuperNode image, the ServerApp Docker image comes with a " +"pre-installed version of Flower and serves as a base for building your " +"own ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:282 +msgid "" +"We will use the same ``quickstart-pytorch`` example as we do in the " +"Flower SuperNode section. If you have not already done so, please follow " +"the `SuperNode Prerequisites`_ before proceeding." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:287 +msgid "Creating a ServerApp Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:298 +msgid "" +"First, we need to create a Dockerfile in the directory where the " +"``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.serverapp`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:302 +msgid "" +"The ``Dockerfile.serverapp`` contains the instructions that assemble the " +"ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:313 +msgid "" +"In the first two lines, we instruct Docker to use the ServerApp image " +"tagged ``1.8.0`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. In the last two lines, we copy the ``server.py`` module into " +"the image and set the entry point to ``flower-server-app`` with the " +"argument ``server:app``. The argument is the object reference of the " +"ServerApp (``:``) that will be run inside the " +"ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:321 +#, fuzzy +msgid "Building the ServerApp Docker image" +msgstr "Démarrer le serveur" + +#: ../../source/how-to-run-flower-using-docker.rst:323 +msgid "" +"Next, we build the ServerApp Docker image by running the following " +"command in the directory where Dockerfile and ServerApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:330 +msgid "" +"We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:335 +#, fuzzy +msgid "Running the ServerApp Docker image" +msgstr "Démarrer le serveur" + +#: ../../source/how-to-run-flower-using-docker.rst:337 +msgid "Now that we have built the ServerApp image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:349 +msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "" +"``--server 192.168.1.100:9091``: This option specifies the address of the" +" SuperLinks Driver" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:363 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your ServerApps." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:367 +msgid "" +"Any argument that comes after the tag is passed to the Flower ServerApp " +"binary. To see all available flags that the ServerApp supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:377 +msgid "" +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:379 +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the ServerApp to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:390 +#, fuzzy +msgid "Advanced Docker options" +msgstr "Options d'installation avancées" + +#: ../../source/how-to-run-flower-using-docker.rst:393 +msgid "Using a different Flower version" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:395 +msgid "" +"If you want to use a different version of Flower, for example Flower " +"nightly, you can do so by changing the tag. All available versions are on" +" `Docker Hub `__." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:400 +msgid "Pinning a Docker image to a specific version" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:402 +msgid "" +"It may happen that we update the images behind the tags. Such updates " +"usually include security updates of system dependencies that should not " +"change the functionality of Flower. However, if you want to ensure that " +"you always use the same image, you can specify the hash of the image " +"instead of the tag." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:407 +msgid "" +"The following command returns the current image hash referenced by the " +"``superlink:1.8.0`` tag:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:414 +msgid "Next, we can pin the hash when running a new SuperLink container:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:423 +#, fuzzy +msgid "Setting environment variables" +msgstr "Mise en place de l'environnement de codage" + +#: ../../source/how-to-run-flower-using-docker.rst:425 +msgid "" +"To set a variable inside a Docker container, you can use the ``-e " +"=`` flag." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:2 +#, fuzzy +msgid "Run simulations" +msgstr "Simulation de moniteur" + +#: ../../source/how-to-run-simulations.rst:8 +msgid "" +"Simulating Federated Learning workloads is useful for a multitude of use-" +"cases: you might want to run your workload on a large cohort of clients " +"but without having to source, configure and mange a large number of " +"physical devices; you might want to run your FL workloads as fast as " +"possible on the compute systems you have access to without having to go " +"through a complex setup process; you might want to validate your " +"algorithm on different scenarios at varying levels of data and system " +"heterogeneity, client availability, privacy budgets, etc. These are among" +" some of the use-cases where simulating FL workloads makes sense. Flower " +"can accommodate these scenarios by means of its `VirtualClientEngine " +"`_ or " +"VCE." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:10 +msgid "" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" +" clients. These clients are identical to `non-virtual` clients (i.e. the " +"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " +"creating a class inheriting, for example, from `flwr.client.NumPyClient " +"`_ and therefore behave in an " +"identical way. In addition to that, clients managed by the " +":code:`VirtualClientEngine` are:" +msgstr "" + +#: ../../source/how-to-run-simulations.rst:12 +msgid "" +"resource-aware: this means that each client gets assigned a portion of " +"the compute and memory on your system. You as a user can control this at " +"the beginning of the simulation and allows you to control the degree of " +"parallelism of your Flower FL simulation. The fewer the resources per " +"client, the more clients can run concurrently on the same hardware." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:13 +msgid "" +"self-managed: this means that you as a user do not need to launch clients" +" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"internals." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:14 +msgid "" +"ephemeral: this means that a client is only materialized when it is " +"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," +" releasing the resources it was assigned and allowing in this way other " +"clients to participate." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:16 +msgid "" +"The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " +"`_, an open-source framework for scalable Python " +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " +"of `Actors `_ to " +"spawn `virtual` clients and run their workload." +msgstr "" + +#: ../../source/how-to-run-simulations.rst:20 +msgid "Launch your Flower simulation" +msgstr "" + +#: ../../source/how-to-run-simulations.rst:22 +msgid "" +"Running Flower simulations still require you to define your client class," +" a strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your " +"simulation is done with `start_simulation `_ and a minimal example looks" +" as follows:" +msgstr "" + +#: ../../source/how-to-run-simulations.rst:44 +#, fuzzy +msgid "VirtualClientEngine resources" +msgstr "Moteur de client virtuel" + +#: ../../source/how-to-run-simulations.rst:45 msgid "" "By default the VCE has access to all system resources (i.e. all CPUs, all" " GPUs, etc) since that is also the default behavior when starting Ray. " @@ -6891,6 +6965,7 @@ msgstr "" "0.x existants." #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 +#: ../../source/how-to-upgrade-to-flower-next.rst:43 msgid "Install update" msgstr "Installer la mise à jour" @@ -6947,6 +7022,7 @@ msgstr "" "l'utilisation de ``start_simulation``)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 +#: ../../source/how-to-upgrade-to-flower-next.rst:100 msgid "Required changes" msgstr "Changements nécessaires" @@ -6986,6 +7062,11 @@ msgstr "" "``start_client(server_address=\"127.0.0.1:8080\", " "client=FlowerClient())``" +#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 +#: ../../source/ref-api/flwr.client.Client.rst:2 +msgid "Client" +msgstr "Client" + #: ../../source/how-to-upgrade-to-flower-1.0.rst:39 msgid "" "Subclasses of ``NumPyClient``: change ``def get_parameters(self):``` to " @@ -7206,6 +7287,7 @@ msgstr "" "round_timeout=600.0), ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 +#: ../../source/how-to-upgrade-to-flower-next.rst:317 msgid "Further help" msgstr "Aide supplémentaire" @@ -7224,81 +7306,284 @@ msgstr "" "Flower `_ et utilise le canal " "``#questions``." -#: ../../source/how-to-use-built-in-mods.rst:2 -msgid "Use Built-in Mods" -msgstr "" +#: ../../source/how-to-upgrade-to-flower-next.rst:2 +#, fuzzy +msgid "Upgrade to Flower Next" +msgstr "Passe à Flower 1.0" -#: ../../source/how-to-use-built-in-mods.rst:4 +#: ../../source/how-to-upgrade-to-flower-next.rst:4 msgid "" -"**Note: This tutorial covers experimental features. The functionality and" -" interfaces may change in future versions.**" +"Welcome to the migration guide for updating Flower to Flower Next! " +"Whether you're a seasoned user or just getting started, this guide will " +"help you smoothly transition your existing setup to take advantage of the" +" latest features and improvements in Flower Next, starting from version " +"1.8." msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:6 +#: ../../source/how-to-upgrade-to-flower-next.rst:9 msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment " -"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " -"allow us to perform operations before and after a task is processed in " -"the ``ClientApp``." +"This guide shows how to reuse pre-``1.8`` Flower code with minimum code " +"changes by using the *compatibility layer* in Flower Next. In another " +"guide, we will show how to run Flower Next end-to-end with pure Flower " +"Next APIs." msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:9 -msgid "What are Mods?" +#: ../../source/how-to-upgrade-to-flower-next.rst:13 +msgid "Let's dive in!" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:11 +#: ../../source/how-to-upgrade-to-flower-next.rst:48 +#, fuzzy msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " -"or inspect the incoming ``Message`` and the resulting outgoing " -"``Message``. The signature for a ``Mod`` is as follows:" +"Here's how to update an existing installation of Flower to Flower Next " +"with ``pip``:" msgstr "" +"Voici comment mettre à jour une installation existante vers Flower 1.0 en" +" utilisant soit pip soit Poetry :" -#: ../../source/how-to-use-built-in-mods.rst:18 -msgid "A typical mod function might look something like this:" +#: ../../source/how-to-upgrade-to-flower-next.rst:54 +msgid "or if you need Flower Next with simulation:" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:31 -msgid "Using Mods" +#: ../../source/how-to-upgrade-to-flower-next.rst:61 +msgid "" +"Ensure you set the following version constraint in your " +"``requirements.txt``" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:33 -msgid "To use mods in your ``ClientApp``, you can follow these steps:" +#: ../../source/how-to-upgrade-to-flower-next.rst:71 +msgid "or ``pyproject.toml``:" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:36 -msgid "1. Import the required mods" -msgstr "" +#: ../../source/how-to-upgrade-to-flower-next.rst:82 +#, fuzzy +msgid "Using Poetry" +msgstr "Utiliser la poésie (recommandé)" -#: ../../source/how-to-use-built-in-mods.rst:38 -msgid "First, import the built-in mod you intend to use:" +#: ../../source/how-to-upgrade-to-flower-next.rst:84 +#, fuzzy +msgid "" +"Update the ``flwr`` dependency in ``pyproject.toml`` and then reinstall " +"(don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` before " +"running ``poetry install``)." msgstr "" +"Poetry : mettez à jour la dépendance ``flwr`` dans ``pyproject.toml`` " +"puis réinstallez (n'oubliez pas de supprimer ``poetry.lock`` via ``rm " +"poetry.lock`` avant d'exécuter ``poetry install``)." -#: ../../source/how-to-use-built-in-mods.rst:46 -msgid "2. Define your client function" -msgstr "" +#: ../../source/how-to-upgrade-to-flower-next.rst:86 +#, fuzzy +msgid "" +"Ensure you set the following version constraint in your " +"``pyproject.toml``:" +msgstr "Augmente la version mineure de ``pyproject.toml`` d'une unité." -#: ../../source/how-to-use-built-in-mods.rst:48 +#: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" -"Define your client function (``client_fn``) that will be wrapped by the " -"mod(s):" +"In Flower Next, the *infrastructure* and *application layers* have been " +"decoupled. Instead of starting a client in code via ``start_client()``, " +"you create a |clientapp_link|_ and start it via the command line. Instead" +" of starting a server in code via ``start_server()``, you create a " +"|serverapp_link|_ and start it via the command line. The long-running " +"components of server and client are called SuperLink and SuperNode. The " +"following non-breaking changes that require manual updates and allow you " +"to run your project both in the traditional way and in the Flower Next " +"way:" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:57 -msgid "3. Create the ``ClientApp`` with mods" -msgstr "" +#: ../../source/how-to-upgrade-to-flower-next.rst:109 +#, fuzzy +msgid "|clientapp_link|_" +msgstr "client" -#: ../../source/how-to-use-built-in-mods.rst:59 +#: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" -"Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " -"argument. The order in which you provide the mods matters:" +"Wrap your existing client with |clientapp_link|_ instead of launching it " +"via |startclient_link|_. Here's an example:" msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:72 +#: ../../source/how-to-upgrade-to-flower-next.rst:132 #, fuzzy -msgid "Order of execution" -msgstr "Dépréciations" +msgid "|serverapp_link|_" +msgstr "serveur" -#: ../../source/how-to-use-built-in-mods.rst:74 +#: ../../source/how-to-upgrade-to-flower-next.rst:133 +msgid "" +"Wrap your existing strategy with |serverapp_link|_ instead of starting " +"the server via |startserver_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:154 +msgid "Deployment" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:155 +msgid "" +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " +"in sequence, |flowernext_clientapp_link|_ (2x) and " +"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" +" `server.py` as Python scripts." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:158 +msgid "" +"Here's an example to start the server without HTTPS (only for " +"prototyping):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:174 +msgid "" +"Here's another example to start with HTTPS. Use the ``--certificates`` " +"command line argument to pass paths to (CA certificate, server " +"certificate, and server private key)." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:201 +#, fuzzy +msgid "Simulation in CLI" +msgstr "Simulation de moniteur" + +#: ../../source/how-to-upgrade-to-flower-next.rst:202 +msgid "" +"Wrap your existing client and strategy with |clientapp_link|_ and " +"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" +" anymore. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:232 +msgid "" +"Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " +"``client_app`` object in the code instead of executing the Python script." +" Here's an example (assuming the ``server_app`` and ``client_app`` " +"objects are in a ``sim.py`` module):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:249 +msgid "" +"Set default resources for each |clientapp_link|_ using the ``--backend-" +"config`` command line argument instead of setting the " +"``client_resources`` argument in |startsim_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:275 +msgid "Simulation in a Notebook" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:276 +msgid "" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " +"an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:319 +#, fuzzy +msgid "" +"Some official `Flower code examples `_ " +"are already updated to Flower Next so they can serve as a reference for " +"using the Flower Next API. If there are further questions, `join the " +"Flower Slack `_ and use the channel " +"``#questions``. You can also `participate in Flower Discuss " +"`_ where you can find us answering questions," +" or share and learn from others about migrating to Flower Next." +msgstr "" +"La plupart des `exemples de code Flower officiels " +"`_ sont déjà mis à " +"jour vers Flower 1.0, ils peuvent servir de référence pour l'utilisation " +"de l'API Flower 1.0. Si vous avez d'autres questions, `joins le Slack " +"Flower `_ et utilise le canal " +"``#questions``." + +#: ../../source/how-to-upgrade-to-flower-next.rst:325 +#, fuzzy +msgid "Important" +msgstr "Changements importants :" + +#: ../../source/how-to-upgrade-to-flower-next.rst:328 +msgid "" +"As we continuously enhance Flower Next at a rapid pace, we'll be " +"periodically updating this guide. Please feel free to share any feedback " +"with us!" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:334 +msgid "Happy migrating! 🚀" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:2 +msgid "Use Built-in Mods" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:4 +msgid "" +"**Note: This tutorial covers experimental features. The functionality and" +" interfaces may change in future versions.**" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:6 +msgid "" +"In this tutorial, we will learn how to utilize built-in mods to augment " +"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " +"allow us to perform operations before and after a task is processed in " +"the ``ClientApp``." +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:9 +msgid "What are Mods?" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:11 +msgid "" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " +"or inspect the incoming ``Message`` and the resulting outgoing " +"``Message``. The signature for a ``Mod`` is as follows:" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:18 +msgid "A typical mod function might look something like this:" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:31 +msgid "Using Mods" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:33 +msgid "To use mods in your ``ClientApp``, you can follow these steps:" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:36 +msgid "1. Import the required mods" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:38 +msgid "First, import the built-in mod you intend to use:" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:46 +msgid "2. Define your client function" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:48 +msgid "" +"Define your client function (``client_fn``) that will be wrapped by the " +"mod(s):" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:57 +msgid "3. Create the ``ClientApp`` with mods" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:59 +msgid "" +"Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " +"argument. The order in which you provide the mods matters:" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:72 +#, fuzzy +msgid "Order of execution" +msgstr "Dépréciations" + +#: ../../source/how-to-use-built-in-mods.rst:74 msgid "" "When the ``ClientApp`` runs, the mods are executed in the order they are " "provided in the list:" @@ -7643,15 +7928,15 @@ msgstr "Tutoriel" msgid "Quickstart tutorials" msgstr "Quickstart tutorials" -#: ../../source/index.rst:75 ../../source/index.rst:79 +#: ../../source/index.rst:74 ../../source/index.rst:78 msgid "How-to guides" msgstr "Guides" -#: ../../source/index.rst:98 +#: ../../source/index.rst:99 msgid "Legacy example guides" msgstr "" -#: ../../source/index.rst:109 ../../source/index.rst:113 +#: ../../source/index.rst:108 ../../source/index.rst:112 msgid "Explanations" msgstr "Explications" @@ -7659,26 +7944,26 @@ msgstr "Explications" msgid "API reference" msgstr "Référence pour l'API" -#: ../../source/index.rst:138 +#: ../../source/index.rst:137 msgid "Reference docs" msgstr "Référence pour la documentation" -#: ../../source/index.rst:154 +#: ../../source/index.rst:153 #, fuzzy msgid "Contributor tutorials" msgstr "Configuration du contributeur" -#: ../../source/index.rst:161 +#: ../../source/index.rst:160 #, fuzzy msgid "Contributor how-to guides" msgstr "Guide pour les contributeurs" -#: ../../source/index.rst:174 +#: ../../source/index.rst:173 #, fuzzy msgid "Contributor explanations" msgstr "Explications" -#: ../../source/index.rst:180 +#: ../../source/index.rst:179 #, fuzzy msgid "Contributor references" msgstr "Configuration du contributeur" @@ -7748,7 +8033,7 @@ msgstr "" "Une serie de tutoriels de Federated Learning, l'endroit parfait pour " "débuter." -#: ../../source/index.rst:62 +#: ../../source/index.rst:61 #, fuzzy msgid "" "QUICKSTART TUTORIALS: :doc:`PyTorch ` | " @@ -7756,10 +8041,10 @@ msgid "" " ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " "` | :doc:`PyTorch Lightning ` | :doc:`MXNet `" -" | :doc:`scikit-learn ` | :doc:`XGBoost " -"` | :doc:`Android ` | :doc:`iOS `" +"quickstart-pytorch-lightning>` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " +":doc:`Android ` | :doc:`iOS `" msgstr "" "QUICKSTART TUTORIALS: :ref:`PyTorch ` | " ":ref:`TensorFlow ` | :ref:`🤗 Transformers " @@ -7770,16 +8055,16 @@ msgstr "" "` | :ref:`Android ` | :ref:`iOS " "`" -#: ../../source/index.rst:64 +#: ../../source/index.rst:63 msgid "We also made video tutorials for PyTorch:" msgstr "" -#: ../../source/index.rst:69 +#: ../../source/index.rst:68 #, fuzzy msgid "And TensorFlow:" msgstr "Exemples de TensorFlow" -#: ../../source/index.rst:77 +#: ../../source/index.rst:76 msgid "" "Problem-oriented how-to guides show step-by-step how to achieve a " "specific goal." @@ -7787,7 +8072,7 @@ msgstr "" "Guides orientés sur la résolutions étapes par étapes de problèmes ou " "objectifs specifiques." -#: ../../source/index.rst:111 +#: ../../source/index.rst:110 msgid "" "Understanding-oriented concept guides explain and discuss key topics and " "underlying ideas behind Flower and collaborative AI." @@ -7795,29 +8080,29 @@ msgstr "" "Guides orientés sur la compréhension et l'explication des sujets et idées" " de fonds sur lesquels sont construits Flower et l'IA collaborative." -#: ../../source/index.rst:121 +#: ../../source/index.rst:120 #, fuzzy msgid "References" msgstr "Référence" -#: ../../source/index.rst:123 +#: ../../source/index.rst:122 msgid "Information-oriented API reference and other reference material." msgstr "Référence de l'API orientée sur l'information pure." -#: ../../source/index.rst:132::1 +#: ../../source/index.rst:131::1 msgid ":py:obj:`flwr `\\" msgstr "" -#: ../../source/index.rst:132::1 flwr:1 of +#: ../../source/index.rst:131::1 flwr:1 of msgid "Flower main package." msgstr "" -#: ../../source/index.rst:149 +#: ../../source/index.rst:148 #, fuzzy msgid "Contributor docs" msgstr "Configuration du contributeur" -#: ../../source/index.rst:151 +#: ../../source/index.rst:150 #, fuzzy msgid "" "The Flower community welcomes contributions. The following docs are " @@ -7833,23 +8118,20 @@ msgid "Flower CLI reference" msgstr "Client de Flower" #: ../../source/ref-api-cli.rst:7 -msgid "flower-superlink" -msgstr "flower-superlink" +#, fuzzy +msgid "flower-simulation" +msgstr "Simulation de moniteur" #: ../../source/ref-api-cli.rst:17 -msgid "flower-driver-api" -msgstr "flower-driver-api" +msgid "flower-superlink" +msgstr "flower-superlink" #: ../../source/ref-api-cli.rst:27 -msgid "flower-fleet-api" -msgstr "flower-fleet-api" - -#: ../../source/ref-api-cli.rst:37 #, fuzzy msgid "flower-client-app" msgstr "Flower ClientApp." -#: ../../source/ref-api-cli.rst:47 +#: ../../source/ref-api-cli.rst:37 #, fuzzy msgid "flower-server-app" msgstr "flower-driver-api" @@ -7859,7 +8141,7 @@ msgstr "flower-driver-api" msgid "flwr" msgstr "Fleur" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:52 +#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 msgid "Modules" msgstr "" @@ -7885,7 +8167,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr "" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:41::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 #: flwr.server.server.Server:1 of #, fuzzy msgid "Flower server." @@ -7912,79 +8194,91 @@ msgstr "client" msgid "Functions" msgstr "Les quatre fonctions :" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 msgid ":py:obj:`run_client_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 -#: flwr.client.app.run_client_app:1 of +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_client_app:1 of #, fuzzy msgid "Run Flower client app." msgstr "Client de Flower" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 +#, fuzzy +msgid ":py:obj:`run_supernode `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_supernode:1 of +#, fuzzy +msgid "Run Flower SuperNode." +msgstr "Serveur de Flower" + +#: ../../source/ref-api/flwr.client.rst:25::1 msgid "" ":py:obj:`start_client `\\ \\(\\*\\, " "server\\_address\\[\\, client\\_fn\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_client:1 of msgid "Start a Flower client node which connects to a Flower server." msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 msgid "" ":py:obj:`start_numpy_client `\\ \\(\\*\\," " server\\_address\\, client\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_numpy_client:1 of msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "" -#: ../../source/ref-api/flwr.client.rst:26 +#: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:29 +#: ../../source/ref-api/flwr.server.rst:28 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`Client `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client.Client:1 of msgid "Abstract base class for Flower clients." msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid "" ":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " "mods\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client_app.ClientApp:1 of #, fuzzy msgid "Flower ClientApp." msgstr "Flower ClientApp." -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`NumPyClient `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.numpy_client.NumPyClient:1 of msgid "Abstract base class for Flower clients using NumPy." msgstr "" #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 -#: flwr.server.strategy.strategy.Strategy:1 of +#: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 +#: of msgid "Bases: :py:class:`~abc.ABC`" msgstr "" @@ -7999,6 +8293,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.Error.rst:15 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:15 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:15 +#: ../../source/ref-api/flwr.common.EventType.rst:15 #: ../../source/ref-api/flwr.common.FitIns.rst:15 #: ../../source/ref-api/flwr.common.FitRes.rst:15 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:15 @@ -8138,7 +8433,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.Error.rst:25 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:25 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:25 -#: ../../source/ref-api/flwr.common.EventType.rst:19 +#: ../../source/ref-api/flwr.common.EventType.rst:165 #: ../../source/ref-api/flwr.common.FitIns.rst:25 #: ../../source/ref-api/flwr.common.FitRes.rst:25 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:25 @@ -8181,7 +8476,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.unregister #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver flwr.server.driver.driver.Driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -8234,7 +8528,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -8269,7 +8562,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -8336,9 +8628,9 @@ msgstr "client" #: flwr.common.typing.GetParametersRes:1 flwr.common.typing.GetPropertiesIns:1 #: flwr.common.typing.GetPropertiesRes:1 flwr.common.typing.Parameters:1 #: flwr.common.typing.ReconnectIns:1 flwr.common.typing.ServerMessage:1 -#: flwr.common.typing.Status:1 flwr.server.driver.driver.Driver:1 -#: flwr.server.history.History:1 flwr.server.server.Server:1 -#: flwr.server.server_app.ServerApp:1 flwr.server.server_config.ServerConfig:1 +#: flwr.common.typing.Status:1 flwr.server.history.History:1 +#: flwr.server.server.Server:1 flwr.server.server_app.ServerApp:1 +#: flwr.server.server_config.ServerConfig:1 #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of @@ -8350,8 +8642,7 @@ msgstr "" #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 #: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 -#: flwr.server.compat.app.start_driver:32 flwr.server.server_app.ServerApp:4 -#: flwr.server.server_app.ServerApp.main:4 +#: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:21 @@ -8578,6 +8869,11 @@ msgstr "" msgid "run\\_client\\_app" msgstr "" +#: ../../source/ref-api/flwr.client.run_supernode.rst:2 +#, fuzzy +msgid "run\\_supernode" +msgstr "flower-superlink" + #: ../../source/ref-api/flwr.client.start_client.rst:2 #, fuzzy msgid "start\\_client" @@ -8610,8 +8906,7 @@ msgid "" "increased limit and block larger messages." msgstr "" -#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 -#: flwr.server.compat.app.start_driver:21 of +#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " "provided, a secure connection using the certificates will be established " @@ -9199,12 +9494,11 @@ msgstr "Configurer les clients" #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "" "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`str`, :py:class:`bytes`, :py:class:`bool`, " -":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " -"[:py:class:`float`], :py:class:`~typing.List`\\ [:py:class:`str`], " -":py:class:`~typing.List`\\ [:py:class:`bytes`], " -":py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" +" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " +"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " +":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" +" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9368,5646 +9662,5675 @@ msgstr "" msgid "Bases: :py:class:`str`, :py:class:`~enum.Enum`" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`PING `\\" -msgstr "" - -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_CLIENT_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid "" +":py:obj:`encode `\\ \\(\\[encoding\\, " +"errors\\]\\)" msgstr "" +"Flower 1.0 : ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_CLIENT_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.encode:1 of +msgid "Encode the string using the codec registered for encoding." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_SERVER_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`replace `\\ \\(old\\, new\\[\\, " +"count\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_SERVER_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.replace:1 of +msgid "Return a copy with all occurrences of substring old replaced by new." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "" -":py:obj:`RUN_DRIVER_API_ENTER " -"`\\" -msgstr "" +":py:obj:`split `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE " -"`\\" +"Return a list of the substrings in the string, using sep as the separator" +" string." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_FLEET_API_ENTER " -"`\\" +":py:obj:`rsplit `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_FLEET_API_LEAVE " -"`\\" -msgstr "" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`join `\\ \\(iterable\\, \\/\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_SUPERLINK_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.join:1 of +msgid "Concatenate any number of strings." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE " -"`\\" -msgstr "" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`capitalize `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`START_SIMULATION_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.capitalize:1 of +msgid "Return a capitalized version of the string." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`START_SIMULATION_LEAVE " -"`\\" -msgstr "" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`casefold `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`DRIVER_CONNECT `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.casefold:1 of +msgid "Return a version of the string suitable for caseless comparisons." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`DRIVER_DISCONNECT `\\" -msgstr "" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`title `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_DRIVER_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.title:1 of +msgid "Return a version of the string where each word is titlecased." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_DRIVER_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`center `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.center:1 of +msgid "Return a centered string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE " -"`\\" +":py:obj:`count `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_SERVER_APP_ENTER " -"`\\" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE " -"`\\" +":py:obj:`expandtabs `\\ " +"\\(\\[tabsize\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:2 -msgid "FitIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.expandtabs:1 of +msgid "Return a copy where all tab characters are expanded using spaces." msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`find `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:2 -msgid "FitRes" -msgstr "" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.partition:1 flwr.common.EventType.rpartition:1 of +msgid "Partition the string into three parts using the given separator." msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`index `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`num_examples `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`ljust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`metrics `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.ljust:1 of +msgid "Return a left-justified string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "GetParametersIns" -msgstr ":code:`get_parameters`" +msgid ":py:obj:`lower `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lower:1 of +msgid "Return a copy of the string converted to lowercase." msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "GetParametersRes" -msgstr ":code:`get_parameters`" +msgid ":py:obj:`lstrip `\\ \\(\\[chars\\]\\)" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lstrip:1 of +msgid "Return a copy of the string with leading whitespace removed." msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rfind `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 -msgid "GetPropertiesIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rindex `\\ \\(sub\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 -msgid "GetPropertiesRes" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rjust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rjust:1 of +msgid "Return a right-justified string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 -msgid ":py:obj:`properties `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`rstrip `\\ \\(\\[chars\\]\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rstrip:1 of +msgid "Return a copy of the string with trailing whitespace removed." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Message" -msgstr "Côté serveur" +msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" +msgstr "serveur.stratégie.Stratégie" -#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 -#: flwr.common.message.Message:3 of -msgid "A dataclass including information about the message to be executed." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid "" +":py:obj:`splitlines `\\ " +"\\(\\[keepends\\]\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.splitlines:1 of +msgid "Return a list of the lines in the string, breaking at line boundaries." msgstr "" -#: flwr.common.message.Message:5 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`strip `\\ \\(\\[chars\\]\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.strip:1 of +msgid "Return a copy of the string with leading and trailing whitespace removed." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`swapcase `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.swapcase:1 of msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side" -" logic to a client, or vice-versa) or that will be sent to it." +"Convert uppercase characters to lowercase and lowercase characters to " +"uppercase." msgstr "" -#: flwr.common.message.Message:8 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.translate:1 of +msgid "Replace each character in the string using the given translation table." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`upper `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.upper:1 of +msgid "Return a copy of the string converted to uppercase." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"A dataclass that captures information about an error that took place when" -" processing another message." +":py:obj:`startswith `\\ \\(prefix\\[\\," +" start\\[\\, end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S starts with the specified prefix, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`create_error_reply `\\ " -"\\(error\\, ttl\\)" +":py:obj:`endswith `\\ \\(suffix\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_error_reply:1 of -msgid "Construct a reply message indicating an error happened." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S ends with the specified suffix, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`create_reply `\\ \\(content\\," -" ttl\\)" +":py:obj:`removeprefix `\\ " +"\\(prefix\\, \\/\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_reply:1 of -msgid "Create a reply to this message with specified content and TTL." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removeprefix:1 of +msgid "Return a str with the given prefix string removed if present." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -msgid ":py:obj:`has_content `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`removesuffix `\\ " +"\\(suffix\\, \\/\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_content:1 of -msgid "Return True if message has content, else False." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removesuffix:1 of +msgid "Return a str with the given suffix string removed if present." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -msgid ":py:obj:`has_error `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isascii `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isascii:1 of +msgid "Return True if all characters in the string are ASCII, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_error:1 of -msgid "Return True if message has an error, else False." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`islower `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.islower:1 of +msgid "Return True if the string is a lowercase string, False otherwise." msgstr "" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`content `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isupper `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isupper:1 of +msgid "Return True if the string is an uppercase string, False otherwise." msgstr "" -#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 -#: of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "The content of this message." -msgstr "Évaluer la réponse d'un client." +msgid ":py:obj:`istitle `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`error `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.istitle:1 of +msgid "Return True if the string is a title-cased string, False otherwise." msgstr "" -#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of -msgid "Error captured by this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isspace `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isspace:1 of +msgid "Return True if the string is a whitespace string, False otherwise." msgstr "" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`metadata `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isdecimal `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdecimal:1 of +msgid "Return True if the string is a decimal string, False otherwise." msgstr "" -#: flwr.common.message.Message.create_error_reply:3 of -msgid "The error that was encountered." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isdigit `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdigit:1 of +msgid "Return True if the string is a digit string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.ttl:1 flwr.common.message.Message.create_error_reply:5 -#: flwr.common.message.Message.create_reply:9 flwr.common.message.Metadata:16 -#: of -msgid "Time-to-live for this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isnumeric `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isnumeric:1 of +msgid "Return True if the string is a numeric string, False otherwise." msgstr "" -#: flwr.common.message.Message.create_reply:3 of -msgid "" -"The method generates a new `Message` as a reply to this message. It " -"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " -"this message and sets 'reply_to_message' to the ID of this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isalpha `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalpha:1 of +msgid "Return True if the string is an alphabetic string, False otherwise." msgstr "" -#: flwr.common.message.Message.create_reply:7 of -msgid "The content for the reply message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isalnum `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalnum:1 of +msgid "Return True if the string is an alpha-numeric string, False otherwise." msgstr "" -#: flwr.common.message.Message.create_reply:12 of -msgid "A new `Message` instance representing the reply." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isidentifier `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isidentifier:1 of +msgid "Return True if the string is a valid Python identifier, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:2 -msgid "MessageType" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`isprintable `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isprintable:1 of +msgid "Return True if the string is printable, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`EVALUATE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`zfill `\\ \\(width\\, \\/\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.zfill:1 of +msgid "" +"Pad a numeric string with zeros on the left, to fill a field of the given" +" width." msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`QUERY `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`format `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`TRAIN `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from args and kwargs." msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 -msgid "MessageTypeLegacy" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`format_map `\\ \\(mapping\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from mapping." msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PARAMETERS `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`maketrans `\\" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.maketrans:1 of +msgid "Return a translation table usable for str.translate()." msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PROPERTIES `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`PING `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of -msgid "An identifier for the current run." +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_CLIENT_ENTER `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of -msgid "An identifier for the current message." +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of -msgid "An identifier for the node sending this message." +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_SERVER_ENTER `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1 -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.message.Metadata:9 of -msgid "An identifier for the node receiving this message." +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_SERVER_LEAVE `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of -msgid "An identifier for the message this message replies to." +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_DRIVER_API_ENTER " +"`\\" msgstr "" -#: flwr.common.message.Metadata:13 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"An identifier for grouping messages. In some settings, this is used as " -"the FL round." +":py:obj:`RUN_DRIVER_API_LEAVE " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of -msgid "A string that encodes the action to be executed on the receiving end." +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_FLEET_API_ENTER " +"`\\" msgstr "" -#: flwr.common.message.Metadata:21 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"An identifier that can be used when loading a particular data partition " -"for a ClientApp. Making use of this identifier is more relevant when " -"conducting simulations." +":py:obj:`RUN_FLEET_API_LEAVE " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`dst_node_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`group_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.group_id:1 of -msgid "An identifier for grouping messages." +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`START_SIMULATION_ENTER " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`message_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`START_SIMULATION_LEAVE " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`message_type `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`DRIVER_CONNECT `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`partition_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`DRIVER_DISCONNECT `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.partition_id:1 of -msgid "An identifier telling which data partition a ClientApp should use." +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_ENTER `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`reply_to_message `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`run_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_CLIENT_APP_ENTER " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`src_node_id `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_CLIENT_APP_LEAVE " +"`\\" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`ttl `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SERVER_APP_ENTER " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 -msgid "MetricsRecord" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SERVER_APP_LEAVE " +"`\\" msgstr "" -#: flwr.common.record.metricsrecord.MetricsRecord:1 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`~typing.List`\\ [:py:class:`int`], " -":py:class:`~typing.List`\\ [:py:class:`float`]]]" +":py:obj:`RUN_SUPERNODE_ENTER " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`clear `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +#, fuzzy +msgid "" +":py:obj:`RUN_SUPERNODE_LEAVE " +"`\\" +msgstr "serveur.stratégie.Stratégie" + +#: flwr.common.EventType.capitalize:3 of +msgid "" +"More specifically, make the first character have upper case and the rest " +"lower case." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +#: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 +#: flwr.common.EventType.rjust:3 of +msgid "Padding is done using the specified fill character (default is a space)." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.count:1 of +msgid "" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]. Optional arguments start and end are interpreted as" +" in slice notation." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.encode:3 of +msgid "encoding" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.encode:4 of +msgid "The encoding in which to encode the string." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.encode:9 of +msgid "errors" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#: flwr.common.EventType.encode:6 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +"The error handling scheme to use for encoding errors. The default is " +"'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " +"as any other name registered with codecs.register_error that can handle " +"UnicodeEncodeErrors." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.endswith:1 of +msgid "" +"Return True if S ends with the specified suffix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. suffix can also be a tuple of strings " +"to try." msgstr "" -#: ../../source/ref-api/flwr.common.NDArray.rst:2 -msgid "NDArray" +#: flwr.common.EventType.expandtabs:3 of +msgid "If tabsize is not given, a tab size of 8 characters is assumed." msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -msgid ":py:obj:`tensors `\\" +#: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of +msgid "" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -msgid ":py:obj:`tensor_type `\\" +#: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of +msgid "Return -1 on failure." msgstr "" -#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 -#, fuzzy -msgid "ParametersRecord" -msgstr "Paramètres du modèle." - -#: flwr.common.record.parametersrecord.ParametersRecord:1 of +#: flwr.common.EventType.format:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Return a formatted version of S, using substitutions from args and " +"kwargs. The substitutions are identified by braces ('{' and '}')." msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord:3 of +#: flwr.common.EventType.format_map:1 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds " -"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " -"viewed as an equivalent to PyTorch's state_dict, but holding serialised " -"tensors instead." -msgstr "" - -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`clear `\\ \\(\\)" +"Return a formatted version of S, using substitutions from mapping. The " +"substitutions are identified by braces ('{' and '}')." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +#: flwr.common.EventType.index:5 flwr.common.EventType.rindex:5 of +msgid "Raises ValueError when the substring is not found." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.isalnum:3 of +msgid "" +"A string is alpha-numeric if all characters in the string are alpha-" +"numeric and there is at least one character in the string." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.isalpha:3 of +msgid "" +"A string is alphabetic if all characters in the string are alphabetic and" +" there is at least one character in the string." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.isascii:3 of +msgid "" +"ASCII characters have code points in the range U+0000-U+007F. Empty " +"string is ASCII too." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.isdecimal:3 of +msgid "" +"A string is a decimal string if all characters in the string are decimal " +"and there is at least one character in the string." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#: flwr.common.EventType.isdigit:3 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +"A string is a digit string if all characters in the string are digits and" +" there is at least one character in the string." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.isidentifier:3 of +msgid "" +"Call keyword.iskeyword(s) to test whether string s is a reserved " +"identifier, such as \"def\" or \"class\"." msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of +#: flwr.common.EventType.islower:3 of msgid "" -"Note that a small amount of Bytes might also be included in this counting" -" that correspond to metadata of the serialized object (e.g. of NumPy " -"array) needed for deseralization." +"A string is lowercase if all cased characters in the string are lowercase" +" and there is at least one cased character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 -#, fuzzy -msgid "ReconnectIns" -msgstr "Collecte centralisée des données" - -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 -msgid ":py:obj:`seconds `\\" +#: flwr.common.EventType.isnumeric:3 of +msgid "" +"A string is numeric if all characters in the string are numeric and there" +" is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.RecordSet.rst:2 -msgid "RecordSet" +#: flwr.common.EventType.isprintable:3 of +msgid "" +"A string is printable if all of its characters are considered printable " +"in repr() or if it is empty." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`configs_records `\\" +#: flwr.common.EventType.isspace:3 of +msgid "" +"A string is whitespace if all characters in the string are whitespace and" +" there is at least one character in the string." msgstr "" -#: flwr.common.RecordSet.configs_records:1 -#: flwr.common.RecordSet.configs_records:1::1 of -msgid "Dictionary holding ConfigsRecord instances." +#: flwr.common.EventType.istitle:3 of +msgid "" +"In a title-cased string, upper- and title-case characters may only follow" +" uncased characters and lowercase characters only cased ones." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`metrics_records `\\" +#: flwr.common.EventType.isupper:3 of +msgid "" +"A string is uppercase if all cased characters in the string are uppercase" +" and there is at least one cased character in the string." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.metrics_records:1 of -msgid "Dictionary holding MetricsRecord instances." +#: flwr.common.EventType.join:3 of +msgid "" +"The string whose method is called is inserted in between each given " +"string. The result is returned as a new string." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`parameters_records `\\" +#: flwr.common.EventType.join:6 of +msgid "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.parameters_records:1 of -msgid "Dictionary holding ParametersRecord instances." +#: flwr.common.EventType.lstrip:3 flwr.common.EventType.rstrip:3 +#: flwr.common.EventType.strip:3 of +msgid "If chars is given and not None, remove characters in chars instead." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 -#, fuzzy -msgid "ServerMessage" -msgstr "Côté serveur" - -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -msgid ":py:obj:`evaluate_ins `\\" +#: flwr.common.EventType.maketrans:3 of +msgid "" +"If there is only one argument, it must be a dictionary mapping Unicode " +"ordinals (integers) or characters to Unicode ordinals, strings or None. " +"Character keys will be then converted to ordinals. If there are two " +"arguments, they must be strings of equal length, and in the resulting " +"dictionary, each character in x will be mapped to the character at the " +"same position in y. If there is a third argument, it must be a string, " +"whose characters will be mapped to None in the result." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -msgid ":py:obj:`fit_ins `\\" +#: flwr.common.EventType.partition:3 of +msgid "" +"This will search for the separator in the string. If the separator is " +"found, returns a 3-tuple containing the part before the separator, the " +"separator itself, and the part after it." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#: flwr.common.EventType.partition:7 of msgid "" -":py:obj:`get_parameters_ins " -"`\\" +"If the separator is not found, returns a 3-tuple containing the original " +"string and two empty strings." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#: flwr.common.EventType.removeprefix:3 of msgid "" -":py:obj:`get_properties_ins " -"`\\" +"If the string starts with the prefix string, return string[len(prefix):]." +" Otherwise, return a copy of the original string." msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:2 -#, fuzzy -msgid "Status" -msgstr "Statut du client." - -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -msgid ":py:obj:`code `\\" +#: flwr.common.EventType.removesuffix:3 of +msgid "" +"If the string ends with the suffix string and that suffix is not empty, " +"return string[:-len(suffix)]. Otherwise, return a copy of the original " +"string." msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -msgid ":py:obj:`message `\\" +#: flwr.common.EventType.replace:5 of +msgid "count" msgstr "" -#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 -msgid "array\\_from\\_numpy" +#: flwr.common.EventType.replace:4 of +msgid "" +"Maximum number of occurrences to replace. -1 (the default value) means " +"replace all occurrences." msgstr "" -#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 -msgid "bytes\\_to\\_ndarray" +#: flwr.common.EventType.replace:7 of +msgid "" +"If the optional argument count is given, only the first count occurrences" +" are replaced." msgstr "" -#: ../../source/ref-api/flwr.common.configure.rst:2 -#, fuzzy -msgid "configure" -msgstr "Configurer les clients" - -#: ../../source/ref-api/flwr.common.event.rst:2 -msgid "event" +#: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of +msgid "" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." msgstr "" -#: ../../source/ref-api/flwr.common.log.rst:2 -msgid "log" +#: flwr.common.EventType.rpartition:3 of +msgid "" +"This will search for the separator in the string, starting at the end. If" +" the separator is found, returns a 3-tuple containing the part before the" +" separator, the separator itself, and the part after it." msgstr "" -#: logging.Logger.log:3 of +#: flwr.common.EventType.rpartition:7 of msgid "" -"To pass exception information, use the keyword argument exc_info with a " -"true value, e.g." +"If the separator is not found, returns a 3-tuple containing two empty " +"strings and the original string." msgstr "" -"Pour transmettre des informations sur les exceptions, utilise l'argument " -"mot-clé exc_info avec une valeur vraie, par ex." - -#: logging.Logger.log:6 of -#, python-format -msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" -msgstr "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" -#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 -msgid "ndarray\\_to\\_bytes" +#: flwr.common.EventType.rsplit:7 flwr.common.EventType.split:7 of +msgid "sep" msgstr "" -#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 -msgid "ndarrays\\_to\\_parameters" +#: flwr.common.EventType.rsplit:4 flwr.common.EventType.split:4 of +msgid "The separator used to split the string." msgstr "" -#: ../../source/ref-api/flwr.common.now.rst:2 -msgid "now" +#: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of +msgid "" +"When set to None (the default value), will split on any whitespace " +"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" +" empty strings from the result." msgstr "" -#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 -msgid "parameters\\_to\\_ndarrays" +#: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of +msgid "maxsplit" msgstr "" -#: ../../source/ref-api/flwr.server.rst:2 -msgid "server" -msgstr "serveur" - -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of +msgid "" +"Maximum number of splits (starting from the left). -1 (the default value)" +" means no limit." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_driver_api:1 of -#, fuzzy -msgid "Run Flower server (Driver API)." -msgstr "flower-driver-api" - -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#: flwr.common.EventType.rsplit:13 of +msgid "Splitting starts at the end of the string and works to the front." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_fleet_api:1 of -#, fuzzy -msgid "Run Flower server (Fleet API)." -msgstr "flower-fleet-api" - -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_server_app `\\ \\(\\)" +#: flwr.common.EventType.split:13 of +msgid "" +"Note, str.split() is mainly useful for data that has been intentionally " +"delimited. With natural text that includes punctuation, consider using " +"the regular expression module." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.run_serverapp.run_server_app:1 of -#, fuzzy -msgid "Run Flower server app." -msgstr "Serveur de Flower" - -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_superlink `\\ \\(\\)" +#: flwr.common.EventType.splitlines:3 of +msgid "" +"Line breaks are not included in the resulting list unless keepends is " +"given and true." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_superlink:1 of -msgid "Run Flower server (Driver API and Fleet API)." +#: flwr.common.EventType.startswith:1 of +msgid "" +"Return True if S starts with the specified prefix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. prefix can also be a tuple of strings " +"to try." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: flwr.common.EventType.title:3 of msgid "" -":py:obj:`start_driver `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" +"More specifically, words start with uppercased characters and all " +"remaining cased characters have lower case." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.compat.app.start_driver:1 of +#: flwr.common.EventType.translate:5 of #, fuzzy -msgid "Start a Flower Driver API server." -msgstr "Tout d'abord, démarre un serveur Flower :" +msgid "table" +msgstr "Database" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: flwr.common.EventType.translate:4 of msgid "" -":py:obj:`start_server `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" +"Translation table, which must be a mapping of Unicode ordinals to Unicode" +" ordinals, strings, or None." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.start_server:1 of -msgid "Start a Flower server using the gRPC transport layer." +#: flwr.common.EventType.translate:7 of +msgid "" +"The table must implement lookup/indexing via __getitem__, for instance a " +"dictionary or list. If this operation raises LookupError, the character " +"is left untouched. Characters mapped to None are deleted." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`ClientManager `\\ \\(\\)" +#: flwr.common.EventType.zfill:3 of +msgid "The string is never truncated." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.ClientManager:1 of -msgid "Abstract base class for managing Flower clients." +#: ../../source/ref-api/flwr.common.FitIns.rst:2 +msgid "FitIns" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#, fuzzy -msgid "" -":py:obj:`Driver `\\ " -"\\(\\[driver\\_service\\_address\\, ...\\]\\)" +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +msgid ":py:obj:`parameters `\\" msgstr "" -"Flower 1.0 : ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.driver.driver.Driver:1 of -msgid "`Driver` class provides an interface to the Driver API." +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +msgid ":py:obj:`config `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`History `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.FitRes.rst:2 +msgid "FitRes" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.history.History:1 of -msgid "History class for training and/or evaluation metrics collection." +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`status `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid "" -":py:obj:`LegacyContext `\\ \\(state\\[\\, " -"config\\, strategy\\, ...\\]\\)" +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`parameters `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.compat.legacy_context.LegacyContext:1 of -msgid "Legacy Context." +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`num_examples `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid "" -":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " -"strategy\\]\\)" +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`metrics `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#, fuzzy -msgid "" -":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " -"strategy\\, ...\\]\\)" -msgstr "serveur.stratégie.Stratégie" - -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_app.ServerApp:1 of +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 #, fuzzy -msgid "Flower ServerApp." -msgstr "Serveur de Flower" +msgid "GetParametersIns" +msgstr ":code:`get_parameters`" -#: ../../source/ref-api/flwr.server.rst:41::1 -#, fuzzy -msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," -" round\\_timeout\\]\\)" +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 +msgid ":py:obj:`config `\\" msgstr "" -"Flower 1.0 : ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_config.ServerConfig:1 of +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 #, fuzzy -msgid "Flower server config." -msgstr "Serveur de Flower" +msgid "GetParametersRes" +msgstr ":code:`get_parameters`" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +msgid ":py:obj:`status `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.SimpleClientManager:1 of -msgid "Provides a pool of available clients." +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +msgid ":py:obj:`parameters `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#, fuzzy -msgid ":py:obj:`flwr.server.strategy `\\" -msgstr "serveur.stratégie.Stratégie" +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 +msgid "GetPropertiesIns" +msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.strategy:1 of -msgid "Contains the strategy abstraction and different implementations." +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 +msgid ":py:obj:`config `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#, fuzzy -msgid ":py:obj:`flwr.server.workflow `\\" -msgstr "serveur.stratégie.Stratégie" +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 +msgid "GetPropertiesRes" +msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.workflow:1 of -#, fuzzy -msgid "Workflows." -msgstr "Flux de travail" - -#: ../../source/ref-api/flwr.server.ClientManager.rst:2 -#, fuzzy -msgid "ClientManager" -msgstr "client" +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +msgid ":py:obj:`status `\\" +msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`all `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +msgid ":py:obj:`properties `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1 -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.all:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "Return all available clients." +#: ../../source/ref-api/flwr.common.Message.rst:2 +#, fuzzy +msgid "Message" +msgstr "Côté serveur" + +#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 +#: flwr.common.message.Message:3 of +msgid "A dataclass including information about the message to be executed." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`num_available `\\ \\(\\)" +#: flwr.common.message.Message:5 of +msgid "" +"Holds records either sent by another entity (e.g. sent by the server-side" +" logic to a client, or vice-versa) or that will be sent to it." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.num_available:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.num_available:1 of -msgid "Return the number of available clients." +#: flwr.common.message.Message:8 of +msgid "" +"A dataclass that captures information about an error that took place when" +" processing another message." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`register `\\ \\(client\\)" +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +msgid "" +":py:obj:`create_error_reply `\\ " +"\\(error\\[\\, ttl\\]\\)" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.register:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.register:1 of -msgid "Register Flower ClientProxy instance." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_error_reply:1 of +msgid "Construct a reply message indicating an error happened." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`create_reply `\\ " +"\\(content\\[\\, ttl\\]\\)" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.sample:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.sample:1 of -msgid "Sample a number of Flower ClientProxy instances." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_reply:1 of +msgid "Create a reply to this message with specified content and TTL." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`unregister `\\ \\(client\\)" +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +msgid ":py:obj:`has_content `\\ \\(\\)" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.unregister:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.unregister:1 of -msgid "Unregister Flower ClientProxy instance." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_content:1 of +msgid "Return True if message has content, else False." msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\, timeout\\)" +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +msgid ":py:obj:`has_error `\\ \\(\\)" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.wait_for:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of -msgid "Wait until at least `num_clients` are available." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_error:1 of +msgid "Return True if message has an error, else False." msgstr "" -#: flwr.server.client_manager.ClientManager.num_available:3 -#: flwr.server.client_manager.SimpleClientManager.num_available:3 of -msgid "**num_available** -- The number of currently available clients." +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`content `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.register:6 -#: flwr.server.client_manager.SimpleClientManager.register:6 of -msgid "" -"**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any " -"reason." +#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 +#: of +#, fuzzy +msgid "The content of this message." +msgstr "Évaluer la réponse d'un client." + +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`error `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.unregister:3 -#: flwr.server.client_manager.SimpleClientManager.unregister:3 of -msgid "This method is idempotent." +#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of +msgid "Error captured by this message." msgstr "" -#: ../../source/ref-api/flwr.server.Driver.rst:2 -#, fuzzy -msgid "Driver" -msgstr "serveur" +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`metadata `\\" +msgstr "" -#: flwr.server.driver.driver.Driver:3 of -msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:9091\"`." +#: flwr.common.message.Message.create_error_reply:3 of +msgid "The error that was encountered." msgstr "" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order: * CA certificate. * " -"server certificate. * server private key." +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " +"msg.meta.created_at)" msgstr "" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order:" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation:" msgstr "" -#: flwr.server.app.start_server:32 flwr.server.driver.driver.Driver:10 of -#, fuzzy -msgid "CA certificate." -msgstr "Certificats" +#: flwr.common.message.Message.create_error_reply:9 +#: flwr.common.message.Message.create_reply:13 of +msgid "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" +msgstr "" -#: flwr.server.app.start_server:33 flwr.server.driver.driver.Driver:11 of -#, fuzzy -msgid "server certificate." -msgstr "Certificats" +#: flwr.common.message.Message.create_reply:3 of +msgid "" +"The method generates a new `Message` as a reply to this message. It " +"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " +"this message and sets 'reply_to_message' to the ID of this message." +msgstr "" -#: flwr.server.app.start_server:34 flwr.server.driver.driver.Driver:12 of -#, fuzzy -msgid "server private key." -msgstr "stratégie.du.serveur" +#: flwr.common.message.Message.create_reply:7 of +msgid "The content for the reply message." +msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -#, fuzzy -msgid ":py:obj:`close `\\ \\(\\)" -msgstr "serveur.stratégie.Stratégie" +#: flwr.common.message.Message.create_reply:16 of +msgid "A new `Message` instance representing the reply." +msgstr "" -#: flwr.server.driver.driver.Driver.close:1 -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "Disconnect from the SuperLink if connected." +#: ../../source/ref-api/flwr.common.MessageType.rst:2 +msgid "MessageType" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "" -":py:obj:`create_message `\\ " -"\\(content\\, message\\_type\\, ...\\)" +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`EVALUATE `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.create_message:1 of -msgid "Create a new message with specified parameters." +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`QUERY `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid ":py:obj:`get_node_ids `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`TRAIN `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.get_node_ids:1 of -msgid "Get node IDs." +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 +msgid "MessageTypeLegacy" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "" -":py:obj:`pull_messages `\\ " -"\\(message\\_ids\\)" +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +msgid ":py:obj:`GET_PARAMETERS `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.pull_messages:1 of -msgid "Pull messages based on message IDs." +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +msgid ":py:obj:`GET_PROPERTIES `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "" -":py:obj:`push_messages `\\ " -"\\(messages\\)" +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of +msgid "An identifier for the current run." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.push_messages:1 of -msgid "Push messages to specified node IDs." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of +msgid "An identifier for the current message." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -#, fuzzy -msgid "" -":py:obj:`send_and_receive `\\ " -"\\(messages\\, \\*\\[\\, timeout\\]\\)" +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of +msgid "An identifier for the node sending this message." msgstr "" -"Flower 1.0 : ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.send_and_receive:1 of -msgid "Push messages to specified node IDs and pull the reply messages." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.dst_node_id:1 flwr.common.message.Metadata:9 of +msgid "An identifier for the node receiving this message." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:3 of -msgid "" -"This method constructs a new `Message` with given content and metadata. " -"The `run_id` and `src_node_id` will be set automatically." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of +msgid "An identifier for the message this message replies to." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:6 of +#: flwr.common.message.Metadata:13 of msgid "" -"The content for the new message. This holds records that are to be sent " -"to the destination node." +"An identifier for grouping messages. In some settings, this is used as " +"the FL round." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:9 of -msgid "" -"The type of the message, defining the action to be executed on the " -"receiving end." +#: flwr.common.message.Metadata:16 of +msgid "Time-to-live for this message in seconds." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:12 of -msgid "The ID of the destination node to which the message is being sent." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of +msgid "A string that encodes the action to be executed on the receiving end." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:14 of +#: flwr.common.message.Metadata:21 of msgid "" -"The ID of the group to which this message is associated. In some " -"settings, this is used as the FL round." +"An identifier that can be used when loading a particular data partition " +"for a ClientApp. Making use of this identifier is more relevant when " +"conducting simulations." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:17 of -msgid "" -"Time-to-live for the round trip of this message, i.e., the time from " -"sending this message to receiving a reply. It specifies the duration for " -"which the message and its potential reply are considered valid." +#: flwr.common.Metadata.created_at:1::1 of +#, fuzzy +msgid ":py:obj:`created_at `\\" +msgstr "serveur.stratégie.Stratégie" + +#: flwr.common.Metadata.created_at:1 +#: flwr.common.Metadata.created_at:1::1 of +msgid "Unix timestamp when the message was created." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:22 of -msgid "" -"**message** -- A new `Message` instance with the specified content and " -"metadata." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`dst_node_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:3 of -msgid "" -"This method is used to collect messages from the SuperLink that " -"correspond to a set of given message IDs." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`group_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:6 of -msgid "An iterable of message IDs for which reply messages are to be retrieved." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.group_id:1 of +msgid "An identifier for grouping messages." msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:9 of -msgid "**messages** -- An iterable of messages received." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`message_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:3 of -msgid "" -"This method takes an iterable of messages and sends each message to the " -"node specified in `dst_node_id`." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`message_type `\\" msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:6 -#: flwr.server.driver.driver.Driver.send_and_receive:7 of -msgid "An iterable of messages to be sent." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`partition_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:9 of -msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, " -"which can be used to pull replies." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.partition_id:1 of +msgid "An identifier telling which data partition a ClientApp should use." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:3 of -msgid "" -"This method sends a list of messages to their destination node IDs and " -"then waits for the replies. It continues to pull replies until either all" -" replies are received or the specified timeout duration is exceeded." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`reply_to_message `\\" msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:9 of -msgid "" -"The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the " -"method will wait until replies for all messages are received." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`run_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:14 of -msgid "**replies** -- An iterable of reply messages received from the SuperLink." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`src_node_id `\\" msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -#, fuzzy -msgid "Notes" -msgstr "Aucun" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`ttl `\\" +msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:19 of -msgid "" -"This method uses `push_messages` to send the messages and `pull_messages`" -" to collect the replies. If `timeout` is set, the method may not return " -"replies for all sent messages. A message remains valid until its TTL, " -"which is not affected by `timeout`." +#: flwr.common.Metadata.created_at:1::1 flwr.common.Metadata.ttl:1 +#: of +msgid "Time-to-live for this message." msgstr "" -#: ../../source/ref-api/flwr.server.History.rst:2 -msgid "History" +#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 +msgid "MetricsRecord" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: flwr.common.record.metricsrecord.MetricsRecord:1 of msgid "" -":py:obj:`add_loss_centralized " -"`\\ \\(server\\_round\\, " -"loss\\)" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " +":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" +" [:py:class:`float`]]" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1 -#: flwr.server.history.History.add_loss_centralized:1::1 of -#, fuzzy -msgid "Add one loss entry (from centralized evaluation)." -msgstr "Évaluation centralisée" - -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_loss_distributed " -"`\\ \\(server\\_round\\, " -"loss\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_loss_distributed:1 of -msgid "Add one loss entry (from distributed evaluation)." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_metrics_centralized " -"`\\ \\(server\\_round\\, " -"metrics\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_centralized:1 of -#, fuzzy -msgid "Add metrics entries (from centralized evaluation)." -msgstr "Évaluation centralisée" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`items `\\ \\(\\)" +msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_metrics_distributed " -"`\\ \\(server\\_round\\, " -"metrics\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`keys `\\ \\(\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed:1 of -msgid "Add metrics entries (from distributed evaluation)." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" -":py:obj:`add_metrics_distributed_fit " -"`\\ \\(server\\_round\\," -" ...\\)" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed_fit:1 of -msgid "Add metrics entries (from distributed fit)." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`values `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 -msgid "LegacyContext" +#: ../../source/ref-api/flwr.common.NDArray.rst:2 +msgid "NDArray" msgstr "" -#: flwr.server.compat.legacy_context.LegacyContext:1 of -msgid "Bases: :py:class:`~flwr.common.context.Context`" +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +msgid ":py:obj:`tensors `\\" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -#, fuzzy -msgid ":py:obj:`config `\\" -msgstr "serveur.stratégie.Stratégie" - -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -#, fuzzy -msgid ":py:obj:`strategy `\\" -msgstr "serveur.stratégie.Stratégie" - -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`client_manager `\\" +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +msgid ":py:obj:`tensor_type `\\" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -#, fuzzy -msgid ":py:obj:`history `\\" -msgstr "serveur.stratégie.Stratégie" - -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 #, fuzzy -msgid ":py:obj:`state `\\" -msgstr "serveur.stratégie.Stratégie" - -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`client_manager `\\ \\(\\)" -msgstr "" - -#: flwr.server.server.Server.client_manager:1 -#: flwr.server.server.Server.client_manager:1::1 of -msgid "Return ClientManager." -msgstr "" +msgid "ParametersRecord" +msgstr "Paramètres du modèle." -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "" -":py:obj:`disconnect_all_clients " -"`\\ \\(timeout\\)" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.disconnect_all_clients:1 of -msgid "Send shutdown signal to all clients." +#: flwr.common.record.parametersrecord.ParametersRecord:3 of +msgid "" +"A dataclass storing named Arrays in order. This means that it holds " +"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " +"viewed as an equivalent to PyTorch's state_dict, but holding serialised " +"tensors instead." msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid "" -":py:obj:`evaluate_round `\\ " -"\\(server\\_round\\, timeout\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.evaluate_round:1 of -msgid "Validate current global model on a number of clients." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit:1 of -msgid "Run federated averaging for a number of rounds." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`items `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\," -" timeout\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`keys `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit_round:1 of -msgid "Perform a single round of federated averaging." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" -":py:obj:`set_max_workers `\\ " -"\\(max\\_workers\\)" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_max_workers:1 of -msgid "Set the max_workers used by ThreadPoolExecutor." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`values `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of +msgid "" +"Note that a small amount of Bytes might also be included in this counting" +" that correspond to metadata of the serialized object (e.g. of NumPy " +"array) needed for deseralization." msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_strategy:1 of +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 #, fuzzy -msgid "Replace server strategy." -msgstr "stratégie.du.serveur" +msgid "ReconnectIns" +msgstr "Collecte centralisée des données" -#: ../../source/ref-api/flwr.server.ServerApp.rst:2 -#, fuzzy -msgid "ServerApp" -msgstr "serveur" +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 +msgid ":py:obj:`seconds `\\" +msgstr "" -#: flwr.server.server_app.ServerApp:5 of -#, fuzzy -msgid "Use the `ServerApp` with an existing `Strategy`:" -msgstr "Utilise une stratégie existante" +#: ../../source/ref-api/flwr.common.RecordSet.rst:2 +msgid "RecordSet" +msgstr "" -#: flwr.server.server_app.ServerApp:15 of -msgid "Use the `ServerApp` with a custom main function:" +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`configs_records `\\" msgstr "" -#: flwr.server.server_app.ServerApp.main:1::1 of -#, fuzzy -msgid ":py:obj:`main `\\ \\(\\)" -msgstr "serveur.stratégie.Stratégie" +#: flwr.common.RecordSet.configs_records:1 +#: flwr.common.RecordSet.configs_records:1::1 of +msgid "Dictionary holding ConfigsRecord instances." +msgstr "" -#: flwr.server.server_app.ServerApp.main:1 -#: flwr.server.server_app.ServerApp.main:1::1 of -msgid "Return a decorator that registers the main fn with the server app." +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`metrics_records `\\" msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.metrics_records:1 of +msgid "Dictionary holding MetricsRecord instances." +msgstr "" + +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`parameters_records `\\" +msgstr "" + +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.parameters_records:1 of +msgid "Dictionary holding ParametersRecord instances." +msgstr "" + +#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 #, fuzzy -msgid "ServerConfig" -msgstr "serveur" +msgid "ServerMessage" +msgstr "Côté serveur" -#: flwr.server.server_config.ServerConfig:3 of -msgid "" -"All attributes have default values which allows users to configure just " -"the ones they care about." +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid ":py:obj:`evaluate_ins `\\" msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 -msgid ":py:obj:`num_rounds `\\" +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid ":py:obj:`fit_ins `\\" msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 -msgid ":py:obj:`round_timeout `\\" +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid "" +":py:obj:`get_parameters_ins " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 -msgid "SimpleClientManager" +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid "" +":py:obj:`get_properties_ins " +"`\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager:1 of -msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" +#: ../../source/ref-api/flwr.common.Status.rst:2 +#, fuzzy +msgid "Status" +msgstr "Statut du client." + +#: ../../source/ref-api/flwr.common.Status.rst:29::1 +msgid ":py:obj:`code `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid ":py:obj:`all `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.Status.rst:29::1 +msgid ":py:obj:`message `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`num_available `\\" -" \\(\\)" +#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 +msgid "array\\_from\\_numpy" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`register `\\ " -"\\(client\\)" +#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 +msgid "bytes\\_to\\_ndarray" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +#: ../../source/ref-api/flwr.common.configure.rst:2 +#, fuzzy +msgid "configure" +msgstr "Configurer les clients" + +#: ../../source/ref-api/flwr.common.event.rst:2 +msgid "event" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`unregister `\\ " -"\\(client\\)" +#: ../../source/ref-api/flwr.common.log.rst:2 +msgid "log" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: logging.Logger.log:3 of msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\[\\, timeout\\]\\)" +"To pass exception information, use the keyword argument exc_info with a " +"true value, e.g." msgstr "" +"Pour transmettre des informations sur les exceptions, utilise l'argument " +"mot-clé exc_info avec une valeur vraie, par ex." -#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of -msgid "" -"Blocks until the requested number of clients is available or until a " -"timeout is reached. Current timeout default: 1 day." +#: logging.Logger.log:6 of +#, python-format +msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" +msgstr "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" + +#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 +msgid "ndarray\\_to\\_bytes" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of -msgid "The number of clients to wait for." +#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 +msgid "ndarrays\\_to\\_parameters" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of -msgid "The time in seconds to wait for, defaults to 86400 (24h)." +#: ../../source/ref-api/flwr.common.now.rst:2 +msgid "now" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of -msgid "**success**" +#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 +msgid "parameters\\_to\\_ndarrays" msgstr "" -#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 -#, fuzzy -msgid "run\\_driver\\_api" -msgstr "flower-driver-api" +#: ../../source/ref-api/flwr.server.rst:2 +msgid "server" +msgstr "serveur" -#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 -msgid "run\\_fleet\\_api" +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_driver_api `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.run_server_app.rst:2 -msgid "run\\_server\\_app" +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_driver_api:1 of +#, fuzzy +msgid "Run Flower server (Driver API)." +msgstr "flower-driver-api" + +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_fleet_api `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.run_superlink.rst:2 +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_fleet_api:1 of #, fuzzy -msgid "run\\_superlink" -msgstr "flower-superlink" +msgid "Run Flower server (Fleet API)." +msgstr "flower-fleet-api" + +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_server_app `\\ \\(\\)" +msgstr "" -#: ../../source/ref-api/flwr.server.start_driver.rst:2 +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.run_serverapp.run_server_app:1 of #, fuzzy -msgid "start\\_driver" -msgstr "start_client" +msgid "Run Flower server app." +msgstr "Serveur de Flower" -#: flwr.server.compat.app.start_driver:3 of -msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:8080\"`." +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr "" -#: flwr.server.compat.app.start_driver:6 of -msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_driver` will create one." -msgstr "" +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_superlink:1 of +#, fuzzy +msgid "Run Flower SuperLink (Driver API and Fleet API)." +msgstr "flower-fleet-api" -#: flwr.server.app.start_server:9 flwr.server.compat.app.start_driver:10 -#: flwr.simulation.app.start_simulation:28 of +#: ../../source/ref-api/flwr.server.rst:26::1 msgid "" -"Currently supported values are `num_rounds` (int, default: 1) and " -"`round_timeout` in seconds (float, default: None)." +":py:obj:`start_server `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" msgstr "" -#: flwr.server.app.start_server:12 flwr.server.compat.app.start_driver:13 of -msgid "" -"An implementation of the abstract base class " -"`flwr.server.strategy.Strategy`. If no strategy is provided, then " -"`start_server` will use `flwr.server.strategy.FedAvg`." +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.start_server:1 of +msgid "Start a Flower server using the gRPC transport layer." msgstr "" -#: flwr.server.compat.app.start_driver:17 of -msgid "" -"An implementation of the class `flwr.server.ClientManager`. If no " -"implementation is provided, then `start_driver` will use " -"`flwr.server.SimpleClientManager`." +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr "" -#: flwr.server.compat.app.start_driver:25 of -msgid "The Driver object to use." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.ClientManager:1 of +msgid "Abstract base class for managing Flower clients." msgstr "" -#: flwr.server.app.start_server:37 flwr.server.compat.app.start_driver:28 of -msgid "**hist** -- Object containing training and evaluation metrics." -msgstr "" +#: ../../source/ref-api/flwr.server.rst:40::1 +#, fuzzy +msgid ":py:obj:`Driver `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: flwr.server.compat.app.start_driver:33 of -msgid "Starting a driver that connects to an insecure server:" +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.driver.driver.Driver:1 of +msgid "Abstract base Driver class for the Driver API." msgstr "" -#: flwr.server.compat.app.start_driver:37 of -msgid "Starting a driver that connects to an SSL-enabled server:" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`History `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.start_server.rst:2 -#, fuzzy -msgid "start\\_server" -msgstr "serveur.start_server" - -#: flwr.server.app.start_server:3 of -msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.history.History:1 of +msgid "History class for training and/or evaluation metrics collection." msgstr "" -#: flwr.server.app.start_server:5 of +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_server` will create one." +":py:obj:`LegacyContext `\\ \\(state\\[\\, " +"config\\, strategy\\, ...\\]\\)" msgstr "" -#: flwr.server.app.start_server:16 of -msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_server` will use " -"`flwr.server.client_manager.SimpleClientManager`." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.compat.legacy_context.LegacyContext:1 of +msgid "Legacy Context." msgstr "" -#: flwr.server.app.start_server:21 of +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" clients. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower clients need to be started with the same value (see " -"`flwr.client.start_client`), otherwise clients will not know about the " -"increased limit and block larger messages." +":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " +"strategy\\]\\)" msgstr "" -#: flwr.server.app.start_server:42 of +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy -msgid "Starting an insecure server:" -msgstr "Démarrer le serveur" +msgid "" +":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " +"strategy\\, ...\\]\\)" +msgstr "serveur.stratégie.Stratégie" -#: flwr.server.app.start_server:46 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_app.ServerApp:1 of #, fuzzy -msgid "Starting an SSL-enabled server:" -msgstr "Démarrer le serveur" +msgid "Flower ServerApp." +msgstr "Serveur de Flower" -#: ../../source/ref-api/flwr.server.strategy.rst:2 +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy -msgid "strategy" -msgstr "stratégie.du.serveur" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," +" round\\_timeout\\]\\)" msgstr "" +"Flower 1.0 : ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.bulyan.Bulyan:1 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_config.ServerConfig:1 of #, fuzzy -msgid "Bulyan strategy." -msgstr "Stratégies intégrées" +msgid "Flower server config." +msgstr "Serveur de Flower" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DPFedAvgAdaptive `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\)" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of -msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.SimpleClientManager:1 of +msgid "Provides a pool of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DPFedAvgFixed `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" -msgstr "" +#: ../../source/ref-api/flwr.server.rst:59::1 +#, fuzzy +msgid ":py:obj:`flwr.server.strategy `\\" +msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of -msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.strategy:1 of +msgid "Contains the strategy abstraction and different implementations." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +#: ../../source/ref-api/flwr.server.rst:59::1 +#, fuzzy +msgid ":py:obj:`flwr.server.workflow `\\" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.workflow:1 of +#, fuzzy +msgid "Workflows." +msgstr "Flux de travail" + +#: ../../source/ref-api/flwr.server.ClientManager.rst:2 +#, fuzzy +msgid "ClientManager" +msgstr "client" + +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`all `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 -#: of -msgid "Strategy wrapper for central DP with client-side adaptive clipping." +#: flwr.server.client_manager.ClientManager.all:1 +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.all:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "Return all available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`num_available `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 -#: of -msgid "Strategy wrapper for central DP with server-side adaptive clipping." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.num_available:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.num_available:1 of +msgid "Return the number of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping " -"`\\ " -"\\(...\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`register `\\ \\(client\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 -#: of -msgid "Strategy wrapper for central DP with client-side fixed clipping." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.register:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.register:1 of +msgid "Register Flower ClientProxy instance." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 -#: of -msgid "Strategy wrapper for central DP with server-side fixed clipping." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.sample:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.sample:1 of +msgid "Sample a number of Flower ClientProxy instances." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`unregister `\\ \\(client\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of -#, fuzzy -msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.unregister:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.unregister:1 of +msgid "Unregister Flower ClientProxy instance." msgstr "" -"`FedAdam` et `FedAdam` correspondent à la dernière version de l'article " -"sur l'optimisation fédérée adaptative." -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`FedAdam `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\, timeout\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadam.FedAdam:1 of -msgid "FedAdam - Adaptive Federated Optimization using Adam." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.wait_for:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of +msgid "Wait until at least `num_clients` are available." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.num_available:3 +#: flwr.server.client_manager.SimpleClientManager.num_available:3 of +msgid "**num_available** -- The number of currently available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavg.FedAvg:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of -#, fuzzy -msgid "Federated Averaging strategy." -msgstr "Stratégie de moyenne fédérée." - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.register:6 +#: flwr.server.client_manager.SimpleClientManager.register:6 of msgid "" -":py:obj:`FedAvgAndroid `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +"**success** -- Indicating if registration was successful. False if " +"ClientProxy is already registered or can not be registered for any " +"reason." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.unregister:3 +#: flwr.server.client_manager.SimpleClientManager.unregister:3 of +msgid "This method is idempotent." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavgm.FedAvgM:1 of +#: ../../source/ref-api/flwr.server.Driver.rst:2 #, fuzzy -msgid "Federated Averaging with Momentum strategy." -msgstr "Stratégie de moyenne fédérée." +msgid "Driver" +msgstr "serveur" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of +#, fuzzy msgid "" -":py:obj:`FedMedian `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`create_message `\\ " +"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" +"Flower 1.0 : ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedmedian.FedMedian:1 of -#, fuzzy -msgid "Configurable FedMedian strategy implementation." -msgstr "Configuration de l'évaluation fédérée" +#: flwr.server.driver.driver.Driver.create_message:1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid "Create a new message with specified parameters." +msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedOpt `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid ":py:obj:`get_node_ids `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedopt.FedOpt:1 of -#, fuzzy -msgid "Federated Optim strategy." -msgstr "Stratégie de moyenne fédérée." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.get_node_ids:1 of +msgid "Get node IDs." +msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`FedProx `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`pull_messages `\\ " +"\\(message\\_ids\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedprox.FedProx:1 of -#, fuzzy -msgid "Federated Optimization strategy." -msgstr "Stratégie de moyenne fédérée." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.pull_messages:1 of +msgid "Pull messages based on message IDs." +msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`FedTrimmedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`push_messages `\\ " +"\\(messages\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of -msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.push_messages:1 of +msgid "Push messages to specified node IDs." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of +#, fuzzy msgid "" -":py:obj:`FedXgbBagging `\\ " -"\\(\\[evaluate\\_function\\]\\)" +":py:obj:`send_and_receive `\\ " +"\\(messages\\, \\*\\[\\, timeout\\]\\)" msgstr "" +"Flower 1.0 : ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of -msgid "Configurable FedXgbBagging strategy implementation." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.send_and_receive:1 of +msgid "Push messages to specified node IDs and pull the reply messages." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:3 of msgid "" -":py:obj:`FedXgbCyclic `\\ " -"\\(\\*\\*kwargs\\)" +"This method constructs a new `Message` with given content and metadata. " +"The `run_id` and `src_node_id` will be set automatically." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of -msgid "Configurable FedXgbCyclic strategy implementation." +#: flwr.server.driver.driver.Driver.create_message:6 of +msgid "" +"The content for the new message. This holds records that are to be sent " +"to the destination node." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:9 of msgid "" -":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " -"\\*\\*kwargs\\)" +"The type of the message, defining the action to be executed on the " +"receiving end." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of -msgid "Configurable FedXgbNnAvg strategy implementation." +#: flwr.server.driver.driver.Driver.create_message:12 of +msgid "The ID of the destination node to which the message is being sent." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:14 of msgid "" -":py:obj:`FedYogi `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +"The ID of the group to which this message is associated. In some " +"settings, this is used as the FL round." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedyogi.FedYogi:1 of -msgid "FedYogi [Reddi et al., 2020] strategy." +#: flwr.server.driver.driver.Driver.create_message:17 of +msgid "" +"Time-to-live for the round trip of this message, i.e., the time from " +"sending this message to receiving a reply. It specifies in seconds the " +"duration for which the message and its potential reply are considered " +"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " +"used." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:23 of msgid "" -":py:obj:`FaultTolerantFedAvg " -"`\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +"**message** -- A new `Message` instance with the specified content and " +"metadata." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of -msgid "Configurable fault-tolerant FedAvg strategy implementation." +#: flwr.server.driver.driver.Driver.pull_messages:3 of +msgid "" +"This method is used to collect messages from the SuperLink that " +"correspond to a set of given message IDs." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +#: flwr.server.driver.driver.Driver.pull_messages:6 of +msgid "An iterable of message IDs for which reply messages are to be retrieved." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.krum.Krum:1 of -msgid "Krum [Blanchard et al., 2017] strategy." +#: flwr.server.driver.driver.Driver.pull_messages:9 of +msgid "**messages** -- An iterable of messages received." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.push_messages:3 of msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " -"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" +"This method takes an iterable of messages and sends each message to the " +"node specified in `dst_node_id`." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.qfedavg.QFedAvg:1 of -msgid "Configurable QFedAvg strategy implementation." +#: flwr.server.driver.driver.Driver.push_messages:6 +#: flwr.server.driver.driver.Driver.send_and_receive:7 of +msgid "An iterable of messages to be sent." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#, fuzzy -msgid ":py:obj:`Strategy `\\ \\(\\)" -msgstr "serveur.stratégie.Stratégie" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.strategy.Strategy:1 of -msgid "Abstract base class for server strategy implementations." +#: flwr.server.driver.driver.Driver.push_messages:9 of +msgid "" +"**message_ids** -- An iterable of IDs for the messages that were sent, " +"which can be used to pull replies." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Bulyan.rst:2 -msgid "Bulyan" +#: flwr.server.driver.driver.Driver.send_and_receive:3 of +msgid "" +"This method sends a list of messages to their destination node IDs and " +"then waits for the replies. It continues to pull replies until either all" +" replies are received or the specified timeout duration is exceeded." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 -#: flwr.server.strategy.fedavgm.FedAvgM:1 -#: flwr.server.strategy.fedmedian.FedMedian:1 -#: flwr.server.strategy.fedopt.FedOpt:1 flwr.server.strategy.fedprox.FedProx:1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 -#: flwr.server.strategy.krum.Krum:1 flwr.server.strategy.qfedavg.QFedAvg:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.fedavg.FedAvg`" +#: flwr.server.driver.driver.Driver.send_and_receive:9 of +msgid "" +"The timeout duration in seconds. If specified, the method will wait for " +"replies for this duration. If `None`, there is no time limit and the " +"method will wait until replies for all messages are received." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:3 of -msgid "Implementation based on https://arxiv.org/abs/1802.07927." +#: flwr.server.driver.driver.Driver.send_and_receive:14 of +msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:5 -#: flwr.server.strategy.fedadagrad.FedAdagrad:5 -#: flwr.server.strategy.fedadam.FedAdam:5 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:5 -#: flwr.server.strategy.fedavgm.FedAvgM:5 flwr.server.strategy.fedopt.FedOpt:5 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:5 -#: flwr.server.strategy.fedyogi.FedYogi:5 flwr.server.strategy.krum.Krum:5 of -msgid "Fraction of clients used during training. Defaults to 1.0." -msgstr "" +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +#, fuzzy +msgid "Notes" +msgstr "Aucun" -#: flwr.server.strategy.bulyan.Bulyan:7 -#: flwr.server.strategy.fedadagrad.FedAdagrad:7 -#: flwr.server.strategy.fedadam.FedAdam:7 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:7 -#: flwr.server.strategy.fedavgm.FedAvgM:7 flwr.server.strategy.fedopt.FedOpt:7 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:7 -#: flwr.server.strategy.fedyogi.FedYogi:7 flwr.server.strategy.krum.Krum:7 of -msgid "Fraction of clients used during validation. Defaults to 1.0." +#: flwr.server.driver.driver.Driver.send_and_receive:19 of +msgid "" +"This method uses `push_messages` to send the messages and `pull_messages`" +" to collect the replies. If `timeout` is set, the method may not return " +"replies for all sent messages. A message remains valid until its TTL, " +"which is not affected by `timeout`." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:9 -#: flwr.server.strategy.fedadagrad.FedAdagrad:9 -#: flwr.server.strategy.fedadam.FedAdam:9 flwr.server.strategy.fedavg.FedAvg:13 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:9 -#: flwr.server.strategy.fedavgm.FedAvgM:9 flwr.server.strategy.fedopt.FedOpt:9 -#: flwr.server.strategy.fedprox.FedProx:45 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:9 -#: flwr.server.strategy.fedyogi.FedYogi:9 flwr.server.strategy.krum.Krum:9 of -msgid "Minimum number of clients used during training. Defaults to 2." +#: ../../source/ref-api/flwr.server.History.rst:2 +msgid "History" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:11 -#: flwr.server.strategy.fedadagrad.FedAdagrad:11 -#: flwr.server.strategy.fedadam.FedAdam:11 -#: flwr.server.strategy.fedavg.FedAvg:15 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:11 -#: flwr.server.strategy.fedavgm.FedAvgM:11 -#: flwr.server.strategy.fedopt.FedOpt:11 -#: flwr.server.strategy.fedprox.FedProx:47 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:11 -#: flwr.server.strategy.fedyogi.FedYogi:11 flwr.server.strategy.krum.Krum:11 of -msgid "Minimum number of clients used during validation. Defaults to 2." +#: flwr.server.history.History.add_loss_centralized:1::1 of +msgid "" +":py:obj:`add_loss_centralized " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:13 -#: flwr.server.strategy.fedadagrad.FedAdagrad:13 -#: flwr.server.strategy.fedadam.FedAdam:13 -#: flwr.server.strategy.fedavg.FedAvg:17 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:13 -#: flwr.server.strategy.fedavgm.FedAvgM:13 -#: flwr.server.strategy.fedopt.FedOpt:13 -#: flwr.server.strategy.fedprox.FedProx:49 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:13 -#: flwr.server.strategy.fedyogi.FedYogi:13 flwr.server.strategy.krum.Krum:13 of -msgid "Minimum number of total clients in the system. Defaults to 2." -msgstr "" +#: flwr.server.history.History.add_loss_centralized:1 +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "Add one loss entry (from centralized evaluation)." +msgstr "Évaluation centralisée" -#: flwr.server.strategy.bulyan.Bulyan:15 flwr.server.strategy.krum.Krum:15 of -msgid "Number of malicious clients in the system. Defaults to 0." +#: flwr.server.history.History.add_loss_centralized:1::1 of +msgid "" +":py:obj:`add_loss_distributed " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:17 -#: flwr.server.strategy.fedadagrad.FedAdagrad:15 -#: flwr.server.strategy.fedadam.FedAdam:15 -#: flwr.server.strategy.fedavg.FedAvg:19 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:15 -#: flwr.server.strategy.fedavgm.FedAvgM:15 -#: flwr.server.strategy.fedopt.FedOpt:15 -#: flwr.server.strategy.fedprox.FedProx:51 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:15 -#: flwr.server.strategy.fedyogi.FedYogi:17 -#: flwr.server.strategy.fedyogi.FedYogi:18 -#: flwr.server.strategy.fedyogi.FedYogi:19 flwr.server.strategy.krum.Krum:20 of -msgid "Optional function used for validation. Defaults to None." +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_loss_distributed:1 of +msgid "Add one loss entry (from distributed evaluation)." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:19 -#: flwr.server.strategy.fedadagrad.FedAdagrad:17 -#: flwr.server.strategy.fedadam.FedAdam:17 -#: flwr.server.strategy.fedavg.FedAvg:21 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:17 -#: flwr.server.strategy.fedavgm.FedAvgM:17 -#: flwr.server.strategy.fedopt.FedOpt:17 -#: flwr.server.strategy.fedprox.FedProx:53 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:17 -#: flwr.server.strategy.fedyogi.FedYogi:20 flwr.server.strategy.krum.Krum:22 of -msgid "Function used to configure training. Defaults to None." +#: flwr.server.history.History.add_loss_centralized:1::1 of +msgid "" +":py:obj:`add_metrics_centralized " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:21 -#: flwr.server.strategy.fedadagrad.FedAdagrad:19 -#: flwr.server.strategy.fedadam.FedAdam:19 -#: flwr.server.strategy.fedavg.FedAvg:23 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:19 -#: flwr.server.strategy.fedavgm.FedAvgM:19 -#: flwr.server.strategy.fedopt.FedOpt:19 -#: flwr.server.strategy.fedprox.FedProx:55 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:19 -#: flwr.server.strategy.fedyogi.FedYogi:22 flwr.server.strategy.krum.Krum:24 of -msgid "Function used to configure validation. Defaults to None." -msgstr "" +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_centralized:1 of +#, fuzzy +msgid "Add metrics entries (from centralized evaluation)." +msgstr "Évaluation centralisée" -#: flwr.server.strategy.bulyan.Bulyan:23 -#: flwr.server.strategy.fedadagrad.FedAdagrad:25 -#: flwr.server.strategy.fedadam.FedAdam:21 -#: flwr.server.strategy.fedavg.FedAvg:25 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:21 -#: flwr.server.strategy.fedavgm.FedAvgM:21 -#: flwr.server.strategy.fedopt.FedOpt:21 -#: flwr.server.strategy.fedprox.FedProx:57 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:21 -#: flwr.server.strategy.fedyogi.FedYogi:24 flwr.server.strategy.krum.Krum:26 of -msgid "Whether or not accept rounds containing failures. Defaults to True." +#: flwr.server.history.History.add_loss_centralized:1::1 of +msgid "" +":py:obj:`add_metrics_distributed " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:25 -#: flwr.server.strategy.fedadagrad.FedAdagrad:27 -#: flwr.server.strategy.fedadam.FedAdam:23 -#: flwr.server.strategy.fedavg.FedAvg:27 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:24 -#: flwr.server.strategy.fedavgm.FedAvgM:23 -#: flwr.server.strategy.fedopt.FedOpt:23 -#: flwr.server.strategy.fedprox.FedProx:59 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:23 -#: flwr.server.strategy.fedyogi.FedYogi:26 flwr.server.strategy.krum.Krum:28 of -#, fuzzy -msgid "Initial global model parameters." -msgstr "Initialise le modèle global" +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed:1 of +msgid "Add metrics entries (from distributed evaluation)." +msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:27 of +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of " -"the Bulyan (e.g., Krum)" +":py:obj:`add_metrics_distributed_fit " +"`\\ \\(server\\_round\\," +" ...\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:29 of -msgid "arguments to the first_aggregation rule" +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed_fit:1 of +msgid "Add metrics entries (from distributed fit)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 +msgid "LegacyContext" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.compat.legacy_context.LegacyContext:1 of +msgid "Bases: :py:class:`~flwr.common.context.Context`" +msgstr "" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 #, fuzzy -msgid "Aggregate evaluation losses using weighted average." -msgstr "Résultats globaux de l'évaluation." +msgid ":py:obj:`config `\\" +msgstr "serveur.stratégie.Stratégie" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`strategy `\\" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`client_manager `\\" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 #, fuzzy -msgid "Aggregate fit results using Bulyan." -msgstr "Résultats globaux de l'évaluation." +msgid ":py:obj:`history `\\" +msgstr "serveur.stratégie.Stratégie" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`state `\\" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.server.Server.rst:2 +msgid "Server" +msgstr "Serveur" + +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`client_manager `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_evaluate:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.configure_evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.configure_evaluate:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:1 of -#, fuzzy -msgid "Configure the next round of evaluation." -msgstr "Configuration de l'évaluation côté serveur" +#: flwr.server.server.Server.client_manager:1 +#: flwr.server.server.Server.client_manager:1::1 of +msgid "Return ClientManager." +msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`disconnect_all_clients " +"`\\ \\(timeout\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_fit:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_fit:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_fit:1 -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.configure_fit:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.configure_fit:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_fit:1 -#: flwr.server.strategy.fedprox.FedProx.configure_fit:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_fit:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.configure_fit:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.configure_fit:1 of -msgid "Configure the next round of training." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.disconnect_all_clients:1 of +msgid "Send shutdown signal to all clients." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate_round `\\ " +"\\(server\\_round\\, timeout\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.evaluate:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -msgid "Evaluate model parameters using an evaluation function." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.evaluate_round:1 of +msgid "Validate current global model on a number of clients." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.initialize_parameters:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.initialize_parameters:1 -#: flwr.server.strategy.fedavgm.FedAvgM.initialize_parameters:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -#, fuzzy -msgid "Initialize global model parameters." -msgstr "Initialise le modèle global" +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit:1 of +msgid "Run federated averaging for a number of rounds." +msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`fit_round `\\ \\(server\\_round\\," +" timeout\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.num_evaluation_clients:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_evaluation_clients:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.num_evaluation_clients:1 of -msgid "Use a fraction of available clients for evaluation." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit_round:1 of +msgid "Perform a single round of federated averaging." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`set_max_workers `\\ " +"\\(max\\_workers\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.num_fit_clients:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_fit_clients:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.num_fit_clients:1 of -msgid "Return the sample size and the required number of available clients." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_max_workers:1 of +msgid "Set the max_workers used by ThreadPoolExecutor." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DPFedAvgAdaptive.rst:2 -msgid "DPFedAvgAdaptive" -msgstr "DPFedAvgAdaptive" - -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:3 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:3 of -msgid "This class is deprecated and will be removed in a future release." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_strategy:1 of +#, fuzzy +msgid "Replace server strategy." +msgstr "stratégie.du.serveur" + +#: ../../source/ref-api/flwr.server.ServerApp.rst:2 +#, fuzzy +msgid "ServerApp" +msgstr "serveur" + +#: flwr.server.server_app.ServerApp:5 of +#, fuzzy +msgid "Use the `ServerApp` with an existing `Strategy`:" +msgstr "Utilise une stratégie existante" + +#: flwr.server.server_app.ServerApp:15 of +msgid "Use the `ServerApp` with a custom main function:" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +#: flwr.server.server_app.ServerApp.main:1::1 of +#, fuzzy +msgid ":py:obj:`main `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" + +#: flwr.server.server_app.ServerApp.main:1 +#: flwr.server.server_app.ServerApp.main:1::1 of +msgid "Return a decorator that registers the main fn with the server app." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 #, fuzzy -msgid "Aggregate evaluation losses using the given strategy." -msgstr "Résultats globaux de l'évaluation." +msgid "ServerConfig" +msgstr "serveur" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.server_config.ServerConfig:3 of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +"All attributes have default values which allows users to configure just " +"the ones they care about." msgstr "" -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "Aggregate training results as in DPFedAvgFixed and update clip norms." +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +msgid ":py:obj:`num_rounds `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +msgid ":py:obj:`round_timeout `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of -msgid "Configure the next round of evaluation using the specified strategy." +#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 +msgid "SimpleClientManager" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.client_manager.SimpleClientManager:1 of +msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid ":py:obj:`all `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "Evaluate model parameters using an evaluation function from the strategy." +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`num_available `\\" +" \\(\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`register `\\ " +"\\(client\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.initialize_parameters:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.initialize_parameters:1 of -msgid "Initialize global model parameters using given strategy." +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:3 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:6 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:3 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:3 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:3 -#: flwr.server.strategy.strategy.Strategy.configure_fit:3 -#: flwr.server.strategy.strategy.Strategy.evaluate:6 of -#, fuzzy -msgid "The current round of federated learning." -msgstr "Qu'est-ce que l'apprentissage fédéré ?" +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`unregister `\\ " +"\\(client\\)" +msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:7 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:10 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:7 -#: flwr.server.strategy.strategy.Strategy.configure_fit:7 -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:3 of -msgid "The client manager which holds all currently connected clients." +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\[\\, timeout\\]\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:10 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:10 of +#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of msgid "" -"**evaluate_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated evaluation." +"Blocks until the requested number of clients is available or until a " +"timeout is reached. Current timeout default: 1 day." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 -msgid "DPFedAvgFixed" -msgstr "DPFedAvgFixed" +#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of +msgid "The number of clients to wait for." +msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 -#: flwr.server.strategy.fedavg.FedAvg:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" +#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of +msgid "The time in seconds to wait for, defaults to 86400 (24h)." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of +msgid "**success**" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 +#, fuzzy +msgid "run\\_driver\\_api" +msgstr "flower-driver-api" + +#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 +msgid "run\\_fleet\\_api" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_fit:1 of -msgid "Aggregate training results using unweighted aggregation." +#: ../../source/ref-api/flwr.server.run_server_app.rst:2 +msgid "run\\_server\\_app" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.run_superlink.rst:2 +#, fuzzy +msgid "run\\_superlink" +msgstr "flower-superlink" + +#: ../../source/ref-api/flwr.server.start_server.rst:2 +#, fuzzy +msgid "start\\_server" +msgstr "serveur.start_server" + +#: flwr.server.app.start_server:3 of +msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.app.start_server:5 of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"A server implementation, either `flwr.server.Server` or a subclass " +"thereof. If no instance is provided, then `start_server` will create one." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of +#: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of msgid "" -"Configure the next round of training incorporating Differential Privacy " -"(DP)." +"Currently supported values are `num_rounds` (int, default: 1) and " +"`round_timeout` in seconds (float, default: None)." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.app.start_server:12 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +"An implementation of the abstract base class " +"`flwr.server.strategy.Strategy`. If no strategy is provided, then " +"`start_server` will use `flwr.server.strategy.FedAvg`." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.app.start_server:16 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_server` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of +#: flwr.server.app.start_server:21 of msgid "" -"Configuration of the next training round includes information related to " -"DP, such as clip norm and noise stddev." +"The maximum length of gRPC messages that can be exchanged with the Flower" +" clients. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower clients need to be started with the same value (see " +"`flwr.client.start_client`), otherwise clients will not know about the " +"increased limit and block larger messages." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 -#: flwr.server.strategy.strategy.Strategy.configure_fit:10 of +#: flwr.server.app.start_server:28 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `FitIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated learning." +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order: * CA certificate. * " +"server certificate. * server private key." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 -msgid "DifferentialPrivacyClientSideAdaptiveClipping" +#: flwr.server.app.start_server:28 of +msgid "" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order:" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:3 -#: of -msgid "Use `adaptiveclipping_mod` modifier at the client side." -msgstr "" +#: flwr.server.app.start_server:32 of +#, fuzzy +msgid "CA certificate." +msgstr "Certificats" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:5 -#: of -msgid "" -"In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " -"performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " -"happen on the client-side, usually by using the built-in " -"`adaptiveclipping_mod`." -msgstr "" +#: flwr.server.app.start_server:33 of +#, fuzzy +msgid "server certificate." +msgstr "Certificats" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:10 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:3 -#: of -msgid "The strategy to which DP functionalities will be added by this wrapper." +#: flwr.server.app.start_server:34 of +#, fuzzy +msgid "server private key." +msgstr "stratégie.du.serveur" + +#: flwr.server.app.start_server:37 of +msgid "**hist** -- Object containing training and evaluation metrics." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:12 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:5 -#: of -msgid "The noise multiplier for the Gaussian mechanism for model updates." -msgstr "" +#: flwr.server.app.start_server:42 of +#, fuzzy +msgid "Starting an insecure server:" +msgstr "Démarrer le serveur" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:14 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:7 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:17 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:10 -#: of -msgid "The number of clients that are sampled on each round." -msgstr "" +#: flwr.server.app.start_server:46 of +#, fuzzy +msgid "Starting an SSL-enabled server:" +msgstr "Démarrer le serveur" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:16 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:9 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:2 +#, fuzzy +msgid "strategy" +msgstr "stratégie.du.serveur" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"The initial value of clipping norm. Defaults to 0.1. Andrew et al. " -"recommends to set to 0.1." +":py:obj:`Bulyan `\\ \\(\\*\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 -#: of -msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.bulyan.Bulyan:1 of +#, fuzzy +msgid "Bulyan strategy." +msgstr "Stratégies intégrées" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. " -"Andrew et al. recommends to set to 0.2." +":py:obj:`DPFedAvgAdaptive `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 -#: of -msgid "" -"The stddev of the noise added to the count of updates currently below the" -" estimate. Andrew et al. recommends to set to `expected_num_records/20`" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:22 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:15 -#: of -#, fuzzy -msgid "Create a strategy:" -msgstr "stratégie.du.serveur" - -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"Wrap the strategy with the " -"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" +":py:obj:`DPFedAvgFixed `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 -#: of -msgid "On the client, add the `adaptiveclipping_mod` to the client-side mods:" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of +msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 #: of -msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +msgid "Strategy wrapper for central DP with client-side adaptive clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_fit:1 -#: of -#, fuzzy -msgid "Aggregate training results and update clip norms." -msgstr "Résultats globaux de l'évaluation." - -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 #: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +msgid "Strategy wrapper for central DP with server-side adaptive clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 #: of -msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +msgid "Strategy wrapper for central DP with client-side fixed clipping." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 -#, fuzzy -msgid "DifferentialPrivacyClientSideFixedClipping" -msgstr "Confidentialité différentielle" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`DifferentialPrivacyServerSideFixedClipping " +"`\\ " +"\\(...\\)" +msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:3 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 #: of -msgid "Use `fixedclipping_mod` modifier at the client side." +msgid "Strategy wrapper for central DP with server-side fixed clipping." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:5 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " -"performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `fixedclipping_mod`." +":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of +#, fuzzy +msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." +msgstr "" +"`FedAdam` et `FedAdam` correspondent à la dernière version de l'article " +"sur l'optimisation fédérée adaptative." + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A " -"value of 1.0 or higher is recommended for strong privacy." +":py:obj:`FedAdam `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -msgid "The value of the clipping norm." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadam.FedAdam:1 of +msgid "FedAdam - Adaptive Federated Optimization using Adam." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` " -"wrapper:" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:32 -#: of -msgid "On the client, add the `fixedclipping_mod` to the client-side mods:" -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavg.FedAvg:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +#, fuzzy +msgid "Federated Averaging strategy." +msgstr "Stratégie de moyenne fédérée." -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`FedAvgAndroid `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavgm.FedAvgM:1 of #, fuzzy -msgid "Add noise to the aggregated parameters." -msgstr "Puis sérialise le résultat agrégé :" +msgid "Federated Averaging with Momentum strategy." +msgstr "Stratégie de moyenne fédérée." -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`FedMedian `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedmedian.FedMedian:1 of +#, fuzzy +msgid "Configurable FedMedian strategy implementation." +msgstr "Configuration de l'évaluation fédérée" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedopt.FedOpt:1 of +#, fuzzy +msgid "Federated Optim strategy." +msgstr "Stratégie de moyenne fédérée." + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`FedProx `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 -msgid "DifferentialPrivacyServerSideAdaptiveClipping" -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedprox.FedProx:1 of +#, fuzzy +msgid "Federated Optimization strategy." +msgstr "Stratégie de moyenne fédérée." -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"The standard deviation of the noise added to the count of updates below " -"the estimate. Andrew et al. recommends to set to " -"`expected_num_records/20`" +":py:obj:`FedTrimmedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 -#: of -msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping " -"wrapper" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of +msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`FedXgbBagging `\\ " +"\\(\\[evaluate\\_function\\]\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of +msgid "Configurable FedXgbBagging strategy implementation." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`FedXgbCyclic `\\ " +"\\(\\*\\*kwargs\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of +msgid "Configurable FedXgbCyclic strategy implementation." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of +msgid "Configurable FedXgbNnAvg strategy implementation." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 -#, fuzzy -msgid "DifferentialPrivacyServerSideFixedClipping" -msgstr "Confidentialité différentielle" - -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " -"wrapper" +":py:obj:`FedYogi `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedyogi.FedYogi:1 of +msgid "FedYogi [Reddi et al., 2020] strategy." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" -msgstr "" - -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 -#: of -msgid "Compute the updates, clip, and pass them for aggregation." +":py:obj:`FaultTolerantFedAvg " +"`\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of +msgid "Configurable fault-tolerant FedAvg strategy implementation." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.krum.Krum:1 of +msgid "Krum [Blanchard et al., 2017] strategy." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " +"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 -#: of -msgid "Afterward, add noise to the aggregated parameters." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.qfedavg.QFedAvg:1 of +msgid "Configurable QFedAvg strategy implementation." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FaultTolerantFedAvg.rst:2 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy -msgid "FaultTolerantFedAvg" -msgstr "server.strategy.FaultTolerantFedAvg" - -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" -msgstr "" +msgid ":py:obj:`Strategy `\\ \\(\\)" +msgstr "serveur.stratégie.Stratégie" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.strategy.Strategy:1 of +msgid "Abstract base class for server strategy implementations." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 -#: flwr.server.strategy.fedadagrad.FedAdagrad.aggregate_fit:1 -#: flwr.server.strategy.fedadam.FedAdam.aggregate_fit:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_fit:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_fit:1 -#: flwr.server.strategy.fedavgm.FedAvgM.aggregate_fit:1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.aggregate_fit:1 -#: flwr.server.strategy.fedyogi.FedYogi.aggregate_fit:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_fit:1 of -msgid "Aggregate fit results using weighted average." +#: ../../source/ref-api/flwr.server.strategy.Bulyan.rst:2 +msgid "Bulyan" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 +#: flwr.server.strategy.fedavgm.FedAvgM:1 +#: flwr.server.strategy.fedmedian.FedMedian:1 +#: flwr.server.strategy.fedopt.FedOpt:1 flwr.server.strategy.fedprox.FedProx:1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 +#: flwr.server.strategy.krum.Krum:1 flwr.server.strategy.qfedavg.QFedAvg:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.fedavg.FedAvg`" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:3 of +msgid "Implementation based on https://arxiv.org/abs/1802.07927." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +#: flwr.server.strategy.bulyan.Bulyan:5 +#: flwr.server.strategy.fedadagrad.FedAdagrad:5 +#: flwr.server.strategy.fedadam.FedAdam:5 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:5 +#: flwr.server.strategy.fedavgm.FedAvgM:5 flwr.server.strategy.fedopt.FedOpt:5 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:5 +#: flwr.server.strategy.fedyogi.FedYogi:5 flwr.server.strategy.krum.Krum:5 of +msgid "Fraction of clients used during training. Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.bulyan.Bulyan:7 +#: flwr.server.strategy.fedadagrad.FedAdagrad:7 +#: flwr.server.strategy.fedadam.FedAdam:7 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:7 +#: flwr.server.strategy.fedavgm.FedAvgM:7 flwr.server.strategy.fedopt.FedOpt:7 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:7 +#: flwr.server.strategy.fedyogi.FedYogi:7 flwr.server.strategy.krum.Krum:7 of +msgid "Fraction of clients used during validation. Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.bulyan.Bulyan:9 +#: flwr.server.strategy.fedadagrad.FedAdagrad:9 +#: flwr.server.strategy.fedadam.FedAdam:9 flwr.server.strategy.fedavg.FedAvg:13 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:9 +#: flwr.server.strategy.fedavgm.FedAvgM:9 flwr.server.strategy.fedopt.FedOpt:9 +#: flwr.server.strategy.fedprox.FedProx:45 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:9 +#: flwr.server.strategy.fedyogi.FedYogi:9 flwr.server.strategy.krum.Krum:9 of +msgid "Minimum number of clients used during training. Defaults to 2." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.bulyan.Bulyan:11 +#: flwr.server.strategy.fedadagrad.FedAdagrad:11 +#: flwr.server.strategy.fedadam.FedAdam:11 +#: flwr.server.strategy.fedavg.FedAvg:15 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:11 +#: flwr.server.strategy.fedavgm.FedAvgM:11 +#: flwr.server.strategy.fedopt.FedOpt:11 +#: flwr.server.strategy.fedprox.FedProx:47 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:11 +#: flwr.server.strategy.fedyogi.FedYogi:11 flwr.server.strategy.krum.Krum:11 of +msgid "Minimum number of clients used during validation. Defaults to 2." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:839 -msgid "FedAdagrad" -msgstr "FedAdagrad" +#: flwr.server.strategy.bulyan.Bulyan:13 +#: flwr.server.strategy.fedadagrad.FedAdagrad:13 +#: flwr.server.strategy.fedadam.FedAdam:13 +#: flwr.server.strategy.fedavg.FedAvg:17 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:13 +#: flwr.server.strategy.fedavgm.FedAvgM:13 +#: flwr.server.strategy.fedopt.FedOpt:13 +#: flwr.server.strategy.fedprox.FedProx:49 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:13 +#: flwr.server.strategy.fedyogi.FedYogi:13 flwr.server.strategy.krum.Krum:13 of +msgid "Minimum number of total clients in the system. Defaults to 2." +msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:1 -#: flwr.server.strategy.fedadam.FedAdam:1 -#: flwr.server.strategy.fedyogi.FedYogi:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" +#: flwr.server.strategy.bulyan.Bulyan:15 flwr.server.strategy.krum.Krum:15 of +msgid "Number of malicious clients in the system. Defaults to 0." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:3 -#: flwr.server.strategy.fedadam.FedAdam:3 flwr.server.strategy.fedopt.FedOpt:3 -#: flwr.server.strategy.fedyogi.FedYogi:3 of -#, fuzzy -msgid "Implementation based on https://arxiv.org/abs/2003.00295v5" +#: flwr.server.strategy.bulyan.Bulyan:17 +#: flwr.server.strategy.fedadagrad.FedAdagrad:15 +#: flwr.server.strategy.fedadam.FedAdam:15 +#: flwr.server.strategy.fedavg.FedAvg:19 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:15 +#: flwr.server.strategy.fedavgm.FedAvgM:15 +#: flwr.server.strategy.fedopt.FedOpt:15 +#: flwr.server.strategy.fedprox.FedProx:51 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:15 +#: flwr.server.strategy.fedyogi.FedYogi:17 +#: flwr.server.strategy.fedyogi.FedYogi:18 +#: flwr.server.strategy.fedyogi.FedYogi:19 flwr.server.strategy.krum.Krum:20 of +msgid "Optional function used for validation. Defaults to None." msgstr "" -"FedYogi - Stratégie d'apprentissage fédéré utilisant Yogi côté serveur. " -"Mise en oeuvre basée sur https://arxiv.org/abs/2003.00295" -#: flwr.server.strategy.fedadagrad.FedAdagrad:21 -#: flwr.server.strategy.fedadagrad.FedAdagrad:23 -#: flwr.server.strategy.fedadam.FedAdam:25 -#: flwr.server.strategy.fedadam.FedAdam:27 -#: flwr.server.strategy.fedavg.FedAvg:29 flwr.server.strategy.fedavg.FedAvg:31 -#: flwr.server.strategy.fedopt.FedOpt:25 flwr.server.strategy.fedopt.FedOpt:27 -#: flwr.server.strategy.fedprox.FedProx:61 -#: flwr.server.strategy.fedprox.FedProx:63 -#: flwr.server.strategy.fedyogi.FedYogi:28 -#: flwr.server.strategy.fedyogi.FedYogi:30 of -msgid "Metrics aggregation function, optional." +#: flwr.server.strategy.bulyan.Bulyan:19 +#: flwr.server.strategy.fedadagrad.FedAdagrad:17 +#: flwr.server.strategy.fedadam.FedAdam:17 +#: flwr.server.strategy.fedavg.FedAvg:21 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:17 +#: flwr.server.strategy.fedavgm.FedAvgM:17 +#: flwr.server.strategy.fedopt.FedOpt:17 +#: flwr.server.strategy.fedprox.FedProx:53 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:17 +#: flwr.server.strategy.fedyogi.FedYogi:20 flwr.server.strategy.krum.Krum:22 of +msgid "Function used to configure training. Defaults to None." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:29 -#: flwr.server.strategy.fedadam.FedAdam:29 -#: flwr.server.strategy.fedopt.FedOpt:29 of -msgid "Server-side learning rate. Defaults to 1e-1." +#: flwr.server.strategy.bulyan.Bulyan:21 +#: flwr.server.strategy.fedadagrad.FedAdagrad:19 +#: flwr.server.strategy.fedadam.FedAdam:19 +#: flwr.server.strategy.fedavg.FedAvg:23 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:19 +#: flwr.server.strategy.fedavgm.FedAvgM:19 +#: flwr.server.strategy.fedopt.FedOpt:19 +#: flwr.server.strategy.fedprox.FedProx:55 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:19 +#: flwr.server.strategy.fedyogi.FedYogi:22 flwr.server.strategy.krum.Krum:24 of +msgid "Function used to configure validation. Defaults to None." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:31 -#: flwr.server.strategy.fedadam.FedAdam:31 -#: flwr.server.strategy.fedopt.FedOpt:31 of -msgid "Client-side learning rate. Defaults to 1e-1." +#: flwr.server.strategy.bulyan.Bulyan:23 +#: flwr.server.strategy.fedadagrad.FedAdagrad:25 +#: flwr.server.strategy.fedadam.FedAdam:21 +#: flwr.server.strategy.fedavg.FedAvg:25 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:21 +#: flwr.server.strategy.fedavgm.FedAvgM:21 +#: flwr.server.strategy.fedopt.FedOpt:21 +#: flwr.server.strategy.fedprox.FedProx:57 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:21 +#: flwr.server.strategy.fedyogi.FedYogi:24 flwr.server.strategy.krum.Krum:26 of +msgid "Whether or not accept rounds containing failures. Defaults to True." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:33 -#: flwr.server.strategy.fedadam.FedAdam:37 -#: flwr.server.strategy.fedopt.FedOpt:37 of -msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-9." +#: flwr.server.strategy.bulyan.Bulyan:25 +#: flwr.server.strategy.fedadagrad.FedAdagrad:27 +#: flwr.server.strategy.fedadam.FedAdam:23 +#: flwr.server.strategy.fedavg.FedAvg:27 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:24 +#: flwr.server.strategy.fedavgm.FedAvgM:23 +#: flwr.server.strategy.fedopt.FedOpt:23 +#: flwr.server.strategy.fedprox.FedProx:59 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:23 +#: flwr.server.strategy.fedyogi.FedYogi:26 flwr.server.strategy.krum.Krum:28 of +#, fuzzy +msgid "Initial global model parameters." +msgstr "Initialise le modèle global" + +#: flwr.server.strategy.bulyan.Bulyan:27 of +msgid "" +"Byzantine resilient aggregation rule that is used as the first step of " +"the Bulyan (e.g., Krum)" +msgstr "" + +#: flwr.server.strategy.bulyan.Bulyan:29 of +msgid "arguments to the first_aggregation rule" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy +msgid "Aggregate evaluation losses using weighted average." +msgstr "Résultats globaux de l'évaluation." + #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" +#: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#, fuzzy +msgid "Aggregate fit results using Bulyan." +msgstr "Résultats globaux de l'évaluation." + #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_evaluate:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.configure_evaluate:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.configure_evaluate:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:1 of +#, fuzzy +msgid "Configure the next round of evaluation." +msgstr "Configuration de l'évaluation côté serveur" + #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_fit:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_fit:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_fit:1 +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.configure_fit:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.configure_fit:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_fit:1 +#: flwr.server.strategy.fedprox.FedProx.configure_fit:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_fit:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.configure_fit:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.configure_fit:1 of +msgid "Configure the next round of training." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.evaluate:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.evaluate:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "Evaluate model parameters using an evaluation function." +msgstr "" + #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.initialize_parameters:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.initialize_parameters:1 +#: flwr.server.strategy.fedavgm.FedAvgM.initialize_parameters:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#, fuzzy +msgid "Initialize global model parameters." +msgstr "Initialise le modèle global" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.num_evaluation_clients:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_evaluation_clients:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.num_evaluation_clients:1 of +msgid "Use a fraction of available clients for evaluation." +msgstr "" + #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 -#, fuzzy -msgid "FedAdam" -msgstr "FedAdagrad" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.num_fit_clients:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_fit_clients:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.num_fit_clients:1 of +msgid "Return the sample size and the required number of available clients." +msgstr "" -#: flwr.server.strategy.fedadam.FedAdam:33 -#: flwr.server.strategy.fedyogi.FedYogi:36 of -msgid "Momentum parameter. Defaults to 0.9." +#: ../../source/ref-api/flwr.server.strategy.DPFedAvgAdaptive.rst:2 +msgid "DPFedAvgAdaptive" +msgstr "DPFedAvgAdaptive" + +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" msgstr "" -#: flwr.server.strategy.fedadam.FedAdam:35 -#: flwr.server.strategy.fedyogi.FedYogi:38 of -msgid "Second moment parameter. Defaults to 0.99." +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:3 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:3 of +msgid "This class is deprecated and will be removed in a future release." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +#, fuzzy +msgid "Aggregate evaluation losses using the given strategy." +msgstr "Résultats globaux de l'évaluation." + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "Aggregate training results as in DPFedAvgFixed and update clip norms." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of +msgid "Configure the next round of evaluation using the specified strategy." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of +msgid "Evaluate model parameters using an evaluation function from the strategy." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.initialize_parameters:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.initialize_parameters:1 of +msgid "Initialize global model parameters using given strategy." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:3 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:6 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:3 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:3 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:3 +#: flwr.server.strategy.strategy.Strategy.configure_fit:3 +#: flwr.server.strategy.strategy.Strategy.evaluate:6 of #, fuzzy -msgid "FedAvg" -msgstr "DP-FedAvg" +msgid "The current round of federated learning." +msgstr "Qu'est-ce que l'apprentissage fédéré ?" -#: flwr.server.strategy.fedavg.FedAvg:3 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:3 of -msgid "Implementation based on https://arxiv.org/abs/1602.05629" +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:7 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:10 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:7 +#: flwr.server.strategy.strategy.Strategy.configure_fit:7 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:3 of +msgid "The client manager which holds all currently connected clients." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:5 flwr.server.strategy.fedprox.FedProx:37 -#: of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:10 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:10 of msgid "" -"Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will " -"still be sampled. Defaults to 1.0." +"**evaluate_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `EvaluateIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated evaluation." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 -#: of -msgid "" -"Fraction of clients used during validation. In case " -"`min_evaluate_clients` is larger than `fraction_evaluate * " -"available_clients`, `min_evaluate_clients` will still be sampled. " -"Defaults to 1.0." -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 +msgid "DPFedAvgFixed" +msgstr "DPFedAvgFixed" -#: flwr.server.strategy.fedavg.FedAvg:33 of -msgid "Enable (True) or disable (False) in-place aggregation of model updates." +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 +#: flwr.server.strategy.fedavg.FedAvg:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_fit:1 of +msgid "Aggregate training results using unweighted aggregation." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +"Configure the next round of training incorporating Differential Privacy " +"(DP)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"Configuration of the next training round includes information related to " +"DP, such as clip norm and noise stddev." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 +#: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +"**fit_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `FitIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated learning." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 -#, fuzzy -msgid "FedAvgAndroid" -msgstr "DPFedAvgAdaptive" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 +msgid "DifferentialPrivacyClientSideAdaptiveClipping" +msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:3 #: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +msgid "Use `adaptiveclipping_mod` modifier at the client side." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:5 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +"In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " +"performs clipping on the server-side, " +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " +"happen on the client-side, usually by using the built-in " +"`adaptiveclipping_mod`." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:10 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:3 #: of -msgid "" -":py:obj:`bytes_to_ndarray " -"`\\ \\(tensor\\)" +msgid "The strategy to which DP functionalities will be added by this wrapper." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of -#, fuzzy -msgid "Deserialize NumPy array from bytes." -msgstr "Désérialise le tableau numérique NumPy à partir d'octets." +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:12 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:5 +#: of +msgid "The noise multiplier for the Gaussian mechanism for model updates." +msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:14 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:7 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:17 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:10 #: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +msgid "The number of clients that are sampled on each round." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:16 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:9 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"The initial value of clipping norm. Defaults to 0.1. Andrew et al. " +"recommends to set to 0.1." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"The learning rate for the clipping norm adaptation. Defaults to 0.2. " +"Andrew et al. recommends to set to 0.2." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of msgid "" -":py:obj:`ndarray_to_bytes " -"`\\ \\(ndarray\\)" +"The stddev of the noise added to the count of updates currently below the" +" estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:22 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:15 +#: of #, fuzzy -msgid "Serialize NumPy array to bytes." -msgstr "Sérialise le tableau numérique NumPy en octets." +msgid "Create a strategy:" +msgstr "stratégie.du.serveur" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 #: of msgid "" -":py:obj:`ndarrays_to_parameters " -"`\\ " -"\\(ndarrays\\)" +"Wrap the strategy with the " +"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 #: of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +msgid "On the client, add the `adaptiveclipping_mod` to the client-side mods:" msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`parameters_to_ndarrays " -"`\\ " -"\\(parameters\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_fit:1 #: of #, fuzzy -msgid "Convert parameters object to NumPy weights." -msgstr "Convertit l'objet des paramètres en ndarrays NumPy." - -#: ../../source/ref-api/flwr.server.strategy.FedAvgM.rst:2 -#, fuzzy -msgid "FedAvgM" -msgstr "DP-FedAvg" - -#: flwr.server.strategy.fedavgm.FedAvgM:3 of -msgid "Implementation based on https://arxiv.org/abs/1909.06335" -msgstr "" +msgid "Aggregate training results and update clip norms." +msgstr "Résultats globaux de l'évaluation." -#: flwr.server.strategy.fedavgm.FedAvgM:25 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to " -"1.0." -msgstr "" - -#: flwr.server.strategy.fedavgm.FedAvgM:28 of -msgid "Server-side momentum factor used for FedAvgM. Defaults to 0.0." +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 +#, fuzzy +msgid "DifferentialPrivacyClientSideFixedClipping" +msgstr "Confidentialité différentielle" + +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:3 +#: of +msgid "Use `fixedclipping_mod` modifier at the client side." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:5 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +"In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " +"performs clipping on the server-side, " +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 +#: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"The noise multiplier for the Gaussian mechanism for model updates. A " +"value of 1.0 or higher is recommended for strong privacy." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +msgid "The value of the clipping norm." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 +#: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` " +"wrapper:" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 -msgid "FedMedian" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:32 +#: of +msgid "On the client, add the `fixedclipping_mod` to the client-side mods:" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 +#: of #, fuzzy -msgid "Aggregate fit results using median." -msgstr "Résultats globaux de l'évaluation." +msgid "Add noise to the aggregated parameters." +msgstr "Puis sérialise le résultat agrégé :" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 +msgid "DifferentialPrivacyServerSideAdaptiveClipping" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 +#: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 -msgid "FedOpt" -msgstr "" - -#: flwr.server.strategy.fedopt.FedOpt:33 of -msgid "Momentum parameter. Defaults to 0.0." +"The standard deviation of the noise added to the count of updates below " +"the estimate. Andrew et al. recommends to set to " +"`expected_num_records/20`" msgstr "" -#: flwr.server.strategy.fedopt.FedOpt:35 of -msgid "Second moment parameter. Defaults to 0.0." +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 +#: of +msgid "" +"Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping " +"wrapper" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 +#, fuzzy +msgid "DifferentialPrivacyServerSideFixedClipping" +msgstr "Confidentialité différentielle" + +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 +#: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " +"wrapper" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 -msgid "FedProx" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:3 of -msgid "Implementation based on https://arxiv.org/abs/1812.06127" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 +#: of +msgid "Compute the updates, clip, and pass them for aggregation." msgstr "" -#: flwr.server.strategy.fedprox.FedProx:5 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -"The strategy in itself will not be different than FedAvg, the client " -"needs to be adjusted. A proximal term needs to be added to the loss " -"function during the training:" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:9 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -"\\\\frac{\\\\mu}{2} || w - w^t ||^2\n" -"\n" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:12 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -"Where $w^t$ are the global parameters and $w$ are the local weights the " -"function will be optimized with." -msgstr "" - -#: flwr.server.strategy.fedprox.FedProx:15 of -msgid "In PyTorch, for example, the loss would go from:" -msgstr "" - -#: flwr.server.strategy.fedprox.FedProx:21 of -msgid "To:" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:30 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -"With `global_params` being a copy of the parameters before the training " -"takes place." +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:65 of -msgid "" -"The weight of the proximal term used in the optimization. 0.0 makes this " -"strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to " -"be closer to the server parameters during training)." +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 +#: of +msgid "Afterward, add noise to the aggregated parameters." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.FaultTolerantFedAvg.rst:2 +#, fuzzy +msgid "FaultTolerantFedAvg" +msgstr "server.strategy.FaultTolerantFedAvg" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" -msgstr "" - -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" -msgstr "" - -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" -msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 +#: flwr.server.strategy.fedadagrad.FedAdagrad.aggregate_fit:1 +#: flwr.server.strategy.fedadam.FedAdam.aggregate_fit:1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_fit:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_fit:1 +#: flwr.server.strategy.fedavgm.FedAvgM.aggregate_fit:1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.aggregate_fit:1 +#: flwr.server.strategy.fedyogi.FedYogi.aggregate_fit:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_fit:1 of +msgid "Aggregate fit results using weighted average." +msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of -msgid "Sends the proximal factor mu to the clients" +#: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 +#: ../../source/ref-changelog.md:905 +msgid "FedAdagrad" +msgstr "FedAdagrad" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:1 +#: flwr.server.strategy.fedadam.FedAdam:1 +#: flwr.server.strategy.fedyogi.FedYogi:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedTrimmedAvg.rst:2 -msgid "FedTrimmedAvg" +#: flwr.server.strategy.fedadagrad.FedAdagrad:3 +#: flwr.server.strategy.fedadam.FedAdam:3 flwr.server.strategy.fedopt.FedOpt:3 +#: flwr.server.strategy.fedyogi.FedYogi:3 of +#, fuzzy +msgid "Implementation based on https://arxiv.org/abs/2003.00295v5" msgstr "" +"FedYogi - Stratégie d'apprentissage fédéré utilisant Yogi côté serveur. " +"Mise en oeuvre basée sur https://arxiv.org/abs/2003.00295" -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:3 of -msgid "Implemented based on: https://arxiv.org/abs/1803.01498" +#: flwr.server.strategy.fedadagrad.FedAdagrad:21 +#: flwr.server.strategy.fedadagrad.FedAdagrad:23 +#: flwr.server.strategy.fedadam.FedAdam:25 +#: flwr.server.strategy.fedadam.FedAdam:27 +#: flwr.server.strategy.fedavg.FedAvg:29 flwr.server.strategy.fedavg.FedAvg:31 +#: flwr.server.strategy.fedopt.FedOpt:25 flwr.server.strategy.fedopt.FedOpt:27 +#: flwr.server.strategy.fedprox.FedProx:61 +#: flwr.server.strategy.fedprox.FedProx:63 +#: flwr.server.strategy.fedyogi.FedYogi:28 +#: flwr.server.strategy.fedyogi.FedYogi:30 of +msgid "Metrics aggregation function, optional." msgstr "" -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:25 of -msgid "Fraction to cut off of both tails of the distribution. Defaults to 0.2." +#: flwr.server.strategy.fedadagrad.FedAdagrad:29 +#: flwr.server.strategy.fedadam.FedAdam:29 +#: flwr.server.strategy.fedopt.FedOpt:29 of +msgid "Server-side learning rate. Defaults to 1e-1." +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:31 +#: flwr.server.strategy.fedadam.FedAdam:31 +#: flwr.server.strategy.fedopt.FedOpt:31 of +msgid "Client-side learning rate. Defaults to 1e-1." +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:33 +#: flwr.server.strategy.fedadam.FedAdam:37 +#: flwr.server.strategy.fedopt.FedOpt:37 of +msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-9." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" -msgstr "" - -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg.aggregate_fit:1 of -msgid "Aggregate fit results using trimmed average." +":py:obj:`aggregate_fit `\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 -msgid "FedXgbBagging" +#: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 +#, fuzzy +msgid "FedAdam" +msgstr "FedAdagrad" + +#: flwr.server.strategy.fedadam.FedAdam:33 +#: flwr.server.strategy.fedyogi.FedYogi:36 of +msgid "Momentum parameter. Defaults to 0.9." msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedadam.FedAdam:35 +#: flwr.server.strategy.fedyogi.FedYogi:38 of +msgid "Second moment parameter. Defaults to 0.99." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of -#, fuzzy -msgid "Aggregate evaluation metrics using average." -msgstr "Résultats globaux de l'évaluation." - -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_fit:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_fit:1 of -msgid "Aggregate fit results using bagging." -msgstr "" - -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 -msgid "FedXgbCyclic" -msgstr "" +#: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 +#, fuzzy +msgid "FedAvg" +msgstr "DP-FedAvg" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +#: flwr.server.strategy.fedavg.FedAvg:3 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:3 of +msgid "Implementation based on https://arxiv.org/abs/1602.05629" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg:5 flwr.server.strategy.fedprox.FedProx:37 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\," -" results\\, failures\\)" +"Fraction of clients used during training. In case `min_fit_clients` is " +"larger than `fraction_fit * available_clients`, `min_fit_clients` will " +"still be sampled. Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"Fraction of clients used during validation. In case " +"`min_evaluate_clients` is larger than `fraction_evaluate * " +"available_clients`, `min_evaluate_clients` will still be sampled. " +"Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +#: flwr.server.strategy.fedavg.FedAvg:33 of +msgid "Enable (True) or disable (False) in-place aggregation of model updates." msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 +#: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 #, fuzzy -msgid "FedXgbNnAvg" -msgstr "DP-FedAvg" - -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of -msgid "" -"This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: " -"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." -msgstr "" +msgid "FedAvgAndroid" +msgstr "DPFedAvgAdaptive" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\, " -"results\\, failures\\)" +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`bytes_to_ndarray " +"`\\ \\(tensor\\)" +msgstr "" + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of +#, fuzzy +msgid "Deserialize NumPy array from bytes." +msgstr "Désérialise le tableau numérique NumPy à partir d'octets." + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_fit " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`ndarray_to_bytes " +"`\\ \\(ndarray\\)" +msgstr "" + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of +#, fuzzy +msgid "Serialize NumPy array to bytes." +msgstr "Sérialise le tableau numérique NumPy en octets." + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`ndarrays_to_parameters " +"`\\ " +"\\(ndarrays\\)" +msgstr "" + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 -msgid "FedYogi" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`parameters_to_ndarrays " +"`\\ " +"\\(parameters\\)" msgstr "" -#: flwr.server.strategy.fedyogi.FedYogi:32 of -msgid "Server-side learning rate. Defaults to 1e-2." +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 +#: of +#, fuzzy +msgid "Convert parameters object to NumPy weights." +msgstr "Convertit l'objet des paramètres en ndarrays NumPy." + +#: ../../source/ref-api/flwr.server.strategy.FedAvgM.rst:2 +#, fuzzy +msgid "FedAvgM" +msgstr "DP-FedAvg" + +#: flwr.server.strategy.fedavgm.FedAvgM:3 of +msgid "Implementation based on https://arxiv.org/abs/1909.06335" msgstr "" -#: flwr.server.strategy.fedyogi.FedYogi:34 of -msgid "Client-side learning rate. Defaults to 0.0316." +#: flwr.server.strategy.fedavgm.FedAvgM:25 of +msgid "" +"Server-side learning rate used in server-side optimization. Defaults to " +"1.0." msgstr "" -#: flwr.server.strategy.fedyogi.FedYogi:40 of -msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-3." +#: flwr.server.strategy.fedavgm.FedAvgM:28 of +msgid "Server-side momentum factor used for FedAvgM. Defaults to 0.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," +"`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," +"`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 -msgid "Krum" -msgstr "" - -#: flwr.server.strategy.krum.Krum:3 of -msgid "Implementation based on https://arxiv.org/abs/1703.02757" -msgstr "" - -#: flwr.server.strategy.krum.Krum:17 of -msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" -" that case classical Krum is applied." +#: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 +msgid "FedMedian" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.krum.Krum.aggregate_fit:1 of +#: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of #, fuzzy -msgid "Aggregate fit results using Krum." +msgid "Aggregate fit results using median." msgstr "Résultats globaux de l'évaluation." #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 -#, fuzzy -msgid "QFedAvg" -msgstr "DP-FedAvg" +#: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 +msgid "FedOpt" +msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedopt.FedOpt:33 of +msgid "Momentum parameter. Defaults to 0.0." +msgstr "" + +#: flwr.server.strategy.fedopt.FedOpt:35 of +msgid "Second moment parameter. Defaults to 0.0." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 -#, fuzzy -msgid "Strategy" -msgstr "stratégie.du.serveur" +#: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 +msgid "FedProx" +msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedprox.FedProx:3 of +msgid "Implementation based on https://arxiv.org/abs/1812.06127" +msgstr "" + +#: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"The strategy in itself will not be different than FedAvg, the client " +"needs to be adjusted. A proximal term needs to be added to the loss " +"function during the training:" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of -#, fuzzy -msgid "Aggregate evaluation results." -msgstr "Résultats globaux de l'évaluation." +#: flwr.server.strategy.fedprox.FedProx:9 of +msgid "" +"\\\\frac{\\\\mu}{2} || w - w^t ||^2\n" +"\n" +msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedprox.FedProx:12 of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +"Where $w^t$ are the global parameters and $w$ are the local weights the " +"function will be optimized with." msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of -#, fuzzy -msgid "Aggregate training results." -msgstr "Résultats globaux de l'évaluation." +#: flwr.server.strategy.fedprox.FedProx:15 of +msgid "In PyTorch, for example, the loss would go from:" +msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedprox.FedProx:21 of +msgid "To:" +msgstr "" + +#: flwr.server.strategy.fedprox.FedProx:30 of +msgid "" +"With `global_params` being a copy of the parameters before the training " +"takes place." +msgstr "" + +#: flwr.server.strategy.fedprox.FedProx:65 of +msgid "" +"The weight of the proximal term used in the optimization. 0.0 makes this " +"strategy equivalent to FedAvg, and the higher the coefficient, the more " +"regularization will be used (that is, the client parameters will need to " +"be closer to the server parameters during training)." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.evaluate:1 of -#, fuzzy -msgid "Evaluate the current model parameters." -msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" - -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of -#, fuzzy -msgid "Initialize the (global) model parameters." -msgstr "Initialise le modèle global" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" +msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " -"one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "Exceptions that occurred while the server was waiting for client updates." +#: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of +msgid "Sends the proximal factor mu to the clients" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of -msgid "" -"**aggregation_result** -- The aggregated evaluation result. Aggregation " -"typically uses some variant of a weighted average." +#: ../../source/ref-api/flwr.server.strategy.FedTrimmedAvg.rst:2 +msgid "FedTrimmedAvg" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of -msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" -" one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:3 of +msgid "Implemented based on: https://arxiv.org/abs/1803.01498" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of -msgid "" -"**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the " -"previous parameters with the ones returned from this method). If `None` " -"is returned (e.g., because there were only failures and no viable " -"results) then the server will no update the previous model parameters, " -"the updates received in this round are discarded, and the global model " -"parameters remain the same." +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:25 of +msgid "Fraction to cut off of both tails of the distribution. Defaults to 0.2." msgstr "" -#: flwr.server.strategy.strategy.Strategy.evaluate:3 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"This function can be used to perform centralized (i.e., server-side) " -"evaluation of model parameters." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.evaluate:11 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple " -"containing loss and a dictionary containing task-specific metrics (e.g., " -"accuracy)." +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of -msgid "" -"**parameters** -- If parameters are returned, then the server will treat " -"these as the initial global model parameters." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg.aggregate_fit:1 of +msgid "Aggregate fit results using trimmed average." msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:2 -#, fuzzy -msgid "workflow" -msgstr "Flux de travail" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`DefaultWorkflow `\\ " -"\\(\\[fit\\_workflow\\, ...\\]\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of -msgid "Default workflow in Flower." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`SecAggPlusWorkflow `\\ " -"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 -#: of -msgid "The workflow for the SecAgg+ protocol." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`SecAggWorkflow `\\ " -"\\(reconstruction\\_threshold\\, \\*\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of -msgid "The workflow for the SecAgg protocol." +#: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 +msgid "FedXgbBagging" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:2 -#, fuzzy -msgid "DefaultWorkflow" -msgstr "Flux de travail" - -#: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:2 -#, fuzzy -msgid "SecAggPlusWorkflow" -msgstr "Flux de travail" - -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors " -"owned by multiple parties, without accessing any individual integer " -"vector. This workflow allows the server to compute the weighted average " -"of model parameters across all clients, ensuring individual contributions" -" remain private. This is achieved by clients sending both, a weighting " -"factor and a weighted version of the locally updated parameters, both of " -"which are masked for privacy. Specifically, each client uploads \"[w, w *" -" params]\" with masks, where weighting factor 'w' is the number of " -"examples ('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of -msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg+ " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" -msgstr "" +#, fuzzy +msgid "Aggregate evaluation metrics using average." +msgstr "Résultats globaux de l'évaluation." -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of -msgid "key shares." +msgid "" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:18 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:18 -#: of -msgid "" -"'collect masked vectors': Forward encrypted secret key shares to target " -"clients and collect masked model parameters." +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_fit:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_fit:1 of +msgid "Aggregate fit results using bagging." msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:20 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:20 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"'unmask': Collect secret key shares to decrypt and aggregate the model " -"parameters." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:22 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"Only the aggregated model parameters are exposed and passed to " -"`Strategy.aggregate_fit`, ensuring individual data privacy." +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"The number of shares into which each client's private key is split under " -"the SecAgg+ protocol. If specified as a float, it represents the " -"proportion of all selected clients, and the number of shares will be set " -"dynamically in the run time. A private key can be reconstructed from " -"these shares, allowing for the secure aggregation of model updates. Each " -"client sends one share to each of its neighbors while retaining one." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"The minimum number of shares required to reconstruct a client's private " -"key, or, if specified as a float, it represents the proportion of the " -"total number of shares needed for reconstruction. This threshold ensures " -"privacy by allowing for the recovery of contributions from dropped " -"clients during aggregation, without compromising individual client data." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"The maximum value of the weight that can be assigned to any single " -"client's update during the weighted average calculation on the server " -"side, e.g., in the FedAvg algorithm." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -"The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within " -"[-clipping_range, clipping_range], facilitating quantization." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 -#: of -msgid "" -"The size of the range into which floating-point model parameters are " -"quantized, mapping each parameter to an integer in [0, " -"quantization_range-1]. This facilitates cryptographic operations on the " -"model updates." +#: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 +msgid "FedXgbCyclic" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " -"Please use 2**n values for `modulus_range` to prevent overflow issues." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for" -" replies for this duration each time. If `None`, there is no time limit " -"and the workflow will wait until replies for all messages are received." +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\," +" results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` " -"means better privacy guarantees but less tolerance to dropouts." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of -msgid "Too large `max_weight` may compromise the precision of the quantization." +msgid "" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:65 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of -msgid "`modulus_range` must be 2**n and larger than `quantization_range`." +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:66 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in " -"the runtime. This allows for dynamic adjustment based on the total number" -" of participating clients." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted " -"as the proportion of the number of shares needed for the reconstruction " -"of a private key. This feature enables flexibility in setting the " -"security threshold relative to the number of distributed shares." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters" -" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+" -" protocol." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 +#, fuzzy +msgid "FedXgbNnAvg" +msgstr "DP-FedAvg" + +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\" -" \\(driver\\, ...\\)" +"This strategy is deprecated, but a copy of it is available in Flower " +"Baselines: " +"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of -msgid "Execute the 'collect masked vectors' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`setup_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\, " +"results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 -#: of -msgid "Execute the 'setup' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`share_keys_stage " -"`\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 -#: of -msgid "Execute the 'share keys' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 -#: of -msgid "Execute the 'unmask' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:2 -#, fuzzy -msgid "SecAggWorkflow" -msgstr "Flux de travail" - -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Bases: " -":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of -msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned" -" by multiple parties, without accessing any individual integer vector. " -"This workflow allows the server to compute the weighted average of model " -"parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and" -" a weighted version of the locally updated parameters, both of which are " -"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" -" with masks, where weighting factor 'w' is the number of examples " -"('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +#: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 +msgid "FedYogi" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of -msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +#: flwr.server.strategy.fedyogi.FedYogi:32 of +msgid "Server-side learning rate. Defaults to 1e-2." msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of -msgid "" -"Each client's private key is split into N shares under the SecAgg " -"protocol, where N is the number of selected clients." +#: flwr.server.strategy.fedyogi.FedYogi:34 of +msgid "Client-side learning rate. Defaults to 0.0316." msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of -msgid "" -"Generally, higher `reconstruction_threshold` means better privacy " -"guarantees but less tolerance to dropouts." +#: flwr.server.strategy.fedyogi.FedYogi:40 of +msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-3." msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"When `reconstruction_threshold` is a float, it is interpreted as the " -"proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in " -"setting the security threshold relative to the number of selected " -"clients." +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"`reconstruction_threshold`, and the quantization parameters " -"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg " -"protocol." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\ " -"\\(driver\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`share_keys_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:2 -#, fuzzy -msgid "simulation" -msgstr "Simulation de moniteur" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" +msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\," -" client\\_fn\\[\\, ...\\]\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.app.start_simulation:1 of -#, fuzzy -msgid "Start a Ray-based Flower simulation server." -msgstr "Simulation de moniteur" +#: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 +msgid "Krum" +msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -msgid "" -":py:obj:`run_simulation_from_cli " -"`\\ \\(\\)" +#: flwr.server.strategy.krum.Krum:3 of +msgid "Implementation based on https://arxiv.org/abs/1703.02757" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.run_simulation.run_simulation_from_cli:1 of -msgid "Run Simulation Engine from the CLI." +#: flwr.server.strategy.krum.Krum:17 of +msgid "" +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" +" that case classical Krum is applied." msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`run_simulation `\\ " -"\\(server\\_app\\, client\\_app\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.run_simulation.run_simulation:1 of -msgid "Run a Flower App using the Simulation Engine." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation.rst:2 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.krum.Krum.aggregate_fit:1 of #, fuzzy -msgid "run\\_simulation" -msgstr "Simulation de moniteur" +msgid "Aggregate fit results using Krum." +msgstr "Résultats globaux de l'évaluation." -#: flwr.simulation.run_simulation.run_simulation:3 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The `ServerApp` to be executed. It will send messages to different " -"`ClientApp` instances running on different (virtual) SuperNodes." +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:6 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive" -" messages sent by the `ServerApp`." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:9 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in " -"the ServerApp and receive a Message describing what the ClientApp should " -"perform." -msgstr "" - -#: flwr.simulation.run_simulation.run_simulation:13 of -msgid "A simulation backend that runs `ClientApp`s." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:15 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to " -"configure a backend. Values supported in are those included by " -"`flwr.common.typing.ConfigsRecordValues`." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:19 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. " -"This is desirable if you make use of a TensorFlow model on your " -"`ServerApp` while having your `ClientApp` running on the same GPU. " -"Without enabling this, you might encounter an out-of-memory error because" -" TensorFlow, by default, allocates all GPU memory. Read more about how " -"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " -"documentation: https://www.tensorflow.org/api/stable." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:26 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" -" enabled, DEBUG-level logs will be displayed." +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation_from_cli.rst:2 -#, fuzzy -msgid "run\\_simulation\\_from\\_cli" -msgstr "Simulation de moniteur" - -#: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 +#: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 #, fuzzy -msgid "start\\_simulation" -msgstr "démarrer_simulation" +msgid "QFedAvg" +msgstr "DP-FedAvg" -#: flwr.simulation.app.start_simulation:3 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"A function creating client instances. The function must take a single " -"`str` argument called `cid`. It should return a single client instance of" -" type Client. Note that the created client instances are ephemeral and " -"will often be destroyed after a single method invocation. Since client " -"instances are not long-lived, they should not attempt to carry state over" -" method invocations. Any state required by the instance (model, dataset, " -"hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load " -"evaluation data in the `evaluate` method itself)." +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:13 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"The total number of clients in this simulation. This must be set if " -"`clients_ids` is not set and vice-versa." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.simulation.app.start_simulation:16 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients`" -" is not set. Setting both `num_clients` and `clients_ids` with " -"`len(clients_ids)` not equal to `num_clients` generates an error." +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:20 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` " -"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " -"as well as using custom resources, please consult the Ray documentation." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:25 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"An implementation of the abstract base class `flwr.server.Server`. If no " -"instance is provided, then `start_server` will create one." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.simulation.app.start_simulation:31 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If " -"no strategy is provided, then `start_server` will use " -"`flwr.server.strategy.FedAvg`." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.simulation.app.start_simulation:35 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_simulation` will use " -"`flwr.server.client_manager.SimpleClientManager`." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.simulation.app.start_simulation:39 of +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"Optional dictionary containing arguments for the call to `ray.init`. If " -"ray_init_args is None (the default), Ray will be initialized with the " -"following default args: { \"ignore_reinit_error\": True, " -"\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to " -"ray.init." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.simulation.app.start_simulation:39 of +#: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 +#, fuzzy +msgid "Strategy" +msgstr "stratégie.du.serveur" + +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"Optional dictionary containing arguments for the call to `ray.init`. If " -"ray_init_args is None (the default), Ray will be initialized with the " -"following default args:" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:43 of -msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" -msgstr "" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of +#, fuzzy +msgid "Aggregate evaluation results." +msgstr "Résultats globaux de l'évaluation." -#: flwr.simulation.app.start_simulation:45 of +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any " -"arguments from being passed to ray.init." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.simulation.app.start_simulation:48 of -msgid "" -"Set to True to prevent `ray.shutdown()` in case " -"`ray.is_initialized()=True`." -msgstr "" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of +#, fuzzy +msgid "Aggregate training results." +msgstr "Résultats globaux de l'évaluation." -#: flwr.simulation.app.start_simulation:50 of +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"Optionally specify the type of actor to use. The actor object, which " -"persists throughout the simulation, will be the process in charge of " -"executing a ClientApp wrapping input argument `client_fn`." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:54 of +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"If you want to create your own Actor classes, you might need to pass some" -" input argument. You can use this dictionary for such purpose." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:57 of +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " -"the VCE to choose in which node the actor is placed. If you are an " -"advanced user needed more control you can use lower-level scheduling " -"strategies to pin actors to specific compute nodes (e.g. via " -"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." -" For all details, please refer to the Ray documentation: " -"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" -msgstr "" - -#: flwr.simulation.app.start_simulation:66 of -msgid "**hist** -- Object containing metrics from training." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-changelog.md:1 -msgid "Changelog" -msgstr "Changelog" - -#: ../../source/ref-changelog.md:3 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.evaluate:1 of #, fuzzy -msgid "Unreleased" -msgstr "Inédit" - -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:17 -#: ../../source/ref-changelog.md:110 ../../source/ref-changelog.md:210 -#: ../../source/ref-changelog.md:294 ../../source/ref-changelog.md:358 -#: ../../source/ref-changelog.md:416 ../../source/ref-changelog.md:485 -#: ../../source/ref-changelog.md:614 ../../source/ref-changelog.md:656 -#: ../../source/ref-changelog.md:723 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:834 ../../source/ref-changelog.md:873 -#: ../../source/ref-changelog.md:906 ../../source/ref-changelog.md:956 -msgid "What's new?" -msgstr "Quoi de neuf ?" +msgid "Evaluate the current model parameters." +msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:80 -#: ../../source/ref-changelog.md:192 ../../source/ref-changelog.md:282 -#: ../../source/ref-changelog.md:346 ../../source/ref-changelog.md:404 -#: ../../source/ref-changelog.md:473 ../../source/ref-changelog.md:535 -#: ../../source/ref-changelog.md:554 ../../source/ref-changelog.md:710 -#: ../../source/ref-changelog.md:781 ../../source/ref-changelog.md:818 -#: ../../source/ref-changelog.md:861 -msgid "Incompatible changes" -msgstr "Changements incompatibles" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" +msgstr "" -#: ../../source/ref-changelog.md:9 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of #, fuzzy -msgid "v1.7.0 (2024-02-05)" -msgstr "v1.3.0 (2023-02-06)" - -#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:104 -#: ../../source/ref-changelog.md:204 ../../source/ref-changelog.md:288 -#: ../../source/ref-changelog.md:352 ../../source/ref-changelog.md:410 -#: ../../source/ref-changelog.md:479 ../../source/ref-changelog.md:548 -msgid "Thanks to our contributors" -msgstr "Merci à nos contributeurs" +msgid "Initialize the (global) model parameters." +msgstr "Initialise le modèle global" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:106 -#: ../../source/ref-changelog.md:206 ../../source/ref-changelog.md:290 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:412 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " +"one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -"Nous tenons à remercier tout particulièrement tous les contributeurs qui " -"ont rendu possible la nouvelle version de Flower (dans l'ordre `git " -"shortlog`) :" -#: ../../source/ref-changelog.md:15 -msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " -"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " -"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " -"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " -"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " -"Shaaban`, `Yan Gao`, `Yasar Abbas` " +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of +msgid "Exceptions that occurred while the server was waiting for client updates." msgstr "" -#: ../../source/ref-changelog.md:19 -#, fuzzy +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of msgid "" -"**Introduce stateful clients (experimental)** " -"([#2770](https://github.com/adap/flower/pull/2770), " -"[#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), " -"[#2643](https://github.com/adap/flower/pull/2643), " -"[#2769](https://github.com/adap/flower/pull/2769))" +"**aggregation_result** -- The aggregated evaluation result. Aggregation " +"typically uses some variant of a weighted average." msgstr "" -"**([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:21 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Subclasses of `Client` and `NumPyClient` can now store local state that " -"remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via " -"`start_simulation`) and networked clients (via `start_client`). It's also" -" the first preview of new abstractions like `Context` and `RecordSet`. " -"Clients can access state of type `RecordSet` via `state: RecordSet = " -"self.context.state`. Changes to this `RecordSet` are preserved across " -"different rounds of execution to enable stateful computations in a " -"unified way across simulation and deployment." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" +" one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -#: ../../source/ref-changelog.md:23 -#, fuzzy +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" -"**Improve performance** " -"([#2293](https://github.com/adap/flower/pull/2293))" +"**parameters** -- If parameters are returned, then the server will treat " +"these as the new global model parameters (i.e., it will replace the " +"previous parameters with the ones returned from this method). If `None` " +"is returned (e.g., because there were only failures and no viable " +"results) then the server will no update the previous model parameters, " +"the updates received in this round are discarded, and the global model " +"parameters remain the same." msgstr "" -"**Supprimer les stratégies expérimentales** " -"([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:25 +#: flwr.server.strategy.strategy.Strategy.evaluate:3 of msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" -"place aggregation to reduce memory consumption. The Flower client " -"serialization/deserialization has been rewritten from the ground up, " -"which results in significant speedups, especially when the client-side " -"training time is short." +"This function can be used to perform centralized (i.e., server-side) " +"evaluation of model parameters." msgstr "" -#: ../../source/ref-changelog.md:27 -#, fuzzy +#: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**Support Federated Learning with Apple MLX and Flower** " -"([#2693](https://github.com/adap/flower/pull/2693))" +"**evaluation_result** -- The evaluation result, usually a Tuple " +"containing loss and a dictionary containing task-specific metrics (e.g., " +"accuracy)." msgstr "" -"**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " -"Flower** ([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:29 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of msgid "" -"Flower has official support for federated learning using [Apple " -"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " -"example." +"**parameters** -- If parameters are returned, then the server will treat " +"these as the initial global model parameters." msgstr "" -#: ../../source/ref-changelog.md:31 +#: ../../source/ref-api/flwr.server.workflow.rst:2 #, fuzzy +msgid "workflow" +msgstr "Flux de travail" + +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Introduce new XGBoost cyclic strategy** " -"([#2666](https://github.com/adap/flower/pull/2666), " -"[#2668](https://github.com/adap/flower/pull/2668))" +":py:obj:`DefaultWorkflow `\\ " +"\\(\\[fit\\_workflow\\, ...\\]\\)" msgstr "" -"**Introduction du SDK iOS (aperçu)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:33 -msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of" -" training (often called cyclic). The `xgboost-comprehensive` code example" -" shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower " -"offers best-in-class XGBoost support." +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of +msgid "Default workflow in Flower." msgstr "" -#: ../../source/ref-changelog.md:35 -#, fuzzy +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Support Python 3.11** " -"([#2394](https://github.com/adap/flower/pull/2394))" -msgstr "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +":py:obj:`SecAggPlusWorkflow `\\ " +"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" +msgstr "" -#: ../../source/ref-changelog.md:37 -msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " -"ensure better support for users using more recent Python versions." +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 +#: of +msgid "The workflow for the SecAgg+ protocol." msgstr "" -#: ../../source/ref-changelog.md:39 -#, fuzzy +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Update gRPC and ProtoBuf dependencies** " -"([#2814](https://github.com/adap/flower/pull/2814))" +":py:obj:`SecAggWorkflow `\\ " +"\\(reconstruction\\_threshold\\, \\*\\)" msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:41 -msgid "" -"The `grpcio` and `protobuf` dependencies were updated to their latest " -"versions for improved security and performance." +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +msgid "The workflow for the SecAgg protocol." msgstr "" -#: ../../source/ref-changelog.md:43 +#: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:2 +#, fuzzy +msgid "DefaultWorkflow" +msgstr "Flux de travail" + +#: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:2 #, fuzzy +msgid "SecAggPlusWorkflow" +msgstr "Flux de travail" + +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 +#: of msgid "" -"**Introduce Docker image for Flower server** " -"([#2700](https://github.com/adap/flower/pull/2700), " -"[#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), " -"[#2695](https://github.com/adap/flower/pull/2695), " -"[#2747](https://github.com/adap/flower/pull/2747), " -"[#2746](https://github.com/adap/flower/pull/2746), " -"[#2680](https://github.com/adap/flower/pull/2680), " -"[#2682](https://github.com/adap/flower/pull/2682), " -"[#2701](https://github.com/adap/flower/pull/2701))" +"The SecAgg+ protocol ensures the secure summation of integer vectors " +"owned by multiple parties, without accessing any individual integer " +"vector. This workflow allows the server to compute the weighted average " +"of model parameters across all clients, ensuring individual contributions" +" remain private. This is achieved by clients sending both, a weighting " +"factor and a weighted version of the locally updated parameters, both of " +"which are masked for privacy. Specifically, each client uploads \"[w, w *" +" params]\" with masks, where weighting factor 'w' is the number of " +"examples ('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" -"**([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:45 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 +#: of msgid "" -"The Flower server can now be run using an official Docker image. A new " -"how-to guide explains [how to run Flower using " -"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html). An official Flower client Docker image will follow." +"The protocol involves four main stages: - 'setup': Send SecAgg+ " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" -#: ../../source/ref-changelog.md:47 -#, fuzzy -msgid "" -"**Introduce** `flower-via-docker-compose` **example** " -"([#2626](https://github.com/adap/flower/pull/2626))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 +#: of +msgid "key shares." msgstr "" -"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " -"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:49 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:18 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:18 +#: of msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** " -"([#2719](https://github.com/adap/flower/pull/2719))" +"'collect masked vectors': Forward encrypted secret key shares to target " +"clients and collect masked model parameters." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:51 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:20 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:20 +#: of msgid "" -"**Introduce** `custom-metrics` **example** " -"([#1958](https://github.com/adap/flower/pull/1958))" +"'unmask': Collect secret key shares to decrypt and aggregate the model " +"parameters." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:53 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:22 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 +#: of msgid "" -"**Update code examples to use Flower Datasets** " -"([#2450](https://github.com/adap/flower/pull/2450), " -"[#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), " -"[#2712](https://github.com/adap/flower/pull/2712))" +"Only the aggregated model parameters are exposed and passed to " +"`Strategy.aggregate_fit`, ensuring individual data privacy." msgstr "" -"Mettre à jour les outils de développement " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:55 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 +#: of msgid "" -"Several code examples were updated to use [Flower " -"Datasets](https://flower.ai/docs/datasets/)." +"The number of shares into which each client's private key is split under " +"the SecAgg+ protocol. If specified as a float, it represents the " +"proportion of all selected clients, and the number of shares will be set " +"dynamically in the run time. A private key can be reconstructed from " +"these shares, allowing for the secure aggregation of model updates. Each " +"client sends one share to each of its neighbors while retaining one." msgstr "" -#: ../../source/ref-changelog.md:57 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 +#: of msgid "" -"**General updates to Flower Examples** " -"([#2381](https://github.com/adap/flower/pull/2381), " -"[#2805](https://github.com/adap/flower/pull/2805), " -"[#2782](https://github.com/adap/flower/pull/2782), " -"[#2806](https://github.com/adap/flower/pull/2806), " -"[#2829](https://github.com/adap/flower/pull/2829), " -"[#2825](https://github.com/adap/flower/pull/2825), " -"[#2816](https://github.com/adap/flower/pull/2816), " -"[#2726](https://github.com/adap/flower/pull/2726), " -"[#2659](https://github.com/adap/flower/pull/2659), " -"[#2655](https://github.com/adap/flower/pull/2655))" +"The minimum number of shares required to reconstruct a client's private " +"key, or, if specified as a float, it represents the proportion of the " +"total number of shares needed for reconstruction. This threshold ensures " +"privacy by allowing for the recovery of contributions from dropped " +"clients during aggregation, without compromising individual client data." msgstr "" -"**Améliorer l'API (expérimentale) du pilote** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:59 -msgid "Many Flower code examples received substantial updates." +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 +#: of +msgid "" +"The maximum value of the weight that can be assigned to any single " +"client's update during the weighted average calculation on the server " +"side, e.g., in the FedAvg algorithm." msgstr "" -#: ../../source/ref-changelog.md:61 ../../source/ref-changelog.md:154 -#, fuzzy -msgid "**Update Flower Baselines**" -msgstr "Demande pour une nouvelle Flower Baseline" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 +#: of +msgid "" +"The range within which model parameters are clipped before quantization. " +"This parameter ensures each model parameter is bounded within " +"[-clipping_range, clipping_range], facilitating quantization." +msgstr "" -#: ../../source/ref-changelog.md:63 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 +#: of msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " -"[#2771](https://github.com/adap/flower/pull/2771))" +"The size of the range into which floating-point model parameters are " +"quantized, mapping each parameter to an integer in [0, " +"quantization_range-1]. This facilitates cryptographic operations on the " +"model updates." msgstr "" -"**Nouvel exemple de code JAX** " -"([#906](https://github.com/adap/flower/pull/906), " -"[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:64 -#, fuzzy -msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 +#: of +msgid "" +"The range of values from which random mask entries are uniformly sampled " +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " +"Please use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" -"Amélioration de la documentation sur le serveur gRPC " -"([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:65 -#, fuzzy -msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 +#: of +msgid "" +"The timeout duration in seconds. If specified, the workflow will wait for" +" replies for this duration each time. If `None`, there is no time limit " +"and the workflow will wait until replies for all messages are received." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:66 -#, fuzzy -msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 +#: of +msgid "" +"Generally, higher `num_shares` means more robust to dropouts while " +"increasing the computational costs; higher `reconstruction_threshold` " +"means better privacy guarantees but less tolerance to dropouts." +msgstr "" -#: ../../source/ref-changelog.md:67 -#, fuzzy -msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 +#: of +msgid "Too large `max_weight` may compromise the precision of the quantization." +msgstr "" -#: ../../source/ref-changelog.md:68 -#, fuzzy -msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:65 +#: of +msgid "`modulus_range` must be 2**n and larger than `quantization_range`." msgstr "" -"**Renommé stratégie q-FedAvg** " -"([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-changelog.md:70 -#, fuzzy -msgid "" -"**Improve documentation** " -"([#2674](https://github.com/adap/flower/pull/2674), " -"[#2480](https://github.com/adap/flower/pull/2480), " -"[#2826](https://github.com/adap/flower/pull/2826), " -"[#2727](https://github.com/adap/flower/pull/2727), " -"[#2761](https://github.com/adap/flower/pull/2761), " -"[#2900](https://github.com/adap/flower/pull/2900))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:66 +#: of +msgid "" +"When `num_shares` is a float, it is interpreted as the proportion of all " +"selected clients, and hence the number of shares will be determined in " +"the runtime. This allows for dynamic adjustment based on the total number" +" of participating clients." msgstr "" -"**Mise à jour de la documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:72 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 +#: of msgid "" -"**Improved testing and development infrastructure** " -"([#2797](https://github.com/adap/flower/pull/2797), " -"[#2676](https://github.com/adap/flower/pull/2676), " -"[#2644](https://github.com/adap/flower/pull/2644), " -"[#2656](https://github.com/adap/flower/pull/2656), " -"[#2848](https://github.com/adap/flower/pull/2848), " -"[#2675](https://github.com/adap/flower/pull/2675), " -"[#2735](https://github.com/adap/flower/pull/2735), " -"[#2767](https://github.com/adap/flower/pull/2767), " -"[#2732](https://github.com/adap/flower/pull/2732), " -"[#2744](https://github.com/adap/flower/pull/2744), " -"[#2681](https://github.com/adap/flower/pull/2681), " -"[#2699](https://github.com/adap/flower/pull/2699), " -"[#2745](https://github.com/adap/flower/pull/2745), " -"[#2734](https://github.com/adap/flower/pull/2734), " -"[#2731](https://github.com/adap/flower/pull/2731), " -"[#2652](https://github.com/adap/flower/pull/2652), " -"[#2720](https://github.com/adap/flower/pull/2720), " -"[#2721](https://github.com/adap/flower/pull/2721), " -"[#2717](https://github.com/adap/flower/pull/2717), " -"[#2864](https://github.com/adap/flower/pull/2864), " -"[#2694](https://github.com/adap/flower/pull/2694), " -"[#2709](https://github.com/adap/flower/pull/2709), " -"[#2658](https://github.com/adap/flower/pull/2658), " -"[#2796](https://github.com/adap/flower/pull/2796), " -"[#2692](https://github.com/adap/flower/pull/2692), " -"[#2657](https://github.com/adap/flower/pull/2657), " -"[#2813](https://github.com/adap/flower/pull/2813), " -"[#2661](https://github.com/adap/flower/pull/2661), " -"[#2398](https://github.com/adap/flower/pull/2398))" +"Similarly, when `reconstruction_threshold` is a float, it is interpreted " +"as the proportion of the number of shares needed for the reconstruction " +"of a private key. This feature enables flexibility in setting the " +"security threshold relative to the number of distributed shares." msgstr "" -#: ../../source/ref-changelog.md:74 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 +#: of msgid "" -"The Flower testing and development infrastructure has received " -"substantial updates. This makes Flower 1.7 the most tested release ever." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters" +" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+" +" protocol." msgstr "" -#: ../../source/ref-changelog.md:76 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Update dependencies** " -"([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), " -"[#2739](https://github.com/adap/flower/pull/2739), " -"[#2837](https://github.com/adap/flower/pull/2837), " -"[#2788](https://github.com/adap/flower/pull/2788), " -"[#2811](https://github.com/adap/flower/pull/2811), " -"[#2774](https://github.com/adap/flower/pull/2774), " -"[#2790](https://github.com/adap/flower/pull/2790), " -"[#2751](https://github.com/adap/flower/pull/2751), " -"[#2850](https://github.com/adap/flower/pull/2850), " -"[#2812](https://github.com/adap/flower/pull/2812), " -"[#2872](https://github.com/adap/flower/pull/2872), " -"[#2736](https://github.com/adap/flower/pull/2736), " -"[#2756](https://github.com/adap/flower/pull/2756), " -"[#2857](https://github.com/adap/flower/pull/2857), " -"[#2757](https://github.com/adap/flower/pull/2757), " -"[#2810](https://github.com/adap/flower/pull/2810), " -"[#2740](https://github.com/adap/flower/pull/2740), " -"[#2789](https://github.com/adap/flower/pull/2789))" +":py:obj:`collect_masked_vectors_stage " +"`\\" +" \\(driver\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:78 -msgid "" -"**General improvements** " -"([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), " -"[#2877](https://github.com/adap/flower/pull/2877), " -"[#2690](https://github.com/adap/flower/pull/2690), " -"[#2889](https://github.com/adap/flower/pull/2889), " -"[#2874](https://github.com/adap/flower/pull/2874), " -"[#2819](https://github.com/adap/flower/pull/2819), " -"[#2689](https://github.com/adap/flower/pull/2689), " -"[#2457](https://github.com/adap/flower/pull/2457), " -"[#2870](https://github.com/adap/flower/pull/2870), " -"[#2669](https://github.com/adap/flower/pull/2669), " -"[#2876](https://github.com/adap/flower/pull/2876), " -"[#2885](https://github.com/adap/flower/pull/2885), " -"[#2858](https://github.com/adap/flower/pull/2858), " -"[#2867](https://github.com/adap/flower/pull/2867), " -"[#2351](https://github.com/adap/flower/pull/2351), " -"[#2886](https://github.com/adap/flower/pull/2886), " -"[#2860](https://github.com/adap/flower/pull/2860), " -"[#2828](https://github.com/adap/flower/pull/2828), " -"[#2869](https://github.com/adap/flower/pull/2869), " -"[#2875](https://github.com/adap/flower/pull/2875), " -"[#2733](https://github.com/adap/flower/pull/2733), " -"[#2488](https://github.com/adap/flower/pull/2488), " -"[#2646](https://github.com/adap/flower/pull/2646), " -"[#2879](https://github.com/adap/flower/pull/2879), " -"[#2821](https://github.com/adap/flower/pull/2821), " -"[#2855](https://github.com/adap/flower/pull/2855), " -"[#2800](https://github.com/adap/flower/pull/2800), " -"[#2807](https://github.com/adap/flower/pull/2807), " -"[#2801](https://github.com/adap/flower/pull/2801), " -"[#2804](https://github.com/adap/flower/pull/2804), " -"[#2851](https://github.com/adap/flower/pull/2851), " -"[#2787](https://github.com/adap/flower/pull/2787), " -"[#2852](https://github.com/adap/flower/pull/2852), " -"[#2672](https://github.com/adap/flower/pull/2672), " -"[#2759](https://github.com/adap/flower/pull/2759))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of +msgid "Execute the 'collect masked vectors' stage." msgstr "" -#: ../../source/ref-changelog.md:82 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Deprecate** `start_numpy_client` " -"([#2563](https://github.com/adap/flower/pull/2563), " -"[#2718](https://github.com/adap/flower/pull/2718))" +":py:obj:`setup_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:84 -msgid "" -"Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we " -"have introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need " -"to first call the `.to_client()` method and then pass returned `Client` " -"object to `start_client`. The examples and the documentation have been " -"updated accordingly." +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 +#: of +msgid "Execute the 'setup' stage." msgstr "" -#: ../../source/ref-changelog.md:86 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Deprecate legacy DP wrappers** " -"([#2749](https://github.com/adap/flower/pull/2749))" +":py:obj:`share_keys_stage " +"`\\ " +"\\(driver\\, context\\, state\\)" msgstr "" -"**Supprimez KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:88 -msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is " -"in preparation for an all-new pluggable version of differential privacy " -"support in Flower." +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 +#: of +msgid "Execute the 'share keys' stage." msgstr "" -#: ../../source/ref-changelog.md:90 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Make optional arg** `--callable` **in** `flower-client` **a required " -"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -"**Log** `Client` **exceptions dans le moteur de client virtuel** " -"([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:92 -#, fuzzy -msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " -"([#2890](https://github.com/adap/flower/pull/2890))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 +#: of +msgid "Execute the 'unmask' stage." msgstr "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:94 +#: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:2 #, fuzzy +msgid "SecAggWorkflow" +msgstr "Flux de travail" + +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"**Drop experimental** `Task` **fields** " -"([#2866](https://github.com/adap/flower/pull/2866), " -"[#2865](https://github.com/adap/flower/pull/2865))" +"Bases: " +":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:96 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed " -"fields are superseded by the new `RecordSet` abstraction." +"The SecAgg protocol ensures the secure summation of integer vectors owned" +" by multiple parties, without accessing any individual integer vector. " +"This workflow allows the server to compute the weighted average of model " +"parameters across all clients, ensuring individual contributions remain " +"private. This is achieved by clients sending both, a weighting factor and" +" a weighted version of the locally updated parameters, both of which are " +"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" +" with masks, where weighting factor 'w' is the number of examples " +"('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" -#: ../../source/ref-changelog.md:98 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"**Retire MXNet examples** " -"([#2724](https://github.com/adap/flower/pull/2724))" +"The protocol involves four main stages: - 'setup': Send SecAgg " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" -"**Nouvel exemple de code scikit-learn** " -"([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:100 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"The development of the MXNet fremework has ended and the project is now " -"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " -"examples won't receive updates." +"Each client's private key is split into N shares under the SecAgg " +"protocol, where N is the number of selected clients." msgstr "" -#: ../../source/ref-changelog.md:102 -#, fuzzy -msgid "v1.6.0 (2023-11-28)" -msgstr "v1.4.0 (2023-04-21)" - -#: ../../source/ref-changelog.md:108 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " -"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," -" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " -"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " -"`cnxdeveloper`, `k3nfalt` " +"Generally, higher `reconstruction_threshold` means better privacy " +"guarantees but less tolerance to dropouts." msgstr "" -#: ../../source/ref-changelog.md:112 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" -"**Add experimental support for Python 3.12** " -"([#2565](https://github.com/adap/flower/pull/2565))" -msgstr "" -"**Ajouter la prise en charge expérimentale de Python 3.10 et Python " -"3.11** ([#1135](https://github.com/adap/flower/pull/1135))" +"When `reconstruction_threshold` is a float, it is interpreted as the " +"proportion of the number of all selected clients needed for the " +"reconstruction of a private key. This feature enables flexibility in " +"setting the security threshold relative to the number of selected " +"clients." +msgstr "" -#: ../../source/ref-changelog.md:114 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of msgid "" -"**Add new XGBoost examples** " -"([#2612](https://github.com/adap/flower/pull/2612), " -"[#2554](https://github.com/adap/flower/pull/2554), " -"[#2617](https://github.com/adap/flower/pull/2617), " -"[#2618](https://github.com/adap/flower/pull/2618), " -"[#2619](https://github.com/adap/flower/pull/2619), " -"[#2567](https://github.com/adap/flower/pull/2567))" +"`reconstruction_threshold`, and the quantization parameters " +"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg " +"protocol." msgstr "" -"**([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:116 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"We have added a new `xgboost-quickstart` example alongside a new " -"`xgboost-comprehensive` example that goes more in-depth." +":py:obj:`collect_masked_vectors_stage " +"`\\ " +"\\(driver\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:118 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Add Vertical FL example** " -"([#2598](https://github.com/adap/flower/pull/2598))" +":py:obj:`setup_stage `\\" +" \\(driver\\, context\\, state\\)" msgstr "" -"**Nouvel exemple de code CoreML pour iOS** " -"([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:120 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"We had many questions about Vertical Federated Learning using Flower, so " -"we decided to add an simple example for it on the [Titanic " -"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " -"tutorial (in the README)." +":py:obj:`share_keys_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:122 -#, fuzzy +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` " -"([#2292](https://github.com/adap/flower/pull/2292))" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -"Ajout de la prise en charge d'un `ClientManager` personnalisé comme " -"paramètre de `start_simulation` " -"([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:124 +#: ../../source/ref-api/flwr.simulation.rst:2 #, fuzzy +msgid "simulation" +msgstr "Simulation de moniteur" + +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -"**Update REST API to support create and delete nodes** " -"([#2283](https://github.com/adap/flower/pull/2283))" +":py:obj:`start_simulation `\\ \\(\\*\\," +" client\\_fn\\[\\, ...\\]\\)" msgstr "" -"**Nouvelle stratégie expérimentale TensorBoard** " -"([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:126 +#: ../../source/ref-api/flwr.simulation.rst:18::1 +#: flwr.simulation.app.start_simulation:1 of #, fuzzy +msgid "Start a Ray-based Flower simulation server." +msgstr "Simulation de moniteur" + +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -"**Update the Android SDK** " -"([#2187](https://github.com/adap/flower/pull/2187))" +":py:obj:`run_simulation `\\ " +"\\(server\\_app\\, client\\_app\\, ...\\)" msgstr "" -"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " -"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:128 -msgid "Add gRPC request-response capability to the Android SDK." +#: ../../source/ref-api/flwr.simulation.rst:18::1 +#: flwr.simulation.run_simulation.run_simulation:1 of +msgid "Run a Flower App using the Simulation Engine." msgstr "" -#: ../../source/ref-changelog.md:130 +#: ../../source/ref-api/flwr.simulation.run_simulation.rst:2 #, fuzzy +msgid "run\\_simulation" +msgstr "Simulation de moniteur" + +#: flwr.simulation.run_simulation.run_simulation:3 of msgid "" -"**Update the C++ SDK** " -"([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"The `ServerApp` to be executed. It will send messages to different " +"`ClientApp` instances running on different (virtual) SuperNodes." msgstr "" -"Mettre à jour les outils de développement " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:132 -msgid "Add gRPC request-response capability to the C++ SDK." +#: flwr.simulation.run_simulation.run_simulation:6 of +msgid "" +"The `ClientApp` to be executed by each of the SuperNodes. It will receive" +" messages sent by the `ServerApp`." msgstr "" -#: ../../source/ref-changelog.md:134 -#, fuzzy +#: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"**Make HTTPS the new default** " -"([#2591](https://github.com/adap/flower/pull/2591), " -"[#2636](https://github.com/adap/flower/pull/2636))" +"Number of nodes that run a ClientApp. They can be sampled by a Driver in " +"the ServerApp and receive a Message describing what the ClientApp should " +"perform." msgstr "" -"**Exemple de code mis à jour** " -"([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:136 -msgid "" -"Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP " -"for prototyping. The same applies to `flower-client`, which can either " -"use user-provided credentials or gRPC-bundled certificates to connect to " -"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " -"enable insecure HTTP connections." +#: flwr.simulation.run_simulation.run_simulation:13 of +msgid "A simulation backend that runs `ClientApp`s." msgstr "" -#: ../../source/ref-changelog.md:138 +#: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` " -"will still start in insecure mode by default. In a future release, " -"insecure connections will require user opt-in by passing `insecure=True`." +"'A dictionary, e.g {\"\": , \"\": } to " +"configure a backend. Values supported in are those included by " +"`flwr.common.typing.ConfigsRecordValues`." msgstr "" -#: ../../source/ref-changelog.md:140 -#, fuzzy +#: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"A boolean to indicate whether to enable GPU growth on the main thread. " +"This is desirable if you make use of a TensorFlow model on your " +"`ServerApp` while having your `ClientApp` running on the same GPU. " +"Without enabling this, you might encounter an out-of-memory error because" +" TensorFlow, by default, allocates all GPU memory. Read more about how " +"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " +"documentation: https://www.tensorflow.org/api/stable." msgstr "" -"**Mettre à jour les exemples de code** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:142 +#: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as " -"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" -" `start_simulation`) without requiring changes to how the client class is" -" defined and instantiated. The `to_client()` function is introduced to " -"convert a `NumPyClient` to a `Client`." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" +" enabled, DEBUG-level logs will be displayed." msgstr "" -#: ../../source/ref-changelog.md:144 +#: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 #, fuzzy +msgid "start\\_simulation" +msgstr "démarrer_simulation" + +#: flwr.simulation.app.start_simulation:3 of msgid "" -"**Add new** `Bulyan` **strategy** " -"([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891))" +"A function creating client instances. The function must take a single " +"`str` argument called `cid`. It should return a single client instance of" +" type Client. Note that the created client instances are ephemeral and " +"will often be destroyed after a single method invocation. Since client " +"instances are not long-lived, they should not attempt to carry state over" +" method invocations. Any state required by the instance (model, dataset, " +"hyperparameters, ...) should be (re-)created in either the call to " +"`client_fn` or the call to any of the client methods (e.g., load " +"evaluation data in the `evaluate` method itself)." msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:146 -#, fuzzy +#: flwr.simulation.app.start_simulation:13 of msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " -"2018](https://arxiv.org/abs/1802.07927)" +"The total number of clients in this simulation. This must be set if " +"`clients_ids` is not set and vice-versa." msgstr "" -"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " -"(FedMedian) par [Yin et al., 2018] " -"(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:148 -#, fuzzy +#: flwr.simulation.app.start_simulation:16 of msgid "" -"**Add new** `XGB Bagging` **strategy** " -"([#2611](https://github.com/adap/flower/pull/2611))" +"List `client_id`s for each client. This is only required if `num_clients`" +" is not set. Setting both `num_clients` and `clients_ids` with " +"`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:150 ../../source/ref-changelog.md:152 -#, fuzzy +#: flwr.simulation.app.start_simulation:20 of msgid "" -"**Introduce `WorkloadState`** " -"([#2564](https://github.com/adap/flower/pull/2564), " -"[#2632](https://github.com/adap/flower/pull/2632))" +"CPU and GPU resources for a single client. Supported keys are `num_cpus` " +"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " +"as well as using custom resources, please consult the Ray documentation." msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:156 -#, fuzzy +#: flwr.simulation.app.start_simulation:25 of msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"An implementation of the abstract base class `flwr.server.Server`. If no " +"instance is provided, then `start_server` will create one." msgstr "" -"**Mettre à jour les exemples de code** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:158 -#, fuzzy +#: flwr.simulation.app.start_simulation:31 of msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400))" +"An implementation of the abstract base class `flwr.server.Strategy`. If " +"no strategy is provided, then `start_server` will use " +"`flwr.server.strategy.FedAvg`." msgstr "" -"**Nouvel exemple de code JAX** " -"([#906](https://github.com/adap/flower/pull/906), " -"[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:160 -#, fuzzy +#: flwr.simulation.app.start_simulation:35 of msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_simulation` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" -"**Exemple de code mis à jour** " -"([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:162 -#, fuzzy +#: flwr.simulation.app.start_simulation:39 of msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"Optional dictionary containing arguments for the call to `ray.init`. If " +"ray_init_args is None (the default), Ray will be initialized with the " +"following default args: { \"ignore_reinit_error\": True, " +"\"include_dashboard\": False } An empty dictionary can be used " +"(ray_init_args={}) to prevent any arguments from being passed to " +"ray.init." msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:164 -#, fuzzy -msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +#: flwr.simulation.app.start_simulation:39 of +msgid "" +"Optional dictionary containing arguments for the call to `ray.init`. If " +"ray_init_args is None (the default), Ray will be initialized with the " +"following default args:" +msgstr "" -#: ../../source/ref-changelog.md:166 -#, fuzzy -msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" +#: flwr.simulation.app.start_simulation:43 of +msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" msgstr "" -"Amélioration de la documentation sur le serveur gRPC " -"([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:168 -#, fuzzy -msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" +#: flwr.simulation.app.start_simulation:45 of +msgid "" +"An empty dictionary can be used (ray_init_args={}) to prevent any " +"arguments from being passed to ray.init." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:170 -#, fuzzy -msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" +#: flwr.simulation.app.start_simulation:48 of +msgid "" +"Set to True to prevent `ray.shutdown()` in case " +"`ray.is_initialized()=True`." msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:172 -#, fuzzy -msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +#: flwr.simulation.app.start_simulation:50 of +msgid "" +"Optionally specify the type of actor to use. The actor object, which " +"persists throughout the simulation, will be the process in charge of " +"executing a ClientApp wrapping input argument `client_fn`." +msgstr "" -#: ../../source/ref-changelog.md:174 -#, fuzzy -msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +#: flwr.simulation.app.start_simulation:54 of +msgid "" +"If you want to create your own Actor classes, you might need to pass some" +" input argument. You can use this dictionary for such purpose." +msgstr "" + +#: flwr.simulation.app.start_simulation:57 of +msgid "" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " +"the VCE to choose in which node the actor is placed. If you are an " +"advanced user needed more control you can use lower-level scheduling " +"strategies to pin actors to specific compute nodes (e.g. via " +"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." +" For all details, please refer to the Ray documentation: " +"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +msgstr "" + +#: flwr.simulation.app.start_simulation:66 of +msgid "**hist** -- Object containing metrics from training." +msgstr "" + +#: ../../source/ref-changelog.md:1 +msgid "Changelog" +msgstr "Changelog" -#: ../../source/ref-changelog.md:176 +#: ../../source/ref-changelog.md:3 #, fuzzy -msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +msgid "Unreleased" +msgstr "Inédit" -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 +#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 +#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 +#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 +#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 +#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 +#: ../../source/ref-changelog.md:1022 +msgid "What's new?" +msgstr "Quoi de neuf ?" + +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 +#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 +#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 +#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 +#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 +msgid "Incompatible changes" +msgstr "Changements incompatibles" + +#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 +#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 +#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 +#: ../../source/ref-changelog.md:603 +msgid "None" +msgstr "Aucun" + +#: ../../source/ref-changelog.md:11 #, fuzzy +msgid "v1.8.0 (2024-04-03)" +msgstr "v1.3.0 (2023-02-06)" + +#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 +#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 +#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 +#: ../../source/ref-changelog.md:614 +msgid "Thanks to our contributors" +msgstr "Merci à nos contributeurs" + +#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 +#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 +#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 +#: ../../source/ref-changelog.md:478 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" +"Nous tenons à remercier tout particulièrement tous les contributeurs qui " +"ont rendu possible la nouvelle version de Flower (dans l'ordre `git " +"shortlog`) :" -#: ../../source/ref-changelog.md:180 -#, fuzzy +#: ../../source/ref-changelog.md:17 msgid "" -"**General updates to Flower Examples** " -"([#2384](https://github.com/adap/flower/pull/2384), " -"[#2425](https://github.com/adap/flower/pull/2425), " -"[#2526](https://github.com/adap/flower/pull/2526), " -"[#2302](https://github.com/adap/flower/pull/2302), " -"[#2545](https://github.com/adap/flower/pull/2545))" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " msgstr "" -"Mettre à jour les outils de développement " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:21 +msgid "" +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" +msgstr "" + +#: ../../source/ref-changelog.md:23 +msgid "" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " +"this multi-run) and execute the same project in either simulation " +"environments or deployment environments without having to change a single" +" line of code. The best part? It's fully compatible with existing Flower " +"projects that use `Strategy`, `NumPyClient` & co." +msgstr "" + +#: ../../source/ref-changelog.md:25 #, fuzzy msgid "" -"**General updates to Flower Baselines** " -"([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435), " -"[#2462](https://github.com/adap/flower/pull/2462), " -"[#2463](https://github.com/adap/flower/pull/2463), " -"[#2461](https://github.com/adap/flower/pull/2461), " -"[#2469](https://github.com/adap/flower/pull/2469), " -"[#2466](https://github.com/adap/flower/pull/2466), " -"[#2471](https://github.com/adap/flower/pull/2471), " -"[#2472](https://github.com/adap/flower/pull/2472), " -"[#2470](https://github.com/adap/flower/pull/2470))" +"**Introduce Flower Next low-level API (preview)** " +"([#3062](https://github.com/adap/flower/pull/3062), " +"[#3034](https://github.com/adap/flower/pull/3034), " +"[#3069](https://github.com/adap/flower/pull/3069))" msgstr "" -"**Améliorations générales** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**Mettre à jour les exemples de code** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:27 +msgid "" +"In addition to the Flower Next *high-level* API that uses `Strategy`, " +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " +"new Flower Next *low-level* API. The low-level API allows for granular " +"control of every aspect of the learning process by sending/receiving " +"individual messages to/from client nodes. The new `ServerApp` supports " +"registering a custom `main` function that allows writing custom training " +"loops for methods like async FL, cyclic training, or federated analytics." +" The new `ClientApp` supports registering `train`, `evaluate` and `query`" +" functions that can access the raw message received from the `ServerApp`." +" New abstractions like `RecordSet`, `Message` and `Context` further " +"enable sending multiple models, multiple sets of config values and " +"metrics, stateful computations on the client node and implementations of " +"custom SMPC protocols, to name just a few." +msgstr "" + +#: ../../source/ref-changelog.md:29 #, fuzzy msgid "" -"**General updates to the simulation engine** " -"([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), " -"[#2294](https://github.com/adap/flower/pull/2294))" +"**Introduce Flower Mods (preview)** " +"([#3054](https://github.com/adap/flower/pull/3054), " +"[#2911](https://github.com/adap/flower/pull/2911), " +"[#3083](https://github.com/adap/flower/pull/3083))" msgstr "" -"Mettre à jour les outils de développement " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"**Introduire la télémétrie optionnelle** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:31 +msgid "" +"Flower Modifiers (we call them Mods) can intercept messages and analyze, " +"edit or handle them directly. Mods can be used to develop pluggable " +"modules that work across different projects. Flower 1.8 already includes " +"mods to log the size of a message, the number of parameters sent over the" +" network, differential privacy with fixed clipping and adaptive clipping," +" local differential privacy and secure aggregation protocols SecAgg and " +"SecAgg+. The Flower Mods API is released as a preview, but researchers " +"can already use it to experiment with arbirtrary SMPC protocols." +msgstr "" + +#: ../../source/ref-changelog.md:33 #, fuzzy msgid "" -"**General updates to Flower SDKs** " -"([#2288](https://github.com/adap/flower/pull/2288), " -"[#2429](https://github.com/adap/flower/pull/2429), " -"[#2555](https://github.com/adap/flower/pull/2555), " -"[#2543](https://github.com/adap/flower/pull/2543), " -"[#2544](https://github.com/adap/flower/pull/2544), " -"[#2597](https://github.com/adap/flower/pull/2597), " -"[#2623](https://github.com/adap/flower/pull/2623))" +"**Fine-tune LLMs with LLM FlowerTune** " +"([#3029](https://github.com/adap/flower/pull/3029), " +"[#3089](https://github.com/adap/flower/pull/3089), " +"[#3092](https://github.com/adap/flower/pull/3092), " +"[#3100](https://github.com/adap/flower/pull/3100), " +"[#3114](https://github.com/adap/flower/pull/3114), " +"[#3162](https://github.com/adap/flower/pull/3162), " +"[#3172](https://github.com/adap/flower/pull/3172))" msgstr "" "**Tutoriel amélioré** ([#1468](https://github.com/adap/flower/pull/1468)," " [#1470](https://github.com/adap/flower/pull/1470), " @@ -15016,447 +15339,611 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:35 msgid "" -"**General improvements** " -"([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[#2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[#2317](https://github.com/adap/flower/pull/2317), " -"[#2349](https://github.com/adap/flower/pull/2349), " -"[#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446), " -"[#2561](https://github.com/adap/flower/pull/2561), " -"[#2273](https://github.com/adap/flower/pull/2273), " -"[#2267](https://github.com/adap/flower/pull/2267), " -"[#2274](https://github.com/adap/flower/pull/2274), " -"[#2275](https://github.com/adap/flower/pull/2275), " -"[#2432](https://github.com/adap/flower/pull/2432), " -"[#2251](https://github.com/adap/flower/pull/2251), " -"[#2321](https://github.com/adap/flower/pull/2321), " -"[#1936](https://github.com/adap/flower/pull/1936), " -"[#2408](https://github.com/adap/flower/pull/2408), " -"[#2413](https://github.com/adap/flower/pull/2413), " -"[#2401](https://github.com/adap/flower/pull/2401), " -"[#2531](https://github.com/adap/flower/pull/2531), " -"[#2534](https://github.com/adap/flower/pull/2534), " -"[#2535](https://github.com/adap/flower/pull/2535), " -"[#2521](https://github.com/adap/flower/pull/2521), " -"[#2553](https://github.com/adap/flower/pull/2553), " -"[#2596](https://github.com/adap/flower/pull/2596))" +"We are introducing LLM FlowerTune, an introductory example that " +"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " +"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" +" different models and/or datasets. Read our blog post [LLM FlowerTune: " +"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" +"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -#: ../../source/ref-changelog.md:190 ../../source/ref-changelog.md:280 -#: ../../source/ref-changelog.md:344 ../../source/ref-changelog.md:398 -#: ../../source/ref-changelog.md:465 -msgid "Flower received many improvements under the hood, too many to list here." +#: ../../source/ref-changelog.md:37 +#, fuzzy +msgid "" +"**Introduce built-in Differential Privacy (preview)** " +"([#2798](https://github.com/adap/flower/pull/2798), " +"[#2959](https://github.com/adap/flower/pull/2959), " +"[#3038](https://github.com/adap/flower/pull/3038), " +"[#3147](https://github.com/adap/flower/pull/3147), " +"[#2909](https://github.com/adap/flower/pull/2909), " +"[#2893](https://github.com/adap/flower/pull/2893), " +"[#2892](https://github.com/adap/flower/pull/2892), " +"[#3039](https://github.com/adap/flower/pull/3039), " +"[#3074](https://github.com/adap/flower/pull/3074))" msgstr "" -"Flower a reçu de nombreuses améliorations sous le capot, trop nombreuses " -"pour être énumérées ici." +"**([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:194 +#: ../../source/ref-changelog.md:39 +msgid "" +"Built-in Differential Privacy is here! Flower supports both central and " +"local differential privacy (DP). Central DP can be configured with either" +" fixed or adaptive clipping. The clipping can happen either on the " +"server-side or the client-side. Local DP does both clipping and noising " +"on the client-side. A new documentation page [explains Differential " +"Privacy approaches](https://flower.ai/docs/framework/explanation-" +"differential-privacy.html) and a new how-to guide describes [how to use " +"the new Differential Privacy components](https://flower.ai/docs/framework" +"/how-to-use-differential-privacy.html) in Flower." +msgstr "" + +#: ../../source/ref-changelog.md:41 #, fuzzy msgid "" -"**Remove support for Python 3.7** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" +"**Introduce built-in Secure Aggregation (preview)** " +"([#3120](https://github.com/adap/flower/pull/3120), " +"[#3110](https://github.com/adap/flower/pull/3110), " +"[#3108](https://github.com/adap/flower/pull/3108))" msgstr "" -"**Nouvel exemple de code MLCube** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"**Introduire la télémétrie optionnelle** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:43 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes" -" support. Flower now requires Python 3.8." +"Built-in Secure Aggregation is here! Flower now supports different secure" +" aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In " +"this initial release, we inlcude support for SecAgg and SecAgg+, but more" +" protocols will be implemented shortly. We'll also add detailed docs that" +" explain secure aggregation and how to use it in Flower. You can already " +"check out the new code example that shows how to use Flower to easily " +"combine Federated Learning, Differential Privacy and Secure Aggregation " +"in the same project." msgstr "" -#: ../../source/ref-changelog.md:198 +#: ../../source/ref-changelog.md:45 #, fuzzy msgid "" -"**Remove experimental argument** `rest` **from** `start_client` " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**Introduce** `flwr` **CLI (preview)** " +"([#2942](https://github.com/adap/flower/pull/2942), " +"[#3055](https://github.com/adap/flower/pull/3055), " +"[#3111](https://github.com/adap/flower/pull/3111), " +"[#3130](https://github.com/adap/flower/pull/3130), " +"[#3136](https://github.com/adap/flower/pull/3136), " +"[#3094](https://github.com/adap/flower/pull/3094), " +"[#3059](https://github.com/adap/flower/pull/3059), " +"[#3049](https://github.com/adap/flower/pull/3049), " +"[#3142](https://github.com/adap/flower/pull/3142))" msgstr "" -"**Supprimer les stratégies expérimentales** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:47 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` " -"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " -"experimental REST API instead." +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" +" and then running them using the Simulation Engine (`flwr run`)." msgstr "" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:49 #, fuzzy -msgid "v1.5.0 (2023-08-31)" -msgstr "v1.4.0 (2023-04-21)" - -#: ../../source/ref-changelog.md:208 msgid "" -"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " -"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " +"**Introduce Flower Next Simulation Engine** " +"([#3024](https://github.com/adap/flower/pull/3024), " +"[#3061](https://github.com/adap/flower/pull/3061), " +"[#2997](https://github.com/adap/flower/pull/2997), " +"[#2783](https://github.com/adap/flower/pull/2783), " +"[#3184](https://github.com/adap/flower/pull/3184), " +"[#3075](https://github.com/adap/flower/pull/3075), " +"[#3047](https://github.com/adap/flower/pull/3047), " +"[#2998](https://github.com/adap/flower/pull/2998), " +"[#3009](https://github.com/adap/flower/pull/3009), " +"[#3008](https://github.com/adap/flower/pull/3008))" msgstr "" +"**Introduire l'API REST (expérimentale)** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:212 -#, fuzzy +#: ../../source/ref-changelog.md:51 msgid "" -"**Introduce new simulation engine** " -"([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"The Flower Simulation Engine can now run Flower Next projects. For " +"notebook environments, there's also a new `run_simulation` function that " +"can run `ServerApp` and `ClientApp`." msgstr "" -"**Introduire la télémétrie optionnelle** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:53 +#, fuzzy msgid "" -"The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and" -" memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-" -"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"**Handle SuperNode connection errors** " +"([#2969](https://github.com/adap/flower/pull/2969))" msgstr "" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:216 +#: ../../source/ref-changelog.md:55 msgid "" -"Comprehensive documentation includes a new [how-to run " -"simulations](https://flower.ai/docs/framework/how-to-run-" -"simulations.html) guide, new [simulation-" -"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " -"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +"A SuperNode will now try to reconnect indefinitely to the SuperLink in " +"case of connection errors. The arguments `--max-retries` and `--max-wait-" +"time` can now be passed to the `flower-client-app` command. `--max-" +"retries` will define the number of tentatives the client should make " +"before it gives up trying to reconnect to the SuperLink, and, `--max-" +"wait-time` defines the time before the SuperNode gives up trying to " +"reconnect to the SuperLink." msgstr "" -#: ../../source/ref-changelog.md:218 +#: ../../source/ref-changelog.md:57 +#, fuzzy msgid "" -"**Restructure Flower Docs** " -"([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +"**General updates to Flower Baselines** " +"([#2904](https://github.com/adap/flower/pull/2904), " +"[#2482](https://github.com/adap/flower/pull/2482), " +"[#2985](https://github.com/adap/flower/pull/2985), " +"[#2968](https://github.com/adap/flower/pull/2968))" msgstr "" +"**Introduire une nouvelle fleur Référence : FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" -#: ../../source/ref-changelog.md:220 +#: ../../source/ref-changelog.md:59 msgid "" -"Much effort went into a completely restructured Flower docs experience. " -"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " -"divided into Flower Framework, Flower Baselines, Flower Android SDK, " -"Flower iOS SDK, and code example projects." +"There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " +"baseline. Several other baselined have been updated as well." msgstr "" -#: ../../source/ref-changelog.md:222 -#, fuzzy +#: ../../source/ref-changelog.md:61 msgid "" -"**Introduce Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +"**Improve documentation and translations** " +"([#3050](https://github.com/adap/flower/pull/3050), " +"[#3044](https://github.com/adap/flower/pull/3044), " +"[#3043](https://github.com/adap/flower/pull/3043), " +"[#2986](https://github.com/adap/flower/pull/2986), " +"[#3041](https://github.com/adap/flower/pull/3041), " +"[#3046](https://github.com/adap/flower/pull/3046), " +"[#3042](https://github.com/adap/flower/pull/3042), " +"[#2978](https://github.com/adap/flower/pull/2978), " +"[#2952](https://github.com/adap/flower/pull/2952), " +"[#3167](https://github.com/adap/flower/pull/3167), " +"[#2953](https://github.com/adap/flower/pull/2953), " +"[#3045](https://github.com/adap/flower/pull/3045), " +"[#2654](https://github.com/adap/flower/pull/2654), " +"[#3082](https://github.com/adap/flower/pull/3082), " +"[#2990](https://github.com/adap/flower/pull/2990), " +"[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" -"**Introduction du SDK iOS (aperçu)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-changelog.md:63 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support" -" on iOS is improving, and alongside the Swift SDK and code example, there" -" is now also an iOS quickstart tutorial." +"As usual, we merged many smaller and larger improvements to the " +"documentation. A special thank you goes to [Sebastian van der " +"Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" -#: ../../source/ref-changelog.md:226 +#: ../../source/ref-changelog.md:65 #, fuzzy msgid "" -"**Introduce Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**General updates to Flower Examples** " +"([3134](https://github.com/adap/flower/pull/3134), " +"[2996](https://github.com/adap/flower/pull/2996), " +"[2930](https://github.com/adap/flower/pull/2930), " +"[2967](https://github.com/adap/flower/pull/2967), " +"[2467](https://github.com/adap/flower/pull/2467), " +"[2910](https://github.com/adap/flower/pull/2910), " +"[#2918](https://github.com/adap/flower/pull/2918), " +"[#2773](https://github.com/adap/flower/pull/2773), " +"[#3063](https://github.com/adap/flower/pull/3063), " +"[#3116](https://github.com/adap/flower/pull/3116), " +"[#3117](https://github.com/adap/flower/pull/3117))" msgstr "" -"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " -"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" +"**Documentation mise à jour** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-changelog.md:67 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower " -"support on Android is improving, and alongside the Kotlin SDK and code " -"example, there is now also an Android quickstart tutorial." +"Two new examples show federated training of a Vision Transformer (ViT) " +"and federated learning in a medical context using the popular MONAI " +"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" +" new Flower Next `ServerApp` and `ClientApp`. Many other examples " +"received considerable updates as well." msgstr "" -#: ../../source/ref-changelog.md:230 -#, fuzzy +#: ../../source/ref-changelog.md:69 msgid "" -"**Introduce new end-to-end testing infrastructure** " -"([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" -msgstr "" -"**Améliorer l'API (expérimentale) du pilote** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**General improvements** " +"([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), " +"[3003](https://github.com/adap/flower/pull/3003), " +"[3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), " +"[3085](https://github.com/adap/flower/pull/3085), " +"[3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), " +"[2991](https://github.com/adap/flower/pull/2991), " +"[2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), " +"[3086](https://github.com/adap/flower/pull/3086), " +"[2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), " +"[2941](https://github.com/adap/flower/pull/2941), " +"[2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), " +"[2973](https://github.com/adap/flower/pull/2973), " +"[2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), " +"[3040](https://github.com/adap/flower/pull/3040), " +"[3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), " +"[2902](https://github.com/adap/flower/pull/2902), " +"[2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), " +"[3132](https://github.com/adap/flower/pull/3132), " +"[3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), " +"[3064](https://github.com/adap/flower/pull/3064), " +"[3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), " +"[3178](https://github.com/adap/flower/pull/3178), " +"[2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), " +"[3091](https://github.com/adap/flower/pull/3091), " +"[3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), " +"[3013](https://github.com/adap/flower/pull/3013), " +"[3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), " +"[3068](https://github.com/adap/flower/pull/3068), " +"[2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), " +"[2984](https://github.com/adap/flower/pull/2984), " +"[2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), " +"[3143](https://github.com/adap/flower/pull/3143), " +"[2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), " +"[2927](https://github.com/adap/flower/pull/2927), " +"[2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), " +"[2912](https://github.com/adap/flower/pull/2912), " +"[3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), " +"[2922](https://github.com/adap/flower/pull/2922), " +"[2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), " +"[3179](https://github.com/adap/flower/pull/3179), " +"[3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), " +"[3187](https://github.com/adap/flower/pull/3187), " +"[2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), " +"[3144](https://github.com/adap/flower/pull/3144), " +"[3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), " +"[#2836](https://github.com/adap/flower/pull/2836), " +"[#2929](https://github.com/adap/flower/pull/2929), " +"[#2943](https://github.com/adap/flower/pull/2943), " +"[#2955](https://github.com/adap/flower/pull/2955), " +"[#2954](https://github.com/adap/flower/pull/2954))" +msgstr "" + +#: ../../source/ref-changelog.md:75 +#, fuzzy +msgid "v1.7.0 (2024-02-05)" +msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:232 +#: ../../source/ref-changelog.md:81 msgid "" -"A new testing infrastructure ensures that new changes stay compatible " -"with existing framework integrations or strategies." +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " +"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " +"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " +"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " +"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " +"Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" -#: ../../source/ref-changelog.md:234 +#: ../../source/ref-changelog.md:85 #, fuzzy -msgid "**Deprecate Python 3.7**" -msgstr "**Créer le PR**" +msgid "" +"**Introduce stateful clients (experimental)** " +"([#2770](https://github.com/adap/flower/pull/2770), " +"[#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), " +"[#2643](https://github.com/adap/flower/pull/2643), " +"[#2769](https://github.com/adap/flower/pull/2769))" +msgstr "" +"**([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:236 +#: ../../source/ref-changelog.md:87 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" -" Python 3.7 is now deprecated and will be removed in an upcoming release." +"Subclasses of `Client` and `NumPyClient` can now store local state that " +"remains on the client. Let's start with the highlight first: this new " +"feature is compatible with both simulated clients (via " +"`start_simulation`) and networked clients (via `start_client`). It's also" +" the first preview of new abstractions like `Context` and `RecordSet`. " +"Clients can access state of type `RecordSet` via `state: RecordSet = " +"self.context.state`. Changes to this `RecordSet` are preserved across " +"different rounds of execution to enable stateful computations in a " +"unified way across simulation and deployment." msgstr "" -#: ../../source/ref-changelog.md:238 +#: ../../source/ref-changelog.md:89 #, fuzzy msgid "" -"**Add new** `FedTrimmedAvg` **strategy** " -"([#1769](https://github.com/adap/flower/pull/1769), " -"[#1853](https://github.com/adap/flower/pull/1853))" +"**Improve performance** " +"([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" -"**Ajouter un nouvel exemple de Federated Analytics avec Pandas** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"**Supprimer les stratégies expérimentales** " +"([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:240 -#, fuzzy +#: ../../source/ref-changelog.md:91 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)." +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" +"place aggregation to reduce memory consumption. The Flower client " +"serialization/deserialization has been rewritten from the ground up, " +"which results in significant speedups, especially when the client-side " +"training time is short." msgstr "" -"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " -"(FedMedian) par [Yin et al., 2018] " -"(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:242 +#: ../../source/ref-changelog.md:93 #, fuzzy msgid "" -"**Introduce start_driver** " -"([#1697](https://github.com/adap/flower/pull/1697))" +"**Support Federated Learning with Apple MLX and Flower** " +"([#2693](https://github.com/adap/flower/pull/2693))" msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " +"Flower** ([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:244 +#: ../../source/ref-changelog.md:95 msgid "" -"In addition to `start_server` and using the raw Driver API, there is a " -"new `start_driver` function that allows for running `start_server` " -"scripts as a Flower driver with only a single-line code change. Check out" -" the `mt-pytorch` code example to see a working example using " -"`start_driver`." +"Flower has official support for federated learning using [Apple " +"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " +"example." msgstr "" -#: ../../source/ref-changelog.md:246 +#: ../../source/ref-changelog.md:97 #, fuzzy msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** " -"([#1785](https://github.com/adap/flower/pull/1785))" +"**Introduce new XGBoost cyclic strategy** " +"([#2666](https://github.com/adap/flower/pull/2666), " +"[#2668](https://github.com/adap/flower/pull/2668))" msgstr "" -"**Nouvel exemple de code PyTorch avancé** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"**Introduction du SDK iOS (aperçu)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:248 +#: ../../source/ref-changelog.md:99 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a" -" driver script. The included `driver.py` and `server.py` have been " -"aligned to demonstrate both the low-level way and the high-level way of " -"building server-side logic." +"A new strategy called `FedXgbCyclic` supports a client-by-client style of" +" training (often called cyclic). The `xgboost-comprehensive` code example" +" shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower " +"offers best-in-class XGBoost support." msgstr "" -#: ../../source/ref-changelog.md:250 +#: ../../source/ref-changelog.md:101 #, fuzzy msgid "" -"**Migrate experimental REST API to Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"**Support Python 3.11** " +"([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" -"**Nouvelle stratégie expérimentale TensorBoard** " -"([#789](https://github.com/adap/flower/pull/789))" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:252 +#: ../../source/ref-changelog.md:103 msgid "" -"The (experimental) REST API used to be implemented in " -"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" -" use [Starlette](https://www.starlette.io/) directly." +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " +"ensure better support for users using more recent Python versions." msgstr "" -#: ../../source/ref-changelog.md:254 +#: ../../source/ref-changelog.md:105 #, fuzzy msgid "" -"Please note: The REST request-response API is still experimental and will" -" likely change significantly over time." +"**Update gRPC and ProtoBuf dependencies** " +"([#2814](https://github.com/adap/flower/pull/2814))" msgstr "" -"Remarque : l'API REST est encore expérimentale et est susceptible de " -"changer de manière significative au fil du temps." +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:256 -#, fuzzy +#: ../../source/ref-changelog.md:107 msgid "" -"**Introduce experimental gRPC request-response API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901))" +"The `grpcio` and `protobuf` dependencies were updated to their latest " +"versions for improved security and performance." msgstr "" -"**Introduire les enveloppes de confidentialité différentielle (aperçu)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:258 +#: ../../source/ref-changelog.md:109 +#, fuzzy msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) " -"and the experimental REST API, there is now a new gRPC API that uses a " -"request-response model to communicate with client nodes." +"**Introduce Docker image for Flower server** " +"([#2700](https://github.com/adap/flower/pull/2700), " +"[#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), " +"[#2695](https://github.com/adap/flower/pull/2695), " +"[#2747](https://github.com/adap/flower/pull/2747), " +"[#2746](https://github.com/adap/flower/pull/2746), " +"[#2680](https://github.com/adap/flower/pull/2680), " +"[#2682](https://github.com/adap/flower/pull/2682), " +"[#2701](https://github.com/adap/flower/pull/2701))" msgstr "" +"**([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:260 -#, fuzzy +#: ../../source/ref-changelog.md:111 msgid "" -"Please note: The gRPC request-response API is still experimental and will" -" likely change significantly over time." +"The Flower server can now be run using an official Docker image. A new " +"how-to guide explains [how to run Flower using " +"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html). An official Flower client Docker image will follow." msgstr "" -"Remarque : l'API REST est encore expérimentale et est susceptible de " -"changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:113 #, fuzzy msgid "" -"**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"**Introduce** `flower-via-docker-compose` **example** " +"([#2626](https://github.com/adap/flower/pull/2626))" msgstr "" -"**Initialise** `start_simulation` **avec une liste d'ID de clients** " -"([#860](https://github.com/adap/flower/pull/860))" +"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " +"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:115 +#, fuzzy msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in " -"favour of a new argument `transport`. `start_client(transport=\"rest\")` " -"will yield the same behaviour as `start_client(rest=True)` did before. " -"All code should migrate to the new argument `transport`. The deprecated " -"argument `rest` will be removed in a future release." +"**Introduce** `quickstart-sklearn-tabular` **example** " +"([#2719](https://github.com/adap/flower/pull/2719))" msgstr "" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:266 +#: ../../source/ref-changelog.md:117 #, fuzzy msgid "" -"**Add a new gRPC option** " -"([#2197](https://github.com/adap/flower/pull/2197))" +"**Introduce** `custom-metrics` **example** " +"([#1958](https://github.com/adap/flower/pull/1958))" msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:119 +#, fuzzy msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" -" option set to 0 by default. This prevents the clients from sending " -"keepalive pings when there is no outstanding stream." +"**Update code examples to use Flower Datasets** " +"([#2450](https://github.com/adap/flower/pull/2450), " +"[#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), " +"[#2712](https://github.com/adap/flower/pull/2712))" +msgstr "" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" + +#: ../../source/ref-changelog.md:121 +msgid "" +"Several code examples were updated to use [Flower " +"Datasets](https://flower.ai/docs/datasets/)." msgstr "" -#: ../../source/ref-changelog.md:270 +#: ../../source/ref-changelog.md:123 #, fuzzy msgid "" -"**Improve example notebooks** " -"([#2005](https://github.com/adap/flower/pull/2005))" +"**General updates to Flower Examples** " +"([#2381](https://github.com/adap/flower/pull/2381), " +"[#2805](https://github.com/adap/flower/pull/2805), " +"[#2782](https://github.com/adap/flower/pull/2782), " +"[#2806](https://github.com/adap/flower/pull/2806), " +"[#2829](https://github.com/adap/flower/pull/2829), " +"[#2825](https://github.com/adap/flower/pull/2825), " +"[#2816](https://github.com/adap/flower/pull/2816), " +"[#2726](https://github.com/adap/flower/pull/2726), " +"[#2659](https://github.com/adap/flower/pull/2659), " +"[#2655](https://github.com/adap/flower/pull/2655))" msgstr "" -"**Supprimer les stratégies expérimentales** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Améliorer l'API (expérimentale) du pilote** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:272 +#: ../../source/ref-changelog.md:125 +msgid "Many Flower code examples received substantial updates." +msgstr "" + +#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 #, fuzzy -msgid "There's a new 30min Federated Learning PyTorch tutorial!" -msgstr "Bienvenue au tutoriel sur l'apprentissage fédéré de la fleur !" +msgid "**Update Flower Baselines**" +msgstr "Demande pour une nouvelle Flower Baseline" -#: ../../source/ref-changelog.md:274 +#: ../../source/ref-changelog.md:129 +#, fuzzy msgid "" -"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " +"[#2771](https://github.com/adap/flower/pull/2771))" +msgstr "" +"**Nouvel exemple de code JAX** " +"([#906](https://github.com/adap/flower/pull/906), " +"[#1143](https://github.com/adap/flower/pull/1143))" + +#: ../../source/ref-changelog.md:130 +#, fuzzy +msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "" +"Amélioration de la documentation sur le serveur gRPC " +"([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:276 -msgid "" -"Many examples have received significant updates, including simplified " -"advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A" -" major upgrade is that all code examples now have a `requirements.txt` " -"(in addition to `pyproject.toml`)." +#: ../../source/ref-changelog.md:131 +#, fuzzy +msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:278 +#: ../../source/ref-changelog.md:132 +#, fuzzy +msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" + +#: ../../source/ref-changelog.md:133 +#, fuzzy +msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" + +#: ../../source/ref-changelog.md:134 +#, fuzzy +msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" +msgstr "" +"**Renommé stratégie q-FedAvg** " +"([#802](https://github.com/adap/flower/pull/802))" + +#: ../../source/ref-changelog.md:136 #, fuzzy msgid "" -"**General improvements** " -"([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" +"**Improve documentation** " +"([#2674](https://github.com/adap/flower/pull/2674), " +"[#2480](https://github.com/adap/flower/pull/2480), " +"[#2826](https://github.com/adap/flower/pull/2826), " +"[#2727](https://github.com/adap/flower/pull/2727), " +"[#2761](https://github.com/adap/flower/pull/2761), " +"[#2900](https://github.com/adap/flower/pull/2900))" msgstr "" "**Mise à jour de la documentation** " "([#1629](https://github.com/adap/flower/pull/1629), " @@ -15467,8675 +15954,9466 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:284 ../../source/ref-changelog.md:348 -#: ../../source/ref-changelog.md:406 ../../source/ref-changelog.md:475 -#: ../../source/ref-changelog.md:537 -msgid "None" -msgstr "Aucun" - -#: ../../source/ref-changelog.md:286 -msgid "v1.4.0 (2023-04-21)" -msgstr "v1.4.0 (2023-04-21)" - -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:138 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"**Improved testing and development infrastructure** " +"([#2797](https://github.com/adap/flower/pull/2797), " +"[#2676](https://github.com/adap/flower/pull/2676), " +"[#2644](https://github.com/adap/flower/pull/2644), " +"[#2656](https://github.com/adap/flower/pull/2656), " +"[#2848](https://github.com/adap/flower/pull/2848), " +"[#2675](https://github.com/adap/flower/pull/2675), " +"[#2735](https://github.com/adap/flower/pull/2735), " +"[#2767](https://github.com/adap/flower/pull/2767), " +"[#2732](https://github.com/adap/flower/pull/2732), " +"[#2744](https://github.com/adap/flower/pull/2744), " +"[#2681](https://github.com/adap/flower/pull/2681), " +"[#2699](https://github.com/adap/flower/pull/2699), " +"[#2745](https://github.com/adap/flower/pull/2745), " +"[#2734](https://github.com/adap/flower/pull/2734), " +"[#2731](https://github.com/adap/flower/pull/2731), " +"[#2652](https://github.com/adap/flower/pull/2652), " +"[#2720](https://github.com/adap/flower/pull/2720), " +"[#2721](https://github.com/adap/flower/pull/2721), " +"[#2717](https://github.com/adap/flower/pull/2717), " +"[#2864](https://github.com/adap/flower/pull/2864), " +"[#2694](https://github.com/adap/flower/pull/2694), " +"[#2709](https://github.com/adap/flower/pull/2709), " +"[#2658](https://github.com/adap/flower/pull/2658), " +"[#2796](https://github.com/adap/flower/pull/2796), " +"[#2692](https://github.com/adap/flower/pull/2692), " +"[#2657](https://github.com/adap/flower/pull/2657), " +"[#2813](https://github.com/adap/flower/pull/2813), " +"[#2661](https://github.com/adap/flower/pull/2661), " +"[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:140 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " -"example)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" +"The Flower testing and development infrastructure has received " +"substantial updates. This makes Flower 1.7 the most tested release ever." msgstr "" -"**Introduire la prise en charge de XGBoost (**`FedXgbNnAvg` **stratégie " -"et exemple)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:142 msgid "" -"XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" -" " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" and a [code example](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart) that demonstrates the usage of this new strategy in " -"an XGBoost project." +"**Update dependencies** " +"([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), " +"[#2739](https://github.com/adap/flower/pull/2739), " +"[#2837](https://github.com/adap/flower/pull/2837), " +"[#2788](https://github.com/adap/flower/pull/2788), " +"[#2811](https://github.com/adap/flower/pull/2811), " +"[#2774](https://github.com/adap/flower/pull/2774), " +"[#2790](https://github.com/adap/flower/pull/2790), " +"[#2751](https://github.com/adap/flower/pull/2751), " +"[#2850](https://github.com/adap/flower/pull/2850), " +"[#2812](https://github.com/adap/flower/pull/2812), " +"[#2872](https://github.com/adap/flower/pull/2872), " +"[#2736](https://github.com/adap/flower/pull/2736), " +"[#2756](https://github.com/adap/flower/pull/2756), " +"[#2857](https://github.com/adap/flower/pull/2857), " +"[#2757](https://github.com/adap/flower/pull/2757), " +"[#2810](https://github.com/adap/flower/pull/2810), " +"[#2740](https://github.com/adap/flower/pull/2740), " +"[#2789](https://github.com/adap/flower/pull/2789))" msgstr "" -"Nous avons ajouté une nouvelle [stratégie] `FedXgbNnAvg` " -"(https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" et un [exemple de code] " -"(https://github.com/adap/flower/tree/main/examples/xgboost-quickstart) " -"qui démontre l'utilisation de cette nouvelle stratégie dans un projet " -"XGBoost." -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:144 msgid "" -"**Introduce iOS SDK (preview)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**General improvements** " +"([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), " +"[#2877](https://github.com/adap/flower/pull/2877), " +"[#2690](https://github.com/adap/flower/pull/2690), " +"[#2889](https://github.com/adap/flower/pull/2889), " +"[#2874](https://github.com/adap/flower/pull/2874), " +"[#2819](https://github.com/adap/flower/pull/2819), " +"[#2689](https://github.com/adap/flower/pull/2689), " +"[#2457](https://github.com/adap/flower/pull/2457), " +"[#2870](https://github.com/adap/flower/pull/2870), " +"[#2669](https://github.com/adap/flower/pull/2669), " +"[#2876](https://github.com/adap/flower/pull/2876), " +"[#2885](https://github.com/adap/flower/pull/2885), " +"[#2858](https://github.com/adap/flower/pull/2858), " +"[#2867](https://github.com/adap/flower/pull/2867), " +"[#2351](https://github.com/adap/flower/pull/2351), " +"[#2886](https://github.com/adap/flower/pull/2886), " +"[#2860](https://github.com/adap/flower/pull/2860), " +"[#2828](https://github.com/adap/flower/pull/2828), " +"[#2869](https://github.com/adap/flower/pull/2869), " +"[#2875](https://github.com/adap/flower/pull/2875), " +"[#2733](https://github.com/adap/flower/pull/2733), " +"[#2488](https://github.com/adap/flower/pull/2488), " +"[#2646](https://github.com/adap/flower/pull/2646), " +"[#2879](https://github.com/adap/flower/pull/2879), " +"[#2821](https://github.com/adap/flower/pull/2821), " +"[#2855](https://github.com/adap/flower/pull/2855), " +"[#2800](https://github.com/adap/flower/pull/2800), " +"[#2807](https://github.com/adap/flower/pull/2807), " +"[#2801](https://github.com/adap/flower/pull/2801), " +"[#2804](https://github.com/adap/flower/pull/2804), " +"[#2851](https://github.com/adap/flower/pull/2851), " +"[#2787](https://github.com/adap/flower/pull/2787), " +"[#2852](https://github.com/adap/flower/pull/2852), " +"[#2672](https://github.com/adap/flower/pull/2672), " +"[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" -"**Introduction du SDK iOS (aperçu)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:148 +#, fuzzy msgid "" -"This is a major update for anyone wanting to implement Federated Learning" -" on iOS mobile devices. We now have a swift iOS SDK present under " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" that will facilitate greatly the app creating process. To showcase its " -"use, the [iOS " -"example](https://github.com/adap/flower/tree/main/examples/ios) has also " -"been updated!" +"**Deprecate** `start_numpy_client` " +"([#2563](https://github.com/adap/flower/pull/2563), " +"[#2718](https://github.com/adap/flower/pull/2718))" msgstr "" -"Il s'agit d'une mise à jour majeure pour tous ceux qui souhaitent mettre " -"en œuvre l'apprentissage fédéré sur les appareils mobiles iOS. Nous " -"disposons désormais d'un SDK swift iOS présent sous " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" qui facilitera grandement le processus de création d'applications. Pour " -"présenter son utilisation, l'[exemple " -"iOS](https://github.com/adap/flower/tree/main/examples/ios) a également " -"été mis à jour !" +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:150 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** " -"([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" +"Until now, clients of type `NumPyClient` needed to be started via " +"`start_numpy_client`. In our efforts to consolidate framework APIs, we " +"have introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need " +"to first call the `.to_client()` method and then pass returned `Client` " +"object to `start_client`. The examples and the documentation have been " +"updated accordingly." msgstr "" -"**Introduire un nouveau tutoriel \"Qu'est-ce que l'apprentissage fédéré ?" -" \"** ([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:152 #, fuzzy msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html) in our documentation explains the basics" -" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" -" Learning to start their journey with Flower. Forward it to anyone who's " -"interested in Federated Learning!" +"**Deprecate legacy DP wrappers** " +"([#2749](https://github.com/adap/flower/pull/2749))" msgstr "" -"Un nouveau [tutoriel d'entrée de gamme] " -"(https://flower.ai/docs/tutorial/Flower-0-What-is-FL.html) dans notre " -"documentation explique les bases de l'apprentissage fédéré. Il permet à " -"tous ceux qui ne connaissent pas l'apprentissage fédéré de commencer leur" -" voyage avec Flower. Fais-le suivre à tous ceux qui s'intéressent à " -"l'apprentissage fédéré !" +"**Supprimez KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:154 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" +"Legacy DP wrapper classes are deprecated, but still functional. This is " +"in preparation for an all-new pluggable version of differential privacy " +"support in Flower." msgstr "" -"**Introduire une nouvelle fleur Référence : FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:156 +#, fuzzy msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated" -" Optimization in Heterogeneous Networks (Li et al., " -"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," -" which aims at making convergence more robust in heterogeneous settings." +"**Make optional arg** `--callable` **in** `flower-client` **a required " +"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" -"Cette nouvelle ligne de base reproduit la tâche MNIST+CNN de l'article " -"[Federated Optimization in Heterogeneous Networks (Li et al., 2018)] " -"(https://arxiv.org/abs/1812.06127). Elle utilise la stratégie `FedProx`, " -"qui vise à rendre la convergence plus robuste dans des contextes " -"hétérogènes." +"**Log** `Client` **exceptions dans le moteur de client virtuel** " +"([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:158 +#, fuzzy msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " +"([#2890](https://github.com/adap/flower/pull/2890))" msgstr "" -"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " -"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:160 +#, fuzzy msgid "" -"This new baseline replicates an experiment evaluating the performance of " -"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " -"Benchmark for Federated Settings (Caldas et al., " -"2018)](https://arxiv.org/abs/1812.01097)." +"**Drop experimental** `Task` **fields** " +"([#2866](https://github.com/adap/flower/pull/2866), " +"[#2865](https://github.com/adap/flower/pull/2865))" msgstr "" -"Cette nouvelle ligne de base reproduit une expérience évaluant les " -"performances de l'algorithme FedAvg sur le jeu de données FEMNIST tiré de" -" l'article [LEAF : A Benchmark for Federated Settings (Caldas et al., " -"2018)] (https://arxiv.org/abs/1812.01097)." +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:162 msgid "" -"**Introduce (experimental) REST API** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" +"Experimental fields `sa`, `legacy_server_message` and " +"`legacy_client_message` were removed from `Task` message. The removed " +"fields are superseded by the new `RecordSet` abstraction." msgstr "" -"**Introduire l'API REST (expérimentale)** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:164 +#, fuzzy msgid "" -"A new REST API has been introduced as an alternative to the gRPC-based " -"communication stack. In this initial version, the REST API only supports " -"anonymous clients." +"**Retire MXNet examples** " +"([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" -"Une nouvelle API REST a été introduite comme alternative à la pile de " -"communication basée sur gRPC. Dans cette version initiale, l'API REST ne " -"prend en charge que les clients anonymes." +"**Nouvel exemple de code scikit-learn** " +"([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:166 msgid "" -"Please note: The REST API is still experimental and will likely change " -"significantly over time." +"The development of the MXNet fremework has ended and the project is now " +"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " +"examples won't receive updates." msgstr "" -"Remarque : l'API REST est encore expérimentale et est susceptible de " -"changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:168 +#, fuzzy +msgid "v1.6.0 (2023-11-28)" +msgstr "v1.4.0 (2023-04-21)" + +#: ../../source/ref-changelog.md:174 msgid "" -"**Improve the (experimental) Driver API** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " +"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," +" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " +"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " +"`cnxdeveloper`, `k3nfalt` " msgstr "" -"**Améliorer l'API (expérimentale) du pilote** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:178 +#, fuzzy msgid "" -"The Driver API is still an experimental feature, but this release " -"introduces some major upgrades. One of the main improvements is the " -"introduction of an SQLite database to store server state on disk (instead" -" of in-memory). Another improvement is that tasks (instructions or " -"results) that have been delivered will now be deleted. This greatly " -"improves the memory efficiency of a long-running Flower server." +"**Add experimental support for Python 3.12** " +"([#2565](https://github.com/adap/flower/pull/2565))" msgstr "" -"L'API du pilote est encore une fonction expérimentale, mais cette version" -" introduit quelques améliorations majeures. L'une des principales " -"améliorations est l'introduction d'une base de données SQLite pour " -"stocker l'état du serveur sur le disque (au lieu de la mémoire). Une " -"autre amélioration est que les tâches (instructions ou résultats) qui ont" -" été livrées seront désormais supprimées, ce qui améliore " -"considérablement l'efficacité de la mémoire d'un serveur Flower " -"fonctionnant depuis longtemps." +"**Ajouter la prise en charge expérimentale de Python 3.10 et Python " +"3.11** ([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:180 +#, fuzzy msgid "" -"**Fix spilling issues related to Ray during simulations** " -"([#1698](https://github.com/adap/flower/pull/1698))" +"**Add new XGBoost examples** " +"([#2612](https://github.com/adap/flower/pull/2612), " +"[#2554](https://github.com/adap/flower/pull/2554), " +"[#2617](https://github.com/adap/flower/pull/2617), " +"[#2618](https://github.com/adap/flower/pull/2618), " +"[#2619](https://github.com/adap/flower/pull/2619), " +"[#2567](https://github.com/adap/flower/pull/2567))" msgstr "" -"**Répare les problèmes de déversement liés à Ray pendant les " -"simulations** ([#1698](https://github.com/adap/flower/pull/1698))" +"**([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:182 +msgid "" +"We have added a new `xgboost-quickstart` example alongside a new " +"`xgboost-comprehensive` example that goes more in-depth." +msgstr "" + +#: ../../source/ref-changelog.md:184 #, fuzzy msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts" -" of data that would make the training unable to continue. This is now " -"fixed! 🎉" +"**Add Vertical FL example** " +"([#2598](https://github.com/adap/flower/pull/2598))" msgstr "" -"Lors de l'exécution de longues simulations, `ray` déversait parfois " -"d'énormes quantités de données qui rendaient l'entraînement incapable de " -"continuer. ce problème est maintenant corrigé ! 🎉" +"**Nouvel exemple de code CoreML pour iOS** " +"([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:186 msgid "" -"**Add new example using** `TabNet` **and Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"We had many questions about Vertical Federated Learning using Flower, so " +"we decided to add an simple example for it on the [Titanic " +"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " +"tutorial (in the README)." msgstr "" -"**Ajouter un nouvel exemple utilisant** `TabNet` **et Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:188 +#, fuzzy msgid "" -"TabNet is a powerful and flexible framework for training machine learning" -" models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" -"/quickstart-tabnet)." +"**Support custom** `ClientManager` **in** `start_driver()` " +"([#2292](https://github.com/adap/flower/pull/2292))" msgstr "" -"TabNet est un cadre puissant et flexible pour former des modèles " -"d'apprentissage automatique sur des données tabulaires. Nous avons " -"maintenant un exemple fédéré utilisant Flower : [quickstart-" -"tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" -"tabnet)." +"Ajout de la prise en charge d'un `ClientManager` personnalisé comme " +"paramètre de `start_simulation` " +"([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:190 +#, fuzzy msgid "" -"**Add new how-to guide for monitoring simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" +"**Update REST API to support create and delete nodes** " +"([#2283](https://github.com/adap/flower/pull/2283))" msgstr "" -"**Ajouter un nouveau guide pratique pour le suivi des simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" +"**Nouvelle stratégie expérimentale TensorBoard** " +"([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:192 +#, fuzzy msgid "" -"We now have a documentation guide to help users monitor their performance" -" during simulations." +"**Update the Android SDK** " +"([#2187](https://github.com/adap/flower/pull/2187))" msgstr "" -"Nous avons maintenant un guide de documentation pour aider les " -"utilisateurs à surveiller leurs performances pendant les simulations." +"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " +"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:194 +msgid "Add gRPC request-response capability to the Android SDK." +msgstr "" + +#: ../../source/ref-changelog.md:196 +#, fuzzy msgid "" -"**Add training metrics to** `History` **object during simulations** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**Update the C++ SDK** " +"([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" msgstr "" -"**Ajouter des mesures de formation à** `History` **objet pendant les " -"simulations** ([#1696](https://github.com/adap/flower/pull/1696))" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:198 +msgid "Add gRPC request-response capability to the C++ SDK." +msgstr "" + +#: ../../source/ref-changelog.md:200 +#, fuzzy msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training " -"metrics, but previous releases did not save the results in the `History` " -"object. This is now the case!" +"**Make HTTPS the new default** " +"([#2591](https://github.com/adap/flower/pull/2591), " +"[#2636](https://github.com/adap/flower/pull/2636))" msgstr "" -"La fonction `fit_metrics_aggregation_fn` peut être utilisée pour agréger " -"les mesures d'entraînement, mais les versions précédentes " -"n'enregistraient pas les résultats dans l'objet `History`. c'est " -"désormais le cas !" +"**Exemple de code mis à jour** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:202 msgid "" -"**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" +"Flower is moving to HTTPS by default. The new `flower-server` requires " +"passing `--certificates`, but users can enable `--insecure` to use HTTP " +"for prototyping. The same applies to `flower-client`, which can either " +"use user-provided credentials or gRPC-bundled certificates to connect to " +"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " +"enable insecure HTTP connections." msgstr "" -"**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/ada" - -#: ../../source/ref-changelog.md:350 -msgid "v1.3.0 (2023-02-06)" -msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:356 +#: ../../source/ref-changelog.md:204 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"For backward compatibility, `start_client()` and `start_numpy_client()` " +"will still start in insecure mode by default. In a future release, " +"insecure connections will require user opt-in by passing `insecure=True`." msgstr "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" -#: ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:206 +#, fuzzy msgid "" -"**Add support for** `workload_id` **and** `group_id` **in Driver API** " -"([#1595](https://github.com/adap/flower/pull/1595))" +"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" msgstr "" -"**Ajouter la prise en charge de** `workload_id` **et** `group_id` **dans " -"l'API du pilote** ([#1595](https://github.com/adap/flower/pull/1595))" +"**Mettre à jour les exemples de code** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:208 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be " -"used to identify which workload a task belongs to. It also supports a new" -" `group_id` that can be used, for example, to indicate the current " -"training round. Both the `workload_id` and `group_id` enable client nodes" -" to decide whether they want to handle a task or not." +"Using the `client_fn`, Flower clients can interchangeably run as " +"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" +" `start_simulation`) without requiring changes to how the client class is" +" defined and instantiated. The `to_client()` function is introduced to " +"convert a `NumPyClient` to a `Client`." msgstr "" -"L'API (expérimentale) Driver prend désormais en charge un `workload_id` " -"qui peut être utilisé pour identifier la charge de travail à laquelle une" -" tâche appartient. Elle prend également en charge un nouveau `group_id` " -"qui peut être utilisé, par exemple, pour indiquer le cycle de formation " -"en cours. Le `workload_id` et le `group_id` permettent tous deux aux " -"nœuds clients de décider s'ils veulent traiter une tâche ou non." -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:210 +#, fuzzy msgid "" -"**Make Driver API and Fleet API address configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Add new** `Bulyan` **strategy** " +"([#1817](https://github.com/adap/flower/pull/1817), " +"[#1891](https://github.com/adap/flower/pull/1891))" msgstr "" -"**Faire en sorte que l'adresse de l'API du conducteur et de l'API de la " -"flotte soit configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:212 +#, fuzzy msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) " -"can now configure the server address of both Driver API (via `--driver-" -"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " +"2018](https://arxiv.org/abs/1802.07927)" msgstr "" -"Le serveur Flower (expérimental) de longue durée (Driver API et Fleet " -"API) peut maintenant configurer l'adresse du serveur de Driver API (via " -"`--driver-api-address`) et de Fleet API (via `--fleet-api-address`) lors " -"de son démarrage :" +"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " +"(FedMedian) par [Yin et al., 2018] " +"(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:214 #, fuzzy msgid "" -"`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " -"\"0.0.0.0:8086\"`" +"**Add new** `XGB Bagging` **strategy** " +"([#2611](https://github.com/adap/flower/pull/2611))" msgstr "" -"``flower-superlink --driver-api-address \"0.0.0.0:8081\" --fleet-api-" -"address \"0.0.0.0:8086\" ``" - -#: ../../source/ref-changelog.md:370 -msgid "Both IPv4 and IPv6 addresses are supported." -msgstr "Les adresses IPv4 et IPv6 sont toutes deux prises en charge." +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 +#, fuzzy msgid "" -"**Add new example of Federated Learning using fastai and Flower** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"**Introduce `WorkloadState`** " +"([#2564](https://github.com/adap/flower/pull/2564), " +"[#2632](https://github.com/adap/flower/pull/2632))" msgstr "" -"**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " -"Flower** ([#1598](https://github.com/adap/flower/pull/1598))" +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:222 +#, fuzzy msgid "" -"A new code example (`quickstart-fastai`) demonstrates federated learning " -"with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" -"/quickstart-fastai)." +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " +"[#2286](https://github.com/adap/flower/pull/2286), " +"[#2509](https://github.com/adap/flower/pull/2509))" msgstr "" -"Un nouvel exemple de code (`quickstart-fastai`) démontre l'apprentissage " -"fédéré avec [fastai](https://www.fast.ai/) et Flower. Tu peux le trouver " -"ici : [quickstart-" -"fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" -"fastai)." +"**Mettre à jour les exemples de code** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:376 +#: ../../source/ref-changelog.md:224 +#, fuzzy msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" -" versions of Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400))" msgstr "" -"**Rendre l'exemple Android compatible avec** `flwr >= 1.0.0` **et les " -"dernières versions d'Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"**Nouvel exemple de code JAX** " +"([#906](https://github.com/adap/flower/pull/906), " +"[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:378 +#: ../../source/ref-changelog.md:226 #, fuzzy msgid "" -"The Android code example has received a substantial update: the project " -"is compatible with Flower 1.0 (and later), the UI received a full " -"refresh, and the project is updated to be compatible with newer Android " -"tooling." +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " +"[#2507](https://github.com/adap/flower/pull/2507))" msgstr "" -"L'exemple de code Android a reçu une mise à jour substantielle : le " -"projet est compatible avec Flower 1.0 et les versions ultérieures, " -"l'interface utilisateur a reçu un rafraîchissement complet, et le projet " -"est mis à jour pour être compatible avec les outils Android les plus " -"récents." +"**Exemple de code mis à jour** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:380 +#: ../../source/ref-changelog.md:228 +#, fuzzy msgid "" -"**Add new `FedProx` strategy** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" msgstr "" -"**Ajouter une nouvelle stratégie `FedProx`** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:382 -msgid "" -"This " -"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" is almost identical to " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" but helps users replicate what is described in this " -"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " -"parameter called `proximal_mu` to regularize the local models with " -"respect to the global models." -msgstr "" -"Cette " -"[stratégie](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" est presque identique à " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" mais aide les utilisateurs à reproduire ce qui est décrit dans cet " -"[article](https://arxiv.org/abs/1812.06127). Elle ajoute essentiellement " -"un paramètre appelé `proximal_mu` pour régulariser les modèles locaux par" -" rapport aux modèles globaux." +#: ../../source/ref-changelog.md:230 +#, fuzzy +msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:384 -msgid "" -"**Add new metrics to telemetry events** " -"([#1640](https://github.com/adap/flower/pull/1640))" +#: ../../source/ref-changelog.md:232 +#, fuzzy +msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "" -"**Ajouter de nouvelles métriques aux événements de télémétrie** " -"([#1640](https://github.com/adap/flower/pull/1640))" +"Amélioration de la documentation sur le serveur gRPC " +"([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:386 -msgid "" -"An updated event structure allows, for example, the clustering of events " -"within the same workload." +#: ../../source/ref-changelog.md:234 +#, fuzzy +msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "" -"Une structure d'événements mise à jour permet, par exemple, de regrouper " -"des événements au sein d'une même charge de travail." +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:388 -msgid "" -"**Add new custom strategy tutorial section** " -"[#1623](https://github.com/adap/flower/pull/1623)" +#: ../../source/ref-changelog.md:236 +#, fuzzy +msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "" -"**Ajouter une nouvelle section de tutoriel sur les stratégies " -"personnalisées** [#1623](https://github.com/adap/flower/pull/1623)" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:238 #, fuzzy -msgid "" -"The Flower tutorial now has a new section that covers implementing a " -"custom strategy from scratch: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" + +#: ../../source/ref-changelog.md:240 +#, fuzzy +msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" + +#: ../../source/ref-changelog.md:242 +#, fuzzy +msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" + +#: ../../source/ref-changelog.md:244 +#, fuzzy +msgid "" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" msgstr "" -"Le tutoriel sur les fleurs comporte désormais une nouvelle section qui " -"traite de la mise en œuvre d'une stratégie personnalisée à partir de zéro" -" : [Ouvrir dans " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-3-Building-a" -"-Strategy-PyTorch.ipynb)" +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:246 +#, fuzzy msgid "" -"**Add new custom serialization tutorial section** " -"([#1622](https://github.com/adap/flower/pull/1622))" +"**General updates to Flower Examples** " +"([#2384](https://github.com/adap/flower/pull/2384), " +"[#2425](https://github.com/adap/flower/pull/2425), " +"[#2526](https://github.com/adap/flower/pull/2526), " +"[#2302](https://github.com/adap/flower/pull/2302), " +"[#2545](https://github.com/adap/flower/pull/2545))" msgstr "" -"**Ajouter une nouvelle section de tutoriel sur la sérialisation " -"personnalisée** ([#1622](https://github.com/adap/flower/pull/1622))" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:248 #, fuzzy msgid "" -"The Flower tutorial now has a new section that covers custom " -"serialization: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"**General updates to Flower Baselines** " +"([#2301](https://github.com/adap/flower/pull/2301), " +"[#2305](https://github.com/adap/flower/pull/2305), " +"[#2307](https://github.com/adap/flower/pull/2307), " +"[#2327](https://github.com/adap/flower/pull/2327), " +"[#2435](https://github.com/adap/flower/pull/2435), " +"[#2462](https://github.com/adap/flower/pull/2462), " +"[#2463](https://github.com/adap/flower/pull/2463), " +"[#2461](https://github.com/adap/flower/pull/2461), " +"[#2469](https://github.com/adap/flower/pull/2469), " +"[#2466](https://github.com/adap/flower/pull/2466), " +"[#2471](https://github.com/adap/flower/pull/2471), " +"[#2472](https://github.com/adap/flower/pull/2472), " +"[#2470](https://github.com/adap/flower/pull/2470))" msgstr "" -"Le tutoriel sur les fleurs comporte désormais une nouvelle section qui " -"traite de la sérialisation personnalisée : [Ouvrir dans " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-4" -"-Client-and-NumPyClient-PyTorch.ipynb)" +"**Améliorations générales** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" -#: ../../source/ref-changelog.md:396 +#: ../../source/ref-changelog.md:250 +#, fuzzy msgid "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github.com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" +"**General updates to the simulation engine** " +"([#2331](https://github.com/adap/flower/pull/2331), " +"[#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), " +"[#2294](https://github.com/adap/flower/pull/2294))" msgstr "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/ada" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:252 +#, fuzzy msgid "" -"**Updated documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" +"**General updates to Flower SDKs** " +"([#2288](https://github.com/adap/flower/pull/2288), " +"[#2429](https://github.com/adap/flower/pull/2429), " +"[#2555](https://github.com/adap/flower/pull/2555), " +"[#2543](https://github.com/adap/flower/pull/2543), " +"[#2544](https://github.com/adap/flower/pull/2544), " +"[#2597](https://github.com/adap/flower/pull/2597), " +"[#2623](https://github.com/adap/flower/pull/2623))" msgstr "" -"**Mise à jour de la documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" +"**Tutoriel amélioré** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:402 ../../source/ref-changelog.md:469 +#: ../../source/ref-changelog.md:254 msgid "" -"As usual, the documentation has improved quite a bit. It is another step " -"in our effort to make the Flower documentation the best documentation of " -"any project. Stay tuned and as always, feel free to provide feedback!" +"**General improvements** " +"([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), " +"[#2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[#2317](https://github.com/adap/flower/pull/2317), " +"[#2349](https://github.com/adap/flower/pull/2349), " +"[#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446), " +"[#2561](https://github.com/adap/flower/pull/2561), " +"[#2273](https://github.com/adap/flower/pull/2273), " +"[#2267](https://github.com/adap/flower/pull/2267), " +"[#2274](https://github.com/adap/flower/pull/2274), " +"[#2275](https://github.com/adap/flower/pull/2275), " +"[#2432](https://github.com/adap/flower/pull/2432), " +"[#2251](https://github.com/adap/flower/pull/2251), " +"[#2321](https://github.com/adap/flower/pull/2321), " +"[#1936](https://github.com/adap/flower/pull/1936), " +"[#2408](https://github.com/adap/flower/pull/2408), " +"[#2413](https://github.com/adap/flower/pull/2413), " +"[#2401](https://github.com/adap/flower/pull/2401), " +"[#2531](https://github.com/adap/flower/pull/2531), " +"[#2534](https://github.com/adap/flower/pull/2534), " +"[#2535](https://github.com/adap/flower/pull/2535), " +"[#2521](https://github.com/adap/flower/pull/2521), " +"[#2553](https://github.com/adap/flower/pull/2553), " +"[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" -"Comme d'habitude, la documentation s'est beaucoup améliorée. C'est une " -"autre étape dans notre effort pour faire de la documentation de Flower la" -" meilleure documentation de tout projet. Reste à l'écoute et comme " -"toujours, n'hésite pas à nous faire part de tes commentaires !" -#: ../../source/ref-changelog.md:408 -msgid "v1.2.0 (2023-01-13)" -msgstr "v1.2.0 (2023-01-13)" +#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 +#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 +#: ../../source/ref-changelog.md:531 +msgid "Flower received many improvements under the hood, too many to list here." +msgstr "" +"Flower a reçu de nombreuses améliorations sous le capot, trop nombreuses " +"pour être énumérées ici." -#: ../../source/ref-changelog.md:414 +#: ../../source/ref-changelog.md:260 +#, fuzzy msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"**Remove support for Python 3.7** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" msgstr "" -"adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " -"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"**Nouvel exemple de code MLCube** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:262 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"Python 3.7 support was deprecated in Flower 1.5, and this release removes" +" support. Flower now requires Python 3.8." msgstr "" -"**Introduire une nouvelle fleur Référence : FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" -#: ../../source/ref-changelog.md:420 -msgid "" -"Over the coming weeks, we will be releasing a number of new reference " -"implementations useful especially to FL newcomers. They will typically " -"revisit well known papers from the literature, and be suitable for " -"integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in " -"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" -msgstr "" -"Au cours des prochaines semaines, nous publierons un certain nombre de " -"nouvelles implémentations de référence utiles en particulier pour les " -"nouveaux venus en FL. Elles revisiteront généralement des articles bien " -"connus de la littérature, et seront adaptées à l'intégration dans votre " -"propre application ou à l'expérimentation, afin d'approfondir votre " -"connaissance de FL en général. La publication d'aujourd'hui est la " -"première de cette série. [Lire la " -"suite.](https://flower.ai/blog/2023-01-12-fl-starter-pack-fedavg-mnist-" -"cnn/)" - -#: ../../source/ref-changelog.md:422 -msgid "" -"**Improve GPU support in simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" -msgstr "" -"**Améliorer la prise en charge des GPU dans les simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" - -#: ../../source/ref-changelog.md:424 -msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" -" to improve GPU support. The update includes some of the hard-earned " -"lessons from scaling simulations in GPU cluster environments. New " -"defaults make running GPU-based simulations substantially more robust." -msgstr "" -"Le moteur client virtuel basé sur Ray (`start_simulation`) a été mis à " -"jour pour améliorer la prise en charge des GPU. La mise à jour inclut " -"certaines des leçons durement apprises lors de la mise à l'échelle des " -"simulations dans des environnements de grappes de GPU. De nouveaux " -"paramètres par défaut rendent l'exécution des simulations basées sur les " -"GPU beaucoup plus robuste." - -#: ../../source/ref-changelog.md:426 -msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" -msgstr "" -"**Améliorer la prise en charge du GPU dans les tutoriels Jupyter " -"Notebook** ([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" - -#: ../../source/ref-changelog.md:428 -msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to " -"use on GPU instances. We listened and made improvements to all of our " -"Jupyter notebooks! Check out the updated notebooks here:" -msgstr "" -"Certains utilisateurs ont signalé que les carnets Jupyter n'ont pas " -"toujours été faciles à utiliser sur les instances GPU. Nous les avons " -"écoutés et avons apporté des améliorations à tous nos carnets Jupyter ! " -"Découvre les carnets mis à jour ici :" - -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:264 #, fuzzy msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework" -"/tutorial-get-started-with-flower-pytorch.html)" +"**Remove experimental argument** `rest` **from** `start_client` " +"([#2324](https://github.com/adap/flower/pull/2324))" msgstr "" -"[Une introduction à l'apprentissage fédéré] " -"(https://flower.ai/docs/tutorial/Flower-1-Intro-to-FL-PyTorch.html)" +"**Supprimer les stratégies expérimentales** " +"([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:431 -#, fuzzy +#: ../../source/ref-changelog.md:266 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework" -"/tutorial-use-a-federated-learning-strategy-pytorch.html)" +"The (still experimental) argument `rest` was removed from `start_client` " +"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " +"experimental REST API instead." msgstr "" -"[Stratégies d'apprentissage fédéré] " -"(https://flower.ai/docs/tutorial/Flower-2-Strategies-in-FL-PyTorch.html)" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:268 #, fuzzy -msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" -"-strategy-from-scratch-pytorch.html)" -msgstr "" -"[Construire une stratégie] " -"(https://flower.ai/docs/tutorial/Flower-3-Building-a-Strategy-" -"PyTorch.html)" +msgid "v1.5.0 (2023-08-31)" +msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:433 -#, fuzzy +#: ../../source/ref-changelog.md:274 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" -"customize-the-client-pytorch.html)" +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " msgstr "" -"[Client et NumPyClient] (https://flower.ai/docs/tutorial/Flower-4-Client-" -"and-NumPyClient-PyTorch.html)" -#: ../../source/ref-changelog.md:435 +#: ../../source/ref-changelog.md:278 +#, fuzzy msgid "" -"**Introduce optional telemetry** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" +"**Introduce new simulation engine** " +"([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" msgstr "" "**Introduire la télémétrie optionnelle** " "([#1533](https://github.com/adap/flower/pull/1533), " "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:437 +#: ../../source/ref-changelog.md:280 msgid "" -"After a [request for " -"feedback](https://github.com/adap/flower/issues/1534) from the community," -" the Flower open-source project introduces optional collection of " -"*anonymous* usage metrics to make well-informed decisions to improve " -"Flower. Doing this enables the Flower team to understand how Flower is " -"used and what challenges users might face." +"The new simulation engine has been rewritten from the ground up, yet it " +"remains fully backwards compatible. It offers much improved stability and" +" memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-" +"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -"À la suite d'une [demande de commentaires] " -"(https://github.com/adap/flower/issues/1534) de la part de la communauté," -" le projet open-source Flower introduit la collecte optionnelle de " -"mesures d'utilisation *anonymes* afin de prendre des décisions éclairées " -"pour améliorer Flower. Cela permet à l'équipe de Flower de comprendre " -"comment Flower est utilisé et quels sont les défis auxquels les " -"utilisateurs peuvent être confrontés." -#: ../../source/ref-changelog.md:439 -#, fuzzy +#: ../../source/ref-changelog.md:282 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users who do not want to share anonymous usage metrics. " -"[Read more.](https://flower.ai/docs/telemetry.html)." +"Comprehensive documentation includes a new [how-to run " +"simulations](https://flower.ai/docs/framework/how-to-run-" +"simulations.html) guide, new [simulation-" +"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " +"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" +"tensorflow.html) notebooks, and a new [YouTube tutorial " +"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" -"**Flower est un cadre convivial pour l'IA collaborative et la science des" -" données.** Restant fidèle à cette déclaration, Flower permet de " -"désactiver facilement la télémétrie pour les utilisateurs qui ne " -"souhaitent pas partager des métriques d'utilisation anonymes.[Lire la " -"suite.](https://flower.ai/docs/telemetry.html)." -#: ../../source/ref-changelog.md:441 +#: ../../source/ref-changelog.md:284 msgid "" -"**Introduce (experimental) Driver API** " -"([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**Restructure Flower Docs** " +"([#1824](https://github.com/adap/flower/pull/1824), " +"[#1865](https://github.com/adap/flower/pull/1865), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1887](https://github.com/adap/flower/pull/1887), " +"[#1919](https://github.com/adap/flower/pull/1919), " +"[#1922](https://github.com/adap/flower/pull/1922), " +"[#1920](https://github.com/adap/flower/pull/1920), " +"[#1923](https://github.com/adap/flower/pull/1923), " +"[#1924](https://github.com/adap/flower/pull/1924), " +"[#1962](https://github.com/adap/flower/pull/1962), " +"[#2006](https://github.com/adap/flower/pull/2006), " +"[#2133](https://github.com/adap/flower/pull/2133), " +"[#2203](https://github.com/adap/flower/pull/2203), " +"[#2215](https://github.com/adap/flower/pull/2215), " +"[#2122](https://github.com/adap/flower/pull/2122), " +"[#2223](https://github.com/adap/flower/pull/2223), " +"[#2219](https://github.com/adap/flower/pull/2219), " +"[#2232](https://github.com/adap/flower/pull/2232), " +"[#2233](https://github.com/adap/flower/pull/2233), " +"[#2234](https://github.com/adap/flower/pull/2234), " +"[#2235](https://github.com/adap/flower/pull/2235), " +"[#2237](https://github.com/adap/flower/pull/2237), " +"[#2238](https://github.com/adap/flower/pull/2238), " +"[#2242](https://github.com/adap/flower/pull/2242), " +"[#2231](https://github.com/adap/flower/pull/2231), " +"[#2243](https://github.com/adap/flower/pull/2243), " +"[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" -"**([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:443 +#: ../../source/ref-changelog.md:286 msgid "" -"Flower now has a new (experimental) Driver API which will enable fully " -"programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API" -" will be the abstraction that many upcoming features will be built on - " -"and you can start building those things now, too." +"Much effort went into a completely restructured Flower docs experience. " +"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " +"divided into Flower Framework, Flower Baselines, Flower Android SDK, " +"Flower iOS SDK, and code example projects." msgstr "" -"Flower dispose désormais d'une nouvelle API de pilote (expérimentale) qui" -" permettra de créer des applications Federated Learning et Federated " -"Analytics entièrement programmables, asynchrones et multi-tenant. Ouf, " -"c'est beaucoup ! À l'avenir, l'API de pilote sera l'abstraction sur " -"laquelle de nombreuses fonctionnalités à venir seront construites - et tu" -" peux commencer à construire ces choses dès maintenant, aussi." -#: ../../source/ref-changelog.md:445 +#: ../../source/ref-changelog.md:288 +#, fuzzy msgid "" -"The Driver API also enables a new execution mode in which the server runs" -" indefinitely. Multiple individual workloads can run concurrently and " -"start and stop their execution independent of the server. This is " -"especially useful for users who want to deploy Flower in production." +"**Introduce Flower Swift SDK** " +"([#1858](https://github.com/adap/flower/pull/1858), " +"[#1897](https://github.com/adap/flower/pull/1897))" msgstr "" -"L'API du pilote permet également un nouveau mode d'exécution dans lequel " -"le serveur s'exécute indéfiniment. Plusieurs charges de travail " -"individuelles peuvent s'exécuter simultanément et démarrer et arrêter " -"leur exécution indépendamment du serveur. Ceci est particulièrement utile" -" pour les utilisateurs qui souhaitent déployer Flower en production." +"**Introduction du SDK iOS (aperçu)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:447 +#: ../../source/ref-changelog.md:290 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward " -"to you feedback!" +"This is the first preview release of the Flower Swift SDK. Flower support" +" on iOS is improving, and alongside the Swift SDK and code example, there" +" is now also an iOS quickstart tutorial." msgstr "" -"Pour en savoir plus, consulte l'exemple de code `mt-pytorch`. Nous " -"attendons tes commentaires avec impatience !" -#: ../../source/ref-changelog.md:449 +#: ../../source/ref-changelog.md:292 +#, fuzzy msgid "" -"Please note: *The Driver API is still experimental and will likely change" -" significantly over time.*" +"**Introduce Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" msgstr "" -"Remarque : *L'API du pilote est encore expérimentale et est susceptible " -"de changer de manière significative au fil du temps.*" +"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " +"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:451 +#: ../../source/ref-changelog.md:294 msgid "" -"**Add new Federated Analytics with Pandas example** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"This is the first preview release of the Flower Kotlin SDK. Flower " +"support on Android is improving, and alongside the Kotlin SDK and code " +"example, there is now also an Android quickstart tutorial." msgstr "" -"**Ajouter un nouvel exemple de Federated Analytics avec Pandas** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" -#: ../../source/ref-changelog.md:453 +#: ../../source/ref-changelog.md:296 +#, fuzzy msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics" -" with Pandas and Flower. You can find it here: [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." -msgstr "" -"Un nouvel exemple de code (`quickstart-pandas`) démontre l'analyse " -"fédérée avec Pandas et Flower. Tu peux le trouver ici : [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." +"**Introduce new end-to-end testing infrastructure** " +"([#1842](https://github.com/adap/flower/pull/1842), " +"[#2071](https://github.com/adap/flower/pull/2071), " +"[#2072](https://github.com/adap/flower/pull/2072), " +"[#2068](https://github.com/adap/flower/pull/2068), " +"[#2067](https://github.com/adap/flower/pull/2067), " +"[#2069](https://github.com/adap/flower/pull/2069), " +"[#2073](https://github.com/adap/flower/pull/2073), " +"[#2070](https://github.com/adap/flower/pull/2070), " +"[#2074](https://github.com/adap/flower/pull/2074), " +"[#2082](https://github.com/adap/flower/pull/2082), " +"[#2084](https://github.com/adap/flower/pull/2084), " +"[#2093](https://github.com/adap/flower/pull/2093), " +"[#2109](https://github.com/adap/flower/pull/2109), " +"[#2095](https://github.com/adap/flower/pull/2095), " +"[#2140](https://github.com/adap/flower/pull/2140), " +"[#2137](https://github.com/adap/flower/pull/2137), " +"[#2165](https://github.com/adap/flower/pull/2165))" +msgstr "" +"**Améliorer l'API (expérimentale) du pilote** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:455 +#: ../../source/ref-changelog.md:298 msgid "" -"**Add new strategies: Krum and MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"A new testing infrastructure ensures that new changes stay compatible " +"with existing framework integrations or strategies." msgstr "" -"**Ajouter de nouvelles stratégies : Krum et MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" -#: ../../source/ref-changelog.md:457 +#: ../../source/ref-changelog.md:300 +#, fuzzy +msgid "**Deprecate Python 3.7**" +msgstr "**Créer le PR**" + +#: ../../source/ref-changelog.md:302 msgid "" -"Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum " -"and MultiKrum in their workloads." +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" +" Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" -"Edoardo, étudiant en informatique à l'Université Sapienza de Rome, a " -"contribué à une nouvelle stratégie `Krum` qui permet aux utilisateurs " -"d'utiliser facilement Krum et MultiKrum dans leurs charges de travail." -#: ../../source/ref-changelog.md:459 +#: ../../source/ref-changelog.md:304 +#, fuzzy msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"**Add new** `FedTrimmedAvg` **strategy** " +"([#1769](https://github.com/adap/flower/pull/1769), " +"[#1853](https://github.com/adap/flower/pull/1853))" msgstr "" -"**Mettre à jour l'exemple C++ pour qu'il soit compatible avec Flower " -"v1.2.0** ([#1495](https://github.com/adap/flower/pull/1495))" +"**Ajouter un nouvel exemple de Federated Analytics avec Pandas** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" -#: ../../source/ref-changelog.md:461 +#: ../../source/ref-changelog.md:306 +#, fuzzy msgid "" -"The C++ code example has received a substantial update to make it " -"compatible with the latest version of Flower." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " +"2018](https://arxiv.org/abs/1803.01498)." msgstr "" -"L'exemple de code C++ a reçu une mise à jour substantielle pour le rendre" -" compatible avec la dernière version de Flower." +"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " +"(FedMedian) par [Yin et al., 2018] " +"(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:463 +#: ../../source/ref-changelog.md:308 +#, fuzzy msgid "" -"**General improvements** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**Introduce start_driver** " +"([#1697](https://github.com/adap/flower/pull/1697))" msgstr "" -"**Améliorations générales** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:467 +#: ../../source/ref-changelog.md:310 msgid "" -"**Updated documentation** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" +"In addition to `start_server` and using the raw Driver API, there is a " +"new `start_driver` function that allows for running `start_server` " +"scripts as a Flower driver with only a single-line code change. Check out" +" the `mt-pytorch` code example to see a working example using " +"`start_driver`." msgstr "" -"**Documentation mise à jour** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:471 +#: ../../source/ref-changelog.md:312 +#, fuzzy msgid "" -"One highlight is the new [first time contributor " -"guide](https://flower.ai/docs/first-time-contributors.html): if you've " -"never contributed on GitHub before, this is the perfect place to start!" +"**Add parameter aggregation to** `mt-pytorch` **code example** " +"([#1785](https://github.com/adap/flower/pull/1785))" msgstr "" -"L'un des points forts est le nouveau [guide du premier contributeur] " -"(https://flower.ai/docs/first-time-contributors.html) : si tu n'as jamais" -" contribué sur GitHub auparavant, c'est l'endroit idéal pour commencer !" +"**Nouvel exemple de code PyTorch avancé** " +"([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:477 -msgid "v1.1.0 (2022-10-31)" -msgstr "v1.1.0 (2022-10-31)" +#: ../../source/ref-changelog.md:314 +msgid "" +"The `mt-pytorch` example shows how to aggregate parameters when writing a" +" driver script. The included `driver.py` and `server.py` have been " +"aligned to demonstrate both the low-level way and the high-level way of " +"building server-side logic." +msgstr "" -#: ../../source/ref-changelog.md:481 +#: ../../source/ref-changelog.md:316 +#, fuzzy msgid "" -"We would like to give our **special thanks** to all the contributors who " -"made the new version of Flower possible (in `git shortlog` order):" +"**Migrate experimental REST API to Starlette** " +"([2171](https://github.com/adap/flower/pull/2171))" msgstr "" -"Nous aimerions **remercier tout particulièrement** tous les contributeurs" -" qui ont rendu possible la nouvelle version de Flower (dans l'ordre `git " -"shortlog`) :" +"**Nouvelle stratégie expérimentale TensorBoard** " +"([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:483 +#: ../../source/ref-changelog.md:318 msgid "" -"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " -"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +"The (experimental) REST API used to be implemented in " +"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" +" use [Starlette](https://www.starlette.io/) directly." msgstr "" -"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " -"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" -#: ../../source/ref-changelog.md:487 +#: ../../source/ref-changelog.md:320 +#, fuzzy msgid "" -"**Introduce Differential Privacy wrappers (preview)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"Please note: The REST request-response API is still experimental and will" +" likely change significantly over time." +msgstr "" +"Remarque : l'API REST est encore expérimentale et est susceptible de " +"changer de manière significative au fil du temps." + +#: ../../source/ref-changelog.md:322 +#, fuzzy +msgid "" +"**Introduce experimental gRPC request-response API** " +"([#1867](https://github.com/adap/flower/pull/1867), " +"[#1901](https://github.com/adap/flower/pull/1901))" msgstr "" "**Introduire les enveloppes de confidentialité différentielle (aperçu)** " "([#1357](https://github.com/adap/flower/pull/1357), " "[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:489 +#: ../../source/ref-changelog.md:324 msgid "" -"The first (experimental) preview of pluggable Differential Privacy " -"wrappers enables easy configuration and usage of differential privacy " -"(DP). The pluggable DP wrappers enable framework-agnostic **and** " -"strategy-agnostic usage of both client-side DP and server-side DP. Head " -"over to the Flower docs, a new explainer goes into more detail." +"In addition to the existing gRPC API (based on bidirectional streaming) " +"and the experimental REST API, there is now a new gRPC API that uses a " +"request-response model to communicate with client nodes." msgstr "" -"Le premier aperçu (expérimental) des wrappers enfichables de " -"confidentialité différentielle permet de configurer et d'utiliser " -"facilement la confidentialité différentielle (DP). Les wrappers DP " -"enfichables permettent une utilisation agnostique du cadre **et** de la " -"stratégie à la fois de la DP côté client et de la DP côté serveur. Va " -"voir les documents de Flower, un nouvel explicatif va plus loin dans les " -"détails." -#: ../../source/ref-changelog.md:491 +#: ../../source/ref-changelog.md:326 +#, fuzzy msgid "" -"**New iOS CoreML code example** " -"([#1289](https://github.com/adap/flower/pull/1289))" +"Please note: The gRPC request-response API is still experimental and will" +" likely change significantly over time." msgstr "" -"**Nouvel exemple de code CoreML pour iOS** " -"([#1289](https://github.com/adap/flower/pull/1289))" +"Remarque : l'API REST est encore expérimentale et est susceptible de " +"changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:493 +#: ../../source/ref-changelog.md:328 +#, fuzzy msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can " -"be built for iOS. The code example contains both Flower iOS SDK " -"components that can be used for many tasks, and one task example running " -"on CoreML." +"**Replace the experimental** `start_client(rest=True)` **with the new** " +"`start_client(transport=\"rest\")` " +"([#1880](https://github.com/adap/flower/pull/1880))" msgstr "" -"Flower passe à iOS ! Un nouvel exemple de code massif montre comment les " -"clients Flower peuvent être construits pour iOS. L'exemple de code " -"contient à la fois des composants Flower iOS SDK qui peuvent être " -"utilisés pour de nombreuses tâches, et un exemple de tâche fonctionnant " -"sur CoreML." +"**Initialise** `start_simulation` **avec une liste d'ID de clients** " +"([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-changelog.md:495 +#: ../../source/ref-changelog.md:330 msgid "" -"**New FedMedian strategy** " -"([#1461](https://github.com/adap/flower/pull/1461))" +"The (experimental) `start_client` argument `rest` was deprecated in " +"favour of a new argument `transport`. `start_client(transport=\"rest\")` " +"will yield the same behaviour as `start_client(rest=True)` did before. " +"All code should migrate to the new argument `transport`. The deprecated " +"argument `rest` will be removed in a future release." msgstr "" -"**Nouvelle stratégie de FedMedian** " -"([#1461](https://github.com/adap/flower/pull/1461))" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:332 +#, fuzzy msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by " -"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"**Add a new gRPC option** " +"([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" -"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " -"(FedMedian) par [Yin et al., 2018] " -"(https://arxiv.org/pdf/1803.01498v1.pdf)." +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:334 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** " -"([#1493](https://github.com/adap/flower/pull/1493))" +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" +" option set to 0 by default. This prevents the clients from sending " +"keepalive pings when there is no outstanding stream." msgstr "" -"**Log** `Client` **exceptions dans le moteur de client virtuel** " -"([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:336 +#, fuzzy msgid "" -"All `Client` exceptions happening in the VCE are now logged by default " -"and not just exposed to the configured `Strategy` (via the `failures` " -"argument)." +"**Improve example notebooks** " +"([#2005](https://github.com/adap/flower/pull/2005))" msgstr "" -"Toutes les exceptions `Client` qui se produisent dans le VCE sont " -"maintenant enregistrées par défaut et ne sont pas seulement exposées à la" -" `Stratégie` configurée (via l'argument `failures`)." +"**Supprimer les stratégies expérimentales** " +"([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:503 -msgid "" -"**Improve Virtual Client Engine internals** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" -msgstr "" -"**Améliorer le moteur du client virtuel** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" +#: ../../source/ref-changelog.md:338 +#, fuzzy +msgid "There's a new 30min Federated Learning PyTorch tutorial!" +msgstr "Bienvenue au tutoriel sur l'apprentissage fédéré de la fleur !" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:340 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE " -"now uses Ray 2.0 under the hood, the value type of the `client_resources`" -" dictionary changed to `float` to allow fractions of resources to be " -"allocated." +"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" msgstr "" -"Le VCE utilise maintenant Ray 2.0 sous le capot, le type de valeur du " -"dictionnaire `client_resources` a été remplacé par `float` pour permettre" -" l'allocation de fractions de ressources." -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:342 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" +"Many examples have received significant updates, including simplified " +"advanced-tensorflow and advanced-pytorch examples, improved macOS " +"compatibility of TensorFlow examples, and code examples for simulation. A" +" major upgrade is that all code examples now have a `requirements.txt` " +"(in addition to `pyproject.toml`)." msgstr "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:344 +#, fuzzy msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and" -" `NumPyClient`) methods." +"**General improvements** " +"([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" msgstr "" -"Le moteur de client virtuel prend désormais en charge les méthodes " -"optionnelles `Client` (et `NumPyClient`)." +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:352 +msgid "v1.4.0 (2023-04-21)" +msgstr "v1.4.0 (2023-04-21)" + +#: ../../source/ref-changelog.md:358 msgid "" -"**Provide type information to packages using** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" -"**Fournir des informations de type aux paquets en utilisant** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:362 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that " -"the package is typed. This enables typing support for projects or " -"packages that use `flwr` by enabling them to improve their code using " -"static type checkers like `mypy`." +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " +"example)** ([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" msgstr "" -"Le paquet `flwr` est maintenant accompagné d'un fichier `py.typed` " -"indiquant que le paquet est typé. Cela permet de prendre en charge le " -"typage pour les projets ou les paquets qui utilisent `flwr` en leur " -"permettant d'améliorer leur code à l'aide de vérificateurs de types " -"statiques comme `mypy`." +"**Introduire la prise en charge de XGBoost (**`FedXgbNnAvg` **stratégie " +"et exemple)** ([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:364 msgid "" -"**Updated code example** " -"([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" +"XGBoost is a tree-based ensemble machine learning algorithm that uses " +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" +" " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," +" and a [code example](https://github.com/adap/flower/tree/main/examples" +"/xgboost-quickstart) that demonstrates the usage of this new strategy in " +"an XGBoost project." msgstr "" -"**Exemple de code mis à jour** " -"([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" +"Nous avons ajouté une nouvelle [stratégie] `FedXgbNnAvg` " +"(https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," +" et un [exemple de code] " +"(https://github.com/adap/flower/tree/main/examples/xgboost-quickstart) " +"qui démontre l'utilisation de cette nouvelle stratégie dans un projet " +"XGBoost." -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:366 msgid "" -"The code examples covering scikit-learn and PyTorch Lightning have been " -"updated to work with the latest version of Flower." +"**Introduce iOS SDK (preview)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" msgstr "" -"Les exemples de code couvrant scikit-learn et PyTorch Lightning ont été " -"mis à jour pour fonctionner avec la dernière version de Flower." +"**Introduction du SDK iOS (aperçu)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:519 +#: ../../source/ref-changelog.md:368 msgid "" -"**Updated documentation** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +"This is a major update for anyone wanting to implement Federated Learning" +" on iOS mobile devices. We now have a swift iOS SDK present under " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" that will facilitate greatly the app creating process. To showcase its " +"use, the [iOS " +"example](https://github.com/adap/flower/tree/main/examples/ios) has also " +"been updated!" msgstr "" -"**Documentation mise à jour** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +"Il s'agit d'une mise à jour majeure pour tous ceux qui souhaitent mettre " +"en œuvre l'apprentissage fédéré sur les appareils mobiles iOS. Nous " +"disposons désormais d'un SDK swift iOS présent sous " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" qui facilitera grandement le processus de création d'applications. Pour " +"présenter son utilisation, l'[exemple " +"iOS](https://github.com/adap/flower/tree/main/examples/ios) a également " +"été mis à jour !" -#: ../../source/ref-changelog.md:521 +#: ../../source/ref-changelog.md:370 msgid "" -"There have been so many documentation updates that it doesn't even make " -"sense to list them individually." +"**Introduce new \"What is Federated Learning?\" tutorial** " +"([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721))" msgstr "" -"Il y a eu tellement de mises à jour de la documentation que cela n'a même" -" pas de sens de les énumérer individuellement." +"**Introduire un nouveau tutoriel \"Qu'est-ce que l'apprentissage fédéré ?" +" \"** ([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721))" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:372 +#, fuzzy msgid "" -"**Restructured documentation** " -"([#1387](https://github.com/adap/flower/pull/1387))" +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" +"what-is-federated-learning.html) in our documentation explains the basics" +" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" +" Learning to start their journey with Flower. Forward it to anyone who's " +"interested in Federated Learning!" msgstr "" -"**Documentation restructurée** " -"([#1387](https://github.com/adap/flower/pull/1387))" +"Un nouveau [tutoriel d'entrée de gamme] " +"(https://flower.ai/docs/tutorial/Flower-0-What-is-FL.html) dans notre " +"documentation explique les bases de l'apprentissage fédéré. Il permet à " +"tous ceux qui ne connaissent pas l'apprentissage fédéré de commencer leur" +" voyage avec Flower. Fais-le suivre à tous ceux qui s'intéressent à " +"l'apprentissage fédéré !" -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:374 msgid "" -"The documentation has been restructured to make it easier to navigate. " -"This is just the first step in a larger effort to make the Flower " -"documentation the best documentation of any project ever. Stay tuned!" +"**Introduce new Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" msgstr "" -"La documentation a été restructurée pour faciliter la navigation. Ce " -"n'est que la première étape d'un effort plus important visant à faire de " -"la documentation de Flower la meilleure documentation de tous les projets" +"**Introduire une nouvelle fleur Référence : FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:376 msgid "" -"**Open in Colab button** " -"([#1389](https://github.com/adap/flower/pull/1389))" +"This new baseline replicates the MNIST+CNN task from the paper [Federated" +" Optimization in Heterogeneous Networks (Li et al., " +"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," +" which aims at making convergence more robust in heterogeneous settings." msgstr "" -"**Ouvrir dans le bouton Colab** " -"([#1389](https://github.com/adap/flower/pull/1389))" +"Cette nouvelle ligne de base reproduit la tâche MNIST+CNN de l'article " +"[Federated Optimization in Heterogeneous Networks (Li et al., 2018)] " +"(https://arxiv.org/abs/1812.06127). Elle utilise la stratégie `FedProx`, " +"qui vise à rendre la convergence plus robuste dans des contextes " +"hétérogènes." -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:378 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a " -"new `Open in Colab` button. No need to install anything on your local " -"machine, you can now use and learn about Flower in your browser, it's " -"only a single click away." +"**Introduce new Flower Baseline: FedAvg FEMNIST** " +"([#1655](https://github.com/adap/flower/pull/1655))" msgstr "" -"Les quatre parties du didacticiel d'apprentissage fédéré Flower sont " -"maintenant accompagnées d'un nouveau bouton \"Ouvrir dans Colab\". Pas " -"besoin d'installer quoi que ce soit sur ta machine locale, tu peux " -"maintenant utiliser et apprendre à connaître Flower dans ton navigateur, " -"il te suffit d'un simple clic." +"**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " +"FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:531 +#: ../../source/ref-changelog.md:380 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"This new baseline replicates an experiment evaluating the performance of " +"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " +"Benchmark for Federated Settings (Caldas et al., " +"2018)](https://arxiv.org/abs/1812.01097)." msgstr "" -"**Tutoriel amélioré** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"Cette nouvelle ligne de base reproduit une expérience évaluant les " +"performances de l'algorithme FedAvg sur le jeu de données FEMNIST tiré de" +" l'article [LEAF : A Benchmark for Federated Settings (Caldas et al., " +"2018)] (https://arxiv.org/abs/1812.01097)." -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:382 msgid "" -"The Flower Federated Learning Tutorial has two brand-new parts covering " -"custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved " -"(many small changes and fixes)." +"**Introduce (experimental) REST API** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" msgstr "" -"Le tutoriel sur l'apprentissage fédéré des fleurs a deux toutes nouvelles" -" parties couvrant les stratégies personnalisées (encore WIP) et la " -"distinction entre `Client` et `NumPyClient`. Les parties un et deux " -"existantes ont également été améliorées (beaucoup de petits changements " -"et de corrections)." - -#: ../../source/ref-changelog.md:539 -msgid "v1.0.0 (2022-07-28)" -msgstr "v1.0.0 (2022-07-28)" - -#: ../../source/ref-changelog.md:541 -msgid "Highlights" -msgstr "Points forts" - -#: ../../source/ref-changelog.md:543 -msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" -msgstr "Moteur de client virtuel stable** (accessible via `start_simulation`)" - -#: ../../source/ref-changelog.md:544 -msgid "All `Client`/`NumPyClient` methods are now optional" -msgstr "Toutes les méthodes `Client`/`NumPyClient` sont maintenant optionnelles" +"**Introduire l'API REST (expérimentale)** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:545 -msgid "Configurable `get_parameters`" -msgstr "`get_parameters` configurable" +#: ../../source/ref-changelog.md:384 +msgid "" +"A new REST API has been introduced as an alternative to the gRPC-based " +"communication stack. In this initial version, the REST API only supports " +"anonymous clients." +msgstr "" +"Une nouvelle API REST a été introduite comme alternative à la pile de " +"communication basée sur gRPC. Dans cette version initiale, l'API REST ne " +"prend en charge que les clients anonymes." -#: ../../source/ref-changelog.md:546 +#: ../../source/ref-changelog.md:386 msgid "" -"Tons of small API cleanups resulting in a more coherent developer " -"experience" +"Please note: The REST API is still experimental and will likely change " +"significantly over time." msgstr "" -"Des tonnes de petits nettoyages d'API résultant en une expérience plus " -"cohérente pour les développeurs" +"Remarque : l'API REST est encore expérimentale et est susceptible de " +"changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:550 +#: ../../source/ref-changelog.md:388 msgid "" -"We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +"**Improve the (experimental) Driver API** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" msgstr "" -"Nous tenons à remercier **particulièrement** tous les contributeurs qui " -"ont rendu Flower 1.0 possible (dans l'ordre inverse de [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors)) :" +"**Améliorer l'API (expérimentale) du pilote** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:552 +#: ../../source/ref-changelog.md:390 msgid "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." +"The Driver API is still an experimental feature, but this release " +"introduces some major upgrades. One of the main improvements is the " +"introduction of an SQLite database to store server state on disk (instead" +" of in-memory). Another improvement is that tasks (instructions or " +"results) that have been delivered will now be deleted. This greatly " +"improves the memory efficiency of a long-running Flower server." msgstr "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), [@mrinaald](" +"L'API du pilote est encore une fonction expérimentale, mais cette version" +" introduit quelques améliorations majeures. L'une des principales " +"améliorations est l'introduction d'une base de données SQLite pour " +"stocker l'état du serveur sur le disque (au lieu de la mémoire). Une " +"autre amélioration est que les tâches (instructions ou résultats) qui ont" +" été livrées seront désormais supprimées, ce qui améliore " +"considérablement l'efficacité de la mémoire d'un serveur Flower " +"fonctionnant depuis longtemps." -#: ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:392 msgid "" -"**All arguments must be passed as keyword arguments** " -"([#1338](https://github.com/adap/flower/pull/1338))" +"**Fix spilling issues related to Ray during simulations** " +"([#1698](https://github.com/adap/flower/pull/1698))" msgstr "" -"**Tous les arguments doivent être passés comme des arguments de mot-clé**" -" ([#1338](https://github.com/adap/flower/pull/1338))" +"**Répare les problèmes de déversement liés à Ray pendant les " +"simulations** ([#1698](https://github.com/adap/flower/pull/1698))" -#: ../../source/ref-changelog.md:558 +#: ../../source/ref-changelog.md:394 #, fuzzy msgid "" -"Pass all arguments as keyword arguments, positional arguments are not " -"longer supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " -"for each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"While running long simulations, `ray` was sometimes spilling huge amounts" +" of data that would make the training unable to continue. This is now " +"fixed! 🎉" msgstr "" -"Le code qui utilise des arguments positionnels (par exemple, " -"``start_client(\"127.0.0.1:8080\", FlowerClient())`) doit ajouter le mot-" -"clé pour chaque argument positionnel (par exemple, " -"``start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"Lors de l'exécution de longues simulations, `ray` déversait parfois " +"d'énormes quantités de données qui rendaient l'entraînement incapable de " +"continuer. ce problème est maintenant corrigé ! 🎉" -#: ../../source/ref-changelog.md:560 +#: ../../source/ref-changelog.md:396 msgid "" -"**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" -msgstr "" -"**Introduire l'objet de configuration** `ServerConfig` **dans** " -"`start_server` **et** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" +"**Add new example using** `TabNet` **and Flower** " +"([#1725](https://github.com/adap/flower/pull/1725))" +msgstr "" +"**Ajouter un nouvel exemple utilisant** `TabNet` **et Flower** " +"([#1725](https://github.com/adap/flower/pull/1725))" -#: ../../source/ref-changelog.md:562 +#: ../../source/ref-changelog.md:398 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " -"600.0}`, `start_server` and `start_simulation` now expect a configuration" -" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" -" arguments that as the previous config dict, but it makes writing type-" -"safe code easier and the default parameters values more transparent." +"TabNet is a powerful and flexible framework for training machine learning" +" models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" +"/quickstart-tabnet)." msgstr "" -"Au lieu d'un dictionnaire de configuration `{\"num_rounds\" : 3, " -"\"round_timeout\" : 600.0}`, `start_server` et `start_simulation` " -"attendent maintenant un objet de configuration de type " -"`flwr.server.ServerConfig`. `ServerConfig` prend les mêmes arguments que " -"le dict de configuration précédent, mais il rend l'écriture de code " -"sécurisé plus facile et les valeurs des paramètres par défaut plus " -"transparentes." +"TabNet est un cadre puissant et flexible pour former des modèles " +"d'apprentissage automatique sur des données tabulaires. Nous avons " +"maintenant un exemple fédéré utilisant Flower : [quickstart-" +"tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" +"tabnet)." -#: ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:400 msgid "" -"**Rename built-in strategy parameters for clarity** " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Add new how-to guide for monitoring simulations** " +"([#1649](https://github.com/adap/flower/pull/1649))" msgstr "" -"**Renommer les paramètres de la stratégie intégrée pour plus de clarté** " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Ajouter un nouveau guide pratique pour le suivi des simulations** " +"([#1649](https://github.com/adap/flower/pull/1649))" -#: ../../source/ref-changelog.md:566 +#: ../../source/ref-changelog.md:402 msgid "" -"The following built-in strategy parameters were renamed to improve " -"readability and consistency with other API's:" +"We now have a documentation guide to help users monitor their performance" +" during simulations." msgstr "" -"Les paramètres de stratégie intégrés suivants ont été renommés pour " -"améliorer la lisibilité et la cohérence avec d'autres API :" - -#: ../../source/ref-changelog.md:568 -msgid "`fraction_eval` --> `fraction_evaluate`" -msgstr "`fraction_eval` --> `fraction_evaluate`" - -#: ../../source/ref-changelog.md:569 -msgid "`min_eval_clients` --> `min_evaluate_clients`" -msgstr "`min_eval_clients` --> `min_evaluate_clients`" - -#: ../../source/ref-changelog.md:570 -msgid "`eval_fn` --> `evaluate_fn`" -msgstr "`eval_fn` --> `evaluate_fn`" +"Nous avons maintenant un guide de documentation pour aider les " +"utilisateurs à surveiller leurs performances pendant les simulations." -#: ../../source/ref-changelog.md:572 +#: ../../source/ref-changelog.md:404 msgid "" -"**Update default arguments of built-in strategies** " -"([#1278](https://github.com/adap/flower/pull/1278))" +"**Add training metrics to** `History` **object during simulations** " +"([#1696](https://github.com/adap/flower/pull/1696))" msgstr "" -"**Mettre à jour les arguments par défaut des stratégies intégrées** " -"([#1278](https://github.com/adap/flower/pull/1278))" +"**Ajouter des mesures de formation à** `History` **objet pendant les " +"simulations** ([#1696](https://github.com/adap/flower/pull/1696))" -#: ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:406 msgid "" -"All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently " -"available clients for training and evaluation. Projects that relied on " -"the previous default values can get the previous behaviour by " -"initializing the strategy in the following way:" +"The `fit_metrics_aggregation_fn` can be used to aggregate training " +"metrics, but previous releases did not save the results in the `History` " +"object. This is now the case!" msgstr "" -"Toutes les stratégies intégrées utilisent désormais `fraction_fit=1.0` et" -" `fraction_evaluate=1.0`, ce qui signifie qu'elles sélectionnent *tous* " -"les clients actuellement disponibles pour l'entraînement et l'évaluation." -" Les projets qui s'appuyaient sur les valeurs par défaut précédentes " -"peuvent retrouver le comportement antérieur en initialisant la stratégie " -"de la manière suivante :" - -#: ../../source/ref-changelog.md:576 -msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" -msgstr "`stratégie = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" +"La fonction `fit_metrics_aggregation_fn` peut être utilisée pour agréger " +"les mesures d'entraînement, mais les versions précédentes " +"n'enregistraient pas les résultats dans l'objet `History`. c'est " +"désormais le cas !" -#: ../../source/ref-changelog.md:578 +#: ../../source/ref-changelog.md:408 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**General improvements** " +"([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/adap/flower/pull/1705), " +"[#1708](https://github.com/adap/flower/pull/1708), " +"[#1711](https://github.com/adap/flower/pull/1711), " +"[#1713](https://github.com/adap/flower/pull/1713), " +"[#1714](https://github.com/adap/flower/pull/1714), " +"[#1718](https://github.com/adap/flower/pull/1718), " +"[#1716](https://github.com/adap/flower/pull/1716), " +"[#1723](https://github.com/adap/flower/pull/1723), " +"[#1735](https://github.com/adap/flower/pull/1735), " +"[#1678](https://github.com/adap/flower/pull/1678), " +"[#1750](https://github.com/adap/flower/pull/1750), " +"[#1753](https://github.com/adap/flower/pull/1753), " +"[#1736](https://github.com/adap/flower/pull/1736), " +"[#1766](https://github.com/adap/flower/pull/1766), " +"[#1760](https://github.com/adap/flower/pull/1760), " +"[#1775](https://github.com/adap/flower/pull/1775), " +"[#1776](https://github.com/adap/flower/pull/1776), " +"[#1777](https://github.com/adap/flower/pull/1777), " +"[#1779](https://github.com/adap/flower/pull/1779), " +"[#1784](https://github.com/adap/flower/pull/1784), " +"[#1773](https://github.com/adap/flower/pull/1773), " +"[#1755](https://github.com/adap/flower/pull/1755), " +"[#1789](https://github.com/adap/flower/pull/1789), " +"[#1788](https://github.com/adap/flower/pull/1788), " +"[#1798](https://github.com/adap/flower/pull/1798), " +"[#1799](https://github.com/adap/flower/pull/1799), " +"[#1739](https://github.com/adap/flower/pull/1739), " +"[#1800](https://github.com/adap/flower/pull/1800), " +"[#1804](https://github.com/adap/flower/pull/1804), " +"[#1805](https://github.com/adap/flower/pull/1805))" msgstr "" -"**Ajouter** `server_round` **à** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**General improvements** " +"([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/ada" + +#: ../../source/ref-changelog.md:416 +msgid "v1.3.0 (2023-02-06)" +msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:580 +#: ../../source/ref-changelog.md:422 msgid "" -"The `Strategy` method `evaluate` now receives the current round of " -"federated learning/evaluation as the first parameter." +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" -"La méthode `Stratégie` `évaluer` reçoit maintenant le cycle actuel " -"d'apprentissage/évaluation fédéré comme premier paramètre." +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" -#: ../../source/ref-changelog.md:582 +#: ../../source/ref-changelog.md:426 msgid "" -"**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Add support for** `workload_id` **and** `group_id` **in Driver API** " +"([#1595](https://github.com/adap/flower/pull/1595))" msgstr "" -"**Ajouter** `server_round` **et** `config` **paramètres à** `evaluate_fn`" -" ([#1334](https://github.com/adap/flower/pull/1334))" +"**Ajouter la prise en charge de** `workload_id` **et** `group_id` **dans " +"l'API du pilote** ([#1595](https://github.com/adap/flower/pull/1595))" -#: ../../source/ref-changelog.md:584 +#: ../../source/ref-changelog.md:428 msgid "" -"The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " -"three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), " -"and (3) a config dictionary (`config`)." +"The (experimental) Driver API now supports a `workload_id` that can be " +"used to identify which workload a task belongs to. It also supports a new" +" `group_id` that can be used, for example, to indicate the current " +"training round. Both the `workload_id` and `group_id` enable client nodes" +" to decide whether they want to handle a task or not." msgstr "" -"Le `evaluate_fn` passé aux stratégies intégrées comme `FedAvg` prend " -"maintenant trois paramètres : (1) le cycle actuel " -"d'apprentissage/évaluation fédéré (`server_round`), (2) les paramètres du" -" modèle à évaluer (`parameters`), et (3) un dictionnaire de configuration" -" (`config`)." +"L'API (expérimentale) Driver prend désormais en charge un `workload_id` " +"qui peut être utilisé pour identifier la charge de travail à laquelle une" +" tâche appartient. Elle prend également en charge un nouveau `group_id` " +"qui peut être utilisé, par exemple, pour indiquer le cycle de formation " +"en cours. Le `workload_id` et le `group_id` permettent tous deux aux " +"nœuds clients de décider s'ils veulent traiter une tâche ou non." -#: ../../source/ref-changelog.md:586 +#: ../../source/ref-changelog.md:430 msgid "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**Make Driver API and Fleet API address configurable** " +"([#1637](https://github.com/adap/flower/pull/1637))" msgstr "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**Faire en sorte que l'adresse de l'API du conducteur et de l'API de la " +"flotte soit configurable** " +"([#1637](https://github.com/adap/flower/pull/1637))" -#: ../../source/ref-changelog.md:588 +#: ../../source/ref-changelog.md:432 msgid "" -"Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " -"`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. " -"To improve reaability and avoid confusion with *random*, this parameter " -"has been renamed from `rnd` to `server_round`." +"The (experimental) long-running Flower server (Driver API and Fleet API) " +"can now configure the server address of both Driver API (via `--driver-" +"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" -"Plusieurs méthodes et fonctions de Flower (`evaluate_fn`, " -"`configure_fit`, `aggregate_fit`, `configure_evaluate`, " -"`aggregate_evaluate`) reçoivent le cycle actuel " -"d'apprentissage/évaluation fédéré comme premier paramètre. Pour améliorer" -" la fiabilité et éviter la confusion avec *random*, ce paramètre a été " -"renommé de `rnd` à `server_round`." +"Le serveur Flower (expérimental) de longue durée (Driver API et Fleet " +"API) peut maintenant configurer l'adresse du serveur de Driver API (via " +"`--driver-api-address`) et de Fleet API (via `--fleet-api-address`) lors " +"de son démarrage :" -#: ../../source/ref-changelog.md:590 +#: ../../source/ref-changelog.md:434 +#, fuzzy msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " +"\"0.0.0.0:8086\"`" msgstr "" -"**Déplacer** `flwr.dataset` **vers** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"``flower-superlink --driver-api-address \"0.0.0.0:8081\" --fleet-api-" +"address \"0.0.0.0:8086\" ``" -#: ../../source/ref-changelog.md:592 -msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." -msgstr "Le paquet expérimental `flwr.dataset` a été migré vers Flower Baselines." +#: ../../source/ref-changelog.md:436 +msgid "Both IPv4 and IPv6 addresses are supported." +msgstr "Les adresses IPv4 et IPv6 sont toutes deux prises en charge." -#: ../../source/ref-changelog.md:594 +#: ../../source/ref-changelog.md:438 msgid "" -"**Remove experimental strategies** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Add new example of Federated Learning using fastai and Flower** " +"([#1598](https://github.com/adap/flower/pull/1598))" msgstr "" -"**Supprimer les stratégies expérimentales** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " +"Flower** ([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:596 +#: ../../source/ref-changelog.md:440 msgid "" -"Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " -"`FedFSv1`)." -msgstr "" -"Supprimer les stratégies expérimentales non maintenues (`FastAndSlow`, " -"`FedFSv0`, `FedFSv1`)." +"A new code example (`quickstart-fastai`) demonstrates federated learning " +"with [fastai](https://www.fast.ai/) and Flower. You can find it here: " +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" +"/quickstart-fastai)." +msgstr "" +"Un nouvel exemple de code (`quickstart-fastai`) démontre l'apprentissage " +"fédéré avec [fastai](https://www.fast.ai/) et Flower. Tu peux le trouver " +"ici : [quickstart-" +"fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" +"fastai)." -#: ../../source/ref-changelog.md:598 +#: ../../source/ref-changelog.md:442 msgid "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" +" versions of Android** " +"([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Rendre l'exemple Android compatible avec** `flwr >= 1.0.0` **et les " +"dernières versions d'Android** " +"([#1603](https://github.com/adap/flower/pull/1603))" -#: ../../source/ref-changelog.md:600 +#: ../../source/ref-changelog.md:444 +#, fuzzy msgid "" -"`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " -"capture what this type is all about." +"The Android code example has received a substantial update: the project " +"is compatible with Flower 1.0 (and later), the UI received a full " +"refresh, and the project is updated to be compatible with newer Android " +"tooling." msgstr "" -"`flwr.common.Weights` a été renommé en `flwr.common.NDArys` pour mieux " -"rendre compte de la nature de ce type." +"L'exemple de code Android a reçu une mise à jour substantielle : le " +"projet est compatible avec Flower 1.0 et les versions ultérieures, " +"l'interface utilisateur a reçu un rafraîchissement complet, et le projet " +"est mis à jour pour être compatible avec les outils Android les plus " +"récents." -#: ../../source/ref-changelog.md:602 +#: ../../source/ref-changelog.md:446 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Add new `FedProx` strategy** " +"([#1619](https://github.com/adap/flower/pull/1619))" msgstr "" -"**Supprimez l'ancien** `force_final_distributed_eval` **de** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:604 +#: ../../source/ref-changelog.md:448 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been" -" a historic artefact, in this release it is finally gone for good." +"This " +"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" +" is almost identical to " +"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," +" but helps users replicate what is described in this " +"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " +"parameter called `proximal_mu` to regularize the local models with " +"respect to the global models." msgstr "" -"Le paramètre `start_server` `force_final_distributed_eval` a longtemps " -"été un artefact historique, dans cette version il a finalement disparu " -"pour de bon." +"Cette " +"[stratégie](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" +" est presque identique à " +"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," +" mais aide les utilisateurs à reproduire ce qui est décrit dans cet " +"[article](https://arxiv.org/abs/1812.06127). Elle ajoute essentiellement " +"un paramètre appelé `proximal_mu` pour régulariser les modèles locaux par" +" rapport aux modèles globaux." -#: ../../source/ref-changelog.md:606 +#: ../../source/ref-changelog.md:450 msgid "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Add new metrics to telemetry events** " +"([#1640](https://github.com/adap/flower/pull/1640))" msgstr "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Ajouter de nouvelles métriques aux événements de télémétrie** " +"([#1640](https://github.com/adap/flower/pull/1640))" -#: ../../source/ref-changelog.md:608 +#: ../../source/ref-changelog.md:452 msgid "" -"The `get_parameters` method now accepts a configuration dictionary, just " -"like `get_properties`, `fit`, and `evaluate`." +"An updated event structure allows, for example, the clustering of events " +"within the same workload." msgstr "" -"La méthode `get_parameters` accepte maintenant un dictionnaire de " -"configuration, tout comme `get_properties`, `fit`, et `evaluate`." +"Une structure d'événements mise à jour permet, par exemple, de regrouper " +"des événements au sein d'une même charge de travail." -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:454 msgid "" -"**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " -"**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" +"**Add new custom strategy tutorial section** " +"[#1623](https://github.com/adap/flower/pull/1623)" msgstr "" -"**Remplace** `num_rounds` **dans** `start_simulation` **avec le nouveau**" -" `config` **paramètre** " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**Ajouter une nouvelle section de tutoriel sur les stratégies " +"personnalisées** [#1623](https://github.com/adap/flower/pull/1623)" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:456 +#, fuzzy msgid "" -"The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the " -"consistency between `start_simulation` and `start_server` and makes " -"transitioning between the two easier." +"The Flower tutorial now has a new section that covers implementing a " +"custom strategy from scratch: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" msgstr "" -"La fonction `start_simulation` accepte maintenant un dictionnaire de " -"configuration `config` au lieu de l'entier `num_rounds`. Cela améliore la" -" cohérence entre `start_simulation` et `start_server` et facilite la " -"transition entre les deux." +"Le tutoriel sur les fleurs comporte désormais une nouvelle section qui " +"traite de la mise en œuvre d'une stratégie personnalisée à partir de zéro" +" : [Ouvrir dans " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-3-Building-a" +"-Strategy-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:458 msgid "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +"**Add new custom serialization tutorial section** " +"([#1622](https://github.com/adap/flower/pull/1622))" msgstr "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +"**Ajouter une nouvelle section de tutoriel sur la sérialisation " +"personnalisée** ([#1622](https://github.com/adap/flower/pull/1622))" -#: ../../source/ref-changelog.md:618 +#: ../../source/ref-changelog.md:460 +#, fuzzy msgid "" -"The previous Flower release introduced experimental support for Python " -"3.10, this release declares Python 3.10 support as stable." +"The Flower tutorial now has a new section that covers custom " +"serialization: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" -"La version précédente de Flower a introduit la prise en charge " -"expérimentale de Python 3.10, cette version déclare la prise en charge de" -" Python 3.10 comme stable." +"Le tutoriel sur les fleurs comporte désormais une nouvelle section qui " +"traite de la sérialisation personnalisée : [Ouvrir dans " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-4" +"-Client-and-NumPyClient-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:462 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**General improvements** " +"([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github.com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github.com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/adap/flower/pull/1600), " +"[#1601](https://github.com/adap/flower/pull/1601), " +"[#1597](https://github.com/adap/flower/pull/1597), " +"[#1595](https://github.com/adap/flower/pull/1595), " +"[#1591](https://github.com/adap/flower/pull/1591), " +"[#1588](https://github.com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), " +"[#1587](https://github.com/adap/flower/pull/1587), " +"[#1573](https://github.com/adap/flower/pull/1573), " +"[#1581](https://github.com/adap/flower/pull/1581), " +"[#1578](https://github.com/adap/flower/pull/1578), " +"[#1574](https://github.com/adap/flower/pull/1574), " +"[#1572](https://github.com/adap/flower/pull/1572), " +"[#1586](https://github.com/adap/flower/pull/1586))" msgstr "" -"**Rendre toutes les **méthodes `Client` **et** `NumPyClient` " -"**facultatives** ([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**General improvements** " +"([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github.com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github.com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/ada" -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:466 msgid "" -"The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that" -" implement, for example, only `fit`, but no other method. No need to " -"implement `evaluate` when using centralized evaluation!" +"**Updated documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" msgstr "" -"Les méthodes `Client`/`NumPyClient` `get_properties`, `get_parameters`, " -"`fit`, et `evaluate` sont toutes optionnelles. Cela permet d'écrire des " -"clients qui n'implémentent, par exemple, que `fit`, mais aucune autre " -"méthode. Pas besoin d'implémenter `evaluate` quand on utilise " -"l'évaluation centralisée !" +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"As usual, the documentation has improved quite a bit. It is another step " +"in our effort to make the Flower documentation the best documentation of " +"any project. Stay tuned and as always, feel free to provide feedback!" msgstr "" -"**Autoriser le passage d'une **instance `Server` à** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"Comme d'habitude, la documentation s'est beaucoup améliorée. C'est une " +"autre étape dans notre effort pour faire de la documentation de Flower la" +" meilleure documentation de tout projet. Reste à l'écoute et comme " +"toujours, n'hésite pas à nous faire part de tes commentaires !" -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:474 +msgid "v1.2.0 (2023-01-13)" +msgstr "v1.2.0 (2023-01-13)" + +#: ../../source/ref-changelog.md:480 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server`" -" instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the" -" Virtual Client Engine." +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." +" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -"Comme pour `start_server`, `start_simulation` accepte maintenant une " -"instance complète de `Server`. Cela permet aux utilisateurs de " -"personnaliser fortement l'exécution des expériences et ouvre la porte à " -"l'exécution, par exemple, de FL asynchrones à l'aide du moteur de client " -"virtuel." +"adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " +"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:484 msgid "" -"**Update code examples** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**Introduce new Flower Baseline: FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -"**Mettre à jour les exemples de code** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**Introduire une nouvelle fleur Référence : FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:486 msgid "" -"Many code examples received small or even large maintenance updates, " -"among them are" +"Over the coming weeks, we will be releasing a number of new reference " +"implementations useful especially to FL newcomers. They will typically " +"revisit well known papers from the literature, and be suitable for " +"integration in your own application or for experimentation, in order to " +"deepen your knowledge of FL in general. Today's release is the first in " +"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" +"pack-fedavg-mnist-cnn/)" msgstr "" -"De nombreux exemples de code ont reçu de petites ou même de grandes mises" -" à jour de maintenance" - -#: ../../source/ref-changelog.md:632 -msgid "`scikit-learn`" -msgstr "`scikit-learn`" - -#: ../../source/ref-changelog.md:633 -msgid "`simulation_pytorch`" -msgstr "`simulation_pytorch`" - -#: ../../source/ref-changelog.md:634 -msgid "`quickstart_pytorch`" -msgstr "`quickstart_pytorch` (démarrage rapide)" - -#: ../../source/ref-changelog.md:635 -msgid "`quickstart_simulation`" -msgstr "`quickstart_simulation`" - -#: ../../source/ref-changelog.md:636 -msgid "`quickstart_tensorflow`" -msgstr "`quickstart_tensorflow`" - -#: ../../source/ref-changelog.md:637 -msgid "`advanced_tensorflow`" -msgstr "`advanced_tensorflow` (en anglais)" +"Au cours des prochaines semaines, nous publierons un certain nombre de " +"nouvelles implémentations de référence utiles en particulier pour les " +"nouveaux venus en FL. Elles revisiteront généralement des articles bien " +"connus de la littérature, et seront adaptées à l'intégration dans votre " +"propre application ou à l'expérimentation, afin d'approfondir votre " +"connaissance de FL en général. La publication d'aujourd'hui est la " +"première de cette série. [Lire la " +"suite.](https://flower.ai/blog/2023-01-12-fl-starter-pack-fedavg-mnist-" +"cnn/)" -#: ../../source/ref-changelog.md:639 +#: ../../source/ref-changelog.md:488 msgid "" -"**Remove the obsolete simulation example** " -"([#1328](https://github.com/adap/flower/pull/1328))" +"**Improve GPU support in simulations** " +"([#1555](https://github.com/adap/flower/pull/1555))" msgstr "" -"**Supprime l'exemple de simulation obsolète** " -"([#1328](https://github.com/adap/flower/pull/1328))" +"**Améliorer la prise en charge des GPU dans les simulations** " +"([#1555](https://github.com/adap/flower/pull/1555))" -#: ../../source/ref-changelog.md:641 +#: ../../source/ref-changelog.md:490 msgid "" -"Removes the obsolete `simulation` example and renames " -"`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " -"naming of `simulation_pytorch`" +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" +" to improve GPU support. The update includes some of the hard-earned " +"lessons from scaling simulations in GPU cluster environments. New " +"defaults make running GPU-based simulations substantially more robust." msgstr "" -"Supprime l'exemple obsolète `simulation` et renomme " -"`quickstart_simulation` en `simulation_tensorflow` pour qu'il corresponde" -" au nom de `simulation_pytorch`" +"Le moteur client virtuel basé sur Ray (`start_simulation`) a été mis à " +"jour pour améliorer la prise en charge des GPU. La mise à jour inclut " +"certaines des leçons durement apprises lors de la mise à l'échelle des " +"simulations dans des environnements de grappes de GPU. De nouveaux " +"paramètres par défaut rendent l'exécution des simulations basées sur les " +"GPU beaucoup plus robuste." -#: ../../source/ref-changelog.md:643 +#: ../../source/ref-changelog.md:492 msgid "" -"**Update documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"**Improve GPU support in Jupyter Notebook tutorials** " +"([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" msgstr "" -"**Mise à jour de la documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"**Améliorer la prise en charge du GPU dans les tutoriels Jupyter " +"Notebook** ([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" -#: ../../source/ref-changelog.md:645 +#: ../../source/ref-changelog.md:494 msgid "" -"One substantial documentation update fixes multiple smaller rendering " -"issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the " -"`flwr.common` module in the API reference, includes support for markdown-" -"based documentation, migrates the changelog from `.rst` to `.md`, and " -"fixes a number of smaller details!" +"Some users reported that Jupyter Notebooks have not always been easy to " +"use on GPU instances. We listened and made improvements to all of our " +"Jupyter notebooks! Check out the updated notebooks here:" msgstr "" -"Une mise à jour substantielle de la documentation corrige plusieurs " -"petits problèmes de rendu, rend les titres plus succincts pour améliorer " -"la navigation, supprime une bibliothèque obsolète, met à jour les " -"dépendances de la documentation, inclut le module `flwr.common` dans la " -"référence de l'API, inclut le support de la documentation basée sur le " -"markdown, migre le changelog de `.rst` vers `.md`, et corrige un certain " -"nombre de détails plus petits !" - -#: ../../source/ref-changelog.md:647 ../../source/ref-changelog.md:702 -#: ../../source/ref-changelog.md:771 ../../source/ref-changelog.md:810 -msgid "**Minor updates**" -msgstr "**Mises à jour mineures**" +"Certains utilisateurs ont signalé que les carnets Jupyter n'ont pas " +"toujours été faciles à utiliser sur les instances GPU. Nous les avons " +"écoutés et avons apporté des améliorations à tous nos carnets Jupyter ! " +"Découvre les carnets mis à jour ici :" -#: ../../source/ref-changelog.md:649 +#: ../../source/ref-changelog.md:496 +#, fuzzy msgid "" -"Add round number to fit and evaluate log messages " -"([#1266](https://github.com/adap/flower/pull/1266))" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework" +"/tutorial-get-started-with-flower-pytorch.html)" msgstr "" -"Ajoute un chiffre rond pour ajuster et évaluer les messages du journal " -"([#1266](https://github.com/adap/flower/pull/1266))" +"[Une introduction à l'apprentissage fédéré] " +"(https://flower.ai/docs/tutorial/Flower-1-Intro-to-FL-PyTorch.html)" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:497 +#, fuzzy msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example " -"([#847](https://github.com/adap/flower/pull/847))" +"[Strategies in Federated Learning](https://flower.ai/docs/framework" +"/tutorial-use-a-federated-learning-strategy-pytorch.html)" msgstr "" -"Ajouter une connexion gRPC sécurisée à l'exemple de code " -"`advanced_tensorflow` ([#847](https://github.com/adap/flower/pull/847))" +"[Stratégies d'apprentissage fédéré] " +"(https://flower.ai/docs/tutorial/Flower-2-Strategies-in-FL-PyTorch.html)" -#: ../../source/ref-changelog.md:651 +#: ../../source/ref-changelog.md:498 +#, fuzzy msgid "" -"Update developer tooling " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" +"-strategy-from-scratch-pytorch.html)" msgstr "" -"Mettre à jour les outils de développement " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"[Construire une stratégie] " +"(https://flower.ai/docs/tutorial/Flower-3-Building-a-Strategy-" +"PyTorch.html)" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:499 +#, fuzzy msgid "" -"Rename ProtoBuf messages to improve consistency " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" +"customize-the-client-pytorch.html)" msgstr "" -"Renomme les messages ProtoBuf pour améliorer la cohérence " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" - -#: ../../source/ref-changelog.md:654 -msgid "v0.19.0 (2022-05-18)" -msgstr "v0.19.0 (2022-05-18)" +"[Client et NumPyClient] (https://flower.ai/docs/tutorial/Flower-4-Client-" +"and-NumPyClient-PyTorch.html)" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:501 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Introduce optional telemetry** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" msgstr "" -"**Flower Baselines (preview) : FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Introduire la télémétrie optionnelle** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:660 -#, fuzzy +#: ../../source/ref-changelog.md:503 msgid "" -"The first preview release of Flower Baselines has arrived! We're " -"kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " -"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " -"With this first preview release we're also inviting the community to " -"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" -"contribute-baselines.html)." +"After a [request for " +"feedback](https://github.com/adap/flower/issues/1534) from the community," +" the Flower open-source project introduces optional collection of " +"*anonymous* usage metrics to make well-informed decisions to improve " +"Flower. Doing this enables the Flower team to understand how Flower is " +"used and what challenges users might face." msgstr "" -"La première version préliminaire de Flower Baselines est arrivée ! Nous " -"démarrons Flower Baselines avec des implémentations de FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, et FedAvgM. Consultez la documentation sur " -"l'utilisation de [Flower Baselines](https://flower.ai/docs/using-" -"baselines.html). Avec cette première version préliminaire, nous invitons " -"également la communauté à [contribuer à leurs propres lignes de " -"base](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)." +"À la suite d'une [demande de commentaires] " +"(https://github.com/adap/flower/issues/1534) de la part de la communauté," +" le projet open-source Flower introduit la collecte optionnelle de " +"mesures d'utilisation *anonymes* afin de prendre des décisions éclairées " +"pour améliorer Flower. Cela permet à l'équipe de Flower de comprendre " +"comment Flower est utilisé et quels sont les défis auxquels les " +"utilisateurs peuvent être confrontés." -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:505 +#, fuzzy msgid "" -"**C++ client SDK (preview) and code example** " -"([#1111](https://github.com/adap/flower/pull/1111))" +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users who do not want to share anonymous usage metrics. " +"[Read more.](https://flower.ai/docs/telemetry.html)." msgstr "" -"**SDK client C++ (aperçu) et exemple de code** " -"([#1111](https://github.com/adap/flower/pull/1111))" +"**Flower est un cadre convivial pour l'IA collaborative et la science des" +" données.** Restant fidèle à cette déclaration, Flower permet de " +"désactiver facilement la télémétrie pour les utilisateurs qui ne " +"souhaitent pas partager des métriques d'utilisation anonymes.[Lire la " +"suite.](https://flower.ai/docs/telemetry.html)." -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:507 msgid "" -"Preview support for Flower clients written in C++. The C++ preview " -"includes a Flower client SDK and a quickstart code example that " -"demonstrates a simple C++ client using the SDK." -msgstr "" -"L'aperçu C++ comprend un SDK pour les clients Flower et un exemple de " -"code de démarrage rapide qui démontre un client C++ simple utilisant le " -"SDK." - -#: ../../source/ref-changelog.md:666 -msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"**Introduce (experimental) Driver API** " +"([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" msgstr "" -"**Ajouter la prise en charge expérimentale de Python 3.10 et Python " -"3.11** ([#1135](https://github.com/adap/flower/pull/1135))" +"**([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:509 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due" -" to be released in October. This Flower release adds experimental support" -" for both Python versions." +"Flower now has a new (experimental) Driver API which will enable fully " +"programmable, async, and multi-tenant Federated Learning and Federated " +"Analytics applications. Phew, that's a lot! Going forward, the Driver API" +" will be the abstraction that many upcoming features will be built on - " +"and you can start building those things now, too." msgstr "" -"Python 3.10 est la dernière version stable de Python et Python 3.11 " -"devrait sortir en octobre. Cette version de Flower ajoute une prise en " -"charge expérimentale pour les deux versions de Python." +"Flower dispose désormais d'une nouvelle API de pilote (expérimentale) qui" +" permettra de créer des applications Federated Learning et Federated " +"Analytics entièrement programmables, asynchrones et multi-tenant. Ouf, " +"c'est beaucoup ! À l'avenir, l'API de pilote sera l'abstraction sur " +"laquelle de nombreuses fonctionnalités à venir seront construites - et tu" +" peux commencer à construire ces choses dès maintenant, aussi." -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:511 msgid "" -"**Aggregate custom metrics through user-provided functions** " -"([#1144](https://github.com/adap/flower/pull/1144))" +"The Driver API also enables a new execution mode in which the server runs" +" indefinitely. Multiple individual workloads can run concurrently and " +"start and stop their execution independent of the server. This is " +"especially useful for users who want to deploy Flower in production." msgstr "" -"**Agréger des mesures personnalisées grâce à des fonctions fournies par " -"l'utilisateur** ([#1144](https://github.com/adap/flower/pull/1144))" +"L'API du pilote permet également un nouveau mode d'exécution dans lequel " +"le serveur s'exécute indéfiniment. Plusieurs charges de travail " +"individuelles peuvent s'exécuter simultanément et démarrer et arrêter " +"leur exécution indépendamment du serveur. Ceci est particulièrement utile" +" pour les utilisateurs qui souhaitent déployer Flower en production." -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:513 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" -" customize the strategy. Built-in strategies support two new arguments, " -"`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " -"allow passing custom metric aggregation functions." +"To learn more, check out the `mt-pytorch` code example. We look forward " +"to you feedback!" msgstr "" -"Les stratégies intégrées prennent en charge deux nouveaux arguments, " -"`fit_metrics_aggregation_fn` et `evaluate_metrics_aggregation_fn`, qui " -"permettent de passer des fonctions d'agrégation de métriques " -"personnalisées." +"Pour en savoir plus, consulte l'exemple de code `mt-pytorch`. Nous " +"attendons tes commentaires avec impatience !" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:515 msgid "" -"**User-configurable round timeout** " -"([#1162](https://github.com/adap/flower/pull/1162))" +"Please note: *The Driver API is still experimental and will likely change" +" significantly over time.*" msgstr "" -"**Temps d'attente configurable par l'utilisateur** " -"([#1162](https://github.com/adap/flower/pull/1162))" +"Remarque : *L'API du pilote est encore expérimentale et est susceptible " +"de changer de manière significative au fil du temps.*" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:517 msgid "" -"A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary " -"contains a `round_timeout` key (with a `float` value in seconds), the " -"server will wait *at least* `round_timeout` seconds before it closes the " -"connection." +"**Add new Federated Analytics with Pandas example** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" msgstr "" -"Si le dictionnaire `config` contient une clé `round_timeout` (avec une " -"valeur `float` en secondes), le serveur attendra *au moins* " -"`round_timeout` secondes avant de fermer la connexion." +"**Ajouter un nouvel exemple de Federated Analytics avec Pandas** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:519 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used " -"at the same time in all built-in strategies** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"A new code example (`quickstart-pandas`) demonstrates federated analytics" +" with Pandas and Flower. You can find it here: [quickstart-" +"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" +"pandas)." msgstr "" -"**Permettre l'utilisation simultanée de l'évaluation fédérée et de " -"l'évaluation centralisée dans toutes les stratégies intégrées** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"Un nouvel exemple de code (`quickstart-pandas`) démontre l'analyse " +"fédérée avec Pandas et Flower. Tu peux le trouver ici : [quickstart-" +"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" +"pandas)." -#: ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:521 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., " -"client-side) and centralized evaluation (i.e., server-side) in the same " -"round. Federated evaluation can be disabled by setting `fraction_eval` to" -" `0.0`." +"**Add new strategies: Krum and MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" msgstr "" -"Les stratégies intégrées peuvent maintenant effectuer une évaluation " -"fédérée (c'est-à-dire côté client) et une évaluation centralisée " -"(c'est-à-dire côté serveur) dans le même tour. L'évaluation fédérée peut " -"être désactivée en réglant `fraction_eval` sur `0.0`." +"**Ajouter de nouvelles stratégies : Krum et MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:523 msgid "" -"**Two new Jupyter Notebook tutorials** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"Edoardo, a computer science student at the Sapienza University of Rome, " +"contributed a new `Krum` strategy that enables users to easily use Krum " +"and MultiKrum in their workloads." msgstr "" -"**Deux nouveaux tutoriels Jupyter Notebook** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"Edoardo, étudiant en informatique à l'Université Sapienza de Rome, a " +"contribué à une nouvelle stratégie `Krum` qui permet aux utilisateurs " +"d'utiliser facilement Krum et MultiKrum dans leurs charges de travail." -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:525 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " -"basic and intermediate Flower features:" +"**Update C++ example to be compatible with Flower v1.2.0** " +"([#1495](https://github.com/adap/flower/pull/1495))" msgstr "" -"Deux tutoriels Jupyter Notebook (compatibles avec Google Colab) " -"expliquent les fonctionnalités de base et intermédiaires de Flower :" +"**Mettre à jour l'exemple C++ pour qu'il soit compatible avec Flower " +"v1.2.0** ([#1495](https://github.com/adap/flower/pull/1495))" -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:527 msgid "" -"*An Introduction to Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"The C++ code example has received a substantial update to make it " +"compatible with the latest version of Flower." msgstr "" -"*Introduction à l'apprentissage fédéré* : [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"L'exemple de code C++ a reçu une mise à jour substantielle pour le rendre" +" compatible avec la dernière version de Flower." -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:529 msgid "" -"*Using Strategies in Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"**General improvements** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" msgstr "" -"*Utiliser des stratégies dans l'apprentissage fédéré* : [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"**Améliorations générales** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:533 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"**Updated documentation** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" msgstr "" -"**Nouvelle stratégie FedAvgM (Federated Averaging with Server Momentum)**" -" ([#1076](https://github.com/adap/flower/pull/1076))" +"**Documentation mise à jour** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:692 -#, fuzzy +#: ../../source/ref-changelog.md:537 msgid "" -"The new `FedAvgM` strategy implements Federated Averaging with Server " -"Momentum \\[Hsu et al., 2019\\]." +"One highlight is the new [first time contributor " +"guide](https://flower.ai/docs/first-time-contributors.html): if you've " +"never contributed on GitHub before, this is the perfect place to start!" msgstr "" -"La nouvelle stratégie `FedAvgM` met en œuvre la moyenne fédérée avec le " -"momentum du serveur [Hsu et al., 2019]." +"L'un des points forts est le nouveau [guide du premier contributeur] " +"(https://flower.ai/docs/first-time-contributors.html) : si tu n'as jamais" +" contribué sur GitHub auparavant, c'est l'endroit idéal pour commencer !" -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:543 +msgid "v1.1.0 (2022-10-31)" +msgstr "v1.1.0 (2022-10-31)" + +#: ../../source/ref-changelog.md:547 msgid "" -"**New advanced PyTorch code example** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"We would like to give our **special thanks** to all the contributors who " +"made the new version of Flower possible (in `git shortlog` order):" msgstr "" -"**Nouvel exemple de code PyTorch avancé** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"Nous aimerions **remercier tout particulièrement** tous les contributeurs" +" qui ont rendu possible la nouvelle version de Flower (dans l'ordre `git " +"shortlog`) :" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:549 msgid "" -"A new code example (`advanced_pytorch`) demonstrates advanced Flower " -"concepts with PyTorch." -msgstr "" -"Un nouvel exemple de code (`advanced_pytorch`) démontre des concepts de " -"fleur avancés avec PyTorch." +"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " +"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" +msgstr "" +"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " +"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:553 msgid "" -"**New JAX code example** " -"([#906](https://github.com/adap/flower/pull/906), " -"[#1143](https://github.com/adap/flower/pull/1143))" +"**Introduce Differential Privacy wrappers (preview)** " +"([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" msgstr "" -"**Nouvel exemple de code JAX** " -"([#906](https://github.com/adap/flower/pull/906), " -"[#1143](https://github.com/adap/flower/pull/1143))" +"**Introduire les enveloppes de confidentialité différentielle (aperçu)** " +"([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:555 msgid "" -"A new code example (`jax_from_centralized_to_federated`) shows federated " -"learning with JAX and Flower." +"The first (experimental) preview of pluggable Differential Privacy " +"wrappers enables easy configuration and usage of differential privacy " +"(DP). The pluggable DP wrappers enable framework-agnostic **and** " +"strategy-agnostic usage of both client-side DP and server-side DP. Head " +"over to the Flower docs, a new explainer goes into more detail." msgstr "" -"Un nouvel exemple de code (`jax_from_centralized_to_federated`) montre " -"l'apprentissage fédéré avec JAX et Flower." +"Le premier aperçu (expérimental) des wrappers enfichables de " +"confidentialité différentielle permet de configurer et d'utiliser " +"facilement la confidentialité différentielle (DP). Les wrappers DP " +"enfichables permettent une utilisation agnostique du cadre **et** de la " +"stratégie à la fois de la DP côté client et de la DP côté serveur. Va " +"voir les documents de Flower, un nouvel explicatif va plus loin dans les " +"détails." -#: ../../source/ref-changelog.md:704 +#: ../../source/ref-changelog.md:557 msgid "" -"New option to keep Ray running if Ray was already initialized in " -"`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" +"**New iOS CoreML code example** " +"([#1289](https://github.com/adap/flower/pull/1289))" msgstr "" -"Nouvelle option pour continuer à faire fonctionner Ray si Ray a déjà été " -"initialisé dans `start_simulation` " -"([#1177](https://github.com/adap/flower/pull/1177))" +"**Nouvel exemple de code CoreML pour iOS** " +"([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:559 msgid "" -"Add support for custom `ClientManager` as a `start_simulation` parameter " -"([#1171](https://github.com/adap/flower/pull/1171))" +"Flower goes iOS! A massive new code example shows how Flower clients can " +"be built for iOS. The code example contains both Flower iOS SDK " +"components that can be used for many tasks, and one task example running " +"on CoreML." msgstr "" -"Ajout de la prise en charge d'un `ClientManager` personnalisé comme " -"paramètre de `start_simulation` " -"([#1171](https://github.com/adap/flower/pull/1171))" +"Flower passe à iOS ! Un nouvel exemple de code massif montre comment les " +"clients Flower peuvent être construits pour iOS. L'exemple de code " +"contient à la fois des composants Flower iOS SDK qui peuvent être " +"utilisés pour de nombreuses tâches, et un exemple de tâche fonctionnant " +"sur CoreML." -#: ../../source/ref-changelog.md:706 -#, fuzzy +#: ../../source/ref-changelog.md:561 msgid "" -"New documentation for [implementing " -"strategies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"**New FedMedian strategy** " +"([#1461](https://github.com/adap/flower/pull/1461))" msgstr "" -"Nouvelle documentation pour [mettre en œuvre des " -"stratégies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"**Nouvelle stratégie de FedMedian** " +"([#1461](https://github.com/adap/flower/pull/1461))" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:563 msgid "" -"New mobile-friendly documentation theme " -"([#1174](https://github.com/adap/flower/pull/1174))" +"The new `FedMedian` strategy implements Federated Median (FedMedian) by " +"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -"Nouveau thème de documentation adapté aux mobiles " -"([#1174](https://github.com/adap/flower/pull/1174))" +"La nouvelle stratégie `FedMedian` met en œuvre Federated Median " +"(FedMedian) par [Yin et al., 2018] " +"(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:708 +#: ../../source/ref-changelog.md:565 msgid "" -"Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"**Log** `Client` **exceptions in Virtual Client Engine** " +"([#1493](https://github.com/adap/flower/pull/1493))" msgstr "" -"Limite la plage de versions pour la dépendance (optionnelle) `ray` pour " -"n'inclure que les versions compatibles (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"**Log** `Client` **exceptions dans le moteur de client virtuel** " +"([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:567 msgid "" -"**Remove deprecated support for Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" +"All `Client` exceptions happening in the VCE are now logged by default " +"and not just exposed to the configured `Strategy` (via the `failures` " +"argument)." msgstr "" -"**Supprime la prise en charge obsolète de Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" +"Toutes les exceptions `Client` qui se produisent dans le VCE sont " +"maintenant enregistrées par défaut et ne sont pas seulement exposées à la" +" `Stratégie` configurée (via l'argument `failures`)." -#: ../../source/ref-changelog.md:713 +#: ../../source/ref-changelog.md:569 msgid "" -"**Remove deprecated KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" +"**Improve Virtual Client Engine internals** " +"([#1401](https://github.com/adap/flower/pull/1401), " +"[#1453](https://github.com/adap/flower/pull/1453))" msgstr "" -"**Supprimez KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" +"**Améliorer le moteur du client virtuel** " +"([#1401](https://github.com/adap/flower/pull/1401), " +"[#1453](https://github.com/adap/flower/pull/1453))" -#: ../../source/ref-changelog.md:714 +#: ../../source/ref-changelog.md:571 msgid "" -"**Remove deprecated no-op extra installs** " -"([#973](https://github.com/adap/flower/pull/973))" +"Some internals of the Virtual Client Engine have been revamped. The VCE " +"now uses Ray 2.0 under the hood, the value type of the `client_resources`" +" dictionary changed to `float` to allow fractions of resources to be " +"allocated." msgstr "" -"**Supprimer les installations supplémentaires no-op dépréciées** " -"([#973](https://github.com/adap/flower/pull/973))" +"Le VCE utilise maintenant Ray 2.0 sous le capot, le type de valeur du " +"dictionnaire `client_resources` a été remplacé par `float` pour permettre" +" l'allocation de fractions de ressources." -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:573 msgid "" -"**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " -"([#869](https://github.com/adap/flower/pull/869))" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " +"Client Engine**" msgstr "" -"**Supprimez les champs proto obsolètes de** `FitRes` **et** `EvaluateRes`" -" ([#869](https://github.com/adap/flower/pull/869))" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " +"Client Engine**" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:575 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"The Virtual Client Engine now has full support for optional `Client` (and" +" `NumPyClient`) methods." msgstr "" -"**Supprime la stratégie QffedAvg (remplacée par QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"Le moteur de client virtuel prend désormais en charge les méthodes " +"optionnelles `Client` (et `NumPyClient`)." -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:577 msgid "" -"**Remove deprecated DefaultStrategy strategy** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Provide type information to packages using** `flwr` " +"([#1377](https://github.com/adap/flower/pull/1377))" msgstr "" -"**Supprime la stratégie DefaultStrategy qui est obsolète** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Fournir des informations de type aux paquets en utilisant** `flwr` " +"([#1377](https://github.com/adap/flower/pull/1377))" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:579 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"The package `flwr` is now bundled with a `py.typed` file indicating that " +"the package is typed. This enables typing support for projects or " +"packages that use `flwr` by enabling them to improve their code using " +"static type checkers like `mypy`." msgstr "" -"**Supprimer la prise en charge obsolète de la valeur de retour de la " -"précision eval_fn** ([#1142](https://github.com/adap/flower/pull/1142))" +"Le paquet `flwr` est maintenant accompagné d'un fichier `py.typed` " +"indiquant que le paquet est typé. Cela permet de prendre en charge le " +"typage pour les projets ou les paquets qui utilisent `flwr` en leur " +"permettant d'améliorer leur code à l'aide de vérificateurs de types " +"statiques comme `mypy`." -#: ../../source/ref-changelog.md:719 +#: ../../source/ref-changelog.md:581 msgid "" -"**Remove deprecated support for passing initial parameters as NumPy " -"ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" +"**Updated code example** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -"**Supprime la prise en charge obsolète du passage des paramètres initiaux" -" en tant que ndarrays NumPy** " -"([#1142](https://github.com/adap/flower/pull/1142))" - -#: ../../source/ref-changelog.md:721 -msgid "v0.18.0 (2022-02-28)" -msgstr "v0.18.0 (2022-02-28)" +"**Exemple de code mis à jour** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:725 +#: ../../source/ref-changelog.md:583 msgid "" -"**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"The code examples covering scikit-learn and PyTorch Lightning have been " +"updated to work with the latest version of Flower." msgstr "" -"**Amélioration de la compatibilité du moteur de client virtuel avec " -"Jupyter Notebook / Google Colab** " -"([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"Les exemples de code couvrant scikit-learn et PyTorch Lightning ont été " +"mis à jour pour fonctionner avec la dernière version de Flower." -#: ../../source/ref-changelog.md:727 +#: ../../source/ref-changelog.md:585 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) " -"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " -"installing Flower with the `simulation` extra (`pip install " -"flwr[simulation]`)." +"**Updated documentation** " +"([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github.com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" msgstr "" -"Les simulations (utilisant le moteur de client virtuel via " -"`start_simulation`) fonctionnent maintenant plus facilement sur les " -"Notebooks Jupyter (y compris Google Colab) après avoir installé Flower " -"avec l'option `simulation` (`pip install flwr[simulation]`)." +"**Documentation mise à jour** " +"([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github.com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" -#: ../../source/ref-changelog.md:729 +#: ../../source/ref-changelog.md:587 msgid "" -"**New Jupyter Notebook code example** " -"([#833](https://github.com/adap/flower/pull/833))" +"There have been so many documentation updates that it doesn't even make " +"sense to list them individually." msgstr "" -"**Nouvel exemple de code Jupyter Notebook** " -"([#833](https://github.com/adap/flower/pull/833))" +"Il y a eu tellement de mises à jour de la documentation que cela n'a même" +" pas de sens de les énumérer individuellement." -#: ../../source/ref-changelog.md:731 +#: ../../source/ref-changelog.md:589 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower " -"simulations using the Virtual Client Engine through Jupyter Notebook " -"(incl. Google Colab)." +"**Restructured documentation** " +"([#1387](https://github.com/adap/flower/pull/1387))" msgstr "" -"Un nouvel exemple de code (`quickstart_simulation`) démontre des " -"simulations de Flower en utilisant le moteur de client virtuel via " -"Jupyter Notebook (y compris Google Colab)." +"**Documentation restructurée** " +"([#1387](https://github.com/adap/flower/pull/1387))" -#: ../../source/ref-changelog.md:733 +#: ../../source/ref-changelog.md:591 msgid "" -"**Client properties (feature preview)** " -"([#795](https://github.com/adap/flower/pull/795))" +"The documentation has been restructured to make it easier to navigate. " +"This is just the first step in a larger effort to make the Flower " +"documentation the best documentation of any project ever. Stay tuned!" msgstr "" -"**Propriétés du client (aperçu des fonctionnalités)** " -"([#795](https://github.com/adap/flower/pull/795))" +"La documentation a été restructurée pour faciliter la navigation. Ce " +"n'est que la première étape d'un effort plus important visant à faire de " +"la documentation de Flower la meilleure documentation de tous les projets" -#: ../../source/ref-changelog.md:735 +#: ../../source/ref-changelog.md:593 msgid "" -"Clients can implement a new method `get_properties` to enable server-side" -" strategies to query client properties." +"**Open in Colab button** " +"([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" -"Les clients peuvent implémenter une nouvelle méthode `get_properties` " -"pour permettre aux stratégies côté serveur d'interroger les propriétés du" -" client." +"**Ouvrir dans le bouton Colab** " +"([#1389](https://github.com/adap/flower/pull/1389))" -#: ../../source/ref-changelog.md:737 +#: ../../source/ref-changelog.md:595 msgid "" -"**Experimental Android support with TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" +"The four parts of the Flower Federated Learning Tutorial now come with a " +"new `Open in Colab` button. No need to install anything on your local " +"machine, you can now use and learn about Flower in your browser, it's " +"only a single click away." msgstr "" -"**Support expérimental d'Android avec TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" +"Les quatre parties du didacticiel d'apprentissage fédéré Flower sont " +"maintenant accompagnées d'un nouveau bouton \"Ouvrir dans Colab\". Pas " +"besoin d'installer quoi que ce soit sur ta machine locale, tu peux " +"maintenant utiliser et apprendre à connaître Flower dans ton navigateur, " +"il te suffit d'un simple clic." -#: ../../source/ref-changelog.md:739 +#: ../../source/ref-changelog.md:597 msgid "" -"Android support has finally arrived in `main`! Flower is both client-" -"agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has " -"become a lot easier." +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" msgstr "" -"La prise en charge d'Android est enfin arrivée dans `main` ! Flower est à" -" la fois agnostique au niveau du client et du cadre de travail. On peut " -"intégrer des plates-formes client arbitraires et avec cette version, " -"l'utilisation de Flower sur Android est devenue beaucoup plus facile." +"**Tutoriel amélioré** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:741 +#: ../../source/ref-changelog.md:599 msgid "" -"The example uses TFLite on the client side, along with a new " -"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " -"still experimental, but they are a first step towards a fully-fledged " -"Android SDK and a unified `FedAvg` implementation that integrated the new" -" functionality from `FedAvgAndroid`." +"The Flower Federated Learning Tutorial has two brand-new parts covering " +"custom strategies (still WIP) and the distinction between `Client` and " +"`NumPyClient`. The existing parts one and two have also been improved " +"(many small changes and fixes)." msgstr "" -"L'exemple utilise TFLite du côté client, ainsi qu'une nouvelle stratégie " -"`FedAvgAndroid`. Le client Android et `FedAvgAndroid` sont encore " -"expérimentaux, mais ils constituent un premier pas vers un SDK Android à " -"part entière et une implémentation unifiée de `FedAvg` intégrant la " -"nouvelle fonctionnalité de `FedAvgAndroid`." +"Le tutoriel sur l'apprentissage fédéré des fleurs a deux toutes nouvelles" +" parties couvrant les stratégies personnalisées (encore WIP) et la " +"distinction entre `Client` et `NumPyClient`. Les parties un et deux " +"existantes ont également été améliorées (beaucoup de petits changements " +"et de corrections)." + +#: ../../source/ref-changelog.md:605 +msgid "v1.0.0 (2022-07-28)" +msgstr "v1.0.0 (2022-07-28)" + +#: ../../source/ref-changelog.md:607 +msgid "Highlights" +msgstr "Points forts" + +#: ../../source/ref-changelog.md:609 +msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" +msgstr "Moteur de client virtuel stable** (accessible via `start_simulation`)" + +#: ../../source/ref-changelog.md:610 +msgid "All `Client`/`NumPyClient` methods are now optional" +msgstr "Toutes les méthodes `Client`/`NumPyClient` sont maintenant optionnelles" + +#: ../../source/ref-changelog.md:611 +msgid "Configurable `get_parameters`" +msgstr "`get_parameters` configurable" -#: ../../source/ref-changelog.md:743 +#: ../../source/ref-changelog.md:612 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default " -"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" +"Tons of small API cleanups resulting in a more coherent developer " +"experience" msgstr "" -"**Rendre le temps de garde gRPC configurable par l'utilisateur et " -"diminuer le temps de garde par défaut** " -"([#1069](https://github.com/adap/flower/pull/1069))" +"Des tonnes de petits nettoyages d'API résultant en une expérience plus " +"cohérente pour les développeurs" -#: ../../source/ref-changelog.md:745 +#: ../../source/ref-changelog.md:616 msgid "" -"The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, " -"Microsoft Azure). Users can configure the keepalive time to customize the" -" gRPC stack based on specific requirements." +"We would like to give our **special thanks** to all the contributors who " +"made Flower 1.0 possible (in reverse [GitHub " +"Contributors](https://github.com/adap/flower/graphs/contributors) order):" msgstr "" -"Le temps de keepalive gRPC par défaut a été réduit pour augmenter la " -"compatibilité de Flower avec davantage d'environnements cloud (par " -"exemple, Microsoft Azure). Les utilisateurs peuvent configurer le temps " -"de keepalive pour personnaliser la pile gRPC en fonction d'exigences " -"spécifiques." +"Nous tenons à remercier **particulièrement** tous les contributeurs qui " +"ont rendu Flower 1.0 possible (dans l'ordre inverse de [GitHub " +"Contributors](https://github.com/adap/flower/graphs/contributors)) :" -#: ../../source/ref-changelog.md:747 +#: ../../source/ref-changelog.md:618 msgid "" -"**New differential privacy example using Opacus and PyTorch** " -"([#805](https://github.com/adap/flower/pull/805))" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), " +"[@mrinaald](https://github.com/mrinaald), " +"[@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), " +"[@sancarlim](https://github.com/sancarlim), " +"[@gubertoli](https://github.com/gubertoli), " +"[@Vingt100](https://github.com/Vingt100), " +"[@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), " +"[@jafermarq](https://github.com/jafermarq), " +"[@sisco0](https://github.com/sisco0), " +"[@akhilmathurs](https://github.com/akhilmathurs), " +"[@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), " +"[@pedropgusmao](https://github.com/pedropgusmao), " +"[@tanertopal](https://github.com/tanertopal), " +"[@danieljanes](https://github.com/danieljanes)." msgstr "" -"**Nouvel exemple de confidentialité différentielle utilisant Opacus et " -"PyTorch** ([#805](https://github.com/adap/flower/pull/805))" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), [@mrinaald](" -#: ../../source/ref-changelog.md:749 +#: ../../source/ref-changelog.md:622 msgid "" -"A new code example (`opacus`) demonstrates differentially-private " -"federated learning with Opacus, PyTorch, and Flower." +"**All arguments must be passed as keyword arguments** " +"([#1338](https://github.com/adap/flower/pull/1338))" msgstr "" -"Un nouvel exemple de code (`opacus`) démontre l'apprentissage fédéré " -"différentiellement privé avec Opacus, PyTorch et Flower." +"**Tous les arguments doivent être passés comme des arguments de mot-clé**" +" ([#1338](https://github.com/adap/flower/pull/1338))" -#: ../../source/ref-changelog.md:751 +#: ../../source/ref-changelog.md:624 +#, fuzzy msgid "" -"**New Hugging Face Transformers code example** " -"([#863](https://github.com/adap/flower/pull/863))" +"Pass all arguments as keyword arguments, positional arguments are not " +"longer supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " +"for each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)." msgstr "" -"**Nouvel exemple de code pour les Transformers à visage embrassant** " -"([#863](https://github.com/adap/flower/pull/863))" +"Le code qui utilise des arguments positionnels (par exemple, " +"``start_client(\"127.0.0.1:8080\", FlowerClient())`) doit ajouter le mot-" +"clé pour chaque argument positionnel (par exemple, " +"``start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)." -#: ../../source/ref-changelog.md:753 +#: ../../source/ref-changelog.md:626 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of " -"Hugging Face Transformers with Flower." +"**Introduce configuration object** `ServerConfig` **in** `start_server` " +"**and** `start_simulation` " +"([#1317](https://github.com/adap/flower/pull/1317))" msgstr "" -"Un nouvel exemple de code (`quickstart_huggingface`) démontre " -"l'utilisation des transformateurs Hugging Face avec Flower." +"**Introduire l'objet de configuration** `ServerConfig` **dans** " +"`start_server` **et** `start_simulation` " +"([#1317](https://github.com/adap/flower/pull/1317))" -#: ../../source/ref-changelog.md:755 +#: ../../source/ref-changelog.md:628 msgid "" -"**New MLCube code example** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " +"600.0}`, `start_server` and `start_simulation` now expect a configuration" +" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" +" arguments that as the previous config dict, but it makes writing type-" +"safe code easier and the default parameters values more transparent." msgstr "" -"**Nouvel exemple de code MLCube** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"Au lieu d'un dictionnaire de configuration `{\"num_rounds\" : 3, " +"\"round_timeout\" : 600.0}`, `start_server` et `start_simulation` " +"attendent maintenant un objet de configuration de type " +"`flwr.server.ServerConfig`. `ServerConfig` prend les mêmes arguments que " +"le dict de configuration précédent, mais il rend l'écriture de code " +"sécurisé plus facile et les valeurs des paramètres par défaut plus " +"transparentes." -#: ../../source/ref-changelog.md:757 +#: ../../source/ref-changelog.md:630 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " -"with Flower." +"**Rename built-in strategy parameters for clarity** " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -"Un nouvel exemple de code (`quickstart_mlcube`) démontre l'utilisation de" -" MLCube avec Flower." +"**Renommer les paramètres de la stratégie intégrée pour plus de clarté** " +"([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:759 +#: ../../source/ref-changelog.md:632 msgid "" -"**SSL-enabled server and client** " -"([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"The following built-in strategy parameters were renamed to improve " +"readability and consistency with other API's:" msgstr "" -"**([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"Les paramètres de stratégie intégrés suivants ont été renommés pour " +"améliorer la lisibilité et la cohérence avec d'autres API :" + +#: ../../source/ref-changelog.md:634 +msgid "`fraction_eval` --> `fraction_evaluate`" +msgstr "`fraction_eval` --> `fraction_evaluate`" + +#: ../../source/ref-changelog.md:635 +msgid "`min_eval_clients` --> `min_evaluate_clients`" +msgstr "`min_eval_clients` --> `min_evaluate_clients`" + +#: ../../source/ref-changelog.md:636 +msgid "`eval_fn` --> `evaluate_fn`" +msgstr "`eval_fn` --> `evaluate_fn`" -#: ../../source/ref-changelog.md:761 +#: ../../source/ref-changelog.md:638 msgid "" -"SSL enables secure encrypted connections between clients and servers. " -"This release open-sources the Flower secure gRPC implementation to make " -"encrypted communication channels accessible to all Flower users." +"**Update default arguments of built-in strategies** " +"([#1278](https://github.com/adap/flower/pull/1278))" msgstr "" -"SSL permet d'établir des connexions cryptées et sécurisées entre les " -"clients et les serveurs. Cette version met en open-source " -"l'implémentation gRPC sécurisée de Flower afin de rendre les canaux de " -"communication cryptés accessibles à tous les utilisateurs de Flower." +"**Mettre à jour les arguments par défaut des stratégies intégrées** " +"([#1278](https://github.com/adap/flower/pull/1278))" -#: ../../source/ref-changelog.md:763 +#: ../../source/ref-changelog.md:640 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"All built-in strategies now use `fraction_fit=1.0` and " +"`fraction_evaluate=1.0`, which means they select *all* currently " +"available clients for training and evaluation. Projects that relied on " +"the previous default values can get the previous behaviour by " +"initializing the strategy in the following way:" msgstr "" -"**Mise à jour** `FedAdam` **et** `FedYogi` **stratégies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"Toutes les stratégies intégrées utilisent désormais `fraction_fit=1.0` et" +" `fraction_evaluate=1.0`, ce qui signifie qu'elles sélectionnent *tous* " +"les clients actuellement disponibles pour l'entraînement et l'évaluation." +" Les projets qui s'appuyaient sur les valeurs par défaut précédentes " +"peuvent retrouver le comportement antérieur en initialisant la stratégie " +"de la manière suivante :" + +#: ../../source/ref-changelog.md:642 +msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" +msgstr "`stratégie = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" -#: ../../source/ref-changelog.md:765 +#: ../../source/ref-changelog.md:644 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive " -"Federated Optimization paper." +"**Add** `server_round` **to** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -"`FedAdam` et `FedAdam` correspondent à la dernière version de l'article " -"sur l'optimisation fédérée adaptative." +"**Ajouter** `server_round` **à** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:767 +#: ../../source/ref-changelog.md:646 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** " -"([#860](https://github.com/adap/flower/pull/860))" +"The `Strategy` method `evaluate` now receives the current round of " +"federated learning/evaluation as the first parameter." msgstr "" -"**Initialise** `start_simulation` **avec une liste d'ID de clients** " -"([#860](https://github.com/adap/flower/pull/860))" +"La méthode `Stratégie` `évaluer` reçoit maintenant le cycle actuel " +"d'apprentissage/évaluation fédéré comme premier paramètre." -#: ../../source/ref-changelog.md:769 +#: ../../source/ref-changelog.md:648 msgid "" -"`start_simulation` can now be called with a list of client IDs " -"(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " -"`client_fn` whenever a client needs to be initialized, which can make it " -"easier to load data partitions that are not accessible through `int` " -"identifiers." +"**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -"`start_simulation` peut maintenant être appelé avec une liste " -"d'identifiants de clients (`clients_ids`, type : `List[str]`). Ces " -"identifiants seront passés à `client_fn` chaque fois qu'un client doit " -"être initialisé, ce qui peut faciliter le chargement de partitions de " -"données qui ne sont pas accessibles par des identifiants `int`." +"**Ajouter** `server_round` **et** `config` **paramètres à** `evaluate_fn`" +" ([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:650 msgid "" -"Update `num_examples` calculation in PyTorch code examples in " -"([#909](https://github.com/adap/flower/pull/909))" +"The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " +"three parameters: (1) The current round of federated learning/evaluation " +"(`server_round`), (2) the model parameters to evaluate (`parameters`), " +"and (3) a config dictionary (`config`)." msgstr "" -"Mettre à jour le calcul de `num_examples` dans les exemples de code " -"PyTorch dans ([#909](https://github.com/adap/flower/pull/909))" +"Le `evaluate_fn` passé aux stratégies intégrées comme `FedAvg` prend " +"maintenant trois paramètres : (1) le cycle actuel " +"d'apprentissage/évaluation fédéré (`server_round`), (2) les paramètres du" +" modèle à évaluer (`parameters`), et (3) un dictionnaire de configuration" +" (`config`)." -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:652 msgid "" -"Expose Flower version through `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" msgstr "" -"Exposer la version de Flower à travers `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:775 +#: ../../source/ref-changelog.md:654 msgid "" -"`start_server` in `app.py` now returns a `History` object containing " -"metrics from training ([#974](https://github.com/adap/flower/pull/974))" +"Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " +"`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " +"current round of federated learning/evaluation as their first parameter. " +"To improve reaability and avoid confusion with *random*, this parameter " +"has been renamed from `rnd` to `server_round`." msgstr "" -"`start_server` dans `app.py` renvoie maintenant un objet `History` " -"contenant les métriques de l'entraînement " -"([#974](https://github.com/adap/flower/pull/974))" +"Plusieurs méthodes et fonctions de Flower (`evaluate_fn`, " +"`configure_fit`, `aggregate_fit`, `configure_evaluate`, " +"`aggregate_evaluate`) reçoivent le cycle actuel " +"d'apprentissage/évaluation fédéré comme premier paramètre. Pour améliorer" +" la fiabilité et éviter la confusion avec *random*, ce paramètre a été " +"renommé de `rnd` à `server_round`." -#: ../../source/ref-changelog.md:776 +#: ../../source/ref-changelog.md:656 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"**Move** `flwr.dataset` **to** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" msgstr "" -"Rendre `max_workers` (utilisé par `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"**Déplacer** `flwr.dataset` **vers** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" + +#: ../../source/ref-changelog.md:658 +msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." +msgstr "Le paquet expérimental `flwr.dataset` a été migré vers Flower Baselines." -#: ../../source/ref-changelog.md:777 +#: ../../source/ref-changelog.md:660 msgid "" -"Increase sleep time after server start to three seconds in all code " -"examples ([#1086](https://github.com/adap/flower/pull/1086))" +"**Remove experimental strategies** " +"([#1280](https://github.com/adap/flower/pull/1280))" msgstr "" -"Augmente le temps de sommeil après le démarrage du serveur à trois " -"secondes dans tous les exemples de code " -"([#1086](https://github.com/adap/flower/pull/1086))" +"**Supprimer les stratégies expérimentales** " +"([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:662 msgid "" -"Added a new FAQ section to the documentation " -"([#948](https://github.com/adap/flower/pull/948))" +"Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " +"`FedFSv1`)." msgstr "" -"Ajout d'une nouvelle section FAQ à la documentation " -"([#948](https://github.com/adap/flower/pull/948))" +"Supprimer les stratégies expérimentales non maintenues (`FastAndSlow`, " +"`FedFSv0`, `FedFSv1`)." -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:664 msgid "" -"And many more under-the-hood changes, library updates, documentation " -"changes, and tooling improvements!" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"Et bien d'autres changements sous le capot, des mises à jour de la " -"bibliothèque, des modifications de la documentation et des améliorations " -"de l'outillage !" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:666 msgid "" -"**Removed** `flwr_example` **and** `flwr_experimental` **from release " -"build** ([#869](https://github.com/adap/flower/pull/869))" +"`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " +"capture what this type is all about." msgstr "" -"**Supprimé** `flwr_example` **et** `flwr_experimental` **de la version " -"release build** ([#869](https://github.com/adap/flower/pull/869))" +"`flwr.common.Weights` a été renommé en `flwr.common.NDArys` pour mieux " +"rendre compte de la nature de ce type." -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:668 msgid "" -"The packages `flwr_example` and `flwr_experimental` have been deprecated " -"since Flower 0.12.0 and they are not longer included in Flower release " -"builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " -"an upcoming release." +"**Remove antiquated** `force_final_distributed_eval` **from** " +"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"Les paquets `flwr_example` et `flwr_experimental` ont été dépréciés " -"depuis Flower 0.12.0 et ils ne sont plus inclus dans les builds de " -"Flower. Les extras associés (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) sont maintenant no-op et seront " -"supprimés dans une prochaine version." - -#: ../../source/ref-changelog.md:787 -msgid "v0.17.0 (2021-09-24)" -msgstr "v0.17.0 (2021-09-24)" +"**Supprimez l'ancien** `force_final_distributed_eval` **de** " +"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:670 msgid "" -"**Experimental virtual client engine** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"The `start_server` parameter `force_final_distributed_eval` has long been" +" a historic artefact, in this release it is finally gone for good." msgstr "" -"**Moteur expérimental de client virtuel** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"Le paramètre `start_server` `force_final_distributed_eval` a longtemps " +"été un artefact historique, dans cette version il a finalement disparu " +"pour de bon." -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:672 msgid "" -"One of Flower's goals is to enable research at scale. This release " -"enables a first (experimental) peek at a major new feature, codenamed the" -" virtual client engine. Virtual clients enable simulations that scale to " -"a (very) large number of clients on a single machine or compute cluster. " -"The easiest way to test the new functionality is to look at the two new " -"code examples called `quickstart_simulation` and `simulation_pytorch`." +"**Make** `get_parameters` **configurable** " +"([#1242](https://github.com/adap/flower/pull/1242))" msgstr "" -"L'un des objectifs de Flower est de permettre la recherche à grande " -"échelle. Cette version donne un premier aperçu (expérimental) d'une " -"nouvelle fonctionnalité majeure, connue sous le nom de code de moteur de " -"client virtuel. Les clients virtuels permettent des simulations qui " -"s'étendent à un (très) grand nombre de clients sur une seule machine ou " -"une grappe de calcul. La façon la plus simple de tester la nouvelle " -"fonctionnalité est de regarder les deux nouveaux exemples de code appelés" -" `quickstart_simulation` et `simulation_pytorch`." +"**Make** `get_parameters` **configurable** " +"([#1242](https://github.com/adap/flower/pull/1242))" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:674 msgid "" -"The feature is still experimental, so there's no stability guarantee for " -"the API. It's also not quite ready for prime time and comes with a few " -"known caveats. However, those who are curious are encouraged to try it " -"out and share their thoughts." +"The `get_parameters` method now accepts a configuration dictionary, just " +"like `get_properties`, `fit`, and `evaluate`." msgstr "" -"La fonction est encore expérimentale, il n'y a donc aucune garantie de " -"stabilité pour l'API. Elle n'est pas non plus tout à fait prête pour le " -"prime time et s'accompagne de quelques mises en garde connues. Cependant," -" les personnes curieuses sont encouragées à l'essayer et à faire part de " -"leurs réflexions." +"La méthode `get_parameters` accepte maintenant un dictionnaire de " +"configuration, tout comme `get_properties`, `fit`, et `evaluate`." -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:676 msgid "" -"**New built-in strategies** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" +"**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " +"**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -"**Nouvelles stratégies intégrées** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" +"**Remplace** `num_rounds` **dans** `start_simulation` **avec le nouveau**" +" `config` **paramètre** " +"([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:678 msgid "" -"FedYogi - Federated learning strategy using Yogi on server-side. " -"Implementation based on https://arxiv.org/abs/2003.00295" +"The `start_simulation` function now accepts a configuration dictionary " +"`config` instead of the `num_rounds` integer. This improves the " +"consistency between `start_simulation` and `start_server` and makes " +"transitioning between the two easier." msgstr "" -"FedYogi - Stratégie d'apprentissage fédéré utilisant Yogi côté serveur. " -"Mise en oeuvre basée sur https://arxiv.org/abs/2003.00295" +"La fonction `start_simulation` accepte maintenant un dictionnaire de " +"configuration `config` au lieu de l'entier `num_rounds`. Cela améliore la" +" cohérence entre `start_simulation` et `start_server` et facilite la " +"transition entre les deux." -#: ../../source/ref-changelog.md:800 +#: ../../source/ref-changelog.md:682 msgid "" -"FedAdam - Federated learning strategy using Adam on server-side. " -"Implementation based on https://arxiv.org/abs/2003.00295" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" -"FedAdam - Stratégie d'apprentissage fédéré utilisant Adam côté serveur. " -"Mise en œuvre basée sur https://arxiv.org/abs/2003.00295" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:802 +#: ../../source/ref-changelog.md:684 msgid "" -"**New PyTorch Lightning code example** " -"([#617](https://github.com/adap/flower/pull/617))" +"The previous Flower release introduced experimental support for Python " +"3.10, this release declares Python 3.10 support as stable." msgstr "" -"**Nouvel exemple de code PyTorch Lightning** " -"([#617](https://github.com/adap/flower/pull/617))" +"La version précédente de Flower a introduit la prise en charge " +"expérimentale de Python 3.10, cette version déclare la prise en charge de" +" Python 3.10 comme stable." -#: ../../source/ref-changelog.md:804 +#: ../../source/ref-changelog.md:686 msgid "" -"**New Variational Auto-Encoder code example** " -"([#752](https://github.com/adap/flower/pull/752))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** " +"([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" msgstr "" -"**Nouvel exemple de code d'autocodage variationnel** " -"([#752](https://github.com/adap/flower/pull/752))" +"**Rendre toutes les **méthodes `Client` **et** `NumPyClient` " +"**facultatives** ([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" -#: ../../source/ref-changelog.md:806 +#: ../../source/ref-changelog.md:688 msgid "" -"**New scikit-learn code example** " -"([#748](https://github.com/adap/flower/pull/748))" +"The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " +"`fit`, and `evaluate` are all optional. This enables writing clients that" +" implement, for example, only `fit`, but no other method. No need to " +"implement `evaluate` when using centralized evaluation!" msgstr "" -"**Nouvel exemple de code scikit-learn** " -"([#748](https://github.com/adap/flower/pull/748))" +"Les méthodes `Client`/`NumPyClient` `get_properties`, `get_parameters`, " +"`fit`, et `evaluate` sont toutes optionnelles. Cela permet d'écrire des " +"clients qui n'implémentent, par exemple, que `fit`, mais aucune autre " +"méthode. Pas besoin d'implémenter `evaluate` quand on utilise " +"l'évaluation centralisée !" -#: ../../source/ref-changelog.md:808 +#: ../../source/ref-changelog.md:690 msgid "" -"**New experimental TensorBoard strategy** " -"([#789](https://github.com/adap/flower/pull/789))" +"**Enable passing a** `Server` **instance to** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -"**Nouvelle stratégie expérimentale TensorBoard** " -"([#789](https://github.com/adap/flower/pull/789))" +"**Autoriser le passage d'une **instance `Server` à** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:812 +#: ../../source/ref-changelog.md:692 msgid "" -"Improved advanced TensorFlow code example " -"([#769](https://github.com/adap/flower/pull/769))" +"Similar to `start_server`, `start_simulation` now accepts a full `Server`" +" instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the" +" Virtual Client Engine." msgstr "" -"Amélioration de l'exemple de code TensorFlow avancé " -"([#769](https://github.com/adap/flower/pull/769))" +"Comme pour `start_server`, `start_simulation` accepte maintenant une " +"instance complète de `Server`. Cela permet aux utilisateurs de " +"personnaliser fortement l'exécution des expériences et ouvre la porte à " +"l'exécution, par exemple, de FL asynchrones à l'aide du moteur de client " +"virtuel." -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:694 msgid "" -"Warning when `min_available_clients` is misconfigured " -"([#830](https://github.com/adap/flower/pull/830))" +"**Update code examples** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" msgstr "" -"Avertissement lorsque `min_available_clients` est mal configuré " -"([#830](https://github.com/adap/flower/pull/830))" +"**Mettre à jour les exemples de code** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:814 +#: ../../source/ref-changelog.md:696 msgid "" -"Improved gRPC server docs " -"([#841](https://github.com/adap/flower/pull/841))" +"Many code examples received small or even large maintenance updates, " +"among them are" msgstr "" -"Amélioration de la documentation sur le serveur gRPC " -"([#841](https://github.com/adap/flower/pull/841))" +"De nombreux exemples de code ont reçu de petites ou même de grandes mises" +" à jour de maintenance" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:698 +msgid "`scikit-learn`" +msgstr "`scikit-learn`" + +#: ../../source/ref-changelog.md:699 +msgid "`simulation_pytorch`" +msgstr "`simulation_pytorch`" + +#: ../../source/ref-changelog.md:700 +msgid "`quickstart_pytorch`" +msgstr "`quickstart_pytorch` (démarrage rapide)" + +#: ../../source/ref-changelog.md:701 +msgid "`quickstart_simulation`" +msgstr "`quickstart_simulation`" + +#: ../../source/ref-changelog.md:702 +msgid "`quickstart_tensorflow`" +msgstr "`quickstart_tensorflow`" + +#: ../../source/ref-changelog.md:703 +msgid "`advanced_tensorflow`" +msgstr "`advanced_tensorflow` (en anglais)" + +#: ../../source/ref-changelog.md:705 msgid "" -"Improved error message in `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" +"**Remove the obsolete simulation example** " +"([#1328](https://github.com/adap/flower/pull/1328))" msgstr "" -"Amélioration du message d'erreur dans `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" +"**Supprime l'exemple de simulation obsolète** " +"([#1328](https://github.com/adap/flower/pull/1328))" -#: ../../source/ref-changelog.md:816 +#: ../../source/ref-changelog.md:707 msgid "" -"Improved PyTorch quickstart code example " -"([#852](https://github.com/adap/flower/pull/852))" +"Removes the obsolete `simulation` example and renames " +"`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " +"naming of `simulation_pytorch`" msgstr "" -"Exemple de code de démarrage rapide PyTorch amélioré " -"([#852](https://github.com/adap/flower/pull/852))" +"Supprime l'exemple obsolète `simulation` et renomme " +"`quickstart_simulation` en `simulation_tensorflow` pour qu'il corresponde" +" au nom de `simulation_pytorch`" -#: ../../source/ref-changelog.md:820 +#: ../../source/ref-changelog.md:709 msgid "" -"**Disabled final distributed evaluation** " -"([#800](https://github.com/adap/flower/pull/800))" +"**Update documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" msgstr "" -"**Désactivé l'évaluation finale distribuée** " -"([#800](https://github.com/adap/flower/pull/800))" +"**Mise à jour de la documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" -#: ../../source/ref-changelog.md:822 +#: ../../source/ref-changelog.md:711 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on" -" all connected clients, which is often not required (e.g., when using " -"server-side evaluation). The prior behaviour can be enabled by passing " -"`force_final_distributed_eval=True` to `start_server`." +"One substantial documentation update fixes multiple smaller rendering " +"issues, makes titles more succinct to improve navigation, removes a " +"deprecated library, updates documentation dependencies, includes the " +"`flwr.common` module in the API reference, includes support for markdown-" +"based documentation, migrates the changelog from `.rst` to `.md`, and " +"fixes a number of smaller details!" msgstr "" -"Le comportement précédent consistait à effectuer un dernier tour " -"d'évaluation distribuée sur tous les clients connectés, ce qui n'est " -"souvent pas nécessaire (par exemple, lors de l'utilisation de " -"l'évaluation côté serveur). Le comportement précédent peut être activé en" -" passant `force_final_distributed_eval=True` à `start_server`." +"Une mise à jour substantielle de la documentation corrige plusieurs " +"petits problèmes de rendu, rend les titres plus succincts pour améliorer " +"la navigation, supprime une bibliothèque obsolète, met à jour les " +"dépendances de la documentation, inclut le module `flwr.common` dans la " +"référence de l'API, inclut le support de la documentation basée sur le " +"markdown, migre le changelog de `.rst` vers `.md`, et corrige un certain " +"nombre de détails plus petits !" + +#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 +#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +msgid "**Minor updates**" +msgstr "**Mises à jour mineures**" -#: ../../source/ref-changelog.md:824 +#: ../../source/ref-changelog.md:715 msgid "" -"**Renamed q-FedAvg strategy** " -"([#802](https://github.com/adap/flower/pull/802))" +"Add round number to fit and evaluate log messages " +"([#1266](https://github.com/adap/flower/pull/1266))" msgstr "" -"**Renommé stratégie q-FedAvg** " -"([#802](https://github.com/adap/flower/pull/802))" +"Ajoute un chiffre rond pour ajuster et évaluer les messages du journal " +"([#1266](https://github.com/adap/flower/pull/1266))" -#: ../../source/ref-changelog.md:826 +#: ../../source/ref-changelog.md:716 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " -"the notation given in the original paper (q-FFL is the optimization " -"objective, q-FedAvg is the proposed solver). Note the original (now " -"deprecated) `QffedAvg` class is still available for compatibility reasons" -" (it will be removed in a future release)." +"Add secure gRPC connection to the `advanced_tensorflow` code example " +"([#847](https://github.com/adap/flower/pull/847))" msgstr "" -"La stratégie nommée `QffedAvg` a été renommée en `QFedAvg` pour mieux " -"refléter la notation donnée dans l'article original (q-FFL est l'objectif" -" d'optimisation, q-FedAvg est le solveur proposé). Notez que la classe " -"`QffedAvg` originale (maintenant obsolète) est toujours disponible pour " -"des raisons de compatibilité (elle sera supprimée dans une prochaine " -"version)." +"Ajouter une connexion gRPC sécurisée à l'exemple de code " +"`advanced_tensorflow` ([#847](https://github.com/adap/flower/pull/847))" -#: ../../source/ref-changelog.md:828 +#: ../../source/ref-changelog.md:717 msgid "" -"**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"Update developer tooling " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" msgstr "" -"**Exemple de code déprécié et renommé** `simulation_pytorch` **en** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:830 +#: ../../source/ref-changelog.md:718 msgid "" -"This example has been replaced by a new example. The new example is based" -" on the experimental virtual client engine, which will become the new " -"default way of doing most types of large-scale simulations in Flower. The" -" existing example was kept for reference purposes, but it might be " -"removed in the future." -msgstr "" -"Cet exemple a été remplacé par un nouvel exemple. Le nouvel exemple est " -"basé sur le moteur expérimental du client virtuel, qui deviendra la " -"nouvelle méthode par défaut pour effectuer la plupart des types de " -"simulations à grande échelle dans Flower. L'exemple existant a été " -"conservé à des fins de référence, mais il pourrait être supprimé à " -"l'avenir." +"Rename ProtoBuf messages to improve consistency " +"([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" +msgstr "" +"Renomme les messages ProtoBuf pour améliorer la cohérence " +"([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:832 -msgid "v0.16.0 (2021-05-11)" -msgstr "v0.16.0 (2021-05-11)" +#: ../../source/ref-changelog.md:720 +msgid "v0.19.0 (2022-05-18)" +msgstr "v0.19.0 (2022-05-18)" -#: ../../source/ref-changelog.md:836 +#: ../../source/ref-changelog.md:724 msgid "" -"**New built-in strategies** " -"([#549](https://github.com/adap/flower/pull/549))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" msgstr "" -"**Nouvelles stratégies intégrées** " -"([#549](https://github.com/adap/flower/pull/549))" - -#: ../../source/ref-changelog.md:838 -msgid "(abstract) FedOpt" -msgstr "(résumé) FedOpt" +"**Flower Baselines (preview) : FedOpt, FedBN, FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:726 +#, fuzzy msgid "" -"**Custom metrics for server and strategies** " -"([#717](https://github.com/adap/flower/pull/717))" +"The first preview release of Flower Baselines has arrived! We're " +"kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " +"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " +"With this first preview release we're also inviting the community to " +"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" +"contribute-baselines.html)." msgstr "" -"**Métriques personnalisées pour le serveur et les stratégies** " -"([#717](https://github.com/adap/flower/pull/717))" +"La première version préliminaire de Flower Baselines est arrivée ! Nous " +"démarrons Flower Baselines avec des implémentations de FedOpt (FedYogi, " +"FedAdam, FedAdagrad), FedBN, et FedAvgM. Consultez la documentation sur " +"l'utilisation de [Flower Baselines](https://flower.ai/docs/using-" +"baselines.html). Avec cette première version préliminaire, nous invitons " +"également la communauté à [contribuer à leurs propres lignes de " +"base](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)." -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:728 msgid "" -"The Flower server is now fully task-agnostic, all remaining instances of " -"task-specific metrics (such as `accuracy`) have been replaced by custom " -"metrics dictionaries. Flower 0.15 introduced the capability to pass a " -"dictionary containing custom metrics from client to server. As of this " -"release, custom metrics replace task-specific metrics on the server." +"**C++ client SDK (preview) and code example** " +"([#1111](https://github.com/adap/flower/pull/1111))" msgstr "" -"Le serveur Flower est maintenant totalement agnostique, toutes les " -"instances restantes de métriques spécifiques à une tâche (telles que " -"`accuracy`) ont été remplacées par des dictionnaires de métriques " -"personnalisées. Flower 0.15 a introduit la possibilité de passer un " -"dictionnaire contenant des métriques personnalisées du client au serveur." -" À partir de cette version, les métriques personnalisées remplacent les " -"métriques spécifiques à une tâche sur le serveur." +"**SDK client C++ (aperçu) et exemple de code** " +"([#1111](https://github.com/adap/flower/pull/1111))" -#: ../../source/ref-changelog.md:845 -#, fuzzy +#: ../../source/ref-changelog.md:730 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are" -" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " -"they enable evaluation functions passed to built-in strategies (via " -"`eval_fn`) to return more than two evaluation metrics. Strategies can " -"even return *aggregated* metrics dictionaries for the server to keep " -"track of." +"Preview support for Flower clients written in C++. The C++ preview " +"includes a Flower client SDK and a quickstart code example that " +"demonstrates a simple C++ client using the SDK." msgstr "" -"Les dictionnaires de métriques personnalisés sont maintenant utilisés " -"dans deux API orientées vers l'utilisateur : ils sont renvoyés par les " -"méthodes de stratégie `aggregate_fit`/`aggregate_evaluate` et ils " -"permettent aux fonctions d'évaluation passées aux stratégies intégrées " -"(via `eval_fn`) de renvoyer plus de deux métriques d'évaluation. Les " -"stratégies peuvent même renvoyer des dictionnaires de métriques " -"*agrégées* pour que le serveur puisse en garder la trace." +"L'aperçu C++ comprend un SDK pour les clients Flower et un exemple de " +"code de démarrage rapide qui démontre un client C++ simple utilisant le " +"SDK." -#: ../../source/ref-changelog.md:847 -#, fuzzy +#: ../../source/ref-changelog.md:732 msgid "" -"Strategy implementations should migrate their `aggregate_fit` and " -"`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate" -" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"**Add experimental support for Python 3.10 and Python 3.11** " +"([#1135](https://github.com/adap/flower/pull/1135))" msgstr "" -"Les implémentations de Stratey doivent migrer leurs méthodes " -"`aggregate_fit` et `aggregate_evaluate` vers le nouveau type de retour " -"(par exemple, en renvoyant simplement un `{}` vide), les fonctions " -"d'évaluation côté serveur doivent migrer de `return loss, accuracy` à " -"`return loss, {\"accuracy\" : accuracy}`." +"**Ajouter la prise en charge expérimentale de Python 3.10 et Python " +"3.11** ([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:734 msgid "" -"Flower 0.15-style return types are deprecated (but still supported), " -"compatibility will be removed in a future release." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due" +" to be released in October. This Flower release adds experimental support" +" for both Python versions." msgstr "" -"Les types de retour du style Flower 0.15 sont dépréciés (mais toujours " -"pris en charge), la compatibilité sera supprimée dans une prochaine " -"version." +"Python 3.10 est la dernière version stable de Python et Python 3.11 " +"devrait sortir en octobre. Cette version de Flower ajoute une prise en " +"charge expérimentale pour les deux versions de Python." -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:736 msgid "" -"**Migration warnings for deprecated functionality** " -"([#690](https://github.com/adap/flower/pull/690))" +"**Aggregate custom metrics through user-provided functions** " +"([#1144](https://github.com/adap/flower/pull/1144))" msgstr "" -"**Avertissements de migration pour les fonctionnalités obsolètes** " -"([#690](https://github.com/adap/flower/pull/690))" +"**Agréger des mesures personnalisées grâce à des fonctions fournies par " +"l'utilisateur** ([#1144](https://github.com/adap/flower/pull/1144))" -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:738 msgid "" -"Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces " -"detailed warning messages if usage of deprecated APIs is detected. The " -"new warning messages often provide details on how to migrate to more " -"recent APIs, thus easing the transition from one release to another." +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" +" customize the strategy. Built-in strategies support two new arguments, " +"`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " +"allow passing custom metric aggregation functions." msgstr "" -"Les versions antérieures de Flower ont souvent été migrées vers de " -"nouvelles API, tout en maintenant la compatibilité avec les anciennes " -"API. Cette version introduit des messages d'avertissement détaillés si " -"l'utilisation d'API obsolètes est détectée. Les nouveaux messages " -"d'avertissement fournissent souvent des détails sur la façon de migrer " -"vers des API plus récentes, facilitant ainsi la transition d'une version " -"à l'autre." +"Les stratégies intégrées prennent en charge deux nouveaux arguments, " +"`fit_metrics_aggregation_fn` et `evaluate_metrics_aggregation_fn`, qui " +"permettent de passer des fonctions d'agrégation de métriques " +"personnalisées." -#: ../../source/ref-changelog.md:855 +#: ../../source/ref-changelog.md:740 msgid "" -"Improved docs and docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +"**User-configurable round timeout** " +"([#1162](https://github.com/adap/flower/pull/1162))" msgstr "" -"Amélioration des docs et des docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" - -#: ../../source/ref-changelog.md:857 -msgid "MXNet example and documentation" -msgstr "Exemple et documentation MXNet" +"**Temps d'attente configurable par l'utilisateur** " +"([#1162](https://github.com/adap/flower/pull/1162))" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:742 msgid "" -"FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"A new configuration value allows the round timeout to be set for " +"`start_server` and `start_simulation`. If the `config` dictionary " +"contains a `round_timeout` key (with a `float` value in seconds), the " +"server will wait *at least* `round_timeout` seconds before it closes the " +"connection." msgstr "" -"Mise en œuvre de FedBN dans l'exemple PyTorch : De la centralisation à la" -" fédération ([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"Si le dictionnaire `config` contient une clé `round_timeout` (avec une " +"valeur `float` en secondes), le serveur attendra *au moins* " +"`round_timeout` secondes avant de fermer la connexion." -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:744 msgid "" -"**Serialization-agnostic server** " -"([#721](https://github.com/adap/flower/pull/721))" +"**Enable both federated evaluation and centralized evaluation to be used " +"at the same time in all built-in strategies** " +"([#1091](https://github.com/adap/flower/pull/1091))" msgstr "" -"**Serveur agnostique de sérialisation** " -"([#721](https://github.com/adap/flower/pull/721))" +"**Permettre l'utilisation simultanée de l'évaluation fédérée et de " +"l'évaluation centralisée dans toutes les stratégies intégrées** " +"([#1091](https://github.com/adap/flower/pull/1091))" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:746 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of " -"class `Weights` (which represents parameters as deserialized NumPy " -"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " -"`Parameters` objects are fully serialization-agnostic and represents " -"parameters as byte arrays, the `tensor_type` attributes indicates how " -"these byte arrays should be interpreted (e.g., for " -"serialization/deserialization)." +"Built-in strategies can now perform both federated evaluation (i.e., " +"client-side) and centralized evaluation (i.e., server-side) in the same " +"round. Federated evaluation can be disabled by setting `fraction_eval` to" +" `0.0`." msgstr "" -"Le serveur Flower est désormais totalement agnostique en matière de " -"sérialisation. L'utilisation antérieure de la classe `Weights` (qui " -"représente les paramètres sous forme de tableaux NumPy désérialisés) a " -"été remplacée par la classe `Parameters` (par exemple, dans `Strategy`). " -"Les objets `Parameters` sont totalement agnostiques en matière de " -"sérialisation et représentent les paramètres sous forme de tableaux " -"d'octets, les attributs `tensor_type` indiquent comment ces tableaux " -"d'octets doivent être interprétés (par exemple, pour la " -"sérialisation/désérialisation)." +"Les stratégies intégrées peuvent maintenant effectuer une évaluation " +"fédérée (c'est-à-dire côté client) et une évaluation centralisée " +"(c'est-à-dire côté serveur) dans le même tour. L'évaluation fédérée peut " +"être désactivée en réglant `fraction_eval` sur `0.0`." -#: ../../source/ref-changelog.md:867 +#: ../../source/ref-changelog.md:748 msgid "" -"Built-in strategies implement this approach by handling serialization and" -" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " -"implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR " -"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" -" easily migrate to the new format." +"**Two new Jupyter Notebook tutorials** " +"([#1141](https://github.com/adap/flower/pull/1141))" msgstr "" -"Les stratégies intégrées mettent en œuvre cette approche en gérant en " -"interne la sérialisation et la désérialisation de `Weights`. Les " -"implémentations de stratégies personnalisées ou tierces doivent être " -"mises à jour avec les définitions de méthodes de stratégie légèrement " -"modifiées. Les auteurs de stratégies peuvent consulter le PR " -"[#721](https://github.com/adap/flower/pull/721) pour voir comment les " -"stratégies peuvent facilement migrer vers le nouveau format." +"**Deux nouveaux tutoriels Jupyter Notebook** " +"([#1141](https://github.com/adap/flower/pull/1141))" -#: ../../source/ref-changelog.md:869 +#: ../../source/ref-changelog.md:750 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use " -"`flwr.server.Server.evaluate_round` instead " -"([#717](https://github.com/adap/flower/pull/717))" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " +"basic and intermediate Flower features:" msgstr "" -"Déclassé `flwr.server.Server.evaluate`, utiliser " -"`flwr.server.Server.evaluate_round` à la place " -"([#717](https://github.com/adap/flower/pull/717))" - -#: ../../source/ref-changelog.md:871 -msgid "v0.15.0 (2021-03-12)" -msgstr "v0.15.0 (2021-03-12)" +"Deux tutoriels Jupyter Notebook (compatibles avec Google Colab) " +"expliquent les fonctionnalités de base et intermédiaires de Flower :" -#: ../../source/ref-changelog.md:875 +#: ../../source/ref-changelog.md:752 msgid "" -"**Server-side parameter initialization** " -"([#658](https://github.com/adap/flower/pull/658))" +"*An Introduction to Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" msgstr "" -"**Initialisation des paramètres côté serveur** " -"([#658](https://github.com/adap/flower/pull/658))" +"*Introduction à l'apprentissage fédéré* : [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:877 +#: ../../source/ref-changelog.md:754 msgid "" -"Model parameters can now be initialized on the server-side. Server-side " -"parameter initialization works via a new `Strategy` method called " -"`initialize_parameters`." +"*Using Strategies in Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" msgstr "" -"Les paramètres du modèle peuvent maintenant être initialisés côté " -"serveur. L'initialisation des paramètres côté serveur fonctionne via une " -"nouvelle méthode `Strategy` appelée `initialize_parameters`." +"*Utiliser des stratégies dans l'apprentissage fédéré* : [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:756 msgid "" -"Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies " -"will provide these initial parameters to the server on startup and then " -"delete them to free the memory afterwards." +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " +"([#1076](https://github.com/adap/flower/pull/1076))" msgstr "" -"Les stratégies intégrées prennent en charge un nouvel argument du " -"constructeur appelé `initial_parameters` pour définir les paramètres " -"initiaux. Les stratégies intégrées fourniront ces paramètres initiaux au " -"serveur au démarrage et les supprimeront ensuite pour libérer la mémoire." +"**Nouvelle stratégie FedAvgM (Federated Averaging with Server Momentum)**" +" ([#1076](https://github.com/adap/flower/pull/1076))" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:758 +#, fuzzy msgid "" -"If no initial parameters are provided to the strategy, the server will " -"continue to use the current behaviour (namely, it will ask one of the " -"connected clients for its parameters and use these as the initial global " -"parameters)." +"The new `FedAvgM` strategy implements Federated Averaging with Server " +"Momentum \\[Hsu et al., 2019\\]." msgstr "" -"Si aucun paramètre initial n'est fourni à la stratégie, le serveur " -"continuera à utiliser le comportement actuel (à savoir qu'il demandera à " -"l'un des clients connectés ses paramètres et les utilisera comme " -"paramètres globaux initiaux)." - -#: ../../source/ref-changelog.md:900 -msgid "Deprecations" -msgstr "Dépréciations" +"La nouvelle stratégie `FedAvgM` met en œuvre la moyenne fédérée avec le " +"momentum du serveur [Hsu et al., 2019]." -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:760 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " -"`flwr.server.strategy.FedAvg`, which is equivalent)" +"**New advanced PyTorch code example** " +"([#1007](https://github.com/adap/flower/pull/1007))" msgstr "" -"Déclasser `flwr.server.strategy.DefaultStrategy` (migrer vers " -"`flwr.server.strategy.FedAvg`, qui est équivalent)" - -#: ../../source/ref-changelog.md:904 -msgid "v0.14.0 (2021-02-18)" -msgstr "v0.14.0 (2021-02-18)" +"**Nouvel exemple de code PyTorch avancé** " +"([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:908 +#: ../../source/ref-changelog.md:762 msgid "" -"**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"A new code example (`advanced_pytorch`) demonstrates advanced Flower " +"concepts with PyTorch." msgstr "" -"**Généralisé** `Client.fit` **et** `Client.evaluate` **valeurs de " -"retour** ([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"Un nouvel exemple de code (`advanced_pytorch`) démontre des concepts de " +"fleur avancés avec PyTorch." -#: ../../source/ref-changelog.md:910 +#: ../../source/ref-changelog.md:764 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to " -"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " -"This means one can return almost arbitrary values from `fit`/`evaluate` " -"and make use of them on the server side!" +"**New JAX code example** " +"([#906](https://github.com/adap/flower/pull/906), " +"[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" -"Les clients peuvent maintenant renvoyer un dictionnaire supplémentaire " -"associant les clés `str` aux valeurs des types suivants : `bool`, " -"`bytes`, `float`, `int`, `str`. Cela signifie que l'on peut renvoyer des " -"valeurs presque arbitraires de `fit`/`evaluate` et les utiliser du côté " -"du serveur !" +"**Nouvel exemple de code JAX** " +"([#906](https://github.com/adap/flower/pull/906), " +"[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:912 +#: ../../source/ref-changelog.md:766 msgid "" -"This improvement also allowed for more consistent return types between " -"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " -"dict)` representing the loss, number of examples, and a dictionary " -"holding arbitrary problem-specific values like accuracy." +"A new code example (`jax_from_centralized_to_federated`) shows federated " +"learning with JAX and Flower." msgstr "" -"Cette amélioration a également permis de rendre plus cohérents les types " -"de retour entre `fit` et `evaluate` : `evaluate` devrait maintenant " -"retourner un tuple `(float, int, dict)` représentant la perte, le nombre " -"d'exemples, et un dictionnaire contenant des valeurs arbitraires " -"spécifiques au problème comme la précision." +"Un nouvel exemple de code (`jax_from_centralized_to_federated`) montre " +"l'apprentissage fédéré avec JAX et Flower." -#: ../../source/ref-changelog.md:914 +#: ../../source/ref-changelog.md:770 msgid "" -"In case you wondered: this feature is compatible with existing projects, " -"the additional dictionary return value is optional. New code should " -"however migrate to the new return types to be compatible with upcoming " -"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " -"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " -"details." +"New option to keep Ray running if Ray was already initialized in " +"`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -"Au cas où tu te poserais la question : cette fonctionnalité est " -"compatible avec les projets existants, la valeur de retour supplémentaire" -" du dictionnaire est facultative. Le nouveau code doit cependant migrer " -"vers les nouveaux types de retour pour être compatible avec les " -"prochaines versions de Flower (`fit` : `List[np.ndarray], int, Dict[str, " -"Scalar]`, `evaluate` : `float, int, Dict[str, Scalar]`). Voir l'exemple " -"ci-dessous pour plus de détails." +"Nouvelle option pour continuer à faire fonctionner Ray si Ray a déjà été " +"initialisé dans `start_simulation` " +"([#1177](https://github.com/adap/flower/pull/1177))" -#: ../../source/ref-changelog.md:916 +#: ../../source/ref-changelog.md:771 msgid "" -"*Code example:* note the additional dictionary return values in both " -"`FlwrClient.fit` and `FlwrClient.evaluate`:" +"Add support for custom `ClientManager` as a `start_simulation` parameter " +"([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -"*Exemple de code:* note les valeurs de retour du dictionnaire " -"supplémentaires dans `FlwrClient.fit` et `FlwrClient.evaluate` :" +"Ajout de la prise en charge d'un `ClientManager` personnalisé comme " +"paramètre de `start_simulation` " +"([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:772 +#, fuzzy msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"New documentation for [implementing " +"strategies](https://flower.ai/docs/framework/how-to-implement-" +"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -"**Généralisé** `config` **argument dans** `Client.fit` **et** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"Nouvelle documentation pour [mettre en œuvre des " +"stratégies](https://flower.ai/docs/framework/how-to-implement-" +"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175))" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:773 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means " -"that dictionary values were expected to be strings. The new release " -"generalizes this to enable values of the following types: `bool`, " -"`bytes`, `float`, `int`, `str`." +"New mobile-friendly documentation theme " +"([#1174](https://github.com/adap/flower/pull/1174))" msgstr "" -"L'argument `config` était auparavant de type `Dict[str, str]`, ce qui " -"signifie que les valeurs du dictionnaire devaient être des chaînes. La " -"nouvelle version généralise cela pour permettre les valeurs des types " -"suivants : `bool`, `bytes`, `float`, `int`, `str`." +"Nouveau thème de documentation adapté aux mobiles " +"([#1174](https://github.com/adap/flower/pull/1174))" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:774 msgid "" -"This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" -"side and `int(config[\"epochs\"])` on the client side!" +"Limit version range for (optional) `ray` dependency to include only " +"compatible releases (`>=1.9.2,<1.12.0`) " +"([#1205](https://github.com/adap/flower/pull/1205))" msgstr "" -"Cela signifie que l'on peut maintenant passer des valeurs presque " -"arbitraires à `fit`/`evaluate` en utilisant le dictionnaire `config`. " -"Yay, plus de `str(epochs)` du côté serveur et `int(config[\"epochs\"])` " -"du côté client !" +"Limite la plage de versions pour la dépendance (optionnelle) `ray` pour " +"n'inclure que les versions compatibles (`>=1.9.2,<1.12.0`) " +"([#1205](https://github.com/adap/flower/pull/1205))" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:778 msgid "" -"*Code example:* note that the `config` dictionary now contains non-`str` " -"values in both `Client.fit` and `Client.evaluate`:" +"**Remove deprecated support for Python 3.6** " +"([#871](https://github.com/adap/flower/pull/871))" msgstr "" -"*Exemple de code:* Notez que le dictionnaire `config` contient maintenant" -" des valeurs autres que `str` dans `Client.fit` et `Client.evaluate` :" - -#: ../../source/ref-changelog.md:954 -msgid "v0.13.0 (2021-01-08)" -msgstr "v0.13.0 (2021-01-08)" +"**Supprime la prise en charge obsolète de Python 3.6** " +"([#871](https://github.com/adap/flower/pull/871))" -#: ../../source/ref-changelog.md:958 +#: ../../source/ref-changelog.md:779 msgid "" -"New example: PyTorch From Centralized To Federated " -"([#549](https://github.com/adap/flower/pull/549))" -msgstr "" -"Nouvel exemple : PyTorch de centralisé à fédéré " -"([#549](https://github.com/adap/flower/pull/549))" - -#: ../../source/ref-changelog.md:959 -msgid "Improved documentation" -msgstr "Amélioration de la documentation" - -#: ../../source/ref-changelog.md:960 -msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +"**Remove deprecated KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" msgstr "" -"Nouveau thème de documentation " -"([#551](https://github.com/adap/flower/pull/551))" - -#: ../../source/ref-changelog.md:961 -msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" -msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" +"**Supprimez KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:962 +#: ../../source/ref-changelog.md:780 msgid "" -"Updated examples documentation " -"([#549](https://github.com/adap/flower/pull/549))" +"**Remove deprecated no-op extra installs** " +"([#973](https://github.com/adap/flower/pull/973))" msgstr "" -"Mise à jour de la documentation des exemples " -"([#549](https://github.com/adap/flower/pull/549))" +"**Supprimer les installations supplémentaires no-op dépréciées** " +"([#973](https://github.com/adap/flower/pull/973))" -#: ../../source/ref-changelog.md:963 +#: ../../source/ref-changelog.md:781 msgid "" -"Removed obsolete documentation " -"([#548](https://github.com/adap/flower/pull/548))" +"**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " +"([#869](https://github.com/adap/flower/pull/869))" msgstr "" -"Suppression de la documentation obsolète " -"([#548](https://github.com/adap/flower/pull/548))" - -#: ../../source/ref-changelog.md:965 -msgid "Bugfix:" -msgstr "Correction de bogues :" +"**Supprimez les champs proto obsolètes de** `FitRes` **et** `EvaluateRes`" +" ([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:967 +#: ../../source/ref-changelog.md:782 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the" -" clients is now handled in `flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " +"([#1107](https://github.com/adap/flower/pull/1107))" msgstr "" -"`Server.fit` ne déconnecte pas les clients lorsqu'il est terminé, la " -"déconnexion des clients est maintenant gérée dans " -"`flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." - -#: ../../source/ref-changelog.md:969 -msgid "v0.12.0 (2020-12-07)" -msgstr "v0.12.0 (2020-12-07)" - -#: ../../source/ref-changelog.md:971 ../../source/ref-changelog.md:987 -msgid "Important changes:" -msgstr "Changements importants :" +"**Supprime la stratégie QffedAvg (remplacée par QFedAvg)** " +"([#1107](https://github.com/adap/flower/pull/1107))" -#: ../../source/ref-changelog.md:973 +#: ../../source/ref-changelog.md:783 msgid "" -"Added an example for embedded devices " -"([#507](https://github.com/adap/flower/pull/507))" +"**Remove deprecated DefaultStrategy strategy** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"Ajout d'un exemple pour les périphériques embarqués " -"([#507](https://github.com/adap/flower/pull/507))" +"**Supprime la stratégie DefaultStrategy qui est obsolète** " +"([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:784 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +"**Remove deprecated support for eval_fn accuracy return value** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"Ajout d'un nouveau NumPyClient (en plus du KerasClient existant) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +"**Supprimer la prise en charge obsolète de la valeur de retour de la " +"précision eval_fn** ([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:975 +#: ../../source/ref-changelog.md:785 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into " -"the top-level `examples` directory " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +"**Remove deprecated support for passing initial parameters as NumPy " +"ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"Déclassement du paquet `flwr_example` et migration des exemples dans le " -"répertoire de premier niveau `examples` " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" - -#: ../../source/ref-changelog.md:977 -msgid "v0.11.0 (2020-11-30)" -msgstr "v0.11.0 (2020-11-30)" +"**Supprime la prise en charge obsolète du passage des paramètres initiaux" +" en tant que ndarrays NumPy** " +"([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:979 -msgid "Incompatible changes:" -msgstr "Changements incompatibles :" +#: ../../source/ref-changelog.md:787 +msgid "v0.18.0 (2022-02-28)" +msgstr "v0.18.0 (2022-02-28)" -#: ../../source/ref-changelog.md:981 +#: ../../source/ref-changelog.md:791 msgid "" -"Renamed strategy methods " -"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " -"Flower's public APIs. Other public methods/functions (e.g., every method " -"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " -"which is why we're removing it from the four methods in Strategy. To " -"migrate rename the following `Strategy` methods accordingly:" +"**Improved Virtual Client Engine compatibility with Jupyter Notebook / " +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -"Renommé les méthodes de stratégie " -"([#486](https://github.com/adap/flower/pull/486)) pour unifier le nommage" -" des API publiques de Flower. D'autres méthodes/fonctions publiques (par " -"exemple, toutes les méthodes de `Client`, mais aussi `Strategy.evaluate`)" -" n'utilisent pas le préfixe `on_`, c'est pourquoi nous le supprimons des " -"quatre méthodes de Stratégie. Pour migrer, renommez les méthodes de " -"`Strategy` suivantes en conséquence :" - -#: ../../source/ref-changelog.md:982 -msgid "`on_configure_evaluate` => `configure_evaluate`" -msgstr "`on_configure_evaluate` => `configure_evaluate`" - -#: ../../source/ref-changelog.md:983 -msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" -msgstr "`on_aggregate_evaluate` => `aggregate_evaluate`" - -#: ../../source/ref-changelog.md:984 -msgid "`on_configure_fit` => `configure_fit`" -msgstr "`on_configure_fit` => `configure_fit`" - -#: ../../source/ref-changelog.md:985 -msgid "`on_aggregate_fit` => `aggregate_fit`" -msgstr "`on_aggregate_fit` => `aggregate_fit`" +"**Amélioration de la compatibilité du moteur de client virtuel avec " +"Jupyter Notebook / Google Colab** " +"([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" -#: ../../source/ref-changelog.md:989 +#: ../../source/ref-changelog.md:793 msgid "" -"Deprecated `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). To migrate use " -"`FedAvg` instead." +"Simulations (using the Virtual Client Engine through `start_simulation`) " +"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"installing Flower with the `simulation` extra (`pip install " +"flwr[simulation]`)." msgstr "" -"Déclassé `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). Pour migrer, utilisez " -"`FedAvg` à la place." +"Les simulations (utilisant le moteur de client virtuel via " +"`start_simulation`) fonctionnent maintenant plus facilement sur les " +"Notebooks Jupyter (y compris Google Colab) après avoir installé Flower " +"avec l'option `simulation` (`pip install flwr[simulation]`)." -#: ../../source/ref-changelog.md:990 +#: ../../source/ref-changelog.md:795 msgid "" -"Simplified examples and baselines " -"([#484](https://github.com/adap/flower/pull/484))." +"**New Jupyter Notebook code example** " +"([#833](https://github.com/adap/flower/pull/833))" msgstr "" -"Exemples simplifiés et lignes de base " -"([#484](https://github.com/adap/flower/pull/484))." +"**Nouvel exemple de code Jupyter Notebook** " +"([#833](https://github.com/adap/flower/pull/833))" -#: ../../source/ref-changelog.md:991 +#: ../../source/ref-changelog.md:797 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface " -"([#483](https://github.com/adap/flower/pull/483))." +"A new code example (`quickstart_simulation`) demonstrates Flower " +"simulations using the Virtual Client Engine through Jupyter Notebook " +"(incl. Google Colab)." msgstr "" -"Suppression de `on_conclude_round` actuellement inutilisé de l'interface " -"de stratégie ([#483](https://github.com/adap/flower/pull/483))." +"Un nouvel exemple de code (`quickstart_simulation`) démontre des " +"simulations de Flower en utilisant le moteur de client virtuel via " +"Jupyter Notebook (y compris Google Colab)." -#: ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:799 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"**Client properties (feature preview)** " +"([#795](https://github.com/adap/flower/pull/795))" msgstr "" -"Fixe la version minimale de Python à 3.6.1 au lieu de 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"**Propriétés du client (aperçu des fonctionnalités)** " +"([#795](https://github.com/adap/flower/pull/795))" -#: ../../source/ref-changelog.md:993 +#: ../../source/ref-changelog.md:801 msgid "" -"Improved `Strategy` docstrings " -"([#470](https://github.com/adap/flower/pull/470))." +"Clients can implement a new method `get_properties` to enable server-side" +" strategies to query client properties." msgstr "" -"Amélioration des docstrings `Stratégie` " -"([#470](https://github.com/adap/flower/pull/470))." - -#: ../../source/ref-example-projects.rst:2 -#, fuzzy -msgid "Example projects" -msgstr "Exemples de PyTorch" +"Les clients peuvent implémenter une nouvelle méthode `get_properties` " +"pour permettre aux stratégies côté serveur d'interroger les propriétés du" +" client." -#: ../../source/ref-example-projects.rst:4 +#: ../../source/ref-changelog.md:803 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate " -"how Flower can be used to federate different kinds of existing machine " -"learning pipelines, usually leveraging popular machine learning " -"frameworks such as `PyTorch `_ or `TensorFlow " -"`_." +"**Experimental Android support with TFLite** " +"([#865](https://github.com/adap/flower/pull/865))" msgstr "" -"Flower est livré avec un certain nombre d'exemples d'utilisation, qui " -"montrent comment Flower peut être utilisé pour fédérer différents types " -"de pipelines d'apprentissage automatique existants, qui s'appuient " -"généralement sur des frameworks d'apprentissage automatique populaires " -"tels que `PyTorch `_ ou `TensorFlow " -"`_." +"**Support expérimental d'Android avec TFLite** " +"([#865](https://github.com/adap/flower/pull/865))" -#: ../../source/ref-example-projects.rst:10 -#, fuzzy +#: ../../source/ref-changelog.md:805 msgid "" -"The following examples are available as standalone projects. Quickstart " -"TensorFlow/Keras ---------------------------" -msgstr "Les exemples suivants sont disponibles sous forme de projets autonomes." +"Android support has finally arrived in `main`! Flower is both client-" +"agnostic and framework-agnostic by design. One can integrate arbitrary " +"client platforms and with this release, using Flower on Android has " +"become a lot easier." +msgstr "" +"La prise en charge d'Android est enfin arrivée dans `main` ! Flower est à" +" la fois agnostique au niveau du client et du cadre de travail. On peut " +"intégrer des plates-formes client arbitraires et avec cette version, " +"l'utilisation de Flower sur Android est devenue beaucoup plus facile." -#: ../../source/ref-example-projects.rst:14 +#: ../../source/ref-changelog.md:807 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image " -"classification with MobileNetV2:" +"The example uses TFLite on the client side, along with a new " +"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " +"still experimental, but they are a first step towards a fully-fledged " +"Android SDK and a unified `FedAvg` implementation that integrated the new" +" functionality from `FedAvgAndroid`." msgstr "" -"L'exemple de démarrage rapide TensorFlow/Keras montre la classification " -"d'images CIFAR-10 avec MobileNetV2 :" +"L'exemple utilise TFLite du côté client, ainsi qu'une nouvelle stratégie " +"`FedAvgAndroid`. Le client Android et `FedAvgAndroid` sont encore " +"expérimentaux, mais ils constituent un premier pas vers un SDK Android à " +"part entière et une implémentation unifiée de `FedAvg` intégrant la " +"nouvelle fonctionnalité de `FedAvgAndroid`." -#: ../../source/ref-example-projects.rst:17 -#, fuzzy +#: ../../source/ref-changelog.md:809 msgid "" -"`Quickstart TensorFlow (Code) " -"`_" +"**Make gRPC keepalive time user-configurable and decrease default " +"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -"`Quickstart TensorFlow (Code) " -"`_" +"**Rendre le temps de garde gRPC configurable par l'utilisateur et " +"diminuer le temps de garde par défaut** " +"([#1069](https://github.com/adap/flower/pull/1069))" -#: ../../source/ref-example-projects.rst:18 -#, fuzzy -msgid ":doc:`Quickstart TensorFlow (Tutorial) `" +#: ../../source/ref-changelog.md:811 +msgid "" +"The default gRPC keepalive time has been reduced to increase the " +"compatibility of Flower with more cloud environments (for example, " +"Microsoft Azure). Users can configure the keepalive time to customize the" +" gRPC stack based on specific requirements." msgstr "" -"`Quickstart TensorFlow (Tutorial) `_" +"Le temps de keepalive gRPC par défaut a été réduit pour augmenter la " +"compatibilité de Flower avec davantage d'environnements cloud (par " +"exemple, Microsoft Azure). Les utilisateurs peuvent configurer le temps " +"de keepalive pour personnaliser la pile gRPC en fonction d'exigences " +"spécifiques." -#: ../../source/ref-example-projects.rst:19 +#: ../../source/ref-changelog.md:813 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"**New differential privacy example using Opacus and PyTorch** " +"([#805](https://github.com/adap/flower/pull/805))" msgstr "" -"`Quickstart TensorFlow (Blog Post) `_" - -#: ../../source/ref-example-projects.rst:23 -#: ../../source/tutorial-quickstart-pytorch.rst:5 -msgid "Quickstart PyTorch" -msgstr "Démarrage rapide de PyTorch" +"**Nouvel exemple de confidentialité différentielle utilisant Opacus et " +"PyTorch** ([#805](https://github.com/adap/flower/pull/805))" -#: ../../source/ref-example-projects.rst:25 +#: ../../source/ref-changelog.md:815 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a" -" simple Convolutional Neural Network:" +"A new code example (`opacus`) demonstrates differentially-private " +"federated learning with Opacus, PyTorch, and Flower." msgstr "" -"L'exemple de démarrage rapide PyTorch montre la classification d'images " -"CIFAR-10 avec un simple réseau neuronal convolutif :" +"Un nouvel exemple de code (`opacus`) démontre l'apprentissage fédéré " +"différentiellement privé avec Opacus, PyTorch et Flower." -#: ../../source/ref-example-projects.rst:28 -#, fuzzy +#: ../../source/ref-changelog.md:817 msgid "" -"`Quickstart PyTorch (Code) " -"`_" +"**New Hugging Face Transformers code example** " +"([#863](https://github.com/adap/flower/pull/863))" msgstr "" -"`Quickstart PyTorch (Code) " -"`_" +"**Nouvel exemple de code pour les Transformers à visage embrassant** " +"([#863](https://github.com/adap/flower/pull/863))" -#: ../../source/ref-example-projects.rst:29 -#, fuzzy -msgid ":doc:`Quickstart PyTorch (Tutorial) `" +#: ../../source/ref-changelog.md:819 +msgid "" +"A new code example (`quickstart_huggingface`) demonstrates usage of " +"Hugging Face Transformers with Flower." msgstr "" -"`Quickstart PyTorch (Tutorial) `_" - -#: ../../source/ref-example-projects.rst:33 -msgid "PyTorch: From Centralized To Federated" -msgstr "PyTorch : De la centralisation à la fédération" +"Un nouvel exemple de code (`quickstart_huggingface`) démontre " +"l'utilisation des transformateurs Hugging Face avec Flower." -#: ../../source/ref-example-projects.rst:35 +#: ../../source/ref-changelog.md:821 msgid "" -"This example shows how a regular PyTorch project can be federated using " -"Flower:" +"**New MLCube code example** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" msgstr "" -"Cet exemple montre comment un projet PyTorch ordinaire peut être fédéré à" -" l'aide de Flower :" +"**Nouvel exemple de code MLCube** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-example-projects.rst:37 -#, fuzzy +#: ../../source/ref-changelog.md:823 msgid "" -"`PyTorch: From Centralized To Federated (Code) " -"`_" +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " +"with Flower." msgstr "" -"`PyTorch : De la centralisation à la fédération (Code) " -"`_" +"Un nouvel exemple de code (`quickstart_mlcube`) démontre l'utilisation de" +" MLCube avec Flower." -#: ../../source/ref-example-projects.rst:38 -#, fuzzy +#: ../../source/ref-changelog.md:825 msgid "" -":doc:`PyTorch: From Centralized To Federated (Tutorial) `" +"**SSL-enabled server and client** " +"([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" msgstr "" -"`PyTorch : De la centralisation à la fédération (Tutoriel) " -"`_" - -#: ../../source/ref-example-projects.rst:42 -msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" -msgstr "Apprentissage fédéré sur Raspberry Pi et Nvidia Jetson" +"**([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-example-projects.rst:44 +#: ../../source/ref-changelog.md:827 msgid "" -"This example shows how Flower can be used to build a federated learning " -"system that run across Raspberry Pi and Nvidia Jetson:" +"SSL enables secure encrypted connections between clients and servers. " +"This release open-sources the Flower secure gRPC implementation to make " +"encrypted communication channels accessible to all Flower users." msgstr "" -"Cet exemple montre comment Flower peut être utilisé pour construire un " -"système d'apprentissage fédéré qui fonctionne sur Raspberry Pi et Nvidia " -"Jetson :" +"SSL permet d'établir des connexions cryptées et sécurisées entre les " +"clients et les serveurs. Cette version met en open-source " +"l'implémentation gRPC sécurisée de Flower afin de rendre les canaux de " +"communication cryptés accessibles à tous les utilisateurs de Flower." -#: ../../source/ref-example-projects.rst:46 -#, fuzzy +#: ../../source/ref-changelog.md:829 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " -"`_" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" msgstr "" -"`L'apprentissage fédéré sur Raspberry Pi et Nvidia Jetson (Code) " -"`_" +"**Mise à jour** `FedAdam` **et** `FedYogi` **stratégies** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" -#: ../../source/ref-example-projects.rst:47 +#: ../../source/ref-changelog.md:831 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " -"`_" +"`FedAdam` and `FedAdam` match the latest version of the Adaptive " +"Federated Optimization paper." msgstr "" -"`L'apprentissage fédéré sur Raspberry Pi et Nvidia Jetson (Blog Post) " -"`_" +"`FedAdam` et `FedAdam` correspondent à la dernière version de l'article " +"sur l'optimisation fédérée adaptative." -#: ../../source/ref-faq.rst:4 +#: ../../source/ref-changelog.md:833 msgid "" -"This page collects answers to commonly asked questions about Federated " -"Learning with Flower." +"**Initialize** `start_simulation` **with a list of client IDs** " +"([#860](https://github.com/adap/flower/pull/860))" msgstr "" -"Cette page rassemble les réponses aux questions les plus fréquemment " -"posées sur l'apprentissage fédéré avec Flower." +"**Initialise** `start_simulation` **avec une liste d'ID de clients** " +"([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-faq.rst -#, fuzzy -msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" +#: ../../source/ref-changelog.md:835 +msgid "" +"`start_simulation` can now be called with a list of client IDs " +"(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " +"`client_fn` whenever a client needs to be initialized, which can make it " +"easier to load data partitions that are not accessible through `int` " +"identifiers." msgstr "" -":fa:`eye,mr-1` Flower peut-il fonctionner sur les ordinateurs portables " -"Juptyter / Google Colab ?" +"`start_simulation` peut maintenant être appelé avec une liste " +"d'identifiants de clients (`clients_ids`, type : `List[str]`). Ces " +"identifiants seront passés à `client_fn` chaque fois qu'un client doit " +"être initialisé, ce qui peut faciliter le chargement de partitions de " +"données qui ne sont pas accessibles par des identifiants `int`." -#: ../../source/ref-faq.rst:8 +#: ../../source/ref-changelog.md:839 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to" -" make it work even better on Colab. Here's a quickstart example:" +"Update `num_examples` calculation in PyTorch code examples in " +"([#909](https://github.com/adap/flower/pull/909))" msgstr "" -"Oui, c'est possible ! Flower est même livré avec quelques optimisations " -"pour qu'il fonctionne encore mieux sur Colab. Voici un exemple de " -"démarrage rapide :" +"Mettre à jour le calcul de `num_examples` dans les exemples de code " +"PyTorch dans ([#909](https://github.com/adap/flower/pull/909))" -#: ../../source/ref-faq.rst:10 -#, fuzzy +#: ../../source/ref-changelog.md:840 msgid "" -"`Flower simulation PyTorch " -"`_" +"Expose Flower version through `flwr.__version__` " +"([#952](https://github.com/adap/flower/pull/952))" msgstr "" -"`Flower Quickstart (TensorFlow/Keras) " -"`_" +"Exposer la version de Flower à travers `flwr.__version__` " +"([#952](https://github.com/adap/flower/pull/952))" -#: ../../source/ref-faq.rst:11 -#, fuzzy +#: ../../source/ref-changelog.md:841 msgid "" -"`Flower simulation TensorFlow/Keras " -"`_" +"`start_server` in `app.py` now returns a `History` object containing " +"metrics from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -"`Flower Quickstart (TensorFlow/Keras) " -"`_" +"`start_server` dans `app.py` renvoie maintenant un objet `History` " +"contenant les métriques de l'entraînement " +"([#974](https://github.com/adap/flower/pull/974))" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" +#: ../../source/ref-changelog.md:842 +msgid "" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " +"([#978](https://github.com/adap/flower/pull/978))" msgstr "" -":fa:`eye,mr-1` Comment puis-je faire fonctionner l'apprentissage fédéré " -"sur un Raspberry Pi ?" +"Rendre `max_workers` (utilisé par `ThreadPoolExecutor`) configurable " +"([#978](https://github.com/adap/flower/pull/978))" -#: ../../source/ref-faq.rst:15 -#, fuzzy +#: ../../source/ref-changelog.md:843 msgid "" -"Find the `blog post about federated learning on embedded device here " -"`_" -" and the corresponding `GitHub code example " -"`_." +"Increase sleep time after server start to three seconds in all code " +"examples ([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" -"Trouve le `blog post about federated learning on embedded device ici " -"`_" -" et l'exemple de code GitHub correspondant " -"`_." +"Augmente le temps de sommeil après le démarrage du serveur à trois " +"secondes dans tous les exemples de code " +"([#1086](https://github.com/adap/flower/pull/1086))" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +#: ../../source/ref-changelog.md:844 +msgid "" +"Added a new FAQ section to the documentation " +"([#948](https://github.com/adap/flower/pull/948))" msgstr "" -":fa:`eye,mr-1` Est-ce que Flower prend en charge l'apprentissage fédéré " -"sur les appareils Android ?" +"Ajout d'une nouvelle section FAQ à la documentation " +"([#948](https://github.com/adap/flower/pull/948))" -#: ../../source/ref-faq.rst:19 -#, fuzzy +#: ../../source/ref-changelog.md:845 msgid "" -"Yes, it does. Please take a look at our `blog post " -"`_ or check out the code examples:" +"And many more under-the-hood changes, library updates, documentation " +"changes, and tooling improvements!" msgstr "" -"Oui. Jetez un coup d'œil à notre `blog post " -"`_ ou consultez l'`exemple de code Android sur GitHub " -"`_." +"Et bien d'autres changements sous le capot, des mises à jour de la " +"bibliothèque, des modifications de la documentation et des améliorations " +"de l'outillage !" -#: ../../source/ref-faq.rst:21 +#: ../../source/ref-changelog.md:849 msgid "" -"`Android Kotlin example `_" +"**Removed** `flwr_example` **and** `flwr_experimental` **from release " +"build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" +"**Supprimé** `flwr_example` **et** `flwr_experimental` **de la version " +"release build** ([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-faq.rst:22 -msgid "`Android Java example `_" +#: ../../source/ref-changelog.md:851 +msgid "" +"The packages `flwr_example` and `flwr_experimental` have been deprecated " +"since Flower 0.12.0 and they are not longer included in Flower release " +"builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " +"an upcoming release." msgstr "" +"Les paquets `flwr_example` et `flwr_experimental` ont été dépréciés " +"depuis Flower 0.12.0 et ils ne sont plus inclus dans les builds de " +"Flower. Les extras associés (`baseline`, `examples-pytorch`, `examples-" +"tensorflow`, `http-logger`, `ops`) sont maintenant no-op et seront " +"supprimés dans une prochaine version." -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Can I combine federated learning with blockchain?" -msgstr "" -":fa:`eye,mr-1` Puis-je combiner l'apprentissage fédéré avec la blockchain" -" ?" +#: ../../source/ref-changelog.md:853 +msgid "v0.17.0 (2021-09-24)" +msgstr "v0.17.0 (2021-09-24)" -#: ../../source/ref-faq.rst:26 +#: ../../source/ref-changelog.md:857 msgid "" -"Yes, of course. A list of available examples using Flower within a " -"blockchain environment is available here:" +"**Experimental virtual client engine** " +"([#781](https://github.com/adap/flower/pull/781) " +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" msgstr "" -"Oui, bien sûr, une liste d'exemples disponibles utilisant Flower dans un " -"environnement blockchain est disponible ici :" +"**Moteur expérimental de client virtuel** " +"([#781](https://github.com/adap/flower/pull/781) " +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-faq.rst:28 +#: ../../source/ref-changelog.md:859 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"One of Flower's goals is to enable research at scale. This release " +"enables a first (experimental) peek at a major new feature, codenamed the" +" virtual client engine. Virtual clients enable simulations that scale to " +"a (very) large number of clients on a single machine or compute cluster. " +"The easiest way to test the new functionality is to look at the two new " +"code examples called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -"`Flower meets Nevermined GitHub Repository `_." +"L'un des objectifs de Flower est de permettre la recherche à grande " +"échelle. Cette version donne un premier aperçu (expérimental) d'une " +"nouvelle fonctionnalité majeure, connue sous le nom de code de moteur de " +"client virtuel. Les clients virtuels permettent des simulations qui " +"s'étendent à un (très) grand nombre de clients sur une seule machine ou " +"une grappe de calcul. La façon la plus simple de tester la nouvelle " +"fonctionnalité est de regarder les deux nouveaux exemples de code appelés" +" `quickstart_simulation` et `simulation_pytorch`." -#: ../../source/ref-faq.rst:29 +#: ../../source/ref-changelog.md:861 msgid "" -"`Flower meets Nevermined YouTube video " -"`_." +"The feature is still experimental, so there's no stability guarantee for " +"the API. It's also not quite ready for prime time and comes with a few " +"known caveats. However, those who are curious are encouraged to try it " +"out and share their thoughts." msgstr "" -"`Flower rencontre Nevermined vidéo YouTube " -"`_." +"La fonction est encore expérimentale, il n'y a donc aucune garantie de " +"stabilité pour l'API. Elle n'est pas non plus tout à fait prête pour le " +"prime time et s'accompagne de quelques mises en garde connues. Cependant," +" les personnes curieuses sont encouragées à l'essayer et à faire part de " +"leurs réflexions." -#: ../../source/ref-faq.rst:30 -#, fuzzy +#: ../../source/ref-changelog.md:863 msgid "" -"`Flower meets KOSMoS `_." +"**New built-in strategies** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" msgstr "" -"`Flower rencontre KOSMoS `_." +"**Nouvelles stratégies intégrées** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-faq.rst:31 +#: ../../source/ref-changelog.md:865 msgid "" -"`Flower meets Talan blog post `_ ." +"FedYogi - Federated learning strategy using Yogi on server-side. " +"Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -"`Flower meets Talan blog post `_ ." +"FedYogi - Stratégie d'apprentissage fédéré utilisant Yogi côté serveur. " +"Mise en oeuvre basée sur https://arxiv.org/abs/2003.00295" -#: ../../source/ref-faq.rst:32 +#: ../../source/ref-changelog.md:866 msgid "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"FedAdam - Federated learning strategy using Adam on server-side. " +"Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -"`Flower rencontre Talan Dépôt GitHub " -"`_ ." - -#: ../../source/ref-telemetry.md:1 -msgid "Telemetry" -msgstr "Télémétrie" +"FedAdam - Stratégie d'apprentissage fédéré utilisant Adam côté serveur. " +"Mise en œuvre basée sur https://arxiv.org/abs/2003.00295" -#: ../../source/ref-telemetry.md:3 +#: ../../source/ref-changelog.md:868 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to " -"make well-informed decisions to improve Flower. Doing this enables the " -"Flower team to understand how Flower is used and what challenges users " -"might face." +"**New PyTorch Lightning code example** " +"([#617](https://github.com/adap/flower/pull/617))" msgstr "" -"Le projet open-source Flower recueille des mesures d'utilisation " -"**anonymes** afin de prendre des décisions éclairées pour améliorer " -"Flower. Cela permet à l'équipe de Flower de comprendre comment Flower est" -" utilisé et quels sont les défis auxquels les utilisateurs peuvent être " -"confrontés." +"**Nouvel exemple de code PyTorch Lightning** " +"([#617](https://github.com/adap/flower/pull/617))" -#: ../../source/ref-telemetry.md:5 +#: ../../source/ref-changelog.md:870 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users that do not want to share anonymous usage metrics." +"**New Variational Auto-Encoder code example** " +"([#752](https://github.com/adap/flower/pull/752))" msgstr "" -"**Flower est un cadre convivial pour l'IA collaborative et la science des" -" données.** En restant fidèle à cette déclaration, Flower permet de " -"désactiver facilement la télémétrie pour les utilisateurs qui ne " -"souhaitent pas partager des mesures d'utilisation anonymes." - -#: ../../source/ref-telemetry.md:7 -msgid "Principles" -msgstr "Principes" +"**Nouvel exemple de code d'autocodage variationnel** " +"([#752](https://github.com/adap/flower/pull/752))" -#: ../../source/ref-telemetry.md:9 -msgid "We follow strong principles guarding anonymous usage metrics collection:" +#: ../../source/ref-changelog.md:872 +msgid "" +"**New scikit-learn code example** " +"([#748](https://github.com/adap/flower/pull/748))" msgstr "" -"Nous suivons des principes stricts concernant la collecte de données " -"anonymes sur l'utilisation :" +"**Nouvel exemple de code scikit-learn** " +"([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-telemetry.md:11 +#: ../../source/ref-changelog.md:874 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to " -"learn “[How to opt-out](#how-to-opt-out)”." +"**New experimental TensorBoard strategy** " +"([#789](https://github.com/adap/flower/pull/789))" msgstr "" -"**Optionnel:** Tu pourras toujours désactiver la télémétrie ; lis la " -"suite pour apprendre \"[Comment se désengager](#how-to-opt-out)\"." +"**Nouvelle stratégie expérimentale TensorBoard** " +"([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-telemetry.md:12 +#: ../../source/ref-changelog.md:878 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not " -"contain any personally identifiable information (PII). See “[Collected " -"metrics](#collected-metrics)” to understand what metrics are being " -"reported." +"Improved advanced TensorFlow code example " +"([#769](https://github.com/adap/flower/pull/769))" msgstr "" -"**Anonyme:** Les mesures d'utilisation rapportées sont anonymes et ne " -"contiennent aucune information personnelle identifiable (PII). Voir " -"\"[Collected metrics](#collected-metrics)\" pour comprendre quelles " -"mesures sont rapportées." +"Amélioration de l'exemple de code TensorFlow avancé " +"([#769](https://github.com/adap/flower/pull/769))" -#: ../../source/ref-telemetry.md:13 +#: ../../source/ref-changelog.md:879 msgid "" -"**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-" -"to-inspect-what-is-being-reported)”" +"Warning when `min_available_clients` is misconfigured " +"([#830](https://github.com/adap/flower/pull/830))" msgstr "" -"**Transparent:** Tu peux facilement inspecter les métriques anonymes qui " -"sont rapportées ; voir la section \"[Comment inspecter ce qui est " -"rapporté](#how-to-inspect-what-is-being-reported)\"" +"Avertissement lorsque `min_available_clients` est mal configuré " +"([#830](https://github.com/adap/flower/pull/830))" -#: ../../source/ref-telemetry.md:14 -#, fuzzy +#: ../../source/ref-changelog.md:880 msgid "" -"**Open for feedback:** You can always reach out to us if you have " -"feedback; see the section “[How to contact us](#how-to-contact-us)” for " -"details." +"Improved gRPC server docs " +"([#841](https://github.com/adap/flower/pull/841))" msgstr "" -"**Ouvert pour les commentaires:** Tu peux toujours nous contacter si tu " -"as des commentaires ; voir la section \"[Comment nous contacter ](#how-" -"to-contact-us)\" pour plus de détails." - -#: ../../source/ref-telemetry.md:16 -msgid "How to opt-out" -msgstr "Comment se désinscrire" +"Amélioration de la documentation sur le serveur gRPC " +"([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-telemetry.md:18 +#: ../../source/ref-changelog.md:881 msgid "" -"When Flower starts, it will check for an environment variable called " -"`FLWR_TELEMETRY_ENABLED`. Telemetry can easily be disabled by setting " -"`FLWR_TELEMETRY_ENABLED=0`. Assuming you are starting a Flower server or " -"client, simply do so by prepending your command as in:" +"Improved error message in `NumPyClient` " +"([#851](https://github.com/adap/flower/pull/851))" msgstr "" -"Lorsque Flower démarre, il vérifie la présence d'une variable " -"d'environnement appelée `FLWR_TELEMETRY_ENABLED`. La télémétrie peut " -"facilement être désactivée en réglant `FLWR_TELEMETRY_ENABLED=0`. En " -"supposant que tu démarres un serveur ou un client Flower, fais-le " -"simplement en faisant précéder ta commande de la façon suivante :" +"Amélioration du message d'erreur dans `NumPyClient` " +"([#851](https://github.com/adap/flower/pull/851))" -#: ../../source/ref-telemetry.md:24 +#: ../../source/ref-changelog.md:882 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," -" `.bashrc` (or whatever configuration file applies to your environment) " -"to disable Flower telemetry permanently." +"Improved PyTorch quickstart code example " +"([#852](https://github.com/adap/flower/pull/852))" msgstr "" -"Tu peux aussi exporter `FLWR_TELEMETRY_ENABLED=0` dans, par exemple, " -"`.bashrc` (ou tout autre fichier de configuration qui s'applique à ton " -"environnement) pour désactiver la télémétrie de la fleur de façon " -"permanente." - -#: ../../source/ref-telemetry.md:26 -msgid "Collected metrics" -msgstr "Mesures collectées" - -#: ../../source/ref-telemetry.md:28 -msgid "Flower telemetry collects the following metrics:" -msgstr "La télémétrie des fleurs recueille les métriques suivantes :" +"Exemple de code de démarrage rapide PyTorch amélioré " +"([#852](https://github.com/adap/flower/pull/852))" -#: ../../source/ref-telemetry.md:30 +#: ../../source/ref-changelog.md:886 msgid "" -"**Flower version.** Understand which versions of Flower are currently " -"being used. This helps us to decide whether we should invest effort into " -"releasing a patch version for an older version of Flower or instead use " -"the bandwidth to build new features." +"**Disabled final distributed evaluation** " +"([#800](https://github.com/adap/flower/pull/800))" msgstr "" -"**Cela nous aide à décider si nous devons investir des efforts dans la " -"publication d'une version corrective pour une version plus ancienne de " -"Flower ou si nous devons plutôt utiliser la bande passante pour " -"développer de nouvelles fonctionnalités." +"**Désactivé l'évaluation finale distribuée** " +"([#800](https://github.com/adap/flower/pull/800))" -#: ../../source/ref-telemetry.md:32 +#: ../../source/ref-changelog.md:888 msgid "" -"**Operating system.** Enables us to answer questions such as: *Should we " -"create more guides for Linux, macOS, or Windows?*" +"Prior behaviour was to perform a final round of distributed evaluation on" +" all connected clients, which is often not required (e.g., when using " +"server-side evaluation). The prior behaviour can be enabled by passing " +"`force_final_distributed_eval=True` to `start_server`." msgstr "" -"**Système d'exploitation.** Nous permet de répondre à des questions " -"telles que : *Faudrait-il créer plus de guides pour Linux, macOS ou " -"Windows ?" +"Le comportement précédent consistait à effectuer un dernier tour " +"d'évaluation distribuée sur tous les clients connectés, ce qui n'est " +"souvent pas nécessaire (par exemple, lors de l'utilisation de " +"l'évaluation côté serveur). Le comportement précédent peut être activé en" +" passant `force_final_distributed_eval=True` à `start_server`." -#: ../../source/ref-telemetry.md:34 +#: ../../source/ref-changelog.md:890 msgid "" -"**Python version.** Knowing the Python version helps us, for example, to " -"decide whether we should invest effort into supporting old versions of " -"Python or stop supporting them and start taking advantage of new Python " -"features." +"**Renamed q-FedAvg strategy** " +"([#802](https://github.com/adap/flower/pull/802))" msgstr "" -"**Version de Python.** Connaître la version de Python nous aide, par " -"exemple, à décider si nous devons investir des efforts dans la prise en " -"charge des anciennes versions de Python ou cesser de les prendre en " -"charge et commencer à tirer parti des nouvelles fonctionnalités de " -"Python." +"**Renommé stratégie q-FedAvg** " +"([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-telemetry.md:36 +#: ../../source/ref-changelog.md:892 msgid "" -"**Hardware properties.** Understanding the hardware environment that " -"Flower is being used in helps to decide whether we should, for example, " -"put more effort into supporting low-resource environments." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " +"the notation given in the original paper (q-FFL is the optimization " +"objective, q-FedAvg is the proposed solver). Note the original (now " +"deprecated) `QffedAvg` class is still available for compatibility reasons" +" (it will be removed in a future release)." msgstr "" -"**Comprendre l'environnement matériel dans lequel Flower est utilisé " -"permet de décider si nous devrions, par exemple, faire plus d'efforts " -"pour prendre en charge les environnements à faibles ressources." +"La stratégie nommée `QffedAvg` a été renommée en `QFedAvg` pour mieux " +"refléter la notation donnée dans l'article original (q-FFL est l'objectif" +" d'optimisation, q-FedAvg est le solveur proposé). Notez que la classe " +"`QffedAvg` originale (maintenant obsolète) est toujours disponible pour " +"des raisons de compatibilité (elle sera supprimée dans une prochaine " +"version)." -#: ../../source/ref-telemetry.md:38 +#: ../../source/ref-changelog.md:894 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables " -"us to understand how heavily certain features are being used and better " -"prioritize based on that." +"**Deprecated and renamed code example** `simulation_pytorch` **to** " +"`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" msgstr "" -"**Mode d'exécution** Connaître le mode d'exécution dans lequel Flower " -"démarre nous permet de comprendre à quel point certaines fonctionnalités " -"sont utilisées et de mieux établir les priorités en fonction de cela." +"**Exemple de code déprécié et renommé** `simulation_pytorch` **en** " +"`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-telemetry.md:40 +#: ../../source/ref-changelog.md:896 msgid "" -"**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " -"time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete " -"them." +"This example has been replaced by a new example. The new example is based" +" on the experimental virtual client engine, which will become the new " +"default way of doing most types of large-scale simulations in Flower. The" +" existing example was kept for reference purposes, but it might be " +"removed in the future." msgstr "" -"**Cluster.** La télémétrie Flower attribue un ID de cluster en mémoire " -"aléatoire à chaque fois qu'une charge de travail Flower démarre. Cela " -"nous permet de comprendre quels types d'appareils non seulement démarrent" -" les charges de travail Flower, mais aussi les terminent avec succès." +"Cet exemple a été remplacé par un nouvel exemple. Le nouvel exemple est " +"basé sur le moteur expérimental du client virtuel, qui deviendra la " +"nouvelle méthode par défaut pour effectuer la plupart des types de " +"simulations à grande échelle dans Flower. L'exemple existant a été " +"conservé à des fins de référence, mais il pourrait être supprimé à " +"l'avenir." -#: ../../source/ref-telemetry.md:42 -msgid "" -"**Source.** Flower telemetry tries to store a random source ID in " -"`~/.flwr/source` the first time a telemetry event is generated. The " -"source ID is important to identify whether an issue is recurring or " -"whether an issue is triggered by multiple clusters running concurrently " -"(which often happens in simulation). For example, if a device runs " -"multiple workloads at the same time, and this results in an issue, then, " -"in order to reproduce the issue, multiple workloads must be started at " -"the same time." -msgstr "" -"**Source.** La télémétrie de Flower essaie de stocker un ID de source " -"aléatoire dans `~/.flwr/source` la première fois qu'un événement de " -"télémétrie est généré. L'ID de source est important pour identifier si un" -" problème est récurrent ou si un problème est déclenché par plusieurs " -"clusters fonctionnant simultanément (ce qui arrive souvent en " -"simulation). Par exemple, si un périphérique exécute plusieurs charges de" -" travail en même temps, et que cela entraîne un problème, alors, afin de " -"reproduire le problème, plusieurs charges de travail doivent être " -"démarrées en même temps." +#: ../../source/ref-changelog.md:898 +msgid "v0.16.0 (2021-05-11)" +msgstr "v0.16.0 (2021-05-11)" -#: ../../source/ref-telemetry.md:44 +#: ../../source/ref-changelog.md:902 msgid "" -"You may delete the source ID at any time. If you wish for all events " -"logged under a specific source ID to be deleted, you can send a deletion " -"request mentioning the source ID to `telemetry@flower.ai`. All events " -"related to that source ID will then be permanently deleted." +"**New built-in strategies** " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -"Tu peux supprimer l'identifiant de la source à tout moment. Si tu " -"souhaites que tous les événements enregistrés sous un identifiant de " -"source spécifique soient supprimés, tu peux envoyer une demande de " -"suppression mentionnant l'identifiant de source à `telemetry@flower.ai`. " -"Tous les événements liés à cet identifiant de source seront alors " -"définitivement supprimés." +"**Nouvelles stratégies intégrées** " +"([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-telemetry.md:46 -msgid "" -"We will not collect any personally identifiable information. If you think" -" any of the metrics collected could be misused in any way, please [get in" -" touch with us](#how-to-contact-us). We will update this page to reflect " -"any changes to the metrics collected and publish changes in the " -"changelog." -msgstr "" -"Nous ne collecterons aucune information personnelle identifiable. Si tu " -"penses que l'une des métriques collectées pourrait être utilisée à " -"mauvais escient de quelque manière que ce soit, merci de [nous " -"contacter](#commentnouscontacter). Nous mettrons à jour cette page pour " -"refléter toute modification des métriques collectées et nous publierons " -"les changements dans le journal des modifications (changelog)." +#: ../../source/ref-changelog.md:904 +msgid "(abstract) FedOpt" +msgstr "(résumé) FedOpt" -#: ../../source/ref-telemetry.md:48 +#: ../../source/ref-changelog.md:907 msgid "" -"If you think other metrics would be helpful for us to better guide our " -"decisions, please let us know! We will carefully review them; if we are " -"confident that they do not compromise user privacy, we may add them." +"**Custom metrics for server and strategies** " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -"Si tu penses que d'autres mesures nous seraient utiles pour mieux " -"orienter nos décisions, fais-le nous savoir ! Nous les examinerons " -"attentivement ; si nous sommes convaincus qu'elles ne compromettent pas " -"la vie privée des utilisateurs, nous pourrons les ajouter." - -#: ../../source/ref-telemetry.md:50 -msgid "How to inspect what is being reported" -msgstr "Comment inspecter ce qui est rapporté" +"**Métriques personnalisées pour le serveur et les stratégies** " +"([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/ref-telemetry.md:52 +#: ../../source/ref-changelog.md:909 msgid "" -"We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information" -" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " -"is disabled by default. You may use logging independently from " -"`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " -"without sending any metrics." +"The Flower server is now fully task-agnostic, all remaining instances of " +"task-specific metrics (such as `accuracy`) have been replaced by custom " +"metrics dictionaries. Flower 0.15 introduced the capability to pass a " +"dictionary containing custom metrics from client to server. As of this " +"release, custom metrics replace task-specific metrics on the server." msgstr "" -"Nous avons voulu qu'il soit très facile pour toi d'inspecter les mesures " -"d'utilisation anonymes qui sont rapportées. Tu peux voir toutes les " -"informations de télémétrie rapportées en définissant la variable " -"d'environnement `FLWR_TELEMETRY_LOGGING=1`. La journalisation est " -"désactivée par défaut. Tu peux utiliser la journalisation indépendamment " -"de `FLWR_TELEMETRY_ENABLED` afin d'inspecter la fonction de télémétrie " -"sans envoyer de mesures." +"Le serveur Flower est maintenant totalement agnostique, toutes les " +"instances restantes de métriques spécifiques à une tâche (telles que " +"`accuracy`) ont été remplacées par des dictionnaires de métriques " +"personnalisées. Flower 0.15 a introduit la possibilité de passer un " +"dictionnaire contenant des métriques personnalisées du client au serveur." +" À partir de cette version, les métriques personnalisées remplacent les " +"métriques spécifiques à une tâche sur le serveur." -#: ../../source/ref-telemetry.md:58 +#: ../../source/ref-changelog.md:911 +#, fuzzy msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics," -" use both environment variables:" +"Custom metric dictionaries are now used in two user-facing APIs: they are" +" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " +"they enable evaluation functions passed to built-in strategies (via " +"`eval_fn`) to return more than two evaluation metrics. Strategies can " +"even return *aggregated* metrics dictionaries for the server to keep " +"track of." msgstr "" -"L'inspecteur Flower telemetry sans envoyer de métriques d'utilisation " -"anonymes, utilise les deux variables d'environnement :" - -#: ../../source/ref-telemetry.md:64 -msgid "How to contact us" -msgstr "Comment nous contacter" +"Les dictionnaires de métriques personnalisés sont maintenant utilisés " +"dans deux API orientées vers l'utilisateur : ils sont renvoyés par les " +"méthodes de stratégie `aggregate_fit`/`aggregate_evaluate` et ils " +"permettent aux fonctions d'évaluation passées aux stratégies intégrées " +"(via `eval_fn`) de renvoyer plus de deux métriques d'évaluation. Les " +"stratégies peuvent même renvoyer des dictionnaires de métriques " +"*agrégées* pour que le serveur puisse en garder la trace." -#: ../../source/ref-telemetry.md:66 +#: ../../source/ref-changelog.md:913 +#, fuzzy msgid "" -"We want to hear from you. If you have any feedback or ideas on how to " -"improve the way we handle anonymous usage metrics, reach out to us via " -"[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " -"(`telemetry@flower.ai`)." +"Strategy implementations should migrate their `aggregate_fit` and " +"`aggregate_evaluate` methods to the new return type (e.g., by simply " +"returning an empty `{}`), server-side evaluation functions should migrate" +" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -"Si tu as des commentaires ou des idées pour améliorer la façon dont nous " -"traitons les mesures d'utilisation anonymes, contacte-nous via " -"[Slack](https://flower.ai/join-slack/) (canal `#telemetry`) ou par " -"courriel (`telemetry@flower.ai`)." +"Les implémentations de Stratey doivent migrer leurs méthodes " +"`aggregate_fit` et `aggregate_evaluate` vers le nouveau type de retour " +"(par exemple, en renvoyant simplement un `{}` vide), les fonctions " +"d'évaluation côté serveur doivent migrer de `return loss, accuracy` à " +"`return loss, {\"accuracy\" : accuracy}`." -#: ../../source/tutorial-quickstart-android.rst:-1 +#: ../../source/ref-changelog.md:915 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android " -"app using Flower." +"Flower 0.15-style return types are deprecated (but still supported), " +"compatibility will be removed in a future release." msgstr "" +"Les types de retour du style Flower 0.15 sont dépréciés (mais toujours " +"pris en charge), la compatibilité sera supprimée dans une prochaine " +"version." -#: ../../source/tutorial-quickstart-android.rst:5 -#, fuzzy -msgid "Quickstart Android" -msgstr "Démarrage rapide des Pandas" - -#: ../../source/tutorial-quickstart-android.rst:10 -#, fuzzy +#: ../../source/ref-changelog.md:917 msgid "" -"Let's build a federated learning system using TFLite and Flower on " -"Android!" +"**Migration warnings for deprecated functionality** " +"([#690](https://github.com/adap/flower/pull/690))" msgstr "" -"Construisons un système d'apprentissage fédéré en utilisant fastai et " -"Flower !" +"**Avertissements de migration pour les fonctionnalités obsolètes** " +"([#690](https://github.com/adap/flower/pull/690))" -#: ../../source/tutorial-quickstart-android.rst:12 -#, fuzzy +#: ../../source/ref-changelog.md:919 msgid "" -"Please refer to the `full code example " -"`_ to learn " -"more." +"Earlier versions of Flower were often migrated to new APIs, while " +"maintaining compatibility with legacy APIs. This release introduces " +"detailed warning messages if usage of deprecated APIs is detected. The " +"new warning messages often provide details on how to migrate to more " +"recent APIs, thus easing the transition from one release to another." msgstr "" -"Réfère-toi à l'exemple de code complet " -"`_ " -"pour en savoir plus." +"Les versions antérieures de Flower ont souvent été migrées vers de " +"nouvelles API, tout en maintenant la compatibilité avec les anciennes " +"API. Cette version introduit des messages d'avertissement détaillés si " +"l'utilisation d'API obsolètes est détectée. Les nouveaux messages " +"d'avertissement fournissent souvent des détails sur la façon de migrer " +"vers des API plus récentes, facilitant ainsi la transition d'une version " +"à l'autre." -#: ../../source/tutorial-quickstart-fastai.rst:-1 +#: ../../source/ref-changelog.md:921 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with FastAI to train a vision model on CIFAR-10." +"Improved docs and docstrings " +"([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" msgstr "" +"Amélioration des docs et des docstrings " +"([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" -#: ../../source/tutorial-quickstart-fastai.rst:5 -msgid "Quickstart fastai" -msgstr "Démarrage rapide fastai" - -#: ../../source/tutorial-quickstart-fastai.rst:10 -msgid "Let's build a federated learning system using fastai and Flower!" -msgstr "" -"Construisons un système d'apprentissage fédéré en utilisant fastai et " -"Flower !" +#: ../../source/ref-changelog.md:923 +msgid "MXNet example and documentation" +msgstr "Exemple et documentation MXNet" -#: ../../source/tutorial-quickstart-fastai.rst:12 -#, fuzzy +#: ../../source/ref-changelog.md:925 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"FedBN implementation in example PyTorch: From Centralized To Federated " +"([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" msgstr "" -"Réfère-toi à l'exemple de code complet " -"`_ " -"pour en savoir plus." +"Mise en œuvre de FedBN dans l'exemple PyTorch : De la centralisation à la" +" fédération ([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" -#: ../../source/tutorial-quickstart-huggingface.rst:-1 +#: ../../source/ref-changelog.md:929 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower " -"with HuggingFace Transformers in order to fine-tune an LLM." +"**Serialization-agnostic server** " +"([#721](https://github.com/adap/flower/pull/721))" msgstr "" +"**Serveur agnostique de sérialisation** " +"([#721](https://github.com/adap/flower/pull/721))" -#: ../../source/tutorial-quickstart-huggingface.rst:5 -msgid "Quickstart 🤗 Transformers" -msgstr "Démarrage rapide 🤗 Transformateurs" - -#: ../../source/tutorial-quickstart-huggingface.rst:10 +#: ../../source/ref-changelog.md:931 msgid "" -"Let's build a federated learning system using Hugging Face Transformers " -"and Flower!" +"The Flower server is now fully serialization-agnostic. Prior usage of " +"class `Weights` (which represents parameters as deserialized NumPy " +"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " +"`Parameters` objects are fully serialization-agnostic and represents " +"parameters as byte arrays, the `tensor_type` attributes indicates how " +"these byte arrays should be interpreted (e.g., for " +"serialization/deserialization)." msgstr "" -"Construisons un système d'apprentissage fédéré à l'aide des " -"transformateurs Hugging Face et de Flower !" +"Le serveur Flower est désormais totalement agnostique en matière de " +"sérialisation. L'utilisation antérieure de la classe `Weights` (qui " +"représente les paramètres sous forme de tableaux NumPy désérialisés) a " +"été remplacée par la classe `Parameters` (par exemple, dans `Strategy`). " +"Les objets `Parameters` sont totalement agnostiques en matière de " +"sérialisation et représentent les paramètres sous forme de tableaux " +"d'octets, les attributs `tensor_type` indiquent comment ces tableaux " +"d'octets doivent être interprétés (par exemple, pour la " +"sérialisation/désérialisation)." -#: ../../source/tutorial-quickstart-huggingface.rst:12 +#: ../../source/ref-changelog.md:933 msgid "" -"We will leverage Hugging Face to federate the training of language models" -" over multiple clients using Flower. More specifically, we will fine-tune" -" a pre-trained Transformer model (distilBERT) for sequence classification" -" over a dataset of IMDB ratings. The end goal is to detect if a movie " -"rating is positive or negative." +"Built-in strategies implement this approach by handling serialization and" +" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"implementations should update to the slightly changed Strategy method " +"definitions. Strategy authors can consult PR " +"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" +" easily migrate to the new format." msgstr "" -"Nous nous appuierons sur Hugging Face pour fédérer l'entraînement de " -"modèles de langage sur plusieurs clients à l'aide de Flower. Plus " -"précisément, nous mettrons au point un modèle Transformer pré-entraîné " -"(distilBERT) pour la classification de séquences sur un ensemble de " -"données d'évaluations IMDB. L'objectif final est de détecter si " -"l'évaluation d'un film est positive ou négative." - -#: ../../source/tutorial-quickstart-huggingface.rst:18 -msgid "Dependencies" -msgstr "Dépendances" +"Les stratégies intégrées mettent en œuvre cette approche en gérant en " +"interne la sérialisation et la désérialisation de `Weights`. Les " +"implémentations de stratégies personnalisées ou tierces doivent être " +"mises à jour avec les définitions de méthodes de stratégie légèrement " +"modifiées. Les auteurs de stratégies peuvent consulter le PR " +"[#721](https://github.com/adap/flower/pull/721) pour voir comment les " +"stratégies peuvent facilement migrer vers le nouveau format." -#: ../../source/tutorial-quickstart-huggingface.rst:20 +#: ../../source/ref-changelog.md:935 msgid "" -"To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " -":code:`torch`, and :code:`transformers`. This can be done using " -":code:`pip`:" +"Deprecated `flwr.server.Server.evaluate`, use " +"`flwr.server.Server.evaluate_round` instead " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -"Pour suivre ce tutoriel, tu devras installer les paquets suivants : " -":code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, et " -":code:`transformers`. Cela peut être fait en utilisant :code:`pip` :" - -#: ../../source/tutorial-quickstart-huggingface.rst:30 -msgid "Standard Hugging Face workflow" -msgstr "Flux de travail standard pour le visage" +"Déclassé `flwr.server.Server.evaluate`, utiliser " +"`flwr.server.Server.evaluate_round` à la place " +"([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/tutorial-quickstart-huggingface.rst:33 -msgid "Handling the data" -msgstr "Traitement des données" +#: ../../source/ref-changelog.md:937 +msgid "v0.15.0 (2021-03-12)" +msgstr "v0.15.0 (2021-03-12)" -#: ../../source/tutorial-quickstart-huggingface.rst:35 +#: ../../source/ref-changelog.md:941 msgid "" -"To fetch the IMDB dataset, we will use Hugging Face's :code:`datasets` " -"library. We then need to tokenize the data and create :code:`PyTorch` " -"dataloaders, this is all done in the :code:`load_data` function:" +"**Server-side parameter initialization** " +"([#658](https://github.com/adap/flower/pull/658))" msgstr "" -"Pour récupérer le jeu de données IMDB, nous utiliserons la bibliothèque " -":code:`datasets` de Hugging Face. Nous devons ensuite tokeniser les " -"données et créer des :code:`PyTorch` dataloaders, ce qui est fait dans la" -" fonction :code:`load_data` :" - -#: ../../source/tutorial-quickstart-huggingface.rst:81 -msgid "Training and testing the model" -msgstr "Former et tester le modèle" +"**Initialisation des paramètres côté serveur** " +"([#658](https://github.com/adap/flower/pull/658))" -#: ../../source/tutorial-quickstart-huggingface.rst:83 +#: ../../source/ref-changelog.md:943 msgid "" -"Once we have a way of creating our trainloader and testloader, we can " -"take care of the training and testing. This is very similar to any " -":code:`PyTorch` training or testing loop:" +"Model parameters can now be initialized on the server-side. Server-side " +"parameter initialization works via a new `Strategy` method called " +"`initialize_parameters`." msgstr "" -"Une fois que nous avons trouvé un moyen de créer notre trainloader et " -"notre testloader, nous pouvons nous occuper de l'entraînement et du test." -" C'est très similaire à n'importe quelle boucle d'entraînement ou de test" -" :code:`PyTorch` :" - -#: ../../source/tutorial-quickstart-huggingface.rst:121 -msgid "Creating the model itself" -msgstr "Créer le modèle lui-même" +"Les paramètres du modèle peuvent maintenant être initialisés côté " +"serveur. L'initialisation des paramètres côté serveur fonctionne via une " +"nouvelle méthode `Strategy` appelée `initialize_parameters`." -#: ../../source/tutorial-quickstart-huggingface.rst:123 +#: ../../source/ref-changelog.md:945 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT" -" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"Built-in strategies support a new constructor argument called " +"`initial_parameters` to set the initial parameters. Built-in strategies " +"will provide these initial parameters to the server on startup and then " +"delete them to free the memory afterwards." msgstr "" -"Pour créer le modèle lui-même, nous allons simplement charger le modèle " -"distillBERT pré-entraîné en utilisant le " -":code:`AutoModelForSequenceClassification` de Hugging Face :" - -#: ../../source/tutorial-quickstart-huggingface.rst:136 -msgid "Federating the example" -msgstr "Fédérer l'exemple" - -#: ../../source/tutorial-quickstart-huggingface.rst:139 -msgid "Creating the IMDBClient" -msgstr "Création du client IMDBC" +"Les stratégies intégrées prennent en charge un nouvel argument du " +"constructeur appelé `initial_parameters` pour définir les paramètres " +"initiaux. Les stratégies intégrées fourniront ces paramètres initiaux au " +"serveur au démarrage et les supprimeront ensuite pour libérer la mémoire." -#: ../../source/tutorial-quickstart-huggingface.rst:141 +#: ../../source/ref-changelog.md:964 msgid "" -"To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " -"This is very easy, as our model is a standard :code:`PyTorch` model:" +"If no initial parameters are provided to the strategy, the server will " +"continue to use the current behaviour (namely, it will ask one of the " +"connected clients for its parameters and use these as the initial global " +"parameters)." msgstr "" -"Pour fédérer notre exemple à plusieurs clients, nous devons d'abord " -"écrire notre classe de client Flower (héritant de " -":code:`flwr.client.NumPyClient`). C'est très facile, car notre modèle est" -" un modèle :code:`PyTorch` standard :" +"Si aucun paramètre initial n'est fourni à la stratégie, le serveur " +"continuera à utiliser le comportement actuel (à savoir qu'il demandera à " +"l'un des clients connectés ses paramètres et les utilisera comme " +"paramètres globaux initiaux)." -#: ../../source/tutorial-quickstart-huggingface.rst:169 +#: ../../source/ref-changelog.md:966 +msgid "Deprecations" +msgstr "Dépréciations" + +#: ../../source/ref-changelog.md:968 msgid "" -"The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the " -"server to send its parameters to the client. Finally, the :code:`fit` " -"function trains the model locally for the client, and the " -":code:`evaluate` function tests the model locally and returns the " -"relevant metrics." +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " +"`flwr.server.strategy.FedAvg`, which is equivalent)" msgstr "" -"La fonction :code:`get_parameters` permet au serveur d'obtenir les " -"paramètres du client. Inversement, la fonction :code:`set_parameters` " -"permet au serveur d'envoyer ses paramètres au client. Enfin, la fonction " -":code:`fit` forme le modèle localement pour le client, et la fonction " -":code:`evaluate` teste le modèle localement et renvoie les mesures " -"correspondantes." +"Déclasser `flwr.server.strategy.DefaultStrategy` (migrer vers " +"`flwr.server.strategy.FedAvg`, qui est équivalent)" -#: ../../source/tutorial-quickstart-huggingface.rst:175 -msgid "Starting the server" -msgstr "Démarrer le serveur" +#: ../../source/ref-changelog.md:970 +msgid "v0.14.0 (2021-02-18)" +msgstr "v0.14.0 (2021-02-18)" -#: ../../source/tutorial-quickstart-huggingface.rst:177 +#: ../../source/ref-changelog.md:974 msgid "" -"Now that we have a way to instantiate clients, we need to create our " -"server in order to aggregate the results. Using Flower, this can be done " -"very easily by first choosing a strategy (here, we are using " -":code:`FedAvg`, which will define the global weights as the average of " -"all the clients' weights at each round) and then using the " -":code:`flwr.server.start_server` function:" +"**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " +"([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" msgstr "" -"Maintenant que nous avons un moyen d'instancier les clients, nous devons " -"créer notre serveur afin d'agréger les résultats. Avec Flower, cela peut " -"être fait très facilement en choisissant d'abord une stratégie (ici, nous" -" utilisons :code:`FedAvg`, qui définira les poids globaux comme la " -"moyenne des poids de tous les clients à chaque tour) et en utilisant " -"ensuite la fonction :code:`flwr.server.start_server` :" +"**Généralisé** `Client.fit` **et** `Client.evaluate` **valeurs de " +"retour** ([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" -#: ../../source/tutorial-quickstart-huggingface.rst:205 +#: ../../source/ref-changelog.md:976 msgid "" -"The :code:`weighted_average` function is there to provide a way to " -"aggregate the metrics distributed amongst the clients (basically this " -"allows us to display a nice average accuracy and loss for every round)." +"Clients can now return an additional dictionary mapping `str` keys to " +"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " +"This means one can return almost arbitrary values from `fit`/`evaluate` " +"and make use of them on the server side!" msgstr "" -"La fonction :code:`weighted_average` est là pour fournir un moyen " -"d'agréger les mesures réparties entre les clients (en gros, cela nous " -"permet d'afficher une belle moyenne de précision et de perte pour chaque " -"tour)." - -#: ../../source/tutorial-quickstart-huggingface.rst:209 -msgid "Putting everything together" -msgstr "Tout assembler" - -#: ../../source/tutorial-quickstart-huggingface.rst:211 -msgid "We can now start client instances using:" -msgstr "Nous pouvons maintenant démarrer des instances de clients en utilisant :" +"Les clients peuvent maintenant renvoyer un dictionnaire supplémentaire " +"associant les clés `str` aux valeurs des types suivants : `bool`, " +"`bytes`, `float`, `int`, `str`. Cela signifie que l'on peut renvoyer des " +"valeurs presque arbitraires de `fit`/`evaluate` et les utiliser du côté " +"du serveur !" -#: ../../source/tutorial-quickstart-huggingface.rst:221 +#: ../../source/ref-changelog.md:978 msgid "" -"And they will be able to connect to the server and start the federated " -"training." -msgstr "Et ils pourront se connecter au serveur et démarrer la formation fédérée." +"This improvement also allowed for more consistent return types between " +"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " +"dict)` representing the loss, number of examples, and a dictionary " +"holding arbitrary problem-specific values like accuracy." +msgstr "" +"Cette amélioration a également permis de rendre plus cohérents les types " +"de retour entre `fit` et `evaluate` : `evaluate` devrait maintenant " +"retourner un tuple `(float, int, dict)` représentant la perte, le nombre " +"d'exemples, et un dictionnaire contenant des valeurs arbitraires " +"spécifiques au problème comme la précision." -#: ../../source/tutorial-quickstart-huggingface.rst:223 -#, fuzzy +#: ../../source/ref-changelog.md:980 msgid "" -"If you want to check out everything put together, you should check out " -"the `full code example `_ ." +"In case you wondered: this feature is compatible with existing projects, " +"the additional dictionary return value is optional. New code should " +"however migrate to the new return types to be compatible with upcoming " +"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " +"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " +"details." msgstr "" -"Si tu veux voir tout ce qui est mis ensemble, tu devrais consulter " -"l'exemple de code complet : " -"[https://github.com/adap/flower/tree/main/examples/quickstart-" -"huggingface](https://github.com/adap/flower/tree/main/examples" -"/quickstart-huggingface)." +"Au cas où tu te poserais la question : cette fonctionnalité est " +"compatible avec les projets existants, la valeur de retour supplémentaire" +" du dictionnaire est facultative. Le nouveau code doit cependant migrer " +"vers les nouveaux types de retour pour être compatible avec les " +"prochaines versions de Flower (`fit` : `List[np.ndarray], int, Dict[str, " +"Scalar]`, `evaluate` : `float, int, Dict[str, Scalar]`). Voir l'exemple " +"ci-dessous pour plus de détails." -#: ../../source/tutorial-quickstart-huggingface.rst:226 +#: ../../source/ref-changelog.md:982 msgid "" -"Of course, this is a very basic example, and a lot can be added or " -"modified, it was just to showcase how simply we could federate a Hugging " -"Face workflow using Flower." +"*Code example:* note the additional dictionary return values in both " +"`FlwrClient.fit` and `FlwrClient.evaluate`:" msgstr "" -"Bien sûr, c'est un exemple très basique, et beaucoup de choses peuvent " -"être ajoutées ou modifiées, il s'agissait juste de montrer avec quelle " -"simplicité on pouvait fédérer un flux de travail Hugging Face à l'aide de" -" Flower." +"*Exemple de code:* note les valeurs de retour du dictionnaire " +"supplémentaires dans `FlwrClient.fit` et `FlwrClient.evaluate` :" -#: ../../source/tutorial-quickstart-huggingface.rst:229 +#: ../../source/ref-changelog.md:997 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very" -" well used :code:`TensorFlow`." +"**Generalized** `config` **argument in** `Client.fit` **and** " +"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -"Notez que dans cet exemple, nous avons utilisé :code:`PyTorch`, mais nous" -" aurions très bien pu utiliser :code:`TensorFlow`." +"**Généralisé** `config` **argument dans** `Client.fit` **et** " +"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" -#: ../../source/tutorial-quickstart-ios.rst:-1 +#: ../../source/ref-changelog.md:999 msgid "" -"Read this Federated Learning quickstart tutorial for creating an iOS app " -"using Flower to train a neural network on MNIST." +"The `config` argument used to be of type `Dict[str, str]`, which means " +"that dictionary values were expected to be strings. The new release " +"generalizes this to enable values of the following types: `bool`, " +"`bytes`, `float`, `int`, `str`." msgstr "" +"L'argument `config` était auparavant de type `Dict[str, str]`, ce qui " +"signifie que les valeurs du dictionnaire devaient être des chaînes. La " +"nouvelle version généralise cela pour permettre les valeurs des types " +"suivants : `bool`, `bytes`, `float`, `int`, `str`." -#: ../../source/tutorial-quickstart-ios.rst:5 -#, fuzzy -msgid "Quickstart iOS" -msgstr "Démarrage rapide XGBoost" - -#: ../../source/tutorial-quickstart-ios.rst:10 -#, fuzzy +#: ../../source/ref-changelog.md:1001 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST " -"using Flower and CoreML on iOS devices." +"This means one can now pass almost arbitrary values to `fit`/`evaluate` " +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" +"side and `int(config[\"epochs\"])` on the client side!" msgstr "" -"Dans ce tutoriel, nous allons apprendre, comment former un réseau " -"neuronal convolutif sur MNIST en utilisant Flower et PyTorch." +"Cela signifie que l'on peut maintenant passer des valeurs presque " +"arbitraires à `fit`/`evaluate` en utilisant le dictionnaire `config`. " +"Yay, plus de `str(epochs)` du côté serveur et `int(config[\"epochs\"])` " +"du côté client !" -#: ../../source/tutorial-quickstart-ios.rst:12 -#, fuzzy +#: ../../source/ref-changelog.md:1003 msgid "" -"First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv" -" `. For the Flower client " -"implementation in iOS, it is recommended to use Xcode as our IDE." +"*Code example:* note that the `config` dictionary now contains non-`str` " +"values in both `Client.fit` and `Client.evaluate`:" msgstr "" -"Tout d'abord, il est recommandé de créer un environnement virtuel et de " -"tout exécuter au sein d'un `virtualenv `_." +"*Exemple de code:* Notez que le dictionnaire `config` contient maintenant" +" des valeurs autres que `str` dans `Client.fit` et `Client.evaluate` :" -#: ../../source/tutorial-quickstart-ios.rst:15 -#, fuzzy -msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that" -" all have the same model." -msgstr "" -"Notre exemple consiste en un *serveur* et deux *clients* ayant tous le " -"même modèle." +#: ../../source/ref-changelog.md:1020 +msgid "v0.13.0 (2021-01-08)" +msgstr "v0.13.0 (2021-01-08)" -#: ../../source/tutorial-quickstart-ios.rst:17 -#, fuzzy +#: ../../source/ref-changelog.md:1024 msgid "" -"*Clients* are responsible for generating individual weight updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"New example: PyTorch From Centralized To Federated " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -"*Les clients* sont chargés de générer des mises à jour de poids " -"individuelles pour le modèle en fonction de leurs ensembles de données " -"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " -"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " -"cette version améliorée du modèle à chaque *client*. Un cycle complet de " -"mises à jour de poids s'appelle un *round*." +"Nouvel exemple : PyTorch de centralisé à fédéré " +"([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/tutorial-quickstart-ios.rst:21 -#, fuzzy -msgid "" -"Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You" -" can do this by using pip:" -msgstr "" -"Maintenant que nous avons une idée générale de ce qui se passe, " -"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " -"exécutant :" +#: ../../source/ref-changelog.md:1025 +msgid "Improved documentation" +msgstr "Amélioration de la documentation" -#: ../../source/tutorial-quickstart-ios.rst:27 -msgid "Or Poetry:" +#: ../../source/ref-changelog.md:1026 +msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" +"Nouveau thème de documentation " +"([#551](https://github.com/adap/flower/pull/551))" -#: ../../source/tutorial-quickstart-ios.rst:34 -#: ../../source/tutorial-quickstart-mxnet.rst:36 -#: ../../source/tutorial-quickstart-pytorch.rst:37 -#: ../../source/tutorial-quickstart-scikitlearn.rst:40 -#: ../../source/tutorial-quickstart-tensorflow.rst:29 -#: ../../source/tutorial-quickstart-xgboost.rst:55 -msgid "Flower Client" -msgstr "Client de la fleur" +#: ../../source/ref-changelog.md:1027 +msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" +msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/tutorial-quickstart-ios.rst:36 +#: ../../source/ref-changelog.md:1028 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and " -"MNIST as our dataset. For simplicity reasons we will use the complete " -"Flower client with CoreML, that has been implemented and stored inside " -"the Swift SDK. The client implementation can be seen below:" +"Updated examples documentation " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" +"Mise à jour de la documentation des exemples " +"([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/tutorial-quickstart-ios.rst:72 +#: ../../source/ref-changelog.md:1029 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a" -" dependency in your project. For our application, we will store the logic" -" of our app in :code:`FLiOSModel.swift` and the UI elements in " -":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" -" in this quickstart. Please refer to the `full code example " -"`_ to learn more " -"about the app." +"Removed obsolete documentation " +"([#548](https://github.com/adap/flower/pull/548))" msgstr "" +"Suppression de la documentation obsolète " +"([#548](https://github.com/adap/flower/pull/548))" -#: ../../source/tutorial-quickstart-ios.rst:75 -msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" -msgstr "" +#: ../../source/ref-changelog.md:1031 +msgid "Bugfix:" +msgstr "Correction de bogues :" -#: ../../source/tutorial-quickstart-ios.rst:83 +#: ../../source/ref-changelog.md:1033 msgid "" -"Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS " -"device. We need to pass the url to access mlmodel and run CoreML machine " -"learning processes, it can be retrieved by calling the function " -":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " -"into :code:`MLBatchProvider` object. The preprocessing is done inside " -":code:`DataLoader.swift`." +"`Server.fit` does not disconnect clients when finished, disconnecting the" +" clients is now handled in `flwr.server.start_server` " +"([#553](https://github.com/adap/flower/pull/553) " +"[#540](https://github.com/adap/flower/issues/540))." msgstr "" +"`Server.fit` ne déconnecte pas les clients lorsqu'il est terminé, la " +"déconnexion des clients est maintenant gérée dans " +"`flwr.server.start_server` " +"([#553](https://github.com/adap/flower/pull/553) " +"[#540](https://github.com/adap/flower/issues/540))." -#: ../../source/tutorial-quickstart-ios.rst:99 +#: ../../source/ref-changelog.md:1035 +msgid "v0.12.0 (2020-12-07)" +msgstr "v0.12.0 (2020-12-07)" + +#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +msgid "Important changes:" +msgstr "Changements importants :" + +#: ../../source/ref-changelog.md:1039 msgid "" -"Since CoreML does not allow the model parameters to be seen before " -"training, and accessing the model parameters during or after the training" -" can only be done by specifying the layer name, we need to know this " -"information beforehand, through looking at the model specification, which" -" are written as proto files. The implementation can be seen in " -":code:`MLModelInspect`." +"Added an example for embedded devices " +"([#507](https://github.com/adap/flower/pull/507))" msgstr "" +"Ajout d'un exemple pour les périphériques embarqués " +"([#507](https://github.com/adap/flower/pull/507))" -#: ../../source/tutorial-quickstart-ios.rst:102 +#: ../../source/ref-changelog.md:1040 msgid "" -"After we have all of the necessary information, let's create our Flower " -"client." +"Added a new NumPyClient (in addition to the existing KerasClient) " +"([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508))" msgstr "" +"Ajout d'un nouveau NumPyClient (en plus du KerasClient existant) " +"([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508))" -#: ../../source/tutorial-quickstart-ios.rst:117 +#: ../../source/ref-changelog.md:1041 msgid "" -"Then start the Flower gRPC client and start communicating to the server " -"by passing our Flower client to the function :code:`startFlwrGRPC`." +"Deprecated `flwr_example` package and started to migrate examples into " +"the top-level `examples` directory " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" msgstr "" +"Déclassement du paquet `flwr_example` et migration des exemples dans le " +"répertoire de premier niveau `examples` " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" -#: ../../source/tutorial-quickstart-ios.rst:124 +#: ../../source/ref-changelog.md:1043 +msgid "v0.11.0 (2020-11-30)" +msgstr "v0.11.0 (2020-11-30)" + +#: ../../source/ref-changelog.md:1045 +msgid "Incompatible changes:" +msgstr "Changements incompatibles :" + +#: ../../source/ref-changelog.md:1047 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " -"The attribute :code:`hostname` and :code:`port` tells the client which " -"server to connect to. This can be done by entering the hostname and port " -"in the application before clicking the start button to start the " -"federated learning process." +"Renamed strategy methods " +"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " +"Flower's public APIs. Other public methods/functions (e.g., every method " +"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " +"which is why we're removing it from the four methods in Strategy. To " +"migrate rename the following `Strategy` methods accordingly:" msgstr "" +"Renommé les méthodes de stratégie " +"([#486](https://github.com/adap/flower/pull/486)) pour unifier le nommage" +" des API publiques de Flower. D'autres méthodes/fonctions publiques (par " +"exemple, toutes les méthodes de `Client`, mais aussi `Strategy.evaluate`)" +" n'utilisent pas le préfixe `on_`, c'est pourquoi nous le supprimons des " +"quatre méthodes de Stratégie. Pour migrer, renommez les méthodes de " +"`Strategy` suivantes en conséquence :" -#: ../../source/tutorial-quickstart-ios.rst:129 -#: ../../source/tutorial-quickstart-mxnet.rst:226 -#: ../../source/tutorial-quickstart-pytorch.rst:203 -#: ../../source/tutorial-quickstart-scikitlearn.rst:157 -#: ../../source/tutorial-quickstart-tensorflow.rst:98 -#: ../../source/tutorial-quickstart-xgboost.rst:309 -msgid "Flower Server" -msgstr "Serveur de Flower" +#: ../../source/ref-changelog.md:1048 +msgid "`on_configure_evaluate` => `configure_evaluate`" +msgstr "`on_configure_evaluate` => `configure_evaluate`" -#: ../../source/tutorial-quickstart-ios.rst:131 -#: ../../source/tutorial-quickstart-mxnet.rst:228 -#: ../../source/tutorial-quickstart-pytorch.rst:205 -#: ../../source/tutorial-quickstart-tensorflow.rst:100 +#: ../../source/ref-changelog.md:1049 +msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" +msgstr "`on_aggregate_evaluate` => `aggregate_evaluate`" + +#: ../../source/ref-changelog.md:1050 +msgid "`on_configure_fit` => `configure_fit`" +msgstr "`on_configure_fit` => `configure_fit`" + +#: ../../source/ref-changelog.md:1051 +msgid "`on_aggregate_fit` => `aggregate_fit`" +msgstr "`on_aggregate_fit` => `aggregate_fit`" + +#: ../../source/ref-changelog.md:1055 msgid "" -"For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named " -":code:`server.py`, import Flower and start the server:" +"Deprecated `DefaultStrategy` " +"([#479](https://github.com/adap/flower/pull/479)). To migrate use " +"`FedAvg` instead." msgstr "" -"Pour les charges de travail simples, nous pouvons démarrer un serveur " -"Flower et laisser toutes les possibilités de configuration à leurs " -"valeurs par défaut. Dans un fichier nommé :code:`server.py`, importe " -"Flower et démarre le serveur :" - -#: ../../source/tutorial-quickstart-ios.rst:142 -#: ../../source/tutorial-quickstart-mxnet.rst:239 -#: ../../source/tutorial-quickstart-pytorch.rst:216 -#: ../../source/tutorial-quickstart-scikitlearn.rst:215 -#: ../../source/tutorial-quickstart-tensorflow.rst:112 -msgid "Train the model, federated!" -msgstr "Entraîne le modèle, fédéré !" +"Déclassé `DefaultStrategy` " +"([#479](https://github.com/adap/flower/pull/479)). Pour migrer, utilisez " +"`FedAvg` à la place." -#: ../../source/tutorial-quickstart-ios.rst:144 -#: ../../source/tutorial-quickstart-pytorch.rst:218 -#: ../../source/tutorial-quickstart-tensorflow.rst:114 -#: ../../source/tutorial-quickstart-xgboost.rst:525 +#: ../../source/ref-changelog.md:1056 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and " -"multiple clients. We therefore have to start the server first:" +"Simplified examples and baselines " +"([#484](https://github.com/adap/flower/pull/484))." msgstr "" -"Le client et le serveur étant prêts, nous pouvons maintenant tout " -"exécuter et voir l'apprentissage fédéré en action. Les systèmes FL ont " -"généralement un serveur et plusieurs clients. Nous devons donc commencer " -"par démarrer le serveur :" +"Exemples simplifiés et lignes de base " +"([#484](https://github.com/adap/flower/pull/484))." -#: ../../source/tutorial-quickstart-ios.rst:152 +#: ../../source/ref-changelog.md:1057 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Build and run the client through your Xcode, one through Xcode" -" Simulator and the other by deploying it to your iPhone. To see more " -"about how to deploy your app to iPhone or Simulator visit `here " -"`_." +"Removed presently unused `on_conclude_round` from strategy interface " +"([#483](https://github.com/adap/flower/pull/483))." msgstr "" +"Suppression de `on_conclude_round` actuellement inutilisé de l'interface " +"de stratégie ([#483](https://github.com/adap/flower/pull/483))." -#: ../../source/tutorial-quickstart-ios.rst:156 -#, fuzzy +#: ../../source/ref-changelog.md:1058 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code " -"`_ for this " -"example can be found in :code:`examples/ios`." +"Set minimal Python version to 3.6.1 instead of 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples" -"/quickstart-mxnet`." +"Fixe la version minimale de Python à 3.6.1 au lieu de 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." -#: ../../source/tutorial-quickstart-jax.rst:-1 +#: ../../source/ref-changelog.md:1059 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Jax to train a linear regression model on a scikit-learn dataset." +"Improved `Strategy` docstrings " +"([#470](https://github.com/adap/flower/pull/470))." msgstr "" +"Amélioration des docstrings `Stratégie` " +"([#470](https://github.com/adap/flower/pull/470))." -#: ../../source/tutorial-quickstart-jax.rst:5 -msgid "Quickstart JAX" -msgstr "Démarrage rapide de JAX" +#: ../../source/ref-example-projects.rst:2 +#, fuzzy +msgid "Example projects" +msgstr "Exemples de PyTorch" -#: ../../source/tutorial-quickstart-mxnet.rst:-1 +#: ../../source/ref-example-projects.rst:4 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with MXNet to train a Sequential model on MNIST." +"Flower comes with a number of usage examples. The examples demonstrate " +"how Flower can be used to federate different kinds of existing machine " +"learning pipelines, usually leveraging popular machine learning " +"frameworks such as `PyTorch `_ or `TensorFlow " +"`_." msgstr "" +"Flower est livré avec un certain nombre d'exemples d'utilisation, qui " +"montrent comment Flower peut être utilisé pour fédérer différents types " +"de pipelines d'apprentissage automatique existants, qui s'appuient " +"généralement sur des frameworks d'apprentissage automatique populaires " +"tels que `PyTorch `_ ou `TensorFlow " +"`_." -#: ../../source/tutorial-quickstart-mxnet.rst:5 -msgid "Quickstart MXNet" -msgstr "Démarrage rapide de MXNet" - -#: ../../source/tutorial-quickstart-mxnet.rst:7 +#: ../../source/ref-example-projects.rst:10 +#, fuzzy msgid "" -"MXNet is no longer maintained and has been moved into `Attic " -"`_. As a result, we would " -"encourage you to use other ML frameworks alongside Flower, for example, " -"PyTorch. This tutorial might be removed in future versions of Flower." -msgstr "" +"The following examples are available as standalone projects. Quickstart " +"TensorFlow/Keras ---------------------------" +msgstr "Les exemples suivants sont disponibles sous forme de projets autonomes." -#: ../../source/tutorial-quickstart-mxnet.rst:12 +#: ../../source/ref-example-projects.rst:14 msgid "" -"In this tutorial, we will learn how to train a :code:`Sequential` model " -"on MNIST using Flower and MXNet." +"The TensorFlow/Keras quickstart example shows CIFAR-10 image " +"classification with MobileNetV2:" msgstr "" -"Dans ce tutoriel, nous allons apprendre à former un modèle " -":code:`Sequential` sur MNIST à l'aide de Flower et de MXNet." +"L'exemple de démarrage rapide TensorFlow/Keras montre la classification " +"d'images CIFAR-10 avec MobileNetV2 :" -#: ../../source/tutorial-quickstart-mxnet.rst:14 -#: ../../source/tutorial-quickstart-scikitlearn.rst:12 +#: ../../source/ref-example-projects.rst:17 #, fuzzy msgid "" -"It is recommended to create a virtual environment and run everything " -"within this :doc:`virtualenv `." -msgstr "" -"Il est recommandé de créer un environnement virtuel et de tout exécuter " -"dans ce `virtualenv `_." - -#: ../../source/tutorial-quickstart-mxnet.rst:16 -#: ../../source/tutorial-quickstart-pytorch.rst:17 -#: ../../source/tutorial-quickstart-scikitlearn.rst:14 -msgid "" -"Our example consists of one *server* and two *clients* all having the " -"same model." +"`Quickstart TensorFlow (Code) " +"`_" msgstr "" -"Notre exemple consiste en un *serveur* et deux *clients* ayant tous le " -"même modèle." +"`Quickstart TensorFlow (Code) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:18 -#: ../../source/tutorial-quickstart-scikitlearn.rst:16 -msgid "" -"*Clients* are responsible for generating individual model parameter " -"updates for the model based on their local datasets. These updates are " -"then sent to the *server* which will aggregate them to produce an updated" -" global model. Finally, the *server* sends this improved version of the " -"model back to each *client*. A complete cycle of parameters updates is " -"called a *round*." +#: ../../source/ref-example-projects.rst:18 +#, fuzzy +msgid ":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" -"*Les clients* sont chargés de générer des mises à jour individuelles des " -"paramètres du modèle en fonction de leurs ensembles de données locales. " -"Ces mises à jour sont ensuite envoyées au *serveur* qui les agrège pour " -"produire un modèle global mis à jour. Enfin, le *serveur* renvoie cette " -"version améliorée du modèle à chaque *client*. Un cycle complet de mises " -"à jour des paramètres s'appelle un *round*." +"`Quickstart TensorFlow (Tutorial) `_" -#: ../../source/tutorial-quickstart-mxnet.rst:22 -#: ../../source/tutorial-quickstart-scikitlearn.rst:20 +#: ../../source/ref-example-projects.rst:19 msgid "" -"Now that we have a rough idea of what is going on, let's get started. We " -"first need to install Flower. You can do this by running:" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" -"Maintenant que nous avons une idée approximative de ce qui se passe, " -"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " -"lançant :" +"`Quickstart TensorFlow (Blog Post) `_" -#: ../../source/tutorial-quickstart-mxnet.rst:28 -msgid "Since we want to use MXNet, let's go ahead and install it:" -msgstr "Puisque nous voulons utiliser MXNet, allons-y et installons-le :" +#: ../../source/ref-example-projects.rst:23 +#: ../../source/tutorial-quickstart-pytorch.rst:5 +msgid "Quickstart PyTorch" +msgstr "Démarrage rapide de PyTorch" -#: ../../source/tutorial-quickstart-mxnet.rst:38 +#: ../../source/ref-example-projects.rst:25 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on MXNet´s `Hand-written " -"Digit Recognition tutorial " -"`_." +"The PyTorch quickstart example shows CIFAR-10 image classification with a" +" simple Convolutional Neural Network:" msgstr "" -"Maintenant que toutes nos dépendances sont installées, lançons une " -"formation distribuée simple avec deux clients et un serveur. Notre " -"procédure de formation et l'architecture du réseau sont basées sur le " -"tutoriel de reconnaissance de chiffres écrits à la main du MXNet " -"`_." +"L'exemple de démarrage rapide PyTorch montre la classification d'images " +"CIFAR-10 avec un simple réseau neuronal convolutif :" -#: ../../source/tutorial-quickstart-mxnet.rst:40 +#: ../../source/ref-example-projects.rst:28 +#, fuzzy msgid "" -"In a file called :code:`client.py`, import Flower and MXNet related " -"packages:" +"`Quickstart PyTorch (Code) " +"`_" msgstr "" -"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " -"liés au MXNet :" - -#: ../../source/tutorial-quickstart-mxnet.rst:55 -msgid "In addition, define the device allocation in MXNet with:" -msgstr "En outre, définis l'attribution de l'appareil dans MXNet avec :" +"`Quickstart PyTorch (Code) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:61 -msgid "" -"We use MXNet to load MNIST, a popular image classification dataset of " -"handwritten digits for machine learning. The MXNet utility " -":code:`mx.test_utils.get_mnist()` downloads the training and test data." +#: ../../source/ref-example-projects.rst:29 +#, fuzzy +msgid ":doc:`Quickstart PyTorch (Tutorial) `" msgstr "" -"Nous utilisons MXNet pour charger MNIST, un ensemble de données de " -"classification d'images populaire de chiffres manuscrits pour " -"l'apprentissage automatique. L'utilitaire MXNet " -":code:`mx.test_utils.get_mnist()` télécharge les données d'entraînement " -"et de test." +"`Quickstart PyTorch (Tutorial) `_" + +#: ../../source/ref-example-projects.rst:33 +msgid "PyTorch: From Centralized To Federated" +msgstr "PyTorch : De la centralisation à la fédération" -#: ../../source/tutorial-quickstart-mxnet.rst:75 +#: ../../source/ref-example-projects.rst:35 msgid "" -"Define the training and loss with MXNet. We train the model by looping " -"over the dataset, measure the corresponding loss, and optimize it." +"This example shows how a regular PyTorch project can be federated using " +"Flower:" msgstr "" -"Définis l'entraînement et la perte avec MXNet. Nous entraînons le modèle " -"en parcourant en boucle l'ensemble des données, nous mesurons la perte " -"correspondante et nous l'optimisons." +"Cet exemple montre comment un projet PyTorch ordinaire peut être fédéré à" +" l'aide de Flower :" -#: ../../source/tutorial-quickstart-mxnet.rst:113 +#: ../../source/ref-example-projects.rst:37 +#, fuzzy msgid "" -"Next, we define the validation of our machine learning model. We loop " -"over the test set and measure both loss and accuracy on the test set." +"`PyTorch: From Centralized To Federated (Code) " +"`_" msgstr "" -"Ensuite, nous définissons la validation de notre modèle d'apprentissage " -"automatique. Nous effectuons une boucle sur l'ensemble de test et " -"mesurons à la fois la perte et la précision sur l'ensemble de test." +"`PyTorch : De la centralisation à la fédération (Code) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:137 +#: ../../source/ref-example-projects.rst:38 +#, fuzzy msgid "" -"After defining the training and testing of a MXNet machine learning " -"model, we use these functions to implement a Flower client." +":doc:`PyTorch: From Centralized To Federated (Tutorial) `" msgstr "" -"Après avoir défini la formation et le test d'un modèle d'apprentissage " -"automatique MXNet, nous utilisons ces fonctions pour mettre en œuvre un " -"client Flower." +"`PyTorch : De la centralisation à la fédération (Tutoriel) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:139 -msgid "Our Flower clients will use a simple :code:`Sequential` model:" -msgstr "Nos clients Flower utiliseront un modèle simple :code:`Sequential` :" +#: ../../source/ref-example-projects.rst:42 +msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" +msgstr "Apprentissage fédéré sur Raspberry Pi et Nvidia Jetson" -#: ../../source/tutorial-quickstart-mxnet.rst:158 +#: ../../source/ref-example-projects.rst:44 msgid "" -"After loading the dataset with :code:`load_data()` we perform one forward" -" propagation to initialize the model and model parameters with " -":code:`model(init)`. Next, we implement a Flower client." +"This example shows how Flower can be used to build a federated learning " +"system that run across Raspberry Pi and Nvidia Jetson:" msgstr "" -"Après avoir chargé l'ensemble de données avec :code:`load_data()`, nous " -"effectuons une propagation vers l'avant pour initialiser le modèle et les" -" paramètres du modèle avec :code:`model(init)`. Ensuite, nous " -"implémentons un client Flower." +"Cet exemple montre comment Flower peut être utilisé pour construire un " +"système d'apprentissage fédéré qui fonctionne sur Raspberry Pi et Nvidia " +"Jetson :" -#: ../../source/tutorial-quickstart-mxnet.rst:160 -#: ../../source/tutorial-quickstart-pytorch.rst:144 -#: ../../source/tutorial-quickstart-tensorflow.rst:54 +#: ../../source/ref-example-projects.rst:46 +#, fuzzy msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to train the neural network we defined earlier)." +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " +"`_" msgstr "" -"Le serveur Flower interagit avec les clients par le biais d'une interface" -" appelée :code:`Client`. Lorsque le serveur sélectionne un client " -"particulier pour la formation, il envoie des instructions de formation " -"sur le réseau. Le client reçoit ces instructions et appelle l'une des " -"méthodes :code:`Client` pour exécuter ton code (c'est-à-dire pour former " -"le réseau neuronal que nous avons défini plus tôt)." +"`L'apprentissage fédéré sur Raspberry Pi et Nvidia Jetson (Code) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:166 +#: ../../source/ref-example-projects.rst:47 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses MXNet. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " +"`_" msgstr "" -"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " -"facilite l'implémentation de l'interface :code:`Client` lorsque ta charge" -" de travail utilise MXNet. L'implémentation de :code:`NumPyClient` " -"signifie généralement la définition des méthodes suivantes " -"(:code:`set_parameters` est cependant facultatif) :" - -#: ../../source/tutorial-quickstart-mxnet.rst:172 -#: ../../source/tutorial-quickstart-pytorch.rst:156 -#: ../../source/tutorial-quickstart-scikitlearn.rst:109 -msgid "return the model weight as a list of NumPy ndarrays" -msgstr "renvoie le poids du modèle sous la forme d'une liste de ndarrays NumPy" - -#: ../../source/tutorial-quickstart-mxnet.rst:173 -#: ../../source/tutorial-quickstart-pytorch.rst:157 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 -msgid ":code:`set_parameters` (optional)" -msgstr ":code:`set_parameters` (optionnel)" +"`L'apprentissage fédéré sur Raspberry Pi et Nvidia Jetson (Blog Post) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:174 -#: ../../source/tutorial-quickstart-pytorch.rst:158 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 +#: ../../source/ref-faq.rst:4 msgid "" -"update the local model weights with the parameters received from the " -"server" +"This page collects answers to commonly asked questions about Federated " +"Learning with Flower." msgstr "" -"mettre à jour les poids du modèle local avec les paramètres reçus du " -"serveur" - -#: ../../source/tutorial-quickstart-mxnet.rst:176 -#: ../../source/tutorial-quickstart-pytorch.rst:160 -#: ../../source/tutorial-quickstart-scikitlearn.rst:114 -msgid "set the local model weights" -msgstr "fixe les poids du modèle local" - -#: ../../source/tutorial-quickstart-mxnet.rst:177 -#: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 -msgid "train the local model" -msgstr "entraîne le modèle local" - -#: ../../source/tutorial-quickstart-mxnet.rst:178 -#: ../../source/tutorial-quickstart-pytorch.rst:162 -#: ../../source/tutorial-quickstart-scikitlearn.rst:116 -msgid "receive the updated local model weights" -msgstr "recevoir les poids du modèle local mis à jour" - -#: ../../source/tutorial-quickstart-mxnet.rst:180 -#: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 -msgid "test the local model" -msgstr "teste le modèle local" +"Cette page rassemble les réponses aux questions les plus fréquemment " +"posées sur l'apprentissage fédéré avec Flower." -#: ../../source/tutorial-quickstart-mxnet.rst:182 -msgid "They can be implemented in the following way:" -msgstr "Ils peuvent être mis en œuvre de la manière suivante :" +#: ../../source/ref-faq.rst +#, fuzzy +msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" +msgstr "" +":fa:`eye,mr-1` Flower peut-il fonctionner sur les ordinateurs portables " +"Juptyter / Google Colab ?" -#: ../../source/tutorial-quickstart-mxnet.rst:212 +#: ../../source/ref-faq.rst:8 msgid "" -"We can now create an instance of our class :code:`MNISTClient` and add " -"one line to actually run this client:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to" +" make it work even better on Colab. Here's a quickstart example:" msgstr "" -"Nous pouvons maintenant créer une instance de notre classe " -":code:`MNISTClient` et ajouter une ligne pour exécuter ce client :" +"Oui, c'est possible ! Flower est même livré avec quelques optimisations " +"pour qu'il fonctionne encore mieux sur Colab. Voici un exemple de " +"démarrage rapide :" -#: ../../source/tutorial-quickstart-mxnet.rst:219 +#: ../../source/ref-faq.rst:10 #, fuzzy msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()` or " -":code:`fl.client.start_numpy_client()`. The string " -":code:`\"0.0.0.0:8080\"` tells the client which server to connect to. In " -"our case we can run the server and the client on the same machine, " -"therefore we use :code:`\"0.0.0.0:8080\"`. If we run a truly federated " -"workload with the server and clients running on different machines, all " -"that needs to change is the :code:`server_address` we pass to the client." +"`Flower simulation PyTorch " +"`_" msgstr "" -"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" -" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " -"chaîne :code:`\"0.0.0:8080\"` indique au client à quel serveur se " -"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " -"sur la même machine, c'est pourquoi nous utilisons " -":code:`\"0.0.0:8080\"`. Si nous exécutons une charge de travail " -"véritablement fédérée avec le serveur et les clients s'exécutant sur des " -"machines différentes, tout ce qui doit changer est :code:`server_address`" -" que nous transmettons au client." +"`Flower Quickstart (TensorFlow/Keras) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:241 +#: ../../source/ref-faq.rst:11 +#, fuzzy msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We therefore have to start the server first:" +"`Flower simulation TensorFlow/Keras " +"`_" msgstr "" -"Le client et le serveur étant prêts, nous pouvons maintenant tout " -"exécuter et voir l'apprentissage fédéré en action. Les systèmes " -"d'apprentissage fédéré ont généralement un serveur et plusieurs clients. " -"Nous devons donc commencer par démarrer le serveur :" +"`Flower Quickstart (TensorFlow/Keras) " +"`_" -#: ../../source/tutorial-quickstart-mxnet.rst:249 -#: ../../source/tutorial-quickstart-pytorch.rst:226 -#: ../../source/tutorial-quickstart-scikitlearn.rst:224 -#: ../../source/tutorial-quickstart-tensorflow.rst:122 -#: ../../source/tutorial-quickstart-xgboost.rst:533 -msgid "" -"Once the server is running we can start the clients in different " -"terminals. Open a new terminal and start the first client:" +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" msgstr "" -"Une fois que le serveur fonctionne, nous pouvons démarrer les clients " -"dans différents terminaux. Ouvre un nouveau terminal et démarre le " -"premier client :" - -#: ../../source/tutorial-quickstart-mxnet.rst:256 -#: ../../source/tutorial-quickstart-pytorch.rst:233 -#: ../../source/tutorial-quickstart-scikitlearn.rst:231 -#: ../../source/tutorial-quickstart-tensorflow.rst:129 -#: ../../source/tutorial-quickstart-xgboost.rst:540 -msgid "Open another terminal and start the second client:" -msgstr "Ouvre un autre terminal et démarre le deuxième client :" +":fa:`eye,mr-1` Comment puis-je faire fonctionner l'apprentissage fédéré " +"sur un Raspberry Pi ?" -#: ../../source/tutorial-quickstart-mxnet.rst:262 -#: ../../source/tutorial-quickstart-pytorch.rst:239 -#: ../../source/tutorial-quickstart-scikitlearn.rst:237 -#: ../../source/tutorial-quickstart-xgboost.rst:546 +#: ../../source/ref-faq.rst:15 +#, fuzzy msgid "" -"Each client will have its own dataset. You should now see how the " -"training does in the very first terminal (the one that started the " -"server):" +"Find the `blog post about federated learning on embedded device here " +"`_" +" and the corresponding `GitHub code example " +"`_." msgstr "" -"Chaque client aura son propre ensemble de données. Tu devrais maintenant " -"voir comment la formation se déroule dans le tout premier terminal (celui" -" qui a démarré le serveur) :" +"Trouve le `blog post about federated learning on embedded device ici " +"`_" +" et l'exemple de code GitHub correspondant " +"`_." + +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgstr "" +":fa:`eye,mr-1` Est-ce que Flower prend en charge l'apprentissage fédéré " +"sur les appareils Android ?" -#: ../../source/tutorial-quickstart-mxnet.rst:294 +#: ../../source/ref-faq.rst:19 #, fuzzy msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-mxnet`." +"Yes, it does. Please take a look at our `blog post " +"`_ or check out the code examples:" msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples" -"/quickstart-mxnet`." +"Oui. Jetez un coup d'œil à notre `blog post " +"`_ ou consultez l'`exemple de code Android sur GitHub " +"`_." -#: ../../source/tutorial-quickstart-pandas.rst:-1 +#: ../../source/ref-faq.rst:21 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Pandas to perform Federated Analytics." +"`Android Kotlin example `_" msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:5 -msgid "Quickstart Pandas" -msgstr "Démarrage rapide des Pandas" +#: ../../source/ref-faq.rst:22 +msgid "`Android Java example `_" +msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:10 -msgid "Let's build a federated analytics system using Pandas and Flower!" -msgstr "Construisons un système d'analyse fédéré à l'aide de Pandas et de Flower !" +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` Can I combine federated learning with blockchain?" +msgstr "" +":fa:`eye,mr-1` Puis-je combiner l'apprentissage fédéré avec la blockchain" +" ?" -#: ../../source/tutorial-quickstart-pandas.rst:12 -#, fuzzy +#: ../../source/ref-faq.rst:26 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Yes, of course. A list of available examples using Flower within a " +"blockchain environment is available here:" msgstr "" -"Réfère-toi à l'exemple de code complet " -"`_ " -"pour en savoir plus." +"Oui, bien sûr, une liste d'exemples disponibles utilisant Flower dans un " +"environnement blockchain est disponible ici :" -#: ../../source/tutorial-quickstart-pytorch.rst:-1 +#: ../../source/ref-faq.rst:28 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch to train a CNN model on MNIST." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" +"`Flower meets Nevermined GitHub Repository `_." -#: ../../source/tutorial-quickstart-pytorch.rst:13 +#: ../../source/ref-faq.rst:29 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural " -"Network on CIFAR10 using Flower and PyTorch." +"`Flower meets Nevermined YouTube video " +"`_." msgstr "" -"Dans ce tutoriel, nous allons apprendre à entraîner un réseau neuronal " -"convolutif sur CIFAR10 à l'aide de Flower et PyTorch." +"`Flower rencontre Nevermined vidéo YouTube " +"`_." -#: ../../source/tutorial-quickstart-pytorch.rst:15 -#: ../../source/tutorial-quickstart-xgboost.rst:39 +#: ../../source/ref-faq.rst:30 #, fuzzy msgid "" -"First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"`Flower meets KOSMoS `_." msgstr "" -"Tout d'abord, il est recommandé de créer un environnement virtuel et de " -"tout exécuter au sein d'un `virtualenv `_." +"`Flower rencontre KOSMoS `_." -#: ../../source/tutorial-quickstart-pytorch.rst:19 +#: ../../source/ref-faq.rst:31 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"`Flower meets Talan blog post `_ ." msgstr "" -"*Les clients* sont chargés de générer des mises à jour de poids " -"individuelles pour le modèle en fonction de leurs ensembles de données " -"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " -"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " -"cette version améliorée du modèle à chaque *client*. Un cycle complet de " -"mises à jour de poids s'appelle un *round*." +"`Flower meets Talan blog post `_ ." -#: ../../source/tutorial-quickstart-pytorch.rst:23 +#: ../../source/ref-faq.rst:32 msgid "" -"Now that we have a rough idea of what is going on, let's get started. We " -"first need to install Flower. You can do this by running :" +"`Flower meets Talan GitHub Repository " +"`_ ." msgstr "" -"Maintenant que nous avons une idée générale de ce qui se passe, " -"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " -"exécutant :" +"`Flower rencontre Talan Dépôt GitHub " +"`_ ." -#: ../../source/tutorial-quickstart-pytorch.rst:29 -msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go " -"ahead and install PyTorch and the **torchvision** library:" -msgstr "" -"Puisque nous voulons utiliser PyTorch pour résoudre une tâche de vision " -"par ordinateur, allons-y et installons PyTorch et la bibliothèque " -"**torchvision** :" +#: ../../source/ref-telemetry.md:1 +msgid "Telemetry" +msgstr "Télémétrie" -#: ../../source/tutorial-quickstart-pytorch.rst:39 +#: ../../source/ref-telemetry.md:3 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on PyTorch's `Deep Learning " -"with PyTorch " -"`_." +"The Flower open-source project collects **anonymous** usage metrics to " +"make well-informed decisions to improve Flower. Doing this enables the " +"Flower team to understand how Flower is used and what challenges users " +"might face." msgstr "" -"Maintenant que nous avons installé toutes nos dépendances, lançons une " -"formation distribuée simple avec deux clients et un serveur. Notre " -"procédure de formation et l'architecture de notre réseau sont basées sur " -"`Deep Learning with PyTorch " -"`_ de" -" PyTorch." +"Le projet open-source Flower recueille des mesures d'utilisation " +"**anonymes** afin de prendre des décisions éclairées pour améliorer " +"Flower. Cela permet à l'équipe de Flower de comprendre comment Flower est" +" utilisé et quels sont les défis auxquels les utilisateurs peuvent être " +"confrontés." -#: ../../source/tutorial-quickstart-pytorch.rst:41 +#: ../../source/ref-telemetry.md:5 msgid "" -"In a file called :code:`client.py`, import Flower and PyTorch related " -"packages:" +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users that do not want to share anonymous usage metrics." msgstr "" -"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " -"liés à PyTorch :" +"**Flower est un cadre convivial pour l'IA collaborative et la science des" +" données.** En restant fidèle à cette déclaration, Flower permet de " +"désactiver facilement la télémétrie pour les utilisateurs qui ne " +"souhaitent pas partager des mesures d'utilisation anonymes." -#: ../../source/tutorial-quickstart-pytorch.rst:56 -msgid "In addition, we define the device allocation in PyTorch with:" -msgstr "En outre, nous définissons l'attribution des appareils dans PyTorch avec :" +#: ../../source/ref-telemetry.md:7 +msgid "Principles" +msgstr "Principes" -#: ../../source/tutorial-quickstart-pytorch.rst:62 -msgid "" -"We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " -"the training and test data that are then normalized." +#: ../../source/ref-telemetry.md:9 +msgid "We follow strong principles guarding anonymous usage metrics collection:" msgstr "" -"Nous utilisons PyTorch pour charger CIFAR10, un ensemble de données de " -"classification d'images colorées populaire pour l'apprentissage " -"automatique. Le :code:`DataLoader()` de PyTorch télécharge les données " -"d'entraînement et de test qui sont ensuite normalisées." +"Nous suivons des principes stricts concernant la collecte de données " +"anonymes sur l'utilisation :" -#: ../../source/tutorial-quickstart-pytorch.rst:78 +#: ../../source/ref-telemetry.md:11 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset " -"is done by looping over the dataset, measure the corresponding loss and " -"optimize it." +"**Optional:** You will always be able to disable telemetry; read on to " +"learn “[How to opt-out](#how-to-opt-out)”." msgstr "" -"Définis la perte et l'optimiseur avec PyTorch L'entraînement de " -"l'ensemble de données se fait en bouclant sur l'ensemble de données, en " -"mesurant la perte correspondante et en l'optimisant." +"**Optionnel:** Tu pourras toujours désactiver la télémétrie ; lis la " +"suite pour apprendre \"[Comment se désengager](#how-to-opt-out)\"." -#: ../../source/tutorial-quickstart-pytorch.rst:94 +#: ../../source/ref-telemetry.md:12 msgid "" -"Define then the validation of the machine learning network. We loop over" -" the test set and measure the loss and accuracy of the test set." +"**Anonymous:** The reported usage metrics are anonymous and do not " +"contain any personally identifiable information (PII). See “[Collected " +"metrics](#collected-metrics)” to understand what metrics are being " +"reported." msgstr "" -"Définis ensuite la validation du réseau d'apprentissage automatique. Nous" -" passons en boucle sur l'ensemble de test et mesurons la perte et la " -"précision de l'ensemble de test." +"**Anonyme:** Les mesures d'utilisation rapportées sont anonymes et ne " +"contiennent aucune information personnelle identifiable (PII). Voir " +"\"[Collected metrics](#collected-metrics)\" pour comprendre quelles " +"mesures sont rapportées." -#: ../../source/tutorial-quickstart-pytorch.rst:113 +#: ../../source/ref-telemetry.md:13 msgid "" -"After defining the training and testing of a PyTorch machine learning " -"model, we use the functions for the Flower clients." +"**Transparent:** You can easily inspect what anonymous metrics are being " +"reported; see the section “[How to inspect what is being reported](#how-" +"to-inspect-what-is-being-reported)”" msgstr "" -"Après avoir défini l'entraînement et le test d'un modèle d'apprentissage " -"automatique PyTorch, nous utilisons les fonctions pour les clients " -"Flower." +"**Transparent:** Tu peux facilement inspecter les métriques anonymes qui " +"sont rapportées ; voir la section \"[Comment inspecter ce qui est " +"rapporté](#how-to-inspect-what-is-being-reported)\"" -#: ../../source/tutorial-quickstart-pytorch.rst:115 +#: ../../source/ref-telemetry.md:14 +#, fuzzy msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " -"Minute Blitz':" +"**Open for feedback:** You can always reach out to us if you have " +"feedback; see the section “[How to contact us](#how-to-contact-us)” for " +"details." msgstr "" -"Les clients de Flower utiliseront un CNN simple adapté de \"PyTorch : A " -"60 Minute Blitz\" :" +"**Ouvert pour les commentaires:** Tu peux toujours nous contacter si tu " +"as des commentaires ; voir la section \"[Comment nous contacter ](#how-" +"to-contact-us)\" pour plus de détails." -#: ../../source/tutorial-quickstart-pytorch.rst:142 +#: ../../source/ref-telemetry.md:16 +msgid "How to opt-out" +msgstr "Comment se désinscrire" + +#: ../../source/ref-telemetry.md:18 msgid "" -"After loading the data set with :code:`load_data()` we define the Flower " -"interface." +"When Flower starts, it will check for an environment variable called " +"`FLWR_TELEMETRY_ENABLED`. Telemetry can easily be disabled by setting " +"`FLWR_TELEMETRY_ENABLED=0`. Assuming you are starting a Flower server or " +"client, simply do so by prepending your command as in:" msgstr "" -"Après avoir chargé l'ensemble des données avec :code:`load_data()`, nous " -"définissons l'interface Flower." +"Lorsque Flower démarre, il vérifie la présence d'une variable " +"d'environnement appelée `FLWR_TELEMETRY_ENABLED`. La télémétrie peut " +"facilement être désactivée en réglant `FLWR_TELEMETRY_ENABLED=0`. En " +"supposant que tu démarres un serveur ou un client Flower, fais-le " +"simplement en faisant précéder ta commande de la façon suivante :" -#: ../../source/tutorial-quickstart-pytorch.rst:150 +#: ../../source/ref-telemetry.md:24 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," +" `.bashrc` (or whatever configuration file applies to your environment) " +"to disable Flower telemetry permanently." msgstr "" -"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " -"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" -" de travail utilise PyTorch. Mettre en œuvre :code:`NumPyClient` signifie" -" généralement définir les méthodes suivantes (:code:`set_parameters` est " -"cependant facultatif) :" +"Tu peux aussi exporter `FLWR_TELEMETRY_ENABLED=0` dans, par exemple, " +"`.bashrc` (ou tout autre fichier de configuration qui s'applique à ton " +"environnement) pour désactiver la télémétrie de la fleur de façon " +"permanente." -#: ../../source/tutorial-quickstart-pytorch.rst:166 -msgid "which can be implemented in the following way:" -msgstr "qui peut être mis en œuvre de la manière suivante :" +#: ../../source/ref-telemetry.md:26 +msgid "Collected metrics" +msgstr "Mesures collectées" -#: ../../source/tutorial-quickstart-pytorch.rst:189 -#: ../../source/tutorial-quickstart-tensorflow.rst:82 +#: ../../source/ref-telemetry.md:28 +msgid "Flower telemetry collects the following metrics:" +msgstr "La télémétrie des fleurs recueille les métriques suivantes :" + +#: ../../source/ref-telemetry.md:30 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add " -"one line to actually run this client:" +"**Flower version.** Understand which versions of Flower are currently " +"being used. This helps us to decide whether we should invest effort into " +"releasing a patch version for an older version of Flower or instead use " +"the bandwidth to build new features." msgstr "" -"Nous pouvons maintenant créer une instance de notre classe " -":code:`CifarClient` et ajouter une ligne pour exécuter ce client :" +"**Cela nous aide à décider si nous devons investir des efforts dans la " +"publication d'une version corrective pour une version plus ancienne de " +"Flower ou si nous devons plutôt utiliser la bande passante pour " +"développer de nouvelles fonctionnalités." -#: ../../source/tutorial-quickstart-pytorch.rst:196 -#: ../../source/tutorial-quickstart-tensorflow.rst:90 -#, fuzzy +#: ../../source/ref-telemetry.md:32 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " -"the client which server to connect to. In our case we can run the server " -"and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"**Operating system.** Enables us to answer questions such as: *Should we " +"create more guides for Linux, macOS, or Windows?*" msgstr "" -"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" -" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " -"chaîne :code:`\"[: :]:8080\"` indique au client à quel serveur se " -"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " -"sur la même machine, c'est pourquoi nous utilisons :code:`\"[: " -":]:8080\"`. Si nous exécutons une charge de travail véritablement fédérée" -" avec le serveur et les clients fonctionnant sur des machines " -"différentes, tout ce qui doit changer est l'adresse " -":code:`server_address` vers laquelle nous dirigeons le client." +"**Système d'exploitation.** Nous permet de répondre à des questions " +"telles que : *Faudrait-il créer plus de guides pour Linux, macOS ou " +"Windows ?" -#: ../../source/tutorial-quickstart-pytorch.rst:271 -#, fuzzy +#: ../../source/ref-telemetry.md:34 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-pytorch`." +"**Python version.** Knowing the Python version helps us, for example, to " +"decide whether we should invest effort into supporting old versions of " +"Python or stop supporting them and start taking advantage of new Python " +"features." msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples" -"/quickstart-pytorch`." +"**Version de Python.** Connaître la version de Python nous aide, par " +"exemple, à décider si nous devons investir des efforts dans la prise en " +"charge des anciennes versions de Python ou cesser de les prendre en " +"charge et commencer à tirer parti des nouvelles fonctionnalités de " +"Python." -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 +#: ../../source/ref-telemetry.md:36 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch Lightning to train an Auto Encoder model on MNIST." +"**Hardware properties.** Understanding the hardware environment that " +"Flower is being used in helps to decide whether we should, for example, " +"put more effort into supporting low-resource environments." msgstr "" +"**Comprendre l'environnement matériel dans lequel Flower est utilisé " +"permet de décider si nous devrions, par exemple, faire plus d'efforts " +"pour prendre en charge les environnements à faibles ressources." -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 -msgid "Quickstart PyTorch Lightning" -msgstr "Démarrage rapide de PyTorch Lightning" - -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 -#, fuzzy +#: ../../source/ref-telemetry.md:38 msgid "" -"Let's build a horizontal federated learning system using PyTorch " -"Lightning and Flower!" +"**Execution mode.** Knowing what execution mode Flower starts in enables " +"us to understand how heavily certain features are being used and better " +"prioritize based on that." msgstr "" -"Construisons un système d'apprentissage fédéré en utilisant PyTorch " -"Lightning et Flower !" +"**Mode d'exécution** Connaître le mode d'exécution dans lequel Flower " +"démarre nous permet de comprendre à quel point certaines fonctionnalités " +"sont utilisées et de mieux établir les priorités en fonction de cela." -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 -#, fuzzy +#: ../../source/ref-telemetry.md:40 msgid "" -"Please refer to the `full code example " -"`_ to learn more." +"**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " +"time a Flower workload starts. This allows us to understand which device " +"types not only start Flower workloads but also successfully complete " +"them." msgstr "" -"Réfère-toi à l'exemple de code complet " -"`_ pour en savoir plus." +"**Cluster.** La télémétrie Flower attribue un ID de cluster en mémoire " +"aléatoire à chaque fois qu'une charge de travail Flower démarre. Cela " +"nous permet de comprendre quels types d'appareils non seulement démarrent" +" les charges de travail Flower, mais aussi les terminent avec succès." -#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 +#: ../../source/ref-telemetry.md:42 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with scikit-learn to train a linear regression model." +"**Source.** Flower telemetry tries to store a random source ID in " +"`~/.flwr/source` the first time a telemetry event is generated. The " +"source ID is important to identify whether an issue is recurring or " +"whether an issue is triggered by multiple clusters running concurrently " +"(which often happens in simulation). For example, if a device runs " +"multiple workloads at the same time, and this results in an issue, then, " +"in order to reproduce the issue, multiple workloads must be started at " +"the same time." msgstr "" +"**Source.** La télémétrie de Flower essaie de stocker un ID de source " +"aléatoire dans `~/.flwr/source` la première fois qu'un événement de " +"télémétrie est généré. L'ID de source est important pour identifier si un" +" problème est récurrent ou si un problème est déclenché par plusieurs " +"clusters fonctionnant simultanément (ce qui arrive souvent en " +"simulation). Par exemple, si un périphérique exécute plusieurs charges de" +" travail en même temps, et que cela entraîne un problème, alors, afin de " +"reproduire le problème, plusieurs charges de travail doivent être " +"démarrées en même temps." -#: ../../source/tutorial-quickstart-scikitlearn.rst:5 -msgid "Quickstart scikit-learn" -msgstr "Démarrage rapide de scikit-learn" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:10 +#: ../../source/ref-telemetry.md:44 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic " -"Regression` model on MNIST using Flower and scikit-learn." +"You may delete the source ID at any time. If you wish for all events " +"logged under a specific source ID to be deleted, you can send a deletion " +"request mentioning the source ID to `telemetry@flower.ai`. All events " +"related to that source ID will then be permanently deleted." msgstr "" -"Dans ce tutoriel, nous allons apprendre à former un :code:`modèle de " -"régression logistique` sur MNIST en utilisant Flower et scikit-learn." - -#: ../../source/tutorial-quickstart-scikitlearn.rst:26 -#, fuzzy -msgid "Since we want to use scikit-learn, let's go ahead and install it:" -msgstr "Puisque nous voulons utiliser scikt-learn, allons-y et installons-le :" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:32 -msgid "Or simply install all dependencies using Poetry:" -msgstr "Ou installe simplement toutes les dépendances à l'aide de Poetry :" +"Tu peux supprimer l'identifiant de la source à tout moment. Si tu " +"souhaites que tous les événements enregistrés sous un identifiant de " +"source spécifique soient supprimés, tu peux envoyer une demande de " +"suppression mentionnant l'identifiant de source à `telemetry@flower.ai`. " +"Tous les événements liés à cet identifiant de source seront alors " +"définitivement supprimés." -#: ../../source/tutorial-quickstart-scikitlearn.rst:42 +#: ../../source/ref-telemetry.md:46 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that" -" we need for our federated learning setup within :code:`utils.py`. The " -":code:`utils.py` contains different functions defining all the machine " -"learning basics:" -msgstr "" -"Maintenant que toutes nos dépendances sont installées, exécutons une " -"formation distribuée simple avec deux clients et un serveur. Cependant, " -"avant de configurer le client et le serveur, nous allons définir toutes " -"les fonctionnalités dont nous avons besoin pour notre configuration " -"d'apprentissage fédéré dans :code:`utils.py`. Le :code:`utils.py` " -"contient différentes fonctions définissant toutes les bases de " -"l'apprentissage automatique :" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:45 -msgid ":code:`get_model_parameters()`" -msgstr ":code:`get_model_parameters()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:46 -msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" +"We will not collect any personally identifiable information. If you think" +" any of the metrics collected could be misused in any way, please [get in" +" touch with us](#how-to-contact-us). We will update this page to reflect " +"any changes to the metrics collected and publish changes in the " +"changelog." msgstr "" -"Renvoie les paramètres d'un modèle de régression logistique " -":code:`sklearn`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:47 -msgid ":code:`set_model_params()`" -msgstr ":code:`set_model_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:48 -msgid "Sets the parameters of a :code:`sklean` LogisticRegression model" -msgstr "Définit les paramètres d'un modèle de régression logistique :code:`sklean`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:49 -msgid ":code:`set_initial_params()`" -msgstr ":code:`set_initial_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:50 -msgid "Initializes the model parameters that the Flower server will ask for" -msgstr "Initialise les paramètres du modèle que le serveur de Flower demandera" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:51 -msgid ":code:`load_mnist()`" -msgstr ":code:`load_mnist()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:52 -msgid "Loads the MNIST dataset using OpenML" -msgstr "Charge l'ensemble de données MNIST à l'aide d'OpenML" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:53 -msgid ":code:`shuffle()`" -msgstr ":code:`shuffle()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:54 -msgid "Shuffles data and its label" -msgstr "Mélange les données et leur étiquette" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid ":code:`partition()`" -msgstr ":code:`partition()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid "Splits datasets into a number of partitions" -msgstr "Divise les ensembles de données en un certain nombre de partitions" +"Nous ne collecterons aucune information personnelle identifiable. Si tu " +"penses que l'une des métriques collectées pourrait être utilisée à " +"mauvais escient de quelque manière que ce soit, merci de [nous " +"contacter](#commentnouscontacter). Nous mettrons à jour cette page pour " +"refléter toute modification des métriques collectées et nous publierons " +"les changements dans le journal des modifications (changelog)." -#: ../../source/tutorial-quickstart-scikitlearn.rst:58 +#: ../../source/ref-telemetry.md:48 msgid "" -"Please check out :code:`utils.py` `here " -"`_ for more details. The pre-defined functions are used in" -" the :code:`client.py` and imported. The :code:`client.py` also requires " -"to import several packages such as Flower and scikit-learn:" +"If you think other metrics would be helpful for us to better guide our " +"decisions, please let us know! We will carefully review them; if we are " +"confident that they do not compromise user privacy, we may add them." msgstr "" -"Tu peux consulter :code:`utils.py` `ici " -"`_ pour plus de détails. Les fonctions prédéfinies sont " -"utilisées dans :code:`client.py` et importées. :code:`client.py` " -"nécessite également d'importer plusieurs paquets tels que Flower et " -"scikit-learn :" +"Si tu penses que d'autres mesures nous seraient utiles pour mieux " +"orienter nos décisions, fais-le nous savoir ! Nous les examinerons " +"attentivement ; si nous sommes convaincus qu'elles ne compromettent pas " +"la vie privée des utilisateurs, nous pourrons les ajouter." -#: ../../source/tutorial-quickstart-scikitlearn.rst:73 -#, fuzzy +#: ../../source/ref-telemetry.md:50 +msgid "How to inspect what is being reported" +msgstr "Comment inspecter ce qui est rapporté" + +#: ../../source/ref-telemetry.md:52 msgid "" -"We load the MNIST dataset from `OpenML " -"`_, a popular " -"image classification dataset of handwritten digits for machine learning. " -"The utility :code:`utils.load_mnist()` downloads the training and test " -"data. The training set is split afterwards into 10 partitions with " -":code:`utils.partition()`." +"We wanted to make it very easy for you to inspect what anonymous usage " +"metrics are reported. You can view all the reported telemetry information" +" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " +"is disabled by default. You may use logging independently from " +"`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " +"without sending any metrics." msgstr "" -"Nous chargeons l'ensemble de données MNIST de `OpenML " -"`_, un ensemble de données de " -"classification d'images populaires de chiffres manuscrits pour " -"l'apprentissage automatique. L'utilitaire :code:`utils.load_mnist()` " -"télécharge les données d'entraînement et de test. L'ensemble " -"d'entraînement est ensuite divisé en 10 partitions avec " -":code:`utils.partition()`." +"Nous avons voulu qu'il soit très facile pour toi d'inspecter les mesures " +"d'utilisation anonymes qui sont rapportées. Tu peux voir toutes les " +"informations de télémétrie rapportées en définissant la variable " +"d'environnement `FLWR_TELEMETRY_LOGGING=1`. La journalisation est " +"désactivée par défaut. Tu peux utiliser la journalisation indépendamment " +"de `FLWR_TELEMETRY_ENABLED` afin d'inspecter la fonction de télémétrie " +"sans envoyer de mesures." -#: ../../source/tutorial-quickstart-scikitlearn.rst:85 +#: ../../source/ref-telemetry.md:58 msgid "" -"Next, the logistic regression model is defined and initialized with " -":code:`utils.set_initial_params()`." +"The inspect Flower telemetry without sending any anonymous usage metrics," +" use both environment variables:" msgstr "" -"Ensuite, le modèle de régression logistique est défini et initialisé avec" -" :code:`utils.set_initial_params()`." +"L'inspecteur Flower telemetry sans envoyer de métriques d'utilisation " +"anonymes, utilise les deux variables d'environnement :" + +#: ../../source/ref-telemetry.md:64 +msgid "How to contact us" +msgstr "Comment nous contacter" -#: ../../source/tutorial-quickstart-scikitlearn.rst:97 +#: ../../source/ref-telemetry.md:66 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to fit the logistic regression we defined earlier)." +"We want to hear from you. If you have any feedback or ideas on how to " +"improve the way we handle anonymous usage metrics, reach out to us via " +"[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " +"(`telemetry@flower.ai`)." msgstr "" -"Le serveur Flower interagit avec les clients par le biais d'une interface" -" appelée :code:`Client`. Lorsque le serveur sélectionne un client " -"particulier pour la formation, il envoie des instructions de formation " -"sur le réseau. Le client reçoit ces instructions et appelle l'une des " -"méthodes :code:`Client` pour exécuter ton code (c'est-à-dire pour ajuster" -" la régression logistique que nous avons définie plus tôt)." +"Si tu as des commentaires ou des idées pour améliorer la façon dont nous " +"traitons les mesures d'utilisation anonymes, contacte-nous via " +"[Slack](https://flower.ai/join-slack/) (canal `#telemetry`) ou par " +"courriel (`telemetry@flower.ai`)." -#: ../../source/tutorial-quickstart-scikitlearn.rst:103 +#: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " -"means defining the following methods (:code:`set_parameters` is optional " -"though):" +"Read this Federated Learning quickstart tutorial for creating an Android " +"app using Flower." msgstr "" -"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " -"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" -" de travail utilise scikit-learn. Mettre en œuvre :code:`NumPyClient` " -"signifie généralement définir les méthodes suivantes " -"(:code:`set_parameters` est cependant facultatif) :" -#: ../../source/tutorial-quickstart-scikitlearn.rst:112 -msgid "is directly imported with :code:`utils.set_model_params()`" -msgstr "est directement importé avec :code:`utils.set_model_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:120 -msgid "The methods can be implemented in the following way:" -msgstr "Les méthodes peuvent être mises en œuvre de la manière suivante :" +#: ../../source/tutorial-quickstart-android.rst:5 +#, fuzzy +msgid "Quickstart Android" +msgstr "Démarrage rapide des Pandas" -#: ../../source/tutorial-quickstart-scikitlearn.rst:143 +#: ../../source/tutorial-quickstart-android.rst:10 +#, fuzzy msgid "" -"We can now create an instance of our class :code:`MnistClient` and add " -"one line to actually run this client:" +"Let's build a federated learning system using TFLite and Flower on " +"Android!" msgstr "" -"Nous pouvons maintenant créer une instance de notre classe " -":code:`MnistClient` et ajouter une ligne pour exécuter ce client :" +"Construisons un système d'apprentissage fédéré en utilisant fastai et " +"Flower !" -#: ../../source/tutorial-quickstart-scikitlearn.rst:150 +#: ../../source/tutorial-quickstart-android.rst:12 #, fuzzy msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" -" the client which server to connect to. In our case we can run the server" -" and the client on the same machine, therefore we use " -":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we pass to the client." +"Please refer to the `full code example " +"`_ to learn " +"more." msgstr "" -"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" -" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " -"chaîne :code:`\"0.0.0:8080\"` indique au client à quel serveur se " -"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " -"sur la même machine, c'est pourquoi nous utilisons " -":code:`\"0.0.0:8080\"`. Si nous exécutons une charge de travail " -"véritablement fédérée avec le serveur et les clients s'exécutant sur des " -"machines différentes, tout ce qui doit changer est :code:`server_address`" -" que nous transmettons au client." +"Réfère-toi à l'exemple de code complet " +"`_ " +"pour en savoir plus." -#: ../../source/tutorial-quickstart-scikitlearn.rst:159 +#: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import " -"again all required libraries such as Flower and scikit-learn." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with FastAI to train a vision model on CIFAR-10." msgstr "" -"Le serveur Flower suivant est un peu plus avancé et renvoie une fonction " -"d'évaluation pour l'évaluation côté serveur. Tout d'abord, nous importons" -" à nouveau toutes les bibliothèques requises telles que Flower et scikit-" -"learn." -#: ../../source/tutorial-quickstart-scikitlearn.rst:162 -msgid ":code:`server.py`, import Flower and start the server:" -msgstr ":code:`server.py`, importe Flower et démarre le serveur :" +#: ../../source/tutorial-quickstart-fastai.rst:5 +msgid "Quickstart fastai" +msgstr "Démarrage rapide fastai" -#: ../../source/tutorial-quickstart-scikitlearn.rst:173 -msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and" -" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " -"function is called after each federated learning round and gives you " -"information about loss and accuracy." +#: ../../source/tutorial-quickstart-fastai.rst:10 +msgid "Let's build a federated learning system using fastai and Flower!" msgstr "" -"Le nombre de tours d'apprentissage fédéré est défini dans " -":code:`fit_round()` et l'évaluation est définie dans " -":code:`get_evaluate_fn()`. La fonction d'évaluation est appelée après " -"chaque tour d'apprentissage fédéré et te donne des informations sur la " -"perte et la précision." +"Construisons un système d'apprentissage fédéré en utilisant fastai et " +"Flower !" -#: ../../source/tutorial-quickstart-scikitlearn.rst:198 +#: ../../source/tutorial-quickstart-fastai.rst:12 +#, fuzzy msgid "" -"The :code:`main` contains the server-side parameter initialization " -":code:`utils.set_initial_params()` as well as the aggregation strategy " -":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " -"federated averaging (or FedAvg), with two clients and evaluation after " -"each federated learning round. The server can be started with the command" -" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" -"Le :code:`main` contient l'initialisation des paramètres côté serveur " -":code:`utils.set_initial_params()` ainsi que la stratégie d'agrégation " -":code:`fl.server.strategy:FedAvg()`. La stratégie est celle par défaut, " -"la moyenne fédérée (ou FedAvg), avec deux clients et une évaluation après" -" chaque tour d'apprentissage fédéré. Le serveur peut être démarré avec la" -" commande :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +"Réfère-toi à l'exemple de code complet " +"`_ " +"pour en savoir plus." -#: ../../source/tutorial-quickstart-scikitlearn.rst:217 +#: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server " -"first:" +"Check out this Federating Learning quickstart tutorial for using Flower " +"with HuggingFace Transformers in order to fine-tune an LLM." msgstr "" -"Le client et le serveur étant prêts, nous pouvons maintenant tout lancer " -"et voir l'apprentissage fédéré en action. Les systèmes d'apprentissage " -"fédéré ont généralement un serveur et plusieurs clients. Nous devons donc" -" commencer par lancer le serveur :" -#: ../../source/tutorial-quickstart-scikitlearn.rst:271 +#: ../../source/tutorial-quickstart-huggingface.rst:5 +msgid "Quickstart 🤗 Transformers" +msgstr "Démarrage rapide 🤗 Transformateurs" + +#: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples/sklearn-logreg-" -"mnist`." +"Let's build a federated learning system using Hugging Face Transformers " +"and Flower!" msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples/sklearn-logreg-" -"mnist`." +"Construisons un système d'apprentissage fédéré à l'aide des " +"transformateurs Hugging Face et de Flower !" -#: ../../source/tutorial-quickstart-tensorflow.rst:-1 +#: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with TensorFlow to train a MobilNetV2 model on CIFAR-10." +"We will leverage Hugging Face to federate the training of language models" +" over multiple clients using Flower. More specifically, we will fine-tune" +" a pre-trained Transformer model (distilBERT) for sequence classification" +" over a dataset of IMDB ratings. The end goal is to detect if a movie " +"rating is positive or negative." msgstr "" +"Nous nous appuierons sur Hugging Face pour fédérer l'entraînement de " +"modèles de langage sur plusieurs clients à l'aide de Flower. Plus " +"précisément, nous mettrons au point un modèle Transformer pré-entraîné " +"(distilBERT) pour la classification de séquences sur un ensemble de " +"données d'évaluations IMDB. L'objectif final est de détecter si " +"l'évaluation d'un film est positive ou négative." -#: ../../source/tutorial-quickstart-tensorflow.rst:5 -msgid "Quickstart TensorFlow" -msgstr "Démarrage rapide de TensorFlow" +#: ../../source/tutorial-quickstart-huggingface.rst:18 +msgid "Dependencies" +msgstr "Dépendances" -#: ../../source/tutorial-quickstart-tensorflow.rst:13 -msgid "Let's build a federated learning system in less than 20 lines of code!" +#: ../../source/tutorial-quickstart-huggingface.rst:20 +msgid "" +"To follow along this tutorial you will need to install the following " +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " +":code:`torch`, and :code:`transformers`. This can be done using " +":code:`pip`:" msgstr "" -"Construisons un système d'apprentissage fédéré en moins de 20 lignes de " -"code !" +"Pour suivre ce tutoriel, tu devras installer les paquets suivants : " +":code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, et " +":code:`transformers`. Cela peut être fait en utilisant :code:`pip` :" -#: ../../source/tutorial-quickstart-tensorflow.rst:15 -msgid "Before Flower can be imported we have to install it:" -msgstr "Avant de pouvoir importer une fleur, nous devons l'installer :" +#: ../../source/tutorial-quickstart-huggingface.rst:30 +msgid "Standard Hugging Face workflow" +msgstr "Flux de travail standard pour le visage" -#: ../../source/tutorial-quickstart-tensorflow.rst:21 +#: ../../source/tutorial-quickstart-huggingface.rst:33 +msgid "Handling the data" +msgstr "Traitement des données" + +#: ../../source/tutorial-quickstart-huggingface.rst:35 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install" -" TF as well:" +"To fetch the IMDB dataset, we will use Hugging Face's :code:`datasets` " +"library. We then need to tokenize the data and create :code:`PyTorch` " +"dataloaders, this is all done in the :code:`load_data` function:" msgstr "" -"Comme nous voulons utiliser l'API Keras de TensorFlow (TF), nous devons " -"également installer TF :" +"Pour récupérer le jeu de données IMDB, nous utiliserons la bibliothèque " +":code:`datasets` de Hugging Face. Nous devons ensuite tokeniser les " +"données et créer des :code:`PyTorch` dataloaders, ce qui est fait dans la" +" fonction :code:`load_data` :" -#: ../../source/tutorial-quickstart-tensorflow.rst:31 -msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" -msgstr "" -"Ensuite, dans un fichier appelé :code:`client.py`, importe Flower et " -"TensorFlow :" +#: ../../source/tutorial-quickstart-huggingface.rst:81 +msgid "Training and testing the model" +msgstr "Former et tester le modèle" -#: ../../source/tutorial-quickstart-tensorflow.rst:38 +#: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image" -" classification dataset for machine learning. The call to " -":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " -"it locally, and then returns the entire training and test set as NumPy " -"ndarrays." +"Once we have a way of creating our trainloader and testloader, we can " +"take care of the training and testing. This is very similar to any " +":code:`PyTorch` training or testing loop:" msgstr "" -"Nous utilisons les utilitaires Keras de TF pour charger CIFAR10, un " -"ensemble de données de classification d'images colorées populaire pour " -"l'apprentissage automatique. L'appel à " -":code:`tf.keras.datasets.cifar10.load_data()` télécharge CIFAR10, le met " -"en cache localement, puis renvoie l'ensemble d'entraînement et de test " -"sous forme de NumPy ndarrays." +"Une fois que nous avons trouvé un moyen de créer notre trainloader et " +"notre testloader, nous pouvons nous occuper de l'entraînement et du test." +" C'est très similaire à n'importe quelle boucle d'entraînement ou de test" +" :code:`PyTorch` :" -#: ../../source/tutorial-quickstart-tensorflow.rst:47 +#: ../../source/tutorial-quickstart-huggingface.rst:121 +msgid "Creating the model itself" +msgstr "Créer le modèle lui-même" + +#: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use " -"MobilNetV2 with 10 output classes:" +"To create the model itself, we will just load the pre-trained distillBERT" +" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" -"Ensuite, nous avons besoin d'un modèle. Pour les besoins de ce tutoriel, " -"nous utilisons MobilNetV2 avec 10 classes de sortie :" +"Pour créer le modèle lui-même, nous allons simplement charger le modèle " +"distillBERT pré-entraîné en utilisant le " +":code:`AutoModelForSequenceClassification` de Hugging Face :" -#: ../../source/tutorial-quickstart-tensorflow.rst:60 +#: ../../source/tutorial-quickstart-huggingface.rst:136 +msgid "Federating the example" +msgstr "Fédérer l'exemple" + +#: ../../source/tutorial-quickstart-huggingface.rst:139 +msgid "Creating the IMDBClient" +msgstr "Création du client IMDBC" + +#: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses Keras. The :code:`NumPyClient` interface defines three " -"methods which can be implemented in the following way:" +"To federate our example to multiple clients, we first need to write our " +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " +"This is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" -"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " -"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" -" de travail utilise Keras. L'interface :code:`NumPyClient` définit trois " -"méthodes qui peuvent être mises en œuvre de la manière suivante :" - -#: ../../source/tutorial-quickstart-tensorflow.rst:135 -msgid "Each client will have its own dataset." -msgstr "Chaque client aura son propre ensemble de données." +"Pour fédérer notre exemple à plusieurs clients, nous devons d'abord " +"écrire notre classe de client Flower (héritant de " +":code:`flwr.client.NumPyClient`). C'est très facile, car notre modèle est" +" un modèle :code:`PyTorch` standard :" -#: ../../source/tutorial-quickstart-tensorflow.rst:137 +#: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" -"You should now see how the training does in the very first terminal (the " -"one that started the server):" +"The :code:`get_parameters` function lets the server get the client's " +"parameters. Inversely, the :code:`set_parameters` function allows the " +"server to send its parameters to the client. Finally, the :code:`fit` " +"function trains the model locally for the client, and the " +":code:`evaluate` function tests the model locally and returns the " +"relevant metrics." msgstr "" -"Tu devrais maintenant voir comment la formation se déroule dans le tout " -"premier terminal (celui qui a démarré le serveur) :" +"La fonction :code:`get_parameters` permet au serveur d'obtenir les " +"paramètres du client. Inversement, la fonction :code:`set_parameters` " +"permet au serveur d'envoyer ses paramètres au client. Enfin, la fonction " +":code:`fit` forme le modèle localement pour le client, et la fonction " +":code:`evaluate` teste le modèle localement et renvoie les mesures " +"correspondantes." -#: ../../source/tutorial-quickstart-tensorflow.rst:169 -#, fuzzy +#: ../../source/tutorial-quickstart-huggingface.rst:175 +msgid "Starting the server" +msgstr "Démarrer le serveur" + +#: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this can be found in :code:`examples" -"/quickstart-tensorflow/client.py`." +"Now that we have a way to instantiate clients, we need to create our " +"server in order to aggregate the results. Using Flower, this can be done " +"very easily by first choosing a strategy (here, we are using " +":code:`FedAvg`, which will define the global weights as the average of " +"all the clients' weights at each round) and then using the " +":code:`flwr.server.start_server` function:" msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le `code source complet " -"`_ pour cela se trouve dans :code:`examples" -"/quickstart-tensorflow/client.py`." +"Maintenant que nous avons un moyen d'instancier les clients, nous devons " +"créer notre serveur afin d'agréger les résultats. Avec Flower, cela peut " +"être fait très facilement en choisissant d'abord une stratégie (ici, nous" +" utilisons :code:`FedAvg`, qui définira les poids globaux comme la " +"moyenne des poids de tous les clients à chaque tour) et en utilisant " +"ensuite la fonction :code:`flwr.server.start_server` :" -#: ../../source/tutorial-quickstart-xgboost.rst:-1 +#: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with XGBoost to train classification models on trees." +"The :code:`weighted_average` function is there to provide a way to " +"aggregate the metrics distributed amongst the clients (basically this " +"allows us to display a nice average accuracy and loss for every round)." msgstr "" +"La fonction :code:`weighted_average` est là pour fournir un moyen " +"d'agréger les mesures réparties entre les clients (en gros, cela nous " +"permet d'afficher une belle moyenne de précision et de perte pour chaque " +"tour)." -#: ../../source/tutorial-quickstart-xgboost.rst:5 -msgid "Quickstart XGBoost" -msgstr "Démarrage rapide XGBoost" +#: ../../source/tutorial-quickstart-huggingface.rst:209 +msgid "Putting everything together" +msgstr "Tout assembler" -#: ../../source/tutorial-quickstart-xgboost.rst:14 -#, fuzzy -msgid "Federated XGBoost" -msgstr "Formation fédérée" +#: ../../source/tutorial-quickstart-huggingface.rst:211 +msgid "We can now start client instances using:" +msgstr "Nous pouvons maintenant démarrer des instances de clients en utilisant :" -#: ../../source/tutorial-quickstart-xgboost.rst:16 +#: ../../source/tutorial-quickstart-huggingface.rst:221 msgid "" -"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that " -"maximises the computational boundaries for boosted tree methods. It's " -"primarily designed to enhance both the performance and computational " -"speed of machine learning models. In XGBoost, trees are constructed " -"concurrently, unlike the sequential approach taken by GBDT." -msgstr "" +"And they will be able to connect to the server and start the federated " +"training." +msgstr "Et ils pourront se connecter au serveur et démarrer la formation fédérée." -#: ../../source/tutorial-quickstart-xgboost.rst:20 +#: ../../source/tutorial-quickstart-huggingface.rst:223 +#, fuzzy msgid "" -"Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning " -"techniques." +"If you want to check out everything put together, you should check out " +"the `full code example `_ ." msgstr "" +"Si tu veux voir tout ce qui est mis ensemble, tu devrais consulter " +"l'exemple de code complet : " +"[https://github.com/adap/flower/tree/main/examples/quickstart-" +"huggingface](https://github.com/adap/flower/tree/main/examples" +"/quickstart-huggingface)." -#: ../../source/tutorial-quickstart-xgboost.rst:23 -#, fuzzy -msgid "Why federated XGBoost?" -msgstr "Qu'est-ce que l'apprentissage fédéré ?" - -#: ../../source/tutorial-quickstart-xgboost.rst:25 +#: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems " -"for specialised applications, like survival analysis and financial fraud " -"detection." +"Of course, this is a very basic example, and a lot can be added or " +"modified, it was just to showcase how simply we could federate a Hugging " +"Face workflow using Flower." msgstr "" +"Bien sûr, c'est un exemple très basique, et beaucoup de choses peuvent " +"être ajoutées ou modifiées, il s'agissait juste de montrer avec quelle " +"simplicité on pouvait fédérer un flux de travail Hugging Face à l'aide de" +" Flower." -#: ../../source/tutorial-quickstart-xgboost.rst:27 +#: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Federated learning ensures that raw data remains on the local device, " -"making it an attractive approach for sensitive domains where data " -"security and privacy are paramount. Given the robustness and efficiency " -"of XGBoost, combining it with federated learning offers a promising " -"solution for these specific challenges." +"Note that in this example we used :code:`PyTorch`, but we could have very" +" well used :code:`TensorFlow`." msgstr "" +"Notez que dans cet exemple, nous avons utilisé :code:`PyTorch`, mais nous" +" aurions très bien pu utiliser :code:`TensorFlow`." -#: ../../source/tutorial-quickstart-xgboost.rst:30 +#: ../../source/tutorial-quickstart-ios.rst:-1 msgid "" -"In this tutorial we will learn how to train a federated XGBoost model on " -"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart " -"`_)" -" with two *clients* and one *server* to demonstrate how federated XGBoost" -" works, and then we dive into a more complex example (`full code xgboost-" -"comprehensive `_) to run various experiments." +"Read this Federated Learning quickstart tutorial for creating an iOS app " +"using Flower to train a neural network on MNIST." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:37 -msgid "Environment Setup" -msgstr "" +#: ../../source/tutorial-quickstart-ios.rst:5 +#, fuzzy +msgid "Quickstart iOS" +msgstr "Démarrage rapide XGBoost" -#: ../../source/tutorial-quickstart-xgboost.rst:41 +#: ../../source/tutorial-quickstart-ios.rst:10 +#, fuzzy msgid "" -"We first need to install Flower and Flower Datasets. You can do this by " -"running :" +"In this tutorial we will learn how to train a Neural Network on MNIST " +"using Flower and CoreML on iOS devices." msgstr "" +"Dans ce tutoriel, nous allons apprendre, comment former un réseau " +"neuronal convolutif sur MNIST en utilisant Flower et PyTorch." -#: ../../source/tutorial-quickstart-xgboost.rst:47 +#: ../../source/tutorial-quickstart-ios.rst:12 #, fuzzy msgid "" -"Since we want to use :code:`xgboost` package to build up XGBoost trees, " -"let's go ahead and install :code:`xgboost`:" -msgstr "Puisque nous voulons utiliser scikt-learn, allons-y et installons-le :" - -#: ../../source/tutorial-quickstart-xgboost.rst:57 -msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. Now that we have all our " -"dependencies installed, let's run a simple distributed training with two " -"clients and one server." +"First of all, for running the Flower Python server, it is recommended to " +"create a virtual environment and run everything within a :doc:`virtualenv" +" `. For the Flower client " +"implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" +"Tout d'abord, il est recommandé de créer un environnement virtuel et de " +"tout exécuter au sein d'un `virtualenv `_." -#: ../../source/tutorial-quickstart-xgboost.rst:60 +#: ../../source/tutorial-quickstart-ios.rst:15 #, fuzzy msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower " -"Datasets and other related functions:" +"Our example consists of one Python *server* and two iPhone *clients* that" +" all have the same model." msgstr "" -"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " -"liés à PyTorch :" +"Notre exemple consiste en un *serveur* et deux *clients* ayant tous le " +"même modèle." -#: ../../source/tutorial-quickstart-xgboost.rst:87 -msgid "Dataset partition and hyper-parameter selection" +#: ../../source/tutorial-quickstart-ios.rst:17 +#, fuzzy +msgid "" +"*Clients* are responsible for generating individual weight updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" +"*Les clients* sont chargés de générer des mises à jour de poids " +"individuelles pour le modèle en fonction de leurs ensembles de données " +"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " +"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " +"cette version améliorée du modèle à chaque *client*. Un cycle complet de " +"mises à jour de poids s'appelle un *round*." -#: ../../source/tutorial-quickstart-xgboost.rst:89 +#: ../../source/tutorial-quickstart-ios.rst:21 +#, fuzzy msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower" -" Datasets and conduct data partitioning for FL:" +"Now that we have a rough idea of what is going on, let's get started to " +"setup our Flower server environment. We first need to install Flower. You" +" can do this by using pip:" msgstr "" +"Maintenant que nous avons une idée générale de ce qui se passe, " +"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " +"exécutant :" -#: ../../source/tutorial-quickstart-xgboost.rst:102 -msgid "" -"In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " -"the partition for the given client based on :code:`node_id`:" +#: ../../source/tutorial-quickstart-ios.rst:27 +msgid "Or Poetry:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:121 +#: ../../source/tutorial-quickstart-ios.rst:34 +#: ../../source/tutorial-quickstart-pytorch.rst:37 +#: ../../source/tutorial-quickstart-scikitlearn.rst:40 +#: ../../source/tutorial-quickstart-tensorflow.rst:29 +#: ../../source/tutorial-quickstart-xgboost.rst:55 +msgid "Flower Client" +msgstr "Client de la fleur" + +#: ../../source/tutorial-quickstart-ios.rst:36 msgid "" -"After that, we do train/test splitting on the given partition (client's " -"local data), and transform data format for :code:`xgboost` package." +"Now that we have all our dependencies installed, let's run a simple " +"distributed training using CoreML as our local training pipeline and " +"MNIST as our dataset. For simplicity reasons we will use the complete " +"Flower client with CoreML, that has been implemented and stored inside " +"the Swift SDK. The client implementation can be seen below:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:134 +#: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"The functions of :code:`train_test_split` and " -":code:`transform_dataset_to_dmatrix` are defined as below:" +"Let's create a new application project in Xcode and add :code:`flwr` as a" +" dependency in your project. For our application, we will store the logic" +" of our app in :code:`FLiOSModel.swift` and the UI elements in " +":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" +" in this quickstart. Please refer to the `full code example " +"`_ to learn more " +"about the app." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:158 -msgid "Finally, we define the hyper-parameters used for XGBoost training." +#: ../../source/tutorial-quickstart-ios.rst:75 +msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:174 +#: ../../source/tutorial-quickstart-ios.rst:83 msgid "" -"The :code:`num_local_round` represents the number of iterations for local" -" tree boost. We use CPU for the training in default. One can shift it to " -"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " -"evaluation metric." -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:181 -msgid "Flower client definition for XGBoost" +"Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " +"will be bundled inside the application during deployment to your iOS " +"device. We need to pass the url to access mlmodel and run CoreML machine " +"learning processes, it can be retrieved by calling the function " +":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " +"into :code:`MLBatchProvider` object. The preprocessing is done inside " +":code:`DataLoader.swift`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:183 +#: ../../source/tutorial-quickstart-ios.rst:99 msgid "" -"After loading the dataset we define the Flower client. We follow the " -"general rule to define :code:`XgbClient` class inherited from " -":code:`fl.client.Client`." +"Since CoreML does not allow the model parameters to be seen before " +"training, and accessing the model parameters during or after the training" +" can only be done by specifying the layer name, we need to know this " +"information beforehand, through looking at the model specification, which" +" are written as proto files. The implementation can be seen in " +":code:`MLModelInspect`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:193 +#: ../../source/tutorial-quickstart-ios.rst:102 msgid "" -"The :code:`self.bst` is used to keep the Booster objects that remain " -"consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures" -" for training." +"After we have all of the necessary information, let's create our Flower " +"client." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:196 +#: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and " -":code:`evaluate` methods insides :code:`XgbClient` class as follows." +"Then start the Flower gRPC client and start communicating to the server " +"by passing our Flower client to the function :code:`startFlwrGRPC`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:210 +#: ../../source/tutorial-quickstart-ios.rst:124 msgid "" -"Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use " -":code:`get_parameters` and :code:`set_parameters` to initialise model " -"parameters for XGBoost. As a result, let's return an empty tensor in " -":code:`get_parameters` when it is called by the server at the first " -"round." +"That's it for the client. We only have to implement :code:`Client` or " +"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " +"The attribute :code:`hostname` and :code:`port` tells the client which " +"server to connect to. This can be done by entering the hostname and port " +"in the application before clicking the start button to start the " +"federated learning process." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:251 +#: ../../source/tutorial-quickstart-ios.rst:129 +#: ../../source/tutorial-quickstart-pytorch.rst:203 +#: ../../source/tutorial-quickstart-scikitlearn.rst:167 +#: ../../source/tutorial-quickstart-tensorflow.rst:98 +#: ../../source/tutorial-quickstart-xgboost.rst:309 +msgid "Flower Server" +msgstr "Serveur de Flower" + +#: ../../source/tutorial-quickstart-ios.rst:131 +#: ../../source/tutorial-quickstart-pytorch.rst:205 +#: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " -"up the first set of trees. the returned Booster object and config are " -"stored in :code:`self.bst` and :code:`self.config`, respectively. From " -"the second round, we load the global model sent from server to " -":code:`self.bst`, and then update model weights on local training data " -"with function :code:`local_boost` as follows:" +"For simple workloads we can start a Flower server and leave all the " +"configuration possibilities at their default values. In a file named " +":code:`server.py`, import Flower and start the server:" msgstr "" +"Pour les charges de travail simples, nous pouvons démarrer un serveur " +"Flower et laisser toutes les possibilités de configuration à leurs " +"valeurs par défaut. Dans un fichier nommé :code:`server.py`, importe " +"Flower et démarre le serveur :" -#: ../../source/tutorial-quickstart-xgboost.rst:269 +#: ../../source/tutorial-quickstart-ios.rst:142 +#: ../../source/tutorial-quickstart-pytorch.rst:216 +#: ../../source/tutorial-quickstart-scikitlearn.rst:230 +#: ../../source/tutorial-quickstart-tensorflow.rst:112 +msgid "Train the model, federated!" +msgstr "Entraîne le modèle, fédéré !" + +#: ../../source/tutorial-quickstart-ios.rst:144 +#: ../../source/tutorial-quickstart-pytorch.rst:218 +#: ../../source/tutorial-quickstart-tensorflow.rst:114 +#: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" -"Given :code:`num_local_round`, we update trees by calling " -":code:`self.bst.update` method. After training, the last " -":code:`N=num_local_round` trees will be extracted to send to the server." +"With both client and server ready, we can now run everything and see " +"federated learning in action. FL systems usually have a server and " +"multiple clients. We therefore have to start the server first:" msgstr "" +"Le client et le serveur étant prêts, nous pouvons maintenant tout " +"exécuter et voir l'apprentissage fédéré en action. Les systèmes FL ont " +"généralement un serveur et plusieurs clients. Nous devons donc commencer " +"par démarrer le serveur :" -#: ../../source/tutorial-quickstart-xgboost.rst:291 +#: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " -"conduct evaluation on valid set. The AUC value will be returned." +"Once the server is running we can start the clients in different " +"terminals. Build and run the client through your Xcode, one through Xcode" +" Simulator and the other by deploying it to your iPhone. To see more " +"about how to deploy your app to iPhone or Simulator visit `here " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:294 +#: ../../source/tutorial-quickstart-ios.rst:156 #, fuzzy msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one" -" line to actually run this client:" +"Congratulations! You've successfully built and run your first federated " +"learning system in your ios device. The full `source code " +"`_ for this " +"example can be found in :code:`examples/ios`." msgstr "" -"Nous pouvons maintenant créer une instance de notre classe " -":code:`MnistClient` et ajouter une ligne pour exécuter ce client :" +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le code source complet " +"`_ de cet exemple se trouve dans :code:`examples" +"/quickstart-mxnet`." -#: ../../source/tutorial-quickstart-xgboost.rst:300 -#, fuzzy +#: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"That's it for the client. We only have to implement :code:`Client`and " -"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " -"tells the client which server to connect to. In our case we can run the " -"server and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Jax to train a linear regression model on a scikit-learn dataset." msgstr "" -"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" -" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " -"chaîne :code:`\"[: :]:8080\"` indique au client à quel serveur se " -"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " -"sur la même machine, c'est pourquoi nous utilisons :code:`\"[: " -":]:8080\"`. Si nous exécutons une charge de travail véritablement fédérée" -" avec le serveur et les clients fonctionnant sur des machines " -"différentes, tout ce qui doit changer est l'adresse " -":code:`server_address` vers laquelle nous dirigeons le client." -#: ../../source/tutorial-quickstart-xgboost.rst:311 -#, fuzzy -msgid "" -"These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version" -" of the model back to each *client* to finish a complete FL round." -msgstr "" -"*Les clients* sont chargés de générer des mises à jour de poids " -"individuelles pour le modèle en fonction de leurs ensembles de données " -"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " -"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " -"cette version améliorée du modèle à chaque *client*. Un cycle complet de " -"mises à jour de poids s'appelle un *round*." +#: ../../source/tutorial-quickstart-jax.rst:5 +msgid "Quickstart JAX" +msgstr "Démarrage rapide de JAX" -#: ../../source/tutorial-quickstart-xgboost.rst:314 -#, fuzzy +#: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from " -":code:`flwr.server.strategy`." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Pandas to perform Federated Analytics." msgstr "" -"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " -"liés au MXNet :" -#: ../../source/tutorial-quickstart-xgboost.rst:316 -msgid "We first define a strategy for XGBoost bagging aggregation." -msgstr "" +#: ../../source/tutorial-quickstart-pandas.rst:5 +msgid "Quickstart Pandas" +msgstr "Démarrage rapide des Pandas" -#: ../../source/tutorial-quickstart-xgboost.rst:339 -msgid "" -"We use two clients for this example. An " -":code:`evaluate_metrics_aggregation` function is defined to collect and " -"wighted average the AUC values from clients." -msgstr "" +#: ../../source/tutorial-quickstart-pandas.rst:10 +msgid "Let's build a federated analytics system using Pandas and Flower!" +msgstr "Construisons un système d'analyse fédéré à l'aide de Pandas et de Flower !" -#: ../../source/tutorial-quickstart-xgboost.rst:342 +#: ../../source/tutorial-quickstart-pandas.rst:12 #, fuzzy -msgid "Then, we start the server:" -msgstr "Démarrer le serveur" - -#: ../../source/tutorial-quickstart-xgboost.rst:354 -msgid "Tree-based bagging aggregation" -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"You must be curious about how bagging aggregation works. Let's look into " -"the details." +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" +"Réfère-toi à l'exemple de code complet " +"`_ " +"pour en savoir plus." -#: ../../source/tutorial-quickstart-xgboost.rst:358 +#: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " -":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." -" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " -"and :code:`evaluate` methods as follows:" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch to train a CNN model on MNIST." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:454 +#: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " -"trees by calling :code:`aggregate()` function:" +"In this tutorial we will learn how to train a Convolutional Neural " +"Network on CIFAR10 using Flower and PyTorch." msgstr "" +"Dans ce tutoriel, nous allons apprendre à entraîner un réseau neuronal " +"convolutif sur CIFAR10 à l'aide de Flower et PyTorch." -#: ../../source/tutorial-quickstart-xgboost.rst:513 +#: ../../source/tutorial-quickstart-pytorch.rst:15 +#: ../../source/tutorial-quickstart-xgboost.rst:39 +#, fuzzy msgid "" -"In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling " -":code:`_get_tree_nums`. Then, the fetched information will be aggregated." -" After that, the trees (containing model weights) are aggregated to " -"generate a new tree model." +"First of all, it is recommended to create a virtual environment and run " +"everything within a :doc:`virtualenv `." msgstr "" +"Tout d'abord, il est recommandé de créer un environnement virtuel et de " +"tout exécuter au sein d'un `virtualenv `_." -#: ../../source/tutorial-quickstart-xgboost.rst:518 +#: ../../source/tutorial-quickstart-pytorch.rst:17 +#: ../../source/tutorial-quickstart-scikitlearn.rst:14 msgid "" -"After traversal of all clients' models, a new global model is generated, " -"followed by the serialisation, and sending back to each client." +"Our example consists of one *server* and two *clients* all having the " +"same model." msgstr "" +"Notre exemple consiste en un *serveur* et deux *clients* ayant tous le " +"même modèle." -#: ../../source/tutorial-quickstart-xgboost.rst:523 -msgid "Launch Federated XGBoost!" +#: ../../source/tutorial-quickstart-pytorch.rst:19 +msgid "" +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" +"*Les clients* sont chargés de générer des mises à jour de poids " +"individuelles pour le modèle en fonction de leurs ensembles de données " +"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " +"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " +"cette version améliorée du modèle à chaque *client*. Un cycle complet de " +"mises à jour de poids s'appelle un *round*." -#: ../../source/tutorial-quickstart-xgboost.rst:585 +#: ../../source/tutorial-quickstart-pytorch.rst:23 msgid "" -"Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in " -":code:`metrics_distributed`. One can see that the average AUC increases " -"over FL rounds." +"Now that we have a rough idea of what is going on, let's get started. We " +"first need to install Flower. You can do this by running :" msgstr "" +"Maintenant que nous avons une idée générale de ce qui se passe, " +"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " +"exécutant :" -#: ../../source/tutorial-quickstart-xgboost.rst:590 -#, fuzzy +#: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"The full `source code `_ for this example can be found in :code:`examples" -"/xgboost-quickstart`." +"Since we want to use PyTorch to solve a computer vision task, let's go " +"ahead and install PyTorch and the **torchvision** library:" msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples" -"/quickstart-mxnet`." +"Puisque nous voulons utiliser PyTorch pour résoudre une tâche de vision " +"par ordinateur, allons-y et installons PyTorch et la bibliothèque " +"**torchvision** :" -#: ../../source/tutorial-quickstart-xgboost.rst:594 -msgid "Comprehensive Federated XGBoost" +#: ../../source/tutorial-quickstart-pytorch.rst:39 +msgid "" +"Now that we have all our dependencies installed, let's run a simple " +"distributed training with two clients and one server. Our training " +"procedure and network architecture are based on PyTorch's `Deep Learning " +"with PyTorch " +"`_." msgstr "" +"Maintenant que nous avons installé toutes nos dépendances, lançons une " +"formation distribuée simple avec deux clients et un serveur. Notre " +"procédure de formation et l'architecture de notre réseau sont basées sur " +"`Deep Learning with PyTorch " +"`_ de" +" PyTorch." -#: ../../source/tutorial-quickstart-xgboost.rst:596 +#: ../../source/tutorial-quickstart-pytorch.rst:41 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time" -" to run some more comprehensive experiments by customising the " -"experimental settings. In the xgboost-comprehensive example (`full code " -"`_), we provide more options to define various experimental" -" setups, including aggregation strategies, data partitioning and " -"centralised/distributed evaluation. We also support :doc:`Flower " -"simulation ` making it easy to simulate large " -"client cohorts in a resource-aware manner. Let's take a look!" +"In a file called :code:`client.py`, import Flower and PyTorch related " +"packages:" msgstr "" +"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " +"liés à PyTorch :" -#: ../../source/tutorial-quickstart-xgboost.rst:603 -#, fuzzy -msgid "Cyclic training" -msgstr "Formation centralisée" +#: ../../source/tutorial-quickstart-pytorch.rst:56 +msgid "In addition, we define the device allocation in PyTorch with:" +msgstr "En outre, nous définissons l'attribution des appareils dans PyTorch avec :" -#: ../../source/tutorial-quickstart-xgboost.rst:605 +#: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, " -"which performs FL in a client-by-client fashion. Instead of aggregating " -"multiple clients, there is only one single client participating in the " -"training per round in the cyclic training scenario. The trained local " -"XGBoost trees will be passed to the next client as an initialised model " -"for next round's boosting." +"We use PyTorch to load CIFAR10, a popular colored image classification " +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " +"the training and test data that are then normalized." msgstr "" +"Nous utilisons PyTorch pour charger CIFAR10, un ensemble de données de " +"classification d'images colorées populaire pour l'apprentissage " +"automatique. Le :code:`DataLoader()` de PyTorch télécharge les données " +"d'entraînement et de test qui sont ensuite normalisées." -#: ../../source/tutorial-quickstart-xgboost.rst:609 +#: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"To do this, we first customise a :code:`ClientManager` in " -":code:`server_utils.py`:" +"Define the loss and optimizer with PyTorch. The training of the dataset " +"is done by looping over the dataset, measure the corresponding loss and " +"optimize it." msgstr "" +"Définis la perte et l'optimiseur avec PyTorch L'entraînement de " +"l'ensemble de données se fait en bouclant sur l'ensemble de données, en " +"mesurant la perte correspondante et en l'optimisant." -#: ../../source/tutorial-quickstart-xgboost.rst:649 +#: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"The customised :code:`ClientManager` samples all available clients in " -"each FL round based on the order of connection to the server. Then, we " -"define a new strategy :code:`FedXgbCyclic` in " -":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " -"select only one client in given round and pass the received model to next" -" client." +"Define then the validation of the machine learning network. We loop over" +" the test set and measure the loss and accuracy of the test set." msgstr "" +"Définis ensuite la validation du réseau d'apprentissage automatique. Nous" +" passons en boucle sur l'ensemble de test et mesurons la perte et la " +"précision de l'ensemble de test." -#: ../../source/tutorial-quickstart-xgboost.rst:690 +#: ../../source/tutorial-quickstart-pytorch.rst:113 msgid "" -"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model" -" by overriding :code:`aggregate_fit`." +"After defining the training and testing of a PyTorch machine learning " +"model, we use the functions for the Flower clients." msgstr "" +"Après avoir défini l'entraînement et le test d'un modèle d'apprentissage " +"automatique PyTorch, nous utilisons les fonctions pour les clients " +"Flower." -#: ../../source/tutorial-quickstart-xgboost.rst:693 +#: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" -" methods ensure the clients to be sequentially selected given FL round:" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " +"Minute Blitz':" msgstr "" +"Les clients de Flower utiliseront un CNN simple adapté de \"PyTorch : A " +"60 Minute Blitz\" :" -#: ../../source/tutorial-quickstart-xgboost.rst:757 -msgid "Customised data partitioning" +#: ../../source/tutorial-quickstart-pytorch.rst:142 +msgid "" +"After loading the data set with :code:`load_data()` we define the Flower " +"interface." msgstr "" +"Après avoir chargé l'ensemble des données avec :code:`load_data()`, nous " +"définissons l'interface Flower." -#: ../../source/tutorial-quickstart-xgboost.rst:759 -msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" -" to instantiate the data partitioner based on the given " -":code:`num_partitions` and :code:`partitioner_type`. Currently, we " -"provide four supported partitioner type to simulate the uniformity/non-" -"uniformity in data quantity (uniform, linear, square, exponential)." -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:790 -#, fuzzy -msgid "Customised centralised/distributed evaluation" -msgstr "Évaluation centralisée" - -#: ../../source/tutorial-quickstart-xgboost.rst:792 +#: ../../source/tutorial-quickstart-pytorch.rst:144 +#: ../../source/tutorial-quickstart-tensorflow.rst:54 msgid "" -"To facilitate centralised evaluation, we define a function in " -":code:`server_utils.py`:" +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to train the neural network we defined earlier)." msgstr "" +"Le serveur Flower interagit avec les clients par le biais d'une interface" +" appelée :code:`Client`. Lorsque le serveur sélectionne un client " +"particulier pour la formation, il envoie des instructions de formation " +"sur le réseau. Le client reçoit ces instructions et appelle l'une des " +"méthodes :code:`Client` pour exécuter ton code (c'est-à-dire pour former " +"le réseau neuronal que nous avons défini plus tôt)." -#: ../../source/tutorial-quickstart-xgboost.rst:824 +#: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"This function returns a evaluation function which instantiates a " -":code:`Booster` object and loads the global model weights to it. The " -"evaluation is conducted by calling :code:`eval_set()` method, and the " -"tested AUC value is reported." +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " +"defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" +"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " +"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" +" de travail utilise PyTorch. Mettre en œuvre :code:`NumPyClient` signifie" +" généralement définir les méthodes suivantes (:code:`set_parameters` est " +"cependant facultatif) :" -#: ../../source/tutorial-quickstart-xgboost.rst:827 -msgid "" -"As for distributed evaluation on the clients, it's same as the quick-" -"start example by overriding the :code:`evaluate()` method insides the " -":code:`XgbClient` class in :code:`client_utils.py`." -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:156 +#: ../../source/tutorial-quickstart-scikitlearn.rst:119 +msgid "return the model weight as a list of NumPy ndarrays" +msgstr "renvoie le poids du modèle sous la forme d'une liste de ndarrays NumPy" -#: ../../source/tutorial-quickstart-xgboost.rst:831 -#, fuzzy -msgid "Flower simulation" -msgstr "Simulation de moniteur" +#: ../../source/tutorial-quickstart-pytorch.rst:157 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 +msgid ":code:`set_parameters` (optional)" +msgstr ":code:`set_parameters` (optionnel)" -#: ../../source/tutorial-quickstart-xgboost.rst:832 +#: ../../source/tutorial-quickstart-pytorch.rst:158 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 msgid "" -"We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a" -" single machine or a cluster of machines." +"update the local model weights with the parameters received from the " +"server" msgstr "" +"mettre à jour les poids du modèle local avec les paramètres reçus du " +"serveur" -#: ../../source/tutorial-quickstart-xgboost.rst:866 -msgid "" -"After importing all required packages, we define a :code:`main()` " -"function to perform the simulation process:" -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:160 +#: ../../source/tutorial-quickstart-scikitlearn.rst:124 +msgid "set the local model weights" +msgstr "fixe les poids du modèle local" -#: ../../source/tutorial-quickstart-xgboost.rst:921 -msgid "" -"We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, " -"the clients won't need to pre-process their partitions again." -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:161 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 +msgid "train the local model" +msgstr "entraîne le modèle local" -#: ../../source/tutorial-quickstart-xgboost.rst:924 -msgid "Then, we define the strategies and other hyper-parameters:" -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:162 +#: ../../source/tutorial-quickstart-scikitlearn.rst:126 +msgid "receive the updated local model weights" +msgstr "recevoir les poids du modèle local mis à jour" -#: ../../source/tutorial-quickstart-xgboost.rst:975 -msgid "" -"After that, we start the simulation by calling " -":code:`fl.simulation.start_simulation`:" -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:164 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 +msgid "test the local model" +msgstr "teste le modèle local" -#: ../../source/tutorial-quickstart-xgboost.rst:995 +#: ../../source/tutorial-quickstart-pytorch.rst:166 +msgid "which can be implemented in the following way:" +msgstr "qui peut être mis en œuvre de la manière suivante :" + +#: ../../source/tutorial-quickstart-pytorch.rst:189 +#: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"One of key parameters for :code:`start_simulation` is :code:`client_fn` " -"which returns a function to construct a client. We define it as follows:" +"We can now create an instance of our class :code:`CifarClient` and add " +"one line to actually run this client:" msgstr "" +"Nous pouvons maintenant créer une instance de notre classe " +":code:`CifarClient` et ajouter une ligne pour exécuter ce client :" -#: ../../source/tutorial-quickstart-xgboost.rst:1038 -msgid "Arguments parser" +#: ../../source/tutorial-quickstart-pytorch.rst:196 +#: ../../source/tutorial-quickstart-tensorflow.rst:90 +#, fuzzy +msgid "" +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " +"the client which server to connect to. In our case we can run the server " +"and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" +"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" +" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " +"chaîne :code:`\"[: :]:8080\"` indique au client à quel serveur se " +"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " +"sur la même machine, c'est pourquoi nous utilisons :code:`\"[: " +":]:8080\"`. Si nous exécutons une charge de travail véritablement fédérée" +" avec le serveur et les clients fonctionnant sur des machines " +"différentes, tout ce qui doit changer est l'adresse " +":code:`server_address` vers laquelle nous dirigeons le client." -#: ../../source/tutorial-quickstart-xgboost.rst:1040 +#: ../../source/tutorial-quickstart-pytorch.rst:226 +#: ../../source/tutorial-quickstart-scikitlearn.rst:239 +#: ../../source/tutorial-quickstart-tensorflow.rst:122 +#: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server " -"and simulation, allowing users to specify different experimental " -"settings. Let's first see the sever side:" +"Once the server is running we can start the clients in different " +"terminals. Open a new terminal and start the first client:" msgstr "" +"Une fois que le serveur fonctionne, nous pouvons démarrer les clients " +"dans différents terminaux. Ouvre un nouveau terminal et démarre le " +"premier client :" -#: ../../source/tutorial-quickstart-xgboost.rst:1086 +#: ../../source/tutorial-quickstart-pytorch.rst:233 +#: ../../source/tutorial-quickstart-scikitlearn.rst:246 +#: ../../source/tutorial-quickstart-tensorflow.rst:129 +#: ../../source/tutorial-quickstart-xgboost.rst:540 +msgid "Open another terminal and start the second client:" +msgstr "Ouvre un autre terminal et démarre le deuxième client :" + +#: ../../source/tutorial-quickstart-pytorch.rst:239 +#: ../../source/tutorial-quickstart-scikitlearn.rst:252 +#: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and" -" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" -" will do centralised evaluation and all functionalities for client " -"evaluation will be disabled." +"Each client will have its own dataset. You should now see how the " +"training does in the very first terminal (the one that started the " +"server):" msgstr "" +"Chaque client aura son propre ensemble de données. Tu devrais maintenant " +"voir comment la formation se déroule dans le tout premier terminal (celui" +" qui a démarré le serveur) :" -#: ../../source/tutorial-quickstart-xgboost.rst:1090 -msgid "Then, the argument parser on client side:" +#: ../../source/tutorial-quickstart-pytorch.rst:271 +#, fuzzy +msgid "" +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples" +"/quickstart-pytorch`." msgstr "" +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le code source complet " +"`_ de cet exemple se trouve dans :code:`examples" +"/quickstart-pytorch`." -#: ../../source/tutorial-quickstart-xgboost.rst:1144 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"This defines various options for client data partitioning. Besides, " -"clients also have an option to conduct evaluation on centralised test set" -" by setting :code:`--centralised-eval`, as well as an option to perform " -"scaled learning rate based on the number of clients by setting :code" -":`--scaled-lr`." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch Lightning to train an Auto Encoder model on MNIST." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1148 -msgid "We also have an argument parser for simulation:" -msgstr "" +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 +msgid "Quickstart PyTorch Lightning" +msgstr "Démarrage rapide de PyTorch Lightning" -#: ../../source/tutorial-quickstart-xgboost.rst:1226 -msgid "This integrates all arguments for both client and server sides." +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 +#, fuzzy +msgid "" +"Let's build a horizontal federated learning system using PyTorch " +"Lightning and Flower!" msgstr "" +"Construisons un système d'apprentissage fédéré en utilisant PyTorch " +"Lightning et Flower !" -#: ../../source/tutorial-quickstart-xgboost.rst:1229 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 #, fuzzy -msgid "Example commands" -msgstr "Exemples de PyTorch" +msgid "" +"Please refer to the `full code example " +"`_ to learn more." +msgstr "" +"Réfère-toi à l'exemple de code complet " +"`_ pour en savoir plus." -#: ../../source/tutorial-quickstart-xgboost.rst:1231 +#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 " -"clients with exponential distribution for 50 rounds, we first start the " -"server as below:" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with scikit-learn to train a linear regression model." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1238 -#, fuzzy -msgid "Then, on each client terminal, we start the clients:" -msgstr "Ouvre un autre terminal et démarre le deuxième client :" +#: ../../source/tutorial-quickstart-scikitlearn.rst:5 +msgid "Quickstart scikit-learn" +msgstr "Démarrage rapide de scikit-learn" -#: ../../source/tutorial-quickstart-xgboost.rst:1244 -msgid "To run the same experiment with Flower simulation:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:10 +msgid "" +"In this tutorial, we will learn how to train a :code:`Logistic " +"Regression` model on MNIST using Flower and scikit-learn." msgstr "" +"Dans ce tutoriel, nous allons apprendre à former un :code:`modèle de " +"régression logistique` sur MNIST en utilisant Flower et scikit-learn." -#: ../../source/tutorial-quickstart-xgboost.rst:1250 +#: ../../source/tutorial-quickstart-scikitlearn.rst:12 #, fuzzy msgid "" -"The full `code `_ for this comprehensive example can be found in" -" :code:`examples/xgboost-comprehensive`." +"It is recommended to create a virtual environment and run everything " +"within this :doc:`virtualenv `." msgstr "" -"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " -"premier système d'apprentissage fédéré. Le code source complet " -"`_ de cet exemple se trouve dans :code:`examples" -"/quickstart-mxnet`." - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 -#, fuzzy -msgid "Build a strategy from scratch" -msgstr "Élaborer une stratégie à partir de zéro" +"Il est recommandé de créer un environnement virtuel et de tout exécuter " +"dans ce `virtualenv `_." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 -#, fuzzy +#: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"Welcome to the third part of the Flower federated learning tutorial. In " -"previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies " -"can be used to customize the execution on both the server and the clients" -" (`part 2 `__)." +"*Clients* are responsible for generating individual model parameter " +"updates for the model based on their local datasets. These updates are " +"then sent to the *server* which will aggregate them to produce an updated" +" global model. Finally, the *server* sends this improved version of the " +"model back to each *client*. A complete cycle of parameters updates is " +"called a *round*." msgstr "" -"Bienvenue dans la troisième partie du tutoriel sur l'apprentissage fédéré" -" Flower. Dans les parties précédentes de ce tutoriel, nous avons présenté" -" l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " -"`__) " -"et nous avons appris comment les stratégies peuvent être utilisées pour " -"personnaliser l'exécution à la fois sur le serveur et sur les clients " -"(`partie 2 `__)." +"*Les clients* sont chargés de générer des mises à jour individuelles des " +"paramètres du modèle en fonction de leurs ensembles de données locales. " +"Ces mises à jour sont ensuite envoyées au *serveur* qui les agrège pour " +"produire un modèle global mis à jour. Enfin, le *serveur* renvoie cette " +"version améliorée du modèle à chaque *client*. Un cycle complet de mises " +"à jour des paramètres s'appelle un *round*." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 +#: ../../source/tutorial-quickstart-scikitlearn.rst:20 msgid "" -"In this notebook, we'll continue to customize the federated learning " -"system we built previously by creating a custom version of FedAvg (again," -" using `Flower `__ and `PyTorch " -"`__)." +"Now that we have a rough idea of what is going on, let's get started. We " +"first need to install Flower. You can do this by running:" msgstr "" -"Dans ce carnet, nous allons continuer à personnaliser le système " -"d'apprentissage fédéré que nous avons construit précédemment en créant " -"une version personnalisée de FedAvg (encore une fois, en utilisant " -"`Flower `__ et `PyTorch `__)." +"Maintenant que nous avons une idée approximative de ce qui se passe, " +"commençons. Nous devons d'abord installer Flower. Tu peux le faire en " +"lançant :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 +#: ../../source/tutorial-quickstart-scikitlearn.rst:26 +#, fuzzy +msgid "Since we want to use scikit-learn, let's go ahead and install it:" +msgstr "Puisque nous voulons utiliser scikt-learn, allons-y et installons-le :" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:32 +msgid "Or simply install all dependencies using Poetry:" +msgstr "Ou installe simplement toutes les dépendances à l'aide de Poetry :" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:42 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the Flower community on Slack to connect, ask questions, and get help: " -"`Join Slack `__ 🌼 We'd love to hear from " -"you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"Now that we have all our dependencies installed, let's run a simple " +"distributed training with two clients and one server. However, before " +"setting up the client and server, we will define all functionalities that" +" we need for our federated learning setup within :code:`utils.py`. The " +":code:`utils.py` contains different functions defining all the machine " +"learning basics:" msgstr "" -"`Star Flower on GitHub `__ ⭐️ et " -"rejoignez la communauté Flower sur Slack pour vous connecter, poser des " -"questions et obtenir de l'aide : `Join Slack `__ 🌼 Nous serions ravis d'avoir de vos nouvelles dans le canal " -"``#introductions`` ! Et si quelque chose n'est pas clair, rendez-vous sur" -" le canal ``#questions``." - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 -msgid "Let's build a new ``Strategy`` from scratch!" -msgstr "Construisons une nouvelle ``Stratégie`` à partir de zéro !" +"Maintenant que toutes nos dépendances sont installées, exécutons une " +"formation distribuée simple avec deux clients et un serveur. Cependant, " +"avant de configurer le client et le serveur, nous allons définir toutes " +"les fonctionnalités dont nous avons besoin pour notre configuration " +"d'apprentissage fédéré dans :code:`utils.py`. Le :code:`utils.py` " +"contient différentes fonctions définissant toutes les bases de " +"l'apprentissage automatique :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 -msgid "Preparation" -msgstr "Préparation" +#: ../../source/tutorial-quickstart-scikitlearn.rst:45 +msgid ":code:`get_model_parameters()`" +msgstr ":code:`get_model_parameters()`" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 -msgid "" -"Before we begin with the actual code, let's make sure that we have " -"everything we need." +#: ../../source/tutorial-quickstart-scikitlearn.rst:46 +msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" msgstr "" -"Avant de commencer le code proprement dit, assurons-nous que nous " -"disposons de tout ce dont nous avons besoin." +"Renvoie les paramètres d'un modèle de régression logistique " +":code:`sklearn`" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 -msgid "Installing dependencies" -msgstr "Installation des dépendances" +#: ../../source/tutorial-quickstart-scikitlearn.rst:47 +msgid ":code:`set_model_params()`" +msgstr ":code:`set_model_params()`" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 -msgid "First, we install the necessary packages:" -msgstr "Tout d'abord, nous installons les paquets nécessaires :" +#: ../../source/tutorial-quickstart-scikitlearn.rst:48 +#, fuzzy +msgid "Sets the parameters of a :code:`sklearn` LogisticRegression model" +msgstr "Définit les paramètres d'un modèle de régression logistique :code:`sklean`" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid ":code:`set_initial_params()`" +msgstr ":code:`set_initial_params()`" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid "Initializes the model parameters that the Flower server will ask for" +msgstr "Initialise les paramètres du modèle que le serveur de Flower demandera" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:52 msgid "" -"Now that we have all dependencies installed, we can import everything we " -"need for this tutorial:" +"Please check out :code:`utils.py` `here " +"`_ for more details. The pre-defined functions are used in" +" the :code:`client.py` and imported. The :code:`client.py` also requires " +"to import several packages such as Flower and scikit-learn:" msgstr "" -"Maintenant que toutes les dépendances sont installées, nous pouvons " -"importer tout ce dont nous avons besoin pour ce tutoriel :" +"Tu peux consulter :code:`utils.py` `ici " +"`_ pour plus de détails. Les fonctions prédéfinies sont " +"utilisées dans :code:`client.py` et importées. :code:`client.py` " +"nécessite également d'importer plusieurs paquets tels que Flower et " +"scikit-learn :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 +#: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " -"GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"Prior to local training, we need to load the MNIST dataset, a popular " +"image classification dataset of handwritten digits for machine learning, " +"and partition the dataset for FL. This can be conveniently achieved using" +" `Flower Datasets `_. The " +":code:`FederatedDataset.load_partition()` method loads the partitioned " +"training set for each partition ID defined in the :code:`--partition-id` " +"argument." msgstr "" -"Il est possible de passer à un runtime dont l'accélération GPU est " -"activée (sur Google Colab : ``Runtime > Change runtime type > Hardware " -"acclerator : GPU > Save``). Note cependant que Google Colab n'est pas " -"toujours en mesure de proposer l'accélération GPU. Si tu vois une erreur " -"liée à la disponibilité du GPU dans l'une des sections suivantes, " -"envisage de repasser à une exécution basée sur le CPU en définissant " -"``DEVICE = torch.device(\"cpu\")``. Si le runtime a activé l'accélération" -" GPU, tu devrais voir apparaître le résultat ``Training on cuda``, sinon " -"il dira ``Training on cpu``." - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 -msgid "Data loading" -msgstr "Chargement des données" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 +#: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``. We introduce a new parameter" -" ``num_clients`` which allows us to call ``load_datasets`` with different" -" numbers of clients." +"Next, the logistic regression model is defined and initialized with " +":code:`utils.set_initial_params()`." msgstr "" -"Chargeons maintenant les ensembles d'entraînement et de test CIFAR-10, " -"divisons-les en dix ensembles de données plus petits (chacun divisé en " -"ensemble d'entraînement et de validation), et enveloppons le tout dans " -"leur propre ``DataLoader``. Nous introduisons un nouveau paramètre " -"``num_clients`` qui nous permet d'appeler ``load_datasets`` avec " -"différents nombres de clients." - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 -msgid "Model training/evaluation" -msgstr "Formation/évaluation du modèle" +"Ensuite, le modèle de régression logistique est défini et initialisé avec" +" :code:`utils.set_initial_params()`." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 +#: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"Let's continue with the usual model definition (including " -"``set_parameters`` and ``get_parameters``), training and test functions:" +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to fit the logistic regression we defined earlier)." msgstr "" -"Continuons avec la définition habituelle du modèle (y compris " -"``set_parameters`` et ``get_parameters``), les fonctions d'entraînement " -"et de test :" - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 -msgid "Flower client" -msgstr "Client de Flower" +"Le serveur Flower interagit avec les clients par le biais d'une interface" +" appelée :code:`Client`. Lorsque le serveur sélectionne un client " +"particulier pour la formation, il envoie des instructions de formation " +"sur le réseau. Le client reçoit ces instructions et appelle l'une des " +"méthodes :code:`Client` pour exécuter ton code (c'est-à-dire pour ajuster" +" la régression logistique que nous avons définie plus tôt)." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 +#: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"To implement the Flower client, we (again) create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " -"``cid`` to the client and use it log additional details:" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " +"means defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" -"Pour mettre en œuvre le client Flower, nous créons (à nouveau) une sous-" -"classe de ``flwr.client.NumPyClient`` et mettons en œuvre les trois " -"méthodes ``get_parameters``, ``fit`` et ``evaluate``. Ici, nous " -"transmettons également le ``cid`` au client et l'utilisons pour consigner" -" des détails supplémentaires :" +"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " +"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" +" de travail utilise scikit-learn. Mettre en œuvre :code:`NumPyClient` " +"signifie généralement définir les méthodes suivantes " +"(:code:`set_parameters` est cependant facultatif) :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 -msgid "Let's test what we have so far before we continue:" -msgstr "Testons ce que nous avons jusqu'à présent avant de continuer :" +#: ../../source/tutorial-quickstart-scikitlearn.rst:122 +msgid "is directly imported with :code:`utils.set_model_params()`" +msgstr "est directement importé avec :code:`utils.set_model_params()`" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 -msgid "Build a Strategy from scratch" -msgstr "Élaborer une stratégie à partir de zéro" +#: ../../source/tutorial-quickstart-scikitlearn.rst:130 +msgid "The methods can be implemented in the following way:" +msgstr "Les méthodes peuvent être mises en œuvre de la manière suivante :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 +#: ../../source/tutorial-quickstart-scikitlearn.rst:153 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher" -" learning rate (potentially also other hyperparameters) to the optimizer " -"of a fraction of the clients. We will keep the sampling of the clients as" -" it is in ``FedAvg`` and then change the configuration dictionary (one of" -" the ``FitIns`` attributes)." +"We can now create an instance of our class :code:`MnistClient` and add " +"one line to actually run this client:" msgstr "" -"Remplaçons la méthode ``configure_fit`` de façon à ce qu'elle transmette " -"un taux d'apprentissage plus élevé (potentiellement aussi d'autres " -"hyperparamètres) à l'optimiseur d'une fraction des clients. Nous " -"garderons l'échantillonnage des clients tel qu'il est dans ``FedAvg`` et " -"changerons ensuite le dictionnaire de configuration (l'un des attributs " -"``FitIns``)." +"Nous pouvons maintenant créer une instance de notre classe " +":code:`MnistClient` et ajouter une ligne pour exécuter ce client :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 +#: ../../source/tutorial-quickstart-scikitlearn.rst:160 +#, fuzzy msgid "" -"The only thing left is to use the newly created custom Strategy " -"``FedCustom`` when starting the experiment:" +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" +" the client which server to connect to. In our case we can run the server" +" and the client on the same machine, therefore we use " +":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we pass to the client." msgstr "" -"Il ne reste plus qu'à utiliser la stratégie personnalisée nouvellement " -"créée ``FedCustom`` lors du démarrage de l'expérience :" - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 -msgid "Recap" -msgstr "Récapitulation" +"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" +" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " +"chaîne :code:`\"0.0.0:8080\"` indique au client à quel serveur se " +"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " +"sur la même machine, c'est pourquoi nous utilisons " +":code:`\"0.0.0:8080\"`. Si nous exécutons une charge de travail " +"véritablement fédérée avec le serveur et les clients s'exécutant sur des " +"machines différentes, tout ce qui doit changer est :code:`server_address`" +" que nous transmettons au client." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 +#: ../../source/tutorial-quickstart-scikitlearn.rst:169 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom" -" strategy enables granular control over client node configuration, result" -" aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``." -" To make custom strategies even more powerful, you can pass custom " -"functions to the constructor of your new class (``__init__``) and then " -"call these functions whenever needed." +"The following Flower server is a little bit more advanced and returns an " +"evaluation function for the server-side evaluation. First, we import " +"again all required libraries such as Flower and scikit-learn." msgstr "" -"Dans ce carnet, nous avons vu comment mettre en place une stratégie " -"personnalisée. Une stratégie personnalisée permet un contrôle granulaire " -"sur la configuration des nœuds clients, l'agrégation des résultats, et " -"bien plus encore. Pour définir une stratégie personnalisée, il te suffit " -"d'écraser les méthodes abstraites de la classe de base (abstraite) " -"``Strategy``. Pour rendre les stratégies personnalisées encore plus " -"puissantes, tu peux passer des fonctions personnalisées au constructeur " -"de ta nouvelle classe (``__init__``) et appeler ensuite ces fonctions à " -"chaque fois que c'est nécessaire." +"Le serveur Flower suivant est un peu plus avancé et renvoie une fonction " +"d'évaluation pour l'évaluation côté serveur. Tout d'abord, nous importons" +" à nouveau toutes les bibliothèques requises telles que Flower et scikit-" +"learn." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 -msgid "" -"Before you continue, make sure to join the Flower community on Slack: " -"`Join Slack `__" -msgstr "" -"Avant de continuer, n'oublie pas de rejoindre la communauté Flower sur " -"Slack : `Join Slack `__" +#: ../../source/tutorial-quickstart-scikitlearn.rst:172 +msgid ":code:`server.py`, import Flower and start the server:" +msgstr ":code:`server.py`, importe Flower et démarre le serveur :" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 +#: ../../source/tutorial-quickstart-scikitlearn.rst:185 +#, fuzzy msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd " -"also love to hear who you are in ``#introductions``!" +"The number of federated learning rounds is set in :code:`fit_round()` and" +" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"function is called after each federated learning round and gives you " +"information about loss and accuracy. Note that we also make use of Flower" +" Datasets here to load the test split of the MNIST dataset for server-" +"side evaluation." msgstr "" -"Il existe un canal dédié aux ``questions`` si vous avez besoin d'aide, " -"mais nous aimerions aussi savoir qui vous êtes dans ``#introductions`` !" +"Le nombre de tours d'apprentissage fédéré est défini dans " +":code:`fit_round()` et l'évaluation est définie dans " +":code:`get_evaluate_fn()`. La fonction d'évaluation est appelée après " +"chaque tour d'apprentissage fédéré et te donne des informations sur la " +"perte et la précision." -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 -#, fuzzy +#: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 " -"`__ introduces ``Client``, the flexible API underlying " -"``NumPyClient``." +"The :code:`main` contains the server-side parameter initialization " +":code:`utils.set_initial_params()` as well as the aggregation strategy " +":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " +"federated averaging (or FedAvg), with two clients and evaluation after " +"each federated learning round. The server can be started with the command" +" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." msgstr "" -"Le `Tutoriel d'apprentissage fédéré Flower - Partie 4 " -"`__ présente ``Client``, l'API flexible qui sous-tend " -"``NumPyClient``." - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 -#, fuzzy -msgid "Customize the client" -msgstr "Création du client IMDBC" +"Le :code:`main` contient l'initialisation des paramètres côté serveur " +":code:`utils.set_initial_params()` ainsi que la stratégie d'agrégation " +":code:`fl.server.strategy:FedAvg()`. La stratégie est celle par défaut, " +"la moyenne fédérée (ou FedAvg), avec deux clients et une évaluation après" +" chaque tour d'apprentissage fédéré. Le serveur peut être démarré avec la" +" commande :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 -#, fuzzy +#: ../../source/tutorial-quickstart-scikitlearn.rst:232 msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In " -"the previous parts of this tutorial, we introduced federated learning " -"with PyTorch and Flower (`part 1 `__), we learned how " -"strategies can be used to customize the execution on both the server and " -"the clients (`part 2 `__), and we built our own " -"custom strategy from scratch (`part 3 `__)." +"With both client and server ready, we can now run everything and see " +"federated learning in action. Federated learning systems usually have a " +"server and multiple clients. We, therefore, have to start the server " +"first:" msgstr "" -"Bienvenue dans la quatrième partie du tutoriel sur l'apprentissage fédéré" -" Flower. Dans les parties précédentes de ce tutoriel, nous avons présenté" -" l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " -"`__), " -"nous avons appris comment les stratégies peuvent être utilisées pour " -"personnaliser l'exécution à la fois sur le serveur et les clients " -"(`partie 2 `__), et nous avons construit notre propre stratégie " -"personnalisée à partir de zéro (`partie 3 - WIP " -"`__)." +"Le client et le serveur étant prêts, nous pouvons maintenant tout lancer " +"et voir l'apprentissage fédéré en action. Les systèmes d'apprentissage " +"fédéré ont généralement un serveur et plusieurs clients. Nous devons donc" +" commencer par lancer le serveur :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 +#: ../../source/tutorial-quickstart-scikitlearn.rst:286 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new " -"baseclass for building clients, simply named ``Client``. In previous " -"parts of this tutorial, we've based our client on ``NumPyClient``, a " -"convenience class which makes it easy to work with machine learning " -"libraries that have good NumPy interoperability. With ``Client``, we gain" -" a lot of flexibility that we didn't have before, but we'll also have to " -"do a few things the we didn't have to do before." +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples/sklearn-logreg-" +"mnist`." msgstr "" -"Dans ce carnet, nous revisitons `NumPyClient`` et introduisons une " -"nouvelle classe de base pour construire des clients, simplement appelée " -"`Client``. Dans les parties précédentes de ce tutoriel, nous avons basé " -"notre client sur ``NumPyClient``, une classe de commodité qui facilite le" -" travail avec les bibliothèques d'apprentissage automatique qui ont une " -"bonne interopérabilité NumPy. Avec ``Client``, nous gagnons beaucoup de " -"flexibilité que nous n'avions pas auparavant, mais nous devrons également" -" faire quelques choses que nous n'avions pas à faire auparavant." +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le code source complet " +"`_ de cet exemple se trouve dans :code:`examples/sklearn-logreg-" +"mnist`." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 +#: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"Let's go deeper and see what it takes to move from ``NumPyClient`` to " -"``Client``!" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with TensorFlow to train a MobilNetV2 model on CIFAR-10." msgstr "" -"Allons plus loin et voyons ce qu'il faut faire pour passer de " -"``NumPyClient`` à ``Client`` !" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 -msgid "Step 0: Preparation" -msgstr "Étape 0 : Préparation" +#: ../../source/tutorial-quickstart-tensorflow.rst:5 +msgid "Quickstart TensorFlow" +msgstr "Démarrage rapide de TensorFlow" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 -msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``." +#: ../../source/tutorial-quickstart-tensorflow.rst:13 +msgid "Let's build a federated learning system in less than 20 lines of code!" msgstr "" -"Chargeons maintenant les ensembles d'entraînement et de test CIFAR-10, " -"divisons-les en dix ensembles de données plus petits (chacun divisé en " -"ensemble d'entraînement et de validation) et enveloppons le tout dans " -"leur propre ``DataLoader``." +"Construisons un système d'apprentissage fédéré en moins de 20 lignes de " +"code !" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 -msgid "Step 1: Revisiting NumPyClient" -msgstr "Étape 1 : Revoir NumPyClient" +#: ../../source/tutorial-quickstart-tensorflow.rst:15 +msgid "Before Flower can be imported we have to install it:" +msgstr "Avant de pouvoir importer une fleur, nous devons l'installer :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 +#: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"So far, we've implemented our client by subclassing " -"``flwr.client.NumPyClient``. The three methods we implemented are " -"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " -"creation of instances of this class in a function called ``client_fn``:" +"Since we want to use the Keras API of TensorFlow (TF), we have to install" +" TF as well:" msgstr "" -"Jusqu'à présent, nous avons implémenté notre client en sous-classant " -"``flwr.client.NumPyClient``. Les trois méthodes que nous avons " -"implémentées sont ``get_parameters``, ``fit`` et ``evaluate``. Enfin, " -"nous enveloppons la création d'instances de cette classe dans une " -"fonction appelée ``client_fn`` :" +"Comme nous voulons utiliser l'API Keras de TensorFlow (TF), nous devons " +"également installer TF :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 -msgid "" -"We've seen this before, there's nothing new so far. The only *tiny* " -"difference compared to the previous notebook is naming, we've changed " -"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " -"``numpyclient_fn``. Let's run it to see the output we get:" +#: ../../source/tutorial-quickstart-tensorflow.rst:31 +msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" msgstr "" -"Nous avons déjà vu cela auparavant, il n'y a rien de nouveau jusqu'à " -"présent. La seule *petite* différence par rapport au carnet précédent est" -" le nommage, nous avons changé ``FlowerClient`` en ``FlowerNumPyClient`` " -"et ``client_fn`` en ``numpyclient_fn``. Exécutons-le pour voir la sortie " -"que nous obtenons :" +"Ensuite, dans un fichier appelé :code:`client.py`, importe Flower et " +"TensorFlow :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 +#: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"This works as expected, two clients are training for three rounds of " -"federated learning." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image" +" classification dataset for machine learning. The call to " +":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " +"it locally, and then returns the entire training and test set as NumPy " +"ndarrays." msgstr "" -"Cela fonctionne comme prévu, deux clients s'entraînent pour trois tours " -"d'apprentissage fédéré." +"Nous utilisons les utilitaires Keras de TF pour charger CIFAR10, un " +"ensemble de données de classification d'images colorées populaire pour " +"l'apprentissage automatique. L'appel à " +":code:`tf.keras.datasets.cifar10.load_data()` télécharge CIFAR10, le met " +"en cache localement, puis renvoie l'ensemble d'entraînement et de test " +"sous forme de NumPy ndarrays." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 +#: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"Let's dive a little bit deeper and discuss how Flower executes this " -"simulation. Whenever a client is selected to do some work, " -"``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and " -"the data)." +"Next, we need a model. For the purpose of this tutorial, we use " +"MobilNetV2 with 10 output classes:" msgstr "" -"Plongeons un peu plus profondément et discutons de la façon dont Flower " -"exécute cette simulation. Chaque fois qu'un client est sélectionné pour " -"effectuer un travail, ``start_simulation`` appelle la fonction " -"``numpyclient_fn`` pour créer une instance de notre ``FlowerNumPyClient``" -" (en même temps qu'il charge le modèle et les données)." +"Ensuite, nous avons besoin d'un modèle. Pour les besoins de ce tutoriel, " +"nous utilisons MobilNetV2 avec 10 classes de sortie :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 +#: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " -"makes it look like a subclass of ``flwr.client.Client``, not " -"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " -"know how to handle ``NumPyClient``'s, it only knows how to handle " -"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " -"top of ``Client``." +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses Keras. The :code:`NumPyClient` interface defines three " +"methods which can be implemented in the following way:" msgstr "" -"Mais voici la partie la plus surprenante : Flower n'utilise pas " -"directement l'objet `FlowerNumPyClient`. Au lieu de cela, il enveloppe " -"l'objet pour le faire ressembler à une sous-classe de " -"`flwr.client.Client`, et non de `flwr.client.NumPyClient`. En fait, le " -"noyau de Flower ne sait pas comment gérer les `NumPyClient`, il sait " -"seulement comment gérer les `Client`. `NumPyClient` est juste une " -"abstraction de commodité construite au dessus de `Client`." +"Flower fournit une classe de commodité appelée :code:`NumPyClient` qui " +"facilite la mise en œuvre de l'interface :code:`Client` lorsque ta charge" +" de travail utilise Keras. L'interface :code:`NumPyClient` définit trois " +"méthodes qui peuvent être mises en œuvre de la manière suivante :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 +#: ../../source/tutorial-quickstart-tensorflow.rst:135 +msgid "Each client will have its own dataset." +msgstr "Chaque client aura son propre ensemble de données." + +#: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on " -"top of ``Client``." +"You should now see how the training does in the very first terminal (the " +"one that started the server):" msgstr "" -"Au lieu de construire par-dessus `NumPyClient``, nous pouvons construire " -"directement par-dessus `Client``." +"Tu devrais maintenant voir comment la formation se déroule dans le tout " +"premier terminal (celui qui a démarré le serveur) :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 -msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" -msgstr "Étape 2 : Passer de ``NumPyClient`` à ``Client``" +#: ../../source/tutorial-quickstart-tensorflow.rst:169 +#, fuzzy +msgid "" +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this can be found in :code:`examples" +"/quickstart-tensorflow/client.py`." +msgstr "" +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le `code source complet " +"`_ pour cela se trouve dans :code:`examples" +"/quickstart-tensorflow/client.py`." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 +#: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Let's try to do the same thing using ``Client`` instead of " -"``NumPyClient``." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with XGBoost to train classification models on trees." msgstr "" -"Essayons de faire la même chose en utilisant ``Client`` au lieu de " -"``NumPyClient``." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 +#: ../../source/tutorial-quickstart-xgboost.rst:5 +msgid "Quickstart XGBoost" +msgstr "Démarrage rapide XGBoost" + +#: ../../source/tutorial-quickstart-xgboost.rst:14 +#, fuzzy +msgid "Federated XGBoost" +msgstr "Formation fédérée" + +#: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta " -"make sure our new ``Client``-based client works, right?" +"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " +"implementation of gradient-boosted decision tree (**GBDT**), that " +"maximises the computational boundaries for boosted tree methods. It's " +"primarily designed to enhance both the performance and computational " +"speed of machine learning models. In XGBoost, trees are constructed " +"concurrently, unlike the sequential approach taken by GBDT." msgstr "" -"Avant de discuter du code plus en détail, essayons de l'exécuter ! Nous " -"devons nous assurer que notre nouveau client basé sur le ``Client`` " -"fonctionne, n'est-ce pas ?" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 +#: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" -"That's it, we're now using ``Client``. It probably looks similar to what " -"we've done with ``NumPyClient``. So what's the difference?" +"Often, for tabular data on medium-sized datasets with fewer than 10k " +"training examples, XGBoost surpasses the results of deep learning " +"techniques." msgstr "" -"Voilà, nous utilisons maintenant ``Client``. Cela ressemble probablement " -"à ce que nous avons fait avec ``NumPyClient``. Alors quelle est la " -"différence ?" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 +#: ../../source/tutorial-quickstart-xgboost.rst:23 +#, fuzzy +msgid "Why federated XGBoost?" +msgstr "Qu'est-ce que l'apprentissage fédéré ?" + +#: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " -"serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." +"Indeed, as the demand for data privacy and decentralized learning grows, " +"there's an increasing requirement to implement federated XGBoost systems " +"for specialised applications, like survival analysis and financial fraud " +"detection." msgstr "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " -"serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 +#: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It " -"can do so because it expects you to return parameters as NumPy ndarray's," -" and it knows how to handle these. This makes working with machine " -"learning libraries that have good NumPy support (most of them) a breeze." +"Federated learning ensures that raw data remains on the local device, " +"making it an attractive approach for sensitive domains where data " +"security and privacy are paramount. Given the robustness and efficiency " +"of XGBoost, combining it with federated learning offers a promising " +"solution for these specific challenges." msgstr "" -"La seule *vraie* différence entre Client et NumPyClient est que " -"NumPyClient s'occupe de la sérialisation et de la désérialisation pour " -"toi. Il peut le faire parce qu'il s'attend à ce que tu renvoies des " -"paramètres sous forme de NumPy ndarray, et il sait comment les gérer. " -"Cela permet de travailler avec des bibliothèques d'apprentissage " -"automatique qui ont une bonne prise en charge de NumPy (la plupart " -"d'entre elles) en un clin d'œil." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 +#: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " -"``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." +"In this tutorial we will learn how to train a federated XGBoost model on " +"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " +"example (`full code xgboost-quickstart " +"`_)" +" with two *clients* and one *server* to demonstrate how federated XGBoost" +" works, and then we dive into a more complex example (`full code xgboost-" +"comprehensive `_) to run various experiments." msgstr "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " -"``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 -msgid "Step 3: Custom serialization" -msgstr "Étape 3 : Sérialisation personnalisée" +#: ../../source/tutorial-quickstart-xgboost.rst:37 +msgid "Environment Setup" +msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 +#: ../../source/tutorial-quickstart-xgboost.rst:41 msgid "" -"Here we will explore how to implement custom serialization with a simple " -"example." +"We first need to install Flower and Flower Datasets. You can do this by " +"running :" msgstr "" -"Nous allons ici explorer comment mettre en œuvre une sérialisation " -"personnalisée à l'aide d'un exemple simple." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 +#: ../../source/tutorial-quickstart-xgboost.rst:47 +#, fuzzy msgid "" -"But first what is serialization? Serialization is just the process of " -"converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an " -"object. This is very useful for network communication. Indeed, without " -"serialization, you could not just a Python object through the internet." -msgstr "" -"Mais d'abord, qu'est-ce que la sérialisation ? La sérialisation est " -"simplement le processus de conversion d'un objet en octets bruts, et tout" -" aussi important, la désérialisation est le processus de reconversion des" -" octets bruts en objet. Ceci est très utile pour la communication réseau." -" En effet, sans la sérialisation, tu ne pourrais pas faire passer un " -"objet Python par Internet." +"Since we want to use :code:`xgboost` package to build up XGBoost trees, " +"let's go ahead and install :code:`xgboost`:" +msgstr "Puisque nous voulons utiliser scikt-learn, allons-y et installons-le :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 +#: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"Federated Learning relies heavily on internet communication for training " -"by sending Python objects back and forth between the clients and the " -"server. This means that serialization is an essential part of Federated " -"Learning." +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. Now that we have all our " +"dependencies installed, let's run a simple distributed training with two " +"clients and one server." msgstr "" -"L'apprentissage fédéré s'appuie fortement sur la communication Internet " -"pour la formation en envoyant des objets Python dans les deux sens entre " -"les clients et le serveur, ce qui signifie que la sérialisation est un " -"élément essentiel de l'apprentissage fédéré." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 +#: ../../source/tutorial-quickstart-xgboost.rst:60 +#, fuzzy msgid "" -"In the following section, we will write a basic example where instead of " -"sending a serialized version of our ``ndarray``\\ s containing our " -"parameters, we will first convert the ``ndarray`` into sparse matrices, " -"before sending them. This technique can be used to save bandwidth, as in " -"certain cases where the weights of a model are sparse (containing many 0 " -"entries), converting them to a sparse matrix can greatly improve their " -"bytesize." +"In a file called :code:`client.py`, import xgboost, Flower, Flower " +"Datasets and other related functions:" msgstr "" -"Dans la section suivante, nous allons écrire un exemple de base où, au " -"lieu d'envoyer une version sérialisée de nos ``ndarray`` contenant nos " -"paramètres, nous allons d'abord convertir les ``ndarray`` en matrices " -"éparses, avant de les envoyer. Cette technique peut être utilisée pour " -"économiser de la bande passante, car dans certains cas où les poids d'un " -"modèle sont épars (contenant de nombreuses entrées 0), les convertir en " -"une matrice éparse peut grandement améliorer leur taille en octets." +"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " +"liés à PyTorch :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 -msgid "Our custom serialization/deserialization functions" -msgstr "Nos fonctions de sérialisation/désérialisation personnalisées" +#: ../../source/tutorial-quickstart-xgboost.rst:87 +msgid "Dataset partition and hyper-parameter selection" +msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 +#: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"This is where the real serialization/deserialization will happen, " -"especially in ``ndarray_to_sparse_bytes`` for serialization and " -"``sparse_bytes_to_ndarray`` for deserialization." +"Prior to local training, we require loading the HIGGS dataset from Flower" +" Datasets and conduct data partitioning for FL:" msgstr "" -"C'est là que la véritable sérialisation/désérialisation se produira, en " -"particulier dans ``ndarray_to_sparse_bytes`` pour la sérialisation et " -"``sparse_bytes_to_ndarray`` pour la désérialisation." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 +#: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert " -"our arrays." +"In this example, we split the dataset into two partitions with uniform " +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " +"the partition for the given client based on :code:`node_id`:" msgstr "" -"Notez que nous avons importé la bibliothèque ``scipy.sparse`` afin de " -"convertir nos tableaux." - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 -msgid "Client-side" -msgstr "Côté client" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 +#: ../../source/tutorial-quickstart-xgboost.rst:121 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " -"will just have to call our custom functions in our " -"``flwr.client.Client``." +"After that, we do train/test splitting on the given partition (client's " +"local data), and transform data format for :code:`xgboost` package." msgstr "" -"Pour pouvoir sérialiser nos ``ndarray`` en paramètres sparse, il nous " -"suffira d'appeler nos fonctions personnalisées dans notre " -"``flwr.client.Client``." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 +#: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` " -"defined above." +"The functions of :code:`train_test_split` and " +":code:`transform_dataset_to_dmatrix` are defined as below:" msgstr "" -"En effet, dans ``get_parameters`` nous devons sérialiser les paramètres " -"que nous avons obtenus de notre réseau en utilisant nos " -"``ndarrays_to_sparse_parameters`` personnalisés définis ci-dessus." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 -msgid "" -"In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we " -"need to serialize our local results with " -"``ndarrays_to_sparse_parameters``." +#: ../../source/tutorial-quickstart-xgboost.rst:158 +msgid "Finally, we define the hyper-parameters used for XGBoost training." msgstr "" -"Dans ``fit``, nous devons d'abord désérialiser les paramètres provenant " -"du serveur en utilisant notre ``sparse_parameters_to_ndarrays`` " -"personnalisé, puis nous devons sérialiser nos résultats locaux avec " -"``ndarrays_to_sparse_parameters``." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +#: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters " -"with our custom function." +"The :code:`num_local_round` represents the number of iterations for local" +" tree boost. We use CPU for the training in default. One can shift it to " +"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " +"evaluation metric." msgstr "" -"Dans ``evaluate``, nous n'aurons besoin que de désérialiser les " -"paramètres globaux avec notre fonction personnalisée." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 -msgid "Server-side" -msgstr "Côté serveur" +#: ../../source/tutorial-quickstart-xgboost.rst:181 +msgid "Flower client definition for XGBoost" +msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 +#: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change " -"the serialization and deserialization here, we only need to reimplement " -"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" -" functions of the strategy will be inherited from the super class " -"``FedAvg``." +"After loading the dataset we define the Flower client. We follow the " +"general rule to define :code:`XgbClient` class inherited from " +":code:`fl.client.Client`." msgstr "" -"Pour cet exemple, nous utiliserons simplement ``FedAvg`` comme stratégie." -" Pour modifier la sérialisation et la désérialisation ici, il suffit de " -"réimplémenter les fonctions ``evaluate`` et ``aggregate_fit`` de " -"``FedAvg``. Les autres fonctions de la stratégie seront héritées de la " -"super-classe ``FedAvg``." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 -msgid "As you can see only one line as change in ``evaluate``:" -msgstr "Comme tu peux le voir, seule une ligne a été modifiée dans ``evaluate`` :" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 +#: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" -"And for ``aggregate_fit``, we will first deserialize every result we " -"received:" +"The :code:`self.bst` is used to keep the Booster objects that remain " +"consistent across rounds, allowing them to store predictions from trees " +"integrated in earlier rounds and maintain other essential data structures" +" for training." msgstr "" -"Et pour ``aggregate_fit``, nous allons d'abord désérialiser chaque " -"résultat que nous avons reçu :" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 -msgid "And then serialize the aggregated result:" -msgstr "Puis sérialise le résultat agrégé :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 -msgid "We can now run our custom serialization example!" +#: ../../source/tutorial-quickstart-xgboost.rst:196 +msgid "" +"Then, we override :code:`get_parameters`, :code:`fit` and " +":code:`evaluate` methods insides :code:`XgbClient` class as follows." msgstr "" -"Nous pouvons maintenant exécuter notre exemple de sérialisation " -"personnalisée !" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 +#: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" -"In this part of the tutorial, we've seen how we can build clients by " -"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine " -"learning libraries that have good NumPy interoperability. ``Client`` is a" -" more flexible abstraction that allows us to do things that are not " -"possible in ``NumPyClient``. In order to do so, it requires us to handle " -"parameter serialization and deserialization ourselves." +"Unlike neural network training, XGBoost trees are not started from a " +"specified random weights. In this case, we do not use " +":code:`get_parameters` and :code:`set_parameters` to initialise model " +"parameters for XGBoost. As a result, let's return an empty tensor in " +":code:`get_parameters` when it is called by the server at the first " +"round." msgstr "" -"Dans cette partie du tutoriel, nous avons vu comment construire des " -"clients en sous-classant soit ``NumPyClient``, soit ``Client``. " -"``NumPyClient`` est une abstraction de commodité qui facilite le travail " -"avec les bibliothèques d'apprentissage automatique qui ont une bonne " -"interopérabilité NumPy. ``Client`` est une abstraction plus flexible qui " -"nous permet de faire des choses qui ne sont pas possibles dans " -"``NumPyClient``. Pour ce faire, elle nous oblige à gérer nous-mêmes la " -"sérialisation et la désérialisation des paramètres." -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 +#: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"This is the final part of the Flower tutorial (for now!), " -"congratulations! You're now well equipped to understand the rest of the " -"documentation. There are many topics we didn't cover in the tutorial, we " -"recommend the following resources:" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " +"up the first set of trees. the returned Booster object and config are " +"stored in :code:`self.bst` and :code:`self.config`, respectively. From " +"the second round, we load the global model sent from server to " +":code:`self.bst`, and then update model weights on local training data " +"with function :code:`local_boost` as follows:" msgstr "" -"C'est la dernière partie du tutoriel Flower (pour l'instant !), " -"félicitations ! Tu es maintenant bien équipé pour comprendre le reste de " -"la documentation. Il y a de nombreux sujets que nous n'avons pas abordés " -"dans le tutoriel, nous te recommandons les ressources suivantes :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 -msgid "`Read Flower Docs `__" -msgstr "`Lire les docs sur les fleurs `__" +#: ../../source/tutorial-quickstart-xgboost.rst:269 +msgid "" +"Given :code:`num_local_round`, we update trees by calling " +":code:`self.bst.update` method. After training, the last " +":code:`N=num_local_round` trees will be extracted to send to the server." +msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 +#: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"`Check out Flower Code Examples " -"`__" +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " +"conduct evaluation on valid set. The AUC value will be returned." msgstr "" -"`Check out Flower Code Examples " -"`__" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 +#: ../../source/tutorial-quickstart-xgboost.rst:294 #, fuzzy msgid "" -"`Use Flower Baselines for your research " -"`__" +"Now, we can create an instance of our class :code:`XgbClient` and add one" +" line to actually run this client:" msgstr "" -"`Utilise les lignes de base des fleurs pour ta recherche " -"`__" +"Nous pouvons maintenant créer une instance de notre classe " +":code:`MnistClient` et ajouter une ligne pour exécuter ce client :" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 +#: ../../source/tutorial-quickstart-xgboost.rst:300 #, fuzzy msgid "" -"`Watch Flower Summit 2023 videos `__" +"That's it for the client. We only have to implement :code:`Client`and " +"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " +"tells the client which server to connect to. In our case we can run the " +"server and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" -"`Regardez les vidéos du Flower Summit 2022 `__" +"C'est tout pour le client. Il nous suffit d'implémenter :code:`Client` ou" +" :code:`NumPyClient` et d'appeler :code:`fl.client.start_client()`. La " +"chaîne :code:`\"[: :]:8080\"` indique au client à quel serveur se " +"connecter. Dans notre cas, nous pouvons exécuter le serveur et le client " +"sur la même machine, c'est pourquoi nous utilisons :code:`\"[: " +":]:8080\"`. Si nous exécutons une charge de travail véritablement fédérée" +" avec le serveur et les clients fonctionnant sur des machines " +"différentes, tout ce qui doit changer est l'adresse " +":code:`server_address` vers laquelle nous dirigeons le client." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 -msgid "Get started with Flower" +#: ../../source/tutorial-quickstart-xgboost.rst:311 +#, fuzzy +msgid "" +"These updates are then sent to the *server* which will aggregate them to " +"produce a better model. Finally, the *server* sends this improved version" +" of the model back to each *client* to finish a complete FL round." msgstr "" +"*Les clients* sont chargés de générer des mises à jour de poids " +"individuelles pour le modèle en fonction de leurs ensembles de données " +"locales. Ces mises à jour sont ensuite envoyées au *serveur* qui les " +"agrège pour produire un meilleur modèle. Enfin, le *serveur* renvoie " +"cette version améliorée du modèle à chaque *client*. Un cycle complet de " +"mises à jour de poids s'appelle un *round*." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 -msgid "Welcome to the Flower federated learning tutorial!" -msgstr "Bienvenue au tutoriel sur l'apprentissage fédéré de la fleur !" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 +#: ../../source/tutorial-quickstart-xgboost.rst:314 #, fuzzy msgid "" -"In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In " -"part 1, we use PyTorch for the model training pipeline and data loading. " -"In part 2, we continue to federate the PyTorch-based pipeline using " -"Flower." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from " +":code:`flwr.server.strategy`." msgstr "" -"Dans ce carnet, nous allons construire un système d'apprentissage fédéré " -"en utilisant Flower et PyTorch. Dans la première partie, nous utilisons " -"PyTorch pour le pipeline d'entraînement des modèles et le chargement des " -"données. Dans la deuxième partie, nous continuons à fédérer le pipeline " -"basé sur PyTorch en utilisant Flower." +"Dans un fichier appelé :code:`client.py`, importe Flower et les paquets " +"liés au MXNet :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 -msgid "Let's get stated!" -msgstr "Allons-y, déclarons-le !" +#: ../../source/tutorial-quickstart-xgboost.rst:316 +msgid "We first define a strategy for XGBoost bagging aggregation." +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 +#: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"Before we begin with any actual code, let's make sure that we have " -"everything we need." +"We use two clients for this example. An " +":code:`evaluate_metrics_aggregation` function is defined to collect and " +"wighted average the AUC values from clients." msgstr "" -"Avant de commencer à coder, assurons-nous que nous disposons de tout ce " -"dont nous avons besoin." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 +#: ../../source/tutorial-quickstart-xgboost.rst:342 #, fuzzy -msgid "" -"Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " -"(``flwr``):" +msgid "Then, we start the server:" +msgstr "Démarrer le serveur" + +#: ../../source/tutorial-quickstart-xgboost.rst:354 +msgid "Tree-based bagging aggregation" msgstr "" -"Ensuite, nous installons les paquets nécessaires pour PyTorch (``torch`` " -"et ``torchvision``) et Flower (``flwr``) :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" -" GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"You must be curious about how bagging aggregation works. Let's look into " +"the details." msgstr "" -"Il est possible de passer à un runtime dont l'accélération GPU est " -"activée (sur Google Colab : ``Runtime > Change runtime type > Hardware " -"acclerator : GPU > Save``). Note cependant que Google Colab n'est pas " -"toujours en mesure de proposer l'accélération GPU. Si tu vois une erreur " -"liée à la disponibilité du GPU dans l'une des sections suivantes, " -"envisage de repasser à une exécution basée sur le CPU en définissant " -"``DEVICE = torch.device(\"cpu\")``. Si le runtime a activé l'accélération" -" GPU, tu devrais voir apparaître le résultat ``Training on cuda``, sinon " -"il dira ``Training on cpu``." - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 -msgid "Loading the data" -msgstr "Chargement des données" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"Federated learning can be applied to many different types of tasks across" -" different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular " -"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " -"distinguish between images from ten different classes: 'airplane', " -"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " -"'truck'." +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " +":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." +" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " +"and :code:`evaluate` methods as follows:" msgstr "" -"L'apprentissage fédéré peut être appliqué à de nombreux types de tâches " -"dans différents domaines. Dans ce tutoriel, nous présentons " -"l'apprentissage fédéré en formant un simple réseau neuronal " -"convolutionnel (CNN) sur l'ensemble de données populaire CIFAR-10. " -"CIFAR-10 peut être utilisé pour former des classificateurs d'images qui " -"font la distinction entre les images de dix classes différentes :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 +#: ../../source/tutorial-quickstart-xgboost.rst:454 msgid "" -"We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the" -" original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely " -"for experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the " -"data is naturally partitioned)." +"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " +"trees by calling :code:`aggregate()` function:" msgstr "" -"Nous simulons le fait d'avoir plusieurs ensembles de données provenant de" -" plusieurs organisations (également appelé le paramètre \"cross-silo\" " -"dans l'apprentissage fédéré) en divisant l'ensemble de données CIFAR-10 " -"original en plusieurs partitions. Chaque partition représentera les " -"données d'une seule organisation. Nous faisons cela purement à des fins " -"d'expérimentation, dans le monde réel, il n'y a pas besoin de diviser les" -" données parce que chaque organisation a déjà ses propres données (les " -"données sont donc naturellement partitionnées)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" -"Each organization will act as a client in the federated learning system. " -"So having ten organizations participate in a federation means having ten " -"clients connected to the federated learning server." +"In this function, we first fetch the number of trees and the number of " +"parallel trees for the current and previous model by calling " +":code:`_get_tree_nums`. Then, the fetched information will be aggregated." +" After that, the trees (containing model weights) are aggregated to " +"generate a new tree model." msgstr "" -"Chaque organisation agira comme un client dans le système d'apprentissage" -" fédéré. Ainsi, le fait que dix organisations participent à une " -"fédération signifie que dix clients sont connectés au serveur " -"d'apprentissage fédéré :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +#: ../../source/tutorial-quickstart-xgboost.rst:518 msgid "" -"Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training " -"and test set for each edge device and wrap each of them into a PyTorch " -"``DataLoader``:" +"After traversal of all clients' models, a new global model is generated, " +"followed by the serialisation, and sending back to each client." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 -msgid "" -"We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten " -"different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4500 training examples and 500 validation examples. There's also a " -"single ``testloader`` (we did not split the test set). Again, this is " -"only necessary for building research or educational systems, actual " -"federated learning systems have their data naturally distributed across " -"multiple partitions." +#: ../../source/tutorial-quickstart-xgboost.rst:523 +msgid "Launch Federated XGBoost!" msgstr "" -"Nous avons maintenant une liste de dix ensembles de formation et dix " -"ensembles de validation (``trainloaders`` et ``valloaders``) représentant" -" les données de dix organisations différentes. Chaque paire " -"``trainloader`/``valloader`` contient 4500 exemples de formation et 500 " -"exemples de validation. Il y a également un seul ``testloader`` (nous " -"n'avons pas divisé l'ensemble de test). Encore une fois, cela n'est " -"nécessaire que pour construire des systèmes de recherche ou d'éducation, " -"les systèmes d'apprentissage fédérés actuels ont leurs données " -"naturellement distribuées à travers plusieurs partitions." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 +#: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" -"Let's take a look at the first batch of images and labels in the first " -"training set (i.e., ``trainloaders[0]``) before we move on:" +"Congratulations! You've successfully built and run your first federated " +"XGBoost system. The AUC values can be checked in " +":code:`metrics_distributed`. One can see that the average AUC increases " +"over FL rounds." msgstr "" -"Jetons un coup d'œil au premier lot d'images et d'étiquettes du premier " -"ensemble d'entraînement (c'est-à-dire ``trainloaders[0]``) avant de " -"poursuivre :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 +#: ../../source/tutorial-quickstart-xgboost.rst:590 +#, fuzzy msgid "" -"The output above shows a random batch of images from the first " -"``trainloader`` in our list of ten ``trainloaders``. It also prints the " -"labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another " -"batch of images." +"The full `source code `_ for this example can be found in :code:`examples" +"/xgboost-quickstart`." msgstr "" -"La sortie ci-dessus montre un lot aléatoire d'images provenant du premier" -" ``chargeur de formation`` de notre liste de dix ``chargeurs de " -"formation``. Elle imprime également les étiquettes associées à chaque " -"image (c'est-à-dire l'une des dix étiquettes possibles que nous avons " -"vues ci-dessus). Si tu exécutes à nouveau la cellule, tu devrais voir un " -"autre lot d'images." +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le code source complet " +"`_ de cet exemple se trouve dans :code:`examples" +"/quickstart-mxnet`." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 -msgid "Step 1: Centralized Training with PyTorch" -msgstr "Étape 1 : Formation centralisée avec PyTorch" +#: ../../source/tutorial-quickstart-xgboost.rst:594 +msgid "Comprehensive Federated XGBoost" +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 +#: ../../source/tutorial-quickstart-xgboost.rst:596 msgid "" -"Next, we're going to use PyTorch to define a simple convolutional neural " -"network. This introduction assumes basic familiarity with PyTorch, so it " -"doesn't cover the PyTorch-related aspects in full detail. If you want to " -"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ " -"`__." +"Now that you have known how federated XGBoost work with Flower, it's time" +" to run some more comprehensive experiments by customising the " +"experimental settings. In the xgboost-comprehensive example (`full code " +"`_), we provide more options to define various experimental" +" setups, including aggregation strategies, data partitioning and " +"centralised/distributed evaluation. We also support :doc:`Flower " +"simulation ` making it easy to simulate large " +"client cohorts in a resource-aware manner. Let's take a look!" msgstr "" -"Ensuite, nous allons utiliser PyTorch pour définir un simple réseau " -"neuronal convolutif. Cette introduction suppose une familiarité de base " -"avec PyTorch, elle ne couvre donc pas en détail les aspects liés à " -"PyTorch. Si tu veux plonger plus profondément dans PyTorch, nous te " -"recommandons `DEEP LEARNING WITH PYTORCH : A 60 MINUTE BLITZ " -"`__." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 -msgid "Defining the model" -msgstr "Définir le modèle" +#: ../../source/tutorial-quickstart-xgboost.rst:603 +#, fuzzy +msgid "Cyclic training" +msgstr "Formation centralisée" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 +#: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"We use the simple CNN described in the `PyTorch tutorial " -"`__:" +"In addition to bagging aggregation, we offer a cyclic training scheme, " +"which performs FL in a client-by-client fashion. Instead of aggregating " +"multiple clients, there is only one single client participating in the " +"training per round in the cyclic training scenario. The trained local " +"XGBoost trees will be passed to the next client as an initialised model " +"for next round's boosting." msgstr "" -"Nous utilisons le CNN simple décrit dans le tutoriel `PyTorch " -"`__ :" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 -msgid "Let's continue with the usual training and test functions:" -msgstr "Poursuivons avec les fonctions habituelles de formation et de test :" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 -msgid "Training the model" -msgstr "Entraîne le modèle" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 +#: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train " -"the model on the dataset of one of our organizations " -"(``trainloaders[0]``). This simulates the reality of most machine " -"learning projects today: each organization has their own data and trains " -"models only on this internal data:" +"To do this, we first customise a :code:`ClientManager` in " +":code:`server_utils.py`:" msgstr "" -"Nous avons maintenant tous les éléments de base dont nous avons besoin : " -"un ensemble de données, un modèle, une fonction d'entraînement et une " -"fonction de test. Assemblons-les pour entraîner le modèle sur l'ensemble " -"de données de l'une de nos organisations (``trainloaders[0]``). Cela " -"simule la réalité de la plupart des projets d'apprentissage automatique " -"aujourd'hui : chaque organisation possède ses propres données et entraîne" -" les modèles uniquement sur ces données internes :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 +#: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " -"in a test set accuracy of about 41%, which is not good, but at the same " -"time, it doesn't really matter for the purposes of this tutorial. The " -"intent was just to show a simplistic centralized training pipeline that " -"sets the stage for what comes next - federated learning!" -msgstr "" -"L'entraînement du CNN simple sur notre fractionnement CIFAR-10 pendant 5 " -"époques devrait se traduire par une précision de l'ensemble de test " -"d'environ 41 %, ce qui n'est pas bon, mais en même temps, cela n'a pas " -"vraiment d'importance pour les besoins de ce tutoriel. L'intention était " -"juste de montrer un pipeline d'entraînement centralisé simpliste qui " -"prépare le terrain pour ce qui vient ensuite - l'apprentissage fédéré !" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 -msgid "Step 2: Federated Learning with Flower" -msgstr "Étape 2 : Apprentissage fédéré avec Flower" +"The customised :code:`ClientManager` samples all available clients in " +"each FL round based on the order of connection to the server. Then, we " +"define a new strategy :code:`FedXgbCyclic` in " +":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " +"select only one client in given round and pass the received model to next" +" client." +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 +#: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was " -"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." -" Next, we'll simulate a situation where we have multiple datasets in " -"multiple organizations and where we train a model over these " -"organizations using federated learning." +"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " +"Instead, we just make a copy of the received client model as global model" +" by overriding :code:`aggregate_fit`." msgstr "" -"L'étape 1 a montré un simple pipeline de formation centralisé. Toutes les" -" données étaient au même endroit (c'est-à-dire un seul ``trainloader`` et" -" un seul ``valloader``). Ensuite, nous allons simuler une situation où " -"nous avons plusieurs ensembles de données dans plusieurs organisations et" -" où nous formons un modèle sur ces organisations à l'aide de " -"l'apprentissage fédéré." - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 -msgid "Updating model parameters" -msgstr "Mise à jour des paramètres du modèle" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 +#: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"In federated learning, the server sends the global model parameters to " -"the client, and the client updates the local model with the parameters " -"received from the server. It then trains the model on the local data " -"(which changes the model parameters locally) and sends the " -"updated/changed model parameters back to the server (or, alternatively, " -"it sends just the gradients back to the server, not the full model " -"parameters)." +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" +" methods ensure the clients to be sequentially selected given FL round:" msgstr "" -"Dans l'apprentissage fédéré, le serveur envoie les paramètres du modèle " -"global au client, et le client met à jour le modèle local avec les " -"paramètres reçus du serveur. Il entraîne ensuite le modèle sur les " -"données locales (ce qui modifie les paramètres du modèle localement) et " -"renvoie les paramètres du modèle mis à jour/changés au serveur (ou, " -"alternativement, il renvoie seulement les gradients au serveur, et non " -"pas les paramètres complets du modèle)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 -msgid "" -"We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the" -" local model: ``set_parameters`` and ``get_parameters``. The following " -"two functions do just that for the PyTorch model above." +#: ../../source/tutorial-quickstart-xgboost.rst:757 +msgid "Customised data partitioning" msgstr "" -"Nous avons besoin de deux fonctions d'aide pour mettre à jour le modèle " -"local avec les paramètres reçus du serveur et pour obtenir les paramètres" -" mis à jour du modèle local : ``set_parameters`` et ``get_parameters``. " -"Les deux fonctions suivantes font exactement cela pour le modèle PyTorch " -"ci-dessus." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 +#: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"The details of how this works are not really important here (feel free to" -" consult the PyTorch documentation if you want to learn more). In " -"essence, we use ``state_dict`` to access PyTorch model parameter tensors." -" The parameter tensors are then converted to/from a list of NumPy " -"ndarray's (which Flower knows how to serialize/deserialize):" +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" +" to instantiate the data partitioner based on the given " +":code:`num_partitions` and :code:`partitioner_type`. Currently, we " +"provide four supported partitioner type to simulate the uniformity/non-" +"uniformity in data quantity (uniform, linear, square, exponential)." msgstr "" -"Les détails de ce fonctionnement ne sont pas vraiment importants ici " -"(n'hésite pas à consulter la documentation PyTorch si tu veux en savoir " -"plus). En substance, nous utilisons ``state_dict`` pour accéder aux " -"tenseurs de paramètres du modèle PyTorch. Les tenseurs de paramètres sont" -" ensuite convertis en/depuis une liste de ndarray NumPy (que Flower sait " -"sérialiser/désérialiser) :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 -msgid "Implementing a Flower client" -msgstr "Mise en place d'un client Flower" +#: ../../source/tutorial-quickstart-xgboost.rst:790 +#, fuzzy +msgid "Customised centralised/distributed evaluation" +msgstr "Évaluation centralisée" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 +#: ../../source/tutorial-quickstart-xgboost.rst:792 msgid "" -"With that out of the way, let's move on to the interesting part. " -"Federated learning systems consist of a server and multiple clients. In " -"Flower, we create clients by implementing subclasses of " -"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " -"``NumPyClient`` in this tutorial because it is easier to implement and " -"requires us to write less boilerplate." +"To facilitate centralised evaluation, we define a function in " +":code:`server_utils.py`:" msgstr "" -"Ceci étant dit, passons à la partie intéressante. Les systèmes " -"d'apprentissage fédérés se composent d'un serveur et de plusieurs " -"clients. Dans Flower, nous créons des clients en mettant en œuvre des " -"sous-classes de ``flwr.client.Client`` ou de ``flwr.client.NumPyClient``." -" Nous utilisons ``NumPyClient`` dans ce tutoriel parce qu'il est plus " -"facile à mettre en œuvre et qu'il nous oblige à rédiger moins de modèles " -"de chaudière." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 +#: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"To implement the Flower client, we create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``:" +"This function returns a evaluation function which instantiates a " +":code:`Booster` object and loads the global model weights to it. The " +"evaluation is conducted by calling :code:`eval_set()` method, and the " +"tested AUC value is reported." msgstr "" -"Pour mettre en œuvre le client Flower, nous créons une sous-classe de " -"``flwr.client.NumPyClient`` et mettons en œuvre les trois méthodes " -"``get_parameters``, ``fit`` et ``evaluate`` :" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 -msgid "``get_parameters``: Return the current local model parameters" -msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 +#: ../../source/tutorial-quickstart-xgboost.rst:827 msgid "" -"``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters " -"to the server" +"As for distributed evaluation on the clients, it's same as the quick-" +"start example by overriding the :code:`evaluate()` method insides the " +":code:`XgbClient` class in :code:`client_utils.py`." msgstr "" -"``fit`` : reçoit les paramètres du modèle du serveur, entraîne les " -"paramètres du modèle sur les données locales et renvoie les paramètres du" -" modèle (mis à jour) au serveur" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 +#: ../../source/tutorial-quickstart-xgboost.rst:831 +#, fuzzy +msgid "Flower simulation" +msgstr "Simulation de moniteur" + +#: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the " -"model parameters on the local data, and return the evaluation result to " -"the server" +"We also provide an example code (:code:`sim.py`) to use the simulation " +"capabilities of Flower to simulate federated XGBoost training on either a" +" single machine or a cluster of machines." msgstr "" -"``evaluate`` : reçoit les paramètres du modèle du serveur, évalue les " -"paramètres du modèle sur les données locales et renvoie le résultat de " -"l'évaluation au serveur" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 +#: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"We mentioned that our clients will use the previously defined PyTorch " -"components for model training and evaluation. Let's see a simple Flower " -"client implementation that brings everything together:" +"After importing all required packages, we define a :code:`main()` " +"function to perform the simulation process:" msgstr "" -"Nous avons mentionné que nos clients utiliseront les composants PyTorch " -"définis précédemment pour la formation et l'évaluation des modèles. " -"Voyons une simple mise en œuvre du client Flower qui réunit tout cela :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 +#: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" -"Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." +"We first load the dataset and perform data partitioning, and the pre-" +"processed data is stored in a :code:`list`. After the simulation begins, " +"the clients won't need to pre-process their partitions again." msgstr "" -"Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 -msgid "Using the Virtual Client Engine" -msgstr "Utilisation du moteur du client virtuel" +#: ../../source/tutorial-quickstart-xgboost.rst:924 +msgid "Then, we define the strategies and other hyper-parameters:" +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 +#: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"In this notebook, we want to simulate a federated learning system with 10" -" clients on a single machine. This means that the server and all 10 " -"clients will live on a single machine and share resources such as CPU, " -"GPU, and memory. Having 10 clients would mean having 10 instances of " -"``FlowerClient`` in memory. Doing this on a single machine can quickly " -"exhaust the available memory resources, even if only a subset of these " -"clients participates in a single round of federated learning." +"After that, we start the simulation by calling " +":code:`fl.simulation.start_simulation`:" msgstr "" -"Dans ce carnet, nous voulons simuler un système d'apprentissage fédéré " -"avec 10 clients sur une seule machine. Cela signifie que le serveur et " -"les 10 clients vivront sur une seule machine et partageront des " -"ressources telles que le CPU, le GPU et la mémoire. Avoir 10 clients " -"signifierait avoir 10 instances de ``FlowerClient`` en mémoire. Faire " -"cela sur une seule machine peut rapidement épuiser les ressources mémoire" -" disponibles, même si seulement un sous-ensemble de ces clients participe" -" à un seul tour d'apprentissage fédéré." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 +#: ../../source/tutorial-quickstart-xgboost.rst:995 msgid "" -"In addition to the regular capabilities where server and clients run on " -"multiple machines, Flower, therefore, provides special simulation " -"capabilities that create ``FlowerClient`` instances only when they are " -"actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" +"One of key parameters for :code:`start_simulation` is :code:`client_fn` " +"which returns a function to construct a client. We define it as follows:" msgstr "" -"In addition to the regular capabilities where server and clients run on " -"multiple machines, Flower, therefore, provides special simulation " -"capabilities that create ``FlowerClient`` instances only when they are " -"actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 -msgid "Starting the training" -msgstr "Commencer la formation" +#: ../../source/tutorial-quickstart-xgboost.rst:1038 +msgid "Arguments parser" +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 +#: ../../source/tutorial-quickstart-xgboost.rst:1040 msgid "" -"We now have the class ``FlowerClient`` which defines client-side " -"training/evaluation and ``client_fn`` which allows Flower to create " -"``FlowerClient`` instances whenever it needs to call ``fit`` or " -"``evaluate`` on one particular client. The last step is to start the " -"actual simulation using ``flwr.simulation.start_simulation``." +"In :code:`utils.py`, we define the arguments parsers for clients, server " +"and simulation, allowing users to specify different experimental " +"settings. Let's first see the sever side:" msgstr "" -"Nous avons maintenant la classe ``FlowerClient`` qui définit " -"l'entraînement/évaluation côté client et ``client_fn`` qui permet à " -"Flower de créer des instances de ``FlowerClient`` chaque fois qu'il a " -"besoin d'appeler ``fit`` ou ``evaluate`` sur un client particulier. La " -"dernière étape consiste à démarrer la simulation réelle en utilisant " -"``flwr.simulation.start_simulation``." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +#: ../../source/tutorial-quickstart-xgboost.rst:1086 msgid "" -"The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the " -"number of clients to simulate (``num_clients``), the number of federated " -"learning rounds (``num_rounds``), and the strategy. The strategy " -"encapsulates the federated learning approach/algorithm, for example, " -"*Federated Averaging* (FedAvg)." +"This allows user to specify training strategies / the number of total " +"clients / FL rounds / participating clients / clients for evaluation, and" +" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" +" will do centralised evaluation and all functionalities for client " +"evaluation will be disabled." msgstr "" -"La fonction ``start_simulation`` accepte un certain nombre d'arguments, " -"parmi lesquels le ``client_fn`` utilisé pour créer les instances " -"``FlowerClient``, le nombre de clients à simuler (``num_clients``), le " -"nombre de tours d'apprentissage fédéré (``num_rounds``), et la stratégie." -" La stratégie encapsule l'approche/algorithme d'apprentissage fédéré, par" -" exemple, *Federated Averaging* (FedAvg)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 -msgid "" -"Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated" -" learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last " -"step is the actual call to ``start_simulation`` which - you guessed it - " -"starts the simulation:" +#: ../../source/tutorial-quickstart-xgboost.rst:1090 +msgid "Then, the argument parser on client side:" msgstr "" -"Flower dispose d'un certain nombre de stratégies intégrées, mais nous " -"pouvons également utiliser nos propres implémentations de stratégies pour" -" personnaliser presque tous les aspects de l'approche de l'apprentissage " -"fédéré. Pour cet exemple, nous utilisons l'implémentation intégrée " -"``FedAvg`` et nous la personnalisons en utilisant quelques paramètres de " -"base. La dernière étape est l'appel à ``start_simulation`` qui - tu l'as " -"deviné - démarre la simulation :" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 -msgid "Behind the scenes" -msgstr "Dans les coulisses" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 -msgid "So how does this work? How does Flower execute this simulation?" +#: ../../source/tutorial-quickstart-xgboost.rst:1144 +msgid "" +"This defines various options for client data partitioning. Besides, " +"clients also have an option to conduct evaluation on centralised test set" +" by setting :code:`--centralised-eval`, as well as an option to perform " +"scaled learning rate based on the number of clients by setting :code" +":`--scaled-lr`." msgstr "" -"Alors, comment cela fonctionne-t-il ? Comment Flower exécute-t-il cette " -"simulation ?" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 -#, python-format -msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 " -"clients (``num_clients=10``). Flower then goes ahead an asks the " -"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " -"select 100% of the available clients (``fraction_fit=1.0``), so it goes " -"ahead and selects 10 random clients (i.e., 100% of 10)." +#: ../../source/tutorial-quickstart-xgboost.rst:1148 +msgid "We also have an argument parser for simulation:" msgstr "" -"Lorsque nous appelons ``start_simulation``, nous disons à Flower qu'il y " -"a 10 clients (``num_clients=10``). Flower demande alors à la stratégie " -"``FedAvg`` de sélectionner des clients. ``FedAvg` sait qu'il doit " -"sélectionner 100% des clients disponibles (``fraction_fit=1.0``), alors " -"il choisit 10 clients au hasard (c'est à dire 100% de 10)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 -msgid "" -"Flower then asks the selected 10 clients to train the model. When the " -"server receives the model parameter updates from the clients, it hands " -"those updates over to the strategy (*FedAvg*) for aggregation. The " -"strategy aggregates those updates and returns the new global model, which" -" then gets used in the next round of federated learning." +#: ../../source/tutorial-quickstart-xgboost.rst:1226 +msgid "This integrates all arguments for both client and server sides." msgstr "" -"Flower demande ensuite aux 10 clients sélectionnés d'entraîner le modèle." -" Lorsque le serveur reçoit les mises à jour des paramètres du modèle de " -"la part des clients, il les transmet à la stratégie (*FedAvg*) pour " -"qu'elle les agrège. La stratégie agrège ces mises à jour et renvoie le " -"nouveau modèle global, qui est ensuite utilisé dans le prochain cycle " -"d'apprentissage fédéré." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 -msgid "Where's the accuracy?" -msgstr "Où est la précision ?" +#: ../../source/tutorial-quickstart-xgboost.rst:1229 +#, fuzzy +msgid "Example commands" +msgstr "Exemples de PyTorch" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 +#: ../../source/tutorial-quickstart-xgboost.rst:1231 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` " -"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"To run a centralised evaluated experiment with bagging strategy on 5 " +"clients with exponential distribution for 50 rounds, we first start the " +"server as below:" msgstr "" -"Tu as peut-être remarqué que toutes les mesures, à l'exception de " -"``pertes_distribuées``, sont vides. Où est passée la ``{\"précision\" : " -"float(précision)}`` ?" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 -msgid "" -"Flower can automatically aggregate losses returned by individual clients," -" but it cannot do the same for metrics in the generic metrics dictionary " -"(the one with the ``accuracy`` key). Metrics dictionaries can contain " -"very different kinds of metrics and even key/value pairs that are not " -"metrics at all, so the framework does not (and can not) know how to " -"handle these automatically." -msgstr "" -"Flower peut automatiquement agréger les pertes renvoyées par les clients " -"individuels, mais il ne peut pas faire la même chose pour les mesures " -"dans le dictionnaire de mesures générique (celui avec la clé " -"``accuracy``). Les dictionnaires de mesures peuvent contenir des types de" -" mesures très différents et même des paires clé/valeur qui ne sont pas " -"des mesures du tout, donc le cadre ne sait pas (et ne peut pas) savoir " -"comment les gérer automatiquement." +#: ../../source/tutorial-quickstart-xgboost.rst:1238 +#, fuzzy +msgid "Then, on each client terminal, we start the clients:" +msgstr "Ouvre un autre terminal et démarre le deuxième client :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 -msgid "" -"As users, we need to tell the framework how to handle/aggregate these " -"custom metrics, and we do so by passing metric aggregation functions to " -"the strategy. The strategy will then call these functions whenever it " -"receives fit or evaluate metrics from clients. The two possible functions" -" are ``fit_metrics_aggregation_fn`` and " -"``evaluate_metrics_aggregation_fn``." +#: ../../source/tutorial-quickstart-xgboost.rst:1244 +msgid "To run the same experiment with Flower simulation:" msgstr "" -"En tant qu'utilisateurs, nous devons indiquer au framework comment " -"gérer/agréger ces métriques personnalisées, et nous le faisons en passant" -" des fonctions d'agrégation de métriques à la stratégie. La stratégie " -"appellera alors ces fonctions chaque fois qu'elle recevra des métriques " -"d'ajustement ou d'évaluation de la part des clients. Les deux fonctions " -"possibles sont ``fit_metrics_aggregation_fn`` et " -"``evaluate_metrics_aggregation_fn``." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 +#: ../../source/tutorial-quickstart-xgboost.rst:1250 +#, fuzzy msgid "" -"Let's create a simple weighted averaging function to aggregate the " -"``accuracy`` metric we return from ``evaluate``:" +"The full `code `_ for this comprehensive example can be found in" +" :code:`examples/xgboost-comprehensive`." msgstr "" -"Créons une simple fonction de calcul de la moyenne pondérée pour agréger " -"la mesure de \"précision\" que nous renvoie ``evaluate`` :" +"Félicitations ! Tu as réussi à construire et à faire fonctionner ton " +"premier système d'apprentissage fédéré. Le code source complet " +"`_ de cet exemple se trouve dans :code:`examples" +"/quickstart-mxnet`." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 +#, fuzzy +msgid "Build a strategy from scratch" +msgstr "Élaborer une stratégie à partir de zéro" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 +#, fuzzy msgid "" -"The only thing left to do is to tell the strategy to call this function " -"whenever it receives evaluation metric dictionaries from the clients:" +"Welcome to the third part of the Flower federated learning tutorial. In " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__) and we learned how strategies " +"can be used to customize the execution on both the server and the clients" +" (`part 2 `__)." msgstr "" -"La seule chose qui reste à faire est d'indiquer à la stratégie d'appeler " -"cette fonction chaque fois qu'elle reçoit des dictionnaires de métriques " -"d'évaluation de la part des clients :" +"Bienvenue dans la troisième partie du tutoriel sur l'apprentissage fédéré" +" Flower. Dans les parties précédentes de ce tutoriel, nous avons présenté" +" l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " +"`__) " +"et nous avons appris comment les stratégies peuvent être utilisées pour " +"personnaliser l'exécution à la fois sur le serveur et sur les clients " +"(`partie 2 `__)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom" -" evaluation metrics and calculates a single ``accuracy`` metric across " -"all clients on the server side." +"In this notebook, we'll continue to customize the federated learning " +"system we built previously by creating a custom version of FedAvg (again," +" using `Flower `__ and `PyTorch " +"`__)." msgstr "" -"Nous avons maintenant un système complet qui effectue la formation " -"fédérée et l'évaluation fédérée. Il utilise la fonction ``moyenne " -"pondérée`` pour agréger les mesures d'évaluation personnalisées et " -"calcule une seule mesure de ``précision`` pour tous les clients du côté " -"du serveur." +"Dans ce carnet, nous allons continuer à personnaliser le système " +"d'apprentissage fédéré que nous avons construit précédemment en créant " +"une version personnalisée de FedAvg (encore une fois, en utilisant " +"`Flower `__ et `PyTorch `__)." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"The other two categories of metrics (``losses_centralized`` and " -"``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial " -"will cover centralized evaluation." +"`Star Flower on GitHub `__ ⭐️ and join " +"the Flower community on Slack to connect, ask questions, and get help: " +"`Join Slack `__ 🌼 We'd love to hear from " +"you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" -"Les deux autres catégories de mesures (``pertes_centralisées`` et " -"``métriques_centralisées``) sont toujours vides car elles ne s'appliquent" -" que lorsque l'évaluation centralisée est utilisée. La deuxième partie du" -" tutoriel sur les fleurs couvrira l'évaluation centralisée." +"`Star Flower on GitHub `__ ⭐️ et " +"rejoignez la communauté Flower sur Slack pour vous connecter, poser des " +"questions et obtenir de l'aide : `Join Slack `__ 🌼 Nous serions ravis d'avoir de vos nouvelles dans le canal " +"``#introductions`` ! Et si quelque chose n'est pas clair, rendez-vous sur" +" le canal ``#questions``." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 -msgid "Final remarks" -msgstr "Remarques finales" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 +msgid "Let's build a new ``Strategy`` from scratch!" +msgstr "Construisons une nouvelle ``Stratégie`` à partir de zéro !" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 +msgid "Preparation" +msgstr "Préparation" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 msgid "" -"Congratulations, you just trained a convolutional neural network, " -"federated over 10 clients! With that, you understand the basics of " -"federated learning with Flower. The same approach you've seen can be used" -" with other machine learning frameworks (not just PyTorch) and tasks (not" -" just CIFAR-10 images classification), for example NLP with Hugging Face " -"Transformers or speech with SpeechBrain." +"Before we begin with the actual code, let's make sure that we have " +"everything we need." msgstr "" -"Félicitations, tu viens d'entraîner un réseau neuronal convolutif, fédéré" -" sur 10 clients ! Avec ça, tu comprends les bases de l'apprentissage " -"fédéré avec Flower. La même approche que tu as vue peut être utilisée " -"avec d'autres cadres d'apprentissage automatique (pas seulement PyTorch) " -"et d'autres tâches (pas seulement la classification des images CIFAR-10)," -" par exemple le NLP avec Hugging Face Transformers ou la parole avec " -"SpeechBrain." +"Avant de commencer le code proprement dit, assurons-nous que nous " +"disposons de tout ce dont nous avons besoin." -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 +msgid "Installing dependencies" +msgstr "Installation des dépendances" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 +msgid "First, we install the necessary packages:" +msgstr "Tout d'abord, nous installons les paquets nécessaires :" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. " -"Want to customize your strategy? Initialize parameters on the server " -"side? Or evaluate the aggregated model on the server side? We'll cover " -"all this and more in the next tutorial." +"Now that we have all dependencies installed, we can import everything we " +"need for this tutorial:" msgstr "" -"Dans le prochain cahier, nous allons aborder des concepts plus avancés. " -"Tu veux personnaliser ta stratégie ? Initialiser des paramètres côté " -"serveur ? Ou évaluer le modèle agrégé côté serveur ? Nous aborderons tout" -" cela et bien plus encore dans le prochain tutoriel." +"Maintenant que toutes les dépendances sont installées, nous pouvons " +"importer tout ce dont nous avons besoin pour ce tutoriel :" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 -#, fuzzy +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 " -"`__ goes into more depth about strategies and all " -"the advanced things you can build with them." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " +"GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" -"Le `Tutoriel d'apprentissage fédéré Flower - Partie 2 " -"`__ va plus en profondeur sur les stratégies et toutes les " -"choses avancées que tu peux construire avec elles." +"Il est possible de passer à un runtime dont l'accélération GPU est " +"activée (sur Google Colab : ``Runtime > Change runtime type > Hardware " +"acclerator : GPU > Save``). Note cependant que Google Colab n'est pas " +"toujours en mesure de proposer l'accélération GPU. Si tu vois une erreur " +"liée à la disponibilité du GPU dans l'une des sections suivantes, " +"envisage de repasser à une exécution basée sur le CPU en définissant " +"``DEVICE = torch.device(\"cpu\")``. Si le runtime a activé l'accélération" +" GPU, tu devrais voir apparaître le résultat ``Training on cuda``, sinon " +"il dira ``Training on cpu``." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 -#, fuzzy -msgid "Use a federated learning strategy" -msgstr "Stratégie de moyenne fédérée." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 +msgid "Data loading" +msgstr "Chargement des données" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 -#, fuzzy +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and" -" Flower (`part 1 `__)." +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``. We introduce a new parameter" +" ``num_clients`` which allows us to call ``load_datasets`` with different" +" numbers of clients." msgstr "" -"Bienvenue dans la prochaine partie du tutoriel sur l'apprentissage " -"fédéré. Dans les parties précédentes de ce tutoriel, nous avons présenté " -"l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " -"`__)." +"Chargeons maintenant les ensembles d'entraînement et de test CIFAR-10, " +"divisons-les en dix ensembles de données plus petits (chacun divisé en " +"ensemble d'entraînement et de validation), et enveloppons le tout dans " +"leur propre ``DataLoader``. Nous introduisons un nouveau paramètre " +"``num_clients`` qui nous permet d'appeler ``load_datasets`` avec " +"différents nombres de clients." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 +msgid "Model training/evaluation" +msgstr "Formation/évaluation du modèle" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"In this notebook, we'll begin to customize the federated learning system " -"we built in the introductory notebook (again, using `Flower " -"`__ and `PyTorch `__)." +"Let's continue with the usual model definition (including " +"``set_parameters`` and ``get_parameters``), training and test functions:" msgstr "" -"Dans ce carnet, nous allons commencer à personnaliser le système " -"d'apprentissage fédéré que nous avons construit dans le carnet " -"d'introduction (toujours en utilisant `Flower `__ et " -"`PyTorch `__)." - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 -#, fuzzy -msgid "Let's move beyond FedAvg with Flower strategies!" -msgstr "Dépassons FedAvg avec les stratégies florales !" +"Continuons avec la définition habituelle du modèle (y compris " +"``set_parameters`` et ``get_parameters``), les fonctions d'entraînement " +"et de test :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 -msgid "Strategy customization" -msgstr "Personnalisation de la stratégie" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 +msgid "Flower client" +msgstr "Client de Flower" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of " -"new features." +"To implement the Flower client, we (again) create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " +"``cid`` to the client and use it log additional details:" msgstr "" -"Jusqu'à présent, tout devrait te sembler familier si tu as travaillé sur " -"le cahier d'introduction. Avec cela, nous sommes prêts à présenter un " -"certain nombre de nouvelles fonctionnalités." +"Pour mettre en œuvre le client Flower, nous créons (à nouveau) une sous-" +"classe de ``flwr.client.NumPyClient`` et mettons en œuvre les trois " +"méthodes ``get_parameters``, ``fit`` et ``evaluate``. Ici, nous " +"transmettons également le ``cid`` au client et l'utilisons pour consigner" +" des détails supplémentaires :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 -msgid "Server-side parameter **initialization**" -msgstr "Paramètres côté serveur **initialisation**" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 +msgid "Let's test what we have so far before we continue:" +msgstr "Testons ce que nous avons jusqu'à présent avant de continuer :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 +msgid "Build a Strategy from scratch" +msgstr "Élaborer une stratégie à partir de zéro" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"Flower, by default, initializes the global model by asking one random " -"client for the initial parameters. In many cases, we want more control " -"over parameter initialization though. Flower therefore allows you to " -"directly pass the initial parameters to the Strategy:" +"Let’s overwrite the ``configure_fit`` method such that it passes a higher" +" learning rate (potentially also other hyperparameters) to the optimizer " +"of a fraction of the clients. We will keep the sampling of the clients as" +" it is in ``FedAvg`` and then change the configuration dictionary (one of" +" the ``FitIns`` attributes)." msgstr "" -"Flower, par défaut, initialise le modèle global en demandant à un client " -"aléatoire les paramètres initiaux. Dans de nombreux cas, nous voulons " -"cependant avoir plus de contrôle sur l'initialisation des paramètres. " -"Flower te permet donc de passer directement les paramètres initiaux à la " -"Stratégie :" +"Remplaçons la méthode ``configure_fit`` de façon à ce qu'elle transmette " +"un taux d'apprentissage plus élevé (potentiellement aussi d'autres " +"hyperparamètres) à l'optimiseur d'une fraction des clients. Nous " +"garderons l'échantillonnage des clients tel qu'il est dans ``FedAvg`` et " +"changerons ensuite le dictionnaire de configuration (l'un des attributs " +"``FitIns``)." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" -" from asking one of the clients for the initial parameters. If we look " -"closely, we can see that the logs do not show any calls to the " -"``FlowerClient.get_parameters`` method." +"The only thing left is to use the newly created custom Strategy " +"``FedCustom`` when starting the experiment:" msgstr "" -"Le fait de passer ``initial_parameters`` à la stratégie ``FedAvg`` " -"empêche Flower de demander les paramètres initiaux à l'un des clients. Si" -" nous regardons de près, nous pouvons voir que les journaux ne montrent " -"aucun appel à la méthode ``FlowerClient.get_parameters``." +"Il ne reste plus qu'à utiliser la stratégie personnalisée nouvellement " +"créée ``FedCustom`` lors du démarrage de l'expérience :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 -msgid "Starting with a customized strategy" -msgstr "Commencer par une stratégie personnalisée" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 +msgid "Recap" +msgstr "Récapitulation" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number " -"of arguments, amongst them the ``client_fn`` used to create " -"``FlowerClient`` instances, the number of clients to simulate " -"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +"In this notebook, we’ve seen how to implement a custom strategy. A custom" +" strategy enables granular control over client node configuration, result" +" aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``." +" To make custom strategies even more powerful, you can pass custom " +"functions to the constructor of your new class (``__init__``) and then " +"call these functions whenever needed." msgstr "" -"Elle accepte un certain nombre d'arguments, parmi lesquels le " -"``client_fn`` utilisé pour créer les instances de ``FlowerClient``, le " -"nombre de clients à simuler ``num_clients``, le nombre de rounds " -"``num_rounds``, et la stratégie." +"Dans ce carnet, nous avons vu comment mettre en place une stratégie " +"personnalisée. Une stratégie personnalisée permet un contrôle granulaire " +"sur la configuration des nœuds clients, l'agrégation des résultats, et " +"bien plus encore. Pour définir une stratégie personnalisée, il te suffit " +"d'écraser les méthodes abstraites de la classe de base (abstraite) " +"``Strategy``. Pour rendre les stratégies personnalisées encore plus " +"puissantes, tu peux passer des fonctions personnalisées au constructeur " +"de ta nouvelle classe (``__init__``) et appeler ensuite ces fonctions à " +"chaque fois que c'est nécessaire." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " -"strategy this time:" +"Before you continue, make sure to join the Flower community on Slack: " +"`Join Slack `__" msgstr "" -"La stratégie englobe l'approche/l'algorithme d'apprentissage fédéré, par " -"exemple, ``FedAvg`` ou ``FedAdagrad``. Essayons d'utiliser une stratégie " -"différente cette fois-ci :" - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 -msgid "Server-side parameter **evaluation**" -msgstr "Paramètre côté serveur **évaluation**" +"Avant de continuer, n'oublie pas de rejoindre la communauté Flower sur " +"Slack : `Join Slack `__" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 -msgid "" -"Flower can evaluate the aggregated model on the server-side or on the " -"client-side. Client-side and server-side evaluation are similar in some " -"ways, but different in others." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 +msgid "" +"There's a dedicated ``#questions`` channel if you need help, but we'd " +"also love to hear who you are in ``#introductions``!" msgstr "" -"Flower peut évaluer le modèle agrégé côté serveur ou côté client. Les " -"évaluations côté client et côté serveur sont similaires à certains " -"égards, mais différentes à d'autres." +"Il existe un canal dédié aux ``questions`` si vous avez besoin d'aide, " +"mais nous aimerions aussi savoir qui vous êtes dans ``#introductions`` !" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 +#, fuzzy msgid "" -"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " -"simple: it works the same way that evaluation in centralized machine " -"learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly " -"aggregated model after each round of training without having to send the " -"model to clients. We're also fortunate in the sense that our entire " -"evaluation dataset is available at all times." +"The `Flower Federated Learning Tutorial - Part 4 " +"`__ introduces ``Client``, the flexible API underlying " +"``NumPyClient``." msgstr "" -"**L'évaluation centralisée** (ou *évaluation côté serveur*) est " -"conceptuellement simple : elle fonctionne de la même manière que " -"l'évaluation dans l'apprentissage automatique centralisé. S'il existe un " -"ensemble de données côté serveur qui peut être utilisé à des fins " -"d'évaluation, alors c'est parfait. Nous pouvons évaluer le modèle " -"nouvellement agrégé après chaque cycle de formation sans avoir à envoyer " -"le modèle aux clients. Nous avons également la chance que l'ensemble de " -"notre ensemble de données d'évaluation soit disponible à tout moment." +"Le `Tutoriel d'apprentissage fédéré Flower - Partie 4 " +"`__ présente ``Client``, l'API flexible qui sous-tend " +"``NumPyClient``." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 +#, fuzzy +msgid "Customize the client" +msgstr "Création du client IMDBC" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 +#, fuzzy msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, " -"but also more powerful: it doesn't require a centralized dataset and " -"allows us to evaluate models over a larger set of data, which often " -"yields more realistic evaluation results. In fact, many scenarios require" -" us to use **Federated Evaluation** if we want to get representative " -"evaluation results at all. But this power comes at a cost: once we start " -"to evaluate on the client side, we should be aware that our evaluation " -"dataset can change over consecutive rounds of learning if those clients " -"are not always available. Moreover, the dataset held by each client can " -"also change over consecutive rounds. This can lead to evaluation results " -"that are not stable, so even if we would not change the model, we'd see " -"our evaluation results fluctuate over consecutive rounds." +"Welcome to the fourth part of the Flower federated learning tutorial. In " +"the previous parts of this tutorial, we introduced federated learning " +"with PyTorch and Flower (`part 1 `__), we learned how " +"strategies can be used to customize the execution on both the server and " +"the clients (`part 2 `__), and we built our own " +"custom strategy from scratch (`part 3 `__)." msgstr "" -"**L'évaluation fédérée** (ou évaluation côté client) est plus complexe, " -"mais aussi plus puissante : elle ne nécessite pas d'ensemble de données " -"centralisé et nous permet d'évaluer les modèles sur un plus grand " -"ensemble de données, ce qui donne souvent des résultats d'évaluation plus" -" réalistes. En fait, de nombreux scénarios exigent que nous utilisions " -"l'évaluation fédérée** si nous voulons obtenir des résultats d'évaluation" -" représentatifs. Mais cette puissance a un coût : une fois que nous " -"commençons à évaluer côté client, nous devons savoir que notre ensemble " -"de données d'évaluation peut changer au cours des cycles d'apprentissage " -"consécutifs si ces clients ne sont pas toujours disponibles. De plus, " -"l'ensemble de données détenu par chaque client peut également changer au " -"cours des cycles consécutifs. Cela peut conduire à des résultats " -"d'évaluation qui ne sont pas stables, donc même si nous ne changions pas " -"le modèle, nous verrions nos résultats d'évaluation fluctuer au cours des" -" cycles consécutifs." +"Bienvenue dans la quatrième partie du tutoriel sur l'apprentissage fédéré" +" Flower. Dans les parties précédentes de ce tutoriel, nous avons présenté" +" l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " +"`__), " +"nous avons appris comment les stratégies peuvent être utilisées pour " +"personnaliser l'exécution à la fois sur le serveur et les clients " +"(`partie 2 `__), et nous avons construit notre propre stratégie " +"personnalisée à partir de zéro (`partie 3 - WIP " +"`__)." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " -"how we can evaluate aggregated model parameters on the server-side:" +"In this notebook, we revisit ``NumPyClient`` and introduce a new " +"baseclass for building clients, simply named ``Client``. In previous " +"parts of this tutorial, we've based our client on ``NumPyClient``, a " +"convenience class which makes it easy to work with machine learning " +"libraries that have good NumPy interoperability. With ``Client``, we gain" +" a lot of flexibility that we didn't have before, but we'll also have to " +"do a few things the we didn't have to do before." msgstr "" -"Nous avons vu comment l'évaluation fédérée fonctionne du côté client " -"(c'est-à-dire en implémentant la méthode ``evaluate`` dans " -"``FlowerClient``). Voyons maintenant comment nous pouvons évaluer les " -"paramètres du modèle agrégé du côté serveur :" - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 -msgid "Sending/receiving arbitrary values to/from clients" -msgstr "Envoi/réception de valeurs arbitraires vers/depuis les clients" +"Dans ce carnet, nous revisitons `NumPyClient`` et introduisons une " +"nouvelle classe de base pour construire des clients, simplement appelée " +"`Client``. Dans les parties précédentes de ce tutoriel, nous avons basé " +"notre client sur ``NumPyClient``, une classe de commodité qui facilite le" +" travail avec les bibliothèques d'apprentissage automatique qui ont une " +"bonne interopérabilité NumPy. Avec ``Client``, nous gagnons beaucoup de " +"flexibilité que nous n'avions pas auparavant, mais nous devrons également" +" faire quelques choses que nous n'avions pas à faire auparavant." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 msgid "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" +"Let's go deeper and see what it takes to move from ``NumPyClient`` to " +"``Client``!" msgstr "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" +"Allons plus loin et voyons ce qu'il faut faire pour passer de " +"``NumPyClient`` à ``Client`` !" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 +msgid "Step 0: Preparation" +msgstr "Étape 0 : Préparation" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"So how can we send this config dictionary from server to clients? The " -"built-in Flower Strategies provide way to do this, and it works similarly" -" to the way server-side evaluation works. We provide a function to the " -"strategy, and the strategy calls this function for every round of " -"federated learning:" +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``." msgstr "" -"Comment pouvons-nous donc envoyer ce dictionnaire de configuration du " -"serveur aux clients ? Les stratégies de Flower intégrées fournissent un " -"moyen de le faire, et cela fonctionne de la même façon que l'évaluation " -"côté serveur. Nous fournissons une fonction à la stratégie, et la " -"stratégie appelle cette fonction pour chaque cycle d'apprentissage fédéré" -" :" +"Chargeons maintenant les ensembles d'entraînement et de test CIFAR-10, " +"divisons-les en dix ensembles de données plus petits (chacun divisé en " +"ensemble d'entraînement et de validation) et enveloppons le tout dans " +"leur propre ``DataLoader``." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 +msgid "Step 1: Revisiting NumPyClient" +msgstr "Étape 1 : Revoir NumPyClient" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before " -"starting the simulation:" +"So far, we've implemented our client by subclassing " +"``flwr.client.NumPyClient``. The three methods we implemented are " +"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " +"creation of instances of this class in a function called ``client_fn``:" msgstr "" -"Ensuite, nous allons simplement passer cette fonction à la stratégie " -"FedAvg avant de commencer la simulation :" +"Jusqu'à présent, nous avons implémenté notre client en sous-classant " +"``flwr.client.NumPyClient``. Les trois méthodes que nous avons " +"implémentées sont ``get_parameters``, ``fit`` et ``evaluate``. Enfin, " +"nous enveloppons la création d'instances de cette classe dans une " +"fonction appelée ``client_fn`` :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 msgid "" -"As we can see, the client logs now include the current round of federated" -" learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second" -" round of federated learning, and then for two epochs during the third " -"round." +"We've seen this before, there's nothing new so far. The only *tiny* " +"difference compared to the previous notebook is naming, we've changed " +"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " +"``numpyclient_fn``. Let's run it to see the output we get:" msgstr "" -"Comme nous pouvons le voir, les journaux des clients incluent maintenant " -"le cycle actuel d'apprentissage fédéré (qu'ils lisent depuis le " -"dictionnaire ``config``). Nous pouvons également configurer " -"l'apprentissage local pour qu'il s'exécute pendant une époque au cours du" -" premier et du deuxième cycle d'apprentissage fédéré, puis pendant deux " -"époques au cours du troisième cycle." +"Nous avons déjà vu cela auparavant, il n'y a rien de nouveau jusqu'à " +"présent. La seule *petite* différence par rapport au carnet précédent est" +" le nommage, nous avons changé ``FlowerClient`` en ``FlowerNumPyClient`` " +"et ``client_fn`` en ``numpyclient_fn``. Exécutons-le pour voir la sortie " +"que nous obtenons :" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 msgid "" -"Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " -"used this concept throughout this notebook without mentioning it " -"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" -" key/value pair as the third return value in ``evaluate``." +"This works as expected, two clients are training for three rounds of " +"federated learning." msgstr "" -"Les clients peuvent également renvoyer des valeurs arbitraires au " -"serveur. Pour ce faire, ils renvoient un dictionnaire depuis ``fit`` " -"et/ou ``evaluate``. Nous avons vu et utilisé ce concept tout au long de " -"ce carnet sans le mentionner explicitement : notre ``FlowerClient`` " -"renvoie un dictionnaire contenant une paire clé/valeur personnalisée en " -"tant que troisième valeur de retour dans ``evaluate``." - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 -msgid "Scaling federated learning" -msgstr "Mise à l'échelle de l'apprentissage fédéré" +"Cela fonctionne comme prévu, deux clients s'entraînent pour trois tours " +"d'apprentissage fédéré." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 msgid "" -"As a last step in this notebook, let's see how we can use Flower to " -"experiment with a large number of clients." +"Let's dive a little bit deeper and discuss how Flower executes this " +"simulation. Whenever a client is selected to do some work, " +"``start_simulation`` calls the function ``numpyclient_fn`` to create an " +"instance of our ``FlowerNumPyClient`` (along with loading the model and " +"the data)." msgstr "" -"Comme dernière étape de ce carnet, voyons comment nous pouvons utiliser " -"Flower pour expérimenter avec un grand nombre de clients." +"Plongeons un peu plus profondément et discutons de la façon dont Flower " +"exécute cette simulation. Chaque fois qu'un client est sélectionné pour " +"effectuer un travail, ``start_simulation`` appelle la fonction " +"``numpyclient_fn`` pour créer une instance de notre ``FlowerNumPyClient``" +" (en même temps qu'il charge le modèle et les données)." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 -#, python-format +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" -"We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is " -"quite small, we should probably train the model a bit longer, so we " -"configure the clients to perform 3 local training epochs. We should also " -"adjust the fraction of clients selected for training during each round " -"(we don't want all 1000 clients participating in every round), so we " -"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " -"available clients (so 50 clients) will be selected for training each " -"round:" +"But here's the perhaps surprising part: Flower doesn't actually use the " +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " +"makes it look like a subclass of ``flwr.client.Client``, not " +"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " +"know how to handle ``NumPyClient``'s, it only knows how to handle " +"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " +"top of ``Client``." msgstr "" -"Nous avons maintenant 1000 partitions, chacune contenant 45 exemples " -"d'entraînement et 5 exemples de validation. Etant donné que le nombre " -"d'exemples d'entraînement sur chaque client est assez faible, nous " -"devrions probablement entraîner le modèle un peu plus longtemps, nous " -"configurons donc les clients pour qu'ils effectuent 3 époques " -"d'entraînement local. Nous devrions également ajuster la fraction de " -"clients sélectionnés pour l'entraînement à chaque tour (nous ne voulons " -"pas que les 1000 clients participent à chaque tour), nous ajustons donc " -"``fraction_fit`` à ``0.05``, ce qui signifie que seulement 5% des clients" -" disponibles (donc 50 clients) seront sélectionnés pour l'entraînement à " -"chaque tour :" +"Mais voici la partie la plus surprenante : Flower n'utilise pas " +"directement l'objet `FlowerNumPyClient`. Au lieu de cela, il enveloppe " +"l'objet pour le faire ressembler à une sous-classe de " +"`flwr.client.Client`, et non de `flwr.client.NumPyClient`. En fait, le " +"noyau de Flower ne sait pas comment gérer les `NumPyClient`, il sait " +"seulement comment gérer les `Client`. `NumPyClient` est juste une " +"abstraction de commodité construite au dessus de `Client`." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"In this notebook, we've seen how we can gradually enhance our system by " -"customizing the strategy, initializing parameters on the server side, " -"choosing a different strategy, and evaluating models on the server-side. " -"That's quite a bit of flexibility with so little code, right?" +"Instead of building on top of ``NumPyClient``, we can directly build on " +"top of ``Client``." msgstr "" -"Dans ce carnet, nous avons vu comment nous pouvons progressivement " -"améliorer notre système en personnalisant la stratégie, en initialisant " -"les paramètres côté serveur, en choisissant une stratégie différente et " -"en évaluant les modèles côté serveur. C'est une sacrée flexibilité avec " -"si peu de code, n'est-ce pas ?" +"Au lieu de construire par-dessus `NumPyClient``, nous pouvons construire " +"directement par-dessus `Client``." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 +msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" +msgstr "Étape 2 : Passer de ``NumPyClient`` à ``Client``" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 msgid "" -"In the later sections, we've seen how we can communicate arbitrary values" -" between server and clients to fully customize client-side execution. " -"With that capability, we built a large-scale Federated Learning " -"simulation using the Flower Virtual Client Engine and ran an experiment " -"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +"Let's try to do the same thing using ``Client`` instead of " +"``NumPyClient``." msgstr "" -"Dans les sections ultérieures, nous avons vu comment nous pouvons " -"communiquer des valeurs arbitraires entre le serveur et les clients pour " -"personnaliser entièrement l'exécution côté client. Grâce à cette " -"capacité, nous avons construit une simulation d'apprentissage fédéré à " -"grande échelle en utilisant le moteur de client virtuel Flower et nous " -"avons mené une expérience impliquant 1000 clients dans la même charge de " -"travail - le tout dans un carnet Jupyter !" +"Essayons de faire la même chose en utilisant ``Client`` au lieu de " +"``NumPyClient``." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 " -"`__ shows how to build a fully custom ``Strategy`` from " -"scratch." +"Before we discuss the code in more detail, let's try to run it! Gotta " +"make sure our new ``Client``-based client works, right?" msgstr "" -"Le `Tutoriel d'apprentissage fédéré Flower - Partie 3 [WIP] " -"`__ montre comment construire une ``Stratégie`` entièrement " -"personnalisée à partir de zéro." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 -msgid "What is Federated Learning?" -msgstr "Qu'est-ce que l'apprentissage fédéré ?" +"Avant de discuter du code plus en détail, essayons de l'exécuter ! Nous " +"devons nous assurer que notre nouveau client basé sur le ``Client`` " +"fonctionne, n'est-ce pas ?" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 msgid "" -"In this tutorial, you will learn what federated learning is, build your " -"first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated " -"learning systems that approach the current state of the art in the field." +"That's it, we're now using ``Client``. It probably looks similar to what " +"we've done with ``NumPyClient``. So what's the difference?" msgstr "" -"Dans ce tutoriel, tu apprendras ce qu'est l'apprentissage fédéré, tu " -"construiras ton premier système dans Flower, et tu l'étendras " -"progressivement. Si tu travailles sur toutes les parties du tutoriel, tu " -"seras capable de construire des systèmes d'apprentissage fédéré avancés " -"qui se rapprochent de l'état actuel de l'art dans le domaine." +"Voilà, nous utilisons maintenant ``Client``. Cela ressemble probablement " +"à ce que nous avons fait avec ``NumPyClient``. Alors quelle est la " +"différence ?" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " -"federated learning. Only a basic understanding of data science and Python" -" programming is assumed." +"First of all, it's more code. But why? The difference comes from the fact" +" that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the " +"network, it eventually needs to turn these parameters into ``bytes``. " +"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"serialization. Turning raw bytes into something more useful (like NumPy " +"``ndarray``'s) is called deserialization. Flower needs to do both: it " +"needs to serialize parameters on the server-side and send them to the " +"client, the client needs to deserialize them to use them for local " +"training, and then serialize the updated parameters again to send them " +"back to the server, which (finally!) deserializes them again in order to " +"aggregate them with the updates received from other clients." msgstr "" -"🧑‍🏫 Ce tutoriel part de zéro et n'attend aucune familiarité avec " -"l'apprentissage fédéré. Seule une compréhension de base de la science des" -" données et de la programmation Python est supposée." +"First of all, it's more code. But why? The difference comes from the fact" +" that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the " +"network, it eventually needs to turn these parameters into ``bytes``. " +"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"serialization. Turning raw bytes into something more useful (like NumPy " +"``ndarray``'s) is called deserialization. Flower needs to do both: it " +"needs to serialize parameters on the server-side and send them to the " +"client, the client needs to deserialize them to use them for local " +"training, and then serialize the updated parameters again to send them " +"back to the server, which (finally!) deserializes them again in order to " +"aggregate them with the updates received from other clients." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the open-source Flower community on Slack to connect, ask questions, and " -"get help: `Join Slack `__ 🌼 We'd love to " -"hear from you in the ``#introductions`` channel! And if anything is " -"unclear, head over to the ``#questions`` channel." +"The only *real* difference between Client and NumPyClient is that " +"NumPyClient takes care of serialization and deserialization for you. It " +"can do so because it expects you to return parameters as NumPy ndarray's," +" and it knows how to handle these. This makes working with machine " +"learning libraries that have good NumPy support (most of them) a breeze." msgstr "" -"`Star Flower on GitHub `__ ⭐️ et " -"rejoignez la communauté Flower sur Slack pour vous connecter, poser des " -"questions et obtenir de l'aide : `Join Slack `__ 🌼 Nous serions ravis d'avoir de vos nouvelles dans le canal " -"``#introductions`` ! Et si quelque chose n'est pas clair, rendez-vous sur" -" le canal ``#questions``." +"La seule *vraie* différence entre Client et NumPyClient est que " +"NumPyClient s'occupe de la sérialisation et de la désérialisation pour " +"toi. Il peut le faire parce qu'il s'attend à ce que tu renvoies des " +"paramètres sous forme de NumPy ndarray, et il sait comment les gérer. " +"Cela permet de travailler avec des bibliothèques d'apprentissage " +"automatique qui ont une bonne prise en charge de NumPy (la plupart " +"d'entre elles) en un clin d'œil." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 -#, fuzzy -msgid "Let's get started!" -msgstr "Allons-y, déclarons-le !" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 +msgid "" +"In terms of API, there's one major difference: all methods in Client take" +" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " +"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"``NumPyClient`` on the other hand have multiple arguments (e.g., " +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" +" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These " +"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " +"values you're used to from ``NumPyClient``." +msgstr "" +"In terms of API, there's one major difference: all methods in Client take" +" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " +"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"``NumPyClient`` on the other hand have multiple arguments (e.g., " +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" +" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These " +"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " +"values you're used to from ``NumPyClient``." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 -msgid "Classic machine learning" -msgstr "Apprentissage automatique classique" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 +msgid "Step 3: Custom serialization" +msgstr "Étape 3 : Sérialisation personnalisée" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how " -"most machine learning works today." +"Here we will explore how to implement custom serialization with a simple " +"example." msgstr "" -"Avant de commencer à discuter de l'apprentissage fédéré, récapitulons " -"rapidement la façon dont la plupart des apprentissages automatiques " -"fonctionnent aujourd'hui." +"Nous allons ici explorer comment mettre en œuvre une sérialisation " +"personnalisée à l'aide d'un exemple simple." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 msgid "" -"In machine learning, we have a model, and we have data. The model could " -"be a neural network (as depicted here), or something else, like classical" -" linear regression." +"But first what is serialization? Serialization is just the process of " +"converting an object into raw bytes, and equally as important, " +"deserialization is the process of converting raw bytes back into an " +"object. This is very useful for network communication. Indeed, without " +"serialization, you could not just a Python object through the internet." msgstr "" -"Dans l'apprentissage automatique, nous avons un modèle et des données. Le" -" modèle peut être un réseau neuronal (comme illustré ici), ou quelque " -"chose d'autre, comme la régression linéaire classique." +"Mais d'abord, qu'est-ce que la sérialisation ? La sérialisation est " +"simplement le processus de conversion d'un objet en octets bruts, et tout" +" aussi important, la désérialisation est le processus de reconversion des" +" octets bruts en objet. Ceci est très utile pour la communication réseau." +" En effet, sans la sérialisation, tu ne pourrais pas faire passer un " +"objet Python par Internet." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|2b5c62c529f6416f840c594cce062fbb|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 +msgid "" +"Federated Learning relies heavily on internet communication for training " +"by sending Python objects back and forth between the clients and the " +"server. This means that serialization is an essential part of Federated " +"Learning." msgstr "" +"L'apprentissage fédéré s'appuie fortement sur la communication Internet " +"pour la formation en envoyant des objets Python dans les deux sens entre " +"les clients et le serveur, ce qui signifie que la sérialisation est un " +"élément essentiel de l'apprentissage fédéré." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 -msgid "Model and data" -msgstr "Modèle et données" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 msgid "" -"We train the model using the data to perform a useful task. A task could " -"be to detect objects in images, transcribe an audio recording, or play a " -"game like Go." -msgstr "" -"Nous entraînons le modèle en utilisant les données pour effectuer une " -"tâche utile. Une tâche peut consister à détecter des objets dans des " -"images, à transcrire un enregistrement audio ou à jouer à un jeu comme le" -" Go." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|90b334680cb7467d9a04d39b8e8dca9f|" +"In the following section, we will write a basic example where instead of " +"sending a serialized version of our ``ndarray``\\ s containing our " +"parameters, we will first convert the ``ndarray`` into sparse matrices, " +"before sending them. This technique can be used to save bandwidth, as in " +"certain cases where the weights of a model are sparse (containing many 0 " +"entries), converting them to a sparse matrix can greatly improve their " +"bytesize." msgstr "" +"Dans la section suivante, nous allons écrire un exemple de base où, au " +"lieu d'envoyer une version sérialisée de nos ``ndarray`` contenant nos " +"paramètres, nous allons d'abord convertir les ``ndarray`` en matrices " +"éparses, avant de les envoyer. Cette technique peut être utilisée pour " +"économiser de la bande passante, car dans certains cas où les poids d'un " +"modèle sont épars (contenant de nombreuses entrées 0), les convertir en " +"une matrice éparse peut grandement améliorer leur taille en octets." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 -msgid "Train model using data" -msgstr "Entraîne le modèle à l'aide des données" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 +msgid "Our custom serialization/deserialization functions" +msgstr "Nos fonctions de sérialisation/désérialisation personnalisées" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"Now, in practice, the training data we work with doesn't originate on the" -" machine we train the model on. It gets created somewhere else." +"This is where the real serialization/deserialization will happen, " +"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"``sparse_bytes_to_ndarray`` for deserialization." msgstr "" -"Dans la pratique, les données d'entraînement avec lesquelles nous " -"travaillons ne proviennent pas de la machine sur laquelle nous entraînons" -" le modèle. Elles sont créées ailleurs." +"C'est là que la véritable sérialisation/désérialisation se produira, en " +"particulier dans ``ndarray_to_sparse_bytes`` pour la sérialisation et " +"``sparse_bytes_to_ndarray`` pour la désérialisation." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"It originates on a smartphone by the user interacting with an app, a car " -"collecting sensor data, a laptop receiving input via the keyboard, or a " -"smart speaker listening to someone trying to sing a song." -msgstr "" -"Elle prend naissance sur un smartphone par l'interaction de l'utilisateur" -" avec une application, une voiture qui collecte des données de capteurs, " -"un ordinateur portable qui reçoit des entrées via le clavier, ou un haut-" -"parleur intelligent qui écoute quelqu'un qui essaie de chanter une " -"chanson." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|65764ceee89f4335bfd93fd0b115e831|" +"Note that we imported the ``scipy.sparse`` library in order to convert " +"our arrays." msgstr "" +"Notez que nous avons importé la bibliothèque ``scipy.sparse`` afin de " +"convertir nos tableaux." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 -msgid "Data on a phone" -msgstr "Données sur un téléphone" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 +msgid "Client-side" +msgstr "Côté client" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running" -" the same app. But it could also be several organizations, all generating" -" data for the same task." +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " +"will just have to call our custom functions in our " +"``flwr.client.Client``." msgstr "" -"Il est également important de mentionner que cet \"ailleurs\" n'est " -"généralement pas un seul endroit, mais plusieurs. Il peut s'agir de " -"plusieurs appareils fonctionnant tous avec la même application. Mais il " -"peut également s'agir de plusieurs organisations, qui génèrent toutes des" -" données pour la même tâche." +"Pour pouvoir sérialiser nos ``ndarray`` en paramètres sparse, il nous " +"suffira d'appeler nos fonctions personnalisées dans notre " +"``flwr.client.Client``." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 +msgid "" +"Indeed, in ``get_parameters`` we need to serialize the parameters we got " +"from our network using our custom ``ndarrays_to_sparse_parameters`` " +"defined above." msgstr "" +"En effet, dans ``get_parameters`` nous devons sérialiser les paramètres " +"que nous avons obtenus de notre réseau en utilisant nos " +"``ndarrays_to_sparse_parameters`` personnalisés définis ci-dessus." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 -msgid "Data is on many devices" -msgstr "Les données se trouvent sur de nombreux appareils" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" -"So to use machine learning, or any kind of data analysis, the approach " -"that has been used in the past was to collect all data on a central " -"server. This server can be somewhere in a data center, or somewhere in " -"the cloud." +"In ``fit``, we first need to deserialize the parameters coming from the " +"server using our custom ``sparse_parameters_to_ndarrays`` and then we " +"need to serialize our local results with " +"``ndarrays_to_sparse_parameters``." msgstr "" -"Ainsi, pour utiliser l'apprentissage automatique, ou tout autre type " -"d'analyse de données, l'approche utilisée par le passé consistait à " -"collecter toutes les données sur un serveur central. Ce serveur peut se " -"trouver quelque part dans un centre de données, ou quelque part dans le " -"cloud." +"Dans ``fit``, nous devons d'abord désérialiser les paramètres provenant " +"du serveur en utilisant notre ``sparse_parameters_to_ndarrays`` " +"personnalisé, puis nous devons sérialiser nos résultats locaux avec " +"``ndarrays_to_sparse_parameters``." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|11e95ac83a8548d8b3505b4663187d07|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +msgid "" +"In ``evaluate``, we will only need to deserialize the global parameters " +"with our custom function." msgstr "" +"Dans ``evaluate``, nous n'aurons besoin que de désérialiser les " +"paramètres globaux avec notre fonction personnalisée." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 -msgid "Central data collection" -msgstr "Collecte centralisée des données" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 +msgid "Server-side" +msgstr "Côté serveur" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"Once all the data is collected in one place, we can finally use machine " -"learning algorithms to train our model on the data. This is the machine " -"learning approach that we've basically always relied on." +"For this example, we will just use ``FedAvg`` as a strategy. To change " +"the serialization and deserialization here, we only need to reimplement " +"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" +" functions of the strategy will be inherited from the super class " +"``FedAvg``." msgstr "" -"Une fois que toutes les données sont rassemblées en un seul endroit, nous" -" pouvons enfin utiliser des algorithmes d'apprentissage automatique pour " -"entraîner notre modèle sur les données. C'est l'approche d'apprentissage " -"automatique sur laquelle nous nous sommes fondamentalement toujours " -"appuyés." +"Pour cet exemple, nous utiliserons simplement ``FedAvg`` comme stratégie." +" Pour modifier la sérialisation et la désérialisation ici, il suffit de " +"réimplémenter les fonctions ``evaluate`` et ``aggregate_fit`` de " +"``FedAvg``. Les autres fonctions de la stratégie seront héritées de la " +"super-classe ``FedAvg``." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|1dab2f3a23674abc8a6731f20fa10730|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 +msgid "As you can see only one line as change in ``evaluate``:" +msgstr "Comme tu peux le voir, seule une ligne a été modifiée dans ``evaluate`` :" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 +msgid "" +"And for ``aggregate_fit``, we will first deserialize every result we " +"received:" msgstr "" +"Et pour ``aggregate_fit``, nous allons d'abord désérialiser chaque " +"résultat que nous avons reçu :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 -msgid "Central model training" -msgstr "Formation au modèle central" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 +msgid "And then serialize the aggregated result:" +msgstr "Puis sérialise le résultat agrégé :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 -msgid "Challenges of classical machine learning" -msgstr "Les défis de l'apprentissage automatique classique" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 +msgid "We can now run our custom serialization example!" +msgstr "" +"Nous pouvons maintenant exécuter notre exemple de sérialisation " +"personnalisée !" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 msgid "" -"The classic machine learning approach we've just seen can be used in some" -" cases. Great examples include categorizing holiday photos, or analyzing " -"web traffic. Cases, where all the data is naturally available on a " -"centralized server." +"In this part of the tutorial, we've seen how we can build clients by " +"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " +"convenience abstraction that makes it easier to work with machine " +"learning libraries that have good NumPy interoperability. ``Client`` is a" +" more flexible abstraction that allows us to do things that are not " +"possible in ``NumPyClient``. In order to do so, it requires us to handle " +"parameter serialization and deserialization ourselves." msgstr "" -"L'approche classique de l'apprentissage automatique que nous venons de " -"voir peut être utilisée dans certains cas. Parmi les grands exemples, on " -"peut citer la catégorisation des photos de vacances, ou l'analyse du " -"trafic web. Des cas, où toutes les données sont naturellement disponibles" -" sur un serveur centralisé." +"Dans cette partie du tutoriel, nous avons vu comment construire des " +"clients en sous-classant soit ``NumPyClient``, soit ``Client``. " +"``NumPyClient`` est une abstraction de commodité qui facilite le travail " +"avec les bibliothèques d'apprentissage automatique qui ont une bonne " +"interopérabilité NumPy. ``Client`` est une abstraction plus flexible qui " +"nous permet de faire des choses qui ne sont pas possibles dans " +"``NumPyClient``. Pour ce faire, elle nous oblige à gérer nous-mêmes la " +"sérialisation et la désérialisation des paramètres." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|7f0ee162da38450788493a21627306f7|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 +msgid "" +"This is the final part of the Flower tutorial (for now!), " +"congratulations! You're now well equipped to understand the rest of the " +"documentation. There are many topics we didn't cover in the tutorial, we " +"recommend the following resources:" msgstr "" +"C'est la dernière partie du tutoriel Flower (pour l'instant !), " +"félicitations ! Tu es maintenant bien équipé pour comprendre le reste de " +"la documentation. Il y a de nombreux sujets que nous n'avons pas abordés " +"dans le tutoriel, nous te recommandons les ressources suivantes :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 -msgid "Centralized possible" -msgstr "Possibilité de centralisation" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 +msgid "`Read Flower Docs `__" +msgstr "`Lire les docs sur les fleurs `__" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"But the approach can not be used in many other cases. Cases, where the " -"data is not available on a centralized server, or cases where the data " -"available on one server is not enough to train a good model." -msgstr "" -"Mais cette approche ne peut pas être utilisée dans de nombreux autres cas" -" : lorsque les données ne sont pas disponibles sur un serveur centralisé," -" ou lorsque les données disponibles sur un serveur ne sont pas " -"suffisantes pour former un bon modèle." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" +"`Check out Flower Code Examples " +"`__" msgstr "" +"`Check out Flower Code Examples " +"`__" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 -msgid "Centralized impossible" -msgstr "Impossible de centraliser" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 #, fuzzy msgid "" -"There are many reasons why the classic centralized machine learning " -"approach does not work for a large number of highly important real-world " -"use cases. Those reasons include:" +"`Use Flower Baselines for your research " +"`__" msgstr "" -"Il existe de nombreuses raisons pour lesquelles l'approche classique " -"centralisée de l'apprentissage automatique ne fonctionne pas pour un " -"grand nombre de cas d'utilisation très importants dans le monde réel, " -"notamment :" +"`Utilise les lignes de base des fleurs pour ta recherche " +"`__" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 #, fuzzy msgid "" -"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " -"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " -"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " -"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " -"protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own " -"users' data for artificial intelligence training because those users live" -" in different parts of the world, and their data is governed by different" -" data protection regulations." +"`Watch Flower Summit 2023 videos `__" msgstr "" -"**Réglementations** : GDPR (Europe), CCPA (Californie), PIPEDA (Canada), " -"LGPD (Brésil), PDPL (Argentine), KVKK (Turquie), POPI (Afrique du Sud), " -"FSS (Russie), CDPR (Chine), PDPB (Inde), PIPA (Corée), APPI (Japon), PDP " -"(Indonésie), PDPA (Singapour), APP (Australie), et d'autres " -"réglementations protègent les données sensibles contre le déplacement. En" -" fait, ces réglementations empêchent même parfois des organisations " -"individuelles de combiner les données de leurs propres utilisateurs pour " -"la formation à l'intelligence artificielle parce que ces utilisateurs " -"vivent dans différentes parties du monde, et que leurs données sont " -"régies par des réglementations différentes en matière de protection des " -"données." +"`Regardez les vidéos du Flower Summit 2022 `__" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 -msgid "" -"**User preference**: In addition to regulation, there are use cases where" -" users just expect that no data leaves their device, ever. If you type " -"your passwords and credit card info into the digital keyboard of your " -"phone, you don't expect those passwords to end up on the server of the " -"company that developed that keyboard, do you? In fact, that use case was " -"the reason federated learning was invented in the first place." +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 +msgid "Get started with Flower" msgstr "" -"**Préférence de l'utilisateur** : En plus de la réglementation, il existe" -" des cas d'utilisation où les utilisateurs s'attendent tout simplement à " -"ce qu'aucune donnée ne quitte leur appareil, jamais. Si tu tapes tes mots" -" de passe et tes informations de carte de crédit sur le clavier numérique" -" de ton téléphone, tu ne t'attends pas à ce que ces mots de passe " -"finissent sur le serveur de l'entreprise qui a développé ce clavier, n" -"'est-ce pas ? En fait, ce cas d'utilisation est la raison pour laquelle " -"l'apprentissage fédéré a été inventé en premier lieu." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 +msgid "Welcome to the Flower federated learning tutorial!" +msgstr "Bienvenue au tutoriel sur l'apprentissage fédéré de la fleur !" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 #, fuzzy msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data " -"volume that it is neither feasible nor economic to collect all the data " -"(due to, for example, bandwidth or communication efficiency). Think about" -" a national rail service with hundreds of train stations across the " -"country. If each of these train stations is outfitted with a number of " -"security cameras, the volume of raw on-device data they produce requires " -"incredibly powerful and exceedingly expensive infrastructure to process " -"and store. And most of the data isn't even useful." -msgstr "" -"**volume de données** : certains capteurs, comme les caméras, produisent " -"un volume de données si important qu'il n'est ni possible ni économique " -"de collecter toutes les données (en raison, par exemple, de la bande " -"passante ou de l'efficacité des communications). Pensez à un service " -"ferroviaire national comptant des centaines de gares à travers le pays. " -"Si chacune de ces gares est équipée d'un certain nombre de caméras de " -"sécurité, le volume de données brutes sur les appareils qu'elles " -"produisent nécessite une infrastructure incroyablement puissante et " -"excessivement coûteuse pour les traiter et les stocker. Et la plupart de " -"ces données ne sont même pas utiles." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 -msgid "Examples where centralized machine learning does not work include:" +"In this notebook, we'll build a federated learning system using Flower, " +"`Flower Datasets `__ and PyTorch. In " +"part 1, we use PyTorch for the model training pipeline and data loading. " +"In part 2, we continue to federate the PyTorch-based pipeline using " +"Flower." msgstr "" -"Voici quelques exemples où l'apprentissage automatique centralisé ne " -"fonctionne pas :" +"Dans ce carnet, nous allons construire un système d'apprentissage fédéré " +"en utilisant Flower et PyTorch. Dans la première partie, nous utilisons " +"PyTorch pour le pipeline d'entraînement des modèles et le chargement des " +"données. Dans la deuxième partie, nous continuons à fédérer le pipeline " +"basé sur PyTorch en utilisant Flower." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 #, fuzzy +msgid "Let's get started!" +msgstr "Allons-y, déclarons-le !" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 msgid "" -"Sensitive healthcare records from multiple hospitals to train cancer " -"detection models" +"Before we begin with any actual code, let's make sure that we have " +"everything we need." msgstr "" -"Des dossiers médicaux sensibles provenant de plusieurs hôpitaux pour " -"former des modèles de détection du cancer" +"Avant de commencer à coder, assurons-nous que nous disposons de tout ce " +"dont nous avons besoin." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 +#, fuzzy msgid "" -"Financial information from different organizations to detect financial " -"fraud" +"Next, we install the necessary packages for PyTorch (``torch`` and " +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " +"(``flwr``):" msgstr "" -"Informations financières provenant de différentes organisations pour " -"détecter les fraudes financières" +"Ensuite, nous installons les paquets nécessaires pour PyTorch (``torch`` " +"et ``torchvision``) et Flower (``flwr``) :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 -msgid "Location data from your electric car to make better range prediction" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 +#, fuzzy +msgid "" +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" +" GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" -"Les données de localisation de ta voiture électrique pour mieux prédire " -"l'autonomie" +"Il est possible de passer à un runtime dont l'accélération GPU est " +"activée (sur Google Colab : ``Runtime > Change runtime type > Hardware " +"acclerator : GPU > Save``). Note cependant que Google Colab n'est pas " +"toujours en mesure de proposer l'accélération GPU. Si tu vois une erreur " +"liée à la disponibilité du GPU dans l'une des sections suivantes, " +"envisage de repasser à une exécution basée sur le CPU en définissant " +"``DEVICE = torch.device(\"cpu\")``. Si le runtime a activé l'accélération" +" GPU, tu devrais voir apparaître le résultat ``Training on cuda``, sinon " +"il dira ``Training on cpu``." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 -msgid "End-to-end encrypted messages to train better auto-complete models" -msgstr "" -"Messages cryptés de bout en bout pour former de meilleurs modèles " -"d'autocomplétion" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 +msgid "Loading the data" +msgstr "Chargement des données" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 #, fuzzy msgid "" -"The popularity of privacy-enhancing systems like the `Brave " -"`__ browser or the `Signal `__ " -"messenger shows that users care about privacy. In fact, they choose the " -"privacy-enhancing version over other alternatives, if such an alternative" -" exists. But what can we do to apply machine learning and data science to" -" these cases to utilize private data? After all, these are all areas that" -" would benefit significantly from recent advances in AI." +"Federated learning can be applied to many different types of tasks across" +" different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular " +"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " +"distinguish between images from ten different classes: 'airplane', " +"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " +"'truck'." msgstr "" -"La popularité des systèmes améliorant la confidentialité comme le " -"navigateur `Brave `__ ou le messager `Signal " -"`__ montre que les utilisateurs se soucient de la " -"confidentialité. En fait, ils choisissent la version améliorant la " -"confidentialité plutôt que d'autres alternatives, si une telle " -"alternative existe. Mais que pouvons-nous faire pour appliquer " -"l'apprentissage automatique et la science des données à ces cas afin " -"d'utiliser les données privées ? Après tout, ce sont tous des domaines " -"qui bénéficieraient de manière significative des récentes avancées en " -"matière d'IA." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 -msgid "Federated learning" -msgstr "Apprentissage fédéré" +"L'apprentissage fédéré peut être appliqué à de nombreux types de tâches " +"dans différents domaines. Dans ce tutoriel, nous présentons " +"l'apprentissage fédéré en formant un simple réseau neuronal " +"convolutionnel (CNN) sur l'ensemble de données populaire CIFAR-10. " +"CIFAR-10 peut être utilisé pour former des classificateurs d'images qui " +"font la distinction entre les images de dix classes différentes :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" -"Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead " -"of moving the data to the training. Here's the single-sentence " -"explanation:" +"We simulate having multiple datasets from multiple organizations (also " +"called the \"cross-silo\" setting in federated learning) by splitting the" +" original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely " +"for experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the " +"data is naturally partitioned)." msgstr "" -"L'apprentissage fédéré inverse simplement cette approche. Il permet " -"l'apprentissage automatique sur des données distribuées en déplaçant la " -"formation vers les données, au lieu de déplacer les données vers la " -"formation. Voici l'explication en une seule phrase :" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 -msgid "Central machine learning: move the data to the computation" -msgstr "Apprentissage automatique central : déplace les données vers le calcul" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 -msgid "Federated (machine) learning: move the computation to the data" -msgstr "Apprentissage (machine) fédéré : déplacer le calcul vers les données" +"Nous simulons le fait d'avoir plusieurs ensembles de données provenant de" +" plusieurs organisations (également appelé le paramètre \"cross-silo\" " +"dans l'apprentissage fédéré) en divisant l'ensemble de données CIFAR-10 " +"original en plusieurs partitions. Chaque partition représentera les " +"données d'une seule organisation. Nous faisons cela purement à des fins " +"d'expérimentation, dans le monde réel, il n'y a pas besoin de diviser les" +" données parce que chaque organisation a déjà ses propres données (les " +"données sont donc naturellement partitionnées)." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 +#, fuzzy msgid "" -"By doing so, it enables us to use machine learning (and other data " -"science approaches) in areas where it wasn't possible before. We can now " -"train excellent medical AI models by enabling different hospitals to work" -" together. We can solve financial fraud by training AI models on the data" -" of different financial institutions. We can build novel privacy-" -"enhancing applications (such as secure messaging) that have better built-" -"in AI than their non-privacy-enhancing alternatives. And those are just a" -" few of the examples that come to mind. As we deploy federated learning, " -"we discover more and more areas that can suddenly be reinvented because " -"they now have access to vast amounts of previously inaccessible data." +"Each organization will act as a client in the federated learning system. " +"So having ten organizations participate in a federation means having ten " +"clients connected to the federated learning server." msgstr "" -"Ce faisant, il nous permet d'utiliser l'apprentissage automatique (et " -"d'autres approches de science des données) dans des domaines où cela " -"n'était pas possible auparavant. Nous pouvons désormais former " -"d'excellents modèles d'IA médicale en permettant à différents hôpitaux de" -" travailler ensemble. Nous pouvons résoudre les fraudes financières en " -"formant des modèles d'IA sur les données de différentes institutions " -"financières. Nous pouvons créer de nouvelles applications d'amélioration " -"de la confidentialité (telles que la messagerie sécurisée) qui ont une " -"meilleure IA intégrée que leurs alternatives d'amélioration de la " -"confidentialité. Et ce ne sont là que quelques exemples qui me viennent à" -" l'esprit. Au fur et à mesure que nous déployons l'apprentissage fédéré, " -"nous découvrons de plus en plus de domaines qui peuvent soudainement être" -" réinventés parce qu'ils ont maintenant accès à de vastes quantités de " -"données auparavant inaccessibles." +"Chaque organisation agira comme un client dans le système d'apprentissage" +" fédéré. Ainsi, le fait que dix organisations participent à une " +"fédération signifie que dix clients sont connectés au serveur " +"d'apprentissage fédéré :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 msgid "" -"So how does federated learning work, exactly? Let's start with an " -"intuitive explanation." +"Let's now create the Federated Dataset abstraction that from ``flwr-" +"datasets`` that partitions the CIFAR-10. We will create small training " +"and test set for each edge device and wrap each of them into a PyTorch " +"``DataLoader``:" msgstr "" -"Comment fonctionne l'apprentissage fédéré ? Commençons par une " -"explication intuitive." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 -msgid "Federated learning in five steps" -msgstr "L'apprentissage fédéré en cinq étapes" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 -msgid "Step 0: Initialize global model" -msgstr "Étape 0 : Initialisation du modèle global" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 +#, fuzzy msgid "" -"We start by initializing the model on the server. This is exactly the " -"same in classic centralized learning: we initialize the model parameters," -" either randomly or from a previously saved checkpoint." -msgstr "" -"Nous commençons par initialiser le modèle sur le serveur. C'est " -"exactement la même chose dans l'apprentissage centralisé classique : nous" -" initialisons les paramètres du modèle, soit de façon aléatoire, soit à " -"partir d'un point de contrôle précédemment sauvegardé." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|5b1408eec0d746cdb91162a9107b6089|" +"We now have a list of ten training sets and ten validation sets " +"(``trainloaders`` and ``valloaders``) representing the data of ten " +"different organizations. Each ``trainloader``/``valloader`` pair contains" +" 4000 training examples and 1000 validation examples. There's also a " +"single ``testloader`` (we did not split the test set). Again, this is " +"only necessary for building research or educational systems, actual " +"federated learning systems have their data naturally distributed across " +"multiple partitions." msgstr "" +"Nous avons maintenant une liste de dix ensembles de formation et dix " +"ensembles de validation (``trainloaders`` et ``valloaders``) représentant" +" les données de dix organisations différentes. Chaque paire " +"``trainloader`/``valloader`` contient 4500 exemples de formation et 500 " +"exemples de validation. Il y a également un seul ``testloader`` (nous " +"n'avons pas divisé l'ensemble de test). Encore une fois, cela n'est " +"nécessaire que pour construire des systèmes de recherche ou d'éducation, " +"les systèmes d'apprentissage fédérés actuels ont leurs données " +"naturellement distribuées à travers plusieurs partitions." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 -msgid "Initialize global model" -msgstr "Initialise le modèle global" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client" -" nodes)" +"Let's take a look at the first batch of images and labels in the first " +"training set (i.e., ``trainloaders[0]``) before we move on:" msgstr "" -"Étape 1 : envoyer le modèle à un certain nombre d'organisations/appareils" -" connectés (nœuds clients)" +"Jetons un coup d'œil au premier lot d'images et d'étiquettes du premier " +"ensemble d'entraînement (c'est-à-dire ``trainloaders[0]``) avant de " +"poursuivre :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 -#, fuzzy +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 msgid "" -"Next, we send the parameters of the global model to the connected client " -"nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts " -"their local training using the same model parameters. We often use only a" -" few of the connected nodes instead of all nodes. The reason for this is " -"that selecting more and more client nodes has diminishing returns." -msgstr "" -"Ensuite, nous envoyons les paramètres du modèle global aux nœuds clients " -"connectés (par exemple, les appareils périphériques comme les smartphones" -" ou les serveurs appartenant à des organisations). Cela permet de " -"s'assurer que chaque nœud participant commence sa formation locale en " -"utilisant les mêmes paramètres de modèle. Nous n'utilisons souvent que " -"quelques-uns des nœuds connectés au lieu de tous les nœuds. La raison en " -"est que la sélection d'un nombre croissant de nœuds clients a des " -"rendements décroissants." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" +"The output above shows a random batch of images from the first " +"``trainloader`` in our list of ten ``trainloaders``. It also prints the " +"labels associated with each image (i.e., one of the ten possible labels " +"we've seen above). If you run the cell again, you should see another " +"batch of images." msgstr "" +"La sortie ci-dessus montre un lot aléatoire d'images provenant du premier" +" ``chargeur de formation`` de notre liste de dix ``chargeurs de " +"formation``. Elle imprime également les étiquettes associées à chaque " +"image (c'est-à-dire l'une des dix étiquettes possibles que nous avons " +"vues ci-dessus). Si tu exécutes à nouveau la cellule, tu devrais voir un " +"autre lot d'images." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 -msgid "Send global model" -msgstr "Envoyer le modèle global" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 +msgid "Step 1: Centralized Training with PyTorch" +msgstr "Étape 1 : Formation centralisée avec PyTorch" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 msgid "" -"Step 2: Train model locally on the data of each organization/device " -"(client node)" +"Next, we're going to use PyTorch to define a simple convolutional neural " +"network. This introduction assumes basic familiarity with PyTorch, so it " +"doesn't cover the PyTorch-related aspects in full detail. If you want to " +"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " +"MINUTE BLITZ " +"`__." msgstr "" -"Étape 2 : Entraîne le modèle localement sur les données de chaque " -"organisation/appareil (nœud client)" +"Ensuite, nous allons utiliser PyTorch pour définir un simple réseau " +"neuronal convolutif. Cette introduction suppose une familiarité de base " +"avec PyTorch, elle ne couvre donc pas en détail les aspects liés à " +"PyTorch. Si tu veux plonger plus profondément dans PyTorch, nous te " +"recommandons `DEEP LEARNING WITH PYTORCH : A 60 MINUTE BLITZ " +"`__." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 -msgid "" -"Now that all (selected) client nodes have the latest version of the " -"global model parameters, they start the local training. They use their " -"own local dataset to train their own local model. They don't train the " -"model until full convergence, but they only train for a little while. " -"This could be as little as one epoch on the local data, or even just a " -"few steps (mini-batches)." -msgstr "" -"Maintenant que tous les nœuds clients (sélectionnés) disposent de la " -"dernière version des paramètres du modèle global, ils commencent " -"l'entraînement local. Ils utilisent leur propre ensemble de données " -"locales pour entraîner leur propre modèle local. Ils n'entraînent pas le " -"modèle jusqu'à la convergence totale, mais ils ne s'entraînent que " -"pendant un petit moment. Il peut s'agir d'une seule époque sur les " -"données locales, ou même de quelques étapes (mini-batchs)." +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 +msgid "Defining the model" +msgstr "Définir le modèle" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 +msgid "" +"We use the simple CNN described in the `PyTorch tutorial " +"`__:" msgstr "" +"Nous utilisons le CNN simple décrit dans le tutoriel `PyTorch " +"`__ :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 -msgid "Train on local data" -msgstr "Forme-toi aux données locales" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 +msgid "Let's continue with the usual training and test functions:" +msgstr "Poursuivons avec les fonctions habituelles de formation et de test :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 -msgid "Step 3: Return model updates back to the server" -msgstr "Étape 3 : Renvoyer les mises à jour du modèle au serveur" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 +msgid "Training the model" +msgstr "Entraîne le modèle" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" -"After local training, each client node has a slightly different version " -"of the model parameters they originally received. The parameters are all " -"different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the " -"server. The model updates they send can either be the full model " -"parameters or just the gradients that were accumulated during local " -"training." +"We now have all the basic building blocks we need: a dataset, a model, a " +"training function, and a test function. Let's put them together to train " +"the model on the dataset of one of our organizations " +"(``trainloaders[0]``). This simulates the reality of most machine " +"learning projects today: each organization has their own data and trains " +"models only on this internal data:" msgstr "" -"Après l'entraînement local, chaque nœud client possède une version " -"légèrement différente des paramètres du modèle qu'il a reçus à l'origine." -" Les paramètres sont tous différents parce que chaque nœud client a des " -"exemples différents dans son ensemble de données local. Les nœuds clients" -" renvoient ensuite ces mises à jour du modèle au serveur. Les mises à " -"jour du modèle qu'ils envoient peuvent être soit les paramètres complets " -"du modèle, soit seulement les gradients qui ont été accumulés au cours de" -" l'entraînement local." +"Nous avons maintenant tous les éléments de base dont nous avons besoin : " +"un ensemble de données, un modèle, une fonction d'entraînement et une " +"fonction de test. Assemblons-les pour entraîner le modèle sur l'ensemble " +"de données de l'une de nos organisations (``trainloaders[0]``). Cela " +"simule la réalité de la plupart des projets d'apprentissage automatique " +"aujourd'hui : chaque organisation possède ses propres données et entraîne" +" les modèles uniquement sur ces données internes :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|ec1fe880237247e0975f52766775ab84|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 +msgid "" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " +"in a test set accuracy of about 41%, which is not good, but at the same " +"time, it doesn't really matter for the purposes of this tutorial. The " +"intent was just to show a simplistic centralized training pipeline that " +"sets the stage for what comes next - federated learning!" msgstr "" +"L'entraînement du CNN simple sur notre fractionnement CIFAR-10 pendant 5 " +"époques devrait se traduire par une précision de l'ensemble de test " +"d'environ 41 %, ce qui n'est pas bon, mais en même temps, cela n'a pas " +"vraiment d'importance pour les besoins de ce tutoriel. L'intention était " +"juste de montrer un pipeline d'entraînement centralisé simpliste qui " +"prépare le terrain pour ce qui vient ensuite - l'apprentissage fédéré !" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 -msgid "Send model updates" -msgstr "Envoyer les mises à jour du modèle" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 +msgid "Step 2: Federated Learning with Flower" +msgstr "Étape 2 : Apprentissage fédéré avec Flower" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 -msgid "Step 4: Aggregate model updates into a new global model" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 +msgid "" +"Step 1 demonstrated a simple centralized training pipeline. All data was " +"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." +" Next, we'll simulate a situation where we have multiple datasets in " +"multiple organizations and where we train a model over these " +"organizations using federated learning." msgstr "" -"Étape 4 : Agréger les mises à jour des modèles dans un nouveau modèle " -"global" +"L'étape 1 a montré un simple pipeline de formation centralisé. Toutes les" +" données étaient au même endroit (c'est-à-dire un seul ``trainloader`` et" +" un seul ``valloader``). Ensuite, nous allons simuler une situation où " +"nous avons plusieurs ensembles de données dans plusieurs organisations et" +" où nous formons un modèle sur ces organisations à l'aide de " +"l'apprentissage fédéré." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 +msgid "Updating model parameters" +msgstr "Mise à jour des paramètres du modèle" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of " -"the original global model, each trained on the local data of one client. " -"But didn't we want to have one model that contains the learnings from the" -" data of all 100 client nodes?" +"In federated learning, the server sends the global model parameters to " +"the client, and the client updates the local model with the parameters " +"received from the server. It then trains the model on the local data " +"(which changes the model parameters locally) and sends the " +"updated/changed model parameters back to the server (or, alternatively, " +"it sends just the gradients back to the server, not the full model " +"parameters)." msgstr "" -"Le serveur reçoit les mises à jour du modèle des nœuds clients " -"sélectionnés. S'il a sélectionné 100 nœuds clients, il dispose maintenant" -" de 100 versions légèrement différentes du modèle global original, " -"chacune ayant été formée sur les données locales d'un client. Mais ne " -"voulions-nous pas avoir un seul modèle qui contienne les apprentissages " -"des données de l'ensemble des 100 nœuds clients ?" +"Dans l'apprentissage fédéré, le serveur envoie les paramètres du modèle " +"global au client, et le client met à jour le modèle local avec les " +"paramètres reçus du serveur. Il entraîne ensuite le modèle sur les " +"données locales (ce qui modifie les paramètres du modèle localement) et " +"renvoie les paramètres du modèle mis à jour/changés au serveur (ou, " +"alternativement, il renvoie seulement les gradients au serveur, et non " +"pas les paramètres complets du modèle)." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." +"We need two helper functions to update the local model with parameters " +"received from the server and to get the updated model parameters from the" +" local model: ``set_parameters`` and ``get_parameters``. The following " +"two functions do just that for the PyTorch model above." msgstr "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" -msgstr "" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 -msgid "Aggregate model updates" -msgstr "Mises à jour globales du modèle" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 -msgid "Step 5: Repeat steps 1 to 4 until the model converges" -msgstr "Étape 5 : répète les étapes 1 à 4 jusqu'à ce que le modèle converge" +"Nous avons besoin de deux fonctions d'aide pour mettre à jour le modèle " +"local avec les paramètres reçus du serveur et pour obtenir les paramètres" +" mis à jour du modèle local : ``set_parameters`` et ``get_parameters``. " +"Les deux fonctions suivantes font exactement cela pour le modèle PyTorch " +"ci-dessus." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 msgid "" -"Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step " -"1), the client nodes train on their local data (step 2), they send their " -"updated models to the server (step 3), and the server then aggregates the" -" model updates to get a new version of the global model (step 4)." +"The details of how this works are not really important here (feel free to" +" consult the PyTorch documentation if you want to learn more). In " +"essence, we use ``state_dict`` to access PyTorch model parameter tensors." +" The parameter tensors are then converted to/from a list of NumPy " +"ndarray's (which Flower knows how to serialize/deserialize):" msgstr "" -"Les étapes 1 à 4 constituent ce que nous appelons un cycle unique " -"d'apprentissage fédéré. Les paramètres du modèle global sont envoyés aux " -"nœuds clients participants (étape 1), les nœuds clients s'entraînent sur " -"leurs données locales (étape 2), ils envoient leurs modèles mis à jour au" -" serveur (étape 3), et le serveur agrège ensuite les mises à jour du " -"modèle pour obtenir une nouvelle version du modèle global (étape 4)." +"Les détails de ce fonctionnement ne sont pas vraiment importants ici " +"(n'hésite pas à consulter la documentation PyTorch si tu veux en savoir " +"plus). En substance, nous utilisons ``state_dict`` pour accéder aux " +"tenseurs de paramètres du modèle PyTorch. Les tenseurs de paramètres sont" +" ensuite convertis en/depuis une liste de ndarray NumPy (que Flower sait " +"sérialiser/désérialiser) :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 -#, fuzzy -msgid "" -"During a single round, each client node that participates in that " -"iteration only trains for a little while. This means that after the " -"aggregation step (step 4), we have a model that has been trained on all " -"the data of all participating client nodes, but only for a little while. " -"We then have to repeat this training process over and over again to " -"eventually arrive at a fully trained model that performs well across the " -"data of all client nodes." -msgstr "" -"Au cours d'un seul tour, chaque nœud client qui participe à cette " -"itération ne s'entraîne que pendant un petit moment. Cela signifie " -"qu'après l'étape d'agrégation (étape 4), nous avons un modèle qui a été " -"entraîné sur toutes les données de tous les nœuds clients participants, " -"mais seulement pendant un petit moment. Nous devons ensuite répéter ce " -"processus d'entraînement encore et encore pour finalement arriver à un " -"modèle entièrement entraîné qui fonctionne bien sur l'ensemble des " -"données de tous les nœuds clients." +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 +msgid "Implementing a Flower client" +msgstr "Mise en place d'un client Flower" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning" -" in a nutshell. In later parts of this tutorial, we will go into more " -"detail. Interesting questions include: How can we select the best client " -"nodes that should participate in the next round? What's the best way to " -"aggregate model updates? How can we handle failing client nodes " -"(stragglers)?" +"With that out of the way, let's move on to the interesting part. " +"Federated learning systems consist of a server and multiple clients. In " +"Flower, we create clients by implementing subclasses of " +"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " +"``NumPyClient`` in this tutorial because it is easier to implement and " +"requires us to write less boilerplate." msgstr "" -"Félicitations, tu comprends maintenant les bases de l'apprentissage " -"fédéré. Il y a bien sûr beaucoup plus à discuter, mais c'était " -"l'apprentissage fédéré en quelques mots. Dans les parties suivantes de ce" -" tutoriel, nous irons plus en détail. Les questions intéressantes " -"comprennent : comment pouvons-nous sélectionner les meilleurs nœuds " -"clients qui devraient participer au prochain tour ? Quelle est la " -"meilleure façon d'agréger les mises à jour du modèle ? Comment pouvons-" -"nous gérer les nœuds clients qui échouent (stragglers) ?" +"Ceci étant dit, passons à la partie intéressante. Les systèmes " +"d'apprentissage fédérés se composent d'un serveur et de plusieurs " +"clients. Dans Flower, nous créons des clients en mettant en œuvre des " +"sous-classes de ``flwr.client.Client`` ou de ``flwr.client.NumPyClient``." +" Nous utilisons ``NumPyClient`` dans ce tutoriel parce qu'il est plus " +"facile à mettre en œuvre et qu'il nous oblige à rédiger moins de modèles " +"de chaudière." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 -#, fuzzy +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"Just like we can train a model on the decentralized data of different " -"client nodes, we can also evaluate the model on that data to receive " -"valuable metrics. This is called federated evaluation, sometimes " -"abbreviated as FE. In fact, federated evaluation is an integral part of " -"most federated learning systems." +"To implement the Flower client, we create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``:" msgstr "" -"Tout comme nous pouvons former un modèle sur les données décentralisées " -"de différents nœuds clients, nous pouvons également évaluer le modèle sur" -" ces données pour recevoir des mesures précieuses. C'est ce qu'on appelle" -" l'évaluation fédérée, parfois abrégée en FE. En fait, l'évaluation " -"fédérée fait partie intégrante de la plupart des systèmes d'apprentissage" -" fédéré." +"Pour mettre en œuvre le client Flower, nous créons une sous-classe de " +"``flwr.client.NumPyClient`` et mettons en œuvre les trois méthodes " +"``get_parameters``, ``fit`` et ``evaluate`` :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 -msgid "Federated analytics" -msgstr "Analyses fédérées" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 +msgid "``get_parameters``: Return the current local model parameters" +msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" -"In many cases, machine learning isn't necessary to derive value from " -"data. Data analysis can yield valuable insights, but again, there's often" -" not enough data to get a clear answer. What's the average age at which " -"people develop a certain type of health condition? Federated analytics " -"enables such queries over multiple client nodes. It is usually used in " -"conjunction with other privacy-enhancing technologies like secure " -"aggregation to prevent the server from seeing the results submitted by " -"individual client nodes." +"``fit``: Receive model parameters from the server, train the model " +"parameters on the local data, and return the (updated) model parameters " +"to the server" msgstr "" -"Dans de nombreux cas, l'apprentissage automatique n'est pas nécessaire " -"pour tirer de la valeur des données. L'analyse des données peut donner " -"des indications précieuses, mais là encore, il n'y a souvent pas assez de" -" données pour obtenir une réponse claire. Quel est l'âge moyen auquel les" -" gens développent un certain type de problème de santé ? L'analyse " -"fédérée permet de telles requêtes sur plusieurs nœuds clients. Elle est " -"généralement utilisée en conjonction avec d'autres technologies de " -"renforcement de la confidentialité, comme l'agrégation sécurisée, pour " -"empêcher le serveur de voir les résultats soumis par les nœuds clients " -"individuels." +"``fit`` : reçoit les paramètres du modèle du serveur, entraîne les " +"paramètres du modèle sur les données locales et renvoie les paramètres du" +" modèle (mis à jour) au serveur" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and " -"sharing statistical data, ensuring the privacy of individual " -"participants. DP achieves this by adding statistical noise to the model " -"updates, ensuring any individual participants’ information cannot be " -"distinguished or re-identified. This technique can be considered an " -"optimization that provides a quantifiable privacy protection measure." +"``evaluate``: Receive model parameters from the server, evaluate the " +"model parameters on the local data, and return the evaluation result to " +"the server" msgstr "" +"``evaluate`` : reçoit les paramètres du modèle du serveur, évalue les " +"paramètres du modèle sur les données locales et renvoie le résultat de " +"l'évaluation au serveur" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 -msgid "Flower" -msgstr "Fleur" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 msgid "" -"Federated learning, federated evaluation, and federated analytics require" -" infrastructure to move machine learning models back and forth, train and" -" evaluate them on local data, and then aggregate the updated models. " -"Flower provides the infrastructure to do exactly that in an easy, " -"scalable, and secure way. In short, Flower presents a unified approach to" -" federated learning, analytics, and evaluation. It allows the user to " -"federate any workload, any ML framework, and any programming language." -msgstr "" -"L'apprentissage fédéré, l'évaluation fédérée et l'analyse fédérée " -"nécessitent une infrastructure pour déplacer les modèles d'apprentissage " -"automatique dans les deux sens, les entraîner et les évaluer sur des " -"données locales, puis agréger les modèles mis à jour. Flower fournit " -"l'infrastructure pour faire exactement cela de manière simple, évolutive " -"et sécurisée. En bref, Flower présente une approche unifiée de " -"l'apprentissage, de l'analyse et de l'évaluation fédérés. Il permet à " -"l'utilisateur de fédérer n'importe quelle charge de travail, n'importe " -"quel cadre de ML et n'importe quel langage de programmation." - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|ff726bc5505e432388ee2fdd6ef420b9|" +"We mentioned that our clients will use the previously defined PyTorch " +"components for model training and evaluation. Let's see a simple Flower " +"client implementation that brings everything together:" msgstr "" +"Nous avons mentionné que nos clients utiliseront les composants PyTorch " +"définis précédemment pour la formation et l'évaluation des modèles. " +"Voyons une simple mise en œuvre du client Flower qui réunit tout cela :" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal" -" computer, roomba, and phone)" +"Our class ``FlowerClient`` defines how local training/evaluation will be " +"performed and allows Flower to call the local training/evaluation through" +" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" +" *single client* in our federated learning system. Federated learning " +"systems have multiple clients (otherwise, there's not much to federate), " +"so each client will be represented by its own instance of " +"``FlowerClient``. If we have, for example, three clients in our workload," +" then we'd have three instances of ``FlowerClient``. Flower calls " +"``FlowerClient.fit`` on the respective instance when the server selects a" +" particular client for training (and ``FlowerClient.evaluate`` for " +"evaluation)." msgstr "" -"Serveur d'apprentissage fédéré de Flower et nœuds clients (voiture, " -"scooter, ordinateur personnel, roomba et téléphone)" +"Our class ``FlowerClient`` defines how local training/evaluation will be " +"performed and allows Flower to call the local training/evaluation through" +" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" +" *single client* in our federated learning system. Federated learning " +"systems have multiple clients (otherwise, there's not much to federate), " +"so each client will be represented by its own instance of " +"``FlowerClient``. If we have, for example, three clients in our workload," +" then we'd have three instances of ``FlowerClient``. Flower calls " +"``FlowerClient.fit`` on the respective instance when the server selects a" +" particular client for training (and ``FlowerClient.evaluate`` for " +"evaluation)." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 -msgid "" -"Congratulations, you just learned the basics of federated learning and " -"how it relates to the classic (centralized) machine learning!" -msgstr "" -"Félicitations, tu viens d'apprendre les bases de l'apprentissage fédéré " -"et son rapport avec l'apprentissage automatique classique (centralisé) !" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 +msgid "Using the Virtual Client Engine" +msgstr "Utilisation du moteur du client virtuel" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In the next part of this tutorial, we are going to build a first " -"federated learning system with Flower." +"In this notebook, we want to simulate a federated learning system with 10" +" clients on a single machine. This means that the server and all 10 " +"clients will live on a single machine and share resources such as CPU, " +"GPU, and memory. Having 10 clients would mean having 10 instances of " +"``FlowerClient`` in memory. Doing this on a single machine can quickly " +"exhaust the available memory resources, even if only a subset of these " +"clients participates in a single round of federated learning." msgstr "" -"Dans la prochaine partie de ce tutoriel, nous allons construire un " -"premier système d'apprentissage fédéré avec Flower." +"Dans ce carnet, nous voulons simuler un système d'apprentissage fédéré " +"avec 10 clients sur une seule machine. Cela signifie que le serveur et " +"les 10 clients vivront sur une seule machine et partageront des " +"ressources telles que le CPU, le GPU et la mémoire. Avoir 10 clients " +"signifierait avoir 10 instances de ``FlowerClient`` en mémoire. Faire " +"cela sur une seule machine peut rapidement épuiser les ressources mémoire" +" disponibles, même si seulement un sous-ensemble de ces clients participe" +" à un seul tour d'apprentissage fédéré." -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 -#, fuzzy +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 msgid "" -"The `Flower Federated Learning Tutorial - Part 1 " -"`__ shows how to build a simple federated learning system " -"with PyTorch and Flower." +"In addition to the regular capabilities where server and clients run on " +"multiple machines, Flower, therefore, provides special simulation " +"capabilities that create ``FlowerClient`` instances only when they are " +"actually necessary for training or evaluation. To enable the Flower " +"framework to create clients when necessary, we need to implement a " +"function called ``client_fn`` that creates a ``FlowerClient`` instance on" +" demand. Flower calls ``client_fn`` whenever it needs an instance of one " +"particular client to call ``fit`` or ``evaluate`` (those instances are " +"usually discarded after use, so they should not keep any local state). " +"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " +"be used, for example, to load different local data partitions for " +"different clients, as can be seen below:" msgstr "" -"Le `Tutoriel d'apprentissage fédéré Flower - Partie 1 " -"`__ " -"montre comment construire un système d'apprentissage fédéré simple avec " -"PyTorch et Flower." +"In addition to the regular capabilities where server and clients run on " +"multiple machines, Flower, therefore, provides special simulation " +"capabilities that create ``FlowerClient`` instances only when they are " +"actually necessary for training or evaluation. To enable the Flower " +"framework to create clients when necessary, we need to implement a " +"function called ``client_fn`` that creates a ``FlowerClient`` instance on" +" demand. Flower calls ``client_fn`` whenever it needs an instance of one " +"particular client to call ``fit`` or ``evaluate`` (those instances are " +"usually discarded after use, so they should not keep any local state). " +"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " +"be used, for example, to load different local data partitions for " +"different clients, as can be seen below:" -#~ msgid "Flower CLI commands" -#~ msgstr "Commandes CLI Flower" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 +msgid "Starting the training" +msgstr "Commencer la formation" -#~ msgid "Contributor guide" -#~ msgstr "Guide pour les contributeurs" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 +msgid "" +"We now have the class ``FlowerClient`` which defines client-side " +"training/evaluation and ``client_fn`` which allows Flower to create " +"``FlowerClient`` instances whenever it needs to call ``fit`` or " +"``evaluate`` on one particular client. The last step is to start the " +"actual simulation using ``flwr.simulation.start_simulation``." +msgstr "" +"Nous avons maintenant la classe ``FlowerClient`` qui définit " +"l'entraînement/évaluation côté client et ``client_fn`` qui permet à " +"Flower de créer des instances de ``FlowerClient`` chaque fois qu'il a " +"besoin d'appeler ``fit`` ou ``evaluate`` sur un client particulier. La " +"dernière étape consiste à démarrer la simulation réelle en utilisant " +"``flwr.simulation.start_simulation``." -#~ msgid "API Reference - Flower CLI commands" -#~ msgstr "Référence API - Commandes CLI pour Flower" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +msgid "" +"The function ``start_simulation`` accepts a number of arguments, amongst " +"them the ``client_fn`` used to create ``FlowerClient`` instances, the " +"number of clients to simulate (``num_clients``), the number of federated " +"learning rounds (``num_rounds``), and the strategy. The strategy " +"encapsulates the federated learning approach/algorithm, for example, " +"*Federated Averaging* (FedAvg)." +msgstr "" +"La fonction ``start_simulation`` accepte un certain nombre d'arguments, " +"parmi lesquels le ``client_fn`` utilisé pour créer les instances " +"``FlowerClient``, le nombre de clients à simuler (``num_clients``), le " +"nombre de tours d'apprentissage fédéré (``num_rounds``), et la stratégie." +" La stratégie encapsule l'approche/algorithme d'apprentissage fédéré, par" +" exemple, *Federated Averaging* (FedAvg)." -#~ msgid "API Reference - flwr (Python package)" -#~ msgstr "Référence API - flwr (paquetage Python)" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 +msgid "" +"Flower has a number of built-in strategies, but we can also use our own " +"strategy implementations to customize nearly all aspects of the federated" +" learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last " +"step is the actual call to ``start_simulation`` which - you guessed it - " +"starts the simulation:" +msgstr "" +"Flower dispose d'un certain nombre de stratégies intégrées, mais nous " +"pouvons également utiliser nos propres implémentations de stratégies pour" +" personnaliser presque tous les aspects de l'approche de l'apprentissage " +"fédéré. Pour cet exemple, nous utilisons l'implémentation intégrée " +"``FedAvg`` et nous la personnalisons en utilisant quelques paramètres de " +"base. La dernière étape est l'appel à ``start_simulation`` qui - tu l'as " +"deviné - démarre la simulation :" -#~ msgid "Flower client." -#~ msgstr "Client de Flower" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 +msgid "Behind the scenes" +msgstr "Dans les coulisses" -#~ msgid "Abstract base class for Flower clients." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 +msgid "So how does this work? How does Flower execute this simulation?" +msgstr "" +"Alors, comment cela fonctionne-t-il ? Comment Flower exécute-t-il cette " +"simulation ?" -#~ msgid "Evaluate the provided parameters using the locally held dataset." -#~ msgstr "évaluer le modèle mis à jour sur l'ensemble de test local" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 +#, python-format +msgid "" +"When we call ``start_simulation``, we tell Flower that there are 10 " +"clients (``num_clients=10``). Flower then goes ahead an asks the " +"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " +"select 100% of the available clients (``fraction_fit=1.0``), so it goes " +"ahead and selects 10 random clients (i.e., 100% of 10)." +msgstr "" +"Lorsque nous appelons ``start_simulation``, nous disons à Flower qu'il y " +"a 10 clients (``num_clients=10``). Flower demande alors à la stratégie " +"``FedAvg`` de sélectionner des clients. ``FedAvg` sait qu'il doit " +"sélectionner 100% des clients disponibles (``fraction_fit=1.0``), alors " +"il choisit 10 clients au hasard (c'est à dire 100% de 10)." -#~ msgid "Parameters" -#~ msgstr "Paramètres du modèle." +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 +msgid "" +"Flower then asks the selected 10 clients to train the model. When the " +"server receives the model parameter updates from the clients, it hands " +"those updates over to the strategy (*FedAvg*) for aggregation. The " +"strategy aggregates those updates and returns the new global model, which" +" then gets used in the next round of federated learning." +msgstr "" +"Flower demande ensuite aux 10 clients sélectionnés d'entraîner le modèle." +" Lorsque le serveur reçoit les mises à jour des paramètres du modèle de " +"la part des clients, il les transmet à la stratégie (*FedAvg*) pour " +"qu'elle les agrège. La stratégie agrège ces mises à jour et renvoie le " +"nouveau modèle global, qui est ensuite utilisé dans le prochain cycle " +"d'apprentissage fédéré." -#~ msgid "" -#~ "The evaluation instructions containing " -#~ "(global) model parameters received from " -#~ "the server and a dictionary of " -#~ "configuration values used to customize " -#~ "the local evaluation process." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 +msgid "Where's the accuracy?" +msgstr "Où est la précision ?" -#~ msgid "Returns" -#~ msgstr "Ressources" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 +msgid "" +"You may have noticed that all metrics except for ``losses_distributed`` " +"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +msgstr "" +"Tu as peut-être remarqué que toutes les mesures, à l'exception de " +"``pertes_distribuées``, sont vides. Où est passée la ``{\"précision\" : " +"float(précision)}`` ?" -#~ msgid "" -#~ "The evaluation result containing the " -#~ "loss on the local dataset and " -#~ "other details such as the number " -#~ "of local data examples used for " -#~ "evaluation." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 +msgid "" +"Flower can automatically aggregate losses returned by individual clients," +" but it cannot do the same for metrics in the generic metrics dictionary " +"(the one with the ``accuracy`` key). Metrics dictionaries can contain " +"very different kinds of metrics and even key/value pairs that are not " +"metrics at all, so the framework does not (and can not) know how to " +"handle these automatically." +msgstr "" +"Flower peut automatiquement agréger les pertes renvoyées par les clients " +"individuels, mais il ne peut pas faire la même chose pour les mesures " +"dans le dictionnaire de mesures générique (celui avec la clé " +"``accuracy``). Les dictionnaires de mesures peuvent contenir des types de" +" mesures très différents et même des paires clé/valeur qui ne sont pas " +"des mesures du tout, donc le cadre ne sait pas (et ne peut pas) savoir " +"comment les gérer automatiquement." -#~ msgid "Return type" -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 +msgid "" +"As users, we need to tell the framework how to handle/aggregate these " +"custom metrics, and we do so by passing metric aggregation functions to " +"the strategy. The strategy will then call these functions whenever it " +"receives fit or evaluate metrics from clients. The two possible functions" +" are ``fit_metrics_aggregation_fn`` and " +"``evaluate_metrics_aggregation_fn``." +msgstr "" +"En tant qu'utilisateurs, nous devons indiquer au framework comment " +"gérer/agréger ces métriques personnalisées, et nous le faisons en passant" +" des fonctions d'agrégation de métriques à la stratégie. La stratégie " +"appellera alors ces fonctions chaque fois qu'elle recevra des métriques " +"d'ajustement ou d'évaluation de la part des clients. Les deux fonctions " +"possibles sont ``fit_metrics_aggregation_fn`` et " +"``evaluate_metrics_aggregation_fn``." -#~ msgid "Refine the provided parameters using the locally held dataset." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 +msgid "" +"Let's create a simple weighted averaging function to aggregate the " +"``accuracy`` metric we return from ``evaluate``:" +msgstr "" +"Créons une simple fonction de calcul de la moyenne pondérée pour agréger " +"la mesure de \"précision\" que nous renvoie ``evaluate`` :" -#~ msgid "" -#~ "The training instructions containing (global)" -#~ " model parameters received from the " -#~ "server and a dictionary of configuration" -#~ " values used to customize the local" -#~ " training process." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 +msgid "" +"The only thing left to do is to tell the strategy to call this function " +"whenever it receives evaluation metric dictionaries from the clients:" +msgstr "" +"La seule chose qui reste à faire est d'indiquer à la stratégie d'appeler " +"cette fonction chaque fois qu'elle reçoit des dictionnaires de métriques " +"d'évaluation de la part des clients :" -#~ msgid "" -#~ "The training result containing updated " -#~ "parameters and other details such as " -#~ "the number of local training examples" -#~ " used for training." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 +msgid "" +"We now have a full system that performs federated training and federated " +"evaluation. It uses the ``weighted_average`` function to aggregate custom" +" evaluation metrics and calculates a single ``accuracy`` metric across " +"all clients on the server side." +msgstr "" +"Nous avons maintenant un système complet qui effectue la formation " +"fédérée et l'évaluation fédérée. Il utilise la fonction ``moyenne " +"pondérée`` pour agréger les mesures d'évaluation personnalisées et " +"calcule une seule mesure de ``précision`` pour tous les clients du côté " +"du serveur." -#~ msgid "Return the current local model parameters." -#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 +msgid "" +"The other two categories of metrics (``losses_centralized`` and " +"``metrics_centralized``) are still empty because they only apply when " +"centralized evaluation is being used. Part two of the Flower tutorial " +"will cover centralized evaluation." +msgstr "" +"Les deux autres catégories de mesures (``pertes_centralisées`` et " +"``métriques_centralisées``) sont toujours vides car elles ne s'appliquent" +" que lorsque l'évaluation centralisée est utilisée. La deuxième partie du" +" tutoriel sur les fleurs couvrira l'évaluation centralisée." -#~ msgid "" -#~ "The get parameters instructions received " -#~ "from the server containing a dictionary" -#~ " of configuration values." -#~ msgstr "" - -#~ msgid "The current local model parameters." -#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" - -#~ msgid "Return set of client's properties." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 +msgid "Final remarks" +msgstr "Remarques finales" -#~ msgid "" -#~ "The get properties instructions received " -#~ "from the server containing a dictionary" -#~ " of configuration values." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 +msgid "" +"Congratulations, you just trained a convolutional neural network, " +"federated over 10 clients! With that, you understand the basics of " +"federated learning with Flower. The same approach you've seen can be used" +" with other machine learning frameworks (not just PyTorch) and tasks (not" +" just CIFAR-10 images classification), for example NLP with Hugging Face " +"Transformers or speech with SpeechBrain." +msgstr "" +"Félicitations, tu viens d'entraîner un réseau neuronal convolutif, fédéré" +" sur 10 clients ! Avec ça, tu comprends les bases de l'apprentissage " +"fédéré avec Flower. La même approche que tu as vue peut être utilisée " +"avec d'autres cadres d'apprentissage automatique (pas seulement PyTorch) " +"et d'autres tâches (pas seulement la classification des images CIFAR-10)," +" par exemple le NLP avec Hugging Face Transformers ou la parole avec " +"SpeechBrain." -#~ msgid "The current client properties." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 +msgid "" +"In the next notebook, we're going to cover some more advanced concepts. " +"Want to customize your strategy? Initialize parameters on the server " +"side? Or evaluate the aggregated model on the server side? We'll cover " +"all this and more in the next tutorial." +msgstr "" +"Dans le prochain cahier, nous allons aborder des concepts plus avancés. " +"Tu veux personnaliser ta stratégie ? Initialiser des paramètres côté " +"serveur ? Ou évaluer le modèle agrégé côté serveur ? Nous aborderons tout" +" cela et bien plus encore dans le prochain tutoriel." -#~ msgid "Start a Flower client node which connects to a Flower server." -#~ msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 +#, fuzzy +msgid "" +"The `Flower Federated Learning Tutorial - Part 2 " +"`__ goes into more depth about strategies and all " +"the advanced things you can build with them." +msgstr "" +"Le `Tutoriel d'apprentissage fédéré Flower - Partie 2 " +"`__ va plus en profondeur sur les stratégies et toutes les " +"choses avancées que tu peux construire avec elles." -#~ msgid "" -#~ "The IPv4 or IPv6 address of the" -#~ " server. If the Flower server runs" -#~ " on the same machine on port " -#~ "8080, then `server_address` would be " -#~ "`\"[::]:8080\"`." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 +#, fuzzy +msgid "Use a federated learning strategy" +msgstr "Stratégie de moyenne fédérée." -#~ msgid "An implementation of the abstract base class `flwr.client.Client`." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 +#, fuzzy +msgid "" +"Welcome to the next part of the federated learning tutorial. In previous " +"parts of this tutorial, we introduced federated learning with PyTorch and" +" Flower (`part 1 `__)." +msgstr "" +"Bienvenue dans la prochaine partie du tutoriel sur l'apprentissage " +"fédéré. Dans les parties précédentes de ce tutoriel, nous avons présenté " +"l'apprentissage fédéré avec PyTorch et Flower (`partie 1 " +"`__)." -#~ msgid "" -#~ "The maximum length of gRPC messages " -#~ "that can be exchanged with the " -#~ "Flower server. The default should be " -#~ "sufficient for most models. Users who" -#~ " train very large models might need" -#~ " to increase this value. Note that" -#~ " the Flower server needs to be " -#~ "started with the same value (see " -#~ "`flwr.server.start_server`), otherwise it will " -#~ "not know about the increased limit " -#~ "and block larger messages." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 +msgid "" +"In this notebook, we'll begin to customize the federated learning system " +"we built in the introductory notebook (again, using `Flower " +"`__ and `PyTorch `__)." +msgstr "" +"Dans ce carnet, nous allons commencer à personnaliser le système " +"d'apprentissage fédéré que nous avons construit dans le carnet " +"d'introduction (toujours en utilisant `Flower `__ et " +"`PyTorch `__)." -#~ msgid "" -#~ "The PEM-encoded root certificates as " -#~ "a byte string or a path string." -#~ " If provided, a secure connection " -#~ "using the certificates will be " -#~ "established to an SSL-enabled Flower " -#~ "server." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 +#, fuzzy +msgid "Let's move beyond FedAvg with Flower strategies!" +msgstr "Dépassons FedAvg avec les stratégies florales !" -#~ msgid "" -#~ "DEPRECATED - USE 'transport' INSTEAD. " -#~ "Defines whether or not the client " -#~ "is interacting with the server using " -#~ "the experimental REST API. This feature" -#~ " is experimental, it might change " -#~ "considerably in future versions of " -#~ "Flower." -#~ msgstr "" -#~ "DÉPRÉCIÉ - UTILISER 'transport' À LA " -#~ "PLACE Définit si le client interagit " -#~ "ou non avec le serveur à l'aide" -#~ " de l'API REST expérimentale. Cette " -#~ "fonctionnalité est expérimentale, elle " -#~ "pourrait changer considérablement dans les " -#~ "futures versions de Flower." +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 +msgid "Strategy customization" +msgstr "Personnalisation de la stratégie" -#~ msgid "" -#~ "Configure the transport layer. Allowed " -#~ "values: - 'grpc-bidi': gRPC, " -#~ "bidirectional streaming - 'grpc-rere': " -#~ "gRPC, request-response (experimental) - " -#~ "'rest': HTTP (experimental)" -#~ msgstr "" -#~ "Valeurs autorisées : - 'grpc-bidi' " -#~ ": gRPC, flux bidirectionnel - 'grpc-" -#~ "rere' : gRPC, requête-réponse " -#~ "(expérimental) - 'rest' : HTTP " -#~ "(expérimental)" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 +msgid "" +"So far, everything should look familiar if you've worked through the " +"introductory notebook. With that, we're ready to introduce a number of " +"new features." +msgstr "" +"Jusqu'à présent, tout devrait te sembler familier si tu as travaillé sur " +"le cahier d'introduction. Avec cela, nous sommes prêts à présenter un " +"certain nombre de nouvelles fonctionnalités." -#~ msgid "Starting a gRPC client with an insecure server connection:" -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 +msgid "Server-side parameter **initialization**" +msgstr "Paramètres côté serveur **initialisation**" -#~ msgid "Starting an SSL-enabled gRPC client:" -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 +msgid "" +"Flower, by default, initializes the global model by asking one random " +"client for the initial parameters. In many cases, we want more control " +"over parameter initialization though. Flower therefore allows you to " +"directly pass the initial parameters to the Strategy:" +msgstr "" +"Flower, par défaut, initialise le modèle global en demandant à un client " +"aléatoire les paramètres initiaux. Dans de nombreux cas, nous voulons " +"cependant avoir plus de contrôle sur l'initialisation des paramètres. " +"Flower te permet donc de passer directement les paramètres initiaux à la " +"Stratégie :" -#~ msgid "Abstract base class for Flower clients using NumPy." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 +msgid "" +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" +" from asking one of the clients for the initial parameters. If we look " +"closely, we can see that the logs do not show any calls to the " +"``FlowerClient.get_parameters`` method." +msgstr "" +"Le fait de passer ``initial_parameters`` à la stratégie ``FedAvg`` " +"empêche Flower de demander les paramètres initiaux à l'un des clients. Si" +" nous regardons de près, nous pouvons voir que les journaux ne montrent " +"aucun appel à la méthode ``FlowerClient.get_parameters``." -#~ msgid "The current (global) model parameters." -#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 +msgid "Starting with a customized strategy" +msgstr "Commencer par une stratégie personnalisée" -#~ msgid "" -#~ "Configuration parameters which allow the " -#~ "server to influence evaluation on the" -#~ " client. It can be used to " -#~ "communicate arbitrary values from the " -#~ "server to the client, for example, " -#~ "to influence the number of examples " -#~ "used for evaluation." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 +msgid "" +"We've seen the function ``start_simulation`` before. It accepts a number " +"of arguments, amongst them the ``client_fn`` used to create " +"``FlowerClient`` instances, the number of clients to simulate " +"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +msgstr "" +"Elle accepte un certain nombre d'arguments, parmi lesquels le " +"``client_fn`` utilisé pour créer les instances de ``FlowerClient``, le " +"nombre de clients à simuler ``num_clients``, le nombre de rounds " +"``num_rounds``, et la stratégie." -#~ msgid "" -#~ "* **loss** (*float*) -- The evaluation" -#~ " loss of the model on the local" -#~ " dataset. * **num_examples** (*int*) -- " -#~ "The number of examples used for " -#~ "evaluation. * **metrics** (*Dict[str, " -#~ "Scalar]*) -- A dictionary mapping " -#~ "arbitrary string keys to values of " -#~ "type bool, bytes, float, int, or " -#~ "str. It can be used to " -#~ "communicate arbitrary values back to the" -#~ " server." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 +msgid "" +"The strategy encapsulates the federated learning approach/algorithm, for " +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " +"strategy this time:" +msgstr "" +"La stratégie englobe l'approche/l'algorithme d'apprentissage fédéré, par " +"exemple, ``FedAvg`` ou ``FedAdagrad``. Essayons d'utiliser une stratégie " +"différente cette fois-ci :" -#~ msgid "" -#~ "**loss** (*float*) -- The evaluation " -#~ "loss of the model on the local " -#~ "dataset." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 +msgid "Server-side parameter **evaluation**" +msgstr "Paramètre côté serveur **évaluation**" -#~ msgid "**num_examples** (*int*) -- The number of examples used for evaluation." -#~ msgstr "" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 +msgid "" +"Flower can evaluate the aggregated model on the server-side or on the " +"client-side. Client-side and server-side evaluation are similar in some " +"ways, but different in others." +msgstr "" +"Flower peut évaluer le modèle agrégé côté serveur ou côté client. Les " +"évaluations côté client et côté serveur sont similaires à certains " +"égards, mais différentes à d'autres." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 +msgid "" +"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " +"simple: it works the same way that evaluation in centralized machine " +"learning does. If there is a server-side dataset that can be used for " +"evaluation purposes, then that's great. We can evaluate the newly " +"aggregated model after each round of training without having to send the " +"model to clients. We're also fortunate in the sense that our entire " +"evaluation dataset is available at all times." +msgstr "" +"**L'évaluation centralisée** (ou *évaluation côté serveur*) est " +"conceptuellement simple : elle fonctionne de la même manière que " +"l'évaluation dans l'apprentissage automatique centralisé. S'il existe un " +"ensemble de données côté serveur qui peut être utilisé à des fins " +"d'évaluation, alors c'est parfait. Nous pouvons évaluer le modèle " +"nouvellement agrégé après chaque cycle de formation sans avoir à envoyer " +"le modèle aux clients. Nous avons également la chance que l'ensemble de " +"notre ensemble de données d'évaluation soit disponible à tout moment." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 +msgid "" +"**Federated Evaluation** (or *client-side evaluation*) is more complex, " +"but also more powerful: it doesn't require a centralized dataset and " +"allows us to evaluate models over a larger set of data, which often " +"yields more realistic evaluation results. In fact, many scenarios require" +" us to use **Federated Evaluation** if we want to get representative " +"evaluation results at all. But this power comes at a cost: once we start " +"to evaluate on the client side, we should be aware that our evaluation " +"dataset can change over consecutive rounds of learning if those clients " +"are not always available. Moreover, the dataset held by each client can " +"also change over consecutive rounds. This can lead to evaluation results " +"that are not stable, so even if we would not change the model, we'd see " +"our evaluation results fluctuate over consecutive rounds." +msgstr "" +"**L'évaluation fédérée** (ou évaluation côté client) est plus complexe, " +"mais aussi plus puissante : elle ne nécessite pas d'ensemble de données " +"centralisé et nous permet d'évaluer les modèles sur un plus grand " +"ensemble de données, ce qui donne souvent des résultats d'évaluation plus" +" réalistes. En fait, de nombreux scénarios exigent que nous utilisions " +"l'évaluation fédérée** si nous voulons obtenir des résultats d'évaluation" +" représentatifs. Mais cette puissance a un coût : une fois que nous " +"commençons à évaluer côté client, nous devons savoir que notre ensemble " +"de données d'évaluation peut changer au cours des cycles d'apprentissage " +"consécutifs si ces clients ne sont pas toujours disponibles. De plus, " +"l'ensemble de données détenu par chaque client peut également changer au " +"cours des cycles consécutifs. Cela peut conduire à des résultats " +"d'évaluation qui ne sont pas stables, donc même si nous ne changions pas " +"le modèle, nous verrions nos résultats d'évaluation fluctuer au cours des" +" cycles consécutifs." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +msgid "" +"We've seen how federated evaluation works on the client side (i.e., by " +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " +"how we can evaluate aggregated model parameters on the server-side:" +msgstr "" +"Nous avons vu comment l'évaluation fédérée fonctionne du côté client " +"(c'est-à-dire en implémentant la méthode ``evaluate`` dans " +"``FlowerClient``). Voyons maintenant comment nous pouvons évaluer les " +"paramètres du modèle agrégé du côté serveur :" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 +msgid "Sending/receiving arbitrary values to/from clients" +msgstr "Envoi/réception de valeurs arbitraires vers/depuis les clients" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 +#, fuzzy +msgid "" +"In some situations, we want to configure client-side execution (training," +" evaluation) from the server-side. One example for that is the server " +"asking the clients to train for a certain number of local epochs. Flower " +"provides a way to send configuration values from the server to the " +"clients using a dictionary. Let's look at an example where the clients " +"receive values from the server through the ``config`` parameter in " +"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " +"method receives the configuration dictionary through the ``config`` " +"parameter and can then read values from this dictionary. In this example," +" it reads ``server_round`` and ``local_epochs`` and uses those values to " +"improve the logging and configure the number of local training epochs:" +msgstr "" +"In some situations, we want to configure client-side execution (training," +" evaluation) from the server-side. One example for that is the server " +"asking the clients to train for a certain number of local epochs. Flower " +"provides a way to send configuration values from the server to the " +"clients using a dictionary. Let's look at an example where the clients " +"receive values from the server through the ``config`` parameter in " +"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " +"method receives the configuration dictionary through the ``config`` " +"parameter and can then read values from this dictionary. In this example," +" it reads ``server_round`` and ``local_epochs`` and uses those values to " +"improve the logging and configure the number of local training epochs:" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 +msgid "" +"So how can we send this config dictionary from server to clients? The " +"built-in Flower Strategies provide way to do this, and it works similarly" +" to the way server-side evaluation works. We provide a function to the " +"strategy, and the strategy calls this function for every round of " +"federated learning:" +msgstr "" +"Comment pouvons-nous donc envoyer ce dictionnaire de configuration du " +"serveur aux clients ? Les stratégies de Flower intégrées fournissent un " +"moyen de le faire, et cela fonctionne de la même façon que l'évaluation " +"côté serveur. Nous fournissons une fonction à la stratégie, et la " +"stratégie appelle cette fonction pour chaque cycle d'apprentissage fédéré" +" :" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 +msgid "" +"Next, we'll just pass this function to the FedAvg strategy before " +"starting the simulation:" +msgstr "" +"Ensuite, nous allons simplement passer cette fonction à la stratégie " +"FedAvg avant de commencer la simulation :" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 +msgid "" +"As we can see, the client logs now include the current round of federated" +" learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second" +" round of federated learning, and then for two epochs during the third " +"round." +msgstr "" +"Comme nous pouvons le voir, les journaux des clients incluent maintenant " +"le cycle actuel d'apprentissage fédéré (qu'ils lisent depuis le " +"dictionnaire ``config``). Nous pouvons également configurer " +"l'apprentissage local pour qu'il s'exécute pendant une époque au cours du" +" premier et du deuxième cycle d'apprentissage fédéré, puis pendant deux " +"époques au cours du troisième cycle." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 +msgid "" +"Clients can also return arbitrary values to the server. To do so, they " +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " +"used this concept throughout this notebook without mentioning it " +"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" +" key/value pair as the third return value in ``evaluate``." +msgstr "" +"Les clients peuvent également renvoyer des valeurs arbitraires au " +"serveur. Pour ce faire, ils renvoient un dictionnaire depuis ``fit`` " +"et/ou ``evaluate``. Nous avons vu et utilisé ce concept tout au long de " +"ce carnet sans le mentionner explicitement : notre ``FlowerClient`` " +"renvoie un dictionnaire contenant une paire clé/valeur personnalisée en " +"tant que troisième valeur de retour dans ``evaluate``." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 +msgid "Scaling federated learning" +msgstr "Mise à l'échelle de l'apprentissage fédéré" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 +msgid "" +"As a last step in this notebook, let's see how we can use Flower to " +"experiment with a large number of clients." +msgstr "" +"Comme dernière étape de ce carnet, voyons comment nous pouvons utiliser " +"Flower pour expérimenter avec un grand nombre de clients." + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 +#, python-format +msgid "" +"We now have 1000 partitions, each holding 45 training and 5 validation " +"examples. Given that the number of training examples on each client is " +"quite small, we should probably train the model a bit longer, so we " +"configure the clients to perform 3 local training epochs. We should also " +"adjust the fraction of clients selected for training during each round " +"(we don't want all 1000 clients participating in every round), so we " +"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " +"available clients (so 50 clients) will be selected for training each " +"round:" +msgstr "" +"Nous avons maintenant 1000 partitions, chacune contenant 45 exemples " +"d'entraînement et 5 exemples de validation. Etant donné que le nombre " +"d'exemples d'entraînement sur chaque client est assez faible, nous " +"devrions probablement entraîner le modèle un peu plus longtemps, nous " +"configurons donc les clients pour qu'ils effectuent 3 époques " +"d'entraînement local. Nous devrions également ajuster la fraction de " +"clients sélectionnés pour l'entraînement à chaque tour (nous ne voulons " +"pas que les 1000 clients participent à chaque tour), nous ajustons donc " +"``fraction_fit`` à ``0.05``, ce qui signifie que seulement 5% des clients" +" disponibles (donc 50 clients) seront sélectionnés pour l'entraînement à " +"chaque tour :" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 +msgid "" +"In this notebook, we've seen how we can gradually enhance our system by " +"customizing the strategy, initializing parameters on the server side, " +"choosing a different strategy, and evaluating models on the server-side. " +"That's quite a bit of flexibility with so little code, right?" +msgstr "" +"Dans ce carnet, nous avons vu comment nous pouvons progressivement " +"améliorer notre système en personnalisant la stratégie, en initialisant " +"les paramètres côté serveur, en choisissant une stratégie différente et " +"en évaluant les modèles côté serveur. C'est une sacrée flexibilité avec " +"si peu de code, n'est-ce pas ?" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 +msgid "" +"In the later sections, we've seen how we can communicate arbitrary values" +" between server and clients to fully customize client-side execution. " +"With that capability, we built a large-scale Federated Learning " +"simulation using the Flower Virtual Client Engine and ran an experiment " +"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +msgstr "" +"Dans les sections ultérieures, nous avons vu comment nous pouvons " +"communiquer des valeurs arbitraires entre le serveur et les clients pour " +"personnaliser entièrement l'exécution côté client. Grâce à cette " +"capacité, nous avons construit une simulation d'apprentissage fédéré à " +"grande échelle en utilisant le moteur de client virtuel Flower et nous " +"avons mené une expérience impliquant 1000 clients dans la même charge de " +"travail - le tout dans un carnet Jupyter !" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 +#, fuzzy +msgid "" +"The `Flower Federated Learning Tutorial - Part 3 " +"`__ shows how to build a fully custom ``Strategy`` from " +"scratch." +msgstr "" +"Le `Tutoriel d'apprentissage fédéré Flower - Partie 3 [WIP] " +"`__ montre comment construire une ``Stratégie`` entièrement " +"personnalisée à partir de zéro." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 +msgid "What is Federated Learning?" +msgstr "Qu'est-ce que l'apprentissage fédéré ?" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 +#, fuzzy +msgid "" +"In this tutorial, you will learn what federated learning is, build your " +"first system in Flower, and gradually extend it. If you work through all " +"parts of the tutorial, you will be able to build advanced federated " +"learning systems that approach the current state of the art in the field." +msgstr "" +"Dans ce tutoriel, tu apprendras ce qu'est l'apprentissage fédéré, tu " +"construiras ton premier système dans Flower, et tu l'étendras " +"progressivement. Si tu travailles sur toutes les parties du tutoriel, tu " +"seras capable de construire des systèmes d'apprentissage fédéré avancés " +"qui se rapprochent de l'état actuel de l'art dans le domaine." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 +msgid "" +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " +"federated learning. Only a basic understanding of data science and Python" +" programming is assumed." +msgstr "" +"🧑‍🏫 Ce tutoriel part de zéro et n'attend aucune familiarité avec " +"l'apprentissage fédéré. Seule une compréhension de base de la science des" +" données et de la programmation Python est supposée." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 +#, fuzzy +msgid "" +"`Star Flower on GitHub `__ ⭐️ and join " +"the open-source Flower community on Slack to connect, ask questions, and " +"get help: `Join Slack `__ 🌼 We'd love to " +"hear from you in the ``#introductions`` channel! And if anything is " +"unclear, head over to the ``#questions`` channel." +msgstr "" +"`Star Flower on GitHub `__ ⭐️ et " +"rejoignez la communauté Flower sur Slack pour vous connecter, poser des " +"questions et obtenir de l'aide : `Join Slack `__ 🌼 Nous serions ravis d'avoir de vos nouvelles dans le canal " +"``#introductions`` ! Et si quelque chose n'est pas clair, rendez-vous sur" +" le canal ``#questions``." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 +msgid "Classic machine learning" +msgstr "Apprentissage automatique classique" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 +msgid "" +"Before we begin to discuss federated learning, let us quickly recap how " +"most machine learning works today." +msgstr "" +"Avant de commencer à discuter de l'apprentissage fédéré, récapitulons " +"rapidement la façon dont la plupart des apprentissages automatiques " +"fonctionnent aujourd'hui." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 +msgid "" +"In machine learning, we have a model, and we have data. The model could " +"be a neural network (as depicted here), or something else, like classical" +" linear regression." +msgstr "" +"Dans l'apprentissage automatique, nous avons un modèle et des données. Le" +" modèle peut être un réseau neuronal (comme illustré ici), ou quelque " +"chose d'autre, comme la régression linéaire classique." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 +msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 +msgid "Model and data" +msgstr "Modèle et données" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 +msgid "" +"We train the model using the data to perform a useful task. A task could " +"be to detect objects in images, transcribe an audio recording, or play a " +"game like Go." +msgstr "" +"Nous entraînons le modèle en utilisant les données pour effectuer une " +"tâche utile. Une tâche peut consister à détecter des objets dans des " +"images, à transcrire un enregistrement audio ou à jouer à un jeu comme le" +" Go." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 +msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 +msgid "Train model using data" +msgstr "Entraîne le modèle à l'aide des données" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 +#, fuzzy +msgid "" +"Now, in practice, the training data we work with doesn't originate on the" +" machine we train the model on. It gets created somewhere else." +msgstr "" +"Dans la pratique, les données d'entraînement avec lesquelles nous " +"travaillons ne proviennent pas de la machine sur laquelle nous entraînons" +" le modèle. Elles sont créées ailleurs." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 +#, fuzzy +msgid "" +"It originates on a smartphone by the user interacting with an app, a car " +"collecting sensor data, a laptop receiving input via the keyboard, or a " +"smart speaker listening to someone trying to sing a song." +msgstr "" +"Elle prend naissance sur un smartphone par l'interaction de l'utilisateur" +" avec une application, une voiture qui collecte des données de capteurs, " +"un ordinateur portable qui reçoit des entrées via le clavier, ou un haut-" +"parleur intelligent qui écoute quelqu'un qui essaie de chanter une " +"chanson." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 +msgid "|2bc8e069228d4873804061ff4a95048c|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 +msgid "Data on a phone" +msgstr "Données sur un téléphone" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 +msgid "" +"What's also important to mention, this \"somewhere else\" is usually not " +"just one place, it's many places. It could be several devices all running" +" the same app. But it could also be several organizations, all generating" +" data for the same task." +msgstr "" +"Il est également important de mentionner que cet \"ailleurs\" n'est " +"généralement pas un seul endroit, mais plusieurs. Il peut s'agir de " +"plusieurs appareils fonctionnant tous avec la même application. Mais il " +"peut également s'agir de plusieurs organisations, qui génèrent toutes des" +" données pour la même tâche." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 +msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 +msgid "Data is on many devices" +msgstr "Les données se trouvent sur de nombreux appareils" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 +msgid "" +"So to use machine learning, or any kind of data analysis, the approach " +"that has been used in the past was to collect all data on a central " +"server. This server can be somewhere in a data center, or somewhere in " +"the cloud." +msgstr "" +"Ainsi, pour utiliser l'apprentissage automatique, ou tout autre type " +"d'analyse de données, l'approche utilisée par le passé consistait à " +"collecter toutes les données sur un serveur central. Ce serveur peut se " +"trouver quelque part dans un centre de données, ou quelque part dans le " +"cloud." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 +msgid "|d5f962c3f4ec48529efda980868c14b0|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 +msgid "Central data collection" +msgstr "Collecte centralisée des données" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 +#, fuzzy +msgid "" +"Once all the data is collected in one place, we can finally use machine " +"learning algorithms to train our model on the data. This is the machine " +"learning approach that we've basically always relied on." +msgstr "" +"Une fois que toutes les données sont rassemblées en un seul endroit, nous" +" pouvons enfin utiliser des algorithmes d'apprentissage automatique pour " +"entraîner notre modèle sur les données. C'est l'approche d'apprentissage " +"automatique sur laquelle nous nous sommes fondamentalement toujours " +"appuyés." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 +msgid "|a5eccea18d4c43a68b54b65043cabef8|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 +msgid "Central model training" +msgstr "Formation au modèle central" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 +msgid "Challenges of classical machine learning" +msgstr "Les défis de l'apprentissage automatique classique" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 +msgid "" +"The classic machine learning approach we've just seen can be used in some" +" cases. Great examples include categorizing holiday photos, or analyzing " +"web traffic. Cases, where all the data is naturally available on a " +"centralized server." +msgstr "" +"L'approche classique de l'apprentissage automatique que nous venons de " +"voir peut être utilisée dans certains cas. Parmi les grands exemples, on " +"peut citer la catégorisation des photos de vacances, ou l'analyse du " +"trafic web. Des cas, où toutes les données sont naturellement disponibles" +" sur un serveur centralisé." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 +msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 +msgid "Centralized possible" +msgstr "Possibilité de centralisation" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 +msgid "" +"But the approach can not be used in many other cases. Cases, where the " +"data is not available on a centralized server, or cases where the data " +"available on one server is not enough to train a good model." +msgstr "" +"Mais cette approche ne peut pas être utilisée dans de nombreux autres cas" +" : lorsque les données ne sont pas disponibles sur un serveur centralisé," +" ou lorsque les données disponibles sur un serveur ne sont pas " +"suffisantes pour former un bon modèle." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 +msgid "|241fc906441a4f038c625a19d30d01b2|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 +msgid "Centralized impossible" +msgstr "Impossible de centraliser" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 +#, fuzzy +msgid "" +"There are many reasons why the classic centralized machine learning " +"approach does not work for a large number of highly important real-world " +"use cases. Those reasons include:" +msgstr "" +"Il existe de nombreuses raisons pour lesquelles l'approche classique " +"centralisée de l'apprentissage automatique ne fonctionne pas pour un " +"grand nombre de cas d'utilisation très importants dans le monde réel, " +"notamment :" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 +#, fuzzy +msgid "" +"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " +"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " +"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " +"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " +"protect sensitive data from being moved. In fact, those regulations " +"sometimes even prevent single organizations from combining their own " +"users' data for artificial intelligence training because those users live" +" in different parts of the world, and their data is governed by different" +" data protection regulations." +msgstr "" +"**Réglementations** : GDPR (Europe), CCPA (Californie), PIPEDA (Canada), " +"LGPD (Brésil), PDPL (Argentine), KVKK (Turquie), POPI (Afrique du Sud), " +"FSS (Russie), CDPR (Chine), PDPB (Inde), PIPA (Corée), APPI (Japon), PDP " +"(Indonésie), PDPA (Singapour), APP (Australie), et d'autres " +"réglementations protègent les données sensibles contre le déplacement. En" +" fait, ces réglementations empêchent même parfois des organisations " +"individuelles de combiner les données de leurs propres utilisateurs pour " +"la formation à l'intelligence artificielle parce que ces utilisateurs " +"vivent dans différentes parties du monde, et que leurs données sont " +"régies par des réglementations différentes en matière de protection des " +"données." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 +msgid "" +"**User preference**: In addition to regulation, there are use cases where" +" users just expect that no data leaves their device, ever. If you type " +"your passwords and credit card info into the digital keyboard of your " +"phone, you don't expect those passwords to end up on the server of the " +"company that developed that keyboard, do you? In fact, that use case was " +"the reason federated learning was invented in the first place." +msgstr "" +"**Préférence de l'utilisateur** : En plus de la réglementation, il existe" +" des cas d'utilisation où les utilisateurs s'attendent tout simplement à " +"ce qu'aucune donnée ne quitte leur appareil, jamais. Si tu tapes tes mots" +" de passe et tes informations de carte de crédit sur le clavier numérique" +" de ton téléphone, tu ne t'attends pas à ce que ces mots de passe " +"finissent sur le serveur de l'entreprise qui a développé ce clavier, n" +"'est-ce pas ? En fait, ce cas d'utilisation est la raison pour laquelle " +"l'apprentissage fédéré a été inventé en premier lieu." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 +#, fuzzy +msgid "" +"**Data volume**: Some sensors, like cameras, produce such a high data " +"volume that it is neither feasible nor economic to collect all the data " +"(due to, for example, bandwidth or communication efficiency). Think about" +" a national rail service with hundreds of train stations across the " +"country. If each of these train stations is outfitted with a number of " +"security cameras, the volume of raw on-device data they produce requires " +"incredibly powerful and exceedingly expensive infrastructure to process " +"and store. And most of the data isn't even useful." +msgstr "" +"**volume de données** : certains capteurs, comme les caméras, produisent " +"un volume de données si important qu'il n'est ni possible ni économique " +"de collecter toutes les données (en raison, par exemple, de la bande " +"passante ou de l'efficacité des communications). Pensez à un service " +"ferroviaire national comptant des centaines de gares à travers le pays. " +"Si chacune de ces gares est équipée d'un certain nombre de caméras de " +"sécurité, le volume de données brutes sur les appareils qu'elles " +"produisent nécessite une infrastructure incroyablement puissante et " +"excessivement coûteuse pour les traiter et les stocker. Et la plupart de " +"ces données ne sont même pas utiles." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 +msgid "Examples where centralized machine learning does not work include:" +msgstr "" +"Voici quelques exemples où l'apprentissage automatique centralisé ne " +"fonctionne pas :" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 +#, fuzzy +msgid "" +"Sensitive healthcare records from multiple hospitals to train cancer " +"detection models" +msgstr "" +"Des dossiers médicaux sensibles provenant de plusieurs hôpitaux pour " +"former des modèles de détection du cancer" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 +msgid "" +"Financial information from different organizations to detect financial " +"fraud" +msgstr "" +"Informations financières provenant de différentes organisations pour " +"détecter les fraudes financières" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 +msgid "Location data from your electric car to make better range prediction" +msgstr "" +"Les données de localisation de ta voiture électrique pour mieux prédire " +"l'autonomie" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 +msgid "End-to-end encrypted messages to train better auto-complete models" +msgstr "" +"Messages cryptés de bout en bout pour former de meilleurs modèles " +"d'autocomplétion" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 +#, fuzzy +msgid "" +"The popularity of privacy-enhancing systems like the `Brave " +"`__ browser or the `Signal `__ " +"messenger shows that users care about privacy. In fact, they choose the " +"privacy-enhancing version over other alternatives, if such an alternative" +" exists. But what can we do to apply machine learning and data science to" +" these cases to utilize private data? After all, these are all areas that" +" would benefit significantly from recent advances in AI." +msgstr "" +"La popularité des systèmes améliorant la confidentialité comme le " +"navigateur `Brave `__ ou le messager `Signal " +"`__ montre que les utilisateurs se soucient de la " +"confidentialité. En fait, ils choisissent la version améliorant la " +"confidentialité plutôt que d'autres alternatives, si une telle " +"alternative existe. Mais que pouvons-nous faire pour appliquer " +"l'apprentissage automatique et la science des données à ces cas afin " +"d'utiliser les données privées ? Après tout, ce sont tous des domaines " +"qui bénéficieraient de manière significative des récentes avancées en " +"matière d'IA." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 +msgid "Federated learning" +msgstr "Apprentissage fédéré" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 +msgid "" +"Federated learning simply reverses this approach. It enables machine " +"learning on distributed data by moving the training to the data, instead " +"of moving the data to the training. Here's the single-sentence " +"explanation:" +msgstr "" +"L'apprentissage fédéré inverse simplement cette approche. Il permet " +"l'apprentissage automatique sur des données distribuées en déplaçant la " +"formation vers les données, au lieu de déplacer les données vers la " +"formation. Voici l'explication en une seule phrase :" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 +msgid "Central machine learning: move the data to the computation" +msgstr "Apprentissage automatique central : déplace les données vers le calcul" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 +msgid "Federated (machine) learning: move the computation to the data" +msgstr "Apprentissage (machine) fédéré : déplacer le calcul vers les données" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 +msgid "" +"By doing so, it enables us to use machine learning (and other data " +"science approaches) in areas where it wasn't possible before. We can now " +"train excellent medical AI models by enabling different hospitals to work" +" together. We can solve financial fraud by training AI models on the data" +" of different financial institutions. We can build novel privacy-" +"enhancing applications (such as secure messaging) that have better built-" +"in AI than their non-privacy-enhancing alternatives. And those are just a" +" few of the examples that come to mind. As we deploy federated learning, " +"we discover more and more areas that can suddenly be reinvented because " +"they now have access to vast amounts of previously inaccessible data." +msgstr "" +"Ce faisant, il nous permet d'utiliser l'apprentissage automatique (et " +"d'autres approches de science des données) dans des domaines où cela " +"n'était pas possible auparavant. Nous pouvons désormais former " +"d'excellents modèles d'IA médicale en permettant à différents hôpitaux de" +" travailler ensemble. Nous pouvons résoudre les fraudes financières en " +"formant des modèles d'IA sur les données de différentes institutions " +"financières. Nous pouvons créer de nouvelles applications d'amélioration " +"de la confidentialité (telles que la messagerie sécurisée) qui ont une " +"meilleure IA intégrée que leurs alternatives d'amélioration de la " +"confidentialité. Et ce ne sont là que quelques exemples qui me viennent à" +" l'esprit. Au fur et à mesure que nous déployons l'apprentissage fédéré, " +"nous découvrons de plus en plus de domaines qui peuvent soudainement être" +" réinventés parce qu'ils ont maintenant accès à de vastes quantités de " +"données auparavant inaccessibles." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 +msgid "" +"So how does federated learning work, exactly? Let's start with an " +"intuitive explanation." +msgstr "" +"Comment fonctionne l'apprentissage fédéré ? Commençons par une " +"explication intuitive." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 +msgid "Federated learning in five steps" +msgstr "L'apprentissage fédéré en cinq étapes" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 +msgid "Step 0: Initialize global model" +msgstr "Étape 0 : Initialisation du modèle global" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 +msgid "" +"We start by initializing the model on the server. This is exactly the " +"same in classic centralized learning: we initialize the model parameters," +" either randomly or from a previously saved checkpoint." +msgstr "" +"Nous commençons par initialiser le modèle sur le serveur. C'est " +"exactement la même chose dans l'apprentissage centralisé classique : nous" +" initialisons les paramètres du modèle, soit de façon aléatoire, soit à " +"partir d'un point de contrôle précédemment sauvegardé." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 +msgid "|0aa5aa05810b44b6a835cecce28f3137|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 +msgid "Initialize global model" +msgstr "Initialise le modèle global" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 +msgid "" +"Step 1: Send model to a number of connected organizations/devices (client" +" nodes)" +msgstr "" +"Étape 1 : envoyer le modèle à un certain nombre d'organisations/appareils" +" connectés (nœuds clients)" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 +#, fuzzy +msgid "" +"Next, we send the parameters of the global model to the connected client " +"nodes (think: edge devices like smartphones or servers belonging to " +"organizations). This is to ensure that each participating node starts " +"their local training using the same model parameters. We often use only a" +" few of the connected nodes instead of all nodes. The reason for this is " +"that selecting more and more client nodes has diminishing returns." +msgstr "" +"Ensuite, nous envoyons les paramètres du modèle global aux nœuds clients " +"connectés (par exemple, les appareils périphériques comme les smartphones" +" ou les serveurs appartenant à des organisations). Cela permet de " +"s'assurer que chaque nœud participant commence sa formation locale en " +"utilisant les mêmes paramètres de modèle. Nous n'utilisons souvent que " +"quelques-uns des nœuds connectés au lieu de tous les nœuds. La raison en " +"est que la sélection d'un nombre croissant de nœuds clients a des " +"rendements décroissants." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 +msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 +msgid "Send global model" +msgstr "Envoyer le modèle global" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 +msgid "" +"Step 2: Train model locally on the data of each organization/device " +"(client node)" +msgstr "" +"Étape 2 : Entraîne le modèle localement sur les données de chaque " +"organisation/appareil (nœud client)" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 +msgid "" +"Now that all (selected) client nodes have the latest version of the " +"global model parameters, they start the local training. They use their " +"own local dataset to train their own local model. They don't train the " +"model until full convergence, but they only train for a little while. " +"This could be as little as one epoch on the local data, or even just a " +"few steps (mini-batches)." +msgstr "" +"Maintenant que tous les nœuds clients (sélectionnés) disposent de la " +"dernière version des paramètres du modèle global, ils commencent " +"l'entraînement local. Ils utilisent leur propre ensemble de données " +"locales pour entraîner leur propre modèle local. Ils n'entraînent pas le " +"modèle jusqu'à la convergence totale, mais ils ne s'entraînent que " +"pendant un petit moment. Il peut s'agir d'une seule époque sur les " +"données locales, ou même de quelques étapes (mini-batchs)." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 +msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 +msgid "Train on local data" +msgstr "Forme-toi aux données locales" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 +msgid "Step 3: Return model updates back to the server" +msgstr "Étape 3 : Renvoyer les mises à jour du modèle au serveur" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 +msgid "" +"After local training, each client node has a slightly different version " +"of the model parameters they originally received. The parameters are all " +"different because each client node has different examples in its local " +"dataset. The client nodes then send those model updates back to the " +"server. The model updates they send can either be the full model " +"parameters or just the gradients that were accumulated during local " +"training." +msgstr "" +"Après l'entraînement local, chaque nœud client possède une version " +"légèrement différente des paramètres du modèle qu'il a reçus à l'origine." +" Les paramètres sont tous différents parce que chaque nœud client a des " +"exemples différents dans son ensemble de données local. Les nœuds clients" +" renvoient ensuite ces mises à jour du modèle au serveur. Les mises à " +"jour du modèle qu'ils envoient peuvent être soit les paramètres complets " +"du modèle, soit seulement les gradients qui ont été accumulés au cours de" +" l'entraînement local." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 +msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 +msgid "Send model updates" +msgstr "Envoyer les mises à jour du modèle" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 +msgid "Step 4: Aggregate model updates into a new global model" +msgstr "" +"Étape 4 : Agréger les mises à jour des modèles dans un nouveau modèle " +"global" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 +msgid "" +"The server receives model updates from the selected client nodes. If it " +"selected 100 client nodes, it now has 100 slightly different versions of " +"the original global model, each trained on the local data of one client. " +"But didn't we want to have one model that contains the learnings from the" +" data of all 100 client nodes?" +msgstr "" +"Le serveur reçoit les mises à jour du modèle des nœuds clients " +"sélectionnés. S'il a sélectionné 100 nœuds clients, il dispose maintenant" +" de 100 versions légèrement différentes du modèle global original, " +"chacune ayant été formée sur les données locales d'un client. Mais ne " +"voulions-nous pas avoir un seul modèle qui contienne les apprentissages " +"des données de l'ensemble des 100 nœuds clients ?" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 +msgid "" +"In order to get one single model, we have to combine all the model " +"updates we received from the client nodes. This process is called " +"*aggregation*, and there are many different ways to do it. The most basic" +" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " +"`__), often abbreviated as *FedAvg*. " +"*FedAvg* takes the 100 model updates and, as the name suggests, averages " +"them. To be more precise, it takes the *weighted average* of the model " +"updates, weighted by the number of examples each client used for " +"training. The weighting is important to make sure that each data example " +"has the same \"influence\" on the resulting global model. If one client " +"has 10 examples, and another client has 100 examples, then - without " +"weighting - each of the 10 examples would influence the global model ten " +"times as much as each of the 100 examples." +msgstr "" +"In order to get one single model, we have to combine all the model " +"updates we received from the client nodes. This process is called " +"*aggregation*, and there are many different ways to do it. The most basic" +" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " +"`__), often abbreviated as *FedAvg*. " +"*FedAvg* takes the 100 model updates and, as the name suggests, averages " +"them. To be more precise, it takes the *weighted average* of the model " +"updates, weighted by the number of examples each client used for " +"training. The weighting is important to make sure that each data example " +"has the same \"influence\" on the resulting global model. If one client " +"has 10 examples, and another client has 100 examples, then - without " +"weighting - each of the 10 examples would influence the global model ten " +"times as much as each of the 100 examples." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 +msgid "|72939caf6e294b0986fee6dde96614d7|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 +msgid "Aggregate model updates" +msgstr "Mises à jour globales du modèle" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 +msgid "Step 5: Repeat steps 1 to 4 until the model converges" +msgstr "Étape 5 : répète les étapes 1 à 4 jusqu'à ce que le modèle converge" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 +msgid "" +"Steps 1 to 4 are what we call a single round of federated learning. The " +"global model parameters get sent to the participating client nodes (step " +"1), the client nodes train on their local data (step 2), they send their " +"updated models to the server (step 3), and the server then aggregates the" +" model updates to get a new version of the global model (step 4)." +msgstr "" +"Les étapes 1 à 4 constituent ce que nous appelons un cycle unique " +"d'apprentissage fédéré. Les paramètres du modèle global sont envoyés aux " +"nœuds clients participants (étape 1), les nœuds clients s'entraînent sur " +"leurs données locales (étape 2), ils envoient leurs modèles mis à jour au" +" serveur (étape 3), et le serveur agrège ensuite les mises à jour du " +"modèle pour obtenir une nouvelle version du modèle global (étape 4)." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 +#, fuzzy +msgid "" +"During a single round, each client node that participates in that " +"iteration only trains for a little while. This means that after the " +"aggregation step (step 4), we have a model that has been trained on all " +"the data of all participating client nodes, but only for a little while. " +"We then have to repeat this training process over and over again to " +"eventually arrive at a fully trained model that performs well across the " +"data of all client nodes." +msgstr "" +"Au cours d'un seul tour, chaque nœud client qui participe à cette " +"itération ne s'entraîne que pendant un petit moment. Cela signifie " +"qu'après l'étape d'agrégation (étape 4), nous avons un modèle qui a été " +"entraîné sur toutes les données de tous les nœuds clients participants, " +"mais seulement pendant un petit moment. Nous devons ensuite répéter ce " +"processus d'entraînement encore et encore pour finalement arriver à un " +"modèle entièrement entraîné qui fonctionne bien sur l'ensemble des " +"données de tous les nœuds clients." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 +msgid "" +"Congratulations, you now understand the basics of federated learning. " +"There's a lot more to discuss, of course, but that was federated learning" +" in a nutshell. In later parts of this tutorial, we will go into more " +"detail. Interesting questions include: How can we select the best client " +"nodes that should participate in the next round? What's the best way to " +"aggregate model updates? How can we handle failing client nodes " +"(stragglers)?" +msgstr "" +"Félicitations, tu comprends maintenant les bases de l'apprentissage " +"fédéré. Il y a bien sûr beaucoup plus à discuter, mais c'était " +"l'apprentissage fédéré en quelques mots. Dans les parties suivantes de ce" +" tutoriel, nous irons plus en détail. Les questions intéressantes " +"comprennent : comment pouvons-nous sélectionner les meilleurs nœuds " +"clients qui devraient participer au prochain tour ? Quelle est la " +"meilleure façon d'agréger les mises à jour du modèle ? Comment pouvons-" +"nous gérer les nœuds clients qui échouent (stragglers) ?" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 +#, fuzzy +msgid "" +"Just like we can train a model on the decentralized data of different " +"client nodes, we can also evaluate the model on that data to receive " +"valuable metrics. This is called federated evaluation, sometimes " +"abbreviated as FE. In fact, federated evaluation is an integral part of " +"most federated learning systems." +msgstr "" +"Tout comme nous pouvons former un modèle sur les données décentralisées " +"de différents nœuds clients, nous pouvons également évaluer le modèle sur" +" ces données pour recevoir des mesures précieuses. C'est ce qu'on appelle" +" l'évaluation fédérée, parfois abrégée en FE. En fait, l'évaluation " +"fédérée fait partie intégrante de la plupart des systèmes d'apprentissage" +" fédéré." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 +msgid "Federated analytics" +msgstr "Analyses fédérées" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 +msgid "" +"In many cases, machine learning isn't necessary to derive value from " +"data. Data analysis can yield valuable insights, but again, there's often" +" not enough data to get a clear answer. What's the average age at which " +"people develop a certain type of health condition? Federated analytics " +"enables such queries over multiple client nodes. It is usually used in " +"conjunction with other privacy-enhancing technologies like secure " +"aggregation to prevent the server from seeing the results submitted by " +"individual client nodes." +msgstr "" +"Dans de nombreux cas, l'apprentissage automatique n'est pas nécessaire " +"pour tirer de la valeur des données. L'analyse des données peut donner " +"des indications précieuses, mais là encore, il n'y a souvent pas assez de" +" données pour obtenir une réponse claire. Quel est l'âge moyen auquel les" +" gens développent un certain type de problème de santé ? L'analyse " +"fédérée permet de telles requêtes sur plusieurs nœuds clients. Elle est " +"généralement utilisée en conjonction avec d'autres technologies de " +"renforcement de la confidentialité, comme l'agrégation sécurisée, pour " +"empêcher le serveur de voir les résultats soumis par les nœuds clients " +"individuels." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 +msgid "" +"Differential privacy (DP) is often mentioned in the context of Federated " +"Learning. It is a privacy-preserving method used when analyzing and " +"sharing statistical data, ensuring the privacy of individual " +"participants. DP achieves this by adding statistical noise to the model " +"updates, ensuring any individual participants’ information cannot be " +"distinguished or re-identified. This technique can be considered an " +"optimization that provides a quantifiable privacy protection measure." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 +msgid "Flower" +msgstr "Fleur" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 +msgid "" +"Federated learning, federated evaluation, and federated analytics require" +" infrastructure to move machine learning models back and forth, train and" +" evaluate them on local data, and then aggregate the updated models. " +"Flower provides the infrastructure to do exactly that in an easy, " +"scalable, and secure way. In short, Flower presents a unified approach to" +" federated learning, analytics, and evaluation. It allows the user to " +"federate any workload, any ML framework, and any programming language." +msgstr "" +"L'apprentissage fédéré, l'évaluation fédérée et l'analyse fédérée " +"nécessitent une infrastructure pour déplacer les modèles d'apprentissage " +"automatique dans les deux sens, les entraîner et les évaluer sur des " +"données locales, puis agréger les modèles mis à jour. Flower fournit " +"l'infrastructure pour faire exactement cela de manière simple, évolutive " +"et sécurisée. En bref, Flower présente une approche unifiée de " +"l'apprentissage, de l'analyse et de l'évaluation fédérés. Il permet à " +"l'utilisateur de fédérer n'importe quelle charge de travail, n'importe " +"quel cadre de ML et n'importe quel langage de programmation." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 +msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 +msgid "" +"Flower federated learning server and client nodes (car, scooter, personal" +" computer, roomba, and phone)" +msgstr "" +"Serveur d'apprentissage fédéré de Flower et nœuds clients (voiture, " +"scooter, ordinateur personnel, roomba et téléphone)" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 +msgid "" +"Congratulations, you just learned the basics of federated learning and " +"how it relates to the classic (centralized) machine learning!" +msgstr "" +"Félicitations, tu viens d'apprendre les bases de l'apprentissage fédéré " +"et son rapport avec l'apprentissage automatique classique (centralisé) !" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 +msgid "" +"In the next part of this tutorial, we are going to build a first " +"federated learning system with Flower." +msgstr "" +"Dans la prochaine partie de ce tutoriel, nous allons construire un " +"premier système d'apprentissage fédéré avec Flower." + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 +#, fuzzy +msgid "" +"The `Flower Federated Learning Tutorial - Part 1 " +"`__ shows how to build a simple federated learning system " +"with PyTorch and Flower." +msgstr "" +"Le `Tutoriel d'apprentissage fédéré Flower - Partie 1 " +"`__ " +"montre comment construire un système d'apprentissage fédéré simple avec " +"PyTorch et Flower." + +#~ msgid "Flower CLI commands" +#~ msgstr "Commandes CLI Flower" + +#~ msgid "Contributor guide" +#~ msgstr "Guide pour les contributeurs" + +#~ msgid "API Reference - Flower CLI commands" +#~ msgstr "Référence API - Commandes CLI pour Flower" + +#~ msgid "API Reference - flwr (Python package)" +#~ msgstr "Référence API - flwr (paquetage Python)" + +#~ msgid "Flower client." +#~ msgstr "Client de Flower" + +#~ msgid "Abstract base class for Flower clients." +#~ msgstr "" + +#~ msgid "Evaluate the provided parameters using the locally held dataset." +#~ msgstr "évaluer le modèle mis à jour sur l'ensemble de test local" + +#~ msgid "Parameters" +#~ msgstr "Paramètres du modèle." + +#~ msgid "" +#~ "The evaluation instructions containing " +#~ "(global) model parameters received from " +#~ "the server and a dictionary of " +#~ "configuration values used to customize " +#~ "the local evaluation process." +#~ msgstr "" + +#~ msgid "Returns" +#~ msgstr "Ressources" + +#~ msgid "" +#~ "The evaluation result containing the " +#~ "loss on the local dataset and " +#~ "other details such as the number " +#~ "of local data examples used for " +#~ "evaluation." +#~ msgstr "" + +#~ msgid "Return type" +#~ msgstr "" + +#~ msgid "Refine the provided parameters using the locally held dataset." +#~ msgstr "" + +#~ msgid "" +#~ "The training instructions containing (global)" +#~ " model parameters received from the " +#~ "server and a dictionary of configuration" +#~ " values used to customize the local" +#~ " training process." +#~ msgstr "" + +#~ msgid "" +#~ "The training result containing updated " +#~ "parameters and other details such as " +#~ "the number of local training examples" +#~ " used for training." +#~ msgstr "" + +#~ msgid "Return the current local model parameters." +#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" + +#~ msgid "" +#~ "The get parameters instructions received " +#~ "from the server containing a dictionary" +#~ " of configuration values." +#~ msgstr "" + +#~ msgid "The current local model parameters." +#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" + +#~ msgid "Return set of client's properties." +#~ msgstr "" + +#~ msgid "" +#~ "The get properties instructions received " +#~ "from the server containing a dictionary" +#~ " of configuration values." +#~ msgstr "" + +#~ msgid "The current client properties." +#~ msgstr "" + +#~ msgid "Start a Flower client node which connects to a Flower server." +#~ msgstr "" + +#~ msgid "" +#~ "The IPv4 or IPv6 address of the" +#~ " server. If the Flower server runs" +#~ " on the same machine on port " +#~ "8080, then `server_address` would be " +#~ "`\"[::]:8080\"`." +#~ msgstr "" + +#~ msgid "An implementation of the abstract base class `flwr.client.Client`." +#~ msgstr "" + +#~ msgid "" +#~ "The maximum length of gRPC messages " +#~ "that can be exchanged with the " +#~ "Flower server. The default should be " +#~ "sufficient for most models. Users who" +#~ " train very large models might need" +#~ " to increase this value. Note that" +#~ " the Flower server needs to be " +#~ "started with the same value (see " +#~ "`flwr.server.start_server`), otherwise it will " +#~ "not know about the increased limit " +#~ "and block larger messages." +#~ msgstr "" + +#~ msgid "" +#~ "The PEM-encoded root certificates as " +#~ "a byte string or a path string." +#~ " If provided, a secure connection " +#~ "using the certificates will be " +#~ "established to an SSL-enabled Flower " +#~ "server." +#~ msgstr "" + +#~ msgid "" +#~ "DEPRECATED - USE 'transport' INSTEAD. " +#~ "Defines whether or not the client " +#~ "is interacting with the server using " +#~ "the experimental REST API. This feature" +#~ " is experimental, it might change " +#~ "considerably in future versions of " +#~ "Flower." +#~ msgstr "" +#~ "DÉPRÉCIÉ - UTILISER 'transport' À LA " +#~ "PLACE Définit si le client interagit " +#~ "ou non avec le serveur à l'aide" +#~ " de l'API REST expérimentale. Cette " +#~ "fonctionnalité est expérimentale, elle " +#~ "pourrait changer considérablement dans les " +#~ "futures versions de Flower." + +#~ msgid "" +#~ "Configure the transport layer. Allowed " +#~ "values: - 'grpc-bidi': gRPC, " +#~ "bidirectional streaming - 'grpc-rere': " +#~ "gRPC, request-response (experimental) - " +#~ "'rest': HTTP (experimental)" +#~ msgstr "" +#~ "Valeurs autorisées : - 'grpc-bidi' " +#~ ": gRPC, flux bidirectionnel - 'grpc-" +#~ "rere' : gRPC, requête-réponse " +#~ "(expérimental) - 'rest' : HTTP " +#~ "(expérimental)" + +#~ msgid "Starting a gRPC client with an insecure server connection:" +#~ msgstr "" + +#~ msgid "Starting an SSL-enabled gRPC client:" +#~ msgstr "" + +#~ msgid "Abstract base class for Flower clients using NumPy." +#~ msgstr "" + +#~ msgid "The current (global) model parameters." +#~ msgstr "``get_parameters`` : renvoie les paramètres du modèle local actuel" + +#~ msgid "" +#~ "Configuration parameters which allow the " +#~ "server to influence evaluation on the" +#~ " client. It can be used to " +#~ "communicate arbitrary values from the " +#~ "server to the client, for example, " +#~ "to influence the number of examples " +#~ "used for evaluation." +#~ msgstr "" + +#~ msgid "" +#~ "* **loss** (*float*) -- The evaluation" +#~ " loss of the model on the local" +#~ " dataset. * **num_examples** (*int*) -- " +#~ "The number of examples used for " +#~ "evaluation. * **metrics** (*Dict[str, " +#~ "Scalar]*) -- A dictionary mapping " +#~ "arbitrary string keys to values of " +#~ "type bool, bytes, float, int, or " +#~ "str. It can be used to " +#~ "communicate arbitrary values back to the" +#~ " server." +#~ msgstr "" + +#~ msgid "" +#~ "**loss** (*float*) -- The evaluation " +#~ "loss of the model on the local " +#~ "dataset." +#~ msgstr "" + +#~ msgid "**num_examples** (*int*) -- The number of examples used for evaluation." +#~ msgstr "" #~ msgid "" #~ "**metrics** (*Dict[str, Scalar]*) -- A " @@ -24953,7 +26231,7 @@ msgstr "" #~ msgstr "Contribuer sur GitHub" #~ msgid "How to write a good PR title" -#~ msgstr "Comment rédiger un bon titre de RP" +#~ msgstr "Comment écrire un bon titre de PR" #~ msgid "" #~ "A well-crafted PR title helps team" @@ -24962,12 +26240,12 @@ msgstr "" #~ "proposed. Here's a guide to help " #~ "you write a good GitHub PR title:" #~ msgstr "" -#~ "Un titre de RP bien rédigé aide" -#~ " les membres de l'équipe à comprendre" -#~ " rapidement l'objectif et la portée " -#~ "des changements proposés. Voici un guide" -#~ " pour t'aider à rédiger un bon " -#~ "titre de RP GitHub :" +#~ "Un titre de PR bien choisi permet" +#~ " aux autres développeurs de rapidement " +#~ "comprendre l'intérêt et le scope des " +#~ "changements proposés. Voici un guide " +#~ "pour vous aider à écrire des bons" +#~ " titres de PR :" #~ msgid "" #~ "1. Be Clear and Concise: Provide a" @@ -24983,22 +26261,20 @@ msgstr "" #~ " and Punctuation: Follow grammar rules " #~ "for clarity." #~ msgstr "" -#~ "1. Être clair et concis : fournir" +#~ "1. Soyez clair et concis : Donnez" #~ " un résumé clair des changements de" -#~ " manière concise. 1. Utiliser des " -#~ "verbes d'action : commencer par des " -#~ "verbes comme \" Ajouter \", \" " -#~ "Mettre à jour \" ou \" Réparer " -#~ "\" pour indiquer l'objectif. 1. Inclure" -#~ " des informations pertinentes : mentionner" -#~ " la fonctionnalité ou le module " -#~ "affecté pour le contexte. 1. Faire " -#~ "court : éviter les titres trop " -#~ "longs pour faciliter la lecture. 1. " -#~ "Utiliser des majuscules et une " -#~ "ponctuation correctes : suivre les " -#~ "règles de grammaire pour plus de " -#~ "clarté." +#~ " manière concise. 1. Utilisez des " +#~ "verbes actionnables : Commencez par des" +#~ " verbes comme \"Add\", \"Update\", ou " +#~ "\"Fix\" pour indiquer le but. 1. " +#~ "Inclure des renseignements pertinents : " +#~ "Mentionner la caractéristique ou le " +#~ "module concerné pour le contexte. 1. " +#~ "Gardez le court : Évitez les longs" +#~ " titres pour une lisibilité facile. " +#~ "1. Utiliser une bonne capitalisation et" +#~ " une ponctuation : Suivre les règles" +#~ " de grammaire pour la clarté." #~ msgid "" #~ "Let's start with a few examples " @@ -25007,21 +26283,21 @@ msgstr "" #~ " information:" #~ msgstr "" #~ "Commençons par quelques exemples de " -#~ "titres à éviter car ils ne " -#~ "fournissent pas d'informations significatives " -#~ ":" +#~ "titres qui devraient être évités parce" +#~ " qu'ils ne fournissent pas d'information" +#~ " significative :" #~ msgid "Implement Algorithm" -#~ msgstr "Implémenter l'algorithme" +#~ msgstr "Implement Algorithm" #~ msgid "Database" #~ msgstr "Base de données" #~ msgid "Add my_new_file.py to codebase" -#~ msgstr "Ajoute my_new_file.py à la base de code" +#~ msgstr "Add my_new_file.py to codebase" #~ msgid "Improve code in module" -#~ msgstr "Améliore le code dans le module" +#~ msgstr "Improve code in module" #~ msgid "Change SomeModule" #~ msgstr "Change SomeModule" @@ -25033,25 +26309,21 @@ msgstr "" #~ " is already visible in the \"Files" #~ " changed\" section of the PR:" #~ msgstr "" -#~ "Voici quelques exemples positifs qui " -#~ "fournissent des informations utiles sans " -#~ "répéter comment ils procèdent, car cela" -#~ " est déjà visible dans la section " -#~ "\"Fichiers modifiés\" du RP :" +#~ "Voici quelques bons exemples qui " +#~ "fournissent de l'information utile sans " +#~ "répéter comment ils le font, comme " +#~ "cela est déjà visible dans la " +#~ "section \"Files changed\" de la PR " +#~ ":" #~ msgid "Update docs banner to mention Flower Summit 2023" -#~ msgstr "" -#~ "Mettre à jour la bannière des docs" -#~ " pour mentionner le sommet des fleurs" -#~ " 2023" +#~ msgstr "Update docs banner to mention Flower Summit 2023" #~ msgid "Remove unnecessary XGBoost dependency" -#~ msgstr "Supprime les dépendances inutiles de XGBoost" +#~ msgstr "Remove unnecessary XGBoost dependency" #~ msgid "Remove redundant attributes in strategies subclassing FedAvg" -#~ msgstr "" -#~ "Supprimer les attributs redondants dans " -#~ "les stratégies sous-classant FedAvg" +#~ msgstr "Remove redundant attributes in strategies subclassing FedAvg" #~ msgid "Add CI job to deploy the staging system when the `main` branch changes" #~ msgstr "" @@ -25063,10 +26335,10 @@ msgstr "" #~ "Add new amazing library which will " #~ "be used to improve the simulation " #~ "engine" -#~ msgstr "" -#~ "Ajoute une nouvelle bibliothèque étonnante " -#~ "qui sera utilisée pour améliorer le " -#~ "moteur de simulation" +#~ msgstr "" +#~ "Add new amazing library which will " +#~ "be used to improve the simulation " +#~ "engine" #~ msgid "Differential privacy" #~ msgstr "Confidentialité différentielle" @@ -26628,2027 +27900,3316 @@ msgstr "" #~ "execute the experiment." #~ msgstr "" -#~ msgid "" -#~ "Please make sure to add your " -#~ "baseline or experiment to the " -#~ "corresponding directory as explained in " -#~ "`Executing Baseline `_. Give your baseline the " -#~ "unique identifier. For example, :code:`fedbn`" -#~ " refers to the paper \"FedBN: " -#~ "Federated Learning on non-IID Features" -#~ " via Local Batch Normalization\" and " -#~ "creates the corresponding directory " -#~ ":code:`flower/baselines/flwr_baselines/publications/fedbn`. Then" -#~ " you create the experiment directory " -#~ "with the experiment name. For example," -#~ " the experiment that measures the " -#~ "convergence has the directory " -#~ ":code:`flower/baselines/flwr_baselines/publications/fedbn/convergence_rate`." -#~ " This directory contains all your " -#~ "code and a :code:`README.md` with a " -#~ "link to the paper, the paper's " -#~ "abstract, and a detailed description of" -#~ " how to execute the experiments." +#~ msgid "" +#~ "Please make sure to add your " +#~ "baseline or experiment to the " +#~ "corresponding directory as explained in " +#~ "`Executing Baseline `_. Give your baseline the " +#~ "unique identifier. For example, :code:`fedbn`" +#~ " refers to the paper \"FedBN: " +#~ "Federated Learning on non-IID Features" +#~ " via Local Batch Normalization\" and " +#~ "creates the corresponding directory " +#~ ":code:`flower/baselines/flwr_baselines/publications/fedbn`. Then" +#~ " you create the experiment directory " +#~ "with the experiment name. For example," +#~ " the experiment that measures the " +#~ "convergence has the directory " +#~ ":code:`flower/baselines/flwr_baselines/publications/fedbn/convergence_rate`." +#~ " This directory contains all your " +#~ "code and a :code:`README.md` with a " +#~ "link to the paper, the paper's " +#~ "abstract, and a detailed description of" +#~ " how to execute the experiments." +#~ msgstr "" + +#~ msgid "" +#~ "Please also check if :code:`pyproject.toml`" +#~ " and :code:`requirements.txt` (all in the" +#~ " directory `baselines " +#~ "`_ contain" +#~ " all required Python packages (libraries," +#~ " frameworks, ...). If the required " +#~ "Python package is not yet listed, " +#~ "please add it to :code:`pyproject.toml`. " +#~ "If you need a different version of" +#~ " a package already listed, please try" +#~ " to ensure your experiment runs with" +#~ " the existing version listed in " +#~ ":code:`pyproject.toml` (or :code:`requirements.txt`). " +#~ "If that doesn't work, open a " +#~ "GitHub Issue and request the version " +#~ "change." +#~ msgstr "" + +#~ msgid "" +#~ "The experiment also needs to contain " +#~ "a file with a downloader for the" +#~ " dataset - if possible automatic. " +#~ "This can be included in one of " +#~ "the files or as an extra file." +#~ msgstr "" + +#~ msgid "" +#~ "Finally, please add plots for all " +#~ "experimental results your code is " +#~ "running to the :code:`experiment` directory" +#~ " and include them in :code:`README.md`. " +#~ "Doing this helps others and enables " +#~ "them to recognize your contributions " +#~ "quickly." +#~ msgstr "" + +#~ msgid "" +#~ "We are aware that a few libraries" +#~ " are available only via Conda. " +#~ "However, we want to encourage you " +#~ "to ensure that your code also runs" +#~ " well outside of Conda to make " +#~ "it more accessible to the broader " +#~ "research community." +#~ msgstr "" + +#~ msgid "Here is a checklist for adding a new baseline:" +#~ msgstr "" + +#~ msgid "" +#~ "add required Python packages to " +#~ ":code:`pyproject.toml` or :code:`requirements.txt`" +#~ msgstr "" + +#~ msgid "" +#~ "add all required code under " +#~ ":code:`baselines/flwr_baselines/publications/[new_publication]`" +#~ msgstr "" + +#~ msgid "add a dataset downloader" +#~ msgstr "" + +#~ msgid "add an experiment plot" +#~ msgstr "" + +#~ msgid "add a :code:`README.md`" +#~ msgstr "" + +#~ msgid "Usability" +#~ msgstr "" + +#~ msgid "" +#~ "Flower is known and loved for its" +#~ " usability. Therefore, make sure that " +#~ "your baseline or experiment can be " +#~ "executed with a single command such " +#~ "as :code:`./run.sh` or :code:`python3 " +#~ "main.py`. How you organize the " +#~ "experiments and the related code " +#~ "structure is up to you as an " +#~ "author, but please keep in mind to" +#~ " make sure that other users can " +#~ "easily understand and execute your " +#~ "baseline." +#~ msgstr "" + +#~ msgid "We look forward to your contribution!" +#~ msgstr "Exemple de première contribution" + +#~ msgid "flwr" +#~ msgstr "Fleur" + +#~ msgid "binaries" +#~ msgstr "" + +#~ msgid "Flower Baselines" +#~ msgstr "Demande pour une nouvelle Flower Baseline" + +#~ msgid "" +#~ "Flower Baselines are a collection of " +#~ "organised scripts used to reproduce " +#~ "results from well-known publications or" +#~ " benchmarks. You can check which " +#~ "baselines already exist and/or contribute " +#~ "your own baseline." +#~ msgstr "" + +#~ msgid "Flower requires `Python 3.7 `_ or above." +#~ msgstr "`Python 3.7 `_ ou plus" + +#~ msgid "|9e234df38403464899ad3aee36bf1b95|" +#~ msgstr "" + +#~ msgid "|081158351506446f9f772cb45ee68523|" +#~ msgstr "" + +#~ msgid "|e9325042b79c45ed96b5a8d2f6f3cdc9|" +#~ msgstr "" + +#~ msgid "|11b83bb107344db78a37266e080c4a7a|" +#~ msgstr "" + +#~ msgid "|cd764bcf6d174a9cb62880ace9a8a6bd|" +#~ msgstr "" + +#~ msgid "|5c520984cced41e38f6bb4af416c3f84|" +#~ msgstr "" + +#~ msgid "|66941b0608644cf1a2269a194d3bc0dd|" +#~ msgstr "" + +#~ msgid "|4b149f3a095b402bb8890275aabc9298|" +#~ msgstr "" + +#~ msgid "|675cf7d3d53a4817b5d47529c0758158|" +#~ msgstr "" + +#~ msgid "|7ca594e16ae7477790c2e3cf096ec7cd|" +#~ msgstr "" + +#~ msgid "|d669336577b545a081d5d74169a9bc4d|" +#~ msgstr "" + +#~ msgid "|00b3d6cde1ff410ba54eff58da4e033a|" +#~ msgstr "" + +#~ msgid "|29a11f5353084c1995c538f7edef71a5|" +#~ msgstr "" + +#~ msgid "|d62eda312fd44726bb5db2b761fe7e0d|" +#~ msgstr "" + +#~ msgid "Using Baselines" +#~ msgstr "" + +#~ msgid "Structure" +#~ msgstr "" + +#~ msgid "" +#~ "All baselines are available in the " +#~ "directory `baselines " +#~ "`_. This " +#~ "directory has two different files:" +#~ msgstr "" + +#~ msgid "" +#~ "Both files contain all the information" +#~ " about required Python packages (libraries," +#~ " frameworks, ...) and their versions. " +#~ "You can install each library separately" +#~ " by using :code: `pip install` or " +#~ "you can use Poetry and run " +#~ "code:`poetry install` in the directory " +#~ "where you find the :code:`pyproject.toml` " +#~ "file. After installing all requirements, " +#~ "you can start to run your " +#~ "baseline." +#~ msgstr "" + +#~ msgid "" +#~ "Go to the baseline that you want" +#~ " to execute. The directories and " +#~ "files are structured so that you " +#~ "can first find the paper with " +#~ "their unique identifier such that, for" +#~ " example, :code:`FedProx` refers to the " +#~ "paper \"Federated Optimization in " +#~ "Heterogeneous Networks\". The :code:`fedprox` " +#~ "section contains all available experiments " +#~ "from that paper." +#~ msgstr "" + +#~ msgid "" +#~ "The experiment area contains a " +#~ ":code:`README.md` covering the corresponding " +#~ "paper, its abstract, and goal as " +#~ "well as a detailed description of " +#~ "how to run the baseline. Please " +#~ "use the :code:`README.md` to see how " +#~ "to execute each individual baseline." +#~ msgstr "" + +#~ msgid "Available Baselines" +#~ msgstr "" + +#~ msgid "" +#~ "The following table lists all currently" +#~ " available baselines and the corresponding" +#~ " papers. If you want to add a" +#~ " new baseline or experiment, please " +#~ "check the `Contributing Baselines " +#~ "`_ section." +#~ msgstr "" + +#~ msgid "Paper" +#~ msgstr "" + +#~ msgid "Experiment" +#~ msgstr "" + +#~ msgid "Directory" +#~ msgstr "" + +#~ msgid "`FedAvg `_" +#~ msgstr "" + +#~ msgid "MNIST" +#~ msgstr "" + +#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedavg_mnist/`" #~ msgstr "" -#~ msgid "" -#~ "Please also check if :code:`pyproject.toml`" -#~ " and :code:`requirements.txt` (all in the" -#~ " directory `baselines " -#~ "`_ contain" -#~ " all required Python packages (libraries," -#~ " frameworks, ...). If the required " -#~ "Python package is not yet listed, " -#~ "please add it to :code:`pyproject.toml`. " -#~ "If you need a different version of" -#~ " a package already listed, please try" -#~ " to ensure your experiment runs with" -#~ " the existing version listed in " -#~ ":code:`pyproject.toml` (or :code:`requirements.txt`). " -#~ "If that doesn't work, open a " -#~ "GitHub Issue and request the version " -#~ "change." +#~ msgid "`FedProx `_" #~ msgstr "" -#~ msgid "" -#~ "The experiment also needs to contain " -#~ "a file with a downloader for the" -#~ " dataset - if possible automatic. " -#~ "This can be included in one of " -#~ "the files or as an extra file." +#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedprox_mnist/`" #~ msgstr "" -#~ msgid "" -#~ "Finally, please add plots for all " -#~ "experimental results your code is " -#~ "running to the :code:`experiment` directory" -#~ " and include them in :code:`README.md`. " -#~ "Doing this helps others and enables " -#~ "them to recognize your contributions " -#~ "quickly." +#~ msgid "`FedOpt `_" #~ msgstr "" -#~ msgid "" -#~ "We are aware that a few libraries" -#~ " are available only via Conda. " -#~ "However, we want to encourage you " -#~ "to ensure that your code also runs" -#~ " well outside of Conda to make " -#~ "it more accessible to the broader " -#~ "research community." +#~ msgid "sparse gradient task" #~ msgstr "" -#~ msgid "Here is a checklist for adding a new baseline:" +#~ msgid ":code:`flower/baselines/flwr_baselines/publications/adaptive_federated_optimization`" #~ msgstr "" -#~ msgid "" -#~ "add required Python packages to " -#~ ":code:`pyproject.toml` or :code:`requirements.txt`" +#~ msgid "`FedBN `_" #~ msgstr "" -#~ msgid "" -#~ "add all required code under " -#~ ":code:`baselines/flwr_baselines/publications/[new_publication]`" +#~ msgid "convergence rate" #~ msgstr "" -#~ msgid "add a dataset downloader" +#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedbn/convergence_rate`" #~ msgstr "" -#~ msgid "add an experiment plot" +#~ msgid "" +#~ "Flower requires `Python 3.7 " +#~ "`_ or above, we " +#~ "recommend `Python 3.8 " +#~ "`_." #~ msgstr "" +#~ "Flower nécessite `Python 3.7 " +#~ "`_ ou plus, nous " +#~ "recommandons `Python 3.8 " +#~ "`_." -#~ msgid "add a :code:`README.md`" +#~ msgid "|6baade94cd14454e82ead34fcc29a182|" #~ msgstr "" -#~ msgid "Usability" +#~ msgid "|1209ecd819104c458d396cf665c7ed4f|" #~ msgstr "" -#~ msgid "" -#~ "Flower is known and loved for its" -#~ " usability. Therefore, make sure that " -#~ "your baseline or experiment can be " -#~ "executed with a single command such " -#~ "as :code:`./run.sh` or :code:`python3 " -#~ "main.py`. How you organize the " -#~ "experiments and the related code " -#~ "structure is up to you as an " -#~ "author, but please keep in mind to" -#~ " make sure that other users can " -#~ "easily understand and execute your " -#~ "baseline." +#~ msgid "|c088b02349304344a53f3ce1464225fb|" #~ msgstr "" -#~ msgid "We look forward to your contribution!" -#~ msgstr "Exemple de première contribution" +#~ msgid "|b54d50afc82a4a57a55997a9eaeb735b|" +#~ msgstr "" -#~ msgid "flwr" -#~ msgstr "Fleur" +#~ msgid "|d17b57e97b714a25b43790d4b832fd87|" +#~ msgstr "" -#~ msgid "binaries" +#~ msgid "|38966d05301a4854aa73c8c5033bfaab|" #~ msgstr "" -#~ msgid "Flower Baselines" -#~ msgstr "Demande pour une nouvelle Flower Baseline" +#~ msgid "|231d55f7926d4a5db02dcd724ec62529|" +#~ msgstr "" -#~ msgid "" -#~ "Flower Baselines are a collection of " -#~ "organised scripts used to reproduce " -#~ "results from well-known publications or" -#~ " benchmarks. You can check which " -#~ "baselines already exist and/or contribute " -#~ "your own baseline." +#~ msgid "|fb44f2e13a1b4b69b7a72234eedd13f4|" #~ msgstr "" -#~ msgid "Flower requires `Python 3.7 `_ or above." -#~ msgstr "`Python 3.7 `_ ou plus" +#~ msgid "|1cfc77af5d164030942e84d14268c256|" +#~ msgstr "" -#~ msgid "|9e234df38403464899ad3aee36bf1b95|" +#~ msgid "|0d50828231a64bc08223544a2d2fa216|" #~ msgstr "" -#~ msgid "|081158351506446f9f772cb45ee68523|" +#~ msgid "|904387757ceb42fbaa1875f3e8061113|" #~ msgstr "" -#~ msgid "|e9325042b79c45ed96b5a8d2f6f3cdc9|" +#~ msgid "|68608e1b7c4842458c528b431c715f5a|" #~ msgstr "" -#~ msgid "|11b83bb107344db78a37266e080c4a7a|" +#~ msgid "|2adb106bda97480bb4b33eac472e321e|" #~ msgstr "" -#~ msgid "|cd764bcf6d174a9cb62880ace9a8a6bd|" +#~ msgid "|025f0a6f7a6145cba4bf8fa0e2495851|" #~ msgstr "" -#~ msgid "|5c520984cced41e38f6bb4af416c3f84|" +#~ msgid "Before the release" +#~ msgstr "Avant la sortie" + +#~ msgid "" +#~ "Update the changelog (``changelog.md``) with" +#~ " all relevant changes that happened " +#~ "after the last release. If the " +#~ "last release was tagged ``v1.2.0``, you" +#~ " can use the following URL to " +#~ "see all commits that got merged " +#~ "into ``main`` since then:" #~ msgstr "" +#~ "Mettez à jour le journal des " +#~ "modifications (``changelog.md``) avec tous les" +#~ " changements pertinents qui se sont " +#~ "produits après la dernière version. Si" +#~ " la dernière version a été étiquetée" +#~ " ``v1.2.0``, vous pouvez utiliser l'URL " +#~ "suivante pour voir tous les commits " +#~ "qui ont été fusionnés dans ``main`` " +#~ "depuis lors :" -#~ msgid "|66941b0608644cf1a2269a194d3bc0dd|" +#~ msgid "" +#~ "`GitHub: Compare v1.2.0...main " +#~ "`_" #~ msgstr "" +#~ "`GitHub : Compare v1.2.0...main " +#~ "`_" -#~ msgid "|4b149f3a095b402bb8890275aabc9298|" +#~ msgid "" +#~ "Thank the authors who contributed since" +#~ " the last release. This command helps" +#~ " extract them: ``git log --format='%aN' " +#~ "v1.1.0..HEAD | sort -u``. The command" +#~ " has the same order as ``git " +#~ "shortlog``." #~ msgstr "" +#~ "Remerciez les auteurs qui ont contribué" +#~ " depuis la dernière version. Cette " +#~ "commande permet de les extraire : " +#~ "``git log --format='%aN' v1.1.0..HEAD | " +#~ "sort -u``. La commande a le même" +#~ " ordre que ``git shortlog``." -#~ msgid "|675cf7d3d53a4817b5d47529c0758158|" +#~ msgid "" +#~ "Update the ``changelog.md`` section header " +#~ "``Unreleased`` to contain the version " +#~ "number and date for the release " +#~ "you are building. Create a pull " +#~ "request with the change." #~ msgstr "" +#~ "Mettez à jour l'en-tête de section" +#~ " ``changelog.md`` ``Unreleased`` pour qu'il " +#~ "contienne le numéro de version et " +#~ "la date de la version que vous " +#~ "construisez. Créez une demande de " +#~ "traction avec le changement." -#~ msgid "|7ca594e16ae7477790c2e3cf096ec7cd|" +#~ msgid "" +#~ "Tag the release commit with the " +#~ "version number as soon as the PR" +#~ " is merged: ``git tag v0.12.3``, then" +#~ " ``git push --tags``" #~ msgstr "" +#~ "Marquez le commit de la version " +#~ "avec le numéro de version dès que" +#~ " le PR est fusionné : ``git tag" +#~ " v0.12.3``, puis ``git push --tags``" -#~ msgid "|d669336577b545a081d5d74169a9bc4d|" +#~ msgid "" +#~ "Build the release with ``./dev/build.sh``, " +#~ "then publish it with ``./dev/publish.sh``" #~ msgstr "" +#~ "Construisez la version avec " +#~ "``./dev/build.sh``, puis publiez-la avec " +#~ "``./dev/publish.sh``" -#~ msgid "|00b3d6cde1ff410ba54eff58da4e033a|" +#~ msgid "" +#~ "Create an entry in GitHub releases " +#~ "with the release notes for the " +#~ "previously tagged commit and attach the" +#~ " build artifacts (:code:`.whl` and " +#~ ":code:`.tar.gz`)." #~ msgstr "" +#~ "Crée une entrée dans GitHub releases " +#~ "avec les notes de version pour le" +#~ " commit précédemment étiqueté et attache" +#~ " les artefacts de construction " +#~ "(:code:`.whl` et :code:`.tar.gz`)." -#~ msgid "|29a11f5353084c1995c538f7edef71a5|" +#~ msgid "" +#~ "Second, create a virtual environment " +#~ "(and activate it). If you chose to" +#~ " use :code:`pyenv` (with the :code" +#~ ":`pyenv-virtualenv` plugin) and already " +#~ "have it installed , you can use" +#~ " the following convenience script (by " +#~ "default it will use :code:`Python " +#~ "3.8.17`, but you can change it by" +#~ " providing a specific :code:``)::" #~ msgstr "" +#~ "Deuxièmement, créer un environnement virtuel" +#~ " (et l'activer). Si vous choisissez " +#~ "d'utiliser :code:`pyenv` (avec le plugin " +#~ ":code:`pyenv-virtualenv`) et que vous " +#~ "l'avez déjà installé, vous pouvez " +#~ "utiliser le script suivant (par défaut" +#~ " il utilisera :code:`Python 3.8.17`, mais" +#~ " vous pouvez le changer en " +#~ "fournissant une :code:`` spécifique)::" + +#~ msgid "server.strategy.FedAvg" +#~ msgstr "serveur.stratégie.FedAvg" + +#~ msgid "server.strategy.FedAvgM" +#~ msgstr "stratégie.serveur.FedAvgM" + +#~ msgid "server.strategy.QFedAvg" +#~ msgstr "server.strategy.QFedAvg" + +#~ msgid "server.strategy.FedOpt" +#~ msgstr "serveur.stratégie.FedOpt" -#~ msgid "|d62eda312fd44726bb5db2b761fe7e0d|" -#~ msgstr "" +#~ msgid "server.strategy.FedProx" +#~ msgstr "serveur.stratégie.FedProx" -#~ msgid "Using Baselines" -#~ msgstr "" +#~ msgid "server.strategy.FedAdagrad" +#~ msgstr "serveur.stratégie.FedAdagrad" -#~ msgid "Structure" -#~ msgstr "" +#~ msgid "server.strategy.FedAdam" +#~ msgstr "serveur.stratégie.FedAdam" -#~ msgid "" -#~ "All baselines are available in the " -#~ "directory `baselines " -#~ "`_. This " -#~ "directory has two different files:" -#~ msgstr "" +#~ msgid "server.strategy.FedYogi" +#~ msgstr "serveur.stratégie.FedYogi" #~ msgid "" -#~ "Both files contain all the information" -#~ " about required Python packages (libraries," -#~ " frameworks, ...) and their versions. " -#~ "You can install each library separately" -#~ " by using :code: `pip install` or " -#~ "you can use Poetry and run " -#~ "code:`poetry install` in the directory " -#~ "where you find the :code:`pyproject.toml` " -#~ "file. After installing all requirements, " -#~ "you can start to run your " -#~ "baseline." +#~ "`achiverram28`, `Adam Narozniak`, `Anass " +#~ "Anhari`, `Charles Beauville`, `Dana-Farber`," +#~ " `Daniel J. Beutel`, `Daniel Nata " +#~ "Nugraha`, `Edoardo Gabrielli`, `eunchung`, " +#~ "`Gustavo Bertoli`, `Heng Pan`, `Javier`, " +#~ "`Mahdi`, `Ruth Galindo`, `Steven Hé " +#~ "(Sīchàng)`, `Taner Topal`" #~ msgstr "" #~ msgid "" -#~ "Go to the baseline that you want" -#~ " to execute. The directories and " -#~ "files are structured so that you " -#~ "can first find the paper with " -#~ "their unique identifier such that, for" -#~ " example, :code:`FedProx` refers to the " -#~ "paper \"Federated Optimization in " -#~ "Heterogeneous Networks\". The :code:`fedprox` " -#~ "section contains all available experiments " -#~ "from that paper." +#~ "Let's now load the CIFAR-10 training " +#~ "and test set, partition them into " +#~ "ten smaller datasets (each split into" +#~ " training and validation set), and " +#~ "wrap the resulting partitions by " +#~ "creating a PyTorch ``DataLoader`` for " +#~ "each of them:" #~ msgstr "" +#~ "Chargeons maintenant l'ensemble de formation" +#~ " et de test CIFAR-10, partitionnons-" +#~ "les en dix ensembles de données " +#~ "plus petits (chacun divisé en ensemble" +#~ " de formation et de validation), et" +#~ " enveloppons les partitions résultantes en" +#~ " créant un PyTorch ``DataLoader`` pour " +#~ "chacun d'entre eux :" #~ msgid "" -#~ "The experiment area contains a " -#~ ":code:`README.md` covering the corresponding " -#~ "paper, its abstract, and goal as " -#~ "well as a detailed description of " -#~ "how to run the baseline. Please " -#~ "use the :code:`README.md` to see how " -#~ "to execute each individual baseline." -#~ msgstr "" - -#~ msgid "Available Baselines" +#~ "Let's build a horizontal federated " +#~ "learning system using XGBoost and " +#~ "Flower!" #~ msgstr "" +#~ "Construisons un système d'apprentissage fédéré" +#~ " horizontal en utilisant XGBoost et " +#~ "Flower !" #~ msgid "" -#~ "The following table lists all currently" -#~ " available baselines and the corresponding" -#~ " papers. If you want to add a" -#~ " new baseline or experiment, please " -#~ "check the `Contributing Baselines " -#~ "`_ section." +#~ "Please refer to the `full code " +#~ "example `_ to learn " +#~ "more." #~ msgstr "" +#~ "Réfère-toi à l'exemple de code " +#~ "complet `_ pour en " +#~ "savoir plus." -#~ msgid "Paper" +#~ msgid "|3ff4c820a01d4a5abb022617de537c54|" #~ msgstr "" -#~ msgid "Experiment" +#~ msgid "|7f1889391ad448e2a65920165f0d798c|" #~ msgstr "" -#~ msgid "Directory" +#~ msgid "|a171dc4a0d044e70b5d585cc10ace0e0|" #~ msgstr "" -#~ msgid "`FedAvg `_" +#~ msgid "|fe518aa0d86341f7b2fc87bd6e3bbf0c|" #~ msgstr "" -#~ msgid "MNIST" +#~ msgid "|6abfdf0dade44469ae9f08c8dc7d148c|" #~ msgstr "" -#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedavg_mnist/`" +#~ msgid "|b4f147db24bb4da9a786e1d6676a1c2d|" #~ msgstr "" -#~ msgid "`FedProx `_" +#~ msgid "|5c62032f589a457bb37b5fee5b2adbde|" #~ msgstr "" -#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedprox_mnist/`" +#~ msgid "|f154df1846dd44f79a94f1dc3ae8b088|" #~ msgstr "" -#~ msgid "`FedOpt `_" +#~ msgid "|9d20be8160f7451fb0f33b194506503f|" #~ msgstr "" -#~ msgid "sparse gradient task" +#~ msgid "|3d949f76988443c59990d2e64f05c386|" #~ msgstr "" -#~ msgid ":code:`flower/baselines/flwr_baselines/publications/adaptive_federated_optimization`" +#~ msgid "|526c6d9140f6404f8a226d9056327b3b|" #~ msgstr "" -#~ msgid "`FedBN `_" +#~ msgid "|a5f6af14cd7c4550929b17f83b4f63c7|" #~ msgstr "" -#~ msgid "convergence rate" +#~ msgid "|bcd571c4f4ee4803a54f71b5c20448cb|" #~ msgstr "" -#~ msgid ":code:`flower/baselines/flwr_baselines/publications/fedbn/convergence_rate`" +#~ msgid "|c76452ae1ed84965be7ef23c72b95845|" #~ msgstr "" #~ msgid "" -#~ "Flower requires `Python 3.7 " -#~ "`_ or above, we " -#~ "recommend `Python 3.8 " -#~ "`_." -#~ msgstr "" -#~ "Flower nécessite `Python 3.7 " -#~ "`_ ou plus, nous " -#~ "recommandons `Python 3.8 " -#~ "`_." - -#~ msgid "|6baade94cd14454e82ead34fcc29a182|" -#~ msgstr "" - -#~ msgid "|1209ecd819104c458d396cf665c7ed4f|" -#~ msgstr "" - -#~ msgid "|c088b02349304344a53f3ce1464225fb|" -#~ msgstr "" - -#~ msgid "|b54d50afc82a4a57a55997a9eaeb735b|" -#~ msgstr "" - -#~ msgid "|d17b57e97b714a25b43790d4b832fd87|" -#~ msgstr "" - -#~ msgid "|38966d05301a4854aa73c8c5033bfaab|" +#~ "Please follow the first section on " +#~ "`Run Flower using Docker " +#~ "`_ which covers this" +#~ " step in more detail." #~ msgstr "" -#~ msgid "|231d55f7926d4a5db02dcd724ec62529|" +#~ msgid "" +#~ "Since `Flower 1.5 `_ we have " +#~ "introduced translations to our doc " +#~ "pages, but, as you might have " +#~ "noticed, the translations are often " +#~ "imperfect. If you speak languages other" +#~ " than English, you might be able " +#~ "to help us in our effort to " +#~ "make Federated Learning accessible to as" +#~ " many people as possible by " +#~ "contributing to those translations! This " +#~ "might also be a great opportunity " +#~ "for those wanting to become open " +#~ "source contributors with little prerequistes." #~ msgstr "" -#~ msgid "|fb44f2e13a1b4b69b7a72234eedd13f4|" +#~ msgid "" +#~ "You input your translation in the " +#~ "textbox at the top and then, once" +#~ " you are happy with it, you " +#~ "either press ``Save and continue`` (to" +#~ " save the translation and go to " +#~ "the next untranslated string), ``Save " +#~ "and stay`` (to save the translation " +#~ "and stay on the same page), " +#~ "``Suggest`` (to add your translation to" +#~ " suggestions for other users to " +#~ "view), or ``Skip`` (to go to the" +#~ " next untranslated string without saving" +#~ " anything)." #~ msgstr "" -#~ msgid "|1cfc77af5d164030942e84d14268c256|" +#~ msgid "" +#~ "If the section is completely empty " +#~ "(without any token) or non-existant, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." #~ msgstr "" -#~ msgid "|0d50828231a64bc08223544a2d2fa216|" -#~ msgstr "" +#~ msgid "Example: Walk-Through PyTorch & MNIST" +#~ msgstr "Exemple : PyTorch et MNIST" -#~ msgid "|904387757ceb42fbaa1875f3e8061113|" +#~ msgid "" +#~ "In this tutorial we will learn, " +#~ "how to train a Convolutional Neural " +#~ "Network on MNIST using Flower and " +#~ "PyTorch." #~ msgstr "" +#~ "Dans ce tutoriel, nous allons apprendre," +#~ " comment former un réseau neuronal " +#~ "convolutif sur MNIST en utilisant Flower" +#~ " et PyTorch." -#~ msgid "|68608e1b7c4842458c528b431c715f5a|" +#~ msgid "" +#~ "Since we want to use PyTorch to" +#~ " solve a computer vision task, let's" +#~ " go ahead an install PyTorch and " +#~ "the **torchvision** library:" #~ msgstr "" +#~ "Puisque nous voulons utiliser PyTorch " +#~ "pour résoudre une tâche de vision " +#~ "par ordinateur, installons PyTorch et la" +#~ " bibliothèque **torchvision** :" -#~ msgid "|2adb106bda97480bb4b33eac472e321e|" -#~ msgstr "" +#~ msgid "Ready... Set... Train!" +#~ msgstr "Prêts... prêts... entraînez-vous !" -#~ msgid "|025f0a6f7a6145cba4bf8fa0e2495851|" +#~ msgid "" +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on PyTorch's `Basic MNIST Example" +#~ " `_. " +#~ "This will allow you see how easy" +#~ " it is to wrap your code with" +#~ " Flower and begin training in a " +#~ "federated way. We provide you with " +#~ "two helper scripts, namely *run-" +#~ "server.sh*, and *run-clients.sh*. Don't " +#~ "be afraid to look inside, they are" +#~ " simple enough =)." #~ msgstr "" - -#~ msgid "Before the release" -#~ msgstr "Avant la sortie" +#~ "Maintenant que nous avons installé " +#~ "toutes nos dépendances, lançons un " +#~ "simple entraînement distribué avec deux " +#~ "clients et un serveur. Notre procédure" +#~ " d'entraînement et l'architecture de notre" +#~ " réseau sont basées sur l'exemple " +#~ "MNIST de base de PyTorch " +#~ "`_. Cela" +#~ " te permettra de voir à quel " +#~ "point il est facile d'envelopper ton " +#~ "code avec Flower et de commencer " +#~ "l'entraînement de manière fédérée. Nous " +#~ "te fournissons deux scripts d'aide, à" +#~ " savoir *run-server.sh*, et *run-" +#~ "clients.sh*. N'aie pas peur de regarder" +#~ " à l'intérieur, ils sont assez " +#~ "simples =)." #~ msgid "" -#~ "Update the changelog (``changelog.md``) with" -#~ " all relevant changes that happened " -#~ "after the last release. If the " -#~ "last release was tagged ``v1.2.0``, you" -#~ " can use the following URL to " -#~ "see all commits that got merged " -#~ "into ``main`` since then:" -#~ msgstr "" -#~ "Mettez à jour le journal des " -#~ "modifications (``changelog.md``) avec tous les" -#~ " changements pertinents qui se sont " -#~ "produits après la dernière version. Si" -#~ " la dernière version a été étiquetée" -#~ " ``v1.2.0``, vous pouvez utiliser l'URL " -#~ "suivante pour voir tous les commits " -#~ "qui ont été fusionnés dans ``main`` " -#~ "depuis lors :" +#~ "Go ahead and launch on a terminal" +#~ " the *run-server.sh* script first as" +#~ " follows:" +#~ msgstr "Lance sur un terminal le script *run-server.sh* d'abord comme suit :" -#~ msgid "" -#~ "`GitHub: Compare v1.2.0...main " -#~ "`_" -#~ msgstr "" -#~ "`GitHub : Compare v1.2.0...main " -#~ "`_" +#~ msgid "Now that the server is up and running, go ahead and launch the clients." +#~ msgstr "Maintenant que le serveur est opérationnel, vas-y et lance les clients." #~ msgid "" -#~ "Thank the authors who contributed since" -#~ " the last release. This command helps" -#~ " extract them: ``git log --format='%aN' " -#~ "v1.1.0..HEAD | sort -u``. The command" -#~ " has the same order as ``git " -#~ "shortlog``." +#~ "Et voilà! You should be seeing the" +#~ " training procedure and, after a few" +#~ " iterations, the test accuracy for " +#~ "each client." #~ msgstr "" -#~ "Remerciez les auteurs qui ont contribué" -#~ " depuis la dernière version. Cette " -#~ "commande permet de les extraire : " -#~ "``git log --format='%aN' v1.1.0..HEAD | " -#~ "sort -u``. La commande a le même" -#~ " ordre que ``git shortlog``." +#~ "Et voilà ! Tu devrais voir la " +#~ "procédure d'entraînement et, après quelques" +#~ " itérations, la précision du test " +#~ "pour chaque client." -#~ msgid "" -#~ "Update the ``changelog.md`` section header " -#~ "``Unreleased`` to contain the version " -#~ "number and date for the release " -#~ "you are building. Create a pull " -#~ "request with the change." -#~ msgstr "" -#~ "Mettez à jour l'en-tête de section" -#~ " ``changelog.md`` ``Unreleased`` pour qu'il " -#~ "contienne le numéro de version et " -#~ "la date de la version que vous " -#~ "construisez. Créez une demande de " -#~ "traction avec le changement." +#~ msgid "Now, let's see what is really happening inside." +#~ msgstr "Maintenant, voyons ce qui se passe réellement à l'intérieur." #~ msgid "" -#~ "Tag the release commit with the " -#~ "version number as soon as the PR" -#~ " is merged: ``git tag v0.12.3``, then" -#~ " ``git push --tags``" +#~ "Inside the server helper script *run-" +#~ "server.sh* you will find the following" +#~ " code that basically runs the " +#~ ":code:`server.py`" #~ msgstr "" -#~ "Marquez le commit de la version " -#~ "avec le numéro de version dès que" -#~ " le PR est fusionné : ``git tag" -#~ " v0.12.3``, puis ``git push --tags``" +#~ "Dans le script d'aide au serveur " +#~ "*run-server.sh*, tu trouveras le code " +#~ "suivant qui exécute le fichier " +#~ ":code:`server.py`" #~ msgid "" -#~ "Build the release with ``./dev/build.sh``, " -#~ "then publish it with ``./dev/publish.sh``" +#~ "We can go a bit deeper and " +#~ "see that :code:`server.py` simply launches " +#~ "a server that will coordinate three " +#~ "rounds of training. Flower Servers are" +#~ " very customizable, but for simple " +#~ "workloads, we can start a server " +#~ "using the :ref:`start_server ` function and leave " +#~ "all the configuration possibilities at " +#~ "their default values, as seen below." #~ msgstr "" -#~ "Construisez la version avec " -#~ "``./dev/build.sh``, puis publiez-la avec " -#~ "``./dev/publish.sh``" +#~ "Nous pouvons aller un peu plus " +#~ "loin et voir que :code:`server.py` lance" +#~ " simplement un serveur qui coordonnera " +#~ "trois tours de formation. Flower Les " +#~ "serveurs sont très personnalisables, mais " +#~ "pour les charges de travail simples, " +#~ "nous pouvons démarrer un serveur à " +#~ "l'aide de la fonction :ref:`start_server " +#~ "` et " +#~ "laisser toutes les possibilités de " +#~ "configuration à leurs valeurs par " +#~ "défaut, comme on peut le voir " +#~ "ci-dessous." #~ msgid "" -#~ "Create an entry in GitHub releases " -#~ "with the release notes for the " -#~ "previously tagged commit and attach the" -#~ " build artifacts (:code:`.whl` and " -#~ ":code:`.tar.gz`)." +#~ "Next, let's take a look at the " +#~ "*run-clients.sh* file. You will see " +#~ "that it contains the main loop " +#~ "that starts a set of *clients*." #~ msgstr "" -#~ "Crée une entrée dans GitHub releases " -#~ "avec les notes de version pour le" -#~ " commit précédemment étiqueté et attache" -#~ " les artefacts de construction " -#~ "(:code:`.whl` et :code:`.tar.gz`)." +#~ "Ensuite, jetons un coup d'œil au " +#~ "fichier *run-clients.sh*. Tu verras " +#~ "qu'il contient la boucle principale qui" +#~ " démarre un ensemble de *clients*." #~ msgid "" -#~ "Second, create a virtual environment " -#~ "(and activate it). If you chose to" -#~ " use :code:`pyenv` (with the :code" -#~ ":`pyenv-virtualenv` plugin) and already " -#~ "have it installed , you can use" -#~ " the following convenience script (by " -#~ "default it will use :code:`Python " -#~ "3.8.17`, but you can change it by" -#~ " providing a specific :code:``)::" +#~ "**cid**: is the client ID. It is" +#~ " an integer that uniquely identifies " +#~ "client identifier." #~ msgstr "" -#~ "Deuxièmement, créer un environnement virtuel" -#~ " (et l'activer). Si vous choisissez " -#~ "d'utiliser :code:`pyenv` (avec le plugin " -#~ ":code:`pyenv-virtualenv`) et que vous " -#~ "l'avez déjà installé, vous pouvez " -#~ "utiliser le script suivant (par défaut" -#~ " il utilisera :code:`Python 3.8.17`, mais" -#~ " vous pouvez le changer en " -#~ "fournissant une :code:`` spécifique)::" - -#~ msgid "server.strategy.FedAvg" -#~ msgstr "serveur.stratégie.FedAvg" - -#~ msgid "server.strategy.FedAvgM" -#~ msgstr "stratégie.serveur.FedAvgM" - -#~ msgid "server.strategy.QFedAvg" -#~ msgstr "server.strategy.QFedAvg" - -#~ msgid "server.strategy.FedOpt" -#~ msgstr "serveur.stratégie.FedOpt" - -#~ msgid "server.strategy.FedProx" -#~ msgstr "serveur.stratégie.FedProx" - -#~ msgid "server.strategy.FedAdagrad" -#~ msgstr "serveur.stratégie.FedAdagrad" +#~ "**cid** : c'est l'identifiant du client." +#~ " C'est un nombre entier qui identifie" +#~ " de façon unique l'identifiant du " +#~ "client." -#~ msgid "server.strategy.FedAdam" -#~ msgstr "serveur.stratégie.FedAdam" +#~ msgid "**sever_address**: String that identifies IP and port of the server." +#~ msgstr "**sever_address** : Chaîne qui identifie l'IP et le port du serveur." -#~ msgid "server.strategy.FedYogi" -#~ msgstr "serveur.stratégie.FedYogi" +#~ msgid "" +#~ "**nb_clients**: This defines the number " +#~ "of clients being created. This piece " +#~ "of information is not required by " +#~ "the client, but it helps us " +#~ "partition the original MNIST dataset to" +#~ " make sure that every client is " +#~ "working on unique subsets of both " +#~ "*training* and *test* sets." +#~ msgstr "" +#~ "**Cette information n'est pas requise " +#~ "par le client, mais elle nous aide" +#~ " à partitionner l'ensemble de données " +#~ "MNIST original pour nous assurer que " +#~ "chaque client travaille sur des sous-" +#~ "ensembles uniques des ensembles *formation*" +#~ " et *test*." #~ msgid "" -#~ "`achiverram28`, `Adam Narozniak`, `Anass " -#~ "Anhari`, `Charles Beauville`, `Dana-Farber`," -#~ " `Daniel J. Beutel`, `Daniel Nata " -#~ "Nugraha`, `Edoardo Gabrielli`, `eunchung`, " -#~ "`Gustavo Bertoli`, `Heng Pan`, `Javier`, " -#~ "`Mahdi`, `Ruth Galindo`, `Steven Hé " -#~ "(Sīchàng)`, `Taner Topal`" +#~ "Again, we can go deeper and look" +#~ " inside :code:`flwr_example/quickstart-" +#~ "pytorch/client.py`. After going through the" +#~ " argument parsing code at the " +#~ "beginning of our :code:`main` function, " +#~ "you will find a call to " +#~ ":code:`mnist.load_data`. This function is " +#~ "responsible for partitioning the original " +#~ "MNIST datasets (*training* and *test*) " +#~ "and returning a :code:`torch.utils.data.DataLoader`" +#~ " s for each of them. We then" +#~ " instantiate a :code:`PytorchMNISTClient` object" +#~ " with our client ID, our DataLoaders," +#~ " the number of epochs in each " +#~ "round, and which device we want to" +#~ " use for training (CPU or GPU)." #~ msgstr "" +#~ "Encore une fois, nous pouvons aller " +#~ "plus loin et regarder dans " +#~ ":code:`flwr_example/quickstart-pytorch/client.py`. Après" +#~ " avoir parcouru le code d'analyse des" +#~ " arguments au début de notre fonction" +#~ " :code:`main`, tu trouveras un appel " +#~ "à :code:`mnist.load_data`. Cette fonction est" +#~ " responsable du partitionnement des " +#~ "ensembles de données MNIST originaux " +#~ "(*training* et *test*) et renvoie un " +#~ ":code:`torch.utils.data.DataLoader` s pour chacun" +#~ " d'entre eux. Nous instancions ensuite " +#~ "un objet :code:`PytorchMNISTClient` avec notre" +#~ " ID client, nos DataLoaders, le " +#~ "nombre d'époques dans chaque tour et " +#~ "le périphérique que nous voulons " +#~ "utiliser pour l'entraînement (CPU ou " +#~ "GPU)." #~ msgid "" -#~ "Let's now load the CIFAR-10 training " -#~ "and test set, partition them into " -#~ "ten smaller datasets (each split into" -#~ " training and validation set), and " -#~ "wrap the resulting partitions by " -#~ "creating a PyTorch ``DataLoader`` for " -#~ "each of them:" +#~ "The :code:`PytorchMNISTClient` object when " +#~ "finally passed to :code:`fl.client.start_client` " +#~ "along with the server's address as " +#~ "the training process begins." #~ msgstr "" -#~ "Chargeons maintenant l'ensemble de formation" -#~ " et de test CIFAR-10, partitionnons-" -#~ "les en dix ensembles de données " -#~ "plus petits (chacun divisé en ensemble" -#~ " de formation et de validation), et" -#~ " enveloppons les partitions résultantes en" -#~ " créant un PyTorch ``DataLoader`` pour " -#~ "chacun d'entre eux :" +#~ "L'objet :code:`PytorchMNISTClient` est finalement" +#~ " transmis à :code:`fl.client.start_client` avec" +#~ " l'adresse du serveur lorsque le " +#~ "processus de formation commence." + +#~ msgid "A Closer Look" +#~ msgstr "Regarder de plus près" #~ msgid "" -#~ "Let's build a horizontal federated " -#~ "learning system using XGBoost and " -#~ "Flower!" +#~ "Now, let's look closely into the " +#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" +#~ ".quickstart-pytorch.mnist` and see what it" +#~ " is doing:" #~ msgstr "" -#~ "Construisons un système d'apprentissage fédéré" -#~ " horizontal en utilisant XGBoost et " -#~ "Flower !" +#~ "Maintenant, examinons de près le " +#~ ":code:`PytorchMNISTClient` à l'intérieur du " +#~ ":code:`flwr_example.quickstart-pytorch.mnist` et " +#~ "voyons ce qu'il fait :" #~ msgid "" -#~ "Please refer to the `full code " -#~ "example `_ to learn " -#~ "more." +#~ "The first thing to notice is that" +#~ " :code:`PytorchMNISTClient` instantiates a CNN" +#~ " model inside its constructor" #~ msgstr "" -#~ "Réfère-toi à l'exemple de code " -#~ "complet `_ pour en " -#~ "savoir plus." +#~ "La première chose à remarquer est " +#~ "que :code:`PytorchMNISTClient` instancie un " +#~ "modèle CNN dans son constructeur" -#~ msgid "|3ff4c820a01d4a5abb022617de537c54|" +#~ msgid "" +#~ "The code for the CNN is available" +#~ " under :code:`quickstart-pytorch.mnist` and " +#~ "it is reproduced below. It is the" +#~ " same network found in `Basic MNIST" +#~ " Example " +#~ "`_." #~ msgstr "" +#~ "Le code du CNN est disponible sous" +#~ " :code:`quickstart-pytorch.mnist` et il est" +#~ " reproduit ci-dessous. Il s'agit du" +#~ " même réseau que celui que l'on " +#~ "trouve dans `Exemple basique de MNIST" +#~ " `_." -#~ msgid "|7f1889391ad448e2a65920165f0d798c|" +#~ msgid "" +#~ "The second thing to notice is that" +#~ " :code:`PytorchMNISTClient` class inherits from" +#~ " the :code:`fl.client.Client`, and hence it" +#~ " must implement the following methods:" #~ msgstr "" +#~ "La deuxième chose à noter est que" +#~ " la classe :code:`PytorchMNISTClient` hérite " +#~ "de :code:`fl.client.Client`, et qu'elle doit" +#~ " donc implémenter les méthodes suivantes" +#~ " :" -#~ msgid "|a171dc4a0d044e70b5d585cc10ace0e0|" +#~ msgid "" +#~ "When comparing the abstract class to " +#~ "its derived class :code:`PytorchMNISTClient` " +#~ "you will notice that :code:`fit` calls" +#~ " a :code:`train` function and that " +#~ ":code:`evaluate` calls a :code:`test`: " +#~ "function." #~ msgstr "" +#~ "En comparant la classe abstraite à " +#~ "sa classe dérivée :code:`PytorchMNISTClient`, " +#~ "tu remarqueras que :code:`fit` appelle " +#~ "une fonction :code:`train` et que " +#~ ":code:`evaluate` appelle une fonction " +#~ ":code:`test` :." -#~ msgid "|fe518aa0d86341f7b2fc87bd6e3bbf0c|" +#~ msgid "" +#~ "These functions can both be found " +#~ "inside the same :code:`quickstart-" +#~ "pytorch.mnist` module:" #~ msgstr "" +#~ "Ces fonctions se trouvent toutes deux" +#~ " dans le même module :code:`quickstart-" +#~ "pytorch.mnist` :" -#~ msgid "|6abfdf0dade44469ae9f08c8dc7d148c|" +#~ msgid "" +#~ "Observe that these functions encapsulate " +#~ "regular training and test loops and " +#~ "provide :code:`fit` and :code:`evaluate` with" +#~ " final statistics for each round. You" +#~ " could substitute them with your " +#~ "custom train and test loops and " +#~ "change the network architecture, and the" +#~ " entire example would still work " +#~ "flawlessly. As a matter of fact, " +#~ "why not try and modify the code" +#~ " to an example of your liking?" #~ msgstr "" +#~ "Observe que ces fonctions encapsulent " +#~ "les boucles d'entraînement et de test" +#~ " habituelles et fournissent à :code:`fit`" +#~ " et :code:`evaluate` les statistiques " +#~ "finales pour chaque tour. Tu pourrais" +#~ " les remplacer par tes boucles " +#~ "d'entraînement et de test personnalisées " +#~ "et changer l'architecture du réseau, et" +#~ " l'ensemble de l'exemple fonctionnerait " +#~ "toujours parfaitement. En fait, pourquoi " +#~ "ne pas essayer de modifier le code" +#~ " pour en faire un exemple qui " +#~ "te plairait ?" -#~ msgid "|b4f147db24bb4da9a786e1d6676a1c2d|" -#~ msgstr "" +#~ msgid "Give It a Try" +#~ msgstr "Fais un essai" -#~ msgid "|5c62032f589a457bb37b5fee5b2adbde|" +#~ msgid "" +#~ "Looking through the quickstart code " +#~ "description above will have given a " +#~ "good understanding of how *clients* and" +#~ " *servers* work in Flower, how to " +#~ "run a simple experiment, and the " +#~ "internals of a client wrapper. Here " +#~ "are a few things you could try " +#~ "on your own and get more " +#~ "experience with Flower:" #~ msgstr "" +#~ "En parcourant la description du code " +#~ "de démarrage rapide ci-dessus, tu " +#~ "auras acquis une bonne compréhension du" +#~ " fonctionnement des *clients* et des " +#~ "*serveurs* dans Flower, de l'exécution " +#~ "d'une expérience simple et de la " +#~ "structure interne d'un wrapper client. " +#~ "Voici quelques exemples que tu peux " +#~ "essayer par toi-même pour acquérir " +#~ "plus d'expérience avec Flower :" -#~ msgid "|f154df1846dd44f79a94f1dc3ae8b088|" +#~ msgid "" +#~ "Try and change :code:`PytorchMNISTClient` so" +#~ " it can accept different architectures." #~ msgstr "" +#~ "Essaie de modifier :code:`PytorchMNISTClient` " +#~ "pour qu'il puisse accepter différentes " +#~ "architectures." -#~ msgid "|9d20be8160f7451fb0f33b194506503f|" +#~ msgid "" +#~ "Modify the :code:`train` function so " +#~ "that it accepts different optimizers" #~ msgstr "" +#~ "Modifie la fonction :code:`train` pour " +#~ "qu'elle accepte différents optimiseurs" -#~ msgid "|3d949f76988443c59990d2e64f05c386|" +#~ msgid "" +#~ "Modify the :code:`test` function so that" +#~ " it proves not only the top-1 " +#~ "(regular accuracy) but also the top-5" +#~ " accuracy?" #~ msgstr "" +#~ "Modifie la fonction :code:`test` pour " +#~ "qu'elle prouve non seulement le top-1" +#~ " (précision normale) mais aussi le " +#~ "top-5 ?" -#~ msgid "|526c6d9140f6404f8a226d9056327b3b|" +#~ msgid "" +#~ "Go larger! Try to adapt the code" +#~ " to larger images and datasets. Why" +#~ " not try training on ImageNet with" +#~ " a ResNet-50?" #~ msgstr "" +#~ "Essaie d'adapter le code à des " +#~ "images et à des ensembles de " +#~ "données plus grands. Pourquoi ne pas " +#~ "essayer de s'entraîner sur ImageNet avec" +#~ " un ResNet-50 ?" -#~ msgid "|a5f6af14cd7c4550929b17f83b4f63c7|" -#~ msgstr "" +#~ msgid "You are ready now. Enjoy learning in a federated way!" +#~ msgstr "Tu es prêt maintenant. Profite de l'apprentissage de manière fédérée !" -#~ msgid "|bcd571c4f4ee4803a54f71b5c20448cb|" +#~ msgid "" +#~ "Flower provides differential privacy (DP) " +#~ "wrapper classes for the easy integration" +#~ " of the central DP guarantees " +#~ "provided by DP-FedAvg into training " +#~ "pipelines defined in any of the " +#~ "various ML frameworks that Flower is " +#~ "compatible with." #~ msgstr "" +#~ "Flower fournit des classes d'enveloppe " +#~ "de confidentialité différentielle (DP) pour" +#~ " l'intégration facile des garanties " +#~ "centrales de DP fournies par DP-" +#~ "FedAvg dans les pipelines de formation" +#~ " définis dans n'importe lequel des " +#~ "divers cadres de ML avec lesquels " +#~ "Flower est compatible." -#~ msgid "|c76452ae1ed84965be7ef23c72b95845|" +#~ msgid "" +#~ "Please note that these components are" +#~ " still experimental; the correct " +#~ "configuration of DP for a specific " +#~ "task is still an unsolved problem." #~ msgstr "" +#~ "Note que ces composants sont encore " +#~ "expérimentaux, la configuration correcte du" +#~ " DP pour une tâche spécifique est " +#~ "encore un problème non résolu." #~ msgid "" -#~ "Please follow the first section on " -#~ "`Run Flower using Docker " -#~ "`_ which covers this" -#~ " step in more detail." +#~ "The name DP-FedAvg is misleading " +#~ "since it can be applied on top " +#~ "of any FL algorithm that conforms " +#~ "to the general structure prescribed by" +#~ " the FedOpt family of algorithms." #~ msgstr "" +#~ "Le nom DP-FedAvg est trompeur car" +#~ " il peut être appliqué à n'importe" +#~ " quel algorithme FL qui se conforme" +#~ " à la structure générale prescrite " +#~ "par la famille d'algorithmes FedOpt." + +#~ msgid "DP-FedAvg" +#~ msgstr "DP-FedAvg" #~ msgid "" -#~ "Since `Flower 1.5 `_ we have " -#~ "introduced translations to our doc " -#~ "pages, but, as you might have " -#~ "noticed, the translations are often " -#~ "imperfect. If you speak languages other" -#~ " than English, you might be able " -#~ "to help us in our effort to " -#~ "make Federated Learning accessible to as" -#~ " many people as possible by " -#~ "contributing to those translations! This " -#~ "might also be a great opportunity " -#~ "for those wanting to become open " -#~ "source contributors with little prerequistes." +#~ "DP-FedAvg, originally proposed by " +#~ "McMahan et al. [mcmahan]_ and extended" +#~ " by Andrew et al. [andrew]_, is " +#~ "essentially FedAvg with the following " +#~ "modifications." #~ msgstr "" +#~ "DP-FedAvg, proposé à l'origine par " +#~ "McMahan et al. [mcmahan]_ et étendu " +#~ "par Andrew et al. [andrew]_, est " +#~ "essentiellement FedAvg avec les modifications" +#~ " suivantes." #~ msgid "" -#~ "You input your translation in the " -#~ "textbox at the top and then, once" -#~ " you are happy with it, you " -#~ "either press ``Save and continue`` (to" -#~ " save the translation and go to " -#~ "the next untranslated string), ``Save " -#~ "and stay`` (to save the translation " -#~ "and stay on the same page), " -#~ "``Suggest`` (to add your translation to" -#~ " suggestions for other users to " -#~ "view), or ``Skip`` (to go to the" -#~ " next untranslated string without saving" -#~ " anything)." +#~ "**Clipping** : The influence of each " +#~ "client's update is bounded by clipping" +#~ " it. This is achieved by enforcing" +#~ " a cap on the L2 norm of " +#~ "the update, scaling it down if " +#~ "needed." #~ msgstr "" +#~ "**Clipping** : L'influence de la mise" +#~ " à jour de chaque client est " +#~ "limitée en l'écrêtant. Ceci est réalisé" +#~ " en imposant un plafond à la " +#~ "norme L2 de la mise à jour, " +#~ "en la réduisant si nécessaire." #~ msgid "" -#~ "If the section is completely empty " -#~ "(without any token) or non-existant, " -#~ "the changelog will just contain the " -#~ "title of the PR for the changelog" -#~ " entry, without any description." +#~ "**Noising** : Gaussian noise, calibrated " +#~ "to the clipping threshold, is added " +#~ "to the average computed at the " +#~ "server." #~ msgstr "" - -#~ msgid "Example: Walk-Through PyTorch & MNIST" -#~ msgstr "Exemple : PyTorch et MNIST" +#~ "**Bruit** : un bruit gaussien, calibré" +#~ " sur le seuil d'écrêtage, est ajouté" +#~ " à la moyenne calculée au niveau " +#~ "du serveur." #~ msgid "" -#~ "In this tutorial we will learn, " -#~ "how to train a Convolutional Neural " -#~ "Network on MNIST using Flower and " -#~ "PyTorch." +#~ "The distribution of the update norm " +#~ "has been shown to vary from " +#~ "task-to-task and to evolve as " +#~ "training progresses. This variability is " +#~ "crucial in understanding its impact on" +#~ " differential privacy guarantees, emphasizing " +#~ "the need for an adaptive approach " +#~ "[andrew]_ that continuously adjusts the " +#~ "clipping threshold to track a " +#~ "prespecified quantile of the update norm" +#~ " distribution." #~ msgstr "" -#~ "Dans ce tutoriel, nous allons apprendre," -#~ " comment former un réseau neuronal " -#~ "convolutif sur MNIST en utilisant Flower" -#~ " et PyTorch." +#~ "Il a été démontré que la " +#~ "distribution de la norme de mise à" +#~ " jour varie d'une tâche à l'autre " +#~ "et évolue au fur et à mesure " +#~ "de la formation. C'est pourquoi nous " +#~ "utilisons une approche adaptative [andrew]_" +#~ " qui ajuste continuellement le seuil " +#~ "d'écrêtage pour suivre un quantile " +#~ "prédéfini de la distribution de la " +#~ "norme de mise à jour." + +#~ msgid "Simplifying Assumptions" +#~ msgstr "Simplifier les hypothèses" #~ msgid "" -#~ "Since we want to use PyTorch to" -#~ " solve a computer vision task, let's" -#~ " go ahead an install PyTorch and " -#~ "the **torchvision** library:" +#~ "We make (and attempt to enforce) a" +#~ " number of assumptions that must be" +#~ " satisfied to ensure that the " +#~ "training process actually realizes the " +#~ ":math:`(\\epsilon, \\delta)` guarantees the " +#~ "user has in mind when configuring " +#~ "the setup." #~ msgstr "" -#~ "Puisque nous voulons utiliser PyTorch " -#~ "pour résoudre une tâche de vision " -#~ "par ordinateur, installons PyTorch et la" -#~ " bibliothèque **torchvision** :" +#~ "Nous formulons (et tentons d'appliquer) " +#~ "un certain nombre d'hypothèses qui " +#~ "doivent être satisfaites pour que le " +#~ "processus de formation réalise réellement " +#~ "les garanties :math:`(\\epsilon, \\delta)` que" +#~ " l'utilisateur a à l'esprit lorsqu'il " +#~ "configure l'installation." -#~ msgid "Ready... Set... Train!" -#~ msgstr "Prêts... prêts... entraînez-vous !" +#~ msgid "" +#~ "**Fixed-size subsampling** :Fixed-size " +#~ "subsamples of the clients must be " +#~ "taken at each round, as opposed to" +#~ " variable-sized Poisson subsamples." +#~ msgstr "" +#~ "**Sous-échantillonnage de taille fixe** " +#~ ":Des sous-échantillons de taille fixe" +#~ " des clients doivent être prélevés à" +#~ " chaque tour, par opposition aux " +#~ "sous-échantillons de Poisson de taille " +#~ "variable." #~ msgid "" -#~ "Now that we have all our " -#~ "dependencies installed, let's run a " -#~ "simple distributed training with two " -#~ "clients and one server. Our training " -#~ "procedure and network architecture are " -#~ "based on PyTorch's `Basic MNIST Example" -#~ " `_. " -#~ "This will allow you see how easy" -#~ " it is to wrap your code with" -#~ " Flower and begin training in a " -#~ "federated way. We provide you with " -#~ "two helper scripts, namely *run-" -#~ "server.sh*, and *run-clients.sh*. Don't " -#~ "be afraid to look inside, they are" -#~ " simple enough =)." +#~ "**Unweighted averaging** : The contributions" +#~ " from all the clients must weighted" +#~ " equally in the aggregate to " +#~ "eliminate the requirement for the server" +#~ " to know in advance the sum of" +#~ " the weights of all clients available" +#~ " for selection." #~ msgstr "" -#~ "Maintenant que nous avons installé " -#~ "toutes nos dépendances, lançons un " -#~ "simple entraînement distribué avec deux " -#~ "clients et un serveur. Notre procédure" -#~ " d'entraînement et l'architecture de notre" -#~ " réseau sont basées sur l'exemple " -#~ "MNIST de base de PyTorch " -#~ "`_. Cela" -#~ " te permettra de voir à quel " -#~ "point il est facile d'envelopper ton " -#~ "code avec Flower et de commencer " -#~ "l'entraînement de manière fédérée. Nous " -#~ "te fournissons deux scripts d'aide, à" -#~ " savoir *run-server.sh*, et *run-" -#~ "clients.sh*. N'aie pas peur de regarder" -#~ " à l'intérieur, ils sont assez " -#~ "simples =)." +#~ "**Moyenne non pondérée** : Les " +#~ "contributions de tous les clients " +#~ "doivent être pondérées de façon égale" +#~ " dans l'ensemble afin que le serveur" +#~ " n'ait pas à connaître à l'avance " +#~ "la somme des poids de tous les " +#~ "clients disponibles pour la sélection." #~ msgid "" -#~ "Go ahead and launch on a terminal" -#~ " the *run-server.sh* script first as" -#~ " follows:" -#~ msgstr "Lance sur un terminal le script *run-server.sh* d'abord comme suit :" +#~ "**No client failures** : The set " +#~ "of available clients must stay constant" +#~ " across all rounds of training. In" +#~ " other words, clients cannot drop out" +#~ " or fail." +#~ msgstr "" +#~ "**Aucune défaillance de client** : " +#~ "L'ensemble des clients disponibles doit " +#~ "rester constant pendant toutes les " +#~ "séries de formation. En d'autres termes," +#~ " les clients ne peuvent pas " +#~ "abandonner ou échouer." -#~ msgid "Now that the server is up and running, go ahead and launch the clients." -#~ msgstr "Maintenant que le serveur est opérationnel, vas-y et lance les clients." +#~ msgid "" +#~ "The first two are useful for " +#~ "eliminating a multitude of complications " +#~ "associated with calibrating the noise to" +#~ " the clipping threshold, while the " +#~ "third one is required to comply " +#~ "with the assumptions of the privacy " +#~ "analysis." +#~ msgstr "" +#~ "Les deux premiers sont utiles pour " +#~ "éliminer une multitude de complications " +#~ "liées au calibrage du bruit en " +#~ "fonction du seuil d'écrêtage, tandis que" +#~ " le troisième est nécessaire pour se" +#~ " conformer aux hypothèses de l'analyse " +#~ "de la vie privée." #~ msgid "" -#~ "Et voilà! You should be seeing the" -#~ " training procedure and, after a few" -#~ " iterations, the test accuracy for " -#~ "each client." +#~ "These restrictions are in line with " +#~ "constraints imposed by Andrew et al. " +#~ "[andrew]_." #~ msgstr "" -#~ "Et voilà ! Tu devrais voir la " -#~ "procédure d'entraînement et, après quelques" -#~ " itérations, la précision du test " -#~ "pour chaque client." +#~ "Ces restrictions sont conformes aux " +#~ "contraintes imposées par Andrew et al." +#~ " [andrew]_." -#~ msgid "Now, let's see what is really happening inside." -#~ msgstr "Maintenant, voyons ce qui se passe réellement à l'intérieur." +#~ msgid "Customizable Responsibility for Noise injection" +#~ msgstr "Responsabilité personnalisable pour l'injection de bruit" #~ msgid "" -#~ "Inside the server helper script *run-" -#~ "server.sh* you will find the following" -#~ " code that basically runs the " -#~ ":code:`server.py`" +#~ "In contrast to other implementations " +#~ "where the addition of noise is " +#~ "performed at the server, you can " +#~ "configure the site of noise injection" +#~ " to better match your threat model." +#~ " We provide users with the " +#~ "flexibility to set up the training " +#~ "such that each client independently adds" +#~ " a small amount of noise to the" +#~ " clipped update, with the result that" +#~ " simply aggregating the noisy updates " +#~ "is equivalent to the explicit addition" +#~ " of noise to the non-noisy " +#~ "aggregate at the server." #~ msgstr "" -#~ "Dans le script d'aide au serveur " -#~ "*run-server.sh*, tu trouveras le code " -#~ "suivant qui exécute le fichier " -#~ ":code:`server.py`" +#~ "Contrairement à d'autres implémentations où" +#~ " l'ajout de bruit est effectué au " +#~ "niveau du serveur, tu peux configurer" +#~ " le site d'injection de bruit pour" +#~ " qu'il corresponde mieux à ton modèle" +#~ " de menace. Nous offrons aux " +#~ "utilisateurs la possibilité de configurer " +#~ "l'entraînement de telle sorte que chaque" +#~ " client ajoute indépendamment une petite" +#~ " quantité de bruit à la mise à" +#~ " jour écrêtée, ce qui fait que " +#~ "le simple fait d'agréger les mises " +#~ "à jour bruyantes équivaut à l'ajout " +#~ "explicite de bruit à l'agrégat non " +#~ "bruyant au niveau du serveur." #~ msgid "" -#~ "We can go a bit deeper and " -#~ "see that :code:`server.py` simply launches " -#~ "a server that will coordinate three " -#~ "rounds of training. Flower Servers are" -#~ " very customizable, but for simple " -#~ "workloads, we can start a server " -#~ "using the :ref:`start_server ` function and leave " -#~ "all the configuration possibilities at " -#~ "their default values, as seen below." -#~ msgstr "" -#~ "Nous pouvons aller un peu plus " -#~ "loin et voir que :code:`server.py` lance" -#~ " simplement un serveur qui coordonnera " -#~ "trois tours de formation. Flower Les " -#~ "serveurs sont très personnalisables, mais " -#~ "pour les charges de travail simples, " -#~ "nous pouvons démarrer un serveur à " -#~ "l'aide de la fonction :ref:`start_server " -#~ "` et " -#~ "laisser toutes les possibilités de " -#~ "configuration à leurs valeurs par " -#~ "défaut, comme on peut le voir " -#~ "ci-dessous." +#~ "To be precise, if we let :math:`m`" +#~ " be the number of clients sampled " +#~ "each round and :math:`\\sigma_\\Delta` be " +#~ "the scale of the total Gaussian " +#~ "noise that needs to be added to" +#~ " the sum of the model updates, " +#~ "we can use simple maths to show" +#~ " that this is equivalent to each " +#~ "client adding noise with scale " +#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ msgstr "" +#~ "Pour être précis, si nous laissons " +#~ ":math:`m` être le nombre de clients " +#~ "échantillonnés à chaque tour et " +#~ ":math:\\sigma_\\Delta` être l'échelle du bruit" +#~ " gaussien total qui doit être ajouté" +#~ " à la somme des mises à jour" +#~ " du modèle, nous pouvons utiliser des" +#~ " mathématiques simples pour montrer que " +#~ "cela équivaut à ce que chaque " +#~ "client ajoute du bruit avec l'échelle" +#~ " :math:\\sigma_\\Delta/\\sqrt{m}`." + +#~ msgid "Wrapper-based approach" +#~ msgstr "Approche basée sur l'enveloppe" #~ msgid "" -#~ "Next, let's take a look at the " -#~ "*run-clients.sh* file. You will see " -#~ "that it contains the main loop " -#~ "that starts a set of *clients*." +#~ "Introducing DP to an existing workload" +#~ " can be thought of as adding an" +#~ " extra layer of security around it." +#~ " This inspired us to provide the " +#~ "additional server and client-side logic" +#~ " needed to make the training process" +#~ " differentially private as wrappers for " +#~ "instances of the :code:`Strategy` and " +#~ ":code:`NumPyClient` abstract classes respectively." +#~ " This wrapper-based approach has the" +#~ " advantage of being easily composable " +#~ "with other wrappers that someone might" +#~ " contribute to the Flower library in" +#~ " the future, e.g., for secure " +#~ "aggregation. Using Inheritance instead can " +#~ "be tedious because that would require" +#~ " the creation of new sub- classes " +#~ "every time a new class implementing " +#~ ":code:`Strategy` or :code:`NumPyClient` is " +#~ "defined." #~ msgstr "" -#~ "Ensuite, jetons un coup d'œil au " -#~ "fichier *run-clients.sh*. Tu verras " -#~ "qu'il contient la boucle principale qui" -#~ " démarre un ensemble de *clients*." +#~ "L'introduction du DP dans une charge " +#~ "de travail existante peut être " +#~ "considérée comme l'ajout d'une couche de" +#~ " sécurité supplémentaire autour d'elle. " +#~ "Cela nous a incités à fournir la" +#~ " logique supplémentaire côté serveur et " +#~ "côté client nécessaire pour rendre le" +#~ " processus de formation différentiellement " +#~ "privé en tant qu'enveloppes pour les " +#~ "instances des classes abstraites " +#~ ":code:`Strategy` et :code:`NumPyClient` " +#~ "respectivement. Cette approche basée sur " +#~ "l'enveloppe a l'avantage d'être facilement " +#~ "composable avec d'autres enveloppes que " +#~ "quelqu'un pourrait contribuer à la " +#~ "bibliothèque Flower à l'avenir, par " +#~ "exemple, pour l'agrégation sécurisée. " +#~ "L'utilisation de l'héritage à la place" +#~ " peut être fastidieuse car cela " +#~ "nécessiterait la création de nouvelles " +#~ "sous-classes chaque fois qu'une nouvelle" +#~ " classe mettant en œuvre :code:`Strategy`" +#~ " ou :code:`NumPyClient` est définie." #~ msgid "" -#~ "**cid**: is the client ID. It is" -#~ " an integer that uniquely identifies " -#~ "client identifier." +#~ "The first version of our solution " +#~ "was to define a decorator whose " +#~ "constructor accepted, among other things, " +#~ "a boolean-valued variable indicating " +#~ "whether adaptive clipping was to be " +#~ "enabled or not. We quickly realized " +#~ "that this would clutter its " +#~ ":code:`__init__()` function with variables " +#~ "corresponding to hyperparameters of adaptive" +#~ " clipping that would remain unused " +#~ "when it was disabled. A cleaner " +#~ "implementation could be achieved by " +#~ "splitting the functionality into two " +#~ "decorators, :code:`DPFedAvgFixed` and " +#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" +#~ " classing the former. The constructors " +#~ "for both classes accept a boolean " +#~ "parameter :code:`server_side_noising`, which, as " +#~ "the name suggests, determines where " +#~ "noising is to be performed." #~ msgstr "" -#~ "**cid** : c'est l'identifiant du client." -#~ " C'est un nombre entier qui identifie" -#~ " de façon unique l'identifiant du " -#~ "client." +#~ "La première version de notre solution" +#~ " consistait à définir un décorateur " +#~ "dont le constructeur acceptait, entre " +#~ "autres, une variable à valeur booléenne" +#~ " indiquant si l'écrêtage adaptatif devait" +#~ " être activé ou non. Nous nous " +#~ "sommes rapidement rendu compte que cela" +#~ " encombrerait sa fonction :code:`__init__()` " +#~ "avec des variables correspondant aux " +#~ "hyperparamètres de l'écrêtage adaptatif qui" +#~ " resteraient inutilisées lorsque celui-ci" +#~ " était désactivé. Une implémentation plus" +#~ " propre pourrait être obtenue en " +#~ "divisant la fonctionnalité en deux " +#~ "décorateurs, :code:`DPFedAvgFixed` et " +#~ ":code:`DPFedAvgAdaptive`, le second sous-" +#~ "classant le premier. Les constructeurs " +#~ "des deux classes acceptent un paramètre" +#~ " booléen :code:`server_side_noising` qui, comme" +#~ " son nom l'indique, détermine l'endroit " +#~ "où le noising doit être effectué." -#~ msgid "**sever_address**: String that identifies IP and port of the server." -#~ msgstr "**sever_address** : Chaîne qui identifie l'IP et le port du serveur." +#~ msgid "" +#~ "The server-side capabilities required " +#~ "for the original version of DP-" +#~ "FedAvg, i.e., the one which performed" +#~ " fixed clipping, can be completely " +#~ "captured with the help of wrapper " +#~ "logic for just the following two " +#~ "methods of the :code:`Strategy` abstract " +#~ "class." +#~ msgstr "" +#~ "Les capacités côté serveur requises pour" +#~ " la version originale de DP-FedAvg," +#~ " c'est-à-dire celle qui effectue un " +#~ "écrêtage fixe, peuvent être entièrement " +#~ "capturées à l'aide d'une logique " +#~ "d'enveloppement pour les deux méthodes " +#~ "suivantes de la classe abstraite " +#~ ":code:`Strategy`." #~ msgid "" -#~ "**nb_clients**: This defines the number " -#~ "of clients being created. This piece " -#~ "of information is not required by " -#~ "the client, but it helps us " -#~ "partition the original MNIST dataset to" -#~ " make sure that every client is " -#~ "working on unique subsets of both " -#~ "*training* and *test* sets." +#~ ":code:`configure_fit()` : The config " +#~ "dictionary being sent by the wrapped " +#~ ":code:`Strategy` to each client needs to" +#~ " be augmented with an additional " +#~ "value equal to the clipping threshold" +#~ " (keyed under :code:`dpfedavg_clip_norm`) and," +#~ " if :code:`server_side_noising=true`, another one" +#~ " equal to the scale of the " +#~ "Gaussian noise that needs to be " +#~ "added at the client (keyed under " +#~ ":code:`dpfedavg_noise_stddev`). This entails " +#~ "*post*-processing of the results returned " +#~ "by the wrappee's implementation of " +#~ ":code:`configure_fit()`." #~ msgstr "" -#~ "**Cette information n'est pas requise " -#~ "par le client, mais elle nous aide" -#~ " à partitionner l'ensemble de données " -#~ "MNIST original pour nous assurer que " -#~ "chaque client travaille sur des sous-" -#~ "ensembles uniques des ensembles *formation*" -#~ " et *test*." +#~ ":code:`configure_fit()` : Le dictionnaire de" +#~ " configuration envoyé par la " +#~ ":code:`Strategy` enveloppée à chaque client" +#~ " doit être augmenté d'une valeur " +#~ "supplémentaire égale au seuil d'écrêtage " +#~ "(indiqué sous :code:`dpfedavg_clip_norm`) et, " +#~ "si :code:`server_side_noising=true`, d'une autre " +#~ "égale à l'échelle du bruit gaussien " +#~ "qui doit être ajouté au client " +#~ "(indiqué sous :code:`dpfedavg_noise_stddev`)." #~ msgid "" -#~ "Again, we can go deeper and look" -#~ " inside :code:`flwr_example/quickstart-" -#~ "pytorch/client.py`. After going through the" -#~ " argument parsing code at the " -#~ "beginning of our :code:`main` function, " -#~ "you will find a call to " -#~ ":code:`mnist.load_data`. This function is " -#~ "responsible for partitioning the original " -#~ "MNIST datasets (*training* and *test*) " -#~ "and returning a :code:`torch.utils.data.DataLoader`" -#~ " s for each of them. We then" -#~ " instantiate a :code:`PytorchMNISTClient` object" -#~ " with our client ID, our DataLoaders," -#~ " the number of epochs in each " -#~ "round, and which device we want to" -#~ " use for training (CPU or GPU)." +#~ ":code:`aggregate_fit()`: We check whether any" +#~ " of the sampled clients dropped out" +#~ " or failed to upload an update " +#~ "before the round timed out. In " +#~ "that case, we need to abort the" +#~ " current round, discarding any successful" +#~ " updates that were received, and move" +#~ " on to the next one. On the " +#~ "other hand, if all clients responded " +#~ "successfully, we must force the " +#~ "averaging of the updates to happen " +#~ "in an unweighted manner by intercepting" +#~ " the :code:`parameters` field of " +#~ ":code:`FitRes` for each received update " +#~ "and setting it to 1. Furthermore, " +#~ "if :code:`server_side_noising=true`, each update " +#~ "is perturbed with an amount of " +#~ "noise equal to what it would have" +#~ " been subjected to had client-side" +#~ " noising being enabled. This entails " +#~ "*pre*-processing of the arguments to " +#~ "this method before passing them on " +#~ "to the wrappee's implementation of " +#~ ":code:`aggregate_fit()`." #~ msgstr "" -#~ "Encore une fois, nous pouvons aller " -#~ "plus loin et regarder dans " -#~ ":code:`flwr_example/quickstart-pytorch/client.py`. Après" -#~ " avoir parcouru le code d'analyse des" -#~ " arguments au début de notre fonction" -#~ " :code:`main`, tu trouveras un appel " -#~ "à :code:`mnist.load_data`. Cette fonction est" -#~ " responsable du partitionnement des " -#~ "ensembles de données MNIST originaux " -#~ "(*training* et *test*) et renvoie un " -#~ ":code:`torch.utils.data.DataLoader` s pour chacun" -#~ " d'entre eux. Nous instancions ensuite " -#~ "un objet :code:`PytorchMNISTClient` avec notre" -#~ " ID client, nos DataLoaders, le " -#~ "nombre d'époques dans chaque tour et " -#~ "le périphérique que nous voulons " -#~ "utiliser pour l'entraînement (CPU ou " -#~ "GPU)." +#~ ":code:`aggregate_fit()`: We check whether any" +#~ " of the sampled clients dropped out" +#~ " or failed to upload an update " +#~ "before the round timed out. In " +#~ "that case, we need to abort the" +#~ " current round, discarding any successful" +#~ " updates that were received, and move" +#~ " on to the next one. On the " +#~ "other hand, if all clients responded " +#~ "successfully, we must force the " +#~ "averaging of the updates to happen " +#~ "in an unweighted manner by intercepting" +#~ " the :code:`parameters` field of " +#~ ":code:`FitRes` for each received update " +#~ "and setting it to 1. Furthermore, " +#~ "if :code:`server_side_noising=true`, each update " +#~ "is perturbed with an amount of " +#~ "noise equal to what it would have" +#~ " been subjected to had client-side" +#~ " noising being enabled. This entails " +#~ "*pre*-processing of the arguments to " +#~ "this method before passing them on " +#~ "to the wrappee's implementation of " +#~ ":code:`aggregate_fit()`." #~ msgid "" -#~ "The :code:`PytorchMNISTClient` object when " -#~ "finally passed to :code:`fl.client.start_client` " -#~ "along with the server's address as " -#~ "the training process begins." +#~ "We can't directly change the aggregation" +#~ " function of the wrapped strategy to" +#~ " force it to add noise to the" +#~ " aggregate, hence we simulate client-" +#~ "side noising to implement server-side" +#~ " noising." #~ msgstr "" -#~ "L'objet :code:`PytorchMNISTClient` est finalement" -#~ " transmis à :code:`fl.client.start_client` avec" -#~ " l'adresse du serveur lorsque le " -#~ "processus de formation commence." +#~ "Nous ne pouvons pas modifier directement" +#~ " la fonction d'agrégation de la " +#~ "stratégie enveloppée pour la forcer à" +#~ " ajouter du bruit à l'agrégat, c'est" +#~ " pourquoi nous simulons le bruit côté" +#~ " client pour mettre en œuvre le " +#~ "bruit côté serveur." -#~ msgid "A Closer Look" -#~ msgstr "Regarder de plus près" +#~ msgid "" +#~ "These changes have been put together " +#~ "into a class called :code:`DPFedAvgFixed`, " +#~ "whose constructor accepts the strategy " +#~ "being decorated, the clipping threshold " +#~ "and the number of clients sampled " +#~ "every round as compulsory arguments. The" +#~ " user is expected to specify the " +#~ "clipping threshold since the order of" +#~ " magnitude of the update norms is " +#~ "highly dependent on the model being " +#~ "trained and providing a default value" +#~ " would be misleading. The number of" +#~ " clients sampled at every round is" +#~ " required to calculate the amount of" +#~ " noise that must be added to " +#~ "each individual update, either by the" +#~ " server or the clients." +#~ msgstr "" +#~ "Ces modifications ont été regroupées " +#~ "dans une classe appelée :code:`DPFedAvgFixed`," +#~ " dont le constructeur accepte la " +#~ "stratégie décorée, le seuil d'écrêtage " +#~ "et le nombre de clients échantillonnés" +#~ " à chaque tour comme arguments " +#~ "obligatoires. L'utilisateur est censé " +#~ "spécifier le seuil d'écrêtage car " +#~ "l'ordre de grandeur des normes de " +#~ "mise à jour dépend fortement du " +#~ "modèle formé et fournir une valeur " +#~ "par défaut serait trompeur. Le nombre" +#~ " de clients échantillonnés à chaque " +#~ "tour est nécessaire pour calculer la " +#~ "quantité de bruit qui doit être " +#~ "ajoutée à chaque mise à jour " +#~ "individuelle, que ce soit par le " +#~ "serveur ou par les clients." #~ msgid "" -#~ "Now, let's look closely into the " -#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" -#~ ".quickstart-pytorch.mnist` and see what it" -#~ " is doing:" +#~ "The additional functionality required to " +#~ "facilitate adaptive clipping has been " +#~ "provided in :code:`DPFedAvgAdaptive`, a " +#~ "subclass of :code:`DPFedAvgFixed`. It " +#~ "overrides the above-mentioned methods to" +#~ " do the following." #~ msgstr "" -#~ "Maintenant, examinons de près le " -#~ ":code:`PytorchMNISTClient` à l'intérieur du " -#~ ":code:`flwr_example.quickstart-pytorch.mnist` et " -#~ "voyons ce qu'il fait :" +#~ "La fonctionnalité supplémentaire nécessaire " +#~ "pour faciliter l'écrêtage adaptatif a " +#~ "été fournie dans :code:`DPFedAvgAdaptive`, une" +#~ " sous-classe de :code:`DPFedAvgFixed`. Elle" +#~ " remplace les méthodes mentionnées ci-" +#~ "dessus pour effectuer les opérations " +#~ "suivantes." #~ msgid "" -#~ "The first thing to notice is that" -#~ " :code:`PytorchMNISTClient` instantiates a CNN" -#~ " model inside its constructor" +#~ ":code:`configure_fit()` : It intercepts the" +#~ " config dict returned by " +#~ ":code:`super.configure_fit()` to add the " +#~ "key-value pair " +#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " +#~ "which the client interprets as an " +#~ "instruction to include an indicator bit" +#~ " (1 if update norm <= clipping " +#~ "threshold, 0 otherwise) in the results" +#~ " returned by it." #~ msgstr "" -#~ "La première chose à remarquer est " -#~ "que :code:`PytorchMNISTClient` instancie un " -#~ "modèle CNN dans son constructeur" +#~ ":code:`configure_fit()` : Il intercepte le " +#~ "dict de configuration renvoyé par " +#~ ":code:`super.configure_fit()` pour y ajouter " +#~ "la paire clé-valeur " +#~ ":code:`dpfedavg_adaptive_clip_enabled:True`, que le " +#~ "client interprète comme une instruction " +#~ "d'inclure un bit indicateur (1 si " +#~ "la norme de mise à jour <= " +#~ "seuil d'écrêtage, 0 sinon) dans les " +#~ "résultats qu'il renvoie." #~ msgid "" -#~ "The code for the CNN is available" -#~ " under :code:`quickstart-pytorch.mnist` and " -#~ "it is reproduced below. It is the" -#~ " same network found in `Basic MNIST" -#~ " Example " -#~ "`_." +#~ ":code:`aggregate_fit()` : It follows a " +#~ "call to :code:`super.aggregate_fit()` with one" +#~ " to :code:`__update_clip_norm__()`, a procedure" +#~ " which adjusts the clipping threshold " +#~ "on the basis of the indicator bits" +#~ " received from the sampled clients." #~ msgstr "" -#~ "Le code du CNN est disponible sous" -#~ " :code:`quickstart-pytorch.mnist` et il est" -#~ " reproduit ci-dessous. Il s'agit du" -#~ " même réseau que celui que l'on " -#~ "trouve dans `Exemple basique de MNIST" -#~ " `_." +#~ ":code:`aggregate_fit()` : Il fait suivre " +#~ "un appel à :code:`super.aggregate_fit()` d'un" +#~ " appel à :code:`__update_clip_norm__()`, une " +#~ "procédure qui ajuste le seuil d'écrêtage" +#~ " sur la base des bits indicateurs " +#~ "reçus des clients échantillonnés." #~ msgid "" -#~ "The second thing to notice is that" -#~ " :code:`PytorchMNISTClient` class inherits from" -#~ " the :code:`fl.client.Client`, and hence it" -#~ " must implement the following methods:" +#~ "The client-side capabilities required " +#~ "can be completely captured through " +#~ "wrapper logic for just the :code:`fit()`" +#~ " method of the :code:`NumPyClient` abstract" +#~ " class. To be precise, we need " +#~ "to *post-process* the update computed" +#~ " by the wrapped client to clip " +#~ "it, if necessary, to the threshold " +#~ "value supplied by the server as " +#~ "part of the config dictionary. In " +#~ "addition to this, it may need to" +#~ " perform some extra work if either" +#~ " (or both) of the following keys " +#~ "are also present in the dict." #~ msgstr "" -#~ "La deuxième chose à noter est que" -#~ " la classe :code:`PytorchMNISTClient` hérite " -#~ "de :code:`fl.client.Client`, et qu'elle doit" -#~ " donc implémenter les méthodes suivantes" -#~ " :" +#~ "Les capacités requises côté client " +#~ "peuvent être entièrement capturées par " +#~ "une logique de wrapper pour la " +#~ "seule méthode :code:`fit()` de la classe" +#~ " abstraite :code:`NumPyClient`. Pour être " +#~ "précis, nous devons *post-traiter* la" +#~ " mise à jour calculée par le " +#~ "client wrapped pour l'écrêter, si " +#~ "nécessaire, à la valeur seuil fournie" +#~ " par le serveur dans le cadre " +#~ "du dictionnaire de configuration. En " +#~ "plus de cela, il peut avoir besoin" +#~ " d'effectuer un travail supplémentaire si" +#~ " l'une des clés suivantes (ou les " +#~ "deux) est également présente dans le " +#~ "dict." #~ msgid "" -#~ "When comparing the abstract class to " -#~ "its derived class :code:`PytorchMNISTClient` " -#~ "you will notice that :code:`fit` calls" -#~ " a :code:`train` function and that " -#~ ":code:`evaluate` calls a :code:`test`: " -#~ "function." +#~ ":code:`dpfedavg_noise_stddev` : Generate and " +#~ "add the specified amount of noise " +#~ "to the clipped update." #~ msgstr "" -#~ "En comparant la classe abstraite à " -#~ "sa classe dérivée :code:`PytorchMNISTClient`, " -#~ "tu remarqueras que :code:`fit` appelle " -#~ "une fonction :code:`train` et que " -#~ ":code:`evaluate` appelle une fonction " -#~ ":code:`test` :." +#~ ":code:`dpfedavg_noise_stddev` : Génère et " +#~ "ajoute la quantité de bruit spécifiée" +#~ " à la mise à jour de " +#~ "l'écrêtage." #~ msgid "" -#~ "These functions can both be found " -#~ "inside the same :code:`quickstart-" -#~ "pytorch.mnist` module:" +#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" +#~ " metrics dict in the :code:`FitRes` " +#~ "object being returned to the server " +#~ "with an indicator bit, calculated as " +#~ "described earlier." #~ msgstr "" -#~ "Ces fonctions se trouvent toutes deux" -#~ " dans le même module :code:`quickstart-" -#~ "pytorch.mnist` :" +#~ ":code:`dpfedavg_adaptive_clip_enabled` : Complète " +#~ "les métriques dict dans l'objet " +#~ ":code:`FitRes` renvoyé au serveur avec " +#~ "un bit indicateur, calculé comme décrit" +#~ " précédemment." + +#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" +#~ msgstr "Effectuer l'analyse :math:`(\\epsilon, \\delta)`" #~ msgid "" -#~ "Observe that these functions encapsulate " -#~ "regular training and test loops and " -#~ "provide :code:`fit` and :code:`evaluate` with" -#~ " final statistics for each round. You" -#~ " could substitute them with your " -#~ "custom train and test loops and " -#~ "change the network architecture, and the" -#~ " entire example would still work " -#~ "flawlessly. As a matter of fact, " -#~ "why not try and modify the code" -#~ " to an example of your liking?" +#~ "Assume you have trained for :math:`n`" +#~ " rounds with sampling fraction :math:`q`" +#~ " and noise multiplier :math:`z`. In " +#~ "order to calculate the :math:`\\epsilon` " +#~ "value this would result in for a" +#~ " particular :math:`\\delta`, the following " +#~ "script may be used." #~ msgstr "" -#~ "Observe que ces fonctions encapsulent " -#~ "les boucles d'entraînement et de test" -#~ " habituelles et fournissent à :code:`fit`" -#~ " et :code:`evaluate` les statistiques " -#~ "finales pour chaque tour. Tu pourrais" -#~ " les remplacer par tes boucles " -#~ "d'entraînement et de test personnalisées " -#~ "et changer l'architecture du réseau, et" -#~ " l'ensemble de l'exemple fonctionnerait " -#~ "toujours parfaitement. En fait, pourquoi " -#~ "ne pas essayer de modifier le code" -#~ " pour en faire un exemple qui " -#~ "te plairait ?" +#~ "Supposons que tu te sois entraîné " +#~ "pendant :math:`n` tours avec la fraction" +#~ " d'échantillonnage :math:`q` et le " +#~ "multiplicateur de bruit :math:`z`. Afin " +#~ "de calculer la valeur :math:`epsilon` " +#~ "qui en résulterait pour un " +#~ ":math:`\\delta` particulier, le script suivant" +#~ " peut être utilisé." -#~ msgid "Give It a Try" -#~ msgstr "Fais un essai" +#~ msgid "" +#~ "`How to run Flower using Docker " +#~ "`_" +#~ msgstr "" -#~ msgid "" -#~ "Looking through the quickstart code " -#~ "description above will have given a " -#~ "good understanding of how *clients* and" -#~ " *servers* work in Flower, how to " -#~ "run a simple experiment, and the " -#~ "internals of a client wrapper. Here " -#~ "are a few things you could try " -#~ "on your own and get more " -#~ "experience with Flower:" +#~ msgid "Enjoy building more robust and flexible ``ClientApp``s with mods!" #~ msgstr "" -#~ "En parcourant la description du code " -#~ "de démarrage rapide ci-dessus, tu " -#~ "auras acquis une bonne compréhension du" -#~ " fonctionnement des *clients* et des " -#~ "*serveurs* dans Flower, de l'exécution " -#~ "d'une expérience simple et de la " -#~ "structure interne d'un wrapper client. " -#~ "Voici quelques exemples que tu peux " -#~ "essayer par toi-même pour acquérir " -#~ "plus d'expérience avec Flower :" #~ msgid "" -#~ "Try and change :code:`PytorchMNISTClient` so" -#~ " it can accept different architectures." +#~ ":py:obj:`ClientApp `\\ " +#~ "\\(client\\_fn\\[\\, mods\\]\\)" #~ msgstr "" -#~ "Essaie de modifier :code:`PytorchMNISTClient` " -#~ "pour qu'il puisse accepter différentes " -#~ "architectures." + +#~ msgid ":py:obj:`flwr.server.driver `\\" +#~ msgstr "" + +#~ msgid "Flower driver SDK." +#~ msgstr "Serveur de Flower" + +#~ msgid "driver" +#~ msgstr "serveur" #~ msgid "" -#~ "Modify the :code:`train` function so " -#~ "that it accepts different optimizers" +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" #~ msgstr "" -#~ "Modifie la fonction :code:`train` pour " -#~ "qu'elle accepte différents optimiseurs" #~ msgid "" -#~ "Modify the :code:`test` function so that" -#~ " it proves not only the top-1 " -#~ "(regular accuracy) but also the top-5" -#~ " accuracy?" +#~ ":py:obj:`Driver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ "Modifie la fonction :code:`test` pour " -#~ "qu'elle prouve non seulement le top-1" -#~ " (précision normale) mais aussi le " -#~ "top-5 ?" #~ msgid "" -#~ "Go larger! Try to adapt the code" -#~ " to larger images and datasets. Why" -#~ " not try training on ImageNet with" -#~ " a ResNet-50?" +#~ ":py:obj:`GrpcDriver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ "Essaie d'adapter le code à des " -#~ "images et à des ensembles de " -#~ "données plus grands. Pourquoi ne pas " -#~ "essayer de s'entraîner sur ImageNet avec" -#~ " un ResNet-50 ?" -#~ msgid "You are ready now. Enjoy learning in a federated way!" -#~ msgstr "Tu es prêt maintenant. Profite de l'apprentissage de manière fédérée !" +#~ msgid "`GrpcDriver` provides access to the gRPC Driver API/service." +#~ msgstr "" + +#~ msgid ":py:obj:`get_nodes `\\ \\(\\)" +#~ msgstr "" #~ msgid "" -#~ "Flower provides differential privacy (DP) " -#~ "wrapper classes for the easy integration" -#~ " of the central DP guarantees " -#~ "provided by DP-FedAvg into training " -#~ "pipelines defined in any of the " -#~ "various ML frameworks that Flower is " -#~ "compatible with." +#~ ":py:obj:`pull_task_res " +#~ "`\\ \\(task\\_ids\\)" +#~ msgstr "" + +#~ msgid "Get task results." #~ msgstr "" -#~ "Flower fournit des classes d'enveloppe " -#~ "de confidentialité différentielle (DP) pour" -#~ " l'intégration facile des garanties " -#~ "centrales de DP fournies par DP-" -#~ "FedAvg dans les pipelines de formation" -#~ " définis dans n'importe lequel des " -#~ "divers cadres de ML avec lesquels " -#~ "Flower est compatible." #~ msgid "" -#~ "Please note that these components are" -#~ " still experimental; the correct " -#~ "configuration of DP for a specific " -#~ "task is still an unsolved problem." +#~ ":py:obj:`push_task_ins " +#~ "`\\ " +#~ "\\(task\\_ins\\_list\\)" +#~ msgstr "" + +#~ msgid "Schedule tasks." +#~ msgstr "" + +#~ msgid "GrpcDriver" +#~ msgstr "" + +#~ msgid ":py:obj:`connect `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Connect to the Driver API." #~ msgstr "" -#~ "Note que ces composants sont encore " -#~ "expérimentaux, la configuration correcte du" -#~ " DP pour une tâche spécifique est " -#~ "encore un problème non résolu." #~ msgid "" -#~ "The name DP-FedAvg is misleading " -#~ "since it can be applied on top " -#~ "of any FL algorithm that conforms " -#~ "to the general structure prescribed by" -#~ " the FedOpt family of algorithms." +#~ ":py:obj:`create_run " +#~ "`\\ \\(req\\)" #~ msgstr "" -#~ "Le nom DP-FedAvg est trompeur car" -#~ " il peut être appliqué à n'importe" -#~ " quel algorithme FL qui se conforme" -#~ " à la structure générale prescrite " -#~ "par la famille d'algorithmes FedOpt." -#~ msgid "DP-FedAvg" -#~ msgstr "DP-FedAvg" +#~ msgid "Request for run ID." +#~ msgstr "Demande pour une nouvelle Flower Baseline" #~ msgid "" -#~ "DP-FedAvg, originally proposed by " -#~ "McMahan et al. [mcmahan]_ and extended" -#~ " by Andrew et al. [andrew]_, is " -#~ "essentially FedAvg with the following " -#~ "modifications." +#~ ":py:obj:`disconnect " +#~ "`\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Disconnect from the Driver API." #~ msgstr "" -#~ "DP-FedAvg, proposé à l'origine par " -#~ "McMahan et al. [mcmahan]_ et étendu " -#~ "par Andrew et al. [andrew]_, est " -#~ "essentiellement FedAvg avec les modifications" -#~ " suivantes." #~ msgid "" -#~ "**Clipping** : The influence of each " -#~ "client's update is bounded by clipping" -#~ " it. This is achieved by enforcing" -#~ " a cap on the L2 norm of " -#~ "the update, scaling it down if " -#~ "needed." +#~ ":py:obj:`get_nodes `\\" +#~ " \\(req\\)" #~ msgstr "" -#~ "**Clipping** : L'influence de la mise" -#~ " à jour de chaque client est " -#~ "limitée en l'écrêtant. Ceci est réalisé" -#~ " en imposant un plafond à la " -#~ "norme L2 de la mise à jour, " -#~ "en la réduisant si nécessaire." + +#~ msgid "Get client IDs." +#~ msgstr "Moteur client Edge" #~ msgid "" -#~ "**Noising** : Gaussian noise, calibrated " -#~ "to the clipping threshold, is added " -#~ "to the average computed at the " -#~ "server." +#~ ":py:obj:`pull_task_res " +#~ "`\\ \\(req\\)" #~ msgstr "" -#~ "**Bruit** : un bruit gaussien, calibré" -#~ " sur le seuil d'écrêtage, est ajouté" -#~ " à la moyenne calculée au niveau " -#~ "du serveur." #~ msgid "" -#~ "The distribution of the update norm " -#~ "has been shown to vary from " -#~ "task-to-task and to evolve as " -#~ "training progresses. This variability is " -#~ "crucial in understanding its impact on" -#~ " differential privacy guarantees, emphasizing " -#~ "the need for an adaptive approach " -#~ "[andrew]_ that continuously adjusts the " -#~ "clipping threshold to track a " -#~ "prespecified quantile of the update norm" -#~ " distribution." +#~ ":py:obj:`push_task_ins " +#~ "`\\ \\(req\\)" #~ msgstr "" -#~ "Il a été démontré que la " -#~ "distribution de la norme de mise à" -#~ " jour varie d'une tâche à l'autre " -#~ "et évolue au fur et à mesure " -#~ "de la formation. C'est pourquoi nous " -#~ "utilisons une approche adaptative [andrew]_" -#~ " qui ajuste continuellement le seuil " -#~ "d'écrêtage pour suivre un quantile " -#~ "prédéfini de la distribution de la " -#~ "norme de mise à jour." -#~ msgid "Simplifying Assumptions" -#~ msgstr "Simplifier les hypothèses" +#~ msgid "" +#~ "Optionally specify the type of actor " +#~ "to use. The actor object, which " +#~ "persists throughout the simulation, will " +#~ "be the process in charge of " +#~ "running the clients' jobs (i.e. their" +#~ " `fit()` method)." +#~ msgstr "" #~ msgid "" -#~ "We make (and attempt to enforce) a" -#~ " number of assumptions that must be" -#~ " satisfied to ensure that the " -#~ "training process actually realizes the " -#~ ":math:`(\\epsilon, \\delta)` guarantees the " -#~ "user has in mind when configuring " -#~ "the setup." +#~ "Much effort went into a completely " +#~ "restructured Flower docs experience. The " +#~ "documentation on [flower.ai/docs](flower.ai/docs) is" +#~ " now divided into Flower Framework, " +#~ "Flower Baselines, Flower Android SDK, " +#~ "Flower iOS SDK, and code example " +#~ "projects." #~ msgstr "" -#~ "Nous formulons (et tentons d'appliquer) " -#~ "un certain nombre d'hypothèses qui " -#~ "doivent être satisfaites pour que le " -#~ "processus de formation réalise réellement " -#~ "les garanties :math:`(\\epsilon, \\delta)` que" -#~ " l'utilisateur a à l'esprit lorsqu'il " -#~ "configure l'installation." #~ msgid "" -#~ "**Fixed-size subsampling** :Fixed-size " -#~ "subsamples of the clients must be " -#~ "taken at each round, as opposed to" -#~ " variable-sized Poisson subsamples." +#~ "Flower usage examples used to be " +#~ "bundled with Flower in a package " +#~ "called ``flwr_example``. We are migrating " +#~ "those examples to standalone projects to" +#~ " make them easier to use. All " +#~ "new examples are based in the " +#~ "directory `examples " +#~ "`_." #~ msgstr "" -#~ "**Sous-échantillonnage de taille fixe** " -#~ ":Des sous-échantillons de taille fixe" -#~ " des clients doivent être prélevés à" -#~ " chaque tour, par opposition aux " -#~ "sous-échantillons de Poisson de taille " -#~ "variable." +#~ "Les exemples d'utilisation de Flower " +#~ "étaient auparavant regroupés avec Flower " +#~ "dans un paquet appelé ``flwr_example``. " +#~ "Nous migrons ces exemples vers des " +#~ "projets autonomes pour les rendre plus" +#~ " faciles à utiliser. Tous les " +#~ "nouveaux exemples sont basés dans le " +#~ "répertoire ``examples " +#~ "`_." + +#~ msgid "Quickstart TensorFlow/Keras" +#~ msgstr "Démarrage rapide de TensorFlow/Keras" + +#~ msgid "Legacy Examples (`flwr_example`)" +#~ msgstr "Exemples hérités (`flwr_example`)" #~ msgid "" -#~ "**Unweighted averaging** : The contributions" -#~ " from all the clients must weighted" -#~ " equally in the aggregate to " -#~ "eliminate the requirement for the server" -#~ " to know in advance the sum of" -#~ " the weights of all clients available" -#~ " for selection." +#~ "The useage examples in `flwr_example` " +#~ "are deprecated and will be removed " +#~ "in the future. New examples are " +#~ "provided as standalone projects in " +#~ "`examples `_." #~ msgstr "" -#~ "**Moyenne non pondérée** : Les " -#~ "contributions de tous les clients " -#~ "doivent être pondérées de façon égale" -#~ " dans l'ensemble afin que le serveur" -#~ " n'ait pas à connaître à l'avance " -#~ "la somme des poids de tous les " -#~ "clients disponibles pour la sélection." +#~ "Les exemples d'utilisation dans `flwr_example`" +#~ " sont obsolètes et seront supprimés à" +#~ " l'avenir. De nouveaux exemples sont " +#~ "fournis en tant que projets autonomes" +#~ " dans `examples " +#~ "`_." + +#~ msgid "Extra Dependencies" +#~ msgstr "Dépendances supplémentaires" #~ msgid "" -#~ "**No client failures** : The set " -#~ "of available clients must stay constant" -#~ " across all rounds of training. In" -#~ " other words, clients cannot drop out" -#~ " or fail." +#~ "The core Flower framework keeps a " +#~ "minimal set of dependencies. The " +#~ "examples demonstrate Flower in the " +#~ "context of different machine learning " +#~ "frameworks, so additional dependencies need" +#~ " to be installed before an example" +#~ " can be run." #~ msgstr "" -#~ "**Aucune défaillance de client** : " -#~ "L'ensemble des clients disponibles doit " -#~ "rester constant pendant toutes les " -#~ "séries de formation. En d'autres termes," -#~ " les clients ne peuvent pas " -#~ "abandonner ou échouer." +#~ "Le noyau du framework Flower conserve" +#~ " un ensemble minimal de dépendances. " +#~ "Les exemples démontrent Flower dans le" +#~ " contexte de différents frameworks " +#~ "d'apprentissage automatique, de sorte que " +#~ "des dépendances supplémentaires doivent être" +#~ " installées avant qu'un exemple puisse " +#~ "être exécuté." + +#~ msgid "For PyTorch examples::" +#~ msgstr "Pour les exemples de PyTorch: :" + +#~ msgid "For TensorFlow examples::" +#~ msgstr "Pour les exemples de TensorFlow : :" + +#~ msgid "For both PyTorch and TensorFlow examples::" +#~ msgstr "Pour les exemples PyTorch et TensorFlow: :" #~ msgid "" -#~ "The first two are useful for " -#~ "eliminating a multitude of complications " -#~ "associated with calibrating the noise to" -#~ " the clipping threshold, while the " -#~ "third one is required to comply " -#~ "with the assumptions of the privacy " -#~ "analysis." +#~ "Please consult :code:`pyproject.toml` for a" +#~ " full list of possible extras " +#~ "(section :code:`[tool.poetry.extras]`)." #~ msgstr "" -#~ "Les deux premiers sont utiles pour " -#~ "éliminer une multitude de complications " -#~ "liées au calibrage du bruit en " -#~ "fonction du seuil d'écrêtage, tandis que" -#~ " le troisième est nécessaire pour se" -#~ " conformer aux hypothèses de l'analyse " -#~ "de la vie privée." +#~ "Tu peux consulter :code:`pyproject.toml` pour" +#~ " une liste complète des extras " +#~ "possibles (section :code:`[tool.poetry.extras]`)." + +#~ msgid "PyTorch Examples" +#~ msgstr "Exemples de PyTorch" #~ msgid "" -#~ "These restrictions are in line with " -#~ "constraints imposed by Andrew et al. " -#~ "[andrew]_." +#~ "Our PyTorch examples are based on " +#~ "PyTorch 1.7. They should work with " +#~ "other releases as well. So far, we" +#~ " provide the following examples." #~ msgstr "" -#~ "Ces restrictions sont conformes aux " -#~ "contraintes imposées par Andrew et al." -#~ " [andrew]_." +#~ "Nos exemples PyTorch sont basés sur " +#~ "PyTorch 1.7. Ils devraient fonctionner " +#~ "avec d'autres versions également. Jusqu'à " +#~ "présent, nous fournissons les exemples " +#~ "suivants." -#~ msgid "Customizable Responsibility for Noise injection" -#~ msgstr "Responsabilité personnalisable pour l'injection de bruit" +#~ msgid "CIFAR-10 Image Classification" +#~ msgstr "Classification d'images CIFAR-10" #~ msgid "" -#~ "In contrast to other implementations " -#~ "where the addition of noise is " -#~ "performed at the server, you can " -#~ "configure the site of noise injection" -#~ " to better match your threat model." -#~ " We provide users with the " -#~ "flexibility to set up the training " -#~ "such that each client independently adds" -#~ " a small amount of noise to the" -#~ " clipped update, with the result that" -#~ " simply aggregating the noisy updates " -#~ "is equivalent to the explicit addition" -#~ " of noise to the non-noisy " -#~ "aggregate at the server." +#~ "`CIFAR-10 and CIFAR-100 " +#~ "`_ are " +#~ "popular RGB image datasets. The Flower" +#~ " CIFAR-10 example uses PyTorch to " +#~ "train a simple CNN classifier in a" +#~ " federated learning setup with two " +#~ "clients." #~ msgstr "" -#~ "Contrairement à d'autres implémentations où" -#~ " l'ajout de bruit est effectué au " -#~ "niveau du serveur, tu peux configurer" -#~ " le site d'injection de bruit pour" -#~ " qu'il corresponde mieux à ton modèle" -#~ " de menace. Nous offrons aux " -#~ "utilisateurs la possibilité de configurer " -#~ "l'entraînement de telle sorte que chaque" -#~ " client ajoute indépendamment une petite" -#~ " quantité de bruit à la mise à" -#~ " jour écrêtée, ce qui fait que " -#~ "le simple fait d'agréger les mises " -#~ "à jour bruyantes équivaut à l'ajout " -#~ "explicite de bruit à l'agrégat non " -#~ "bruyant au niveau du serveur." +#~ "`CIFAR-10 et CIFAR-100 " +#~ "`_ sont des" +#~ " ensembles de données d'images RVB " +#~ "populaires. L'exemple Flower CIFAR-10 utilise" +#~ " PyTorch pour former un classificateur " +#~ "CNN simple dans une configuration " +#~ "d'apprentissage fédéré avec deux clients." -#~ msgid "" -#~ "To be precise, if we let :math:`m`" -#~ " be the number of clients sampled " -#~ "each round and :math:`\\sigma_\\Delta` be " -#~ "the scale of the total Gaussian " -#~ "noise that needs to be added to" -#~ " the sum of the model updates, " -#~ "we can use simple maths to show" -#~ " that this is equivalent to each " -#~ "client adding noise with scale " -#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ msgid "First, start a Flower server:" +#~ msgstr "Tout d'abord, démarre un serveur Flower :" + +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" + +#~ msgid "Then, start the two clients in a new terminal window:" #~ msgstr "" -#~ "Pour être précis, si nous laissons " -#~ ":math:`m` être le nombre de clients " -#~ "échantillonnés à chaque tour et " -#~ ":math:\\sigma_\\Delta` être l'échelle du bruit" -#~ " gaussien total qui doit être ajouté" -#~ " à la somme des mises à jour" -#~ " du modèle, nous pouvons utiliser des" -#~ " mathématiques simples pour montrer que " -#~ "cela équivaut à ce que chaque " -#~ "client ajoute du bruit avec l'échelle" -#~ " :math:\\sigma_\\Delta/\\sqrt{m}`." +#~ "Ensuite, démarre les deux clients dans" +#~ " une nouvelle fenêtre de terminal :" -#~ msgid "Wrapper-based approach" -#~ msgstr "Approche basée sur l'enveloppe" +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" + +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." +#~ msgstr "Pour plus de détails, voir :code:`src/py/flwr_example/pytorch_cifar`." + +#~ msgid "ImageNet-2012 Image Classification" +#~ msgstr "ImageNet-2012 Classification des images" #~ msgid "" -#~ "Introducing DP to an existing workload" -#~ " can be thought of as adding an" -#~ " extra layer of security around it." -#~ " This inspired us to provide the " -#~ "additional server and client-side logic" -#~ " needed to make the training process" -#~ " differentially private as wrappers for " -#~ "instances of the :code:`Strategy` and " -#~ ":code:`NumPyClient` abstract classes respectively." -#~ " This wrapper-based approach has the" -#~ " advantage of being easily composable " -#~ "with other wrappers that someone might" -#~ " contribute to the Flower library in" -#~ " the future, e.g., for secure " -#~ "aggregation. Using Inheritance instead can " -#~ "be tedious because that would require" -#~ " the creation of new sub- classes " -#~ "every time a new class implementing " -#~ ":code:`Strategy` or :code:`NumPyClient` is " -#~ "defined." +#~ "`ImageNet-2012 `_ is " +#~ "one of the major computer vision " +#~ "datasets. The Flower ImageNet example " +#~ "uses PyTorch to train a ResNet-18 " +#~ "classifier in a federated learning setup" +#~ " with ten clients." #~ msgstr "" -#~ "L'introduction du DP dans une charge " -#~ "de travail existante peut être " -#~ "considérée comme l'ajout d'une couche de" -#~ " sécurité supplémentaire autour d'elle. " -#~ "Cela nous a incités à fournir la" -#~ " logique supplémentaire côté serveur et " -#~ "côté client nécessaire pour rendre le" -#~ " processus de formation différentiellement " -#~ "privé en tant qu'enveloppes pour les " -#~ "instances des classes abstraites " -#~ ":code:`Strategy` et :code:`NumPyClient` " -#~ "respectivement. Cette approche basée sur " -#~ "l'enveloppe a l'avantage d'être facilement " -#~ "composable avec d'autres enveloppes que " -#~ "quelqu'un pourrait contribuer à la " -#~ "bibliothèque Flower à l'avenir, par " -#~ "exemple, pour l'agrégation sécurisée. " -#~ "L'utilisation de l'héritage à la place" -#~ " peut être fastidieuse car cela " -#~ "nécessiterait la création de nouvelles " -#~ "sous-classes chaque fois qu'une nouvelle" -#~ " classe mettant en œuvre :code:`Strategy`" -#~ " ou :code:`NumPyClient` est définie." +#~ "`ImageNet-2012 `_ est " +#~ "l'un des principaux ensembles de données" +#~ " de vision par ordinateur. L'exemple " +#~ "Flower ImageNet utilise PyTorch pour " +#~ "entraîner un classificateur ResNet-18 dans " +#~ "une configuration d'apprentissage fédéré avec" +#~ " dix clients." + +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" + +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" + +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." +#~ msgstr "" +#~ "Pour plus de détails, voir " +#~ ":code:`src/py/flwr_example/pytorch_imagenet`." + +#~ msgid "TensorFlow Examples" +#~ msgstr "Exemples de TensorFlow" #~ msgid "" -#~ "The first version of our solution " -#~ "was to define a decorator whose " -#~ "constructor accepted, among other things, " -#~ "a boolean-valued variable indicating " -#~ "whether adaptive clipping was to be " -#~ "enabled or not. We quickly realized " -#~ "that this would clutter its " -#~ ":code:`__init__()` function with variables " -#~ "corresponding to hyperparameters of adaptive" -#~ " clipping that would remain unused " -#~ "when it was disabled. A cleaner " -#~ "implementation could be achieved by " -#~ "splitting the functionality into two " -#~ "decorators, :code:`DPFedAvgFixed` and " -#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" -#~ " classing the former. The constructors " -#~ "for both classes accept a boolean " -#~ "parameter :code:`server_side_noising`, which, as " -#~ "the name suggests, determines where " -#~ "noising is to be performed." +#~ "Our TensorFlow examples are based on " +#~ "TensorFlow 2.0 or newer. So far, " +#~ "we provide the following examples." #~ msgstr "" -#~ "La première version de notre solution" -#~ " consistait à définir un décorateur " -#~ "dont le constructeur acceptait, entre " -#~ "autres, une variable à valeur booléenne" -#~ " indiquant si l'écrêtage adaptatif devait" -#~ " être activé ou non. Nous nous " -#~ "sommes rapidement rendu compte que cela" -#~ " encombrerait sa fonction :code:`__init__()` " -#~ "avec des variables correspondant aux " -#~ "hyperparamètres de l'écrêtage adaptatif qui" -#~ " resteraient inutilisées lorsque celui-ci" -#~ " était désactivé. Une implémentation plus" -#~ " propre pourrait être obtenue en " -#~ "divisant la fonctionnalité en deux " -#~ "décorateurs, :code:`DPFedAvgFixed` et " -#~ ":code:`DPFedAvgAdaptive`, le second sous-" -#~ "classant le premier. Les constructeurs " -#~ "des deux classes acceptent un paramètre" -#~ " booléen :code:`server_side_noising` qui, comme" -#~ " son nom l'indique, détermine l'endroit " -#~ "où le noising doit être effectué." +#~ "Nos exemples TensorFlow sont basés sur" +#~ " TensorFlow 2.0 ou une version plus" +#~ " récente. Jusqu'à présent, nous te " +#~ "proposons les exemples suivants." + +#~ msgid "Fashion-MNIST Image Classification" +#~ msgstr "Classification d'images Fashion-MNIST" #~ msgid "" -#~ "The server-side capabilities required " -#~ "for the original version of DP-" -#~ "FedAvg, i.e., the one which performed" -#~ " fixed clipping, can be completely " -#~ "captured with the help of wrapper " -#~ "logic for just the following two " -#~ "methods of the :code:`Strategy` abstract " -#~ "class." +#~ "`Fashion-MNIST `_ is often used as " +#~ "the \"Hello, world!\" of machine " +#~ "learning. We follow this tradition and" +#~ " provide an example which samples " +#~ "random local datasets from Fashion-MNIST" +#~ " and trains a simple image " +#~ "classification model over those partitions." #~ msgstr "" -#~ "Les capacités côté serveur requises pour" -#~ " la version originale de DP-FedAvg," -#~ " c'est-à-dire celle qui effectue un " -#~ "écrêtage fixe, peuvent être entièrement " -#~ "capturées à l'aide d'une logique " -#~ "d'enveloppement pour les deux méthodes " -#~ "suivantes de la classe abstraite " -#~ ":code:`Strategy`." +#~ "nous suivons cette tradition et " +#~ "fournissons un exemple qui échantillonne " +#~ "des ensembles de données locales " +#~ "aléatoires de Fashion-MNIST et entraîne" +#~ " un modèle simple de classification " +#~ "d'images sur ces partitions." + +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" + +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" #~ msgid "" -#~ ":code:`configure_fit()` : The config " -#~ "dictionary being sent by the wrapped " -#~ ":code:`Strategy` to each client needs to" -#~ " be augmented with an additional " -#~ "value equal to the clipping threshold" -#~ " (keyed under :code:`dpfedavg_clip_norm`) and," -#~ " if :code:`server_side_noising=true`, another one" -#~ " equal to the scale of the " -#~ "Gaussian noise that needs to be " -#~ "added at the client (keyed under " -#~ ":code:`dpfedavg_noise_stddev`). This entails " -#~ "*post*-processing of the results returned " -#~ "by the wrappee's implementation of " -#~ ":code:`configure_fit()`." +#~ "For more details, see " +#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." #~ msgstr "" -#~ ":code:`configure_fit()` : Le dictionnaire de" -#~ " configuration envoyé par la " -#~ ":code:`Strategy` enveloppée à chaque client" -#~ " doit être augmenté d'une valeur " -#~ "supplémentaire égale au seuil d'écrêtage " -#~ "(indiqué sous :code:`dpfedavg_clip_norm`) et, " -#~ "si :code:`server_side_noising=true`, d'une autre " -#~ "égale à l'échelle du bruit gaussien " -#~ "qui doit être ajouté au client " -#~ "(indiqué sous :code:`dpfedavg_noise_stddev`)." +#~ "Pour plus de détails, voir " +#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." #~ msgid "" -#~ ":code:`aggregate_fit()`: We check whether any" -#~ " of the sampled clients dropped out" -#~ " or failed to upload an update " -#~ "before the round timed out. In " -#~ "that case, we need to abort the" -#~ " current round, discarding any successful" -#~ " updates that were received, and move" -#~ " on to the next one. On the " -#~ "other hand, if all clients responded " -#~ "successfully, we must force the " -#~ "averaging of the updates to happen " -#~ "in an unweighted manner by intercepting" -#~ " the :code:`parameters` field of " -#~ ":code:`FitRes` for each received update " -#~ "and setting it to 1. Furthermore, " -#~ "if :code:`server_side_noising=true`, each update " -#~ "is perturbed with an amount of " -#~ "noise equal to what it would have" -#~ " been subjected to had client-side" -#~ " noising being enabled. This entails " -#~ "*pre*-processing of the arguments to " -#~ "this method before passing them on " -#~ "to the wrappee's implementation of " -#~ ":code:`aggregate_fit()`." +#~ "MXNet is no longer maintained and " +#~ "has been moved into `Attic " +#~ "`_. As a " +#~ "result, we would encourage you to " +#~ "use other ML frameworks alongise Flower," +#~ " for example, PyTorch. This tutorial " +#~ "might be removed in future versions " +#~ "of Flower." #~ msgstr "" -#~ ":code:`aggregate_fit()`: We check whether any" -#~ " of the sampled clients dropped out" -#~ " or failed to upload an update " -#~ "before the round timed out. In " -#~ "that case, we need to abort the" -#~ " current round, discarding any successful" -#~ " updates that were received, and move" -#~ " on to the next one. On the " -#~ "other hand, if all clients responded " -#~ "successfully, we must force the " -#~ "averaging of the updates to happen " -#~ "in an unweighted manner by intercepting" -#~ " the :code:`parameters` field of " -#~ ":code:`FitRes` for each received update " -#~ "and setting it to 1. Furthermore, " -#~ "if :code:`server_side_noising=true`, each update " -#~ "is perturbed with an amount of " -#~ "noise equal to what it would have" -#~ " been subjected to had client-side" -#~ " noising being enabled. This entails " -#~ "*pre*-processing of the arguments to " -#~ "this method before passing them on " -#~ "to the wrappee's implementation of " -#~ ":code:`aggregate_fit()`." #~ msgid "" -#~ "We can't directly change the aggregation" -#~ " function of the wrapped strategy to" -#~ " force it to add noise to the" -#~ " aggregate, hence we simulate client-" -#~ "side noising to implement server-side" -#~ " noising." +#~ "Now that you have known how " +#~ "federated XGBoost work with Flower, it's" +#~ " time to run some more comprehensive" +#~ " experiments by customising the " +#~ "experimental settings. In the xgboost-" +#~ "comprehensive example (`full code " +#~ "`_), we provide more options " +#~ "to define various experimental setups, " +#~ "including aggregation strategies, data " +#~ "partitioning and centralised/distributed evaluation." +#~ " We also support `Flower simulation " +#~ "`_ making it easy to " +#~ "simulate large client cohorts in a " +#~ "resource-aware manner. Let's take a " +#~ "look!" #~ msgstr "" -#~ "Nous ne pouvons pas modifier directement" -#~ " la fonction d'agrégation de la " -#~ "stratégie enveloppée pour la forcer à" -#~ " ajouter du bruit à l'agrégat, c'est" -#~ " pourquoi nous simulons le bruit côté" -#~ " client pour mettre en œuvre le " -#~ "bruit côté serveur." -#~ msgid "" -#~ "These changes have been put together " -#~ "into a class called :code:`DPFedAvgFixed`, " -#~ "whose constructor accepts the strategy " -#~ "being decorated, the clipping threshold " -#~ "and the number of clients sampled " -#~ "every round as compulsory arguments. The" -#~ " user is expected to specify the " -#~ "clipping threshold since the order of" -#~ " magnitude of the update norms is " -#~ "highly dependent on the model being " -#~ "trained and providing a default value" -#~ " would be misleading. The number of" -#~ " clients sampled at every round is" -#~ " required to calculate the amount of" -#~ " noise that must be added to " -#~ "each individual update, either by the" -#~ " server or the clients." +#~ msgid "|31e4b1afa87c4b968327bbeafbf184d4|" +#~ msgstr "" + +#~ msgid "|c9d935b4284e4c389a33d86b33e07c0a|" +#~ msgstr "" + +#~ msgid "|00727b5faffb468f84dd1b03ded88638|" +#~ msgstr "" + +#~ msgid "|daf0cf0ff4c24fd29439af78416cf47b|" +#~ msgstr "" + +#~ msgid "|9f093007080d471d94ca90d3e9fde9b6|" +#~ msgstr "" + +#~ msgid "|46a26e6150e0479fbd3dfd655f36eb13|" +#~ msgstr "" + +#~ msgid "|3daba297595c4c7fb845d90404a6179a|" +#~ msgstr "" + +#~ msgid "|5769874fa9c4455b80b2efda850d39d7|" +#~ msgstr "" + +#~ msgid "|ba47ffb421814b0f8f9fa5719093d839|" +#~ msgstr "" + +#~ msgid "|aeac5bf79cbf497082e979834717e01b|" +#~ msgstr "" + +#~ msgid "|ce27ed4bbe95459dba016afc42486ba2|" #~ msgstr "" -#~ "Ces modifications ont été regroupées " -#~ "dans une classe appelée :code:`DPFedAvgFixed`," -#~ " dont le constructeur accepte la " -#~ "stratégie décorée, le seuil d'écrêtage " -#~ "et le nombre de clients échantillonnés" -#~ " à chaque tour comme arguments " -#~ "obligatoires. L'utilisateur est censé " -#~ "spécifier le seuil d'écrêtage car " -#~ "l'ordre de grandeur des normes de " -#~ "mise à jour dépend fortement du " -#~ "modèle formé et fournir une valeur " -#~ "par défaut serait trompeur. Le nombre" -#~ " de clients échantillonnés à chaque " -#~ "tour est nécessaire pour calculer la " -#~ "quantité de bruit qui doit être " -#~ "ajoutée à chaque mise à jour " -#~ "individuelle, que ce soit par le " -#~ "serveur ou par les clients." -#~ msgid "" -#~ "The additional functionality required to " -#~ "facilitate adaptive clipping has been " -#~ "provided in :code:`DPFedAvgAdaptive`, a " -#~ "subclass of :code:`DPFedAvgFixed`. It " -#~ "overrides the above-mentioned methods to" -#~ " do the following." +#~ msgid "|ae94a7f71dda443cbec2385751427d41|" #~ msgstr "" -#~ "La fonctionnalité supplémentaire nécessaire " -#~ "pour faciliter l'écrêtage adaptatif a " -#~ "été fournie dans :code:`DPFedAvgAdaptive`, une" -#~ " sous-classe de :code:`DPFedAvgFixed`. Elle" -#~ " remplace les méthodes mentionnées ci-" -#~ "dessus pour effectuer les opérations " -#~ "suivantes." -#~ msgid "" -#~ ":code:`configure_fit()` : It intercepts the" -#~ " config dict returned by " -#~ ":code:`super.configure_fit()` to add the " -#~ "key-value pair " -#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " -#~ "which the client interprets as an " -#~ "instruction to include an indicator bit" -#~ " (1 if update norm <= clipping " -#~ "threshold, 0 otherwise) in the results" -#~ " returned by it." +#~ msgid "|e61fce4d43d243e7bb08bdde97d81ce6|" #~ msgstr "" -#~ ":code:`configure_fit()` : Il intercepte le " -#~ "dict de configuration renvoyé par " -#~ ":code:`super.configure_fit()` pour y ajouter " -#~ "la paire clé-valeur " -#~ ":code:`dpfedavg_adaptive_clip_enabled:True`, que le " -#~ "client interprète comme une instruction " -#~ "d'inclure un bit indicateur (1 si " -#~ "la norme de mise à jour <= " -#~ "seuil d'écrêtage, 0 sinon) dans les " -#~ "résultats qu'il renvoie." -#~ msgid "" -#~ ":code:`aggregate_fit()` : It follows a " -#~ "call to :code:`super.aggregate_fit()` with one" -#~ " to :code:`__update_clip_norm__()`, a procedure" -#~ " which adjusts the clipping threshold " -#~ "on the basis of the indicator bits" -#~ " received from the sampled clients." +#~ msgid "|08cb60859b07461588fe44e55810b050|" #~ msgstr "" -#~ ":code:`aggregate_fit()` : Il fait suivre " -#~ "un appel à :code:`super.aggregate_fit()` d'un" -#~ " appel à :code:`__update_clip_norm__()`, une " -#~ "procédure qui ajuste le seuil d'écrêtage" -#~ " sur la base des bits indicateurs " -#~ "reçus des clients échantillonnés." #~ msgid "" -#~ "The client-side capabilities required " -#~ "can be completely captured through " -#~ "wrapper logic for just the :code:`fit()`" -#~ " method of the :code:`NumPyClient` abstract" -#~ " class. To be precise, we need " -#~ "to *post-process* the update computed" -#~ " by the wrapped client to clip " -#~ "it, if necessary, to the threshold " -#~ "value supplied by the server as " -#~ "part of the config dictionary. In " -#~ "addition to this, it may need to" -#~ " perform some extra work if either" -#~ " (or both) of the following keys " -#~ "are also present in the dict." +#~ "Flower provides pre-made docker images" +#~ " on `Docker Hub " +#~ "`_ that include" +#~ " all necessary dependencies for running " +#~ "the server. You can also build " +#~ "your own custom docker images from " +#~ "scratch with a different version of " +#~ "Python or Ubuntu if that is what" +#~ " you need. In this guide, we " +#~ "will explain what images exist and " +#~ "how to build them locally." #~ msgstr "" -#~ "Les capacités requises côté client " -#~ "peuvent être entièrement capturées par " -#~ "une logique de wrapper pour la " -#~ "seule méthode :code:`fit()` de la classe" -#~ " abstraite :code:`NumPyClient`. Pour être " -#~ "précis, nous devons *post-traiter* la" -#~ " mise à jour calculée par le " -#~ "client wrapped pour l'écrêter, si " -#~ "nécessaire, à la valeur seuil fournie" -#~ " par le serveur dans le cadre " -#~ "du dictionnaire de configuration. En " -#~ "plus de cela, il peut avoir besoin" -#~ " d'effectuer un travail supplémentaire si" -#~ " l'une des clés suivantes (ou les " -#~ "deux) est également présente dans le " -#~ "dict." #~ msgid "" -#~ ":code:`dpfedavg_noise_stddev` : Generate and " -#~ "add the specified amount of noise " -#~ "to the clipped update." +#~ "Currently, Flower provides two images, a" +#~ " base image and a server image. " +#~ "There will also be a client image" +#~ " soon. The base image, as the " +#~ "name suggests, contains basic dependencies " +#~ "that both the server and the " +#~ "client need. This includes system " +#~ "dependencies, Python and Python tools. " +#~ "The server image is based on the" +#~ " base image, but it additionally " +#~ "installs the Flower server using " +#~ "``pip``." #~ msgstr "" -#~ ":code:`dpfedavg_noise_stddev` : Génère et " -#~ "ajoute la quantité de bruit spécifiée" -#~ " à la mise à jour de " -#~ "l'écrêtage." #~ msgid "" -#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" -#~ " metrics dict in the :code:`FitRes` " -#~ "object being returned to the server " -#~ "with an indicator bit, calculated as " -#~ "described earlier." +#~ "Both, base and server image are " +#~ "configured via build arguments. Through " +#~ "build arguments, we can make our " +#~ "build more flexible. For example, in " +#~ "the base image, we can specify the" +#~ " version of Python to install using" +#~ " the ``PYTHON_VERSION`` build argument. " +#~ "Some of the build arguments have " +#~ "default values, others must be specified" +#~ " when building the image. All " +#~ "available build arguments for each image" +#~ " are listed in one of the " +#~ "tables below." #~ msgstr "" -#~ ":code:`dpfedavg_adaptive_clip_enabled` : Complète " -#~ "les métriques dict dans l'objet " -#~ ":code:`FitRes` renvoyé au serveur avec " -#~ "un bit indicateur, calculé comme décrit" -#~ " précédemment." -#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" -#~ msgstr "Effectuer l'analyse :math:`(\\epsilon, \\delta)`" +#~ msgid "Defaults to ``flwr/server``." +#~ msgstr "" -#~ msgid "" -#~ "Assume you have trained for :math:`n`" -#~ " rounds with sampling fraction :math:`q`" -#~ " and noise multiplier :math:`z`. In " -#~ "order to calculate the :math:`\\epsilon` " -#~ "value this would result in for a" -#~ " particular :math:`\\delta`, the following " -#~ "script may be used." +#~ msgid "``BASE_IMAGE_TAG``" +#~ msgstr "" + +#~ msgid "The image tag of the base image." +#~ msgstr "" + +#~ msgid "Defaults to ``py3.11-ubuntu22.04``." #~ msgstr "" -#~ "Supposons que tu te sois entraîné " -#~ "pendant :math:`n` tours avec la fraction" -#~ " d'échantillonnage :math:`q` et le " -#~ "multiplicateur de bruit :math:`z`. Afin " -#~ "de calculer la valeur :math:`epsilon` " -#~ "qui en résulterait pour un " -#~ ":math:`\\delta` particulier, le script suivant" -#~ " peut être utilisé." #~ msgid "" -#~ "`How to run Flower using Docker " -#~ "`_" +#~ "The following example creates a server" +#~ " image with the official Flower base" +#~ " image py3.11-ubuntu22.04 and Flower 1.7.0:" #~ msgstr "" -#~ msgid "Enjoy building more robust and flexible ``ClientApp``s with mods!" +#~ msgid "" +#~ "The name of image is ``flwr_server`` " +#~ "and the tag ``0.1.0``. Remember that " +#~ "the build arguments as well as the" +#~ " name and tag can be adapted to" +#~ " your needs. These values serve as" +#~ " examples only." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`ClientApp `\\ " -#~ "\\(client\\_fn\\[\\, mods\\]\\)" +#~ "If you want to use your own " +#~ "base image instead of the official " +#~ "Flower base image, all you need to" +#~ " do is set the ``BASE_REPOSITORY`` " +#~ "and ``BASE_IMAGE_TAG`` build arguments. The" +#~ " value of ``BASE_REPOSITORY`` must match" +#~ " the name of your image and the" +#~ " value of ``BASE_IMAGE_TAG`` must match " +#~ "the tag of your image." #~ msgstr "" -#~ msgid ":py:obj:`flwr.server.driver `\\" +#~ msgid "" +#~ "It is important to follow the " +#~ "instructions described in comments. For " +#~ "instance, in order to not break " +#~ "how our changelog system works, you " +#~ "should read the information above the" +#~ " ``Changelog entry`` section carefully. You" +#~ " can also checkout some examples and" +#~ " details in the :ref:`changelogentry` " +#~ "appendix." #~ msgstr "" -#~ msgid "Flower driver SDK." -#~ msgstr "Serveur de Flower" +#~ msgid "Open a PR (as shown above)" +#~ msgstr "Ouvre un RP (comme indiqué ci-dessus)" -#~ msgid "driver" -#~ msgstr "serveur" +#~ msgid "" +#~ "Add CI job to deploy the staging" +#~ " system when the ``main`` branch " +#~ "changes" +#~ msgstr "Add CI job to deploy the staging system when the `main` branch changes" + +#~ msgid "Changelog entry" +#~ msgstr "Changelog" #~ msgid "" -#~ ":py:obj:`start_driver `\\ " -#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" +#~ "When opening a new PR, inside its" +#~ " description, there should be a " +#~ "``Changelog entry`` header." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`Driver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" +#~ "Above this header you should see " +#~ "the following comment that explains how" +#~ " to write your changelog entry:" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`GrpcDriver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" +#~ "Inside the following 'Changelog entry' " +#~ "section, you should put the description" +#~ " of your changes that will be " +#~ "added to the changelog alongside your" +#~ " PR title." #~ msgstr "" -#~ msgid "`GrpcDriver` provides access to the gRPC Driver API/service." +#~ msgid "" +#~ "If the section is completely empty " +#~ "(without any token) or non-existent, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." #~ msgstr "" -#~ msgid ":py:obj:`get_nodes `\\ \\(\\)" +#~ msgid "" +#~ "If the section contains some text " +#~ "other than tokens, it will use it" +#~ " to add a description to the " +#~ "change." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(task\\_ids\\)" +#~ "If the section contains one of the" +#~ " following tokens it will ignore any" +#~ " other text and put the PR " +#~ "under the corresponding section of the" +#~ " changelog:" #~ msgstr "" -#~ msgid "Get task results." +#~ msgid " is for classifying a PR as a general improvement." +#~ msgstr "" + +#~ msgid " is to not add the PR to the changelog" +#~ msgstr "" + +#~ msgid " is to add a general baselines change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general examples change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general sdk change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general simulations change to the PR" +#~ msgstr "" + +#~ msgid "Note that only one token should be used." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ " -#~ "\\(task\\_ins\\_list\\)" +#~ "Its content must have a specific " +#~ "format. We will break down what " +#~ "each possibility does:" #~ msgstr "" -#~ msgid "Schedule tasks." +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains nothing or doesn't exist, " +#~ "the following text will be added " +#~ "to the changelog::" #~ msgstr "" -#~ msgid "GrpcDriver" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains a description (and no " +#~ "token), the following text will be " +#~ "added to the changelog::" #~ msgstr "" -#~ msgid ":py:obj:`connect `\\ \\(\\)" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, nothing will change" +#~ " in the changelog." #~ msgstr "" -#~ msgid "Connect to the Driver API." +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text" +#~ " will be added to the changelog::" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`create_run " -#~ "`\\ \\(req\\)" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" #~ msgstr "" -#~ msgid "Request for run ID." -#~ msgstr "Demande pour une nouvelle Flower Baseline" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "" #~ msgid "" -#~ ":py:obj:`disconnect " -#~ "`\\ \\(\\)" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text " +#~ "will be added to the changelog::" #~ msgstr "" -#~ msgid "Disconnect from the Driver API." +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`get_nodes `\\" -#~ " \\(req\\)" +#~ "Note that only one token must be" +#~ " provided, otherwise, only the first " +#~ "action (in the order listed above), " +#~ "will be performed." #~ msgstr "" -#~ msgid "Get client IDs." -#~ msgstr "Moteur client Edge" +#~ msgid "Example: MXNet - Run MXNet Federated" +#~ msgstr "Exemple : MXNet - Exécuter MXNet Federated" #~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(req\\)" +#~ "This tutorial will show you how to" +#~ " use Flower to build a federated " +#~ "version of an existing MXNet workload." +#~ " We are using MXNet to train a" +#~ " Sequential model on the MNIST " +#~ "dataset. We will structure the example" +#~ " similar to our `PyTorch - From " +#~ "Centralized To Federated " +#~ "`_ walkthrough. " +#~ "MXNet and PyTorch are very similar " +#~ "and a very good comparison between " +#~ "MXNet and PyTorch is given `here " +#~ "`_. First, " +#~ "we build a centralized training approach" +#~ " based on the `Handwritten Digit " +#~ "Recognition " +#~ "`_" +#~ " tutorial. Then, we build upon the" +#~ " centralized training code to run the" +#~ " training in a federated fashion." +#~ msgstr "" +#~ "Ce tutoriel te montrera comment utiliser" +#~ " Flower pour construire une version " +#~ "fédérée d'une charge de travail MXNet" +#~ " existante. Nous utilisons MXNet pour " +#~ "former un modèle séquentiel sur " +#~ "l'ensemble de données MNIST. Nous " +#~ "structurerons l'exemple de la même " +#~ "manière que notre présentation `PyTorch " +#~ "- De la centralisation à la " +#~ "fédération `_. " +#~ "MXNet et PyTorch sont très similaires" +#~ " et une très bonne comparaison entre" +#~ " MXNet et PyTorch est donnée ici " +#~ "`_. Tout " +#~ "d'abord, nous construisons une approche " +#~ "de formation centralisée basée sur le" +#~ " tutoriel `Handandwritten Digit Recognition " +#~ "`_." +#~ " Ensuite, nous nous basons sur le " +#~ "code de formation centralisé pour " +#~ "exécuter la formation de manière " +#~ "fédérée." + +#~ msgid "" +#~ "Before we start setting up our " +#~ "MXNet example, we install the " +#~ ":code:`mxnet` and :code:`flwr` packages:" +#~ msgstr "" +#~ "Avant de commencer à configurer notre" +#~ " exemple MXNet, nous installons les " +#~ "paquets :code:`mxnet` et :code:`flwr` :" + +#~ msgid "MNIST Training with MXNet" +#~ msgstr "Formation MNIST avec MXNet" + +#~ msgid "" +#~ "We begin with a brief description " +#~ "of the centralized training code based" +#~ " on a :code:`Sequential` model. If " +#~ "you want a more in-depth " +#~ "explanation of what's going on then " +#~ "have a look at the official `MXNet" +#~ " tutorial " +#~ "`_." +#~ msgstr "" +#~ "Nous commençons par une brève " +#~ "description du code d'entraînement centralisé" +#~ " basé sur un modèle :code:`Sequential`. " +#~ "Si tu veux une explication plus " +#~ "approfondie de ce qui se passe, " +#~ "jette un coup d'œil au tutoriel " +#~ "officiel `MXNet " +#~ "`_." + +#~ msgid "" +#~ "Let's create a new file " +#~ "called:code:`mxnet_mnist.py` with all the " +#~ "components required for a traditional " +#~ "(centralized) MNIST training. First, the " +#~ "MXNet package :code:`mxnet` needs to be" +#~ " imported. You can see that we " +#~ "do not yet import the :code:`flwr` " +#~ "package for federated learning. This " +#~ "will be done later." +#~ msgstr "" +#~ "Créons un nouveau fichier appelé " +#~ ":code:`mxnet_mnist.py` avec tous les " +#~ "composants requis pour un apprentissage " +#~ "MNIST traditionnel (centralisé). Tout d'abord," +#~ " le package MXNet :code:`mxnet` doit " +#~ "être importé. Tu peux voir que " +#~ "nous n'avons pas encore importé le " +#~ "package :code:`flwr` pour l'apprentissage " +#~ "fédéré. Cela sera fait plus tard." + +#~ msgid "" +#~ "The :code:`load_data()` function loads the " +#~ "MNIST training and test sets." +#~ msgstr "" +#~ "La fonction :code:`load_data()` charge les " +#~ "ensembles d'entraînement et de test " +#~ "MNIST." + +#~ msgid "" +#~ "As already mentioned, we will use " +#~ "the MNIST dataset for this machine " +#~ "learning workload. The model architecture " +#~ "(a very simple :code:`Sequential` model) " +#~ "is defined in :code:`model()`." +#~ msgstr "" +#~ "Comme nous l'avons déjà mentionné, nous" +#~ " utiliserons l'ensemble de données MNIST" +#~ " pour cette charge de travail " +#~ "d'apprentissage automatique. L'architecture du " +#~ "modèle (un modèle :code:`Séquentiel` très " +#~ "simple) est définie dans :code:`model()`." + +#~ msgid "" +#~ "We now need to define the training" +#~ " (function :code:`train()`) which loops " +#~ "over the training set and measures " +#~ "the loss for each batch of " +#~ "training examples." +#~ msgstr "" +#~ "Nous devons maintenant définir la " +#~ "formation (fonction :code:`train()`) qui passe" +#~ " en boucle sur l'ensemble de la " +#~ "formation et mesure la perte pour " +#~ "chaque lot d'exemples de formation." + +#~ msgid "" +#~ "The evaluation of the model is " +#~ "defined in function :code:`test()`. The " +#~ "function loops over all test samples " +#~ "and measures the loss and accuracy " +#~ "of the model based on the test " +#~ "dataset." #~ msgstr "" +#~ "L'évaluation du modèle est définie dans" +#~ " la fonction :code:`test()`. Cette fonction" +#~ " passe en boucle sur tous les " +#~ "échantillons de test et mesure la " +#~ "perte et la précision du modèle en" +#~ " fonction de l'ensemble des données " +#~ "de test." + +#~ msgid "" +#~ "Having defined the data loading, model" +#~ " architecture, training, and evaluation we" +#~ " can put everything together and " +#~ "train our model on MNIST. Note " +#~ "that the GPU/CPU device for the " +#~ "training and testing is defined within" +#~ " the :code:`ctx` (context)." +#~ msgstr "" +#~ "Après avoir défini le chargement des " +#~ "données, l'architecture du modèle, " +#~ "l'entraînement et l'évaluation, nous pouvons" +#~ " tout assembler et entraîner notre " +#~ "modèle sur MNIST. Note que le " +#~ "dispositif GPU/CPU pour l'entraînement et " +#~ "le test est défini dans le " +#~ ":code:`ctx` (contexte)." + +#~ msgid "You can now run your (centralized) MXNet machine learning workload:" +#~ msgstr "" +#~ "Tu peux maintenant exécuter ta charge" +#~ " de travail (centralisée) d'apprentissage " +#~ "automatique MXNet :" + +#~ msgid "" +#~ "So far this should all look fairly" +#~ " familiar if you've used MXNet (or" +#~ " even PyTorch) before. Let's take the" +#~ " next step and use what we've " +#~ "built to create a simple federated " +#~ "learning system consisting of one server" +#~ " and two clients." +#~ msgstr "" +#~ "Jusqu'à présent, tout cela devrait te" +#~ " sembler assez familier si tu as " +#~ "déjà utilisé MXNet (ou même PyTorch)." +#~ " Passons à l'étape suivante et " +#~ "utilisons ce que nous avons construit" +#~ " pour créer un simple système " +#~ "d'apprentissage fédéré composé d'un serveur" +#~ " et de deux clients." + +#~ msgid "MXNet meets Flower" +#~ msgstr "MXNet rencontre Flower" + +#~ msgid "" +#~ "So far, it was not easily possible" +#~ " to use MXNet workloads for federated" +#~ " learning because federated learning is " +#~ "not supported in MXNet. Since Flower " +#~ "is fully agnostic towards the underlying" +#~ " machine learning framework, it can " +#~ "be used to federated arbitrary machine" +#~ " learning workloads. This section will " +#~ "show you how Flower can be used" +#~ " to federate our centralized MXNet " +#~ "workload." +#~ msgstr "" +#~ "Jusqu'à présent, il n'était pas facile" +#~ " d'utiliser les charges de travail " +#~ "MXNet pour l'apprentissage fédéré car " +#~ "l'apprentissage fédéré n'est pas pris en" +#~ " charge dans MXNet. Comme Flower est" +#~ " totalement agnostique vis-à-vis du cadre" +#~ " d'apprentissage automatique sous-jacent, " +#~ "il peut être utilisé pour fédérer " +#~ "des charges de travail d'apprentissage " +#~ "automatique arbitraires. Cette section te " +#~ "montrera comment Flower peut être " +#~ "utilisé pour fédérer notre charge de " +#~ "travail MXNet centralisée." + +#~ msgid "" +#~ "The concept to federate an existing " +#~ "workload is always the same and " +#~ "easy to understand. We have to " +#~ "start a *server* and then use the" +#~ " code in :code:`mxnet_mnist.py` for the " +#~ "*clients* that are connected to the " +#~ "*server*. The *server* sends model " +#~ "parameters to the clients. The *clients*" +#~ " run the training and update the " +#~ "parameters. The updated parameters are " +#~ "sent back to the *server* which " +#~ "averages all received parameter updates. " +#~ "This describes one round of the " +#~ "federated learning process and we repeat" +#~ " this for multiple rounds." +#~ msgstr "" +#~ "Le concept pour fédérer une charge " +#~ "de travail existante est toujours le " +#~ "même et facile à comprendre. Nous " +#~ "devons démarrer un *serveur* et ensuite" +#~ " utiliser le code dans " +#~ ":code:`mxnet_mnist.py` pour les *clients* qui" +#~ " sont connectés au *serveur*. Le " +#~ "*serveur* envoie les paramètres du " +#~ "modèle aux clients. Les *clients* " +#~ "exécutent la formation et mettent à " +#~ "jour les paramètres. Les paramètres mis" +#~ " à jour sont renvoyés au *serveur*" +#~ " qui fait la moyenne de toutes " +#~ "les mises à jour de paramètres " +#~ "reçues. Ceci décrit un tour du " +#~ "processus d'apprentissage fédéré et nous " +#~ "répétons cette opération pour plusieurs " +#~ "tours." + +#~ msgid "" +#~ "Finally, we will define our *client* " +#~ "logic in :code:`client.py` and build " +#~ "upon the previously defined MXNet " +#~ "training in :code:`mxnet_mnist.py`. Our " +#~ "*client* needs to import :code:`flwr`, " +#~ "but also :code:`mxnet` to update the " +#~ "parameters on our MXNet model:" +#~ msgstr "" +#~ "Enfin, nous allons définir la logique" +#~ " de notre *client* dans :code:`client.py`" +#~ " et nous appuyer sur l'entraînement " +#~ "MXNet défini précédemment dans " +#~ ":code:`mxnet_mnist.py`. Notre *client* doit " +#~ "importer :code:`flwr`, mais aussi " +#~ ":code:`mxnet` pour mettre à jour les " +#~ "paramètres de notre modèle MXNet :" + +#~ msgid "" +#~ "Implementing a Flower *client* basically " +#~ "means implementing a subclass of either" +#~ " :code:`flwr.client.Client` or " +#~ ":code:`flwr.client.NumPyClient`. Our implementation " +#~ "will be based on " +#~ ":code:`flwr.client.NumPyClient` and we'll call " +#~ "it :code:`MNISTClient`. :code:`NumPyClient` is " +#~ "slightly easier to implement than " +#~ ":code:`Client` if you use a framework" +#~ " with good NumPy interoperability (like " +#~ "PyTorch or MXNet) because it avoids " +#~ "some of the boilerplate that would " +#~ "otherwise be necessary. :code:`MNISTClient` " +#~ "needs to implement four methods, two " +#~ "methods for getting/setting model parameters," +#~ " one method for training the model," +#~ " and one method for testing the " +#~ "model:" +#~ msgstr "" +#~ "Implementing a Flower *client* basically " +#~ "means implementing a subclass of either" +#~ " :code:`flwr.client.Client` or " +#~ ":code:`flwr.client.NumPyClient`. Our implementation " +#~ "will be based on " +#~ ":code:`flwr.client.NumPyClient` and we'll call " +#~ "it :code:`MNISTClient`. :code:`NumPyClient` is " +#~ "slightly easier to implement than " +#~ ":code:`Client` if you use a framework" +#~ " with good NumPy interoperability (like " +#~ "PyTorch or MXNet) because it avoids " +#~ "some of the boilerplate that would " +#~ "otherwise be necessary. :code:`MNISTClient` " +#~ "needs to implement four methods, two " +#~ "methods for getting/setting model parameters," +#~ " one method for training the model," +#~ " and one method for testing the " +#~ "model:" + +#~ msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" +#~ msgstr "transforme les :code:`NDArray` du MXNet en :code:`ndarray` de NumPy" + +#~ msgid "" +#~ "The challenging part is to transform " +#~ "the MXNet parameters from :code:`NDArray` " +#~ "to :code:`NumPy Arrays` to make it " +#~ "readable for Flower." +#~ msgstr "" +#~ "La partie la plus difficile est de" +#~ " transformer les paramètres MXNet de " +#~ ":code:`NDArray` en :code:`NumPy Arrays` pour" +#~ " les rendre lisibles pour Flower." + +#~ msgid "" +#~ "The two :code:`NumPyClient` methods " +#~ ":code:`fit` and :code:`evaluate` make use " +#~ "of the functions :code:`train()` and " +#~ ":code:`test()` previously defined in " +#~ ":code:`mxnet_mnist.py`. So what we really " +#~ "do here is we tell Flower through" +#~ " our :code:`NumPyClient` subclass which of" +#~ " our already defined functions to " +#~ "call for training and evaluation. We " +#~ "included type annotations to give you" +#~ " a better understanding of the data" +#~ " types that get passed around." +#~ msgstr "" +#~ "Les deux méthodes :code:`NumPyClient` " +#~ ":code:`fit` et :code:`evaluate` utilisent les" +#~ " fonctions :code:`train()` et :code:`test()` " +#~ "définies précédemment dans :code:`mxnet_mnist.py`." +#~ " Ce que nous faisons vraiment ici," +#~ " c'est que nous indiquons à Flower," +#~ " par le biais de notre sous-" +#~ "classe :code:`NumPyClient`, laquelle de nos" +#~ " fonctions déjà définies doit être " +#~ "appelée pour l'entraînement et l'évaluation." +#~ " Nous avons inclus des annotations de" +#~ " type pour te donner une meilleure" +#~ " compréhension des types de données " +#~ "qui sont transmis." + +#~ msgid "" +#~ "Having defined data loading, model " +#~ "architecture, training, and evaluation we " +#~ "can put everything together and train" +#~ " our :code:`Sequential` model on MNIST." +#~ msgstr "" +#~ "Après avoir défini le chargement des " +#~ "données, l'architecture du modèle, la " +#~ "formation et l'évaluation, nous pouvons " +#~ "tout rassembler et former notre modèle" +#~ " :code:`Sequential` sur MNIST." + +#~ msgid "" +#~ "in each window (make sure that the" +#~ " server is still running before you" +#~ " do so) and see your MXNet " +#~ "project run federated learning across " +#~ "two clients. Congratulations!" +#~ msgstr "" +#~ "dans chaque fenêtre (assure-toi que " +#~ "le serveur est toujours en cours " +#~ "d'exécution avant de le faire) et " +#~ "tu verras ton projet MXNet exécuter " +#~ "l'apprentissage fédéré sur deux clients. " +#~ "Félicitations !" + +#~ msgid "" +#~ "The full source code for this " +#~ "example: `MXNet: From Centralized To " +#~ "Federated (Code) " +#~ "`_. Our " +#~ "example is of course somewhat over-" +#~ "simplified because both clients load the" +#~ " exact same dataset, which isn't " +#~ "realistic. You're now prepared to " +#~ "explore this topic further. How about" +#~ " using a CNN or using a " +#~ "different dataset? How about adding more" +#~ " clients?" +#~ msgstr "" +#~ "Le code source complet de cet " +#~ "exemple : `MXNet : From Centralized " +#~ "To Federated (Code) " +#~ "`_. Notre " +#~ "exemple est bien sûr un peu trop" +#~ " simplifié parce que les deux clients" +#~ " chargent exactement le même ensemble " +#~ "de données, ce qui n'est pas " +#~ "réaliste. Tu es maintenant prêt à " +#~ "explorer ce sujet plus en profondeur." +#~ " Pourquoi ne pas utiliser un CNN " +#~ "ou un ensemble de données différent " +#~ "? Pourquoi ne pas ajouter d'autres " +#~ "clients ?" + +#~ msgid "with the following command sequence:" +#~ msgstr "avec la séquence de commandes suivante :" + +#~ msgid "" +#~ "In case you are a researcher you" +#~ " might be just fine using the " +#~ "self-signed certificates generated using " +#~ "the scripts which are part of this" +#~ " guide." +#~ msgstr "" +#~ "Si tu es un chercheur, tu peux " +#~ "très bien utiliser les certificats " +#~ "auto-signés générés à l'aide des " +#~ "scripts qui font partie de ce " +#~ "guide." + +#~ msgid "" +#~ "We are now going to show how " +#~ "to write a sever which uses the" +#~ " previously generated scripts." +#~ msgstr "" +#~ "Nous allons maintenant montrer comment " +#~ "écrire un serveur qui utilise les " +#~ "scripts générés précédemment." + +#~ msgid "" +#~ "When providing certificates, the server " +#~ "expects a tuple of three certificates." +#~ " :code:`Path` can be used to easily" +#~ " read the contents of those files " +#~ "into byte strings, which is the " +#~ "data type :code:`start_server` expects." +#~ msgstr "" +#~ "Lorsqu'il fournit des certificats, le " +#~ "serveur attend un tuple de trois " +#~ "certificats. :code:`Path` peut être utilisé" +#~ " pour lire facilement le contenu de" +#~ " ces fichiers en chaînes d'octets, ce" +#~ " qui est le type de données " +#~ "attendu par :code:`start_server`." + +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`_." +#~ msgstr "" + +#~ msgid "Flower server" +#~ msgstr "Serveur de Flower" #~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ \\(req\\)" +#~ "The command will pull the Docker " +#~ "image with the tag " +#~ "``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. " +#~ "The tag contains the information which" +#~ " Flower, Python and Ubuntu is used." +#~ " In this case, it uses Flower " +#~ "1.7.0, Python 3.11 and Ubuntu 22.04. " +#~ "The ``--rm`` flag tells Docker to " +#~ "remove the container after it exits." #~ msgstr "" #~ msgid "" -#~ "Optionally specify the type of actor " -#~ "to use. The actor object, which " -#~ "persists throughout the simulation, will " -#~ "be the process in charge of " -#~ "running the clients' jobs (i.e. their" -#~ " `fit()` method)." +#~ "By default, the Flower server keeps " +#~ "state in-memory. When using the " +#~ "Docker flag ``--rm``, the state is " +#~ "not persisted between container starts. " +#~ "We will show below how to save " +#~ "the state in a file on your " +#~ "host system." #~ msgstr "" #~ msgid "" -#~ "Much effort went into a completely " -#~ "restructured Flower docs experience. The " -#~ "documentation on [flower.ai/docs](flower.ai/docs) is" -#~ " now divided into Flower Framework, " -#~ "Flower Baselines, Flower Android SDK, " -#~ "Flower iOS SDK, and code example " -#~ "projects." +#~ "The ``-p :`` flag tells " +#~ "Docker to map the ports " +#~ "``9091``/``9092`` of the host to " +#~ "``9091``/``9092`` of the container, allowing" +#~ " you to access the Driver API " +#~ "on ``http://localhost:9091`` and the Fleet " +#~ "API on ``http://localhost:9092``. Lastly, any" +#~ " flag that comes after the tag " +#~ "is passed to the Flower server. " +#~ "Here, we are passing the flag " +#~ "``--insecure``." #~ msgstr "" #~ msgid "" -#~ "Flower usage examples used to be " -#~ "bundled with Flower in a package " -#~ "called ``flwr_example``. We are migrating " -#~ "those examples to standalone projects to" -#~ " make them easier to use. All " -#~ "new examples are based in the " -#~ "directory `examples " -#~ "`_." +#~ "The ``--insecure`` flag enables insecure " +#~ "communication (using HTTP, not HTTPS) " +#~ "and should only be used for " +#~ "testing purposes. We strongly recommend " +#~ "enabling `SSL `_ when " +#~ "deploying to a production environment." #~ msgstr "" -#~ "Les exemples d'utilisation de Flower " -#~ "étaient auparavant regroupés avec Flower " -#~ "dans un paquet appelé ``flwr_example``. " -#~ "Nous migrons ces exemples vers des " -#~ "projets autonomes pour les rendre plus" -#~ " faciles à utiliser. Tous les " -#~ "nouveaux exemples sont basés dans le " -#~ "répertoire ``examples " -#~ "`_." -#~ msgid "Quickstart TensorFlow/Keras" -#~ msgstr "Démarrage rapide de TensorFlow/Keras" +#~ msgid "" +#~ "You can use ``--help`` to view all" +#~ " available flags that the server " +#~ "supports:" +#~ msgstr "" + +#~ msgid "" +#~ "If you want to persist the state" +#~ " of the server on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``-v`` to" +#~ " mount the user's home directory " +#~ "(``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." +#~ msgstr "" + +#~ msgid "" +#~ "As soon as the server starts, the" +#~ " file ``state.db`` is created in the" +#~ " user's home directory on your host" +#~ " system. If the file already exists," +#~ " the server tries to restore the " +#~ "state from the file. To start the" +#~ " server with an empty database, " +#~ "simply remove the ``state.db`` file." +#~ msgstr "" -#~ msgid "Legacy Examples (`flwr_example`)" -#~ msgstr "Exemples hérités (`flwr_example`)" +#~ msgid "" +#~ "To enable SSL, you will need a " +#~ "CA certificate, a server certificate and" +#~ " a server private key." +#~ msgstr "" #~ msgid "" -#~ "The useage examples in `flwr_example` " -#~ "are deprecated and will be removed " -#~ "in the future. New examples are " -#~ "provided as standalone projects in " -#~ "`examples `_." +#~ "For testing purposes, you can generate" +#~ " your own self-signed certificates. " +#~ "The `Enable SSL connections " +#~ "`_ page contains " +#~ "a section that will guide you " +#~ "through the process." #~ msgstr "" -#~ "Les exemples d'utilisation dans `flwr_example`" -#~ " sont obsolètes et seront supprimés à" -#~ " l'avenir. De nouveaux exemples sont " -#~ "fournis en tant que projets autonomes" -#~ " dans `examples " -#~ "`_." -#~ msgid "Extra Dependencies" -#~ msgstr "Dépendances supplémentaires" +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``-v`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the server to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the server with the " +#~ "``--certificates`` flag." +#~ msgstr "" + +#~ msgid "Using a different Flower or Python version" +#~ msgstr "" #~ msgid "" -#~ "The core Flower framework keeps a " -#~ "minimal set of dependencies. The " -#~ "examples demonstrate Flower in the " -#~ "context of different machine learning " -#~ "frameworks, so additional dependencies need" -#~ " to be installed before an example" -#~ " can be run." +#~ "If you want to use a different " +#~ "version of Flower or Python, you " +#~ "can do so by changing the tag. " +#~ "All versions we provide are available" +#~ " on `Docker Hub " +#~ "`_." #~ msgstr "" -#~ "Le noyau du framework Flower conserve" -#~ " un ensemble minimal de dépendances. " -#~ "Les exemples démontrent Flower dans le" -#~ " contexte de différents frameworks " -#~ "d'apprentissage automatique, de sorte que " -#~ "des dépendances supplémentaires doivent être" -#~ " installées avant qu'un exemple puisse " -#~ "être exécuté." -#~ msgid "For PyTorch examples::" -#~ msgstr "Pour les exemples de PyTorch: :" +#~ msgid "" +#~ "The following command returns the " +#~ "current image hash referenced by the " +#~ "``server:1.7.0-py3.11-ubuntu22.04`` tag:" +#~ msgstr "" -#~ msgid "For TensorFlow examples::" -#~ msgstr "Pour les exemples de TensorFlow : :" +#~ msgid "Next, we can pin the hash when running a new server container:" +#~ msgstr "" -#~ msgid "For both PyTorch and TensorFlow examples::" -#~ msgstr "Pour les exemples PyTorch et TensorFlow: :" +#~ msgid "flower-driver-api" +#~ msgstr "flower-driver-api" + +#~ msgid "flower-fleet-api" +#~ msgstr "flower-fleet-api" #~ msgid "" -#~ "Please consult :code:`pyproject.toml` for a" -#~ " full list of possible extras " -#~ "(section :code:`[tool.poetry.extras]`)." +#~ "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +#~ "[:py:class:`str`, :py:obj:`~typing.Union`\\ " +#~ "[:py:class:`int`, :py:class:`float`, :py:class:`str`, " +#~ ":py:class:`bytes`, :py:class:`bool`, " +#~ ":py:class:`~typing.List`\\ [:py:class:`int`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`float`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`str`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`bytes`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`bool`]]]" #~ msgstr "" -#~ "Tu peux consulter :code:`pyproject.toml` pour" -#~ " une liste complète des extras " -#~ "possibles (section :code:`[tool.poetry.extras]`)." -#~ msgid "PyTorch Examples" -#~ msgstr "Exemples de PyTorch" +#~ msgid "" +#~ ":py:obj:`create_error_reply " +#~ "`\\ \\(error\\, " +#~ "ttl\\)" +#~ msgstr "" #~ msgid "" -#~ "Our PyTorch examples are based on " -#~ "PyTorch 1.7. They should work with " -#~ "other releases as well. So far, we" -#~ " provide the following examples." +#~ ":py:obj:`create_reply `\\ " +#~ "\\(content\\, ttl\\)" #~ msgstr "" -#~ "Nos exemples PyTorch sont basés sur " -#~ "PyTorch 1.7. Ils devraient fonctionner " -#~ "avec d'autres versions également. Jusqu'à " -#~ "présent, nous fournissons les exemples " -#~ "suivants." -#~ msgid "CIFAR-10 Image Classification" -#~ msgstr "Classification d'images CIFAR-10" +#~ msgid "" +#~ "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +#~ "[:py:class:`str`, :py:obj:`~typing.Union`\\ " +#~ "[:py:class:`int`, :py:class:`float`, " +#~ ":py:class:`~typing.List`\\ [:py:class:`int`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`float`]]]" +#~ msgstr "" + +#~ msgid "Run Flower server (Driver API and Fleet API)." +#~ msgstr "" #~ msgid "" -#~ "`CIFAR-10 and CIFAR-100 " -#~ "`_ are " -#~ "popular RGB image datasets. The Flower" -#~ " CIFAR-10 example uses PyTorch to " -#~ "train a simple CNN classifier in a" -#~ " federated learning setup with two " -#~ "clients." +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" #~ msgstr "" -#~ "`CIFAR-10 et CIFAR-100 " -#~ "`_ sont des" -#~ " ensembles de données d'images RVB " -#~ "populaires. L'exemple Flower CIFAR-10 utilise" -#~ " PyTorch pour former un classificateur " -#~ "CNN simple dans une configuration " -#~ "d'apprentissage fédéré avec deux clients." -#~ msgid "First, start a Flower server:" +#~ msgid "Start a Flower Driver API server." #~ msgstr "Tout d'abord, démarre un serveur Flower :" -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" - -#~ msgid "Then, start the two clients in a new terminal window:" +#~ msgid "" +#~ ":py:obj:`Driver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ "Ensuite, démarre les deux clients dans" -#~ " une nouvelle fenêtre de terminal :" +#~ "Flower 1.0 : ``start_server(..., " +#~ "config=flwr.server.ServerConfig(num_rounds=3, " +#~ "round_timeout=600.0), ...)``" -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" +#~ msgid "`Driver` class provides an interface to the Driver API." +#~ msgstr "" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." -#~ msgstr "Pour plus de détails, voir :code:`src/py/flwr_example/pytorch_cifar`." +#~ msgid "" +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:9091\"`." +#~ msgstr "" -#~ msgid "ImageNet-2012 Image Classification" -#~ msgstr "ImageNet-2012 Classification des images" +#~ msgid "Disconnect from the SuperLink if connected." +#~ msgstr "" #~ msgid "" -#~ "`ImageNet-2012 `_ is " -#~ "one of the major computer vision " -#~ "datasets. The Flower ImageNet example " -#~ "uses PyTorch to train a ResNet-18 " -#~ "classifier in a federated learning setup" -#~ " with ten clients." +#~ ":py:obj:`create_message `\\" +#~ " \\(content\\, message\\_type\\, ...\\)" #~ msgstr "" -#~ "`ImageNet-2012 `_ est " -#~ "l'un des principaux ensembles de données" -#~ " de vision par ordinateur. L'exemple " -#~ "Flower ImageNet utilise PyTorch pour " -#~ "entraîner un classificateur ResNet-18 dans " -#~ "une configuration d'apprentissage fédéré avec" -#~ " dix clients." -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" +#~ msgid "" +#~ "Time-to-live for the round trip" +#~ " of this message, i.e., the time " +#~ "from sending this message to receiving" +#~ " a reply. It specifies the duration" +#~ " for which the message and its " +#~ "potential reply are considered valid." +#~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" +#~ msgid "start\\_driver" +#~ msgstr "start_client" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." +#~ msgid "" +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:8080\"`." #~ msgstr "" -#~ "Pour plus de détails, voir " -#~ ":code:`src/py/flwr_example/pytorch_imagenet`." -#~ msgid "TensorFlow Examples" -#~ msgstr "Exemples de TensorFlow" +#~ msgid "" +#~ "A server implementation, either " +#~ "`flwr.server.Server` or a subclass thereof." +#~ " If no instance is provided, then " +#~ "`start_driver` will create one." +#~ msgstr "" #~ msgid "" -#~ "Our TensorFlow examples are based on " -#~ "TensorFlow 2.0 or newer. So far, " -#~ "we provide the following examples." +#~ "An implementation of the class " +#~ "`flwr.server.ClientManager`. If no implementation" +#~ " is provided, then `start_driver` will " +#~ "use `flwr.server.SimpleClientManager`." #~ msgstr "" -#~ "Nos exemples TensorFlow sont basés sur" -#~ " TensorFlow 2.0 ou une version plus" -#~ " récente. Jusqu'à présent, nous te " -#~ "proposons les exemples suivants." -#~ msgid "Fashion-MNIST Image Classification" -#~ msgstr "Classification d'images Fashion-MNIST" +#~ msgid "The Driver object to use." +#~ msgstr "" + +#~ msgid "Starting a driver that connects to an insecure server:" +#~ msgstr "" + +#~ msgid "Starting a driver that connects to an SSL-enabled server:" +#~ msgstr "" #~ msgid "" -#~ "`Fashion-MNIST `_ is often used as " -#~ "the \"Hello, world!\" of machine " -#~ "learning. We follow this tradition and" -#~ " provide an example which samples " -#~ "random local datasets from Fashion-MNIST" -#~ " and trains a simple image " -#~ "classification model over those partitions." +#~ ":py:obj:`run_simulation_from_cli " +#~ "`\\ \\(\\)" #~ msgstr "" -#~ "nous suivons cette tradition et " -#~ "fournissons un exemple qui échantillonne " -#~ "des ensembles de données locales " -#~ "aléatoires de Fashion-MNIST et entraîne" -#~ " un modèle simple de classification " -#~ "d'images sur ces partitions." -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgid "Run Simulation Engine from the CLI." +#~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" +#~ msgid "run\\_simulation\\_from\\_cli" +#~ msgstr "Simulation de moniteur" #~ msgid "" -#~ "For more details, see " -#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." +#~ "Check out this Federated Learning " +#~ "quickstart tutorial for using Flower " +#~ "with MXNet to train a Sequential " +#~ "model on MNIST." #~ msgstr "" -#~ "Pour plus de détails, voir " -#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." + +#~ msgid "Quickstart MXNet" +#~ msgstr "Démarrage rapide de MXNet" #~ msgid "" #~ "MXNet is no longer maintained and " #~ "has been moved into `Attic " #~ "`_. As a " #~ "result, we would encourage you to " -#~ "use other ML frameworks alongise Flower," -#~ " for example, PyTorch. This tutorial " -#~ "might be removed in future versions " -#~ "of Flower." +#~ "use other ML frameworks alongside " +#~ "Flower, for example, PyTorch. This " +#~ "tutorial might be removed in future " +#~ "versions of Flower." #~ msgstr "" #~ msgid "" -#~ "Now that you have known how " -#~ "federated XGBoost work with Flower, it's" -#~ " time to run some more comprehensive" -#~ " experiments by customising the " -#~ "experimental settings. In the xgboost-" -#~ "comprehensive example (`full code " -#~ "`_), we provide more options " -#~ "to define various experimental setups, " -#~ "including aggregation strategies, data " -#~ "partitioning and centralised/distributed evaluation." -#~ " We also support `Flower simulation " -#~ "`_ making it easy to " -#~ "simulate large client cohorts in a " -#~ "resource-aware manner. Let's take a " -#~ "look!" +#~ "In this tutorial, we will learn " +#~ "how to train a :code:`Sequential` model" +#~ " on MNIST using Flower and MXNet." #~ msgstr "" +#~ "Dans ce tutoriel, nous allons apprendre" +#~ " à former un modèle :code:`Sequential` " +#~ "sur MNIST à l'aide de Flower et" +#~ " de MXNet." -#~ msgid "|31e4b1afa87c4b968327bbeafbf184d4|" +#~ msgid "Since we want to use MXNet, let's go ahead and install it:" +#~ msgstr "Puisque nous voulons utiliser MXNet, allons-y et installons-le :" + +#~ msgid "" +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on MXNet´s `Hand-written Digit " +#~ "Recognition tutorial " +#~ "`_." #~ msgstr "" +#~ "Maintenant que toutes nos dépendances " +#~ "sont installées, lançons une formation " +#~ "distribuée simple avec deux clients et" +#~ " un serveur. Notre procédure de " +#~ "formation et l'architecture du réseau " +#~ "sont basées sur le tutoriel de " +#~ "reconnaissance de chiffres écrits à la" +#~ " main du MXNet " +#~ "`_." + +#~ msgid "" +#~ "In a file called :code:`client.py`, " +#~ "import Flower and MXNet related " +#~ "packages:" +#~ msgstr "" +#~ "Dans un fichier appelé :code:`client.py`, " +#~ "importe Flower et les paquets liés " +#~ "au MXNet :" + +#~ msgid "In addition, define the device allocation in MXNet with:" +#~ msgstr "En outre, définis l'attribution de l'appareil dans MXNet avec :" + +#~ msgid "" +#~ "We use MXNet to load MNIST, a " +#~ "popular image classification dataset of " +#~ "handwritten digits for machine learning. " +#~ "The MXNet utility :code:`mx.test_utils.get_mnist()`" +#~ " downloads the training and test " +#~ "data." +#~ msgstr "" +#~ "Nous utilisons MXNet pour charger MNIST," +#~ " un ensemble de données de " +#~ "classification d'images populaire de chiffres" +#~ " manuscrits pour l'apprentissage automatique. " +#~ "L'utilitaire MXNet :code:`mx.test_utils.get_mnist()` " +#~ "télécharge les données d'entraînement et " +#~ "de test." + +#~ msgid "" +#~ "Define the training and loss with " +#~ "MXNet. We train the model by " +#~ "looping over the dataset, measure the" +#~ " corresponding loss, and optimize it." +#~ msgstr "" +#~ "Définis l'entraînement et la perte avec" +#~ " MXNet. Nous entraînons le modèle en" +#~ " parcourant en boucle l'ensemble des " +#~ "données, nous mesurons la perte " +#~ "correspondante et nous l'optimisons." + +#~ msgid "" +#~ "Next, we define the validation of " +#~ "our machine learning model. We loop " +#~ "over the test set and measure both" +#~ " loss and accuracy on the test " +#~ "set." +#~ msgstr "" +#~ "Ensuite, nous définissons la validation " +#~ "de notre modèle d'apprentissage automatique." +#~ " Nous effectuons une boucle sur " +#~ "l'ensemble de test et mesurons à " +#~ "la fois la perte et la précision" +#~ " sur l'ensemble de test." + +#~ msgid "" +#~ "After defining the training and testing" +#~ " of a MXNet machine learning model," +#~ " we use these functions to implement" +#~ " a Flower client." +#~ msgstr "" +#~ "Après avoir défini la formation et " +#~ "le test d'un modèle d'apprentissage " +#~ "automatique MXNet, nous utilisons ces " +#~ "fonctions pour mettre en œuvre un " +#~ "client Flower." + +#~ msgid "Our Flower clients will use a simple :code:`Sequential` model:" +#~ msgstr "Nos clients Flower utiliseront un modèle simple :code:`Sequential` :" + +#~ msgid "" +#~ "After loading the dataset with " +#~ ":code:`load_data()` we perform one forward " +#~ "propagation to initialize the model and" +#~ " model parameters with :code:`model(init)`. " +#~ "Next, we implement a Flower client." +#~ msgstr "" +#~ "Après avoir chargé l'ensemble de données" +#~ " avec :code:`load_data()`, nous effectuons " +#~ "une propagation vers l'avant pour " +#~ "initialiser le modèle et les paramètres" +#~ " du modèle avec :code:`model(init)`. " +#~ "Ensuite, nous implémentons un client " +#~ "Flower." -#~ msgid "|c9d935b4284e4c389a33d86b33e07c0a|" +#~ msgid "" +#~ "Flower provides a convenience class " +#~ "called :code:`NumPyClient` which makes it " +#~ "easier to implement the :code:`Client` " +#~ "interface when your workload uses MXNet." +#~ " Implementing :code:`NumPyClient` usually means" +#~ " defining the following methods " +#~ "(:code:`set_parameters` is optional though):" #~ msgstr "" +#~ "Flower fournit une classe de commodité" +#~ " appelée :code:`NumPyClient` qui facilite " +#~ "l'implémentation de l'interface :code:`Client` " +#~ "lorsque ta charge de travail utilise " +#~ "MXNet. L'implémentation de :code:`NumPyClient` " +#~ "signifie généralement la définition des " +#~ "méthodes suivantes (:code:`set_parameters` est " +#~ "cependant facultatif) :" -#~ msgid "|00727b5faffb468f84dd1b03ded88638|" +#~ msgid "They can be implemented in the following way:" +#~ msgstr "Ils peuvent être mis en œuvre de la manière suivante :" + +#~ msgid "" +#~ "We can now create an instance of" +#~ " our class :code:`MNISTClient` and add " +#~ "one line to actually run this " +#~ "client:" #~ msgstr "" +#~ "Nous pouvons maintenant créer une " +#~ "instance de notre classe :code:`MNISTClient`" +#~ " et ajouter une ligne pour exécuter" +#~ " ce client :" -#~ msgid "|daf0cf0ff4c24fd29439af78416cf47b|" +#~ msgid "" +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()` or " +#~ ":code:`fl.client.start_numpy_client()`. The string " +#~ ":code:`\"0.0.0.0:8080\"` tells the client " +#~ "which server to connect to. In our" +#~ " case we can run the server and" +#~ " the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" +#~ " we run a truly federated workload" +#~ " with the server and clients running" +#~ " on different machines, all that " +#~ "needs to change is the " +#~ ":code:`server_address` we pass to the " +#~ "client." #~ msgstr "" +#~ "C'est tout pour le client. Il nous" +#~ " suffit d'implémenter :code:`Client` ou " +#~ ":code:`NumPyClient` et d'appeler " +#~ ":code:`fl.client.start_client()`. La chaîne " +#~ ":code:`\"0.0.0:8080\"` indique au client à " +#~ "quel serveur se connecter. Dans notre" +#~ " cas, nous pouvons exécuter le " +#~ "serveur et le client sur la même" +#~ " machine, c'est pourquoi nous utilisons " +#~ ":code:`\"0.0.0:8080\"`. Si nous exécutons une" +#~ " charge de travail véritablement fédérée" +#~ " avec le serveur et les clients " +#~ "s'exécutant sur des machines différentes, " +#~ "tout ce qui doit changer est " +#~ ":code:`server_address` que nous transmettons " +#~ "au client." + +#~ msgid "" +#~ "With both client and server ready, " +#~ "we can now run everything and see" +#~ " federated learning in action. Federated" +#~ " learning systems usually have a " +#~ "server and multiple clients. We " +#~ "therefore have to start the server " +#~ "first:" +#~ msgstr "" +#~ "Le client et le serveur étant " +#~ "prêts, nous pouvons maintenant tout " +#~ "exécuter et voir l'apprentissage fédéré " +#~ "en action. Les systèmes d'apprentissage " +#~ "fédéré ont généralement un serveur et" +#~ " plusieurs clients. Nous devons donc " +#~ "commencer par démarrer le serveur :" -#~ msgid "|9f093007080d471d94ca90d3e9fde9b6|" +#~ msgid "" +#~ "Congratulations! You've successfully built and" +#~ " run your first federated learning " +#~ "system. The full `source code " +#~ "`_ for this example can " +#~ "be found in :code:`examples/quickstart-mxnet`." #~ msgstr "" +#~ "Félicitations ! Tu as réussi à " +#~ "construire et à faire fonctionner ton" +#~ " premier système d'apprentissage fédéré. Le" +#~ " code source complet " +#~ "`_ de cet exemple se " +#~ "trouve dans :code:`examples/quickstart-mxnet`." -#~ msgid "|46a26e6150e0479fbd3dfd655f36eb13|" +#~ msgid ":code:`load_mnist()`" +#~ msgstr ":code:`load_mnist()`" + +#~ msgid "Loads the MNIST dataset using OpenML" +#~ msgstr "Charge l'ensemble de données MNIST à l'aide d'OpenML" + +#~ msgid ":code:`shuffle()`" +#~ msgstr ":code:`shuffle()`" + +#~ msgid "Shuffles data and its label" +#~ msgstr "Mélange les données et leur étiquette" + +#~ msgid ":code:`partition()`" +#~ msgstr ":code:`partition()`" + +#~ msgid "Splits datasets into a number of partitions" +#~ msgstr "Divise les ensembles de données en un certain nombre de partitions" + +#~ msgid "" +#~ "We load the MNIST dataset from " +#~ "`OpenML " +#~ "`_, a" +#~ " popular image classification dataset of" +#~ " handwritten digits for machine learning." +#~ " The utility :code:`utils.load_mnist()` downloads" +#~ " the training and test data. The " +#~ "training set is split afterwards into" +#~ " 10 partitions with :code:`utils.partition()`." #~ msgstr "" +#~ "Nous chargeons l'ensemble de données " +#~ "MNIST de `OpenML `_," +#~ " un ensemble de données de " +#~ "classification d'images populaires de chiffres" +#~ " manuscrits pour l'apprentissage automatique. " +#~ "L'utilitaire :code:`utils.load_mnist()` télécharge " +#~ "les données d'entraînement et de test." +#~ " L'ensemble d'entraînement est ensuite " +#~ "divisé en 10 partitions avec " +#~ ":code:`utils.partition()`." -#~ msgid "|3daba297595c4c7fb845d90404a6179a|" +#~ msgid "Let's get stated!" +#~ msgstr "Allons-y, déclarons-le !" + +#~ msgid "|2b5c62c529f6416f840c594cce062fbb|" #~ msgstr "" -#~ msgid "|5769874fa9c4455b80b2efda850d39d7|" +#~ msgid "|90b334680cb7467d9a04d39b8e8dca9f|" #~ msgstr "" -#~ msgid "|ba47ffb421814b0f8f9fa5719093d839|" +#~ msgid "|65764ceee89f4335bfd93fd0b115e831|" #~ msgstr "" -#~ msgid "|aeac5bf79cbf497082e979834717e01b|" +#~ msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" #~ msgstr "" -#~ msgid "|ce27ed4bbe95459dba016afc42486ba2|" +#~ msgid "|11e95ac83a8548d8b3505b4663187d07|" #~ msgstr "" -#~ msgid "|ae94a7f71dda443cbec2385751427d41|" +#~ msgid "|1dab2f3a23674abc8a6731f20fa10730|" #~ msgstr "" -#~ msgid "|e61fce4d43d243e7bb08bdde97d81ce6|" +#~ msgid "|7f0ee162da38450788493a21627306f7|" #~ msgstr "" -#~ msgid "|08cb60859b07461588fe44e55810b050|" +#~ msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" +#~ msgstr "" + +#~ msgid "|5b1408eec0d746cdb91162a9107b6089|" +#~ msgstr "" + +#~ msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" +#~ msgstr "" + +#~ msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" +#~ msgstr "" + +#~ msgid "|ec1fe880237247e0975f52766775ab84|" +#~ msgstr "" + +#~ msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" +#~ msgstr "" + +#~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" diff --git a/doc/locales/fr/LC_MESSAGES/sphinx.po b/doc/locales/fr/LC_MESSAGES/sphinx.po index 28669f60bab6..d1978d701446 100644 --- a/doc/locales/fr/LC_MESSAGES/sphinx.po +++ b/doc/locales/fr/LC_MESSAGES/sphinx.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower \n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-08-29 16:41+0200\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: fr\n" @@ -17,21 +17,26 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.12.1\n" +"Generated-By: Babel 2.15.0\n" -#: ../../source/_templates/base.html:13 +#: ../../source/_templates/base.html:18 msgid "About these documents" msgstr "" -#: ../../source/_templates/base.html:16 +#: ../../source/_templates/base.html:21 msgid "Index" msgstr "" -#: ../../source/_templates/base.html:19 +#: ../../source/_templates/base.html:24 +#: ../../source/_templates/sidebar/search.html:2 msgid "Search" msgstr "" -#: ../../source/_templates/base.html:22 +#: ../../source/_templates/base.html:27 msgid "Copyright" msgstr "" +#: ../../source/_templates/sidebar/search.html:2 +msgid "Type / to search" +msgstr "" + diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 63a160232909..17960b663150 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -7,18 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-13 09:48+0200\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: 2024-05-14 21:01+0000\n" "Last-Translator: \"Young D. Kwon\" \n" -"Language-Team: Korean \n" "Language: ko\n" +"Language-Team: Korean \n" +"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.6-dev\n" -"Generated-By: Babel 2.14.0\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" @@ -32,8 +31,7 @@ msgstr "엣지 클라이언트 엔진" msgid "" "`Flower `_ core framework architecture with Edge " "Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 " -"엔진" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" @@ -43,8 +41,7 @@ msgstr "가상 클라이언트 엔진" msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 " -"엔진" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" @@ -54,8 +51,7 @@ msgstr "동일 작업에서 가상 클라이언트 엔진과 엣지 클라이언 msgid "" "`Flower `_ core framework architecture with both " "Virtual Client Engine and Edge Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 " -"클라이언트 엔진" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라이언트 엔진" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" @@ -78,17 +74,16 @@ msgid "" msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:11 -#: ../../source/how-to-run-flower-using-docker.rst:129 msgid "Clone the flower repository." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:17 -#: ../../source/how-to-run-flower-using-docker.rst:135 +#: ../../source/how-to-run-flower-using-docker.rst:144 msgid "Verify the Docker daemon is running." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:19 -#: ../../source/how-to-run-flower-using-docker.rst:137 +#: ../../source/how-to-run-flower-using-docker.rst:146 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." @@ -288,22 +283,10 @@ msgstr "" msgid "" "If you want to use your own base image instead of the official Flower " "base image, all you need to do is set the ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments. .. code-" -"block:: bash" -msgstr "" - -#: ../../source/contributor-how-to-build-docker-images.rst:129 -msgid "$ cd src/docker/superlink/ $ docker build \\" +"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:131 -msgid "" -"--build-arg BASE_REPOSITORY=flwr_base \\ --build-arg PYTHON_VERSION=3.11 " -"\\ --build-arg UBUNTU_VERSION=ubuntu22.04 \\ --build-arg " -"FLWR_VERSION=1.8.0 \\ -t flwr_superlink:0.1.0 ." -msgstr "" - -#: ../../source/contributor-how-to-build-docker-images.rst:137 +#: ../../source/contributor-how-to-build-docker-images.rst:138 msgid "After creating the image, we can test whether the image is working:" msgstr "" @@ -1511,7 +1494,7 @@ msgstr "" msgid "Creating and merging a pull request (PR)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:205 +#: ../../source/contributor-tutorial-contribute-on-github.rst:206 msgid "**Create the PR**" msgstr "" @@ -1544,178 +1527,180 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" +"The title should be changed to adhere to the :ref:`pr_title_format` " +"guidelines, otherwise it won't be possible to merge the PR. So in this " +"case, a correct title might be ``docs(framework:skip) Fix typos``." +msgstr "" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:196 +msgid "" "The input box in the middle is there for you to describe what your PR " "does and to link it to existing issues. We have placed comments (that " "won't be rendered once the PR is opened) to guide you through the " "process." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:196 -msgid "" -"It is important to follow the instructions described in comments. For " -"instance, in order to not break how our changelog system works, you " -"should read the information above the ``Changelog entry`` section " -"carefully. You can also checkout some examples and details in the " -":ref:`changelogentry` appendix." +#: ../../source/contributor-tutorial-contribute-on-github.rst:199 +msgid "It is important to follow the instructions described in comments." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:200 +#: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " "reviewers that a new PR has been opened and that they should look over it" " to merge or to request changes." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:203 +#: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" "If your PR is not yet ready for review, and you don't want to notify " "anyone, you have the option to create a draft pull request:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "**Making new changes**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " "commits to it the same way we did before, by making changes to the branch" " associated with the PR." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:230 +#: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:211 +#: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" "Once the PR has been opened or once the draft PR has been marked as " "ready, a review from code owners will be automatically requested:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:215 +#: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" "Code owners will then look into the code, ask questions, request changes " "or validate the PR." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:217 +#: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:221 +#: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" "To resolve them, just push the necessary changes to the branch associated" " with the PR:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:225 +#: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:229 +#: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" "Once all the conversations have been resolved, you can re-request a " "review." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:250 +#: ../../source/contributor-tutorial-contribute-on-github.rst:251 msgid "**Once the PR is merged**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:233 +#: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" "If all the automatic tests have passed and reviewers have no more changes" " to request, they can approve the PR and merge it." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:237 +#: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:244 +#: ../../source/contributor-tutorial-contribute-on-github.rst:245 msgid "Then you should update your forked repository by doing:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:253 +#: ../../source/contributor-tutorial-contribute-on-github.rst:254 msgid "Example of first contribution" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:256 +#: ../../source/contributor-tutorial-contribute-on-github.rst:257 msgid "Problem" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:258 +#: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" "For our documentation, we've started to use the `Diàtaxis framework " "`_." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:260 +#: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" "Our \"How to\" guides should have titles that continue the sentence \"How" " to …\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:262 +#: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:264 +#: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" "This issue is about changing the title of a doc from present continuous " "to present simple." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:266 +#: ../../source/contributor-tutorial-contribute-on-github.rst:267 msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:268 +#: ../../source/contributor-tutorial-contribute-on-github.rst:269 msgid "Before: \"How to saving progress\" ❌" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:270 +#: ../../source/contributor-tutorial-contribute-on-github.rst:271 msgid "After: \"How to save progress\" ✅" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:273 +#: ../../source/contributor-tutorial-contribute-on-github.rst:274 msgid "Solution" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:275 +#: ../../source/contributor-tutorial-contribute-on-github.rst:276 msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " "After cloning and setting up the Flower repo, here's what you should do:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:277 +#: ../../source/contributor-tutorial-contribute-on-github.rst:278 msgid "Find the source file in ``doc/source``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:278 +#: ../../source/contributor-tutorial-contribute-on-github.rst:279 msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " "should be the same length as the title itself)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:279 +#: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" "Build the docs and `check the result `_" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:282 +#: ../../source/contributor-tutorial-contribute-on-github.rst:283 msgid "Rename file" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:284 +#: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" "You might have noticed that the file name still reflects the old wording." " If we just change the file, then we break all existing links to it - it " @@ -1723,142 +1708,68 @@ msgid "" "engine ranking." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:287 +#: ../../source/contributor-tutorial-contribute-on-github.rst:288 msgid "Here's how to change the file name:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:289 +#: ../../source/contributor-tutorial-contribute-on-github.rst:290 msgid "Change the file name to ``save-progress.rst``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:290 +#: ../../source/contributor-tutorial-contribute-on-github.rst:291 msgid "Add a redirect rule to ``doc/source/conf.py``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:292 +#: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" "This will cause a redirect from ``saving-progress.html`` to ``save-" "progress.html``, old links will continue to work." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:295 +#: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:297 +#: ../../source/contributor-tutorial-contribute-on-github.rst:298 msgid "" "For the lateral navigation bar to work properly, it is very important to " "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:300 +#: ../../source/contributor-tutorial-contribute-on-github.rst:301 msgid "Find and modify the file name in ``index.rst``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:303 +#: ../../source/contributor-tutorial-contribute-on-github.rst:304 msgid "Open PR" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:305 +#: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" "Commit the changes (commit messages are always imperative: \"Do " "something\", in this case \"Change …\")" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:306 -msgid "Push the changes to your fork" -msgstr "" - #: ../../source/contributor-tutorial-contribute-on-github.rst:307 -msgid "Open a PR (as shown above)" +msgid "Push the changes to your fork" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 -msgid "Wait for it to be approved!" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:309 -msgid "Congrats! 🥳 You're now officially a Flower contributor!" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:313 -msgid "How to write a good PR title" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:315 -msgid "" -"A well-crafted PR title helps team members quickly understand the purpose" -" and scope of the changes being proposed. Here's a guide to help you " -"write a good GitHub PR title:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:317 -msgid "" -"1. Be Clear and Concise: Provide a clear summary of the changes in a " -"concise manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" " -"\"Update,\" or \"Fix\" to indicate the purpose. 1. Include Relevant " -"Information: Mention the affected feature or module for context. 1. Keep " -"it Short: Avoid lengthy titles for easy readability. 1. Use Proper " -"Capitalization and Punctuation: Follow grammar rules for clarity." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:323 -msgid "" -"Let's start with a few examples for titles that should be avoided because" -" they do not provide meaningful information:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:325 -msgid "Implement Algorithm" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:326 -msgid "Database" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:327 -msgid "Add my_new_file.py to codebase" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:328 -msgid "Improve code in module" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:329 -msgid "Change SomeModule" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:331 msgid "" -"Here are a few positive examples which provide helpful information " -"without repeating how they do it, as that is already visible in the " -"\"Files changed\" section of the PR:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:333 -msgid "Update docs banner to mention Flower Summit 2023" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:334 -msgid "Remove unnecessary XGBoost dependency" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:335 -msgid "Remove redundant attributes in strategies subclassing FedAvg" +"Open a PR (as shown above) with title ``docs(framework) Update how-to " +"guide title``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:336 -msgid "Add CI job to deploy the staging system when the ``main`` branch changes" +#: ../../source/contributor-tutorial-contribute-on-github.rst:309 +msgid "Wait for it to be approved!" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:337 -msgid "" -"Add new amazing library which will be used to improve the simulation " -"engine" +#: ../../source/contributor-tutorial-contribute-on-github.rst:310 +msgid "Congrats! 🥳 You're now officially a Flower contributor!" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#: ../../source/contributor-tutorial-contribute-on-github.rst:314 #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:548 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:946 #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:727 @@ -1867,153 +1778,91 @@ msgstr "" msgid "Next steps" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +#: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" "Once you have made your first PR, and want to contribute more, be sure to" " check out the following :" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +#: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" ":doc:`Good first contributions `, where you should particularly look into the " ":code:`baselines` contributions." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +#: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 msgid "Appendix" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:354 -msgid "Changelog entry" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:356 -msgid "" -"When opening a new PR, inside its description, there should be a " -"``Changelog entry`` header." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:358 -msgid "" -"Above this header you should see the following comment that explains how " -"to write your changelog entry:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:360 -msgid "" -"Inside the following 'Changelog entry' section, you should put the " -"description of your changes that will be added to the changelog alongside" -" your PR title." +#: ../../source/contributor-tutorial-contribute-on-github.rst:327 +msgid "PR title format" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:363 -msgid "" -"If the section is completely empty (without any token) or non-existent, " -"the changelog will just contain the title of the PR for the changelog " -"entry, without any description." +#: ../../source/contributor-tutorial-contribute-on-github.rst:329 +msgid "We enforce the following PR title format:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:366 +#: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"If the section contains some text other than tokens, it will use it to " -"add a description to the change." +"(or ``(:skip) `` to ignore the PR in the " +"changelog)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:368 +#: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"If the section contains one of the following tokens it will ignore any " -"other text and put the PR under the corresponding section of the " -"changelog:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:370 -msgid " is for classifying a PR as a general improvement." +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " +"break}``, ```` should be in ``{framework, baselines, datasets, " +"examples, or '*' when modifying multiple projects which requires the " +"':skip' flag to be used}``, and ```` starts with a capitalised " +"verb in the imperative mood." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:372 -msgid " is to not add the PR to the changelog" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:374 -msgid " is to add a general baselines change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:376 -msgid " is to add a general examples change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:378 -msgid " is to add a general sdk change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:380 -msgid " is to add a general simulations change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:382 -msgid "Note that only one token should be used." +#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +msgid "Valid examples:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:384 -msgid "" -"Its content must have a specific format. We will break down what each " -"possibility does:" +#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +msgid "``feat(framework) Add flwr build CLI command``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:386 -msgid "" -"If the ``### Changelog entry`` section contains nothing or doesn't exist," -" the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:344 +msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:390 -msgid "" -"If the ``### Changelog entry`` section contains a description (and no " -"token), the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +msgid "``ci(*:skip) Enforce PR title format``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:396 -msgid "" -"If the ``### Changelog entry`` section contains ````, nothing will " -"change in the changelog." +#: ../../source/contributor-tutorial-contribute-on-github.rst:347 +msgid "Invalid examples:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:398 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:402 +#: ../../source/contributor-tutorial-contribute-on-github.rst:350 msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +"``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " +"``*``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:406 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:351 +msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:410 -msgid "" -"If the ``### Changelog entry`` section contains ````, the following " -"text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:352 +msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:414 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:353 +msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:418 -msgid "" -"Note that only one token must be provided, otherwise, only the first " -"action (in the order listed above), will be performed." +#: ../../source/contributor-tutorial-contribute-on-github.rst:354 +msgid "``Add flwr build CLI command.`` (missing ``()``)" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 @@ -2021,7 +1870,7 @@ msgid "Get started as a contributor" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 -#: ../../source/how-to-run-flower-using-docker.rst:123 +#: ../../source/how-to-run-flower-using-docker.rst:132 msgid "Prerequisites" msgstr "" @@ -3779,7 +3628,7 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:12 msgid "" "We recommend you to check out the complete `code example " -"`_ demonstrating federated learning with Flower in an " "authenticated setting." msgstr "" @@ -3812,18 +3661,19 @@ msgid "" "authentication enabled:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:34 -msgid "Let's break down the :code:`--require-client-authentication` flag:" +#: ../../source/how-to-authenticate-supernodes.rst:36 +msgid "Let's break down the authentication flags:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:36 +#: ../../source/how-to-authenticate-supernodes.rst:38 msgid "" -"The first argument is a path to a CSV file storing all known node public " -"keys. You need to store all known node public keys that are allowed to " -"participate in a federation in one CSV file (:code:`.csv`)." +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " +"file storing all known node public keys. You need to store all known node" +" public keys that are allowed to participate in a federation in one CSV " +"file (:code:`.csv`)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:38 +#: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " @@ -3831,14 +3681,15 @@ msgid "" "known node public keys." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:40 +#: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" -"The second and third arguments are paths to the server's private and " +"The second and third flags :code:`--auth-superlink-private-key` and :code" +":`--auth-superlink-public-key` expect paths to the server's private and " "public keys. For development purposes, you can generate a private and " "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:43 +#: ../../source/how-to-authenticate-supernodes.rst:45 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " "adding known node public keys to the SuperLink. To change the set of " @@ -3847,11 +3698,11 @@ msgid "" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:49 +#: ../../source/how-to-authenticate-supernodes.rst:51 msgid "Enable node authentication in :code:`SuperNode`" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:51 +#: ../../source/how-to-authenticate-supernodes.rst:53 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " "easily enable node authentication in the long-running Flower client " @@ -3859,19 +3710,20 @@ msgid "" "authenticated :code:`SuperNode`:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:61 +#: ../../source/how-to-authenticate-supernodes.rst:64 msgid "" -"The :code:`--authentication-keys` flag expects two arguments: a path to " -"the node's private key file and a path to the node's public key file. For" -" development purposes, you can generate a private and public key pair " -"using :code:`ssh-keygen -t ecdsa -b 384`." +"The :code:`--auth-supernode-private-key` flag expects a path to the " +"node's private key file and the :code:`--auth-supernode-public-key` flag " +"expects a path to the node's public key file. For development purposes, " +"you can generate a private and public key pair using :code:`ssh-keygen -t" +" ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:65 +#: ../../source/how-to-authenticate-supernodes.rst:68 msgid "Security notice" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:67 +#: ../../source/how-to-authenticate-supernodes.rst:70 msgid "" "The system's security relies on the credentials of the SuperLink and each" " SuperNode. Therefore, it is imperative to safeguard and safely store the" @@ -3882,14 +3734,14 @@ msgid "" "methods." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:72 +#: ../../source/how-to-authenticate-supernodes.rst:75 #: ../../source/how-to-enable-ssl-connections.rst:65 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:74 +#: ../../source/how-to-authenticate-supernodes.rst:77 msgid "" "You should now have learned how to start a long-running Flower server " "(:code:`SuperLink`) and client (:code:`SuperNode`) with node " @@ -4481,7 +4333,7 @@ msgid "Install stable release" msgstr "" #: ../../source/how-to-install-flower.rst:15 -#: ../../source/how-to-upgrade-to-flower-next.rst:45 +#: ../../source/how-to-upgrade-to-flower-next.rst:46 msgid "Using pip" msgstr "" @@ -4819,7 +4671,7 @@ msgstr "" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`_." +"`__." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:7 @@ -4842,26 +4694,34 @@ msgid "" "official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:25 +#: ../../source/how-to-run-flower-using-docker.rst:26 +msgid "" +"To ensure optimal performance and compatibility, the SuperLink, SuperNode" +" and ServerApp image must have the same version when running together. " +"This guarantees seamless integration and avoids potential conflicts or " +"issues that may arise from using different versions." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:31 msgid "Flower SuperLink" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:28 +#: ../../source/how-to-run-flower-using-docker.rst:34 msgid "Quickstart" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:30 +#: ../../source/how-to-run-flower-using-docker.rst:36 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:36 +#: ../../source/how-to-run-flower-using-docker.rst:42 msgid "" "The command pulls the Docker image with the tag ``1.8.0`` from Docker " "Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " "The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:42 +#: ../../source/how-to-run-flower-using-docker.rst:48 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " @@ -4869,7 +4729,7 @@ msgid "" "system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:46 +#: ../../source/how-to-run-flower-using-docker.rst:52 msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " @@ -4879,38 +4739,39 @@ msgid "" " flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:53 -#: ../../source/how-to-run-flower-using-docker.rst:216 +#: ../../source/how-to-run-flower-using-docker.rst:59 +#: ../../source/how-to-run-flower-using-docker.rst:238 +#: ../../source/how-to-run-flower-using-docker.rst:354 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " "recommend enabling `SSL `_ when " +"flower-using-docker.html#enabling-ssl-for-secure-connections>`__ when " "deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:58 +#: ../../source/how-to-run-flower-using-docker.rst:64 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:65 +#: ../../source/how-to-run-flower-using-docker.rst:71 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:67 +#: ../../source/how-to-run-flower-using-docker.rst:73 msgid "" "If you want to persist the state of the SuperLink on your host system, " "all you need to do is specify a path where you want to save the file on " "your host system and a name for the database file. In the example below, " -"we tell Docker via the flag ``-v`` to mount the user's home directory " -"(``~/`` on your host) into the ``/app/`` directory of the container. " -"Furthermore, we use the flag ``--database`` to specify the name of the " -"database file." +"we tell Docker via the flag ``--volume`` to mount the user's home " +"directory (``~/`` on your host) into the ``/app/`` directory of the " +"container. Furthermore, we use the flag ``--database`` to specify the " +"name of the database file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:80 +#: ../../source/how-to-run-flower-using-docker.rst:86 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " "user's home directory on your host system. If the file already exists, " @@ -4918,210 +4779,350 @@ msgid "" "SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:85 -#: ../../source/how-to-run-flower-using-docker.rst:234 +#: ../../source/how-to-run-flower-using-docker.rst:91 +#: ../../source/how-to-run-flower-using-docker.rst:260 +#: ../../source/how-to-run-flower-using-docker.rst:375 msgid "Enabling SSL for secure connections" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:87 +#: ../../source/how-to-run-flower-using-docker.rst:93 msgid "" "To enable SSL, you will need a PEM-encoded root certificate, a PEM-" "encoded private key and a PEM-encoded certificate chain." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:91 +#: ../../source/how-to-run-flower-using-docker.rst:97 msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `_ page contains a section that " -"will guide you through the process." +"enable-ssl-connections.html#certificates>`__ page contains a section that" +" will guide you through the process." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:95 +#: ../../source/how-to-run-flower-using-docker.rst:101 msgid "" "Assuming all files we need are in the local ``certificates`` directory, " -"we can use the flag ``-v`` to mount the local directory into the " +"we can use the flag ``--volume`` to mount the local directory into the " "``/app/`` directory of the container. This allows the SuperLink to access" " the files within the container. Finally, we pass the names of the " "certificates to the SuperLink with the ``--certificates`` flag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:107 +#: ../../source/how-to-run-flower-using-docker.rst:113 msgid "Flower SuperNode" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:109 +#: ../../source/how-to-run-flower-using-docker.rst:115 msgid "" "The SuperNode Docker image comes with a pre-installed version of Flower " "and serves as a base for building your own SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:114 +#: ../../source/how-to-run-flower-using-docker.rst:120 msgid "" "The SuperNode Docker image currently works only with the 1.9.0-nightly " "release. A stable version will be available when Flower 1.9.0 (stable) " "gets released (ETA: May). A SuperNode nightly image must be paired with " -"the corresponding SuperLink nightly image released on the same day. To " -"ensure the versions are in sync, using the concrete tag, e.g., " -"``1.9.0.dev20240501`` instead of ``nightly`` is recommended." +"the corresponding SuperLink and ServerApp nightly images released on the " +"same day. To ensure the versions are in sync, using the concrete tag, " +"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:119 +#: ../../source/how-to-run-flower-using-docker.rst:126 msgid "" -"We will use the ``app-pytorch`` example, which you can find in the Flower" -" repository, to illustrate how you can dockerize your client-app." +"We will use the ``quickstart-pytorch`` example, which you can find in the" +" Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:125 +#: ../../source/how-to-run-flower-using-docker.rst:134 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment. You can skip the first part if you want to run " -"your client-app instead of the ``app-pytorch`` example." +"your ClientApp instead of the ``quickstart-pytorch`` example." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:138 +msgid "Clone the Flower repository." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:143 +#: ../../source/how-to-run-flower-using-docker.rst:152 msgid "Creating a SuperNode Dockerfile" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:145 +#: ../../source/how-to-run-flower-using-docker.rst:154 +#: ../../source/how-to-run-flower-using-docker.rst:289 msgid "Let's assume the following project layout:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:156 +#: ../../source/how-to-run-flower-using-docker.rst:163 msgid "" -"First, we need to create a Dockerfile in the directory where the " -"``ClientApp`` code is located. If you use the ``app-pytorch`` example, " -"create a new file called ``Dockerfile`` in ``examples/app-pytorch``." +"First, we need to create a ``requirements.txt`` file in the directory " +"where the ``ClientApp`` code is located. In the file, we list all the " +"dependencies that the ClientApp requires." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:175 +msgid "" +"Note that `flwr `__ is already installed " +"in the ``flwr/supernode`` base image, so you only need to include other " +"package dependencies in your ``requirements.txt``, such as ``torch``, " +"``tensorflow``, etc." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:160 +#: ../../source/how-to-run-flower-using-docker.rst:179 msgid "" -"The ``Dockerfile`` contains the instructions that assemble the SuperNode " -"image." +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.supernode`` in ``examples" +"/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:173 +#: ../../source/how-to-run-flower-using-docker.rst:182 +msgid "" +"The ``Dockerfile.supernode`` contains the instructions that assemble the " +"SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:196 msgid "" "In the first two lines, we instruct Docker to use the SuperNode image " "tagged ``nightly`` as a base image and set our working directory to " "``/app``. The following instructions will now be executed in the ``/app``" -" directory. Next, we install the ``ClientApp`` dependencies by copying " -"the ``requirements.txt`` file into the image and run ``pip install``. In " -"the last two lines, we copy the ``ClientApp`` code (``client.py`` and " -"``task.py``) into the image and set the entry point to ``flower-client-" -"app``." +" directory. Next, we install the ClientApp dependencies by copying the " +"``requirements.txt`` file into the image and run ``pip install``. In the " +"last two lines, we copy the ``client.py`` module into the image and set " +"the entry point to ``flower-client-app`` with the argument " +"``client:app``. The argument is the object reference of the ClientApp " +"(``:``) that will be run inside the ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:181 +#: ../../source/how-to-run-flower-using-docker.rst:205 msgid "Building the SuperNode Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:183 +#: ../../source/how-to-run-flower-using-docker.rst:207 msgid "" "Next, we build the SuperNode Docker image by running the following " -"command in the directory where Dockerfile and client-app code are " -"located." +"command in the directory where Dockerfile and ClientApp code are located." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:190 +#: ../../source/how-to-run-flower-using-docker.rst:214 msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:195 +#: ../../source/how-to-run-flower-using-docker.rst:219 msgid "Running the SuperNode Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:197 +#: ../../source/how-to-run-flower-using-docker.rst:221 msgid "Now that we have built the SuperNode image, we can finally run it." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:205 +#: ../../source/how-to-run-flower-using-docker.rst:229 +#: ../../source/how-to-run-flower-using-docker.rst:345 msgid "Let's break down each part of this command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:207 +#: ../../source/how-to-run-flower-using-docker.rst:231 +#: ../../source/how-to-run-flower-using-docker.rst:347 msgid "``docker run``: This is the command to run a new Docker container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:208 +#: ../../source/how-to-run-flower-using-docker.rst:232 +#: ../../source/how-to-run-flower-using-docker.rst:348 msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst +#: ../../source/how-to-run-flower-using-docker.rst:233 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "" +#: ../../source/how-to-run-flower-using-docker.rst:234 +#: ../../source/how-to-run-flower-using-docker.rst:350 +msgid "``--insecure``: This option enables insecure communication." +msgstr "" + #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``client:app``: The object reference of the ``ClientApp`` " -"(``:``)." +"``--server 192.168.1.100:9092``: This option specifies the address of the" +" SuperLinks Fleet" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst +msgid "API to connect to. Remember to update it with your SuperLink IP." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:248 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your SuperNodes." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:252 +msgid "" +"Any argument that comes after the tag is passed to the Flower SuperNode " +"binary. To see all available flags that the SuperNode supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:262 msgid "" -"It points to the ``ClientApp`` that will be run inside the SuperNode " +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your SuperNode container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:264 +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the SuperNode to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " "container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:212 -msgid "``--insecure``: This option enables insecure communication." +#: ../../source/how-to-run-flower-using-docker.rst:275 +msgid "Flower ServerApp" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst +#: ../../source/how-to-run-flower-using-docker.rst:277 msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the" -" SuperLinks Fleet" +"The procedure for building and running a ServerApp image is almost " +"identical to the SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:279 +msgid "" +"Similar to the SuperNode image, the ServerApp Docker image comes with a " +"pre-installed version of Flower and serves as a base for building your " +"own ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:282 +msgid "" +"We will use the same ``quickstart-pytorch`` example as we do in the " +"Flower SuperNode section. If you have not already done so, please follow " +"the `SuperNode Prerequisites`_ before proceeding." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:287 +msgid "Creating a ServerApp Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:298 +msgid "" +"First, we need to create a Dockerfile in the directory where the " +"``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.serverapp`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:302 +msgid "" +"The ``Dockerfile.serverapp`` contains the instructions that assemble the " +"ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:313 +msgid "" +"In the first two lines, we instruct Docker to use the ServerApp image " +"tagged ``1.8.0`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. In the last two lines, we copy the ``server.py`` module into " +"the image and set the entry point to ``flower-server-app`` with the " +"argument ``server:app``. The argument is the object reference of the " +"ServerApp (``:``) that will be run inside the " +"ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:321 +msgid "Building the ServerApp Docker image" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:323 +msgid "" +"Next, we build the ServerApp Docker image by running the following " +"command in the directory where Dockerfile and ServerApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:330 +msgid "" +"We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:335 +msgid "Running the ServerApp Docker image" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:337 +msgid "Now that we have built the ServerApp image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:349 +msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst -msgid "API to connect to. Remember to update it with your SuperLink IP." +msgid "" +"``--server 192.168.1.100:9091``: This option specifies the address of the" +" SuperLinks Driver" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:226 +#: ../../source/how-to-run-flower-using-docker.rst:363 msgid "" -"Any argument that comes after the tag is passed to the Flower SuperNode " -"binary. To see all available flags that the SuperNode supports, run:" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your ServerApps." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:367 +msgid "" +"Any argument that comes after the tag is passed to the Flower ServerApp " +"binary. To see all available flags that the ServerApp supports, run:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:236 +#: ../../source/how-to-run-flower-using-docker.rst:377 msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " -"your SuperNode container." +"your ServerApp container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:238 +#: ../../source/how-to-run-flower-using-docker.rst:379 msgid "" "Assuming the certificate already exists locally, we can use the flag " -"``-v`` to mount the local certificate into the container's ``/app/`` " -"directory. This allows the SuperNode to access the certificate within the" -" container. Use the ``--certificates`` flag when starting the container." +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the ServerApp to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:249 +#: ../../source/how-to-run-flower-using-docker.rst:390 msgid "Advanced Docker options" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:393 msgid "Using a different Flower version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:254 +#: ../../source/how-to-run-flower-using-docker.rst:395 msgid "" "If you want to use a different version of Flower, for example Flower " "nightly, you can do so by changing the tag. All available versions are on" -" `Docker Hub `_." +" `Docker Hub `__." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:259 +#: ../../source/how-to-run-flower-using-docker.rst:400 msgid "Pinning a Docker image to a specific version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:261 +#: ../../source/how-to-run-flower-using-docker.rst:402 msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " @@ -5130,21 +5131,21 @@ msgid "" "instead of the tag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:266 +#: ../../source/how-to-run-flower-using-docker.rst:407 msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:273 +#: ../../source/how-to-run-flower-using-docker.rst:414 msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:282 +#: ../../source/how-to-run-flower-using-docker.rst:423 msgid "Setting environment variables" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:284 +#: ../../source/how-to-run-flower-using-docker.rst:425 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." @@ -5617,7 +5618,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 -#: ../../source/how-to-upgrade-to-flower-next.rst:42 +#: ../../source/how-to-upgrade-to-flower-next.rst:43 msgid "Install update" msgstr "" @@ -5661,7 +5662,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 -#: ../../source/how-to-upgrade-to-flower-next.rst:99 +#: ../../source/how-to-upgrade-to-flower-next.rst:100 msgid "Required changes" msgstr "" @@ -5865,7 +5866,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 -#: ../../source/how-to-upgrade-to-flower-next.rst:316 +#: ../../source/how-to-upgrade-to-flower-next.rst:317 msgid "Further help" msgstr "" @@ -5903,44 +5904,44 @@ msgstr "" msgid "Let's dive in!" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:47 +#: ../../source/how-to-upgrade-to-flower-next.rst:48 msgid "" "Here's how to update an existing installation of Flower to Flower Next " "with ``pip``:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:53 +#: ../../source/how-to-upgrade-to-flower-next.rst:54 msgid "or if you need Flower Next with simulation:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:60 +#: ../../source/how-to-upgrade-to-flower-next.rst:61 msgid "" "Ensure you set the following version constraint in your " "``requirements.txt``" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:70 +#: ../../source/how-to-upgrade-to-flower-next.rst:71 msgid "or ``pyproject.toml``:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:81 +#: ../../source/how-to-upgrade-to-flower-next.rst:82 msgid "Using Poetry" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:83 +#: ../../source/how-to-upgrade-to-flower-next.rst:84 msgid "" "Update the ``flwr`` dependency in ``pyproject.toml`` and then reinstall " "(don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` before " "running ``poetry install``)." msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:85 +#: ../../source/how-to-upgrade-to-flower-next.rst:86 msgid "" "Ensure you set the following version constraint in your " "``pyproject.toml``:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:101 +#: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" "In Flower Next, the *infrastructure* and *application layers* have been " "decoupled. Instead of starting a client in code via ``start_client()``, " @@ -5953,31 +5954,31 @@ msgid "" "way:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:108 +#: ../../source/how-to-upgrade-to-flower-next.rst:109 msgid "|clientapp_link|_" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:109 +#: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" "Wrap your existing client with |clientapp_link|_ instead of launching it " "via |startclient_link|_. Here's an example:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:131 +#: ../../source/how-to-upgrade-to-flower-next.rst:132 msgid "|serverapp_link|_" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:132 +#: ../../source/how-to-upgrade-to-flower-next.rst:133 msgid "" "Wrap your existing strategy with |serverapp_link|_ instead of starting " "the server via |startserver_link|_. Here's an example:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:153 +#: ../../source/how-to-upgrade-to-flower-next.rst:154 msgid "Deployment" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:154 +#: ../../source/how-to-upgrade-to-flower-next.rst:155 msgid "" "Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " "in sequence, |flowernext_clientapp_link|_ (2x) and " @@ -5985,56 +5986,56 @@ msgid "" " `server.py` as Python scripts." msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:157 +#: ../../source/how-to-upgrade-to-flower-next.rst:158 msgid "" "Here's an example to start the server without HTTPS (only for " "prototyping):" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:173 +#: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" "Here's another example to start with HTTPS. Use the ``--certificates`` " "command line argument to pass paths to (CA certificate, server " "certificate, and server private key)." msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:200 +#: ../../source/how-to-upgrade-to-flower-next.rst:201 msgid "Simulation in CLI" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:201 +#: ../../source/how-to-upgrade-to-flower-next.rst:202 msgid "" "Wrap your existing client and strategy with |clientapp_link|_ and " "|serverapp_link|_, respectively. There is no need to use |startsim_link|_" " anymore. Here's an example:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:231 +#: ../../source/how-to-upgrade-to-flower-next.rst:232 msgid "" -"Run |runsimcli_link|_ in CLI and point to the ``server_app`` / " +"Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " "``client_app`` object in the code instead of executing the Python script." " Here's an example (assuming the ``server_app`` and ``client_app`` " "objects are in a ``sim.py`` module):" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:248 +#: ../../source/how-to-upgrade-to-flower-next.rst:249 msgid "" "Set default resources for each |clientapp_link|_ using the ``--backend-" "config`` command line argument instead of setting the " "``client_resources`` argument in |startsim_link|_. Here's an example:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:274 +#: ../../source/how-to-upgrade-to-flower-next.rst:275 msgid "Simulation in a Notebook" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:275 +#: ../../source/how-to-upgrade-to-flower-next.rst:276 msgid "" "Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " "an example:" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:318 +#: ../../source/how-to-upgrade-to-flower-next.rst:319 msgid "" "Some official `Flower code examples `_ " "are already updated to Flower Next so they can serve as a reference for " @@ -6045,18 +6046,18 @@ msgid "" " or share and learn from others about migrating to Flower Next." msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:324 +#: ../../source/how-to-upgrade-to-flower-next.rst:325 msgid "Important" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:327 +#: ../../source/how-to-upgrade-to-flower-next.rst:328 msgid "" "As we continuously enhance Flower Next at a rapid pace, we'll be " "periodically updating this guide. Please feel free to share any feedback " "with us!" msgstr "" -#: ../../source/how-to-upgrade-to-flower-next.rst:333 +#: ../../source/how-to-upgrade-to-flower-next.rst:334 msgid "Happy migrating! 🚀" msgstr "" @@ -10212,10 +10213,6 @@ msgstr "" msgid "run\\_superlink" msgstr "" -#: ../../source/ref-api/flwr.server.start_driver.rst:2 -msgid "start\\_driver" -msgstr "" - #: ../../source/ref-api/flwr.server.start_server.rst:2 msgid "start\\_server" msgstr "" @@ -13308,10 +13305,6 @@ msgid "" " enabled, DEBUG-level logs will be displayed." msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation_from_cli.rst:2 -msgid "run\\_simulation\\_from\\_cli" -msgstr "" - #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 msgid "start\\_simulation" msgstr "" @@ -19595,7 +19588,7 @@ msgid "" "We now have a list of ten training sets and ten validation sets " "(``trainloaders`` and ``valloaders``) representing the data of ten " "different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4500 training examples and 500 validation examples. There's also a " +" 4000 training examples and 1000 validation examples. There's also a " "single ``testloader`` (we did not split the test set). Again, this is " "only necessary for building research or educational systems, actual " "federated learning systems have their data naturally distributed across " @@ -20220,7 +20213,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|191c6b8b5e1d46f99de4872746afa8af|" +msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 @@ -20235,7 +20228,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|21b83f3feb024a049617190555a13549|" +msgid "|5aa1711387d74d0f8b9c499e1a51627e|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 @@ -20256,7 +20249,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|0dd15b4df7e3422f88aaf74cb401bfa7|" +msgid "|2bc8e069228d4873804061ff4a95048c|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 @@ -20272,7 +20265,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|60e16f6be7354ca793444e01aa7adf25|" +msgid "|c258488766324dc9a6807f0e7c4fd5f4|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 @@ -20288,7 +20281,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|a7032acbd65948a8beef8bccbbb9b83a|" +msgid "|d5f962c3f4ec48529efda980868c14b0|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 @@ -20303,7 +20296,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|dd0e05706e584ee29e07cd39e6af5498|" +msgid "|a5eccea18d4c43a68b54b65043cabef8|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 @@ -20323,7 +20316,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|2a2031018a1c4f81a69ea16df4947bd0|" +msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 @@ -20338,7 +20331,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|5e841497933340d3b5c2efbf37e3e6a6|" +msgid "|241fc906441a4f038c625a19d30d01b2|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 @@ -20478,7 +20471,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|19687aecbc3a485da999b66fe2051005|" +msgid "|0aa5aa05810b44b6a835cecce28f3137|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 @@ -20502,7 +20495,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|32ef0bbade4d4500b7be97cf62405661|" +msgid "|c742940dd4bf4de09d8d0d5e8d179638|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 @@ -20526,7 +20519,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|9d57ed324b304a698263f5a983a56a6b|" +msgid "|1f169ab4601a47e1a226f1628f4ebddb|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 @@ -20549,7 +20542,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|d41510e6781c4bf18c234c6bfb8d4937|" +msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 @@ -20587,7 +20580,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|a0198a7ebbfb4b9289e7312711cbc967|" +msgid "|72939caf6e294b0986fee6dde96614d7|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 @@ -20681,7 +20674,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|2c13f726c8c843fc8aae997bf906125b|" +msgid "|83a8daee45da4a98b8d6f24ae098fc50|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 @@ -20709,3 +20702,526 @@ msgid "" "pytorch.html>`__ shows how to build a simple federated learning system " "with PyTorch and Flower." msgstr "" + +#~ msgid "" +#~ "If you want to use your own " +#~ "base image instead of the official " +#~ "Flower base image, all you need to" +#~ " do is set the ``BASE_REPOSITORY``, " +#~ "``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build " +#~ "arguments. .. code-block:: bash" +#~ msgstr "" + +#~ msgid "$ cd src/docker/superlink/ $ docker build \\" +#~ msgstr "" + +#~ msgid "" +#~ "--build-arg BASE_REPOSITORY=flwr_base \\ " +#~ "--build-arg PYTHON_VERSION=3.11 \\ --build-" +#~ "arg UBUNTU_VERSION=ubuntu22.04 \\ --build-arg" +#~ " FLWR_VERSION=1.8.0 \\ -t flwr_superlink:0.1.0" +#~ " ." +#~ msgstr "" + +#~ msgid "" +#~ "It is important to follow the " +#~ "instructions described in comments. For " +#~ "instance, in order to not break " +#~ "how our changelog system works, you " +#~ "should read the information above the" +#~ " ``Changelog entry`` section carefully. You" +#~ " can also checkout some examples and" +#~ " details in the :ref:`changelogentry` " +#~ "appendix." +#~ msgstr "" + +#~ msgid "Open a PR (as shown above)" +#~ msgstr "" + +#~ msgid "How to write a good PR title" +#~ msgstr "" + +#~ msgid "" +#~ "A well-crafted PR title helps team" +#~ " members quickly understand the purpose " +#~ "and scope of the changes being " +#~ "proposed. Here's a guide to help " +#~ "you write a good GitHub PR title:" +#~ msgstr "" + +#~ msgid "" +#~ "1. Be Clear and Concise: Provide a" +#~ " clear summary of the changes in " +#~ "a concise manner. 1. Use Actionable " +#~ "Verbs: Start with verbs like \"Add,\"" +#~ " \"Update,\" or \"Fix\" to indicate " +#~ "the purpose. 1. Include Relevant " +#~ "Information: Mention the affected feature " +#~ "or module for context. 1. Keep it" +#~ " Short: Avoid lengthy titles for easy" +#~ " readability. 1. Use Proper Capitalization" +#~ " and Punctuation: Follow grammar rules " +#~ "for clarity." +#~ msgstr "" + +#~ msgid "" +#~ "Let's start with a few examples " +#~ "for titles that should be avoided " +#~ "because they do not provide meaningful" +#~ " information:" +#~ msgstr "" + +#~ msgid "Implement Algorithm" +#~ msgstr "" + +#~ msgid "Database" +#~ msgstr "" + +#~ msgid "Add my_new_file.py to codebase" +#~ msgstr "" + +#~ msgid "Improve code in module" +#~ msgstr "" + +#~ msgid "Change SomeModule" +#~ msgstr "" + +#~ msgid "" +#~ "Here are a few positive examples " +#~ "which provide helpful information without " +#~ "repeating how they do it, as that" +#~ " is already visible in the \"Files" +#~ " changed\" section of the PR:" +#~ msgstr "" + +#~ msgid "Update docs banner to mention Flower Summit 2023" +#~ msgstr "" + +#~ msgid "Remove unnecessary XGBoost dependency" +#~ msgstr "" + +#~ msgid "Remove redundant attributes in strategies subclassing FedAvg" +#~ msgstr "" + +#~ msgid "" +#~ "Add CI job to deploy the staging" +#~ " system when the ``main`` branch " +#~ "changes" +#~ msgstr "" + +#~ msgid "" +#~ "Add new amazing library which will " +#~ "be used to improve the simulation " +#~ "engine" +#~ msgstr "" + +#~ msgid "Changelog entry" +#~ msgstr "" + +#~ msgid "" +#~ "When opening a new PR, inside its" +#~ " description, there should be a " +#~ "``Changelog entry`` header." +#~ msgstr "" + +#~ msgid "" +#~ "Above this header you should see " +#~ "the following comment that explains how" +#~ " to write your changelog entry:" +#~ msgstr "" + +#~ msgid "" +#~ "Inside the following 'Changelog entry' " +#~ "section, you should put the description" +#~ " of your changes that will be " +#~ "added to the changelog alongside your" +#~ " PR title." +#~ msgstr "" + +#~ msgid "" +#~ "If the section is completely empty " +#~ "(without any token) or non-existent, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." +#~ msgstr "" + +#~ msgid "" +#~ "If the section contains some text " +#~ "other than tokens, it will use it" +#~ " to add a description to the " +#~ "change." +#~ msgstr "" + +#~ msgid "" +#~ "If the section contains one of the" +#~ " following tokens it will ignore any" +#~ " other text and put the PR " +#~ "under the corresponding section of the" +#~ " changelog:" +#~ msgstr "" + +#~ msgid " is for classifying a PR as a general improvement." +#~ msgstr "" + +#~ msgid " is to not add the PR to the changelog" +#~ msgstr "" + +#~ msgid " is to add a general baselines change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general examples change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general sdk change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general simulations change to the PR" +#~ msgstr "" + +#~ msgid "Note that only one token should be used." +#~ msgstr "" + +#~ msgid "" +#~ "Its content must have a specific " +#~ "format. We will break down what " +#~ "each possibility does:" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains nothing or doesn't exist, " +#~ "the following text will be added " +#~ "to the changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains a description (and no " +#~ "token), the following text will be " +#~ "added to the changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, nothing will change" +#~ " in the changelog." +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text" +#~ " will be added to the changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text " +#~ "will be added to the changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "" + +#~ msgid "" +#~ "Note that only one token must be" +#~ " provided, otherwise, only the first " +#~ "action (in the order listed above), " +#~ "will be performed." +#~ msgstr "" + +#~ msgid "" +#~ "We recommend you to check out the" +#~ " complete `code example " +#~ "`_ demonstrating federated " +#~ "learning with Flower in an authenticated" +#~ " setting." +#~ msgstr "" + +#~ msgid "Let's break down the :code:`--require-client-authentication` flag:" +#~ msgstr "" + +#~ msgid "" +#~ "The first argument is a path to" +#~ " a CSV file storing all known " +#~ "node public keys. You need to " +#~ "store all known node public keys " +#~ "that are allowed to participate in " +#~ "a federation in one CSV file " +#~ "(:code:`.csv`)." +#~ msgstr "" + +#~ msgid "" +#~ "The second and third arguments are " +#~ "paths to the server's private and " +#~ "public keys. For development purposes, " +#~ "you can generate a private and " +#~ "public key pair using :code:`ssh-keygen" +#~ " -t ecdsa -b 384`." +#~ msgstr "" + +#~ msgid "" +#~ "The :code:`--authentication-keys` flag expects" +#~ " two arguments: a path to the " +#~ "node's private key file and a path" +#~ " to the node's public key file. " +#~ "For development purposes, you can " +#~ "generate a private and public key " +#~ "pair using :code:`ssh-keygen -t ecdsa" +#~ " -b 384`." +#~ msgstr "" + +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`_." +#~ msgstr "" + +#~ msgid "" +#~ "The ``--insecure`` flag enables insecure " +#~ "communication (using HTTP, not HTTPS) " +#~ "and should only be used for " +#~ "testing purposes. We strongly recommend " +#~ "enabling `SSL `_ when " +#~ "deploying to a production environment." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to persist the state" +#~ " of the SuperLink on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``-v`` to" +#~ " mount the user's home directory " +#~ "(``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." +#~ msgstr "" + +#~ msgid "" +#~ "For testing purposes, you can generate" +#~ " your own self-signed certificates. " +#~ "The `Enable SSL connections " +#~ "`_ page contains " +#~ "a section that will guide you " +#~ "through the process." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``-v`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the SuperLink to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the SuperLink with the" +#~ " ``--certificates`` flag." +#~ msgstr "" + +#~ msgid "" +#~ "The SuperNode Docker image currently " +#~ "works only with the 1.9.0-nightly " +#~ "release. A stable version will be " +#~ "available when Flower 1.9.0 (stable) " +#~ "gets released (ETA: May). A SuperNode" +#~ " nightly image must be paired with" +#~ " the corresponding SuperLink nightly image" +#~ " released on the same day. To " +#~ "ensure the versions are in sync, " +#~ "using the concrete tag, e.g., " +#~ "``1.9.0.dev20240501`` instead of ``nightly`` " +#~ "is recommended." +#~ msgstr "" + +#~ msgid "" +#~ "We will use the ``app-pytorch`` " +#~ "example, which you can find in the" +#~ " Flower repository, to illustrate how " +#~ "you can dockerize your client-app." +#~ msgstr "" + +#~ msgid "" +#~ "Before we can start, we need to" +#~ " meet a few prerequisites in our " +#~ "local development environment. You can " +#~ "skip the first part if you want" +#~ " to run your client-app instead " +#~ "of the ``app-pytorch`` example." +#~ msgstr "" + +#~ msgid "" +#~ "First, we need to create a " +#~ "Dockerfile in the directory where the" +#~ " ``ClientApp`` code is located. If " +#~ "you use the ``app-pytorch`` example, " +#~ "create a new file called ``Dockerfile``" +#~ " in ``examples/app-pytorch``." +#~ msgstr "" + +#~ msgid "" +#~ "The ``Dockerfile`` contains the instructions" +#~ " that assemble the SuperNode image." +#~ msgstr "" + +#~ msgid "" +#~ "In the first two lines, we " +#~ "instruct Docker to use the SuperNode " +#~ "image tagged ``nightly`` as a base " +#~ "image and set our working directory " +#~ "to ``/app``. The following instructions " +#~ "will now be executed in the " +#~ "``/app`` directory. Next, we install the" +#~ " ``ClientApp`` dependencies by copying the" +#~ " ``requirements.txt`` file into the image" +#~ " and run ``pip install``. In the " +#~ "last two lines, we copy the " +#~ "``ClientApp`` code (``client.py`` and " +#~ "``task.py``) into the image and set " +#~ "the entry point to ``flower-client-" +#~ "app``." +#~ msgstr "" + +#~ msgid "" +#~ "Next, we build the SuperNode Docker " +#~ "image by running the following command" +#~ " in the directory where Dockerfile " +#~ "and client-app code are located." +#~ msgstr "" + +#~ msgid "" +#~ "``client:app``: The object reference of " +#~ "the ``ClientApp`` (``:``)." +#~ msgstr "" + +#~ msgid "" +#~ "It points to the ``ClientApp`` that " +#~ "will be run inside the SuperNode " +#~ "container." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``-v`` to mount the local certificate" +#~ " into the container's ``/app/`` directory." +#~ " This allows the SuperNode to access" +#~ " the certificate within the container. " +#~ "Use the ``--certificates`` flag when " +#~ "starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to use a different " +#~ "version of Flower, for example Flower" +#~ " nightly, you can do so by " +#~ "changing the tag. All available versions" +#~ " are on `Docker Hub " +#~ "`_." +#~ msgstr "" + +#~ msgid "" +#~ "Run |runsimcli_link|_ in CLI and point" +#~ " to the ``server_app`` / ``client_app`` " +#~ "object in the code instead of " +#~ "executing the Python script. Here's an" +#~ " example (assuming the ``server_app`` and" +#~ " ``client_app`` objects are in a " +#~ "``sim.py`` module):" +#~ msgstr "" + +#~ msgid "start\\_driver" +#~ msgstr "" + +#~ msgid "run\\_simulation\\_from\\_cli" +#~ msgstr "" + +#~ msgid "" +#~ "We now have a list of ten " +#~ "training sets and ten validation sets" +#~ " (``trainloaders`` and ``valloaders``) " +#~ "representing the data of ten different" +#~ " organizations. Each ``trainloader``/``valloader`` " +#~ "pair contains 4500 training examples and" +#~ " 500 validation examples. There's also " +#~ "a single ``testloader`` (we did not " +#~ "split the test set). Again, this " +#~ "is only necessary for building research" +#~ " or educational systems, actual federated" +#~ " learning systems have their data " +#~ "naturally distributed across multiple " +#~ "partitions." +#~ msgstr "" + +#~ msgid "|191c6b8b5e1d46f99de4872746afa8af|" +#~ msgstr "" + +#~ msgid "|21b83f3feb024a049617190555a13549|" +#~ msgstr "" + +#~ msgid "|0dd15b4df7e3422f88aaf74cb401bfa7|" +#~ msgstr "" + +#~ msgid "|60e16f6be7354ca793444e01aa7adf25|" +#~ msgstr "" + +#~ msgid "|a7032acbd65948a8beef8bccbbb9b83a|" +#~ msgstr "" + +#~ msgid "|dd0e05706e584ee29e07cd39e6af5498|" +#~ msgstr "" + +#~ msgid "|2a2031018a1c4f81a69ea16df4947bd0|" +#~ msgstr "" + +#~ msgid "|5e841497933340d3b5c2efbf37e3e6a6|" +#~ msgstr "" + +#~ msgid "|19687aecbc3a485da999b66fe2051005|" +#~ msgstr "" + +#~ msgid "|32ef0bbade4d4500b7be97cf62405661|" +#~ msgstr "" + +#~ msgid "|9d57ed324b304a698263f5a983a56a6b|" +#~ msgstr "" + +#~ msgid "|d41510e6781c4bf18c234c6bfb8d4937|" +#~ msgstr "" + +#~ msgid "|a0198a7ebbfb4b9289e7312711cbc967|" +#~ msgstr "" + +#~ msgid "|2c13f726c8c843fc8aae997bf906125b|" +#~ msgstr "" + diff --git a/doc/locales/ko/LC_MESSAGES/sphinx.po b/doc/locales/ko/LC_MESSAGES/sphinx.po index bcfa940edeac..fbb6c75085a1 100644 --- a/doc/locales/ko/LC_MESSAGES/sphinx.po +++ b/doc/locales/ko/LC_MESSAGES/sphinx.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-13 09:48+0200\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: ko\n" @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.14.0\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/_templates/base.html:18 msgid "About these documents" @@ -28,6 +28,7 @@ msgid "Index" msgstr "" #: ../../source/_templates/base.html:24 +#: ../../source/_templates/sidebar/search.html:2 msgid "Search" msgstr "" @@ -35,3 +36,7 @@ msgstr "" msgid "Copyright" msgstr "" +#: ../../source/_templates/sidebar/search.html:2 +msgid "Type / to search" +msgstr "" + diff --git a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po index 75a49d95d404..f0127ad93ed7 100644 --- a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po +++ b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po @@ -7,18 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-15 14:23+0000\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: 2024-05-25 11:09+0000\n" "Last-Translator: Gustavo Bertoli \n" -"Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" +"Language-Team: Portuguese (Brazil) \n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n > 1;\n" -"X-Generator: Weblate 5.6-dev\n" -"Generated-By: Babel 2.14.0\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" @@ -33,8 +32,8 @@ msgid "" "`Flower `_ core framework architecture with Edge " "Client Engine" msgstr "" -"`Flower `_ arquitetura principal do framework com Engine " -"do Edge Client" +"`Flower `_ arquitetura principal do framework com " +"Engine do Edge Client" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" @@ -45,8 +44,8 @@ msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" msgstr "" -"`Flower `_ arquitetura principal do framework com Engine " -"do Virtual Client" +"`Flower `_ arquitetura principal do framework com " +"Engine do Virtual Client" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" @@ -59,28 +58,29 @@ msgid "" "`Flower `_ core framework architecture with both " "Virtual Client Engine and Edge Client Engine" msgstr "" -"`Flower `_ arquitetura principal do framework com ambas " -"engines do Virtual Client e do Edge Client" +"`Flower `_ arquitetura principal do framework com " +"ambas engines do Virtual Client e do Edge Client" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" msgstr "Como construir imagens Docker do Flower localmente" #: ../../source/contributor-how-to-build-docker-images.rst:4 +#, fuzzy msgid "" "Flower provides pre-made docker images on `Docker Hub " -"`_ that include all necessary " -"dependencies for running the server. You can also build your own custom " -"docker images from scratch with a different version of Python or Ubuntu " -"if that is what you need. In this guide, we will explain what images " -"exist and how to build them locally." -msgstr "" -"Flower disponibiliza imagens docker em `Docker Hub `_ que incluem todas as dependências necesárias para " -"executar o servidor. Você pode também compilar suas próprias imagens docker " -"customizadas do zero com uma versão diferente do Python ou do Ubuntu se isso " -"for o que você precisa. Neste guia, explicaremos quais imagens existem e " -"como compilar localmente." +"`_ that include all necessary dependencies" +" for running the SuperLink. You can also build your own custom docker " +"images from scratch with a different version of Python or Ubuntu if that " +"is what you need. In this guide, we will explain what images exist and " +"how to build them locally." +msgstr "" +"Flower disponibiliza imagens docker em `Docker Hub " +"`_ que incluem todas as " +"dependências necesárias para executar o servidor. Você pode também " +"compilar suas próprias imagens docker customizadas do zero com uma versão" +" diferente do Python ou do Ubuntu se isso for o que você precisa. Neste " +"guia, explicaremos quais imagens existem e como compilar localmente." #: ../../source/contributor-how-to-build-docker-images.rst:9 msgid "" @@ -95,10 +95,12 @@ msgid "Clone the flower repository." msgstr "Clone o repositório do flower." #: ../../source/contributor-how-to-build-docker-images.rst:17 +#: ../../source/how-to-run-flower-using-docker.rst:144 msgid "Verify the Docker daemon is running." msgstr "Verifique que o serviço Docker está rodando." #: ../../source/contributor-how-to-build-docker-images.rst:19 +#: ../../source/how-to-run-flower-using-docker.rst:146 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." @@ -107,20 +109,20 @@ msgstr "" "` que cobre este passo em mais detalhes." #: ../../source/contributor-how-to-build-docker-images.rst:23 +#, fuzzy msgid "" -"Currently, Flower provides two images, a base image and a server image. " -"There will also be a client image soon. The base image, as the name " -"suggests, contains basic dependencies that both the server and the client" -" need. This includes system dependencies, Python and Python tools. The " -"server image is based on the base image, but it additionally installs the" -" Flower server using ``pip``." +"Currently, Flower provides two images, a ``base`` image and a " +"``superlink`` image. The base image, as the name suggests, contains basic" +" dependencies that the SuperLink needs. This includes system " +"dependencies, Python and Python tools. The SuperLink image is based on " +"the base image, but it additionally installs the SuperLink using ``pip``." msgstr "" "Atualmente, Flower fornece duas imagens, uma imagem base e uma imagem de " -"servidor. Também haverá uma imagem de cliente em breve. A imagem base, como " -"o nome sugere, contém dependências básicas que tanto o servidor quanto o " -"cliente precisam. Isso inclui dependências do sistema, Python e ferramentas " -"Python. A imagem do servidor é baseada na imagem base, mas também instala o " -"servidor Flower usando ``pip```." +"servidor. Também haverá uma imagem de cliente em breve. A imagem base, " +"como o nome sugere, contém dependências básicas que tanto o servidor " +"quanto o cliente precisam. Isso inclui dependências do sistema, Python e " +"ferramentas Python. A imagem do servidor é baseada na imagem base, mas " +"também instala o servidor Flower usando ``pip```." #: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" @@ -129,27 +131,28 @@ msgid "" "``src/docker``." msgstr "" "As instruções de compilação que montam as imagens estão localizadas nos " -"respectivos Dockerfiles. Você pode encontrá-los nos subdiretórios ``src/" -"docker```." +"respectivos Dockerfiles. Você pode encontrá-los nos subdiretórios " +"``src/docker```." #: ../../source/contributor-how-to-build-docker-images.rst:31 +#, fuzzy msgid "" -"Both, base and server image are configured via build arguments. Through " -"build arguments, we can make our build more flexible. For example, in the" -" base image, we can specify the version of Python to install using the " -"``PYTHON_VERSION`` build argument. Some of the build arguments have " -"default values, others must be specified when building the image. All " -"available build arguments for each image are listed in one of the tables " -"below." -msgstr "" -"Ambas, imagens base e do servidor são configuradas através dos argumentos de " -"compilação. Através dos argumentos de compilação, podemos tornar nossa " -"compilação mais flexível. Por exemplo, na imagem base, podemos especificar a " -"versão do Python para instalar usando o argumento de compilação " -"`PYTHON_VERSION`. Alguns dos argumentos de compilação têm valores padrão, " -"outros devem ser especificados ao compilar a imagem. Todos os argumentos de " -"compilação disponíveis para cada imagem estão listados em uma das tabelas " -"abaixo." +"Both, base and SuperLink image are configured via build arguments. " +"Through build arguments, we can make our build more flexible. For " +"example, in the base image, we can specify the version of Python to " +"install using the ``PYTHON_VERSION`` build argument. Some of the build " +"arguments have default values, others must be specified when building the" +" image. All available build arguments for each image are listed in one of" +" the tables below." +msgstr "" +"Ambas, imagens base e do servidor são configuradas através dos argumentos" +" de compilação. Através dos argumentos de compilação, podemos tornar " +"nossa compilação mais flexível. Por exemplo, na imagem base, podemos " +"especificar a versão do Python para instalar usando o argumento de " +"compilação `PYTHON_VERSION`. Alguns dos argumentos de compilação têm " +"valores padrão, outros devem ser especificados ao compilar a imagem. " +"Todos os argumentos de compilação disponíveis para cada imagem estão " +"listados em uma das tabelas abaixo." #: ../../source/contributor-how-to-build-docker-images.rst:38 msgid "Building the base image" @@ -176,6 +179,7 @@ msgid "Example" msgstr "Exemplo" #: ../../source/contributor-how-to-build-docker-images.rst:48 +#: ../../source/contributor-how-to-build-docker-images.rst:94 msgid "``PYTHON_VERSION``" msgstr "``PYTHON_VERSION``" @@ -186,7 +190,7 @@ msgstr "Versão do ``python`` a ser instalada." #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 #: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:100 +#: ../../source/contributor-how-to-build-docker-images.rst:108 msgid "Yes" msgstr "Sim" @@ -219,6 +223,7 @@ msgid "``69.0.2``" msgstr "``69.0.2``" #: ../../source/contributor-how-to-build-docker-images.rst:60 +#: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "``UBUNTU_VERSION``" msgstr "``UBUNTU_VERSION``" @@ -245,11 +250,12 @@ msgid "" "needs. These values serve as examples only." msgstr "" "O nome da imagem é ``flwr_base`` com a tag ``0.1.0``. Lembre-se que os " -"argumentos de construção assim como o nome e a tag podem ser adaptados de " -"acordo com suas necessidades. Estes valores servem apenas como exemplo." +"argumentos de construção assim como o nome e a tag podem ser adaptados de" +" acordo com suas necessidades. Estes valores servem apenas como exemplo." #: ../../source/contributor-how-to-build-docker-images.rst:80 -msgid "Building the server image" +#, fuzzy +msgid "Building the SuperLink image" msgstr "Construindo a imagem do servidor" #: ../../source/contributor-how-to-build-docker-images.rst:90 @@ -261,67 +267,92 @@ msgid "The repository name of the base image." msgstr "O nome do repositório da imagem base." #: ../../source/contributor-how-to-build-docker-images.rst:92 -msgid "Defaults to ``flwr/server``." +#, fuzzy +msgid "Defaults to ``flwr/base``." msgstr "Pré-definido para ``flwr/server``." -#: ../../source/contributor-how-to-build-docker-images.rst:94 -msgid "``BASE_IMAGE_TAG``" -msgstr "``BASE_IMAGE_TAG``" - #: ../../source/contributor-how-to-build-docker-images.rst:95 #, fuzzy -msgid "The image tag of the base image." -msgstr "A tag da imagem da imagem base." +msgid "The Python version of the base image." +msgstr "O nome do repositório da imagem base." #: ../../source/contributor-how-to-build-docker-images.rst:96 -msgid "Defaults to ``py3.11-ubuntu22.04``." +#, fuzzy +msgid "Defaults to ``py3.11``." +msgstr "Como padrão ``22.04``." + +#: ../../source/contributor-how-to-build-docker-images.rst:99 +#, fuzzy +msgid "The Ubuntu version of the base image." +msgstr "O nome do repositório da imagem base." + +#: ../../source/contributor-how-to-build-docker-images.rst:100 +#, fuzzy +msgid "Defaults to ``ubuntu22.04``." msgstr "Pré-definido para ``py3.11-ubuntu22.04``." -#: ../../source/contributor-how-to-build-docker-images.rst:98 +#: ../../source/contributor-how-to-build-docker-images.rst:102 +#, fuzzy +msgid "``FLWR_PACKAGE``" +msgstr "``FLWR_VERSION``" + +#: ../../source/contributor-how-to-build-docker-images.rst:103 +msgid "The PyPI package to install." +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:104 +#, fuzzy +msgid "Defaults to ``flwr``." +msgstr "Pré-definido para ``flwr/server``." + +#: ../../source/contributor-how-to-build-docker-images.rst:106 msgid "``FLWR_VERSION``" msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:99 +#: ../../source/contributor-how-to-build-docker-images.rst:107 msgid "Version of Flower to be installed." msgstr "Versão do Flower a ser instalada." -#: ../../source/contributor-how-to-build-docker-images.rst:101 -msgid "``1.7.0``" +#: ../../source/contributor-how-to-build-docker-images.rst:109 +#, fuzzy +msgid "``1.8.0``" msgstr "``1.7.0``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 +#: ../../source/contributor-how-to-build-docker-images.rst:112 +#, fuzzy msgid "" -"The following example creates a server image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.7.0:" +"The following example creates a SuperLink image with the official Flower " +"base image py3.11-ubuntu22.04 and Flower 1.8.0:" msgstr "" -"O exemplo a seguir cria uma imagem de servidor com a imagem base oficial do " -"Flower py3.11-ubuntu22.04 e Flower 1.7.0:" +"O exemplo a seguir cria uma imagem de servidor com a imagem base oficial " +"do Flower py3.11-ubuntu22.04 e Flower 1.7.0:" -#: ../../source/contributor-how-to-build-docker-images.rst:114 +#: ../../source/contributor-how-to-build-docker-images.rst:122 +#, fuzzy msgid "" -"The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that" -" the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " +"that the build arguments as well as the name and tag can be adapted to " +"your needs. These values serve as examples only." msgstr "" "O nome da imagem é ``flwr_server`` e a tag ``0.1.0``. Lembre-se que os " "argumentos de compilação, bem como o nome e a tag podem ser adaptados às " "suas necessidades. Esses valores servem apenas como exemplos." -#: ../../source/contributor-how-to-build-docker-images.rst:117 +#: ../../source/contributor-how-to-build-docker-images.rst:125 +#, fuzzy msgid "" "If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY`` and " -"``BASE_IMAGE_TAG`` build arguments. The value of ``BASE_REPOSITORY`` must" -" match the name of your image and the value of ``BASE_IMAGE_TAG`` must " -"match the tag of your image." +"base image, all you need to do is set the ``BASE_REPOSITORY``, " +"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." msgstr "" -"Se você quiser usar sua própria imagem base ao invés da imagem oficial base " -"do Flower, tudo que você precisa fazer é definir os argumentos " +"Se você quiser usar sua própria imagem base ao invés da imagem oficial " +"base do Flower, tudo que você precisa fazer é definir os argumentos " "``BASE_REPOSITORY`` e ``BASE_IMAGE_TAG`` como parte do comando de " -"compilação. O valor de ``BASE_REPOSITORY`` deve corresponder ao nome da sua " -"imagem e o valor de ``BASE_IMAGE_TAG`` deve corresponder à tag da sua imagem." +"compilação. O valor de ``BASE_REPOSITORY`` deve corresponder ao nome da " +"sua imagem e o valor de ``BASE_IMAGE_TAG`` deve corresponder à tag da sua" +" imagem." -#: ../../source/contributor-how-to-build-docker-images.rst:131 +#: ../../source/contributor-how-to-build-docker-images.rst:138 msgid "After creating the image, we can test whether the image is working:" msgstr "Depois de criar a imagem, podemos testar se a imagem está funcionando:" @@ -340,14 +371,15 @@ msgid "" "also be a great opportunity for those wanting to become open source " "contributors with little prerequisites." msgstr "" -"Desde o `Flower 1.5 `_ nós introduzimos traduções para nossas páginas de " -"documentação, mas, como você pode ter notado, as traduções são muitas vezes " -"imperfeitas. Se você fala línguas diferentes do inglês, você pode ser capaz " -"de nos ajudar neste esforço para tornar o aprendizado federado acessível a " -"tantas pessoas quanto possível, contribuindo para essas traduções! Isso " -"também pode ser uma grande oportunidade para aqueles que querem se tornar " -"contribuintes de código aberto com poucos pré-requisitos." +"Desde o `Flower 1.5 `_ nós introduzimos traduções para " +"nossas páginas de documentação, mas, como você pode ter notado, as " +"traduções são muitas vezes imperfeitas. Se você fala línguas diferentes " +"do inglês, você pode ser capaz de nos ajudar neste esforço para tornar o " +"aprendizado federado acessível a tantas pessoas quanto possível, " +"contribuindo para essas traduções! Isso também pode ser uma grande " +"oportunidade para aqueles que querem se tornar contribuintes de código " +"aberto com poucos pré-requisitos." #: ../../source/contributor-how-to-contribute-translations.rst:13 #, fuzzy @@ -373,10 +405,11 @@ msgid "" " profile settings can be found `here " "`_." msgstr "" -"A primeira coisa que você precisa fazer para contribuir é criar uma conta " -"Weblate gratuita nesta `página `_. Mais informações sobre as configurações de perfil podem ser encontradas " -"`aqui `_." +"A primeira coisa que você precisa fazer para contribuir é criar uma conta" +" Weblate gratuita nesta `página " +"`_. Mais informações sobre" +" as configurações de perfil podem ser encontradas `aqui " +"`_." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" @@ -386,17 +419,17 @@ msgid "" " that can be found on the website." msgstr "" "Uma vez que você esteja conectado ao Weblate, você pode navegar até o " -"projeto `Flower Framework `_. Aqui, você deve ver os diferentes idiomas existentes que " -"podem ser encontrados no site." +"projeto `Flower Framework `_. Aqui, você deve ver os diferentes idiomas existentes " +"que podem ser encontrados no site." #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" "Once you have selected the language you want to contribute to, you should" " see a similar interface to this:" msgstr "" -"Uma vez que você tenha selecionado o idioma que deseja contribuir, você deve " -"ver uma interface semelhante a esta:" +"Uma vez que você tenha selecionado o idioma que deseja contribuir, você " +"deve ver uma interface semelhante a esta:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" @@ -405,9 +438,10 @@ msgid "" "will automatically bring you to the translation interface for " "untranslated strings." msgstr "" -"A opção mais direta aqui é clicar no botão ``Translate`` no canto superior " -"direito (na seção ``Translation status``). Isso te levará automaticamente " -"para a interface de tradução de strings ainda não traduzidas." +"A opção mais direta aqui é clicar no botão ``Translate`` no canto " +"superior direito (na seção ``Translation status``). Isso te levará " +"automaticamente para a interface de tradução de strings ainda não " +"traduzidas." #: ../../source/contributor-how-to-contribute-translations.rst:43 #, fuzzy @@ -426,10 +460,10 @@ msgstr "" "Você insire sua tradução na caixa de texto no topo e depois, uma vez que " "você está satisfeito com ela, você pressiona ``Save and continue`` (para " "salvar a tradução e ir para a próxima string não traduzida), ``Save and " -"stay`` (para salvar a tradução e ficar na mesma página), ``Suggest`` (para " -"adicionar sua tradução para sugestões para outros usuários verem), ou " -"``Skip`` (para ir para a próxima string não traduzida sem salvar nada na " -"atual)." +"stay`` (para salvar a tradução e ficar na mesma página), ``Suggest`` " +"(para adicionar sua tradução para sugestões para outros usuários verem), " +"ou ``Skip`` (para ir para a próxima string não traduzida sem salvar nada " +"na atual)." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" @@ -442,8 +476,9 @@ msgstr "" "Para ajudar com as traduções, você pode ver na parte inferior o ``Nearby " "strings`` (strings próximas), o ``Comments`` (comentários de outros " "contribuidores), o ``Automatic suggestions`` (sugestões atuomáticas de " -"sistemas de tradução automática), as traduções em ``Other languages`` (" -"outras línguas), e o ``History`` (histórico) de traduções para esta string." +"sistemas de tradução automática), as traduções em ``Other languages`` " +"(outras línguas), e o ``History`` (histórico) de traduções para esta " +"string." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" @@ -451,9 +486,9 @@ msgid "" "click the link under ``Source string location`` in order to view the " "source of the doc file containing the string." msgstr "" -"À direita, sob a seção ``String information``, você também pode clicar no " -"link sob ``Source string location`` para visualizar a fonte do arquivo doc " -"que contém a string." +"À direita, sob a seção ``String information``, você também pode clicar no" +" link sob ``Source string location`` para visualizar a fonte do arquivo " +"doc que contém a string." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" @@ -461,9 +496,9 @@ msgid "" "this `in-depth guide " "`_." msgstr "" -"Para obter mais informações sobre como traduzir usando o Weblate, você pode " -"conferir este `guia detalhado `_." +"Para obter mais informações sobre como traduzir usando o Weblate, você " +"pode conferir este `guia detalhado " +"`_." #: ../../source/contributor-how-to-contribute-translations.rst:67 #, fuzzy @@ -476,9 +511,10 @@ msgid "" "either on `Slack `_, or by opening an issue" " on our `GitHub repo `_." msgstr "" -"Se você quiser adicionar uma nova língua, primeiro você terá que entrar em " -"contato conosco, no `Slack `_, ou abrindo uma " -"issue no nosso `repositório GitHub `_." +"Se você quiser adicionar uma nova língua, primeiro você terá que entrar " +"em contato conosco, no `Slack `_, ou " +"abrindo uma issue no nosso `repositório GitHub " +"`_." #: ../../source/contributor-how-to-create-new-messages.rst:2 #, fuzzy @@ -808,14 +844,14 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:51 msgid "" -"Open the notebook ``doc/source/tutorial-get-started-with-flower-" +"Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" "pytorch.ipynb``:" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" "https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-get-started-with-flower-pytorch.ipynb" +"/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:55 @@ -827,7 +863,7 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" "https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" +"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:59 @@ -1047,10 +1083,18 @@ msgid "" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 -msgid "Virutualenv with Pyenv/Virtualenv" +msgid "" +"Due to a known incompatibility with `ray " +"`_, we currently recommend utilizing at " +"most `Python 3.11 `_ for running Flower " +"simulations." +msgstr "" + +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 +msgid "Virtualenv with Pyenv/Virtualenv" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:16 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" "One of the recommended virtual environment is `pyenv " "`_/`virtualenv `_ for details." msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:18 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " "`_ or above:" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:24 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:29 msgid "Create the virtualenv with:" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:31 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:36 msgid "Activate the virtualenv by running the following command:" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:39 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:44 msgid "Virtualenv with Poetry" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:41 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" "The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " "simply create a virtual environment with:" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:47 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" "If you open a new terminal you can activate the previously created " "virtual environment with the following command:" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:55 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 msgid "Virtualenv with Anaconda" msgstr "" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:57 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" "If you prefer to use Anaconda for your virtual environment then install " "and setup the `conda `_." @@ -1131,7 +1175,7 @@ msgid "" msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:10 -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 msgid "" "Note that, in order to build the documentation locally (with ``poetry run" " make html``, like described below), `Pandoc " @@ -1571,7 +1615,7 @@ msgstr "" msgid "Creating and merging a pull request (PR)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:205 +#: ../../source/contributor-tutorial-contribute-on-github.rst:206 msgid "**Create the PR**" msgstr "" @@ -1604,178 +1648,180 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" +"The title should be changed to adhere to the :ref:`pr_title_format` " +"guidelines, otherwise it won't be possible to merge the PR. So in this " +"case, a correct title might be ``docs(framework:skip) Fix typos``." +msgstr "" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:196 +msgid "" "The input box in the middle is there for you to describe what your PR " "does and to link it to existing issues. We have placed comments (that " "won't be rendered once the PR is opened) to guide you through the " "process." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:196 -msgid "" -"It is important to follow the instructions described in comments. For " -"instance, in order to not break how our changelog system works, you " -"should read the information above the ``Changelog entry`` section " -"carefully. You can also checkout some examples and details in the " -":ref:`changelogentry` appendix." +#: ../../source/contributor-tutorial-contribute-on-github.rst:199 +msgid "It is important to follow the instructions described in comments." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:200 +#: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " "reviewers that a new PR has been opened and that they should look over it" " to merge or to request changes." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:203 +#: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" "If your PR is not yet ready for review, and you don't want to notify " "anyone, you have the option to create a draft pull request:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "**Making new changes**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " "commits to it the same way we did before, by making changes to the branch" " associated with the PR." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:230 +#: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:211 +#: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" "Once the PR has been opened or once the draft PR has been marked as " "ready, a review from code owners will be automatically requested:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:215 +#: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" "Code owners will then look into the code, ask questions, request changes " "or validate the PR." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:217 +#: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:221 +#: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" "To resolve them, just push the necessary changes to the branch associated" " with the PR:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:225 +#: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:229 +#: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" "Once all the conversations have been resolved, you can re-request a " "review." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:250 +#: ../../source/contributor-tutorial-contribute-on-github.rst:251 msgid "**Once the PR is merged**" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:233 +#: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" "If all the automatic tests have passed and reviewers have no more changes" " to request, they can approve the PR and merge it." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:237 +#: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:244 +#: ../../source/contributor-tutorial-contribute-on-github.rst:245 msgid "Then you should update your forked repository by doing:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:253 +#: ../../source/contributor-tutorial-contribute-on-github.rst:254 msgid "Example of first contribution" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:256 +#: ../../source/contributor-tutorial-contribute-on-github.rst:257 msgid "Problem" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:258 +#: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" "For our documentation, we've started to use the `Diàtaxis framework " "`_." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:260 +#: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" "Our \"How to\" guides should have titles that continue the sentence \"How" " to …\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:262 +#: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:264 +#: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" "This issue is about changing the title of a doc from present continuous " "to present simple." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:266 +#: ../../source/contributor-tutorial-contribute-on-github.rst:267 msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:268 +#: ../../source/contributor-tutorial-contribute-on-github.rst:269 msgid "Before: \"How to saving progress\" ❌" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:270 +#: ../../source/contributor-tutorial-contribute-on-github.rst:271 msgid "After: \"How to save progress\" ✅" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:273 +#: ../../source/contributor-tutorial-contribute-on-github.rst:274 msgid "Solution" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:275 +#: ../../source/contributor-tutorial-contribute-on-github.rst:276 msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " "After cloning and setting up the Flower repo, here's what you should do:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:277 +#: ../../source/contributor-tutorial-contribute-on-github.rst:278 msgid "Find the source file in ``doc/source``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:278 +#: ../../source/contributor-tutorial-contribute-on-github.rst:279 msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " "should be the same length as the title itself)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:279 +#: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" "Build the docs and `check the result `_" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:282 +#: ../../source/contributor-tutorial-contribute-on-github.rst:283 msgid "Rename file" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:284 +#: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" "You might have noticed that the file name still reflects the old wording." " If we just change the file, then we break all existing links to it - it " @@ -1783,142 +1829,68 @@ msgid "" "engine ranking." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:287 +#: ../../source/contributor-tutorial-contribute-on-github.rst:288 msgid "Here's how to change the file name:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:289 +#: ../../source/contributor-tutorial-contribute-on-github.rst:290 msgid "Change the file name to ``save-progress.rst``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:290 +#: ../../source/contributor-tutorial-contribute-on-github.rst:291 msgid "Add a redirect rule to ``doc/source/conf.py``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:292 +#: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" "This will cause a redirect from ``saving-progress.html`` to ``save-" "progress.html``, old links will continue to work." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:295 +#: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:297 +#: ../../source/contributor-tutorial-contribute-on-github.rst:298 msgid "" "For the lateral navigation bar to work properly, it is very important to " "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:300 +#: ../../source/contributor-tutorial-contribute-on-github.rst:301 msgid "Find and modify the file name in ``index.rst``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:303 +#: ../../source/contributor-tutorial-contribute-on-github.rst:304 msgid "Open PR" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:305 +#: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" "Commit the changes (commit messages are always imperative: \"Do " "something\", in this case \"Change …\")" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:306 -msgid "Push the changes to your fork" -msgstr "" - #: ../../source/contributor-tutorial-contribute-on-github.rst:307 -msgid "Open a PR (as shown above)" +msgid "Push the changes to your fork" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 -msgid "Wait for it to be approved!" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:309 -msgid "Congrats! 🥳 You're now officially a Flower contributor!" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:313 -msgid "How to write a good PR title" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:315 -msgid "" -"A well-crafted PR title helps team members quickly understand the purpose" -" and scope of the changes being proposed. Here's a guide to help you " -"write a good GitHub PR title:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:317 -msgid "" -"1. Be Clear and Concise: Provide a clear summary of the changes in a " -"concise manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" " -"\"Update,\" or \"Fix\" to indicate the purpose. 1. Include Relevant " -"Information: Mention the affected feature or module for context. 1. Keep " -"it Short: Avoid lengthy titles for easy readability. 1. Use Proper " -"Capitalization and Punctuation: Follow grammar rules for clarity." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:323 msgid "" -"Let's start with a few examples for titles that should be avoided because" -" they do not provide meaningful information:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:325 -msgid "Implement Algorithm" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:326 -msgid "Database" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:327 -msgid "Add my_new_file.py to codebase" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:328 -msgid "Improve code in module" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:329 -msgid "Change SomeModule" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:331 -msgid "" -"Here are a few positive examples which provide helpful information " -"without repeating how they do it, as that is already visible in the " -"\"Files changed\" section of the PR:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:333 -msgid "Update docs banner to mention Flower Summit 2023" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:334 -msgid "Remove unnecessary XGBoost dependency" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:335 -msgid "Remove redundant attributes in strategies subclassing FedAvg" +"Open a PR (as shown above) with title ``docs(framework) Update how-to " +"guide title``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:336 -msgid "Add CI job to deploy the staging system when the ``main`` branch changes" +#: ../../source/contributor-tutorial-contribute-on-github.rst:309 +msgid "Wait for it to be approved!" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:337 -msgid "" -"Add new amazing library which will be used to improve the simulation " -"engine" +#: ../../source/contributor-tutorial-contribute-on-github.rst:310 +msgid "Congrats! 🥳 You're now officially a Flower contributor!" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#: ../../source/contributor-tutorial-contribute-on-github.rst:314 #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:548 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:946 #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:727 @@ -1927,153 +1899,92 @@ msgstr "" msgid "Next steps" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +#: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" "Once you have made your first PR, and want to contribute more, be sure to" " check out the following :" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +#: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" ":doc:`Good first contributions `, where you should particularly look into the " ":code:`baselines` contributions." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +#: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 msgid "Appendix" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:354 -msgid "Changelog entry" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:356 -msgid "" -"When opening a new PR, inside its description, there should be a " -"``Changelog entry`` header." -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:358 -msgid "" -"Above this header you should see the following comment that explains how " -"to write your changelog entry:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:360 -msgid "" -"Inside the following 'Changelog entry' section, you should put the " -"description of your changes that will be added to the changelog alongside" -" your PR title." +#: ../../source/contributor-tutorial-contribute-on-github.rst:327 +msgid "PR title format" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:363 -msgid "" -"If the section is completely empty (without any token) or non-existent, " -"the changelog will just contain the title of the PR for the changelog " -"entry, without any description." +#: ../../source/contributor-tutorial-contribute-on-github.rst:329 +msgid "We enforce the following PR title format:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:366 +#: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"If the section contains some text other than tokens, it will use it to " -"add a description to the change." +"(or ``(:skip) `` to ignore the PR in the " +"changelog)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:368 +#: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"If the section contains one of the following tokens it will ignore any " -"other text and put the PR under the corresponding section of the " -"changelog:" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:370 -msgid " is for classifying a PR as a general improvement." +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " +"break}``, ```` should be in ``{framework, baselines, datasets, " +"examples, or '*' when modifying multiple projects which requires the " +"':skip' flag to be used}``, and ```` starts with a capitalised " +"verb in the imperative mood." msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:372 -msgid " is to not add the PR to the changelog" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:374 -msgid " is to add a general baselines change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:376 -msgid " is to add a general examples change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:378 -msgid " is to add a general sdk change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:380 -msgid " is to add a general simulations change to the PR" -msgstr "" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:382 -msgid "Note that only one token should be used." -msgstr "" +#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#, fuzzy +msgid "Valid examples:" +msgstr "Exemplo" -#: ../../source/contributor-tutorial-contribute-on-github.rst:384 -msgid "" -"Its content must have a specific format. We will break down what each " -"possibility does:" +#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +msgid "``feat(framework) Add flwr build CLI command``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:386 -msgid "" -"If the ``### Changelog entry`` section contains nothing or doesn't exist," -" the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:344 +msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:390 -msgid "" -"If the ``### Changelog entry`` section contains a description (and no " -"token), the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +msgid "``ci(*:skip) Enforce PR title format``" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:396 -msgid "" -"If the ``### Changelog entry`` section contains ````, nothing will " -"change in the changelog." +#: ../../source/contributor-tutorial-contribute-on-github.rst:347 +msgid "Invalid examples:" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:398 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:402 +#: ../../source/contributor-tutorial-contribute-on-github.rst:350 msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +"``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " +"``*``)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:406 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:351 +msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:410 -msgid "" -"If the ``### Changelog entry`` section contains ````, the following " -"text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:352 +msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:414 -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:353 +msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:418 -msgid "" -"Note that only one token must be provided, otherwise, only the first " -"action (in the order listed above), will be performed." +#: ../../source/contributor-tutorial-contribute-on-github.rst:354 +msgid "``Add flwr build CLI command.`` (missing ``()``)" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 @@ -2081,6 +1992,7 @@ msgid "Get started as a contributor" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 +#: ../../source/how-to-run-flower-using-docker.rst:132 msgid "Prerequisites" msgstr "" @@ -2213,51 +2125,96 @@ msgid "Run Linters and Tests" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:106 -msgid "Run Github Actions (CI) locally" +msgid "Add a pre-commit hook" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 msgid "" +"Developers may integrate a pre-commit hook into their workflow utilizing " +"the `pre-commit `_ library. The pre-" +"commit hook is configured to execute two primary operations: " +"``./dev/format.sh`` and ``./dev/test.sh`` scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 +msgid "There are multiple ways developers can use this:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 +msgid "Install the pre-commit hook to your local git directory by simply running:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 +msgid "" +"Each ``git commit`` will trigger the execution of formatting and " +"linting/test scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 +msgid "" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " +"commit`` command. ::" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 +msgid "" +"For developers who prefer not to install the hook permanently, it is " +"possible to execute a one-time check prior to committing changes by using" +" the following command:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 +msgid "" +"This executes the formatting and linting checks/tests on all the files " +"without modifying the default behavior of ``git commit``." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 +msgid "Run Github Actions (CI) locally" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 +msgid "" "Developers could run the full set of Github Actions workflows under their" " local environment by using `Act `_. " "Please refer to the installation instructions under the linked repository" " and run the next command under Flower main cloned repository folder::" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:115 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 msgid "" "The Flower default workflow would run by setting up the required Docker " "machines underneath." msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:120 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:147 msgid "Build Release" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:122 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" "Flower uses Poetry to build releases. The necessary command is wrapped in" " a simple script::" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:127 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" "The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" " the :code:`/dist` subdirectory." msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:132 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 msgid "Build Documentation" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:134 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" "Flower's documentation uses `Sphinx `_. " "There's no convenience script to re-build the documentation yet, but it's" " pretty easy::" msgstr "" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:140 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 msgid "This will generate HTML documentation in ``doc/build/html``." msgstr "" @@ -2351,7 +2308,6 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 -#: ../../source/example-mxnet-walk-through.rst:356 #: ../../source/example-pytorch-from-centralized-to-federated.rst:310 #: ../../source/tutorial-quickstart-jax.rst:283 msgid "Next Steps" @@ -2494,7 +2450,6 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:123 -#: ../../source/example-mxnet-walk-through.rst:204 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" @@ -2505,7 +2460,6 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:133 -#: ../../source/example-mxnet-walk-through.rst:214 #: ../../source/example-pytorch-from-centralized-to-federated.rst:191 #: ../../source/tutorial-quickstart-jax.rst:139 msgid "We can already start the *server*:" @@ -2536,13 +2490,11 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:161 -#: ../../source/example-mxnet-walk-through.rst:242 #: ../../source/tutorial-quickstart-jax.rst:167 msgid ":code:`set_parameters (optional)`" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:160 -#: ../../source/example-mxnet-walk-through.rst:241 #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" @@ -2556,7 +2508,6 @@ msgid "transform parameters to NumPy :code:`ndarray`'s" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:162 -#: ../../source/example-mxnet-walk-through.rst:243 #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" @@ -2565,17 +2516,14 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:163 -#: ../../source/example-mxnet-walk-through.rst:244 #: ../../source/example-pytorch-from-centralized-to-federated.rst:221 #: ../../source/tutorial-quickstart-jax.rst:169 -#: ../../source/tutorial-quickstart-mxnet.rst:171 #: ../../source/tutorial-quickstart-pytorch.rst:155 -#: ../../source/tutorial-quickstart-scikitlearn.rst:108 +#: ../../source/tutorial-quickstart-scikitlearn.rst:118 msgid ":code:`get_parameters`" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:164 -#: ../../source/example-mxnet-walk-through.rst:245 #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" @@ -2584,19 +2532,15 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 -#: ../../source/tutorial-quickstart-mxnet.rst:177 #: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 msgid ":code:`fit`" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:166 #: ../../source/example-jax-from-centralized-to-federated.rst:170 -#: ../../source/example-mxnet-walk-through.rst:247 -#: ../../source/example-mxnet-walk-through.rst:251 #: ../../source/example-pytorch-from-centralized-to-federated.rst:224 #: ../../source/example-pytorch-from-centralized-to-federated.rst:228 #: ../../source/tutorial-quickstart-jax.rst:172 @@ -2607,7 +2551,6 @@ msgid "" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 msgid "train the model on the local training set" @@ -2619,17 +2562,14 @@ msgid "get the updated local model parameters and return them to the server" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:172 -#: ../../source/example-mxnet-walk-through.rst:253 #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 #: ../../source/tutorial-quickstart-jax.rst:178 -#: ../../source/tutorial-quickstart-mxnet.rst:180 #: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 msgid ":code:`evaluate`" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:171 -#: ../../source/example-mxnet-walk-through.rst:252 #: ../../source/example-pytorch-from-centralized-to-federated.rst:229 #: ../../source/tutorial-quickstart-jax.rst:177 msgid "evaluate the updated model on the local test set" @@ -2666,7 +2606,6 @@ msgid "Having defined the federation process, we can run it." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:268 -#: ../../source/example-mxnet-walk-through.rst:347 #: ../../source/example-pytorch-from-centralized-to-federated.rst:301 #: ../../source/tutorial-quickstart-jax.rst:274 msgid "And that's it. You can now open two additional terminal windows and run" @@ -2697,332 +2636,143 @@ msgid "" "clients?" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:2 -msgid "Example: MXNet - Run MXNet Federated" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:2 +msgid "Example: PyTorch - From Centralized To Federated" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:4 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" "This tutorial will show you how to use Flower to build a federated " -"version of an existing MXNet workload. We are using MXNet to train a " -"Sequential model on the MNIST dataset. We will structure the example " -"similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. MXNet and PyTorch are very " -"similar and a very good comparison between MXNet and PyTorch is given " -"`here `_. First, we build a centralized " -"training approach based on the `Handwritten Digit Recognition " -"`_" -" tutorial. Then, we build upon the centralized training code to run the " +"version of an existing machine learning workload. We are using PyTorch to" +" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " +"introduce this machine learning task with a centralized training approach" +" based on the `Deep Learning with PyTorch " +"`_ " +"tutorial. Then, we build upon the centralized training code to run the " "training in a federated fashion." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:10 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"Before we start setting up our MXNet example, we install the " -":code:`mxnet` and :code:`flwr` packages:" -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:19 -msgid "MNIST Training with MXNet" +"We begin with a brief description of the centralized CNN training code. " +"If you want a more in-depth explanation of what's going on then have a " +"look at the official `PyTorch tutorial " +"`_." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:21 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Sequential` model. If you want a more in-depth explanation of" -" what's going on then have a look at the official `MXNet tutorial " -"`_." +"Let's create a new file called :code:`cifar.py` with all the components " +"required for a traditional (centralized) training on CIFAR-10. First, all" +" required packages (such as :code:`torch` and :code:`torchvision`) need " +"to be imported. You can see that we do not import any package for " +"federated learning. You can keep all these imports as they are even when " +"we add the federated learning components at a later point." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:24 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" -"Let's create a new file called:code:`mxnet_mnist.py` with all the " -"components required for a traditional (centralized) MNIST training. " -"First, the MXNet package :code:`mxnet` needs to be imported. You can see " -"that we do not yet import the :code:`flwr` package for federated " -"learning. This will be done later." -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:42 -msgid "The :code:`load_data()` function loads the MNIST training and test sets." +"As already mentioned we will use the CIFAR-10 dataset for this machine " +"learning workload. The model architecture (a very simple Convolutional " +"Neural Network) is defined in :code:`class Net()`." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:57 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"As already mentioned, we will use the MNIST dataset for this machine " -"learning workload. The model architecture (a very simple " -":code:`Sequential` model) is defined in :code:`model()`." +"The :code:`load_data()` function loads the CIFAR-10 training and test " +"sets. The :code:`transform` normalized the data after loading." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:70 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" "We now need to define the training (function :code:`train()`) which loops" -" over the training set and measures the loss for each batch of training " -"examples." +" over the training set, measures the loss, backpropagates it, and then " +"takes one optimizer step for each batch of training examples." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:123 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in function :code:`test()`. The " -"function loops over all test samples and measures the loss and accuracy " -"of the model based on the test dataset." +"The evaluation of the model is defined in the function :code:`test()`. " +"The function loops over all test samples and measures the loss of the " +"model based on the test dataset." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:158 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model on MNIST. " -"Note that the GPU/CPU device for the training and testing is defined " -"within the :code:`ctx` (context)." -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:184 -msgid "You can now run your (centralized) MXNet machine learning workload:" +"evaluation we can put everything together and train our CNN on CIFAR-10." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:190 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far this should all look fairly familiar if you've used MXNet (or even" -" PyTorch) before. Let's take the next step and use what we've built to " -"create a simple federated learning system consisting of one server and " -"two clients." +"So far, this should all look fairly familiar if you've used PyTorch " +"before. Let's take the next step and use what we've built to create a " +"simple federated learning system consisting of one server and two " +"clients." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:194 -msgid "MXNet meets Flower" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:169 +msgid "" +"The simple machine learning project discussed in the previous section " +"trains the model on a single dataset (CIFAR-10), we call this centralized" +" learning. This concept of centralized learning, as shown in the previous" +" section, is probably known to most of you, and many of you have used it " +"previously. Normally, if you'd want to run machine learning workloads in " +"a federated fashion, then you'd have to change most of your code and set " +"everything up from scratch. This can be a considerable effort." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:196 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"So far, it was not easily possible to use MXNet workloads for federated " -"learning because federated learning is not supported in MXNet. Since " -"Flower is fully agnostic towards the underlying machine learning " -"framework, it can be used to federated arbitrary machine learning " -"workloads. This section will show you how Flower can be used to federate " -"our centralized MXNet workload." +"However, with Flower you can evolve your pre-existing code into a " +"federated learning setup without the need for a major rewrite." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:198 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept to federate an existing workload is always the same and easy " -"to understand. We have to start a *server* and then use the code in " -":code:`mxnet_mnist.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " +"The concept is easy to understand. We have to start a *server* and then " +"use the code in :code:`cifar.py` for the *clients* that are connected to " +"the *server*. The *server* sends model parameters to the clients. The " "*clients* run the training and update the parameters. The updated " "parameters are sent back to the *server* which averages all received " "parameter updates. This describes one round of the federated learning " "process and we repeat this for multiple rounds." msgstr "" -#: ../../source/example-mxnet-walk-through.rst:220 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" "Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined MXNet training in :code:`mxnet_mnist.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`mxnet` to " -"update the parameters on our MXNet model:" +" upon the previously defined centralized training in :code:`cifar.py`. " +"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " +"update the parameters on our PyTorch model:" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:235 +#: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" "Implementing a Flower *client* basically means implementing a subclass of" " either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " "Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier" +"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" " to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or MXNet) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs " -"to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " +"some of the boilerplate that would otherwise be necessary. " +":code:`CifarClient` needs to implement four methods, two methods for " +"getting/setting model parameters, one method for training the model, and " +"one method for testing the model:" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:242 -msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:219 +msgid ":code:`set_parameters`" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:249 #: ../../source/example-pytorch-from-centralized-to-federated.rst:226 msgid "get the updated local model weights and return them to the server" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:253 #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 msgid "return the local loss and accuracy to the server" msgstr "" -#: ../../source/example-mxnet-walk-through.rst:255 -msgid "" -"The challenging part is to transform the MXNet parameters from " -":code:`NDArray` to :code:`NumPy Arrays` to make it readable for Flower." -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:257 -msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`mxnet_mnist.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:319 -msgid "" -"Having defined data loading, model architecture, training, and evaluation" -" we can put everything together and train our :code:`Sequential` model on" -" MNIST." -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:353 -msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your MXNet project run federated learning across two clients." -" Congratulations!" -msgstr "" - -#: ../../source/example-mxnet-walk-through.rst:358 -msgid "" -"The full source code for this example: `MXNet: From Centralized To " -"Federated (Code) `_. Our example is of course " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using a CNN or using a different dataset? How about " -"adding more clients?" -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:2 -msgid "Example: PyTorch - From Centralized To Federated" -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:4 -msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload. We are using PyTorch to" -" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " -"introduce this machine learning task with a centralized training approach" -" based on the `Deep Learning with PyTorch " -"`_ " -"tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:12 -msgid "" -"We begin with a brief description of the centralized CNN training code. " -"If you want a more in-depth explanation of what's going on then have a " -"look at the official `PyTorch tutorial " -"`_." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:15 -msgid "" -"Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all" -" required packages (such as :code:`torch` and :code:`torchvision`) need " -"to be imported. You can see that we do not import any package for " -"federated learning. You can keep all these imports as they are even when " -"we add the federated learning components at a later point." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:32 -msgid "" -"As already mentioned we will use the CIFAR-10 dataset for this machine " -"learning workload. The model architecture (a very simple Convolutional " -"Neural Network) is defined in :code:`class Net()`." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:56 -msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test " -"sets. The :code:`transform` normalized the data after loading." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:74 -msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set, measures the loss, backpropagates it, and then " -"takes one optimizer step for each batch of training examples." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:76 -msgid "" -"The evaluation of the model is defined in the function :code:`test()`. " -"The function loops over all test samples and measures the loss of the " -"model based on the test dataset." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:136 -msgid "" -"Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:163 -msgid "" -"So far, this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"simple federated learning system consisting of one server and two " -"clients." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:169 -msgid "" -"The simple machine learning project discussed in the previous section " -"trains the model on a single dataset (CIFAR-10), we call this centralized" -" learning. This concept of centralized learning, as shown in the previous" -" section, is probably known to most of you, and many of you have used it " -"previously. Normally, if you'd want to run machine learning workloads in " -"a federated fashion, then you'd have to change most of your code and set " -"everything up from scratch. This can be a considerable effort." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:173 -msgid "" -"However, with Flower you can evolve your pre-existing code into a " -"federated learning setup without the need for a major rewrite." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:175 -msgid "" -"The concept is easy to understand. We have to start a *server* and then " -"use the code in :code:`cifar.py` for the *clients* that are connected to " -"the *server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:197 -msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined centralized training in :code:`cifar.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " -"update the parameters on our PyTorch model:" -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:213 -msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " -"some of the boilerplate that would otherwise be necessary. " -":code:`CifarClient` needs to implement four methods, two methods for " -"getting/setting model parameters, one method for training the model, and " -"one method for testing the model:" -msgstr "" - -#: ../../source/example-pytorch-from-centralized-to-federated.rst:219 -msgid ":code:`set_parameters`" -msgstr "" - #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" "The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" @@ -3965,6 +3715,162 @@ msgid "" "provided in these dictionaries:" msgstr "" +#: ../../source/how-to-authenticate-supernodes.rst:2 +msgid "Authenticate SuperNodes" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:4 +msgid "" +"Flower has built-in support for authenticated SuperNodes that you can use" +" to verify the identities of each SuperNode connecting to a SuperLink. " +"Flower node authentication works similar to how GitHub SSH authentication" +" works:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:7 +msgid "SuperLink (server) stores a list of known (client) node public keys" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:8 +msgid "" +"Using ECDH, both SuperNode and SuperLink independently derive a shared " +"secret" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:9 +msgid "" +"Shared secret is used to compute the HMAC value of the message sent from " +"SuperNode to SuperLink as a token" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:10 +msgid "SuperLink verifies the token" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:12 +msgid "" +"We recommend you to check out the complete `code example " +"`_ demonstrating federated learning with Flower in an " +"authenticated setting." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:15 +msgid "" +"This guide covers a preview feature that might change in future versions " +"of Flower." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:18 +msgid "" +"For increased security, node authentication can only be used when " +"encrypted connections (SSL/TLS) are enabled." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:21 +msgid "Enable node authentication in :code:`SuperLink`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:23 +msgid "" +"To enable node authentication, first you need to configure SSL/TLS " +"connections to secure the SuperLink<>SuperNode communication. You can " +"find the complete guide `here `_. After configuring secure connections, you" +" can enable client authentication in a long-running Flower " +":code:`SuperLink`. Use the following terminal command to start a Flower " +":code:`SuperNode` that has both secure connections and node " +"authentication enabled:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:36 +msgid "Let's break down the authentication flags:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:38 +msgid "" +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " +"file storing all known node public keys. You need to store all known node" +" public keys that are allowed to participate in a federation in one CSV " +"file (:code:`.csv`)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:40 +msgid "" +"A valid CSV file storing known node public keys should list the keys in " +"OpenSSH format, separated by commas and without any comments. For an " +"example, refer to our code sample, which contains a CSV file with two " +"known node public keys." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:42 +msgid "" +"The second and third flags :code:`--auth-superlink-private-key` and :code" +":`--auth-superlink-public-key` expect paths to the server's private and " +"public keys. For development purposes, you can generate a private and " +"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:45 +msgid "" +"In Flower 1.9, there is no support for dynamically removing, editing, or " +"adding known node public keys to the SuperLink. To change the set of " +"known nodes, you need to shut the server down, edit the CSV file, and " +"start the server again. Support for dynamically changing the set of known" +" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:51 +msgid "Enable node authentication in :code:`SuperNode`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:53 +msgid "" +"Similar to the long-running Flower server (:code:`SuperLink`), you can " +"easily enable node authentication in the long-running Flower client " +"(:code:`SuperNode`). Use the following terminal command to start an " +"authenticated :code:`SuperNode`:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:64 +msgid "" +"The :code:`--auth-supernode-private-key` flag expects a path to the " +"node's private key file and the :code:`--auth-supernode-public-key` flag " +"expects a path to the node's public key file. For development purposes, " +"you can generate a private and public key pair using :code:`ssh-keygen -t" +" ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:68 +msgid "Security notice" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:70 +msgid "" +"The system's security relies on the credentials of the SuperLink and each" +" SuperNode. Therefore, it is imperative to safeguard and safely store the" +" credentials to avoid security risks such as Public Key Infrastructure " +"(PKI) impersonation attacks. The node authentication mechanism also " +"involves human interaction, so please ensure that all of the " +"communication is done in a secure manner, using trusted communication " +"methods." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:75 +#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-use-built-in-mods.rst:85 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 +msgid "Conclusion" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:77 +msgid "" +"You should now have learned how to start a long-running Flower server " +"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " +"authentication enabled. You should also know the significance of the " +"private key and store it safely to minimize security risks." +msgstr "" + #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" msgstr "" @@ -4173,8 +4079,9 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:4 msgid "" -"This guide describes how to a SSL-enabled secure Flower server can be " -"started and how a Flower client can establish a secure connections to it." +"This guide describes how to a SSL-enabled secure Flower server " +"(:code:`SuperLink`) can be started and how a Flower client " +"(:code:`SuperNode`) can establish a secure connections to it." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:7 @@ -4186,10 +4093,10 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" -"The code example comes with a README.md file which will explain how to " -"start it. Although it is already SSL-enabled, it might be less " -"descriptive on how. Stick to this guide for a deeper introduction to the " -"topic." +"The code example comes with a :code:`README.md` file which explains how " +"to start it. Although it is already SSL-enabled, it might be less " +"descriptive on how it does so. Stick to this guide for a deeper " +"introduction to the topic." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:16 @@ -4202,100 +4109,81 @@ msgid "" "server and client. For the purpose of this guide we are going to generate" " self-signed certificates. As this can become quite complex we are going " "to ask you to run the script in :code:`examples/advanced-" -"tensorflow/certificates/generate.sh`" -msgstr "" - -#: ../../source/how-to-enable-ssl-connections.rst:23 -msgid "with the following command sequence:" +"tensorflow/certificates/generate.sh` with the following command sequence:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:30 +#: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" "This will generate the certificates in :code:`examples/advanced-" "tensorflow/.cache/certificates`." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:32 +#: ../../source/how-to-enable-ssl-connections.rst:31 msgid "" -"The approach how the SSL certificates are generated in this example can " -"serve as an inspiration and starting point but should not be taken as " -"complete for production environments. Please refer to other sources " -"regarding the issue of correctly generating certificates for production " -"environments." +"The approach for generating SSL certificates in the context of this " +"example can serve as an inspiration and starting point, but it should not" +" be used as a reference for production environments. Please refer to " +"other sources regarding the issue of correctly generating certificates " +"for production environments. For non-critical prototyping or research " +"projects, it might be sufficient to use the self-signed certificates " +"generated using the scripts mentioned in this guide." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:36 -msgid "" -"In case you are a researcher you might be just fine using the self-signed" -" certificates generated using the scripts which are part of this guide." +#: ../../source/how-to-enable-ssl-connections.rst:39 +msgid "Server (SuperLink)" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:41 -#: ../../source/ref-api/flwr.server.Server.rst:2 -msgid "Server" -msgstr "" - -#: ../../source/how-to-enable-ssl-connections.rst:43 msgid "" -"We are now going to show how to write a sever which uses the previously " -"generated scripts." +"Use the following terminal command to start a sever (SuperLink) that uses" +" the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:47 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates. :code:`Path` can be used to easily read the contents of " -"those files into byte strings, which is the data type " -":code:`start_server` expects." +"certificates paths: CA certificate, server certificate and server private" +" key." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:65 -#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 -#: ../../source/ref-api/flwr.client.Client.rst:2 -msgid "Client" +#: ../../source/how-to-enable-ssl-connections.rst:51 +msgid "Client (SuperNode)" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:53 msgid "" -"We are now going to show how to write a client which uses the previously " -"generated scripts:" +"Use the following terminal command to start a client (SuperNode) that " +"uses the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:84 +#: ../../source/how-to-enable-ssl-connections.rst:61 msgid "" -"When setting :code:`root_certificates`, the client expects the PEM-" -"encoded root certificates as a byte string. We are again using " -":code:`Path` to simplify reading those as byte strings." +"When setting :code:`root_certificates`, the client expects a file path to" +" PEM-encoded root certificates." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:89 -#: ../../source/how-to-use-built-in-mods.rst:85 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 -msgid "Conclusion" -msgstr "" - -#: ../../source/how-to-enable-ssl-connections.rst:91 +#: ../../source/how-to-enable-ssl-connections.rst:67 msgid "" "You should now have learned how to generate self-signed certificates " -"using the given script, start a SSL-enabled server, and have a client " +"using the given script, start an SSL-enabled server and have a client " "establish a secure connection to it." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:96 +#: ../../source/how-to-enable-ssl-connections.rst:72 msgid "Additional resources" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:98 +#: ../../source/how-to-enable-ssl-connections.rst:74 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:100 +#: ../../source/how-to-enable-ssl-connections.rst:76 msgid "`Let's Encrypt `_" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:101 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "`certbot `_" msgstr "" @@ -4567,6 +4455,7 @@ msgid "Install stable release" msgstr "" #: ../../source/how-to-install-flower.rst:15 +#: ../../source/how-to-upgrade-to-flower-next.rst:46 msgid "Using pip" msgstr "" @@ -4904,7 +4793,7 @@ msgstr "" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`_." +"`__." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:7 @@ -4927,149 +4816,466 @@ msgid "" "official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:25 -msgid "Flower server" +#: ../../source/how-to-run-flower-using-docker.rst:26 +msgid "" +"To ensure optimal performance and compatibility, the SuperLink, SuperNode" +" and ServerApp image must have the same version when running together. " +"This guarantees seamless integration and avoids potential conflicts or " +"issues that may arise from using different versions." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:31 +msgid "Flower SuperLink" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:28 +#: ../../source/how-to-run-flower-using-docker.rst:34 msgid "Quickstart" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:30 +#: ../../source/how-to-run-flower-using-docker.rst:36 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:37 +#: ../../source/how-to-run-flower-using-docker.rst:42 msgid "" -"The command will pull the Docker image with the tag " -"``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. The tag contains the " -"information which Flower, Python and Ubuntu is used. In this case, it " -"uses Flower 1.7.0, Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells " -"Docker to remove the container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker " +"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " +"The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:44 +#: ../../source/how-to-run-flower-using-docker.rst:48 msgid "" -"By default, the Flower server keeps state in-memory. When using the " +"By default, the Flower SuperLink keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " "starts. We will show below how to save the state in a file on your host " "system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:52 msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " "allowing you to access the Driver API on ``http://localhost:9091`` and " "the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " -"after the tag is passed to the Flower server. Here, we are passing the " -"flag ``--insecure``." +"after the tag is passed to the Flower SuperLink. Here, we are passing the" +" flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:55 +#: ../../source/how-to-run-flower-using-docker.rst:59 +#: ../../source/how-to-run-flower-using-docker.rst:238 +#: ../../source/how-to-run-flower-using-docker.rst:354 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " "recommend enabling `SSL `_ when " +"flower-using-docker.html#enabling-ssl-for-secure-connections>`__ when " "deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:64 msgid "" -"You can use ``--help`` to view all available flags that the server " +"You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:67 +#: ../../source/how-to-run-flower-using-docker.rst:71 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:69 +#: ../../source/how-to-run-flower-using-docker.rst:73 msgid "" -"If you want to persist the state of the server on your host system, all " -"you need to do is specify a path where you want to save the file on your " -"host system and a name for the database file. In the example below, we " -"tell Docker via the flag ``-v`` to mount the user's home directory " -"(``~/`` on your host) into the ``/app/`` directory of the container. " -"Furthermore, we use the flag ``--database`` to specify the name of the " -"database file." +"If you want to persist the state of the SuperLink on your host system, " +"all you need to do is specify a path where you want to save the file on " +"your host system and a name for the database file. In the example below, " +"we tell Docker via the flag ``--volume`` to mount the user's home " +"directory (``~/`` on your host) into the ``/app/`` directory of the " +"container. Furthermore, we use the flag ``--database`` to specify the " +"name of the database file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:82 +#: ../../source/how-to-run-flower-using-docker.rst:86 msgid "" -"As soon as the server starts, the file ``state.db`` is created in the " +"As soon as the SuperLink starts, the file ``state.db`` is created in the " "user's home directory on your host system. If the file already exists, " -"the server tries to restore the state from the file. To start the server " -"with an empty database, simply remove the ``state.db`` file." +"the SuperLink tries to restore the state from the file. To start the " +"SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:87 +#: ../../source/how-to-run-flower-using-docker.rst:91 +#: ../../source/how-to-run-flower-using-docker.rst:260 +#: ../../source/how-to-run-flower-using-docker.rst:375 msgid "Enabling SSL for secure connections" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:89 +#: ../../source/how-to-run-flower-using-docker.rst:93 msgid "" -"To enable SSL, you will need a CA certificate, a server certificate and a" -" server private key." +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" +"encoded private key and a PEM-encoded certificate chain." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:92 +#: ../../source/how-to-run-flower-using-docker.rst:97 msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `_ page contains a section that " -"will guide you through the process." +"enable-ssl-connections.html#certificates>`__ page contains a section that" +" will guide you through the process." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:96 +#: ../../source/how-to-run-flower-using-docker.rst:101 msgid "" "Assuming all files we need are in the local ``certificates`` directory, " -"we can use the flag ``-v`` to mount the local directory into the " -"``/app/`` directory of the container. This allows the server to access " -"the files within the container. Finally, we pass the names of the " -"certificates to the server with the ``--certificates`` flag." +"we can use the flag ``--volume`` to mount the local directory into the " +"``/app/`` directory of the container. This allows the SuperLink to access" +" the files within the container. Finally, we pass the names of the " +"certificates to the SuperLink with the ``--certificates`` flag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:108 -msgid "Using a different Flower or Python version" +#: ../../source/how-to-run-flower-using-docker.rst:113 +msgid "Flower SuperNode" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:110 +#: ../../source/how-to-run-flower-using-docker.rst:115 msgid "" -"If you want to use a different version of Flower or Python, you can do so" -" by changing the tag. All versions we provide are available on `Docker " -"Hub `_." +"The SuperNode Docker image comes with a pre-installed version of Flower " +"and serves as a base for building your own SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:114 -msgid "Pinning a Docker image to a specific version" +#: ../../source/how-to-run-flower-using-docker.rst:120 +msgid "" +"The SuperNode Docker image currently works only with the 1.9.0-nightly " +"release. A stable version will be available when Flower 1.9.0 (stable) " +"gets released (ETA: May). A SuperNode nightly image must be paired with " +"the corresponding SuperLink and ServerApp nightly images released on the " +"same day. To ensure the versions are in sync, using the concrete tag, " +"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:116 +#: ../../source/how-to-run-flower-using-docker.rst:126 msgid "" -"It may happen that we update the images behind the tags. Such updates " -"usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that " +"We will use the ``quickstart-pytorch`` example, which you can find in the" +" Flower repository, to illustrate how you can dockerize your ClientApp." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:134 +#, fuzzy +msgid "" +"Before we can start, we need to meet a few prerequisites in our local " +"development environment. You can skip the first part if you want to run " +"your ClientApp instead of the ``quickstart-pytorch`` example." +msgstr "" +"Antes de começarmos, precisamos encontrar alguns pré-requisitos em nosso " +"ambiente de desenvolvimento local." + +#: ../../source/how-to-run-flower-using-docker.rst:138 +#, fuzzy +msgid "Clone the Flower repository." +msgstr "Clone o repositório do flower." + +#: ../../source/how-to-run-flower-using-docker.rst:152 +msgid "Creating a SuperNode Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:154 +#: ../../source/how-to-run-flower-using-docker.rst:289 +msgid "Let's assume the following project layout:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:163 +msgid "" +"First, we need to create a ``requirements.txt`` file in the directory " +"where the ``ClientApp`` code is located. In the file, we list all the " +"dependencies that the ClientApp requires." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:175 +msgid "" +"Note that `flwr `__ is already installed " +"in the ``flwr/supernode`` base image, so you only need to include other " +"package dependencies in your ``requirements.txt``, such as ``torch``, " +"``tensorflow``, etc." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:179 +msgid "" +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.supernode`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:182 +msgid "" +"The ``Dockerfile.supernode`` contains the instructions that assemble the " +"SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:196 +msgid "" +"In the first two lines, we instruct Docker to use the SuperNode image " +"tagged ``nightly`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. Next, we install the ClientApp dependencies by copying the " +"``requirements.txt`` file into the image and run ``pip install``. In the " +"last two lines, we copy the ``client.py`` module into the image and set " +"the entry point to ``flower-client-app`` with the argument " +"``client:app``. The argument is the object reference of the ClientApp " +"(``:``) that will be run inside the ClientApp." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:205 +#, fuzzy +msgid "Building the SuperNode Docker image" +msgstr "Construindo a imagem do servidor" + +#: ../../source/how-to-run-flower-using-docker.rst:207 +msgid "" +"Next, we build the SuperNode Docker image by running the following " +"command in the directory where Dockerfile and ClientApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:214 +msgid "" +"We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:219 +#, fuzzy +msgid "Running the SuperNode Docker image" +msgstr "Construindo a imagem do servidor" + +#: ../../source/how-to-run-flower-using-docker.rst:221 +msgid "Now that we have built the SuperNode image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:229 +#: ../../source/how-to-run-flower-using-docker.rst:345 +msgid "Let's break down each part of this command:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:231 +#: ../../source/how-to-run-flower-using-docker.rst:347 +msgid "``docker run``: This is the command to run a new Docker container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:232 +#: ../../source/how-to-run-flower-using-docker.rst:348 +msgid "" +"``--rm``: This option specifies that the container should be " +"automatically removed when it stops." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:233 +msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:234 +#: ../../source/how-to-run-flower-using-docker.rst:350 +msgid "``--insecure``: This option enables insecure communication." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "" +"``--server 192.168.1.100:9092``: This option specifies the address of the" +" SuperLinks Fleet" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "API to connect to. Remember to update it with your SuperLink IP." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:248 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your SuperNodes." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:252 +msgid "" +"Any argument that comes after the tag is passed to the Flower SuperNode " +"binary. To see all available flags that the SuperNode supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:262 +msgid "" +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your SuperNode container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:264 +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the SuperNode to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:275 +msgid "Flower ServerApp" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:277 +msgid "" +"The procedure for building and running a ServerApp image is almost " +"identical to the SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:279 +msgid "" +"Similar to the SuperNode image, the ServerApp Docker image comes with a " +"pre-installed version of Flower and serves as a base for building your " +"own ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:282 +msgid "" +"We will use the same ``quickstart-pytorch`` example as we do in the " +"Flower SuperNode section. If you have not already done so, please follow " +"the `SuperNode Prerequisites`_ before proceeding." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:287 +msgid "Creating a ServerApp Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:298 +msgid "" +"First, we need to create a Dockerfile in the directory where the " +"``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.serverapp`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:302 +msgid "" +"The ``Dockerfile.serverapp`` contains the instructions that assemble the " +"ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:313 +msgid "" +"In the first two lines, we instruct Docker to use the ServerApp image " +"tagged ``1.8.0`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. In the last two lines, we copy the ``server.py`` module into " +"the image and set the entry point to ``flower-server-app`` with the " +"argument ``server:app``. The argument is the object reference of the " +"ServerApp (``:``) that will be run inside the " +"ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:321 +#, fuzzy +msgid "Building the ServerApp Docker image" +msgstr "Construindo a imagem do servidor" + +#: ../../source/how-to-run-flower-using-docker.rst:323 +msgid "" +"Next, we build the ServerApp Docker image by running the following " +"command in the directory where Dockerfile and ServerApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:330 +msgid "" +"We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:335 +#, fuzzy +msgid "Running the ServerApp Docker image" +msgstr "Construindo a imagem do servidor" + +#: ../../source/how-to-run-flower-using-docker.rst:337 +msgid "Now that we have built the ServerApp image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:349 +msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "" +"``--server 192.168.1.100:9091``: This option specifies the address of the" +" SuperLinks Driver" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:363 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your ServerApps." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:367 +msgid "" +"Any argument that comes after the tag is passed to the Flower ServerApp " +"binary. To see all available flags that the ServerApp supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:377 +msgid "" +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:379 +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the ServerApp to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:390 +msgid "Advanced Docker options" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:393 +msgid "Using a different Flower version" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:395 +msgid "" +"If you want to use a different version of Flower, for example Flower " +"nightly, you can do so by changing the tag. All available versions are on" +" `Docker Hub `__." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:400 +msgid "Pinning a Docker image to a specific version" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:402 +msgid "" +"It may happen that we update the images behind the tags. Such updates " +"usually include security updates of system dependencies that should not " +"change the functionality of Flower. However, if you want to ensure that " "you always use the same image, you can specify the hash of the image " "instead of the tag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:121 +#: ../../source/how-to-run-flower-using-docker.rst:407 msgid "" "The following command returns the current image hash referenced by the " -"``server:1.7.0-py3.11-ubuntu22.04`` tag:" +"``superlink:1.8.0`` tag:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:128 -msgid "Next, we can pin the hash when running a new server container:" +#: ../../source/how-to-run-flower-using-docker.rst:414 +msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:137 +#: ../../source/how-to-run-flower-using-docker.rst:423 msgid "Setting environment variables" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:139 +#: ../../source/how-to-run-flower-using-docker.rst:425 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." @@ -5542,6 +5748,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 +#: ../../source/how-to-upgrade-to-flower-next.rst:43 msgid "Install update" msgstr "" @@ -5585,6 +5792,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 +#: ../../source/how-to-upgrade-to-flower-next.rst:100 msgid "Required changes" msgstr "" @@ -5615,6 +5823,11 @@ msgid "" "client=FlowerClient())``" msgstr "" +#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 +#: ../../source/ref-api/flwr.client.Client.rst:2 +msgid "Client" +msgstr "" + #: ../../source/how-to-upgrade-to-flower-1.0.rst:39 msgid "" "Subclasses of ``NumPyClient``: change ``def get_parameters(self):``` to " @@ -5783,6 +5996,7 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 +#: ../../source/how-to-upgrade-to-flower-next.rst:317 msgid "Further help" msgstr "" @@ -5795,6 +6009,188 @@ msgid "" "`_ and use the channel ``#questions``." msgstr "" +#: ../../source/how-to-upgrade-to-flower-next.rst:2 +msgid "Upgrade to Flower Next" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:4 +msgid "" +"Welcome to the migration guide for updating Flower to Flower Next! " +"Whether you're a seasoned user or just getting started, this guide will " +"help you smoothly transition your existing setup to take advantage of the" +" latest features and improvements in Flower Next, starting from version " +"1.8." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:9 +msgid "" +"This guide shows how to reuse pre-``1.8`` Flower code with minimum code " +"changes by using the *compatibility layer* in Flower Next. In another " +"guide, we will show how to run Flower Next end-to-end with pure Flower " +"Next APIs." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:13 +msgid "Let's dive in!" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:48 +msgid "" +"Here's how to update an existing installation of Flower to Flower Next " +"with ``pip``:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:54 +msgid "or if you need Flower Next with simulation:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:61 +msgid "" +"Ensure you set the following version constraint in your " +"``requirements.txt``" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:71 +msgid "or ``pyproject.toml``:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:82 +msgid "Using Poetry" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:84 +msgid "" +"Update the ``flwr`` dependency in ``pyproject.toml`` and then reinstall " +"(don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` before " +"running ``poetry install``)." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:86 +msgid "" +"Ensure you set the following version constraint in your " +"``pyproject.toml``:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:102 +msgid "" +"In Flower Next, the *infrastructure* and *application layers* have been " +"decoupled. Instead of starting a client in code via ``start_client()``, " +"you create a |clientapp_link|_ and start it via the command line. Instead" +" of starting a server in code via ``start_server()``, you create a " +"|serverapp_link|_ and start it via the command line. The long-running " +"components of server and client are called SuperLink and SuperNode. The " +"following non-breaking changes that require manual updates and allow you " +"to run your project both in the traditional way and in the Flower Next " +"way:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:109 +msgid "|clientapp_link|_" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:110 +msgid "" +"Wrap your existing client with |clientapp_link|_ instead of launching it " +"via |startclient_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:132 +msgid "|serverapp_link|_" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:133 +msgid "" +"Wrap your existing strategy with |serverapp_link|_ instead of starting " +"the server via |startserver_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:154 +msgid "Deployment" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:155 +msgid "" +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " +"in sequence, |flowernext_clientapp_link|_ (2x) and " +"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" +" `server.py` as Python scripts." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:158 +msgid "" +"Here's an example to start the server without HTTPS (only for " +"prototyping):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:174 +msgid "" +"Here's another example to start with HTTPS. Use the ``--certificates`` " +"command line argument to pass paths to (CA certificate, server " +"certificate, and server private key)." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:201 +msgid "Simulation in CLI" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:202 +msgid "" +"Wrap your existing client and strategy with |clientapp_link|_ and " +"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" +" anymore. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:232 +msgid "" +"Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " +"``client_app`` object in the code instead of executing the Python script." +" Here's an example (assuming the ``server_app`` and ``client_app`` " +"objects are in a ``sim.py`` module):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:249 +msgid "" +"Set default resources for each |clientapp_link|_ using the ``--backend-" +"config`` command line argument instead of setting the " +"``client_resources`` argument in |startsim_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:275 +msgid "Simulation in a Notebook" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:276 +msgid "" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " +"an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:319 +msgid "" +"Some official `Flower code examples `_ " +"are already updated to Flower Next so they can serve as a reference for " +"using the Flower Next API. If there are further questions, `join the " +"Flower Slack `_ and use the channel " +"``#questions``. You can also `participate in Flower Discuss " +"`_ where you can find us answering questions," +" or share and learn from others about migrating to Flower Next." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:325 +msgid "Important" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:328 +msgid "" +"As we continuously enhance Flower Next at a rapid pace, we'll be " +"periodically updating this guide. Please feel free to share any feedback " +"with us!" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:334 +msgid "Happy migrating! 🚀" +msgstr "" + #: ../../source/how-to-use-built-in-mods.rst:2 msgid "Use Built-in Mods" msgstr "" @@ -6170,15 +6566,15 @@ msgstr "" msgid "Quickstart tutorials" msgstr "" -#: ../../source/index.rst:75 ../../source/index.rst:79 +#: ../../source/index.rst:74 ../../source/index.rst:78 msgid "How-to guides" msgstr "" -#: ../../source/index.rst:98 +#: ../../source/index.rst:99 msgid "Legacy example guides" msgstr "" -#: ../../source/index.rst:109 ../../source/index.rst:113 +#: ../../source/index.rst:108 ../../source/index.rst:112 msgid "Explanations" msgstr "" @@ -6186,23 +6582,23 @@ msgstr "" msgid "API reference" msgstr "" -#: ../../source/index.rst:138 +#: ../../source/index.rst:137 msgid "Reference docs" msgstr "" -#: ../../source/index.rst:154 +#: ../../source/index.rst:153 msgid "Contributor tutorials" msgstr "" -#: ../../source/index.rst:161 +#: ../../source/index.rst:160 msgid "Contributor how-to guides" msgstr "" -#: ../../source/index.rst:174 +#: ../../source/index.rst:173 msgid "Contributor explanations" msgstr "" -#: ../../source/index.rst:180 +#: ../../source/index.rst:179 msgid "Contributor references" msgstr "" @@ -6259,60 +6655,60 @@ msgid "" "place to start." msgstr "" -#: ../../source/index.rst:62 +#: ../../source/index.rst:61 msgid "" "QUICKSTART TUTORIALS: :doc:`PyTorch ` | " ":doc:`TensorFlow ` | :doc:`🤗 Transformers" " ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " "` | :doc:`PyTorch Lightning ` | :doc:`MXNet `" -" | :doc:`scikit-learn ` | :doc:`XGBoost " -"` | :doc:`Android ` | :doc:`iOS `" +"quickstart-pytorch-lightning>` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " +":doc:`Android ` | :doc:`iOS `" msgstr "" -#: ../../source/index.rst:64 +#: ../../source/index.rst:63 msgid "We also made video tutorials for PyTorch:" msgstr "" -#: ../../source/index.rst:69 +#: ../../source/index.rst:68 msgid "And TensorFlow:" msgstr "" -#: ../../source/index.rst:77 +#: ../../source/index.rst:76 msgid "" "Problem-oriented how-to guides show step-by-step how to achieve a " "specific goal." msgstr "" -#: ../../source/index.rst:111 +#: ../../source/index.rst:110 msgid "" "Understanding-oriented concept guides explain and discuss key topics and " "underlying ideas behind Flower and collaborative AI." msgstr "" -#: ../../source/index.rst:121 +#: ../../source/index.rst:120 msgid "References" msgstr "" -#: ../../source/index.rst:123 +#: ../../source/index.rst:122 msgid "Information-oriented API reference and other reference material." msgstr "" -#: ../../source/index.rst:132::1 +#: ../../source/index.rst:131::1 msgid ":py:obj:`flwr `\\" msgstr "" -#: ../../source/index.rst:132::1 flwr:1 of +#: ../../source/index.rst:131::1 flwr:1 of msgid "Flower main package." msgstr "" -#: ../../source/index.rst:149 +#: ../../source/index.rst:148 msgid "Contributor docs" msgstr "" -#: ../../source/index.rst:151 +#: ../../source/index.rst:150 msgid "" "The Flower community welcomes contributions. The following docs are " "intended to help along the way." @@ -6323,22 +6719,18 @@ msgid "Flower CLI reference" msgstr "" #: ../../source/ref-api-cli.rst:7 -msgid "flower-superlink" +msgid "flower-simulation" msgstr "" #: ../../source/ref-api-cli.rst:17 -msgid "flower-driver-api" +msgid "flower-superlink" msgstr "" #: ../../source/ref-api-cli.rst:27 -msgid "flower-fleet-api" -msgstr "" - -#: ../../source/ref-api-cli.rst:37 msgid "flower-client-app" msgstr "" -#: ../../source/ref-api-cli.rst:47 +#: ../../source/ref-api-cli.rst:37 msgid "flower-server-app" msgstr "" @@ -6346,7 +6738,7 @@ msgstr "" msgid "flwr" msgstr "" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:52 +#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 msgid "Modules" msgstr "" @@ -6371,7 +6763,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr "" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:41::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." msgstr "" @@ -6395,77 +6787,87 @@ msgstr "" msgid "Functions" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 msgid ":py:obj:`run_client_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 -#: flwr.client.app.run_client_app:1 of +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_client_app:1 of msgid "Run Flower client app." msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 +msgid ":py:obj:`run_supernode `\\ \\(\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_supernode:1 of +msgid "Run Flower SuperNode." +msgstr "" + +#: ../../source/ref-api/flwr.client.rst:25::1 msgid "" ":py:obj:`start_client `\\ \\(\\*\\, " "server\\_address\\[\\, client\\_fn\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_client:1 of msgid "Start a Flower client node which connects to a Flower server." msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 msgid "" ":py:obj:`start_numpy_client `\\ \\(\\*\\," " server\\_address\\, client\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_numpy_client:1 of msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "" -#: ../../source/ref-api/flwr.client.rst:26 +#: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:29 +#: ../../source/ref-api/flwr.server.rst:28 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`Client `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client.Client:1 of msgid "Abstract base class for Flower clients." msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid "" ":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " "mods\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client_app.ClientApp:1 of msgid "Flower ClientApp." msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`NumPyClient `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.numpy_client.NumPyClient:1 of msgid "Abstract base class for Flower clients using NumPy." msgstr "" #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 -#: flwr.server.strategy.strategy.Strategy:1 of +#: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 +#: of msgid "Bases: :py:class:`~abc.ABC`" msgstr "" @@ -6480,6 +6882,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.Error.rst:15 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:15 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:15 +#: ../../source/ref-api/flwr.common.EventType.rst:15 #: ../../source/ref-api/flwr.common.FitIns.rst:15 #: ../../source/ref-api/flwr.common.FitRes.rst:15 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:15 @@ -6616,7 +7019,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.Error.rst:25 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:25 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:25 -#: ../../source/ref-api/flwr.common.EventType.rst:19 +#: ../../source/ref-api/flwr.common.EventType.rst:165 #: ../../source/ref-api/flwr.common.FitIns.rst:25 #: ../../source/ref-api/flwr.common.FitRes.rst:25 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:25 @@ -6659,7 +7062,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.unregister #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver flwr.server.driver.driver.Driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -6711,7 +7113,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -6745,7 +7146,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -6810,9 +7210,9 @@ msgstr "" #: flwr.common.typing.GetParametersRes:1 flwr.common.typing.GetPropertiesIns:1 #: flwr.common.typing.GetPropertiesRes:1 flwr.common.typing.Parameters:1 #: flwr.common.typing.ReconnectIns:1 flwr.common.typing.ServerMessage:1 -#: flwr.common.typing.Status:1 flwr.server.driver.driver.Driver:1 -#: flwr.server.history.History:1 flwr.server.server.Server:1 -#: flwr.server.server_app.ServerApp:1 flwr.server.server_config.ServerConfig:1 +#: flwr.common.typing.Status:1 flwr.server.history.History:1 +#: flwr.server.server.Server:1 flwr.server.server_app.ServerApp:1 +#: flwr.server.server_config.ServerConfig:1 #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of @@ -6824,8 +7224,7 @@ msgstr "" #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 #: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 -#: flwr.server.compat.app.start_driver:32 flwr.server.server_app.ServerApp:4 -#: flwr.server.server_app.ServerApp.main:4 +#: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:21 @@ -7045,6 +7444,10 @@ msgstr "" msgid "run\\_client\\_app" msgstr "" +#: ../../source/ref-api/flwr.client.run_supernode.rst:2 +msgid "run\\_supernode" +msgstr "" + #: ../../source/ref-api/flwr.client.start_client.rst:2 msgid "start\\_client" msgstr "" @@ -7076,8 +7479,7 @@ msgid "" "increased limit and block larger messages." msgstr "" -#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 -#: flwr.server.compat.app.start_driver:21 of +#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " "provided, a secure connection using the certificates will be established " @@ -7643,12 +8045,11 @@ msgstr "" #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "" "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`str`, :py:class:`bytes`, :py:class:`bool`, " -":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " -"[:py:class:`float`], :py:class:`~typing.List`\\ [:py:class:`str`], " -":py:class:`~typing.List`\\ [:py:class:`bytes`], " -":py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" +" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " +"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " +":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" +" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -7810,11931 +8211,13894 @@ msgstr "" msgid "Bases: :py:class:`str`, :py:class:`~enum.Enum`" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`PING `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`encode `\\ \\(\\[encoding\\, " +"errors\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_CLIENT_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.encode:1 of +msgid "Encode the string using the codec registered for encoding." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_CLIENT_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`replace `\\ \\(old\\, new\\[\\, " +"count\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_SERVER_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.replace:1 of +msgid "Return a copy with all occurrences of substring old replaced by new." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_SERVER_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`split `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -":py:obj:`RUN_DRIVER_API_ENTER " -"`\\" +"Return a list of the substrings in the string, using sep as the separator" +" string." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE " -"`\\" +":py:obj:`rsplit `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_FLEET_API_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`join `\\ \\(iterable\\, \\/\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_FLEET_API_LEAVE " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.join:1 of +msgid "Concatenate any number of strings." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_SUPERLINK_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`capitalize `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.capitalize:1 of +msgid "Return a capitalized version of the string." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`START_SIMULATION_ENTER " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`casefold `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`START_SIMULATION_LEAVE " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.casefold:1 of +msgid "Return a version of the string suitable for caseless comparisons." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`DRIVER_CONNECT `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`title `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`DRIVER_DISCONNECT `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.title:1 of +msgid "Return a version of the string where each word is titlecased." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_DRIVER_ENTER `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`center `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid ":py:obj:`START_DRIVER_LEAVE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.center:1 of +msgid "Return a centered string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER " -"`\\" +":py:obj:`count `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE " -"`\\" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_SERVER_APP_ENTER " -"`\\" +":py:obj:`expandtabs `\\ " +"\\(\\[tabsize\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE " -"`\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.expandtabs:1 of +msgid "Return a copy where all tab characters are expanded using spaces." msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:2 -msgid "FitIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`find `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:2 -msgid "FitRes" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.partition:1 flwr.common.EventType.rpartition:1 of +msgid "Partition the string into three parts using the given separator." msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`index `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`ljust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`num_examples `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.ljust:1 of +msgid "Return a left-justified string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -msgid ":py:obj:`metrics `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`lower `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 -msgid "GetParametersIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lower:1 of +msgid "Return a copy of the string converted to lowercase." msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`lstrip `\\ \\(\\[chars\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 -msgid "GetParametersRes" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lstrip:1 of +msgid "Return a copy of the string with leading whitespace removed." msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rfind `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 -msgid ":py:obj:`parameters `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]." msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 -msgid "GetPropertiesIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rindex `\\ \\(sub\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 -msgid ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`rjust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 -msgid "GetPropertiesRes" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rjust:1 of +msgid "Return a right-justified string of length width." msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 -msgid ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`rstrip `\\ \\(\\[chars\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 -msgid ":py:obj:`properties `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rstrip:1 of +msgid "Return a copy of the string with trailing whitespace removed." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:2 -msgid "Message" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" msgstr "" -#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 -#: flwr.common.message.Message:3 of -msgid "A dataclass including information about the message to be executed." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`splitlines `\\ " +"\\(\\[keepends\\]\\)" msgstr "" -#: flwr.common.message.Message:5 of -msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side" -" logic to a client, or vice-versa) or that will be sent to it." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.splitlines:1 of +msgid "Return a list of the lines in the string, breaking at line boundaries." msgstr "" -#: flwr.common.message.Message:8 of -msgid "" -"A dataclass that captures information about an error that took place when" -" processing another message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`strip `\\ \\(\\[chars\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -msgid "" -":py:obj:`create_error_reply `\\ " -"\\(error\\, ttl\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.strip:1 of +msgid "Return a copy of the string with leading and trailing whitespace removed." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_error_reply:1 of -msgid "Construct a reply message indicating an error happened." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`swapcase `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.swapcase:1 of msgid "" -":py:obj:`create_reply `\\ \\(content\\," -" ttl\\)" +"Convert uppercase characters to lowercase and lowercase characters to " +"uppercase." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_reply:1 of -msgid "Create a reply to this message with specified content and TTL." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -msgid ":py:obj:`has_content `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.translate:1 of +msgid "Replace each character in the string using the given translation table." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_content:1 of -msgid "Return True if message has content, else False." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`upper `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -msgid ":py:obj:`has_error `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.upper:1 of +msgid "Return a copy of the string converted to uppercase." msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_error:1 of -msgid "Return True if message has an error, else False." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`startswith `\\ \\(prefix\\[\\," +" start\\[\\, end\\]\\]\\)" msgstr "" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`content `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S starts with the specified prefix, False otherwise." msgstr "" -#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 -#: of -msgid "The content of this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`endswith `\\ \\(suffix\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`error `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S ends with the specified suffix, False otherwise." msgstr "" -#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of -msgid "Error captured by this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`removeprefix `\\ " +"\\(prefix\\, \\/\\)" msgstr "" -#: flwr.common.Message.content:1::1 of -msgid ":py:obj:`metadata `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removeprefix:1 of +msgid "Return a str with the given prefix string removed if present." msgstr "" -#: flwr.common.message.Message.create_error_reply:3 of -msgid "The error that was encountered." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`removesuffix `\\ " +"\\(suffix\\, \\/\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.ttl:1 flwr.common.message.Message.create_error_reply:5 -#: flwr.common.message.Message.create_reply:9 flwr.common.message.Metadata:16 -#: of -msgid "Time-to-live for this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removesuffix:1 of +msgid "Return a str with the given suffix string removed if present." msgstr "" -#: flwr.common.message.Message.create_reply:3 of -msgid "" -"The method generates a new `Message` as a reply to this message. It " -"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " -"this message and sets 'reply_to_message' to the ID of this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isascii `\\ \\(\\)" msgstr "" -#: flwr.common.message.Message.create_reply:7 of -msgid "The content for the reply message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isascii:1 of +msgid "Return True if all characters in the string are ASCII, False otherwise." msgstr "" -#: flwr.common.message.Message.create_reply:12 of -msgid "A new `Message` instance representing the reply." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`islower `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:2 -msgid "MessageType" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.islower:1 of +msgid "Return True if the string is a lowercase string, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`EVALUATE `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isupper `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`QUERY `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isupper:1 of +msgid "Return True if the string is an uppercase string, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 -msgid ":py:obj:`TRAIN `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`istitle `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 -msgid "MessageTypeLegacy" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.istitle:1 of +msgid "Return True if the string is a title-cased string, False otherwise." msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PARAMETERS `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isspace `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PROPERTIES `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isspace:1 of +msgid "Return True if the string is a whitespace string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of -msgid "An identifier for the current run." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isdecimal `\\ \\(\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of -msgid "An identifier for the current message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdecimal:1 of +msgid "Return True if the string is a decimal string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of -msgid "An identifier for the node sending this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isdigit `\\ \\(\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1 -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.message.Metadata:9 of -msgid "An identifier for the node receiving this message." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdigit:1 of +msgid "Return True if the string is a digit string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of -msgid "An identifier for the message this message replies to." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isnumeric `\\ \\(\\)" msgstr "" -#: flwr.common.message.Metadata:13 of -msgid "" -"An identifier for grouping messages. In some settings, this is used as " -"the FL round." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isnumeric:1 of +msgid "Return True if the string is a numeric string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of -msgid "A string that encodes the action to be executed on the receiving end." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isalpha `\\ \\(\\)" msgstr "" -#: flwr.common.message.Metadata:21 of -msgid "" -"An identifier that can be used when loading a particular data partition " -"for a ClientApp. Making use of this identifier is more relevant when " -"conducting simulations." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalpha:1 of +msgid "Return True if the string is an alphabetic string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`dst_node_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isalnum `\\ \\(\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`group_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalnum:1 of +msgid "Return True if the string is an alpha-numeric string, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.group_id:1 of -msgid "An identifier for grouping messages." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isidentifier `\\ \\(\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`message_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isidentifier:1 of +msgid "Return True if the string is a valid Python identifier, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`message_type `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`isprintable `\\ \\(\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`partition_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isprintable:1 of +msgid "Return True if the string is printable, False otherwise." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.partition_id:1 of -msgid "An identifier telling which data partition a ClientApp should use." +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`zfill `\\ \\(width\\, \\/\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`reply_to_message `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.zfill:1 of +msgid "" +"Pad a numeric string with zeros on the left, to fill a field of the given" +" width." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`run_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +":py:obj:`format `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`src_node_id `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from args and kwargs." msgstr "" -#: flwr.common.Metadata.dst_node_id:1::1 of -msgid ":py:obj:`ttl `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`format_map `\\ \\(mapping\\)" msgstr "" -#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 -msgid "MetricsRecord" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from mapping." msgstr "" -#: flwr.common.record.metricsrecord.MetricsRecord:1 of -msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " -":py:class:`float`, :py:class:`~typing.List`\\ [:py:class:`int`], " -":py:class:`~typing.List`\\ [:py:class:`float`]]]" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid ":py:obj:`maketrans `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`clear `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.maketrans:1 of +msgid "Return a translation table usable for str.translate()." msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`PING `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_CLIENT_ENTER `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_SERVER_ENTER `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_SERVER_LEAVE `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +":py:obj:`RUN_DRIVER_API_ENTER " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_DRIVER_API_LEAVE " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.NDArray.rst:2 -msgid "NDArray" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_FLEET_API_ENTER " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -msgid ":py:obj:`tensors `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_FLEET_API_LEAVE " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -msgid ":py:obj:`tensor_type `\\" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 -msgid "ParametersRecord" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord:1 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +":py:obj:`START_SIMULATION_ENTER " +"`\\" msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord:3 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds " -"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " -"viewed as an equivalent to PyTorch's state_dict, but holding serialised " -"tensors instead." +":py:obj:`START_SIMULATION_LEAVE " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`clear `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`DRIVER_CONNECT `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`DRIVER_DISCONNECT `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_ENTER `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_CLIENT_APP_ENTER " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_CLIENT_APP_LEAVE " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +":py:obj:`RUN_SERVER_APP_ENTER " +"`\\" msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SERVER_APP_LEAVE " +"`\\" msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of +#: flwr.common.EventType.capitalize:1::1 of msgid "" -"Note that a small amount of Bytes might also be included in this counting" -" that correspond to metadata of the serialized object (e.g. of NumPy " -"array) needed for deseralization." +":py:obj:`RUN_SUPERNODE_ENTER " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 -msgid "ReconnectIns" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPERNODE_LEAVE " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 -msgid ":py:obj:`seconds `\\" +#: flwr.common.EventType.capitalize:3 of +msgid "" +"More specifically, make the first character have upper case and the rest " +"lower case." msgstr "" -#: ../../source/ref-api/flwr.common.RecordSet.rst:2 -msgid "RecordSet" +#: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 +#: flwr.common.EventType.rjust:3 of +msgid "Padding is done using the specified fill character (default is a space)." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`configs_records `\\" +#: flwr.common.EventType.count:1 of +msgid "" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]. Optional arguments start and end are interpreted as" +" in slice notation." msgstr "" -#: flwr.common.RecordSet.configs_records:1 -#: flwr.common.RecordSet.configs_records:1::1 of -msgid "Dictionary holding ConfigsRecord instances." +#: flwr.common.EventType.encode:3 of +msgid "encoding" msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`metrics_records `\\" +#: flwr.common.EventType.encode:4 of +msgid "The encoding in which to encode the string." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.metrics_records:1 of -msgid "Dictionary holding MetricsRecord instances." +#: flwr.common.EventType.encode:9 of +msgid "errors" msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`parameters_records `\\" +#: flwr.common.EventType.encode:6 of +msgid "" +"The error handling scheme to use for encoding errors. The default is " +"'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " +"as any other name registered with codecs.register_error that can handle " +"UnicodeEncodeErrors." msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.parameters_records:1 of -msgid "Dictionary holding ParametersRecord instances." +#: flwr.common.EventType.endswith:1 of +msgid "" +"Return True if S ends with the specified suffix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. suffix can also be a tuple of strings " +"to try." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 -msgid "ServerMessage" +#: flwr.common.EventType.expandtabs:3 of +msgid "If tabsize is not given, a tab size of 8 characters is assumed." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -msgid ":py:obj:`evaluate_ins `\\" +#: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of +msgid "" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -msgid ":py:obj:`fit_ins `\\" +#: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of +msgid "Return -1 on failure." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#: flwr.common.EventType.format:1 of msgid "" -":py:obj:`get_parameters_ins " -"`\\" +"Return a formatted version of S, using substitutions from args and " +"kwargs. The substitutions are identified by braces ('{' and '}')." msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +#: flwr.common.EventType.format_map:1 of msgid "" -":py:obj:`get_properties_ins " -"`\\" +"Return a formatted version of S, using substitutions from mapping. The " +"substitutions are identified by braces ('{' and '}')." msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:2 -msgid "Status" +#: flwr.common.EventType.index:5 flwr.common.EventType.rindex:5 of +msgid "Raises ValueError when the substring is not found." msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -msgid ":py:obj:`code `\\" +#: flwr.common.EventType.isalnum:3 of +msgid "" +"A string is alpha-numeric if all characters in the string are alpha-" +"numeric and there is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -msgid ":py:obj:`message `\\" +#: flwr.common.EventType.isalpha:3 of +msgid "" +"A string is alphabetic if all characters in the string are alphabetic and" +" there is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 -msgid "array\\_from\\_numpy" +#: flwr.common.EventType.isascii:3 of +msgid "" +"ASCII characters have code points in the range U+0000-U+007F. Empty " +"string is ASCII too." msgstr "" -#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 -msgid "bytes\\_to\\_ndarray" +#: flwr.common.EventType.isdecimal:3 of +msgid "" +"A string is a decimal string if all characters in the string are decimal " +"and there is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.configure.rst:2 -msgid "configure" +#: flwr.common.EventType.isdigit:3 of +msgid "" +"A string is a digit string if all characters in the string are digits and" +" there is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.event.rst:2 -msgid "event" +#: flwr.common.EventType.isidentifier:3 of +msgid "" +"Call keyword.iskeyword(s) to test whether string s is a reserved " +"identifier, such as \"def\" or \"class\"." msgstr "" -#: ../../source/ref-api/flwr.common.log.rst:2 -msgid "log" +#: flwr.common.EventType.islower:3 of +msgid "" +"A string is lowercase if all cased characters in the string are lowercase" +" and there is at least one cased character in the string." msgstr "" -#: logging.Logger.log:3 of +#: flwr.common.EventType.isnumeric:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a " -"true value, e.g." +"A string is numeric if all characters in the string are numeric and there" +" is at least one character in the string." msgstr "" -#: logging.Logger.log:6 of -#, python-format -msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" +#: flwr.common.EventType.isprintable:3 of +msgid "" +"A string is printable if all of its characters are considered printable " +"in repr() or if it is empty." msgstr "" -#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 -msgid "ndarray\\_to\\_bytes" +#: flwr.common.EventType.isspace:3 of +msgid "" +"A string is whitespace if all characters in the string are whitespace and" +" there is at least one character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 -msgid "ndarrays\\_to\\_parameters" +#: flwr.common.EventType.istitle:3 of +msgid "" +"In a title-cased string, upper- and title-case characters may only follow" +" uncased characters and lowercase characters only cased ones." msgstr "" -#: ../../source/ref-api/flwr.common.now.rst:2 -msgid "now" +#: flwr.common.EventType.isupper:3 of +msgid "" +"A string is uppercase if all cased characters in the string are uppercase" +" and there is at least one cased character in the string." msgstr "" -#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 -msgid "parameters\\_to\\_ndarrays" +#: flwr.common.EventType.join:3 of +msgid "" +"The string whose method is called is inserted in between each given " +"string. The result is returned as a new string." msgstr "" -#: ../../source/ref-api/flwr.server.rst:2 -msgid "server" +#: flwr.common.EventType.join:6 of +msgid "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#: flwr.common.EventType.lstrip:3 flwr.common.EventType.rstrip:3 +#: flwr.common.EventType.strip:3 of +msgid "If chars is given and not None, remove characters in chars instead." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_driver_api:1 of -msgid "Run Flower server (Driver API)." +#: flwr.common.EventType.maketrans:3 of +msgid "" +"If there is only one argument, it must be a dictionary mapping Unicode " +"ordinals (integers) or characters to Unicode ordinals, strings or None. " +"Character keys will be then converted to ordinals. If there are two " +"arguments, they must be strings of equal length, and in the resulting " +"dictionary, each character in x will be mapped to the character at the " +"same position in y. If there is a third argument, it must be a string, " +"whose characters will be mapped to None in the result." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#: flwr.common.EventType.partition:3 of +msgid "" +"This will search for the separator in the string. If the separator is " +"found, returns a 3-tuple containing the part before the separator, the " +"separator itself, and the part after it." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_fleet_api:1 of -msgid "Run Flower server (Fleet API)." +#: flwr.common.EventType.partition:7 of +msgid "" +"If the separator is not found, returns a 3-tuple containing the original " +"string and two empty strings." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_server_app `\\ \\(\\)" +#: flwr.common.EventType.removeprefix:3 of +msgid "" +"If the string starts with the prefix string, return string[len(prefix):]." +" Otherwise, return a copy of the original string." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.run_serverapp.run_server_app:1 of -msgid "Run Flower server app." +#: flwr.common.EventType.removesuffix:3 of +msgid "" +"If the string ends with the suffix string and that suffix is not empty, " +"return string[:-len(suffix)]. Otherwise, return a copy of the original " +"string." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -msgid ":py:obj:`run_superlink `\\ \\(\\)" +#: flwr.common.EventType.replace:5 of +msgid "count" msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_superlink:1 of -msgid "Run Flower server (Driver API and Fleet API)." +#: flwr.common.EventType.replace:4 of +msgid "" +"Maximum number of occurrences to replace. -1 (the default value) means " +"replace all occurrences." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: flwr.common.EventType.replace:7 of msgid "" -":py:obj:`start_driver `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" +"If the optional argument count is given, only the first count occurrences" +" are replaced." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.compat.app.start_driver:1 of -msgid "Start a Flower Driver API server." +#: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of +msgid "" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: flwr.common.EventType.rpartition:3 of msgid "" -":py:obj:`start_server `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" +"This will search for the separator in the string, starting at the end. If" +" the separator is found, returns a 3-tuple containing the part before the" +" separator, the separator itself, and the part after it." msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.start_server:1 of -msgid "Start a Flower server using the gRPC transport layer." +#: flwr.common.EventType.rpartition:7 of +msgid "" +"If the separator is not found, returns a 3-tuple containing two empty " +"strings and the original string." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`ClientManager `\\ \\(\\)" +#: flwr.common.EventType.rsplit:7 flwr.common.EventType.split:7 of +msgid "sep" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.ClientManager:1 of -msgid "Abstract base class for managing Flower clients." +#: flwr.common.EventType.rsplit:4 flwr.common.EventType.split:4 of +msgid "The separator used to split the string." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of msgid "" -":py:obj:`Driver `\\ " -"\\(\\[driver\\_service\\_address\\, ...\\]\\)" +"When set to None (the default value), will split on any whitespace " +"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" +" empty strings from the result." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.driver.driver.Driver:1 of -msgid "`Driver` class provides an interface to the Driver API." +#: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of +msgid "maxsplit" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`History `\\ \\(\\)" +#: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of +msgid "" +"Maximum number of splits (starting from the left). -1 (the default value)" +" means no limit." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.history.History:1 of -msgid "History class for training and/or evaluation metrics collection." +#: flwr.common.EventType.rsplit:13 of +msgid "Splitting starts at the end of the string and works to the front." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.EventType.split:13 of msgid "" -":py:obj:`LegacyContext `\\ \\(state\\[\\, " -"config\\, strategy\\, ...\\]\\)" +"Note, str.split() is mainly useful for data that has been intentionally " +"delimited. With natural text that includes punctuation, consider using " +"the regular expression module." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.compat.legacy_context.LegacyContext:1 of -msgid "Legacy Context." +#: flwr.common.EventType.splitlines:3 of +msgid "" +"Line breaks are not included in the resulting list unless keepends is " +"given and true." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.EventType.startswith:1 of msgid "" -":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " -"strategy\\]\\)" +"Return True if S starts with the specified prefix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. prefix can also be a tuple of strings " +"to try." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.EventType.title:3 of msgid "" -":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " -"strategy\\, ...\\]\\)" +"More specifically, words start with uppercased characters and all " +"remaining cased characters have lower case." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_app.ServerApp:1 of -msgid "Flower ServerApp." +#: flwr.common.EventType.translate:5 of +msgid "table" msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.EventType.translate:4 of msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," -" round\\_timeout\\]\\)" +"Translation table, which must be a mapping of Unicode ordinals to Unicode" +" ordinals, strings, or None." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_config.ServerConfig:1 of -msgid "Flower server config." +#: flwr.common.EventType.translate:7 of +msgid "" +"The table must implement lookup/indexing via __getitem__, for instance a " +"dictionary or list. If this operation raises LookupError, the character " +"is left untouched. Characters mapped to None are deleted." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +#: flwr.common.EventType.zfill:3 of +msgid "The string is never truncated." msgstr "" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.SimpleClientManager:1 of -msgid "Provides a pool of available clients." +#: ../../source/ref-api/flwr.common.FitIns.rst:2 +msgid "FitIns" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -msgid ":py:obj:`flwr.server.strategy `\\" +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +msgid ":py:obj:`parameters `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.strategy:1 of -msgid "Contains the strategy abstraction and different implementations." +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +msgid ":py:obj:`config `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -msgid ":py:obj:`flwr.server.workflow `\\" +#: ../../source/ref-api/flwr.common.FitRes.rst:2 +msgid "FitRes" msgstr "" -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.workflow:1 of -msgid "Workflows." +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`status `\\" msgstr "" -#: ../../source/ref-api/flwr.server.ClientManager.rst:2 -msgid "ClientManager" +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`parameters `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`all `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`num_examples `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1 -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.all:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "Return all available clients." +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +msgid ":py:obj:`metrics `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`num_available `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 +msgid "GetParametersIns" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.num_available:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.num_available:1 of -msgid "Return the number of available clients." +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 +msgid ":py:obj:`config `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`register `\\ \\(client\\)" +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 +msgid "GetParametersRes" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.register:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.register:1 of -msgid "Register Flower ClientProxy instance." +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +msgid ":py:obj:`status `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +msgid ":py:obj:`parameters `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.sample:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.sample:1 of -msgid "Sample a number of Flower ClientProxy instances." +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 +msgid "GetPropertiesIns" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`unregister `\\ \\(client\\)" +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 +msgid ":py:obj:`config `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.unregister:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.unregister:1 of -msgid "Unregister Flower ClientProxy instance." +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 +msgid "GetPropertiesRes" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of -msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\, timeout\\)" +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +msgid ":py:obj:`status `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.wait_for:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of -msgid "Wait until at least `num_clients` are available." +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +msgid ":py:obj:`properties `\\" msgstr "" -#: flwr.server.client_manager.ClientManager.num_available:3 -#: flwr.server.client_manager.SimpleClientManager.num_available:3 of -msgid "**num_available** -- The number of currently available clients." +#: ../../source/ref-api/flwr.common.Message.rst:2 +msgid "Message" msgstr "" -#: flwr.server.client_manager.ClientManager.register:6 -#: flwr.server.client_manager.SimpleClientManager.register:6 of -msgid "" -"**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any " -"reason." +#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 +#: flwr.common.message.Message:3 of +msgid "A dataclass including information about the message to be executed." msgstr "" -#: flwr.server.client_manager.ClientManager.unregister:3 -#: flwr.server.client_manager.SimpleClientManager.unregister:3 of -msgid "This method is idempotent." +#: flwr.common.message.Message:5 of +msgid "" +"Holds records either sent by another entity (e.g. sent by the server-side" +" logic to a client, or vice-versa) or that will be sent to it." msgstr "" -#: ../../source/ref-api/flwr.server.Driver.rst:2 -msgid "Driver" +#: flwr.common.message.Message:8 of +msgid "" +"A dataclass that captures information about an error that took place when" +" processing another message." msgstr "" -#: flwr.server.driver.driver.Driver:3 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:9091\"`." +":py:obj:`create_error_reply `\\ " +"\\(error\\[\\, ttl\\]\\)" msgstr "" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of -msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order: * CA certificate. * " -"server certificate. * server private key." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_error_reply:1 of +msgid "Construct a reply message indicating an error happened." msgstr "" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order:" +":py:obj:`create_reply `\\ " +"\\(content\\[\\, ttl\\]\\)" msgstr "" -#: flwr.server.app.start_server:32 flwr.server.driver.driver.Driver:10 of -msgid "CA certificate." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_reply:1 of +msgid "Create a reply to this message with specified content and TTL." msgstr "" -#: flwr.server.app.start_server:33 flwr.server.driver.driver.Driver:11 of -msgid "server certificate." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +msgid ":py:obj:`has_content `\\ \\(\\)" msgstr "" -#: flwr.server.app.start_server:34 flwr.server.driver.driver.Driver:12 of -msgid "server private key." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_content:1 of +msgid "Return True if message has content, else False." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid ":py:obj:`close `\\ \\(\\)" +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +msgid ":py:obj:`has_error `\\ \\(\\)" msgstr "" -#: flwr.server.driver.driver.Driver.close:1 -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "Disconnect from the SuperLink if connected." +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_error:1 of +msgid "Return True if message has an error, else False." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "" -":py:obj:`create_message `\\ " -"\\(content\\, message\\_type\\, ...\\)" +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`content `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.create_message:1 of -msgid "Create a new message with specified parameters." +#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 +#: of +msgid "The content of this message." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid ":py:obj:`get_node_ids `\\ \\(\\)" +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`error `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.get_node_ids:1 of -msgid "Get node IDs." +#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of +msgid "Error captured by this message." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of -msgid "" -":py:obj:`pull_messages `\\ " -"\\(message\\_ids\\)" +#: flwr.common.Message.content:1::1 of +msgid ":py:obj:`metadata `\\" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.pull_messages:1 of -msgid "Pull messages based on message IDs." +#: flwr.common.message.Message.create_error_reply:3 of +msgid "The error that was encountered." msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -":py:obj:`push_messages `\\ " -"\\(messages\\)" -msgstr "" - -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.push_messages:1 of -msgid "Push messages to specified node IDs." +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " +"msg.meta.created_at)" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -":py:obj:`send_and_receive `\\ " -"\\(messages\\, \\*\\[\\, timeout\\]\\)" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation:" msgstr "" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.send_and_receive:1 of -msgid "Push messages to specified node IDs and pull the reply messages." +#: flwr.common.message.Message.create_error_reply:9 +#: flwr.common.message.Message.create_reply:13 of +msgid "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" msgstr "" -#: flwr.server.driver.driver.Driver.create_message:3 of +#: flwr.common.message.Message.create_reply:3 of msgid "" -"This method constructs a new `Message` with given content and metadata. " -"The `run_id` and `src_node_id` will be set automatically." +"The method generates a new `Message` as a reply to this message. It " +"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " +"this message and sets 'reply_to_message' to the ID of this message." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:6 of -msgid "" -"The content for the new message. This holds records that are to be sent " -"to the destination node." +#: flwr.common.message.Message.create_reply:7 of +msgid "The content for the reply message." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:9 of -msgid "" -"The type of the message, defining the action to be executed on the " -"receiving end." +#: flwr.common.message.Message.create_reply:16 of +msgid "A new `Message` instance representing the reply." msgstr "" -#: flwr.server.driver.driver.Driver.create_message:12 of -msgid "The ID of the destination node to which the message is being sent." +#: ../../source/ref-api/flwr.common.MessageType.rst:2 +msgid "MessageType" msgstr "" -#: flwr.server.driver.driver.Driver.create_message:14 of -msgid "" -"The ID of the group to which this message is associated. In some " -"settings, this is used as the FL round." +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`EVALUATE `\\" msgstr "" -#: flwr.server.driver.driver.Driver.create_message:17 of -msgid "" -"Time-to-live for the round trip of this message, i.e., the time from " -"sending this message to receiving a reply. It specifies the duration for " -"which the message and its potential reply are considered valid." +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`QUERY `\\" msgstr "" -#: flwr.server.driver.driver.Driver.create_message:22 of -msgid "" -"**message** -- A new `Message` instance with the specified content and " -"metadata." +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +msgid ":py:obj:`TRAIN `\\" msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:3 of -msgid "" -"This method is used to collect messages from the SuperLink that " -"correspond to a set of given message IDs." +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 +msgid "MessageTypeLegacy" msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:6 of -msgid "An iterable of message IDs for which reply messages are to be retrieved." +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +msgid ":py:obj:`GET_PARAMETERS `\\" msgstr "" -#: flwr.server.driver.driver.Driver.pull_messages:9 of -msgid "**messages** -- An iterable of messages received." +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +msgid ":py:obj:`GET_PROPERTIES `\\" msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:3 of -msgid "" -"This method takes an iterable of messages and sends each message to the " -"node specified in `dst_node_id`." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of +msgid "An identifier for the current run." msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:6 -#: flwr.server.driver.driver.Driver.send_and_receive:7 of -msgid "An iterable of messages to be sent." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of +msgid "An identifier for the current message." msgstr "" -#: flwr.server.driver.driver.Driver.push_messages:9 of -msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, " -"which can be used to pull replies." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of +msgid "An identifier for the node sending this message." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:3 of -msgid "" -"This method sends a list of messages to their destination node IDs and " -"then waits for the replies. It continues to pull replies until either all" -" replies are received or the specified timeout duration is exceeded." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.dst_node_id:1 flwr.common.message.Metadata:9 of +msgid "An identifier for the node receiving this message." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:9 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of +msgid "An identifier for the message this message replies to." +msgstr "" + +#: flwr.common.message.Metadata:13 of msgid "" -"The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the " -"method will wait until replies for all messages are received." +"An identifier for grouping messages. In some settings, this is used as " +"the FL round." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:14 of -msgid "**replies** -- An iterable of reply messages received from the SuperLink." +#: flwr.common.message.Metadata:16 of +msgid "Time-to-live for this message in seconds." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -msgid "Notes" +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of +msgid "A string that encodes the action to be executed on the receiving end." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:19 of +#: flwr.common.message.Metadata:21 of msgid "" -"This method uses `push_messages` to send the messages and `pull_messages`" -" to collect the replies. If `timeout` is set, the method may not return " -"replies for all sent messages. A message remains valid until its TTL, " -"which is not affected by `timeout`." +"An identifier that can be used when loading a particular data partition " +"for a ClientApp. Making use of this identifier is more relevant when " +"conducting simulations." msgstr "" -#: ../../source/ref-api/flwr.server.History.rst:2 -msgid "History" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`created_at `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_loss_centralized " -"`\\ \\(server\\_round\\, " -"loss\\)" +#: flwr.common.Metadata.created_at:1 +#: flwr.common.Metadata.created_at:1::1 of +msgid "Unix timestamp when the message was created." msgstr "" -#: flwr.server.history.History.add_loss_centralized:1 -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "Add one loss entry (from centralized evaluation)." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`dst_node_id `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_loss_distributed " -"`\\ \\(server\\_round\\, " -"loss\\)" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`group_id `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_loss_distributed:1 of -msgid "Add one loss entry (from distributed evaluation)." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.group_id:1 of +msgid "An identifier for grouping messages." msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_metrics_centralized " -"`\\ \\(server\\_round\\, " -"metrics\\)" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`message_id `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_centralized:1 of -msgid "Add metrics entries (from centralized evaluation)." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`message_type `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_metrics_distributed " -"`\\ \\(server\\_round\\, " -"metrics\\)" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`partition_id `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed:1 of -msgid "Add metrics entries (from distributed evaluation)." +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.partition_id:1 of +msgid "An identifier telling which data partition a ClientApp should use." msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 of -msgid "" -":py:obj:`add_metrics_distributed_fit " -"`\\ \\(server\\_round\\," -" ...\\)" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`reply_to_message `\\" msgstr "" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed_fit:1 of -msgid "Add metrics entries (from distributed fit)." +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`run_id `\\" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 -msgid "LegacyContext" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`src_node_id `\\" msgstr "" -#: flwr.server.compat.legacy_context.LegacyContext:1 of -msgid "Bases: :py:class:`~flwr.common.context.Context`" +#: flwr.common.Metadata.created_at:1::1 of +msgid ":py:obj:`ttl `\\" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`config `\\" +#: flwr.common.Metadata.created_at:1::1 flwr.common.Metadata.ttl:1 +#: of +msgid "Time-to-live for this message." msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`strategy `\\" +#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 +msgid "MetricsRecord" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`client_manager `\\" +#: flwr.common.record.metricsrecord.MetricsRecord:1 of +msgid "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " +":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" +" [:py:class:`float`]]" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`history `\\" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 -msgid ":py:obj:`state `\\" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`client_manager `\\ \\(\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1 -#: flwr.server.server.Server.client_manager:1::1 of -msgid "Return ClientManager." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`items `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid "" -":py:obj:`disconnect_all_clients " -"`\\ \\(timeout\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`keys `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.disconnect_all_clients:1 of -msgid "Send shutdown signal to all clients." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" -":py:obj:`evaluate_round `\\ " -"\\(server\\_round\\, timeout\\)" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.evaluate_round:1 of -msgid "Validate current global model on a number of clients." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`values `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" +#: ../../source/ref-api/flwr.common.NDArray.rst:2 +msgid "NDArray" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit:1 of -msgid "Run federated averaging for a number of rounds." +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +msgid ":py:obj:`tensors `\\" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\," -" timeout\\)" +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 +msgid ":py:obj:`tensor_type `\\" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit_round:1 of -msgid "Perform a single round of federated averaging." +#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 +msgid "ParametersRecord" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "" -":py:obj:`set_max_workers `\\ " -"\\(max\\_workers\\)" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_max_workers:1 of -msgid "Set the max_workers used by ThreadPoolExecutor." +#: flwr.common.record.parametersrecord.ParametersRecord:3 of +msgid "" +"A dataclass storing named Arrays in order. This means that it holds " +"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " +"viewed as an equivalent to PyTorch's state_dict, but holding serialised " +"tensors instead." msgstr "" -#: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_strategy:1 of -msgid "Replace server strategy." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.ServerApp.rst:2 -msgid "ServerApp" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server_app.ServerApp:5 of -msgid "Use the `ServerApp` with an existing `Strategy`:" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`items `\\ \\(\\)" msgstr "" -#: flwr.server.server_app.ServerApp:15 of -msgid "Use the `ServerApp` with a custom main function:" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`keys `\\ \\(\\)" msgstr "" -#: flwr.server.server_app.ServerApp.main:1::1 of -msgid ":py:obj:`main `\\ \\(\\)" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" msgstr "" -#: flwr.server.server_app.ServerApp.main:1 -#: flwr.server.server_app.ServerApp.main:1::1 of -msgid "Return a decorator that registers the main fn with the server app." +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid "" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 -msgid "ServerConfig" +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +msgid ":py:obj:`values `\\ \\(\\)" msgstr "" -#: flwr.server.server_config.ServerConfig:3 of +#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of msgid "" -"All attributes have default values which allows users to configure just " -"the ones they care about." +"Note that a small amount of Bytes might also be included in this counting" +" that correspond to metadata of the serialized object (e.g. of NumPy " +"array) needed for deseralization." msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 -msgid ":py:obj:`num_rounds `\\" +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 +msgid "ReconnectIns" msgstr "" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 -msgid ":py:obj:`round_timeout `\\" +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 +msgid ":py:obj:`seconds `\\" msgstr "" -#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 -msgid "SimpleClientManager" +#: ../../source/ref-api/flwr.common.RecordSet.rst:2 +msgid "RecordSet" msgstr "" -#: flwr.server.client_manager.SimpleClientManager:1 of -msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`configs_records `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid ":py:obj:`all `\\ \\(\\)" +#: flwr.common.RecordSet.configs_records:1 +#: flwr.common.RecordSet.configs_records:1::1 of +msgid "Dictionary holding ConfigsRecord instances." msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`num_available `\\" -" \\(\\)" +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`metrics_records `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`register `\\ " -"\\(client\\)" +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.metrics_records:1 of +msgid "Dictionary holding MetricsRecord instances." msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +#: flwr.common.RecordSet.configs_records:1::1 of +msgid ":py:obj:`parameters_records `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`unregister `\\ " -"\\(client\\)" +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.parameters_records:1 of +msgid "Dictionary holding ParametersRecord instances." msgstr "" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of -msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\[\\, timeout\\]\\)" +#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 +msgid "ServerMessage" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of -msgid "" -"Blocks until the requested number of clients is available or until a " -"timeout is reached. Current timeout default: 1 day." +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid ":py:obj:`evaluate_ins `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of -msgid "The number of clients to wait for." +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid ":py:obj:`fit_ins `\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of -msgid "The time in seconds to wait for, defaults to 86400 (24h)." +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid "" +":py:obj:`get_parameters_ins " +"`\\" msgstr "" -#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of -msgid "**success**" +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 +msgid "" +":py:obj:`get_properties_ins " +"`\\" msgstr "" -#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 -msgid "run\\_driver\\_api" +#: ../../source/ref-api/flwr.common.Status.rst:2 +msgid "Status" msgstr "" -#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 -msgid "run\\_fleet\\_api" +#: ../../source/ref-api/flwr.common.Status.rst:29::1 +msgid ":py:obj:`code `\\" msgstr "" -#: ../../source/ref-api/flwr.server.run_server_app.rst:2 -msgid "run\\_server\\_app" +#: ../../source/ref-api/flwr.common.Status.rst:29::1 +msgid ":py:obj:`message `\\" msgstr "" -#: ../../source/ref-api/flwr.server.run_superlink.rst:2 -msgid "run\\_superlink" +#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 +msgid "array\\_from\\_numpy" msgstr "" -#: ../../source/ref-api/flwr.server.start_driver.rst:2 -msgid "start\\_driver" +#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 +msgid "bytes\\_to\\_ndarray" msgstr "" -#: flwr.server.compat.app.start_driver:3 of -msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:8080\"`." +#: ../../source/ref-api/flwr.common.configure.rst:2 +msgid "configure" msgstr "" -#: flwr.server.compat.app.start_driver:6 of -msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_driver` will create one." +#: ../../source/ref-api/flwr.common.event.rst:2 +msgid "event" msgstr "" -#: flwr.server.app.start_server:9 flwr.server.compat.app.start_driver:10 -#: flwr.simulation.app.start_simulation:28 of -msgid "" -"Currently supported values are `num_rounds` (int, default: 1) and " -"`round_timeout` in seconds (float, default: None)." +#: ../../source/ref-api/flwr.common.log.rst:2 +msgid "log" msgstr "" -#: flwr.server.app.start_server:12 flwr.server.compat.app.start_driver:13 of +#: logging.Logger.log:3 of msgid "" -"An implementation of the abstract base class " -"`flwr.server.strategy.Strategy`. If no strategy is provided, then " -"`start_server` will use `flwr.server.strategy.FedAvg`." +"To pass exception information, use the keyword argument exc_info with a " +"true value, e.g." msgstr "" -#: flwr.server.compat.app.start_driver:17 of -msgid "" -"An implementation of the class `flwr.server.ClientManager`. If no " -"implementation is provided, then `start_driver` will use " -"`flwr.server.SimpleClientManager`." +#: logging.Logger.log:6 of +#, python-format +msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" msgstr "" -#: flwr.server.compat.app.start_driver:25 of -msgid "The Driver object to use." +#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 +msgid "ndarray\\_to\\_bytes" msgstr "" -#: flwr.server.app.start_server:37 flwr.server.compat.app.start_driver:28 of -msgid "**hist** -- Object containing training and evaluation metrics." +#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 +msgid "ndarrays\\_to\\_parameters" msgstr "" -#: flwr.server.compat.app.start_driver:33 of -msgid "Starting a driver that connects to an insecure server:" +#: ../../source/ref-api/flwr.common.now.rst:2 +msgid "now" msgstr "" -#: flwr.server.compat.app.start_driver:37 of -msgid "Starting a driver that connects to an SSL-enabled server:" +#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 +msgid "parameters\\_to\\_ndarrays" msgstr "" -#: ../../source/ref-api/flwr.server.start_server.rst:2 -msgid "start\\_server" +#: ../../source/ref-api/flwr.server.rst:2 +msgid "server" msgstr "" -#: flwr.server.app.start_server:3 of -msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_driver_api `\\ \\(\\)" msgstr "" -#: flwr.server.app.start_server:5 of -msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_server` will create one." -msgstr "" - -#: flwr.server.app.start_server:16 of -msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_server` will use " -"`flwr.server.client_manager.SimpleClientManager`." +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_driver_api:1 of +msgid "Run Flower server (Driver API)." msgstr "" -#: flwr.server.app.start_server:21 of -msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" clients. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower clients need to be started with the same value (see " -"`flwr.client.start_client`), otherwise clients will not know about the " -"increased limit and block larger messages." +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_fleet_api `\\ \\(\\)" msgstr "" -#: flwr.server.app.start_server:42 of -msgid "Starting an insecure server:" +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_fleet_api:1 of +msgid "Run Flower server (Fleet API)." msgstr "" -#: flwr.server.app.start_server:46 of -msgid "Starting an SSL-enabled server:" +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_server_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:2 -msgid "strategy" +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.run_serverapp.run_server_app:1 of +msgid "Run Flower server app." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +#: ../../source/ref-api/flwr.server.rst:26::1 +msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.bulyan.Bulyan:1 of -msgid "Bulyan strategy." +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_superlink:1 of +msgid "Run Flower SuperLink (Driver API and Fleet API)." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.rst:26::1 msgid "" -":py:obj:`DPFedAvgAdaptive `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\)" +":py:obj:`start_server `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of -msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.start_server:1 of +msgid "Start a Flower server using the gRPC transport layer." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DPFedAvgFixed `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of -msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.ClientManager:1 of +msgid "Abstract base class for managing Flower clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`Driver `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 -#: of -msgid "Strategy wrapper for central DP with client-side adaptive clipping." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.driver.driver.Driver:1 of +msgid "Abstract base Driver class for the Driver API." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`History `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 -#: of -msgid "Strategy wrapper for central DP with server-side adaptive clipping." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.history.History:1 of +msgid "History class for training and/or evaluation metrics collection." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`LegacyContext `\\ \\(state\\[\\, " +"config\\, strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 -#: of -msgid "Strategy wrapper for central DP with client-side fixed clipping." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.compat.legacy_context.LegacyContext:1 of +msgid "Legacy Context." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping " -"`\\ " -"\\(...\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 -#: of -msgid "Strategy wrapper for central DP with server-side fixed clipping." +":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " +"strategy\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " +"strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of -msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_app.ServerApp:1 of +msgid "Flower ServerApp." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -":py:obj:`FedAdam `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," +" round\\_timeout\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadam.FedAdam:1 of -msgid "FedAdam - Adaptive Federated Optimization using Adam." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_config.ServerConfig:1 of +msgid "Flower server config." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +#: ../../source/ref-api/flwr.server.rst:40::1 +msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavg.FedAvg:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of -msgid "Federated Averaging strategy." +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.SimpleClientManager:1 of +msgid "Provides a pool of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAvgAndroid `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +#: ../../source/ref-api/flwr.server.rst:59::1 +msgid ":py:obj:`flwr.server.strategy `\\" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.strategy:1 of +msgid "Contains the strategy abstraction and different implementations." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavgm.FedAvgM:1 of -msgid "Federated Averaging with Momentum strategy." +#: ../../source/ref-api/flwr.server.rst:59::1 +msgid ":py:obj:`flwr.server.workflow `\\" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedMedian `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.workflow:1 of +msgid "Workflows." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedmedian.FedMedian:1 of -msgid "Configurable FedMedian strategy implementation." +#: ../../source/ref-api/flwr.server.ClientManager.rst:2 +msgid "ClientManager" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedOpt `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`all `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedopt.FedOpt:1 of -msgid "Federated Optim strategy." +#: flwr.server.client_manager.ClientManager.all:1 +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.all:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "Return all available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedProx `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`num_available `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedprox.FedProx:1 of -msgid "Federated Optimization strategy." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.num_available:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.num_available:1 of +msgid "Return the number of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedTrimmedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`register `\\ \\(client\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of -msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.register:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.register:1 of +msgid "Register Flower ClientProxy instance." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`FedXgbBagging `\\ " -"\\(\\[evaluate\\_function\\]\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of -msgid "Configurable FedXgbBagging strategy implementation." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.sample:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.sample:1 of +msgid "Sample a number of Flower ClientProxy instances." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedXgbCyclic `\\ " -"\\(\\*\\*kwargs\\)" +#: flwr.server.client_manager.ClientManager.all:1::1 of +msgid ":py:obj:`unregister `\\ \\(client\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of -msgid "Configurable FedXgbCyclic strategy implementation." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.unregister:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.unregister:1 of +msgid "Unregister Flower ClientProxy instance." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " -"\\*\\*kwargs\\)" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\, timeout\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of -msgid "Configurable FedXgbNnAvg strategy implementation." +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.wait_for:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of +msgid "Wait until at least `num_clients` are available." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FedYogi `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.num_available:3 +#: flwr.server.client_manager.SimpleClientManager.num_available:3 of +msgid "**num_available** -- The number of currently available clients." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedyogi.FedYogi:1 of -msgid "FedYogi [Reddi et al., 2020] strategy." +#: flwr.server.client_manager.ClientManager.register:6 +#: flwr.server.client_manager.SimpleClientManager.register:6 of +msgid "" +"**success** -- Indicating if registration was successful. False if " +"ClientProxy is already registered or can not be registered for any " +"reason." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`FaultTolerantFedAvg " -"`\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +#: flwr.server.client_manager.ClientManager.unregister:3 +#: flwr.server.client_manager.SimpleClientManager.unregister:3 of +msgid "This method is idempotent." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of -msgid "Configurable fault-tolerant FedAvg strategy implementation." +#: ../../source/ref-api/flwr.server.Driver.rst:2 +msgid "Driver" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`create_message `\\ " +"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.krum.Krum:1 of -msgid "Krum [Blanchard et al., 2017] strategy." +#: flwr.server.driver.driver.Driver.create_message:1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid "Create a new message with specified parameters." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " -"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid ":py:obj:`get_node_ids `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.qfedavg.QFedAvg:1 of -msgid "Configurable QFedAvg strategy implementation." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.get_node_ids:1 of +msgid "Get node IDs." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -msgid ":py:obj:`Strategy `\\ \\(\\)" +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid "" +":py:obj:`pull_messages `\\ " +"\\(message\\_ids\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.strategy.Strategy:1 of -msgid "Abstract base class for server strategy implementations." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.pull_messages:1 of +msgid "Pull messages based on message IDs." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Bulyan.rst:2 -msgid "Bulyan" +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid "" +":py:obj:`push_messages `\\ " +"\\(messages\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 -#: flwr.server.strategy.fedavgm.FedAvgM:1 -#: flwr.server.strategy.fedmedian.FedMedian:1 -#: flwr.server.strategy.fedopt.FedOpt:1 flwr.server.strategy.fedprox.FedProx:1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 -#: flwr.server.strategy.krum.Krum:1 flwr.server.strategy.qfedavg.QFedAvg:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.fedavg.FedAvg`" +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.push_messages:1 of +msgid "Push messages to specified node IDs." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:3 of -msgid "Implementation based on https://arxiv.org/abs/1802.07927." +#: flwr.server.driver.driver.Driver.create_message:1::1 of +msgid "" +":py:obj:`send_and_receive `\\ " +"\\(messages\\, \\*\\[\\, timeout\\]\\)" msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:5 -#: flwr.server.strategy.fedadagrad.FedAdagrad:5 -#: flwr.server.strategy.fedadam.FedAdam:5 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:5 -#: flwr.server.strategy.fedavgm.FedAvgM:5 flwr.server.strategy.fedopt.FedOpt:5 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:5 -#: flwr.server.strategy.fedyogi.FedYogi:5 flwr.server.strategy.krum.Krum:5 of -msgid "Fraction of clients used during training. Defaults to 1.0." +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.send_and_receive:1 of +msgid "Push messages to specified node IDs and pull the reply messages." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:7 -#: flwr.server.strategy.fedadagrad.FedAdagrad:7 -#: flwr.server.strategy.fedadam.FedAdam:7 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:7 -#: flwr.server.strategy.fedavgm.FedAvgM:7 flwr.server.strategy.fedopt.FedOpt:7 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:7 -#: flwr.server.strategy.fedyogi.FedYogi:7 flwr.server.strategy.krum.Krum:7 of -msgid "Fraction of clients used during validation. Defaults to 1.0." +#: flwr.server.driver.driver.Driver.create_message:3 of +msgid "" +"This method constructs a new `Message` with given content and metadata. " +"The `run_id` and `src_node_id` will be set automatically." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:9 -#: flwr.server.strategy.fedadagrad.FedAdagrad:9 -#: flwr.server.strategy.fedadam.FedAdam:9 flwr.server.strategy.fedavg.FedAvg:13 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:9 -#: flwr.server.strategy.fedavgm.FedAvgM:9 flwr.server.strategy.fedopt.FedOpt:9 -#: flwr.server.strategy.fedprox.FedProx:45 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:9 -#: flwr.server.strategy.fedyogi.FedYogi:9 flwr.server.strategy.krum.Krum:9 of -msgid "Minimum number of clients used during training. Defaults to 2." +#: flwr.server.driver.driver.Driver.create_message:6 of +msgid "" +"The content for the new message. This holds records that are to be sent " +"to the destination node." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:11 -#: flwr.server.strategy.fedadagrad.FedAdagrad:11 -#: flwr.server.strategy.fedadam.FedAdam:11 -#: flwr.server.strategy.fedavg.FedAvg:15 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:11 -#: flwr.server.strategy.fedavgm.FedAvgM:11 -#: flwr.server.strategy.fedopt.FedOpt:11 -#: flwr.server.strategy.fedprox.FedProx:47 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:11 -#: flwr.server.strategy.fedyogi.FedYogi:11 flwr.server.strategy.krum.Krum:11 of -msgid "Minimum number of clients used during validation. Defaults to 2." +#: flwr.server.driver.driver.Driver.create_message:9 of +msgid "" +"The type of the message, defining the action to be executed on the " +"receiving end." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:13 -#: flwr.server.strategy.fedadagrad.FedAdagrad:13 -#: flwr.server.strategy.fedadam.FedAdam:13 -#: flwr.server.strategy.fedavg.FedAvg:17 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:13 -#: flwr.server.strategy.fedavgm.FedAvgM:13 -#: flwr.server.strategy.fedopt.FedOpt:13 -#: flwr.server.strategy.fedprox.FedProx:49 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:13 -#: flwr.server.strategy.fedyogi.FedYogi:13 flwr.server.strategy.krum.Krum:13 of -msgid "Minimum number of total clients in the system. Defaults to 2." +#: flwr.server.driver.driver.Driver.create_message:12 of +msgid "The ID of the destination node to which the message is being sent." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:15 flwr.server.strategy.krum.Krum:15 of -msgid "Number of malicious clients in the system. Defaults to 0." +#: flwr.server.driver.driver.Driver.create_message:14 of +msgid "" +"The ID of the group to which this message is associated. In some " +"settings, this is used as the FL round." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:17 -#: flwr.server.strategy.fedadagrad.FedAdagrad:15 -#: flwr.server.strategy.fedadam.FedAdam:15 -#: flwr.server.strategy.fedavg.FedAvg:19 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:15 -#: flwr.server.strategy.fedavgm.FedAvgM:15 -#: flwr.server.strategy.fedopt.FedOpt:15 -#: flwr.server.strategy.fedprox.FedProx:51 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:15 -#: flwr.server.strategy.fedyogi.FedYogi:17 -#: flwr.server.strategy.fedyogi.FedYogi:18 -#: flwr.server.strategy.fedyogi.FedYogi:19 flwr.server.strategy.krum.Krum:20 of -msgid "Optional function used for validation. Defaults to None." +#: flwr.server.driver.driver.Driver.create_message:17 of +msgid "" +"Time-to-live for the round trip of this message, i.e., the time from " +"sending this message to receiving a reply. It specifies in seconds the " +"duration for which the message and its potential reply are considered " +"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " +"used." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:19 -#: flwr.server.strategy.fedadagrad.FedAdagrad:17 -#: flwr.server.strategy.fedadam.FedAdam:17 -#: flwr.server.strategy.fedavg.FedAvg:21 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:17 -#: flwr.server.strategy.fedavgm.FedAvgM:17 -#: flwr.server.strategy.fedopt.FedOpt:17 -#: flwr.server.strategy.fedprox.FedProx:53 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:17 -#: flwr.server.strategy.fedyogi.FedYogi:20 flwr.server.strategy.krum.Krum:22 of -msgid "Function used to configure training. Defaults to None." +#: flwr.server.driver.driver.Driver.create_message:23 of +msgid "" +"**message** -- A new `Message` instance with the specified content and " +"metadata." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:21 -#: flwr.server.strategy.fedadagrad.FedAdagrad:19 -#: flwr.server.strategy.fedadam.FedAdam:19 -#: flwr.server.strategy.fedavg.FedAvg:23 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:19 -#: flwr.server.strategy.fedavgm.FedAvgM:19 -#: flwr.server.strategy.fedopt.FedOpt:19 -#: flwr.server.strategy.fedprox.FedProx:55 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:19 -#: flwr.server.strategy.fedyogi.FedYogi:22 flwr.server.strategy.krum.Krum:24 of -msgid "Function used to configure validation. Defaults to None." +#: flwr.server.driver.driver.Driver.pull_messages:3 of +msgid "" +"This method is used to collect messages from the SuperLink that " +"correspond to a set of given message IDs." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:23 -#: flwr.server.strategy.fedadagrad.FedAdagrad:25 -#: flwr.server.strategy.fedadam.FedAdam:21 -#: flwr.server.strategy.fedavg.FedAvg:25 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:21 -#: flwr.server.strategy.fedavgm.FedAvgM:21 -#: flwr.server.strategy.fedopt.FedOpt:21 -#: flwr.server.strategy.fedprox.FedProx:57 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:21 -#: flwr.server.strategy.fedyogi.FedYogi:24 flwr.server.strategy.krum.Krum:26 of -msgid "Whether or not accept rounds containing failures. Defaults to True." +#: flwr.server.driver.driver.Driver.pull_messages:6 of +msgid "An iterable of message IDs for which reply messages are to be retrieved." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:25 -#: flwr.server.strategy.fedadagrad.FedAdagrad:27 -#: flwr.server.strategy.fedadam.FedAdam:23 -#: flwr.server.strategy.fedavg.FedAvg:27 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:24 -#: flwr.server.strategy.fedavgm.FedAvgM:23 -#: flwr.server.strategy.fedopt.FedOpt:23 -#: flwr.server.strategy.fedprox.FedProx:59 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:23 -#: flwr.server.strategy.fedyogi.FedYogi:26 flwr.server.strategy.krum.Krum:28 of -msgid "Initial global model parameters." +#: flwr.server.driver.driver.Driver.pull_messages:9 of +msgid "**messages** -- An iterable of messages received." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:27 of +#: flwr.server.driver.driver.Driver.push_messages:3 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of " -"the Bulyan (e.g., Krum)" +"This method takes an iterable of messages and sends each message to the " +"node specified in `dst_node_id`." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan:29 of -msgid "arguments to the first_aggregation rule" +#: flwr.server.driver.driver.Driver.push_messages:6 +#: flwr.server.driver.driver.Driver.send_and_receive:7 of +msgid "An iterable of messages to be sent." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.driver.driver.Driver.push_messages:9 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +"**message_ids** -- An iterable of IDs for the messages that were sent, " +"which can be used to pull replies." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -msgid "Aggregate evaluation losses using weighted average." +#: flwr.server.driver.driver.Driver.send_and_receive:3 of +msgid "" +"This method sends a list of messages to their destination node IDs and " +"then waits for the replies. It continues to pull replies until either all" +" replies are received or the specified timeout duration is exceeded." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.driver.driver.Driver.send_and_receive:9 of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +"The timeout duration in seconds. If specified, the method will wait for " +"replies for this duration. If `None`, there is no time limit and the " +"method will wait until replies for all messages are received." msgstr "" -#: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "Aggregate fit results using Bulyan." +#: flwr.server.driver.driver.Driver.send_and_receive:14 of +msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +msgid "Notes" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_evaluate:1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.configure_evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.configure_evaluate:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:1 of -msgid "Configure the next round of evaluation." +#: flwr.server.driver.driver.Driver.send_and_receive:19 of +msgid "" +"This method uses `push_messages` to send the messages and `pull_messages`" +" to collect the replies. If `timeout` is set, the method may not return " +"replies for all sent messages. A message remains valid until its TTL, " +"which is not affected by `timeout`." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.History.rst:2 +msgid "History" +msgstr "" + +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`add_loss_centralized " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_fit:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_fit:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_fit:1 -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.configure_fit:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.configure_fit:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_fit:1 -#: flwr.server.strategy.fedprox.FedProx.configure_fit:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_fit:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.configure_fit:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.configure_fit:1 of -msgid "Configure the next round of training." +#: flwr.server.history.History.add_loss_centralized:1 +#: flwr.server.history.History.add_loss_centralized:1::1 of +msgid "Add one loss entry (from centralized evaluation)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`add_loss_distributed " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.evaluate:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.evaluate:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.evaluate:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -msgid "Evaluate model parameters using an evaluation function." +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_loss_distributed:1 of +msgid "Add one loss entry (from distributed evaluation)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`add_metrics_centralized " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.initialize_parameters:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.initialize_parameters:1 -#: flwr.server.strategy.fedavgm.FedAvgM.initialize_parameters:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -msgid "Initialize global model parameters." +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_centralized:1 of +msgid "Add metrics entries (from centralized evaluation)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`add_metrics_distributed " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.num_evaluation_clients:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_evaluation_clients:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.num_evaluation_clients:1 of -msgid "Use a fraction of available clients for evaluation." +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed:1 of +msgid "Add metrics entries (from distributed evaluation)." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`add_metrics_distributed_fit " +"`\\ \\(server\\_round\\," +" ...\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.num_fit_clients:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_fit_clients:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.num_fit_clients:1 of -msgid "Return the sample size and the required number of available clients." +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed_fit:1 of +msgid "Add metrics entries (from distributed fit)." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DPFedAvgAdaptive.rst:2 -msgid "DPFedAvgAdaptive" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 +msgid "LegacyContext" msgstr "" -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" +#: flwr.server.compat.legacy_context.LegacyContext:1 of +msgid "Bases: :py:class:`~flwr.common.context.Context`" msgstr "" -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:3 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:3 of -msgid "This class is deprecated and will be removed in a future release." +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`config `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`strategy `\\" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "Aggregate evaluation losses using the given strategy." +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`client_manager `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`history `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "Aggregate training results as in DPFedAvgFixed and update clip norms." +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +msgid ":py:obj:`state `\\" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.Server.rst:2 +msgid "Server" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of -msgid "Configure the next round of evaluation using the specified strategy." +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`client_manager `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.server.Server.client_manager:1 +#: flwr.server.server.Server.client_manager:1::1 of +msgid "Return ClientManager." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`disconnect_all_clients " +"`\\ \\(timeout\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.evaluate:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "Evaluate model parameters using an evaluation function from the strategy." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.disconnect_all_clients:1 of +msgid "Send shutdown signal to all clients." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`evaluate_round `\\ " +"\\(server\\_round\\, timeout\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.initialize_parameters:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.initialize_parameters:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.initialize_parameters:1 of -msgid "Initialize global model parameters using given strategy." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.evaluate_round:1 of +msgid "Validate current global model on a number of clients." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:3 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:6 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:3 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:3 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:3 -#: flwr.server.strategy.strategy.Strategy.configure_fit:3 -#: flwr.server.strategy.strategy.Strategy.evaluate:6 of -msgid "The current round of federated learning." +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:7 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:10 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:7 -#: flwr.server.strategy.strategy.Strategy.configure_fit:7 -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:3 of -msgid "The client manager which holds all currently connected clients." +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit:1 of +msgid "Run federated averaging for a number of rounds." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:10 -#: flwr.server.strategy.strategy.Strategy.configure_evaluate:10 of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -"**evaluate_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated evaluation." -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 -msgid "DPFedAvgFixed" +":py:obj:`fit_round `\\ \\(server\\_round\\," +" timeout\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 -#: flwr.server.strategy.fedavg.FedAvg:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit_round:1 of +msgid "Perform a single round of federated averaging." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of +#: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`set_max_workers `\\ " +"\\(max\\_workers\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_max_workers:1 of +msgid "Set the max_workers used by ThreadPoolExecutor." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_fit:1 of -msgid "Aggregate training results using unweighted aggregation." +#: flwr.server.server.Server.client_manager:1::1 of +msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_strategy:1 of +msgid "Replace server strategy." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.ServerApp.rst:2 +msgid "ServerApp" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of -msgid "" -"Configure the next round of training incorporating Differential Privacy " -"(DP)." +#: flwr.server.server_app.ServerApp:5 of +msgid "Use the `ServerApp` with an existing `Strategy`:" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +#: flwr.server.server_app.ServerApp:15 of +msgid "Use the `ServerApp` with a custom main function:" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.server_app.ServerApp.main:1::1 of +msgid ":py:obj:`main `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of -msgid "" -"Configuration of the next training round includes information related to " -"DP, such as clip norm and noise stddev." +#: flwr.server.server_app.ServerApp.main:1 +#: flwr.server.server_app.ServerApp.main:1::1 of +msgid "Return a decorator that registers the main fn with the server app." msgstr "" -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 -#: flwr.server.strategy.strategy.Strategy.configure_fit:10 of -msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `FitIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated learning." +#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 +msgid "ServerConfig" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 -msgid "DifferentialPrivacyClientSideAdaptiveClipping" +#: flwr.server.server_config.ServerConfig:3 of +msgid "" +"All attributes have default values which allows users to configure just " +"the ones they care about." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:3 -#: of -msgid "Use `adaptiveclipping_mod` modifier at the client side." +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +msgid ":py:obj:`num_rounds `\\" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:5 -#: of -msgid "" -"In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " -"performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " -"happen on the client-side, usually by using the built-in " -"`adaptiveclipping_mod`." +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +msgid ":py:obj:`round_timeout `\\" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:10 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:3 -#: of -msgid "The strategy to which DP functionalities will be added by this wrapper." +#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 +msgid "SimpleClientManager" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:12 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:5 -#: of -msgid "The noise multiplier for the Gaussian mechanism for model updates." +#: flwr.server.client_manager.SimpleClientManager:1 of +msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:14 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:7 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:17 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:10 -#: of -msgid "The number of clients that are sampled on each round." +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid ":py:obj:`all `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:16 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:9 -#: of +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -"The initial value of clipping norm. Defaults to 0.1. Andrew et al. " -"recommends to set to 0.1." +":py:obj:`num_available `\\" +" \\(\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 -#: of -msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`register `\\ " +"\\(client\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 -#: of +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. " -"Andrew et al. recommends to set to 0.2." +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 -#: of +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -"The stddev of the noise added to the count of updates currently below the" -" estimate. Andrew et al. recommends to set to `expected_num_records/20`" +":py:obj:`unregister `\\ " +"\\(client\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:22 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:15 -#: of -msgid "Create a strategy:" +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +msgid "" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\[\\, timeout\\]\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 -#: of +#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of msgid "" -"Wrap the strategy with the " -"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" +"Blocks until the requested number of clients is available or until a " +"timeout is reached. Current timeout default: 1 day." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 -#: of -msgid "On the client, add the `adaptiveclipping_mod` to the client-side mods:" +#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of +msgid "The number of clients to wait for." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of +msgid "The time in seconds to wait for, defaults to 86400 (24h)." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of +msgid "**success**" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_fit:1 -#: of -msgid "Aggregate training results and update clip norms." +#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 +msgid "run\\_driver\\_api" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" -msgstr "" - -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 +msgid "run\\_fleet\\_api" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +#: ../../source/ref-api/flwr.server.run_server_app.rst:2 +msgid "run\\_server\\_app" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +#: ../../source/ref-api/flwr.server.run_superlink.rst:2 +msgid "run\\_superlink" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 -msgid "DifferentialPrivacyClientSideFixedClipping" +#: ../../source/ref-api/flwr.server.start_server.rst:2 +msgid "start\\_server" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:3 -#: of -msgid "Use `fixedclipping_mod` modifier at the client side." +#: flwr.server.app.start_server:3 of +msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:5 -#: of +#: flwr.server.app.start_server:5 of msgid "" -"In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " -"performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `fixedclipping_mod`." +"A server implementation, either `flwr.server.Server` or a subclass " +"thereof. If no instance is provided, then `start_server` will create one." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 -#: of +#: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A " -"value of 1.0 or higher is recommended for strong privacy." +"Currently supported values are `num_rounds` (int, default: 1) and " +"`round_timeout` in seconds (float, default: None)." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -msgid "The value of the clipping norm." +#: flwr.server.app.start_server:12 of +msgid "" +"An implementation of the abstract base class " +"`flwr.server.strategy.Strategy`. If no strategy is provided, then " +"`start_server` will use `flwr.server.strategy.FedAvg`." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 -#: of +#: flwr.server.app.start_server:16 of msgid "" -"Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` " -"wrapper:" +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_server` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:32 -#: of -msgid "On the client, add the `fixedclipping_mod` to the client-side mods:" +#: flwr.server.app.start_server:21 of +msgid "" +"The maximum length of gRPC messages that can be exchanged with the Flower" +" clients. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower clients need to be started with the same value (see " +"`flwr.client.start_client`), otherwise clients will not know about the " +"increased limit and block larger messages." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: flwr.server.app.start_server:28 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order: * CA certificate. * " +"server certificate. * server private key." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: flwr.server.app.start_server:28 of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order:" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 -#: of -msgid "Add noise to the aggregated parameters." +#: flwr.server.app.start_server:32 of +msgid "CA certificate." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.app.start_server:33 of +msgid "server certificate." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.app.start_server:34 of +msgid "server private key." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +#: flwr.server.app.start_server:37 of +msgid "**hist** -- Object containing training and evaluation metrics." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +#: flwr.server.app.start_server:42 of +msgid "Starting an insecure server:" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 -msgid "DifferentialPrivacyServerSideAdaptiveClipping" +#: flwr.server.app.start_server:46 of +msgid "Starting an SSL-enabled server:" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 -#: of -msgid "" -"The standard deviation of the noise added to the count of updates below " -"the estimate. Andrew et al. recommends to set to " -"`expected_num_records/20`" +#: ../../source/ref-api/flwr.server.strategy.rst:2 +msgid "strategy" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping " -"wrapper" +":py:obj:`Bulyan `\\ \\(\\*\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.bulyan.Bulyan:1 of +msgid "Bulyan strategy." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`DPFedAvgAdaptive `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`DPFedAvgFixed `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of +msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." msgstr "" -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 -msgid "DifferentialPrivacyServerSideFixedClipping" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 +#: of +msgid "Strategy wrapper for central DP with client-side adaptive clipping." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " -"wrapper" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 #: of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +msgid "Strategy wrapper for central DP with server-side adaptive clipping." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 #: of -msgid "Compute the updates, clip, and pass them for aggregation." +msgid "Strategy wrapper for central DP with client-side fixed clipping." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`DifferentialPrivacyServerSideFixedClipping " +"`\\ " +"\\(...\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 #: of -msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +msgid "Strategy wrapper for central DP with server-side fixed clipping." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of +msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 -#: of -msgid "Afterward, add noise to the aggregated parameters." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`FedAdam `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FaultTolerantFedAvg.rst:2 -msgid "FaultTolerantFedAvg" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadam.FedAdam:1 of +msgid "FedAdam - Adaptive Federated Optimization using Adam." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavg.FedAvg:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +msgid "Federated Averaging strategy." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 -#: flwr.server.strategy.fedadagrad.FedAdagrad.aggregate_fit:1 -#: flwr.server.strategy.fedadam.FedAdam.aggregate_fit:1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg.FedAvg.aggregate_fit:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_fit:1 -#: flwr.server.strategy.fedavgm.FedAvgM.aggregate_fit:1 -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.aggregate_fit:1 -#: flwr.server.strategy.fedyogi.FedYogi.aggregate_fit:1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_fit:1 of -msgid "Aggregate fit results using weighted average." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`FedAvgAndroid `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavgm.FedAvgM:1 of +msgid "Federated Averaging with Momentum strategy." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`FedMedian `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedmedian.FedMedian:1 of +msgid "Configurable FedMedian strategy implementation." msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 -#: of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedopt.FedOpt:1 of +msgid "Federated Optim strategy." +msgstr "" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`FedProx `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:839 -msgid "FedAdagrad" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedprox.FedProx:1 of +msgid "Federated Optimization strategy." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:1 -#: flwr.server.strategy.fedadam.FedAdam:1 -#: flwr.server.strategy.fedyogi.FedYogi:1 of -msgid "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`FedTrimmedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:3 -#: flwr.server.strategy.fedadam.FedAdam:3 flwr.server.strategy.fedopt.FedOpt:3 -#: flwr.server.strategy.fedyogi.FedYogi:3 of -msgid "Implementation based on https://arxiv.org/abs/2003.00295v5" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of +msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:21 -#: flwr.server.strategy.fedadagrad.FedAdagrad:23 -#: flwr.server.strategy.fedadam.FedAdam:25 -#: flwr.server.strategy.fedadam.FedAdam:27 -#: flwr.server.strategy.fedavg.FedAvg:29 flwr.server.strategy.fedavg.FedAvg:31 -#: flwr.server.strategy.fedopt.FedOpt:25 flwr.server.strategy.fedopt.FedOpt:27 -#: flwr.server.strategy.fedprox.FedProx:61 -#: flwr.server.strategy.fedprox.FedProx:63 -#: flwr.server.strategy.fedyogi.FedYogi:28 -#: flwr.server.strategy.fedyogi.FedYogi:30 of -msgid "Metrics aggregation function, optional." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`FedXgbBagging `\\ " +"\\(\\[evaluate\\_function\\]\\)" msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:29 -#: flwr.server.strategy.fedadam.FedAdam:29 -#: flwr.server.strategy.fedopt.FedOpt:29 of -msgid "Server-side learning rate. Defaults to 1e-1." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of +msgid "Configurable FedXgbBagging strategy implementation." msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:31 -#: flwr.server.strategy.fedadam.FedAdam:31 -#: flwr.server.strategy.fedopt.FedOpt:31 of -msgid "Client-side learning rate. Defaults to 1e-1." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`FedXgbCyclic `\\ " +"\\(\\*\\*kwargs\\)" msgstr "" -#: flwr.server.strategy.fedadagrad.FedAdagrad:33 -#: flwr.server.strategy.fedadam.FedAdam:37 -#: flwr.server.strategy.fedopt.FedOpt:37 of -msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-9." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of +msgid "Configurable FedXgbCyclic strategy implementation." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_fit `\\" -" \\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 of +msgid "Configurable FedXgbNnAvg strategy implementation." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`FedYogi `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedyogi.FedYogi:1 of +msgid "FedYogi [Reddi et al., 2020] strategy." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`FaultTolerantFedAvg " +"`\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of +msgid "Configurable fault-tolerant FedAvg strategy implementation." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.krum.Krum:1 of +msgid "Krum [Blanchard et al., 2017] strategy." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 -msgid "FedAdam" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid "" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " +"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" -#: flwr.server.strategy.fedadam.FedAdam:33 -#: flwr.server.strategy.fedyogi.FedYogi:36 of -msgid "Momentum parameter. Defaults to 0.9." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.qfedavg.QFedAvg:1 of +msgid "Configurable QFedAvg strategy implementation." msgstr "" -#: flwr.server.strategy.fedadam.FedAdam:35 -#: flwr.server.strategy.fedyogi.FedYogi:38 of -msgid "Second moment parameter. Defaults to 0.99." +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +msgid ":py:obj:`Strategy `\\ \\(\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.strategy.Strategy:1 of +msgid "Abstract base class for server strategy implementations." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: ../../source/ref-api/flwr.server.strategy.Bulyan.rst:2 +msgid "Bulyan" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 +#: flwr.server.strategy.fedavgm.FedAvgM:1 +#: flwr.server.strategy.fedmedian.FedMedian:1 +#: flwr.server.strategy.fedopt.FedOpt:1 flwr.server.strategy.fedprox.FedProx:1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:1 +#: flwr.server.strategy.krum.Krum:1 flwr.server.strategy.qfedavg.QFedAvg:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.fedavg.FedAvg`" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:3 of +msgid "Implementation based on https://arxiv.org/abs/1802.07927." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +#: flwr.server.strategy.bulyan.Bulyan:5 +#: flwr.server.strategy.fedadagrad.FedAdagrad:5 +#: flwr.server.strategy.fedadam.FedAdam:5 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:5 +#: flwr.server.strategy.fedavgm.FedAvgM:5 flwr.server.strategy.fedopt.FedOpt:5 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:5 +#: flwr.server.strategy.fedyogi.FedYogi:5 flwr.server.strategy.krum.Krum:5 of +msgid "Fraction of clients used during training. Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.bulyan.Bulyan:7 +#: flwr.server.strategy.fedadagrad.FedAdagrad:7 +#: flwr.server.strategy.fedadam.FedAdam:7 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:7 +#: flwr.server.strategy.fedavgm.FedAvgM:7 flwr.server.strategy.fedopt.FedOpt:7 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:7 +#: flwr.server.strategy.fedyogi.FedYogi:7 flwr.server.strategy.krum.Krum:7 of +msgid "Fraction of clients used during validation. Defaults to 1.0." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.bulyan.Bulyan:9 +#: flwr.server.strategy.fedadagrad.FedAdagrad:9 +#: flwr.server.strategy.fedadam.FedAdam:9 flwr.server.strategy.fedavg.FedAvg:13 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:9 +#: flwr.server.strategy.fedavgm.FedAvgM:9 flwr.server.strategy.fedopt.FedOpt:9 +#: flwr.server.strategy.fedprox.FedProx:45 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:9 +#: flwr.server.strategy.fedyogi.FedYogi:9 flwr.server.strategy.krum.Krum:9 of +msgid "Minimum number of clients used during training. Defaults to 2." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.bulyan.Bulyan:11 +#: flwr.server.strategy.fedadagrad.FedAdagrad:11 +#: flwr.server.strategy.fedadam.FedAdam:11 +#: flwr.server.strategy.fedavg.FedAvg:15 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:11 +#: flwr.server.strategy.fedavgm.FedAvgM:11 +#: flwr.server.strategy.fedopt.FedOpt:11 +#: flwr.server.strategy.fedprox.FedProx:47 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:11 +#: flwr.server.strategy.fedyogi.FedYogi:11 flwr.server.strategy.krum.Krum:11 of +msgid "Minimum number of clients used during validation. Defaults to 2." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 -msgid "FedAvg" +#: flwr.server.strategy.bulyan.Bulyan:13 +#: flwr.server.strategy.fedadagrad.FedAdagrad:13 +#: flwr.server.strategy.fedadam.FedAdam:13 +#: flwr.server.strategy.fedavg.FedAvg:17 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:13 +#: flwr.server.strategy.fedavgm.FedAvgM:13 +#: flwr.server.strategy.fedopt.FedOpt:13 +#: flwr.server.strategy.fedprox.FedProx:49 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:13 +#: flwr.server.strategy.fedyogi.FedYogi:13 flwr.server.strategy.krum.Krum:13 of +msgid "Minimum number of total clients in the system. Defaults to 2." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:3 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:3 of -msgid "Implementation based on https://arxiv.org/abs/1602.05629" +#: flwr.server.strategy.bulyan.Bulyan:15 flwr.server.strategy.krum.Krum:15 of +msgid "Number of malicious clients in the system. Defaults to 0." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:5 flwr.server.strategy.fedprox.FedProx:37 -#: of -msgid "" -"Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will " -"still be sampled. Defaults to 1.0." +#: flwr.server.strategy.bulyan.Bulyan:17 +#: flwr.server.strategy.fedadagrad.FedAdagrad:15 +#: flwr.server.strategy.fedadam.FedAdam:15 +#: flwr.server.strategy.fedavg.FedAvg:19 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:15 +#: flwr.server.strategy.fedavgm.FedAvgM:15 +#: flwr.server.strategy.fedopt.FedOpt:15 +#: flwr.server.strategy.fedprox.FedProx:51 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:15 +#: flwr.server.strategy.fedyogi.FedYogi:17 +#: flwr.server.strategy.fedyogi.FedYogi:18 +#: flwr.server.strategy.fedyogi.FedYogi:19 flwr.server.strategy.krum.Krum:20 of +msgid "Optional function used for validation. Defaults to None." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 -#: of -msgid "" -"Fraction of clients used during validation. In case " -"`min_evaluate_clients` is larger than `fraction_evaluate * " -"available_clients`, `min_evaluate_clients` will still be sampled. " -"Defaults to 1.0." +#: flwr.server.strategy.bulyan.Bulyan:19 +#: flwr.server.strategy.fedadagrad.FedAdagrad:17 +#: flwr.server.strategy.fedadam.FedAdam:17 +#: flwr.server.strategy.fedavg.FedAvg:21 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:17 +#: flwr.server.strategy.fedavgm.FedAvgM:17 +#: flwr.server.strategy.fedopt.FedOpt:17 +#: flwr.server.strategy.fedprox.FedProx:53 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:17 +#: flwr.server.strategy.fedyogi.FedYogi:20 flwr.server.strategy.krum.Krum:22 of +msgid "Function used to configure training. Defaults to None." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg:33 of -msgid "Enable (True) or disable (False) in-place aggregation of model updates." +#: flwr.server.strategy.bulyan.Bulyan:21 +#: flwr.server.strategy.fedadagrad.FedAdagrad:19 +#: flwr.server.strategy.fedadam.FedAdam:19 +#: flwr.server.strategy.fedavg.FedAvg:23 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:19 +#: flwr.server.strategy.fedavgm.FedAvgM:19 +#: flwr.server.strategy.fedopt.FedOpt:19 +#: flwr.server.strategy.fedprox.FedProx:55 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:19 +#: flwr.server.strategy.fedyogi.FedYogi:22 flwr.server.strategy.krum.Krum:24 of +msgid "Function used to configure validation. Defaults to None." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:23 +#: flwr.server.strategy.fedadagrad.FedAdagrad:25 +#: flwr.server.strategy.fedadam.FedAdam:21 +#: flwr.server.strategy.fedavg.FedAvg:25 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:21 +#: flwr.server.strategy.fedavgm.FedAvgM:21 +#: flwr.server.strategy.fedopt.FedOpt:21 +#: flwr.server.strategy.fedprox.FedProx:57 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:21 +#: flwr.server.strategy.fedyogi.FedYogi:24 flwr.server.strategy.krum.Krum:26 of +msgid "Whether or not accept rounds containing failures. Defaults to True." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: flwr.server.strategy.bulyan.Bulyan:25 +#: flwr.server.strategy.fedadagrad.FedAdagrad:27 +#: flwr.server.strategy.fedadam.FedAdam:23 +#: flwr.server.strategy.fedavg.FedAvg:27 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:24 +#: flwr.server.strategy.fedavgm.FedAvgM:23 +#: flwr.server.strategy.fedopt.FedOpt:23 +#: flwr.server.strategy.fedprox.FedProx:59 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:23 +#: flwr.server.strategy.fedyogi.FedYogi:26 flwr.server.strategy.krum.Krum:28 of +msgid "Initial global model parameters." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +"Byzantine resilient aggregation rule that is used as the first step of " +"the Bulyan (e.g., Krum)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.bulyan.Bulyan:29 of +msgid "arguments to the first_aggregation rule" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "Aggregate evaluation losses using weighted average." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" +#: flwr.server.strategy.bulyan.Bulyan.aggregate_fit:1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 -msgid "FedAvgAndroid" +msgid "Aggregate fit results using Bulyan." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_evaluate:1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.configure_evaluate:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" -msgstr "" - -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`bytes_to_ndarray " -"`\\ \\(tensor\\)" -msgstr "" - -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of -msgid "Deserialize NumPy array from bytes." +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.configure_evaluate:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:1 of +msgid "Configure the next round of evaluation." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_fit:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.configure_fit:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.configure_fit:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.configure_fit:1 +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.configure_fit:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.configure_fit:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.configure_fit:1 +#: flwr.server.strategy.fedprox.FedProx.configure_fit:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.configure_fit:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.configure_fit:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.configure_fit:1 of +msgid "Configure the next round of training." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.evaluate:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.evaluate:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.evaluate:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "Evaluate model parameters using an evaluation function." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`ndarray_to_bytes " -"`\\ \\(ndarray\\)" -msgstr "" - -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of -msgid "Serialize NumPy array to bytes." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.initialize_parameters:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`ndarrays_to_parameters " -"`\\ " -"\\(ndarrays\\)" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.initialize_parameters:1 +#: flwr.server.strategy.fedavgm.FedAvgM.initialize_parameters:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "Initialize global model parameters." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.num_evaluation_clients:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_evaluation_clients:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.num_evaluation_clients:1 of +msgid "Use a fraction of available clients for evaluation." msgstr "" -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`parameters_to_ndarrays " -"`\\ " -"\\(parameters\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.num_fit_clients:1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 -#: of -msgid "Convert parameters object to NumPy weights." -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedAvgM.rst:2 -msgid "FedAvgM" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.num_fit_clients:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.num_fit_clients:1 of +msgid "Return the sample size and the required number of available clients." msgstr "" -#: flwr.server.strategy.fedavgm.FedAvgM:3 of -msgid "Implementation based on https://arxiv.org/abs/1909.06335" +#: ../../source/ref-api/flwr.server.strategy.DPFedAvgAdaptive.rst:2 +msgid "DPFedAvgAdaptive" msgstr "" -#: flwr.server.strategy.fedavgm.FedAvgM:25 of -msgid "" -"Server-side learning rate used in server-side optimization. Defaults to " -"1.0." +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed`" msgstr "" -#: flwr.server.strategy.fedavgm.FedAvgM:28 of -msgid "Server-side momentum factor used for FedAvgM. Defaults to 0.0." +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:3 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:3 of +msgid "This class is deprecated and will be removed in a future release." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "Aggregate evaluation losses using the given strategy." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "Aggregate training results as in DPFedAvgFixed and update clip norms." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of +msgid "Configure the next round of evaluation using the specified strategy." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.evaluate:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.evaluate:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of +msgid "Evaluate model parameters using an evaluation function from the strategy." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.initialize_parameters:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.initialize_parameters:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.initialize_parameters:1 of +msgid "Initialize global model parameters using given strategy." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:3 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:6 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:3 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:3 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:3 +#: flwr.server.strategy.strategy.Strategy.configure_fit:3 +#: flwr.server.strategy.strategy.Strategy.evaluate:6 of +msgid "The current round of federated learning." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:7 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:10 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:7 +#: flwr.server.strategy.strategy.Strategy.configure_fit:7 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:3 of +msgid "The client manager which holds all currently connected clients." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:10 +#: flwr.server.strategy.strategy.Strategy.configure_evaluate:10 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"**evaluate_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `EvaluateIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated evaluation." msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 -msgid "FedMedian" +#: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 +msgid "DPFedAvgFixed" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 +#: flwr.server.strategy.fedavg.FedAvg:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of -msgid "Aggregate fit results using median." +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_fit:1 of +msgid "Aggregate training results using unweighted aggregation." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -":py:obj:`evaluate `\\ " +"Configure the next round of training incorporating Differential Privacy " +"(DP)." +msgstr "" + +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"Configuration of the next training round includes information related to " +"DP, such as clip norm and noise stddev." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 +#: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 -msgid "FedOpt" +"**fit_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `FitIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated learning." msgstr "" -#: flwr.server.strategy.fedopt.FedOpt:33 of -msgid "Momentum parameter. Defaults to 0.0." +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 +msgid "DifferentialPrivacyClientSideAdaptiveClipping" msgstr "" -#: flwr.server.strategy.fedopt.FedOpt:35 of -msgid "Second moment parameter. Defaults to 0.0." +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:3 +#: of +msgid "Use `adaptiveclipping_mod` modifier at the client side." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:5 +#: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +"In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " +"performs clipping on the server-side, " +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " +"happen on the client-side, usually by using the built-in " +"`adaptiveclipping_mod`." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:10 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:3 +#: of +msgid "The strategy to which DP functionalities will be added by this wrapper." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:12 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:5 +#: of +msgid "The noise multiplier for the Gaussian mechanism for model updates." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:14 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:7 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:17 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:10 +#: of +msgid "The number of clients that are sampled on each round." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:16 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:9 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +"The initial value of clipping norm. Defaults to 0.1. Andrew et al. " +"recommends to set to 0.1." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 +#: of +msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 +#: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +"The learning rate for the clipping norm adaptation. Defaults to 0.2. " +"Andrew et al. recommends to set to 0.2." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 +#: of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +"The stddev of the noise added to the count of updates currently below the" +" estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 -msgid "FedProx" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:22 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:15 +#: of +msgid "Create a strategy:" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:3 of -msgid "Implementation based on https://arxiv.org/abs/1812.06127" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 +#: of +msgid "" +"Wrap the strategy with the " +"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:5 of -msgid "" -"The strategy in itself will not be different than FedAvg, the client " -"needs to be adjusted. A proximal term needs to be added to the loss " -"function during the training:" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 +#: of +msgid "On the client, add the `adaptiveclipping_mod` to the client-side mods:" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:9 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -"\\\\frac{\\\\mu}{2} || w - w^t ||^2\n" -"\n" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:12 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -"Where $w^t$ are the global parameters and $w$ are the local weights the " -"function will be optimized with." +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:15 of -msgid "In PyTorch, for example, the loss would go from:" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_fit:1 +#: of +msgid "Aggregate training results and update clip norms." msgstr "" -#: flwr.server.strategy.fedprox.FedProx:21 of -msgid "To:" +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:30 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -"With `global_params` being a copy of the parameters before the training " -"takes place." +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedprox.FedProx:65 of -msgid "" -"The weight of the proximal term used in the optimization. 0.0 makes this " -"strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to " -"be closer to the server parameters during training)." -msgstr "" - -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 +msgid "DifferentialPrivacyClientSideFixedClipping" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:3 +#: of +msgid "Use `fixedclipping_mod` modifier at the client side." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:5 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +"In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " +"performs clipping on the server-side, " +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 +#: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"The noise multiplier for the Gaussian mechanism for model updates. A " +"value of 1.0 or higher is recommended for strong privacy." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +msgid "The value of the clipping norm." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 +#: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of -msgid "Sends the proximal factor mu to the clients" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedTrimmedAvg.rst:2 -msgid "FedTrimmedAvg" -msgstr "" - -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:3 of -msgid "Implemented based on: https://arxiv.org/abs/1803.01498" +"Wrap the strategy with the `DifferentialPrivacyClientSideFixedClipping` " +"wrapper:" msgstr "" -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:25 of -msgid "Fraction to cut off of both tails of the distribution. Defaults to 0.2." +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:32 +#: of +msgid "On the client, add the `fixedclipping_mod` to the client-side mods:" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg.aggregate_fit:1 of -msgid "Aggregate fit results using trimmed average." +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 +#: of +msgid "Add noise to the aggregated parameters." msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 +msgid "DifferentialPrivacyServerSideAdaptiveClipping" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 +#: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 -msgid "FedXgbBagging" +"The standard deviation of the noise added to the count of updates below " +"the estimate. Andrew et al. recommends to set to " +"`expected_num_records/20`" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"Wrap the strategy with the DifferentialPrivacyServerSideAdaptiveClipping " +"wrapper" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of -msgid "Aggregate evaluation metrics using average." +msgid "" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" -msgstr "" - -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_fit:1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_fit:1 of -msgid "Aggregate fit results using bagging." +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"`\\" +" \\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +#: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 +msgid "DifferentialPrivacyServerSideFixedClipping" msgstr "" -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 -msgid "FedXgbCyclic" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " +"wrapper" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\," -" results\\, failures\\)" +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 #: of -msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +msgid "Compute the updates, clip, and pass them for aggregation." msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" +msgstr "" + +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" +msgstr "" + +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 +#: of +msgid "Afterward, add noise to the aggregated parameters." +msgstr "" + +#: ../../source/ref-api/flwr.server.strategy.FaultTolerantFedAvg.rst:2 +msgid "FaultTolerantFedAvg" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 +#: flwr.server.strategy.fedadagrad.FedAdagrad.aggregate_fit:1 +#: flwr.server.strategy.fedadam.FedAdam.aggregate_fit:1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_fit:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_fit:1 +#: flwr.server.strategy.fedavgm.FedAvgM.aggregate_fit:1 +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg.aggregate_fit:1 +#: flwr.server.strategy.fedyogi.FedYogi.aggregate_fit:1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_fit:1 of +msgid "Aggregate fit results using weighted average." +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" +msgstr "" + +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 -msgid "FedXgbNnAvg" +#: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 +#: ../../source/ref-changelog.md:905 +msgid "FedAdagrad" msgstr "" -#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of -msgid "" -"This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: " -"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +#: flwr.server.strategy.fedadagrad.FedAdagrad:1 +#: flwr.server.strategy.fedadam.FedAdam:1 +#: flwr.server.strategy.fedyogi.FedYogi:1 of +msgid "Bases: :py:class:`~flwr.server.strategy.fedopt.FedOpt`" +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:3 +#: flwr.server.strategy.fedadam.FedAdam:3 flwr.server.strategy.fedopt.FedOpt:3 +#: flwr.server.strategy.fedyogi.FedYogi:3 of +msgid "Implementation based on https://arxiv.org/abs/2003.00295v5" +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:21 +#: flwr.server.strategy.fedadagrad.FedAdagrad:23 +#: flwr.server.strategy.fedadam.FedAdam:25 +#: flwr.server.strategy.fedadam.FedAdam:27 +#: flwr.server.strategy.fedavg.FedAvg:29 flwr.server.strategy.fedavg.FedAvg:31 +#: flwr.server.strategy.fedopt.FedOpt:25 flwr.server.strategy.fedopt.FedOpt:27 +#: flwr.server.strategy.fedprox.FedProx:61 +#: flwr.server.strategy.fedprox.FedProx:63 +#: flwr.server.strategy.fedyogi.FedYogi:28 +#: flwr.server.strategy.fedyogi.FedYogi:30 of +msgid "Metrics aggregation function, optional." +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:29 +#: flwr.server.strategy.fedadam.FedAdam:29 +#: flwr.server.strategy.fedopt.FedOpt:29 of +msgid "Server-side learning rate. Defaults to 1e-1." +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:31 +#: flwr.server.strategy.fedadam.FedAdam:31 +#: flwr.server.strategy.fedopt.FedOpt:31 of +msgid "Client-side learning rate. Defaults to 1e-1." +msgstr "" + +#: flwr.server.strategy.fedadagrad.FedAdagrad:33 +#: flwr.server.strategy.fedadam.FedAdam:37 +#: flwr.server.strategy.fedopt.FedOpt:37 of +msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-9." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\, " -"results\\, failures\\)" +":py:obj:`aggregate_fit `\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_fit `\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 -msgid "FedYogi" -msgstr "" - -#: flwr.server.strategy.fedyogi.FedYogi:32 of -msgid "Server-side learning rate. Defaults to 1e-2." +#: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 +msgid "FedAdam" msgstr "" -#: flwr.server.strategy.fedyogi.FedYogi:34 of -msgid "Client-side learning rate. Defaults to 0.0316." +#: flwr.server.strategy.fedadam.FedAdam:33 +#: flwr.server.strategy.fedyogi.FedYogi:36 of +msgid "Momentum parameter. Defaults to 0.9." msgstr "" -#: flwr.server.strategy.fedyogi.FedYogi:40 of -msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-3." +#: flwr.server.strategy.fedadam.FedAdam:35 +#: flwr.server.strategy.fedyogi.FedYogi:38 of +msgid "Second moment parameter. Defaults to 0.99." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," +"`\\ \\(server\\_round\\," " results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," +"`\\ \\(server\\_round\\," " parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_fit_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 -msgid "Krum" +#: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 +msgid "FedAvg" msgstr "" -#: flwr.server.strategy.krum.Krum:3 of -msgid "Implementation based on https://arxiv.org/abs/1703.02757" +#: flwr.server.strategy.fedavg.FedAvg:3 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:3 of +msgid "Implementation based on https://arxiv.org/abs/1602.05629" msgstr "" -#: flwr.server.strategy.krum.Krum:17 of +#: flwr.server.strategy.fedavg.FedAvg:5 flwr.server.strategy.fedprox.FedProx:37 +#: of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" -" that case classical Krum is applied." +"Fraction of clients used during training. In case `min_fit_clients` is " +"larger than `fraction_fit * available_clients`, `min_fit_clients` will " +"still be sampled. Defaults to 1.0." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 +#: of +msgid "" +"Fraction of clients used during validation. In case " +"`min_evaluate_clients` is larger than `fraction_evaluate * " +"available_clients`, `min_evaluate_clients` will still be sampled. " +"Defaults to 1.0." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg:33 of +msgid "Enable (True) or disable (False) in-place aggregation of model updates." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " +"`\\ \\(server\\_round\\, " "results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 -#: flwr.server.strategy.krum.Krum.aggregate_fit:1 of -msgid "Aggregate fit results using Krum." -msgstr "" - #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " +"`\\ \\(server\\_round\\, " "parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" ":py:obj:`num_evaluation_clients " -"`\\ " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 -msgid "QFedAvg" +#: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 +msgid "FedAvgAndroid" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`bytes_to_ndarray " +"`\\ \\(tensor\\)" +msgstr "" + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of +msgid "Deserialize NumPy array from bytes." +msgstr "" + +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`evaluate `\\ " +":py:obj:`evaluate `\\ " "\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" ":py:obj:`initialize_parameters " -"`\\ " +"`\\ " "\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of -msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" -msgstr "" - -#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`ndarray_to_bytes " +"`\\ \\(ndarray\\)" msgstr "" -#: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 -msgid "Strategy" +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of +msgid "Serialize NumPy array to bytes." msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`ndarrays_to_parameters " +"`\\ " +"\\(ndarrays\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of -msgid "Aggregate evaluation results." +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" -msgstr "" - -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of -msgid "Aggregate training results." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`parameters_to_ndarrays " +"`\\ " +"\\(parameters\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 #: of -msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +msgid "Convert parameters object to NumPy weights." msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of -msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +#: ../../source/ref-api/flwr.server.strategy.FedAvgM.rst:2 +msgid "FedAvgM" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.evaluate:1 of -msgid "Evaluate the current model parameters." +#: flwr.server.strategy.fedavgm.FedAvgM:3 of +msgid "Implementation based on https://arxiv.org/abs/1909.06335" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: of +#: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +"Server-side learning rate used in server-side optimization. Defaults to " +"1.0." msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of -msgid "Initialize the (global) model parameters." +#: flwr.server.strategy.fedavgm.FedAvgM:28 of +msgid "Server-side momentum factor used for FedAvgM. Defaults to 0.0." msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " -"one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "Exceptions that occurred while the server was waiting for client updates." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**aggregation_result** -- The aggregated evaluation result. Aggregation " -"typically uses some variant of a weighted average." +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" -" one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the " -"previous parameters with the ones returned from this method). If `None` " -"is returned (e.g., because there were only failures and no viable " -"results) then the server will no update the previous model parameters, " -"the updates received in this round are discarded, and the global model " -"parameters remain the same." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.evaluate:3 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"This function can be used to perform centralized (i.e., server-side) " -"evaluation of model parameters." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.evaluate:11 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple " -"containing loss and a dictionary containing task-specific metrics (e.g., " -"accuracy)." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**parameters** -- If parameters are returned, then the server will treat " -"these as the initial global model parameters." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:2 -msgid "workflow" +#: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 +msgid "FedMedian" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`DefaultWorkflow `\\ " -"\\(\\[fit\\_workflow\\, ...\\]\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of -msgid "Default workflow in Flower." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`SecAggPlusWorkflow `\\ " -"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 -#: of -msgid "The workflow for the SecAgg+ protocol." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedmedian.FedMedian.aggregate_fit:1 of +msgid "Aggregate fit results using median." msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`SecAggWorkflow `\\ " -"\\(reconstruction\\_threshold\\, \\*\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.rst:24::1 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of -msgid "The workflow for the SecAgg protocol." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:2 -msgid "DefaultWorkflow" -msgstr "" - -#: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:2 -msgid "SecAggPlusWorkflow" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors " -"owned by multiple parties, without accessing any individual integer " -"vector. This workflow allows the server to compute the weighted average " -"of model parameters across all clients, ensuring individual contributions" -" remain private. This is achieved by clients sending both, a weighting " -"factor and a weighted version of the locally updated parameters, both of " -"which are masked for privacy. Specifically, each client uploads \"[w, w *" -" params]\" with masks, where weighting factor 'w' is the number of " -"examples ('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg+ " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 -#: of -msgid "key shares." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:18 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:18 -#: of -msgid "" -"'collect masked vectors': Forward encrypted secret key shares to target " -"clients and collect masked model parameters." +#: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 +msgid "FedOpt" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:20 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:20 -#: of -msgid "" -"'unmask': Collect secret key shares to decrypt and aggregate the model " -"parameters." +#: flwr.server.strategy.fedopt.FedOpt:33 of +msgid "Momentum parameter. Defaults to 0.0." msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:22 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 -#: of -msgid "" -"Only the aggregated model parameters are exposed and passed to " -"`Strategy.aggregate_fit`, ensuring individual data privacy." +#: flwr.server.strategy.fedopt.FedOpt:35 of +msgid "Second moment parameter. Defaults to 0.0." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The number of shares into which each client's private key is split under " -"the SecAgg+ protocol. If specified as a float, it represents the " -"proportion of all selected clients, and the number of shares will be set " -"dynamically in the run time. A private key can be reconstructed from " -"these shares, allowing for the secure aggregation of model updates. Each " -"client sends one share to each of its neighbors while retaining one." +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The minimum number of shares required to reconstruct a client's private " -"key, or, if specified as a float, it represents the proportion of the " -"total number of shares needed for reconstruction. This threshold ensures " -"privacy by allowing for the recovery of contributions from dropped " -"clients during aggregation, without compromising individual client data." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The maximum value of the weight that can be assigned to any single " -"client's update during the weighted average calculation on the server " -"side, e.g., in the FedAvg algorithm." +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within " -"[-clipping_range, clipping_range], facilitating quantization." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The size of the range into which floating-point model parameters are " -"quantized, mapping each parameter to an integer in [0, " -"quantization_range-1]. This facilitates cryptographic operations on the " -"model updates." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " -"Please use 2**n values for `modulus_range` to prevent overflow issues." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for" -" replies for this duration each time. If `None`, there is no time limit " -"and the workflow will wait until replies for all messages are received." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` " -"means better privacy guarantees but less tolerance to dropouts." +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 -#: of -msgid "Too large `max_weight` may compromise the precision of the quantization." +#: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 +msgid "FedProx" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:65 -#: of -msgid "`modulus_range` must be 2**n and larger than `quantization_range`." +#: flwr.server.strategy.fedprox.FedProx:3 of +msgid "Implementation based on https://arxiv.org/abs/1812.06127" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:66 -#: of +#: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in " -"the runtime. This allows for dynamic adjustment based on the total number" -" of participating clients." +"The strategy in itself will not be different than FedAvg, the client " +"needs to be adjusted. A proximal term needs to be added to the loss " +"function during the training:" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 -#: of +#: flwr.server.strategy.fedprox.FedProx:9 of msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted " -"as the proportion of the number of shares needed for the reconstruction " -"of a private key. This feature enables flexibility in setting the " -"security threshold relative to the number of distributed shares." +"\\\\frac{\\\\mu}{2} || w - w^t ||^2\n" +"\n" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 -#: of +#: flwr.server.strategy.fedprox.FedProx:12 of msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters" -" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+" -" protocol." +"Where $w^t$ are the global parameters and $w$ are the local weights the " +"function will be optimized with." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of -msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\" -" \\(driver\\, ...\\)" +#: flwr.server.strategy.fedprox.FedProx:15 of +msgid "In PyTorch, for example, the loss would go from:" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of -msgid "Execute the 'collect masked vectors' stage." +#: flwr.server.strategy.fedprox.FedProx:21 of +msgid "To:" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedprox.FedProx:30 of msgid "" -":py:obj:`setup_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +"With `global_params` being a copy of the parameters before the training " +"takes place." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 -#: of -msgid "Execute the 'setup' stage." +#: flwr.server.strategy.fedprox.FedProx:65 of +msgid "" +"The weight of the proximal term used in the optimization. 0.0 makes this " +"strategy equivalent to FedAvg, and the higher the coefficient, the more " +"regularization will be used (that is, the client parameters will need to " +"be closer to the server parameters during training)." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`share_keys_stage " -"`\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 -#: of -msgid "Execute the 'share keys' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 -#: of -msgid "Execute the 'unmask' stage." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:2 -msgid "SecAggWorkflow" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Bases: " -":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned" -" by multiple parties, without accessing any individual integer vector. " -"This workflow allows the server to compute the weighted average of model " -"parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and" -" a weighted version of the locally updated parameters, both of which are " -"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" -" with masks, where weighting factor 'w' is the number of examples " -"('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of -msgid "" -"Each client's private key is split into N shares under the SecAgg " -"protocol, where N is the number of selected clients." +#: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of +msgid "Sends the proximal factor mu to the clients" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of -msgid "" -"Generally, higher `reconstruction_threshold` means better privacy " -"guarantees but less tolerance to dropouts." +#: ../../source/ref-api/flwr.server.strategy.FedTrimmedAvg.rst:2 +msgid "FedTrimmedAvg" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of -msgid "" -"When `reconstruction_threshold` is a float, it is interpreted as the " -"proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in " -"setting the security threshold relative to the number of selected " -"clients." +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:3 of +msgid "Implemented based on: https://arxiv.org/abs/1803.01498" msgstr "" -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of -msgid "" -"`reconstruction_threshold`, and the quantization parameters " -"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg " -"protocol." +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:25 of +msgid "Fraction to cut off of both tails of the distribution. Defaults to 0.2." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\ " -"\\(driver\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of -msgid "" -":py:obj:`share_keys_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg.aggregate_fit:1 of +msgid "Aggregate fit results using trimmed average." msgstr "" -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 -#: of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:2 -msgid "simulation" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\," -" client\\_fn\\[\\, ...\\]\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.app.start_simulation:1 of -msgid "Start a Ray-based Flower simulation server." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`run_simulation_from_cli " -"`\\ \\(\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.run_simulation.run_simulation_from_cli:1 of -msgid "Run Simulation Engine from the CLI." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -msgid "" -":py:obj:`run_simulation `\\ " -"\\(server\\_app\\, client\\_app\\, ...\\)" +#: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 +msgid "FedXgbBagging" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.run_simulation.run_simulation:1 of -msgid "Run a Flower App using the Simulation Engine." +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation.rst:2 -msgid "run\\_simulation" +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of +msgid "Aggregate evaluation metrics using average." msgstr "" -#: flwr.simulation.run_simulation.run_simulation:3 of +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of msgid "" -"The `ServerApp` to be executed. It will send messages to different " -"`ClientApp` instances running on different (virtual) SuperNodes." +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:6 of -msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive" -" messages sent by the `ServerApp`." +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_fit:1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_fit:1 of +msgid "Aggregate fit results using bagging." msgstr "" -#: flwr.simulation.run_simulation.run_simulation:9 of +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in " -"the ServerApp and receive a Message describing what the ClientApp should " -"perform." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:13 of -msgid "A simulation backend that runs `ClientApp`s." +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:15 of +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to " -"configure a backend. Values supported in are those included by " -"`flwr.common.typing.ConfigsRecordValues`." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:19 of +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. " -"This is desirable if you make use of a TensorFlow model on your " -"`ServerApp` while having your `ClientApp` running on the same GPU. " -"Without enabling this, you might encounter an out-of-memory error because" -" TensorFlow, by default, allocates all GPU memory. Read more about how " -"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " -"documentation: https://www.tensorflow.org/api/stable." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.simulation.run_simulation.run_simulation:26 of +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" -" enabled, DEBUG-level logs will be displayed." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation_from_cli.rst:2 -msgid "run\\_simulation\\_from\\_cli" +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 -msgid "start\\_simulation" +#: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 +msgid "FedXgbCyclic" msgstr "" -#: flwr.simulation.app.start_simulation:3 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"A function creating client instances. The function must take a single " -"`str` argument called `cid`. It should return a single client instance of" -" type Client. Note that the created client instances are ephemeral and " -"will often be destroyed after a single method invocation. Since client " -"instances are not long-lived, they should not attempt to carry state over" -" method invocations. Any state required by the instance (model, dataset, " -"hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load " -"evaluation data in the `evaluate` method itself)." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:13 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"The total number of clients in this simulation. This must be set if " -"`clients_ids` is not set and vice-versa." +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\," +" results\\, failures\\)" msgstr "" -#: flwr.simulation.app.start_simulation:16 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"List `client_id`s for each client. This is only required if `num_clients`" -" is not set. Setting both `num_clients` and `clients_ids` with " -"`len(clients_ids)` not equal to `num_clients` generates an error." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:20 of -msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` " -"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " -"as well as using custom resources, please consult the Ray documentation." +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:25 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"An implementation of the abstract base class `flwr.server.Server`. If no " -"instance is provided, then `start_server` will create one." +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.simulation.app.start_simulation:31 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If " -"no strategy is provided, then `start_server` will use " -"`flwr.server.strategy.FedAvg`." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: flwr.simulation.app.start_simulation:35 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_simulation` will use " -"`flwr.server.client_manager.SimpleClientManager`." +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.simulation.app.start_simulation:39 of +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 +#: of msgid "" -"Optional dictionary containing arguments for the call to `ray.init`. If " -"ray_init_args is None (the default), Ray will be initialized with the " -"following default args: { \"ignore_reinit_error\": True, " -"\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to " -"ray.init." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: flwr.simulation.app.start_simulation:39 of -msgid "" -"Optional dictionary containing arguments for the call to `ray.init`. If " -"ray_init_args is None (the default), Ray will be initialized with the " -"following default args:" +#: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 +msgid "FedXgbNnAvg" msgstr "" -#: flwr.simulation.app.start_simulation:43 of -msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" +#: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of +msgid "" +"This strategy is deprecated, but a copy of it is available in Flower " +"Baselines: " +"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" -#: flwr.simulation.app.start_simulation:45 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any " -"arguments from being passed to ray.init." +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:48 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Set to True to prevent `ray.shutdown()` in case " -"`ray.is_initialized()=True`." +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\, " +"results\\, failures\\)" msgstr "" -#: flwr.simulation.app.start_simulation:50 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Optionally specify the type of actor to use. The actor object, which " -"persists throughout the simulation, will be the process in charge of " -"executing a ClientApp wrapping input argument `client_fn`." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:54 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"If you want to create your own Actor classes, you might need to pass some" -" input argument. You can use this dictionary for such purpose." +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: flwr.simulation.app.start_simulation:57 of +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " -"the VCE to choose in which node the actor is placed. If you are an " -"advanced user needed more control you can use lower-level scheduling " -"strategies to pin actors to specific compute nodes (e.g. via " -"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." -" For all details, please refer to the Ray documentation: " -"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: flwr.simulation.app.start_simulation:66 of -msgid "**hist** -- Object containing metrics from training." +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-changelog.md:1 -msgid "Changelog" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:3 -msgid "Unreleased" +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:17 -#: ../../source/ref-changelog.md:110 ../../source/ref-changelog.md:210 -#: ../../source/ref-changelog.md:294 ../../source/ref-changelog.md:358 -#: ../../source/ref-changelog.md:416 ../../source/ref-changelog.md:485 -#: ../../source/ref-changelog.md:614 ../../source/ref-changelog.md:656 -#: ../../source/ref-changelog.md:723 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:834 ../../source/ref-changelog.md:873 -#: ../../source/ref-changelog.md:906 ../../source/ref-changelog.md:956 -msgid "What's new?" +#: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 +msgid "FedYogi" msgstr "" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:80 -#: ../../source/ref-changelog.md:192 ../../source/ref-changelog.md:282 -#: ../../source/ref-changelog.md:346 ../../source/ref-changelog.md:404 -#: ../../source/ref-changelog.md:473 ../../source/ref-changelog.md:535 -#: ../../source/ref-changelog.md:554 ../../source/ref-changelog.md:710 -#: ../../source/ref-changelog.md:781 ../../source/ref-changelog.md:818 -#: ../../source/ref-changelog.md:861 -msgid "Incompatible changes" +#: flwr.server.strategy.fedyogi.FedYogi:32 of +msgid "Server-side learning rate. Defaults to 1e-2." msgstr "" -#: ../../source/ref-changelog.md:9 -msgid "v1.7.0 (2024-02-05)" +#: flwr.server.strategy.fedyogi.FedYogi:34 of +msgid "Client-side learning rate. Defaults to 0.0316." msgstr "" -#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:104 -#: ../../source/ref-changelog.md:204 ../../source/ref-changelog.md:288 -#: ../../source/ref-changelog.md:352 ../../source/ref-changelog.md:410 -#: ../../source/ref-changelog.md:479 ../../source/ref-changelog.md:548 -msgid "Thanks to our contributors" +#: flwr.server.strategy.fedyogi.FedYogi:40 of +msgid "Controls the algorithm's degree of adaptability. Defaults to 1e-3." msgstr "" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:106 -#: ../../source/ref-changelog.md:206 ../../source/ref-changelog.md:290 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:412 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:15 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " -"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " -"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " -"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " -"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " -"Shaaban`, `Yan Gao`, `Yasar Abbas` " +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-changelog.md:19 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Introduce stateful clients (experimental)** " -"([#2770](https://github.com/adap/flower/pull/2770), " -"[#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), " -"[#2643](https://github.com/adap/flower/pull/2643), " -"[#2769](https://github.com/adap/flower/pull/2769))" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:21 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Subclasses of `Client` and `NumPyClient` can now store local state that " -"remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via " -"`start_simulation`) and networked clients (via `start_client`). It's also" -" the first preview of new abstractions like `Context` and `RecordSet`. " -"Clients can access state of type `RecordSet` via `state: RecordSet = " -"self.context.state`. Changes to this `RecordSet` are preserved across " -"different rounds of execution to enable stateful computations in a " -"unified way across simulation and deployment." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:23 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Improve performance** " -"([#2293](https://github.com/adap/flower/pull/2293))" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-changelog.md:25 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" -"place aggregation to reduce memory consumption. The Flower client " -"serialization/deserialization has been rewritten from the ground up, " -"which results in significant speedups, especially when the client-side " -"training time is short." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-changelog.md:27 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Support Federated Learning with Apple MLX and Flower** " -"([#2693](https://github.com/adap/flower/pull/2693))" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:29 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Flower has official support for federated learning using [Apple " -"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " -"example." +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:31 -msgid "" -"**Introduce new XGBoost cyclic strategy** " -"([#2666](https://github.com/adap/flower/pull/2666), " -"[#2668](https://github.com/adap/flower/pull/2668))" +#: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 +msgid "Krum" msgstr "" -#: ../../source/ref-changelog.md:33 +#: flwr.server.strategy.krum.Krum:3 of +msgid "Implementation based on https://arxiv.org/abs/1703.02757" +msgstr "" + +#: flwr.server.strategy.krum.Krum:17 of msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of" -" training (often called cyclic). The `xgboost-comprehensive` code example" -" shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower " -"offers best-in-class XGBoost support." +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" +" that case classical Krum is applied." msgstr "" -#: ../../source/ref-changelog.md:35 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Support Python 3.11** " -"([#2394](https://github.com/adap/flower/pull/2394))" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:37 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " -"ensure better support for users using more recent Python versions." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-changelog.md:39 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 +#: flwr.server.strategy.krum.Krum.aggregate_fit:1 of +msgid "Aggregate fit results using Krum." +msgstr "" + +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Update gRPC and ProtoBuf dependencies** " -"([#2814](https://github.com/adap/flower/pull/2814))" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:41 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The `grpcio` and `protobuf` dependencies were updated to their latest " -"versions for improved security and performance." +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:43 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Introduce Docker image for Flower server** " -"([#2700](https://github.com/adap/flower/pull/2700), " -"[#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), " -"[#2695](https://github.com/adap/flower/pull/2695), " -"[#2747](https://github.com/adap/flower/pull/2747), " -"[#2746](https://github.com/adap/flower/pull/2746), " -"[#2680](https://github.com/adap/flower/pull/2680), " -"[#2682](https://github.com/adap/flower/pull/2682), " -"[#2701](https://github.com/adap/flower/pull/2701))" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-changelog.md:45 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"The Flower server can now be run using an official Docker image. A new " -"how-to guide explains [how to run Flower using " -"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html). An official Flower client Docker image will follow." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-changelog.md:47 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Introduce** `flower-via-docker-compose` **example** " -"([#2626](https://github.com/adap/flower/pull/2626))" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:49 +#: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** " -"([#2719](https://github.com/adap/flower/pull/2719))" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:51 -msgid "" -"**Introduce** `custom-metrics` **example** " -"([#1958](https://github.com/adap/flower/pull/1958))" +#: ../../source/ref-api/flwr.server.strategy.QFedAvg.rst:2 +msgid "QFedAvg" msgstr "" -#: ../../source/ref-changelog.md:53 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"**Update code examples to use Flower Datasets** " -"([#2450](https://github.com/adap/flower/pull/2450), " -"[#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), " -"[#2712](https://github.com/adap/flower/pull/2712))" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:55 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"Several code examples were updated to use [Flower " -"Datasets](https://flower.ai/docs/datasets/)." +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-changelog.md:57 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"**General updates to Flower Examples** " -"([#2381](https://github.com/adap/flower/pull/2381), " -"[#2805](https://github.com/adap/flower/pull/2805), " -"[#2782](https://github.com/adap/flower/pull/2782), " -"[#2806](https://github.com/adap/flower/pull/2806), " -"[#2829](https://github.com/adap/flower/pull/2829), " -"[#2825](https://github.com/adap/flower/pull/2825), " -"[#2816](https://github.com/adap/flower/pull/2816), " -"[#2726](https://github.com/adap/flower/pull/2726), " -"[#2659](https://github.com/adap/flower/pull/2659), " -"[#2655](https://github.com/adap/flower/pull/2655))" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:59 -msgid "Many Flower code examples received substantial updates." +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:61 ../../source/ref-changelog.md:154 -msgid "**Update Flower Baselines**" +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-changelog.md:63 +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " -"[#2771](https://github.com/adap/flower/pull/2771))" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-changelog.md:64 -msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:65 -msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" +#: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of +msgid "" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -#: ../../source/ref-changelog.md:66 -msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" +#: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 +msgid "Strategy" msgstr "" -#: ../../source/ref-changelog.md:67 -msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of +msgid "" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:68 -msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of +msgid "Aggregate evaluation results." msgstr "" -#: ../../source/ref-changelog.md:70 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"**Improve documentation** " -"([#2674](https://github.com/adap/flower/pull/2674), " -"[#2480](https://github.com/adap/flower/pull/2480), " -"[#2826](https://github.com/adap/flower/pull/2826), " -"[#2727](https://github.com/adap/flower/pull/2727), " -"[#2761](https://github.com/adap/flower/pull/2761), " -"[#2900](https://github.com/adap/flower/pull/2900))" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -#: ../../source/ref-changelog.md:72 -msgid "" -"**Improved testing and development infrastructure** " -"([#2797](https://github.com/adap/flower/pull/2797), " -"[#2676](https://github.com/adap/flower/pull/2676), " -"[#2644](https://github.com/adap/flower/pull/2644), " -"[#2656](https://github.com/adap/flower/pull/2656), " -"[#2848](https://github.com/adap/flower/pull/2848), " -"[#2675](https://github.com/adap/flower/pull/2675), " -"[#2735](https://github.com/adap/flower/pull/2735), " -"[#2767](https://github.com/adap/flower/pull/2767), " -"[#2732](https://github.com/adap/flower/pull/2732), " -"[#2744](https://github.com/adap/flower/pull/2744), " -"[#2681](https://github.com/adap/flower/pull/2681), " -"[#2699](https://github.com/adap/flower/pull/2699), " -"[#2745](https://github.com/adap/flower/pull/2745), " -"[#2734](https://github.com/adap/flower/pull/2734), " -"[#2731](https://github.com/adap/flower/pull/2731), " -"[#2652](https://github.com/adap/flower/pull/2652), " -"[#2720](https://github.com/adap/flower/pull/2720), " -"[#2721](https://github.com/adap/flower/pull/2721), " -"[#2717](https://github.com/adap/flower/pull/2717), " -"[#2864](https://github.com/adap/flower/pull/2864), " -"[#2694](https://github.com/adap/flower/pull/2694), " -"[#2709](https://github.com/adap/flower/pull/2709), " -"[#2658](https://github.com/adap/flower/pull/2658), " -"[#2796](https://github.com/adap/flower/pull/2796), " -"[#2692](https://github.com/adap/flower/pull/2692), " -"[#2657](https://github.com/adap/flower/pull/2657), " -"[#2813](https://github.com/adap/flower/pull/2813), " -"[#2661](https://github.com/adap/flower/pull/2661), " -"[#2398](https://github.com/adap/flower/pull/2398))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:1 of +msgid "Aggregate training results." msgstr "" -#: ../../source/ref-changelog.md:74 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"The Flower testing and development infrastructure has received " -"substantial updates. This makes Flower 1.7 the most tested release ever." +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:76 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"**Update dependencies** " -"([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), " -"[#2739](https://github.com/adap/flower/pull/2739), " -"[#2837](https://github.com/adap/flower/pull/2837), " -"[#2788](https://github.com/adap/flower/pull/2788), " -"[#2811](https://github.com/adap/flower/pull/2811), " -"[#2774](https://github.com/adap/flower/pull/2774), " -"[#2790](https://github.com/adap/flower/pull/2790), " -"[#2751](https://github.com/adap/flower/pull/2751), " -"[#2850](https://github.com/adap/flower/pull/2850), " -"[#2812](https://github.com/adap/flower/pull/2812), " -"[#2872](https://github.com/adap/flower/pull/2872), " -"[#2736](https://github.com/adap/flower/pull/2736), " -"[#2756](https://github.com/adap/flower/pull/2756), " -"[#2857](https://github.com/adap/flower/pull/2857), " -"[#2757](https://github.com/adap/flower/pull/2757), " -"[#2810](https://github.com/adap/flower/pull/2810), " -"[#2740](https://github.com/adap/flower/pull/2740), " -"[#2789](https://github.com/adap/flower/pull/2789))" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:78 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"**General improvements** " -"([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), " -"[#2877](https://github.com/adap/flower/pull/2877), " -"[#2690](https://github.com/adap/flower/pull/2690), " -"[#2889](https://github.com/adap/flower/pull/2889), " -"[#2874](https://github.com/adap/flower/pull/2874), " -"[#2819](https://github.com/adap/flower/pull/2819), " -"[#2689](https://github.com/adap/flower/pull/2689), " -"[#2457](https://github.com/adap/flower/pull/2457), " -"[#2870](https://github.com/adap/flower/pull/2870), " -"[#2669](https://github.com/adap/flower/pull/2669), " -"[#2876](https://github.com/adap/flower/pull/2876), " -"[#2885](https://github.com/adap/flower/pull/2885), " -"[#2858](https://github.com/adap/flower/pull/2858), " -"[#2867](https://github.com/adap/flower/pull/2867), " -"[#2351](https://github.com/adap/flower/pull/2351), " -"[#2886](https://github.com/adap/flower/pull/2886), " -"[#2860](https://github.com/adap/flower/pull/2860), " -"[#2828](https://github.com/adap/flower/pull/2828), " -"[#2869](https://github.com/adap/flower/pull/2869), " -"[#2875](https://github.com/adap/flower/pull/2875), " -"[#2733](https://github.com/adap/flower/pull/2733), " -"[#2488](https://github.com/adap/flower/pull/2488), " -"[#2646](https://github.com/adap/flower/pull/2646), " -"[#2879](https://github.com/adap/flower/pull/2879), " -"[#2821](https://github.com/adap/flower/pull/2821), " -"[#2855](https://github.com/adap/flower/pull/2855), " -"[#2800](https://github.com/adap/flower/pull/2800), " -"[#2807](https://github.com/adap/flower/pull/2807), " -"[#2801](https://github.com/adap/flower/pull/2801), " -"[#2804](https://github.com/adap/flower/pull/2804), " -"[#2851](https://github.com/adap/flower/pull/2851), " -"[#2787](https://github.com/adap/flower/pull/2787), " -"[#2852](https://github.com/adap/flower/pull/2852), " -"[#2672](https://github.com/adap/flower/pull/2672), " -"[#2759](https://github.com/adap/flower/pull/2759))" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" -#: ../../source/ref-changelog.md:82 -msgid "" -"**Deprecate** `start_numpy_client` " -"([#2563](https://github.com/adap/flower/pull/2563), " -"[#2718](https://github.com/adap/flower/pull/2718))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.evaluate:1 of +msgid "Evaluate the current model parameters." msgstr "" -#: ../../source/ref-changelog.md:84 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: of msgid "" -"Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we " -"have introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need " -"to first call the `.to_client()` method and then pass returned `Client` " -"object to `start_client`. The examples and the documentation have been " -"updated accordingly." +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -#: ../../source/ref-changelog.md:86 -msgid "" -"**Deprecate legacy DP wrappers** " -"([#2749](https://github.com/adap/flower/pull/2749))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of +msgid "Initialize the (global) model parameters." msgstr "" -#: ../../source/ref-changelog.md:88 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is " -"in preparation for an all-new pluggable version of differential privacy " -"support in Flower." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " +"one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -#: ../../source/ref-changelog.md:90 -msgid "" -"**Make optional arg** `--callable` **in** `flower-client` **a required " -"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of +msgid "Exceptions that occurred while the server was waiting for client updates." msgstr "" -#: ../../source/ref-changelog.md:92 +#: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " -"([#2890](https://github.com/adap/flower/pull/2890))" +"**aggregation_result** -- The aggregated evaluation result. Aggregation " +"typically uses some variant of a weighted average." msgstr "" -#: ../../source/ref-changelog.md:94 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"**Drop experimental** `Task` **fields** " -"([#2866](https://github.com/adap/flower/pull/2866), " -"[#2865](https://github.com/adap/flower/pull/2865))" +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" +" one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -#: ../../source/ref-changelog.md:96 +#: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" -"Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed " -"fields are superseded by the new `RecordSet` abstraction." +"**parameters** -- If parameters are returned, then the server will treat " +"these as the new global model parameters (i.e., it will replace the " +"previous parameters with the ones returned from this method). If `None` " +"is returned (e.g., because there were only failures and no viable " +"results) then the server will no update the previous model parameters, " +"the updates received in this round are discarded, and the global model " +"parameters remain the same." msgstr "" -#: ../../source/ref-changelog.md:98 +#: flwr.server.strategy.strategy.Strategy.evaluate:3 of msgid "" -"**Retire MXNet examples** " -"([#2724](https://github.com/adap/flower/pull/2724))" +"This function can be used to perform centralized (i.e., server-side) " +"evaluation of model parameters." msgstr "" -#: ../../source/ref-changelog.md:100 +#: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"The development of the MXNet fremework has ended and the project is now " -"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " -"examples won't receive updates." -msgstr "" - -#: ../../source/ref-changelog.md:102 -msgid "v1.6.0 (2023-11-28)" +"**evaluation_result** -- The evaluation result, usually a Tuple " +"containing loss and a dictionary containing task-specific metrics (e.g., " +"accuracy)." msgstr "" -#: ../../source/ref-changelog.md:108 +#: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of msgid "" -"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " -"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," -" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " -"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " -"`cnxdeveloper`, `k3nfalt` " +"**parameters** -- If parameters are returned, then the server will treat " +"these as the initial global model parameters." msgstr "" -#: ../../source/ref-changelog.md:112 -msgid "" -"**Add experimental support for Python 3.12** " -"([#2565](https://github.com/adap/flower/pull/2565))" +#: ../../source/ref-api/flwr.server.workflow.rst:2 +msgid "workflow" msgstr "" -#: ../../source/ref-changelog.md:114 +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Add new XGBoost examples** " -"([#2612](https://github.com/adap/flower/pull/2612), " -"[#2554](https://github.com/adap/flower/pull/2554), " -"[#2617](https://github.com/adap/flower/pull/2617), " -"[#2618](https://github.com/adap/flower/pull/2618), " -"[#2619](https://github.com/adap/flower/pull/2619), " -"[#2567](https://github.com/adap/flower/pull/2567))" +":py:obj:`DefaultWorkflow `\\ " +"\\(\\[fit\\_workflow\\, ...\\]\\)" msgstr "" -#: ../../source/ref-changelog.md:116 -msgid "" -"We have added a new `xgboost-quickstart` example alongside a new " -"`xgboost-comprehensive` example that goes more in-depth." +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.default_workflows.DefaultWorkflow:1 of +msgid "Default workflow in Flower." msgstr "" -#: ../../source/ref-changelog.md:118 +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Add Vertical FL example** " -"([#2598](https://github.com/adap/flower/pull/2598))" +":py:obj:`SecAggPlusWorkflow `\\ " +"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" msgstr "" -#: ../../source/ref-changelog.md:120 -msgid "" -"We had many questions about Vertical Federated Learning using Flower, so " -"we decided to add an simple example for it on the [Titanic " -"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " -"tutorial (in the README)." +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 +#: of +msgid "The workflow for the SecAgg+ protocol." msgstr "" -#: ../../source/ref-changelog.md:122 +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` " -"([#2292](https://github.com/adap/flower/pull/2292))" +":py:obj:`SecAggWorkflow `\\ " +"\\(reconstruction\\_threshold\\, \\*\\)" msgstr "" -#: ../../source/ref-changelog.md:124 -msgid "" -"**Update REST API to support create and delete nodes** " -"([#2283](https://github.com/adap/flower/pull/2283))" +#: ../../source/ref-api/flwr.server.workflow.rst:24::1 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +msgid "The workflow for the SecAgg protocol." msgstr "" -#: ../../source/ref-changelog.md:126 -msgid "" -"**Update the Android SDK** " -"([#2187](https://github.com/adap/flower/pull/2187))" +#: ../../source/ref-api/flwr.server.workflow.DefaultWorkflow.rst:2 +msgid "DefaultWorkflow" msgstr "" -#: ../../source/ref-changelog.md:128 -msgid "Add gRPC request-response capability to the Android SDK." +#: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:2 +msgid "SecAggPlusWorkflow" msgstr "" -#: ../../source/ref-changelog.md:130 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 +#: of msgid "" -"**Update the C++ SDK** " -"([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"The SecAgg+ protocol ensures the secure summation of integer vectors " +"owned by multiple parties, without accessing any individual integer " +"vector. This workflow allows the server to compute the weighted average " +"of model parameters across all clients, ensuring individual contributions" +" remain private. This is achieved by clients sending both, a weighting " +"factor and a weighted version of the locally updated parameters, both of " +"which are masked for privacy. Specifically, each client uploads \"[w, w *" +" params]\" with masks, where weighting factor 'w' is the number of " +"examples ('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" -#: ../../source/ref-changelog.md:132 -msgid "Add gRPC request-response capability to the C++ SDK." +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 +#: of +msgid "" +"The protocol involves four main stages: - 'setup': Send SecAgg+ " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" -#: ../../source/ref-changelog.md:134 -msgid "" -"**Make HTTPS the new default** " -"([#2591](https://github.com/adap/flower/pull/2591), " -"[#2636](https://github.com/adap/flower/pull/2636))" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 +#: of +msgid "key shares." msgstr "" -#: ../../source/ref-changelog.md:136 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:18 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:18 +#: of msgid "" -"Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP " -"for prototyping. The same applies to `flower-client`, which can either " -"use user-provided credentials or gRPC-bundled certificates to connect to " -"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " -"enable insecure HTTP connections." +"'collect masked vectors': Forward encrypted secret key shares to target " +"clients and collect masked model parameters." msgstr "" -#: ../../source/ref-changelog.md:138 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:20 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:20 +#: of msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` " -"will still start in insecure mode by default. In a future release, " -"insecure connections will require user opt-in by passing `insecure=True`." +"'unmask': Collect secret key shares to decrypt and aggregate the model " +"parameters." msgstr "" -#: ../../source/ref-changelog.md:140 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:22 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 +#: of msgid "" -"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"Only the aggregated model parameters are exposed and passed to " +"`Strategy.aggregate_fit`, ensuring individual data privacy." msgstr "" -#: ../../source/ref-changelog.md:142 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 +#: of msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as " -"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" -" `start_simulation`) without requiring changes to how the client class is" -" defined and instantiated. The `to_client()` function is introduced to " -"convert a `NumPyClient` to a `Client`." +"The number of shares into which each client's private key is split under " +"the SecAgg+ protocol. If specified as a float, it represents the " +"proportion of all selected clients, and the number of shares will be set " +"dynamically in the run time. A private key can be reconstructed from " +"these shares, allowing for the secure aggregation of model updates. Each " +"client sends one share to each of its neighbors while retaining one." msgstr "" -#: ../../source/ref-changelog.md:144 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 +#: of msgid "" -"**Add new** `Bulyan` **strategy** " -"([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891))" +"The minimum number of shares required to reconstruct a client's private " +"key, or, if specified as a float, it represents the proportion of the " +"total number of shares needed for reconstruction. This threshold ensures " +"privacy by allowing for the recovery of contributions from dropped " +"clients during aggregation, without compromising individual client data." msgstr "" -#: ../../source/ref-changelog.md:146 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 +#: of msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " -"2018](https://arxiv.org/abs/1802.07927)" +"The maximum value of the weight that can be assigned to any single " +"client's update during the weighted average calculation on the server " +"side, e.g., in the FedAvg algorithm." msgstr "" -#: ../../source/ref-changelog.md:148 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 +#: of msgid "" -"**Add new** `XGB Bagging` **strategy** " -"([#2611](https://github.com/adap/flower/pull/2611))" +"The range within which model parameters are clipped before quantization. " +"This parameter ensures each model parameter is bounded within " +"[-clipping_range, clipping_range], facilitating quantization." msgstr "" -#: ../../source/ref-changelog.md:150 ../../source/ref-changelog.md:152 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 +#: of msgid "" -"**Introduce `WorkloadState`** " -"([#2564](https://github.com/adap/flower/pull/2564), " -"[#2632](https://github.com/adap/flower/pull/2632))" +"The size of the range into which floating-point model parameters are " +"quantized, mapping each parameter to an integer in [0, " +"quantization_range-1]. This facilitates cryptographic operations on the " +"model updates." msgstr "" -#: ../../source/ref-changelog.md:156 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 +#: of msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"The range of values from which random mask entries are uniformly sampled " +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " +"Please use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" -#: ../../source/ref-changelog.md:158 -msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400))" -msgstr "" - -#: ../../source/ref-changelog.md:160 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 +#: of msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"The timeout duration in seconds. If specified, the workflow will wait for" +" replies for this duration each time. If `None`, there is no time limit " +"and the workflow will wait until replies for all messages are received." msgstr "" -#: ../../source/ref-changelog.md:162 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 +#: of msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"Generally, higher `num_shares` means more robust to dropouts while " +"increasing the computational costs; higher `reconstruction_threshold` " +"means better privacy guarantees but less tolerance to dropouts." msgstr "" -#: ../../source/ref-changelog.md:164 -msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 +#: of +msgid "Too large `max_weight` may compromise the precision of the quantization." msgstr "" -#: ../../source/ref-changelog.md:166 -msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:65 +#: of +msgid "`modulus_range` must be 2**n and larger than `quantization_range`." msgstr "" -#: ../../source/ref-changelog.md:168 -msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:66 +#: of +msgid "" +"When `num_shares` is a float, it is interpreted as the proportion of all " +"selected clients, and hence the number of shares will be determined in " +"the runtime. This allows for dynamic adjustment based on the total number" +" of participating clients." msgstr "" -#: ../../source/ref-changelog.md:170 -msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 +#: of +msgid "" +"Similarly, when `reconstruction_threshold` is a float, it is interpreted " +"as the proportion of the number of shares needed for the reconstruction " +"of a private key. This feature enables flexibility in setting the " +"security threshold relative to the number of distributed shares." msgstr "" -#: ../../source/ref-changelog.md:172 -msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 +#: of +msgid "" +"`num_shares`, `reconstruction_threshold`, and the quantization parameters" +" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+" +" protocol." msgstr "" -#: ../../source/ref-changelog.md:174 -msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of +msgid "" +":py:obj:`collect_masked_vectors_stage " +"`\\" +" \\(driver\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:176 -msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of +msgid "Execute the 'collect masked vectors' stage." msgstr "" -#: ../../source/ref-changelog.md:178 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +":py:obj:`setup_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:180 -msgid "" -"**General updates to Flower Examples** " -"([#2384](https://github.com/adap/flower/pull/2384), " -"[#2425](https://github.com/adap/flower/pull/2425), " -"[#2526](https://github.com/adap/flower/pull/2526), " -"[#2302](https://github.com/adap/flower/pull/2302), " -"[#2545](https://github.com/adap/flower/pull/2545))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 +#: of +msgid "Execute the 'setup' stage." msgstr "" -#: ../../source/ref-changelog.md:182 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**General updates to Flower Baselines** " -"([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435), " -"[#2462](https://github.com/adap/flower/pull/2462), " -"[#2463](https://github.com/adap/flower/pull/2463), " -"[#2461](https://github.com/adap/flower/pull/2461), " -"[#2469](https://github.com/adap/flower/pull/2469), " -"[#2466](https://github.com/adap/flower/pull/2466), " -"[#2471](https://github.com/adap/flower/pull/2471), " -"[#2472](https://github.com/adap/flower/pull/2472), " -"[#2470](https://github.com/adap/flower/pull/2470))" +":py:obj:`share_keys_stage " +"`\\ " +"\\(driver\\, context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:184 -msgid "" -"**General updates to the simulation engine** " -"([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), " -"[#2294](https://github.com/adap/flower/pull/2294))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 +#: of +msgid "Execute the 'share keys' stage." msgstr "" -#: ../../source/ref-changelog.md:186 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**General updates to Flower SDKs** " -"([#2288](https://github.com/adap/flower/pull/2288), " -"[#2429](https://github.com/adap/flower/pull/2429), " -"[#2555](https://github.com/adap/flower/pull/2555), " -"[#2543](https://github.com/adap/flower/pull/2543), " -"[#2544](https://github.com/adap/flower/pull/2544), " -"[#2597](https://github.com/adap/flower/pull/2597), " -"[#2623](https://github.com/adap/flower/pull/2623))" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:188 -msgid "" -"**General improvements** " -"([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[#2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[#2317](https://github.com/adap/flower/pull/2317), " -"[#2349](https://github.com/adap/flower/pull/2349), " -"[#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446), " -"[#2561](https://github.com/adap/flower/pull/2561), " -"[#2273](https://github.com/adap/flower/pull/2273), " -"[#2267](https://github.com/adap/flower/pull/2267), " -"[#2274](https://github.com/adap/flower/pull/2274), " -"[#2275](https://github.com/adap/flower/pull/2275), " -"[#2432](https://github.com/adap/flower/pull/2432), " -"[#2251](https://github.com/adap/flower/pull/2251), " -"[#2321](https://github.com/adap/flower/pull/2321), " -"[#1936](https://github.com/adap/flower/pull/1936), " -"[#2408](https://github.com/adap/flower/pull/2408), " -"[#2413](https://github.com/adap/flower/pull/2413), " -"[#2401](https://github.com/adap/flower/pull/2401), " -"[#2531](https://github.com/adap/flower/pull/2531), " -"[#2534](https://github.com/adap/flower/pull/2534), " -"[#2535](https://github.com/adap/flower/pull/2535), " -"[#2521](https://github.com/adap/flower/pull/2521), " -"[#2553](https://github.com/adap/flower/pull/2553), " -"[#2596](https://github.com/adap/flower/pull/2596))" +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 +#: of +msgid "Execute the 'unmask' stage." msgstr "" -#: ../../source/ref-changelog.md:190 ../../source/ref-changelog.md:280 -#: ../../source/ref-changelog.md:344 ../../source/ref-changelog.md:398 -#: ../../source/ref-changelog.md:465 -msgid "Flower received many improvements under the hood, too many to list here." +#: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:2 +msgid "SecAggWorkflow" msgstr "" -#: ../../source/ref-changelog.md:194 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"**Remove support for Python 3.7** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" +"Bases: " +":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" -#: ../../source/ref-changelog.md:196 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes" -" support. Flower now requires Python 3.8." +"The SecAgg protocol ensures the secure summation of integer vectors owned" +" by multiple parties, without accessing any individual integer vector. " +"This workflow allows the server to compute the weighted average of model " +"parameters across all clients, ensuring individual contributions remain " +"private. This is achieved by clients sending both, a weighting factor and" +" a weighted version of the locally updated parameters, both of which are " +"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" +" with masks, where weighting factor 'w' is the number of examples " +"('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" -#: ../../source/ref-changelog.md:198 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"**Remove experimental argument** `rest` **from** `start_client` " -"([#2324](https://github.com/adap/flower/pull/2324))" +"The protocol involves four main stages: - 'setup': Send SecAgg " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" -#: ../../source/ref-changelog.md:200 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"The (still experimental) argument `rest` was removed from `start_client` " -"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " -"experimental REST API instead." +"Each client's private key is split into N shares under the SecAgg " +"protocol, where N is the number of selected clients." msgstr "" -#: ../../source/ref-changelog.md:202 -msgid "v1.5.0 (2023-08-31)" +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of +msgid "" +"Generally, higher `reconstruction_threshold` means better privacy " +"guarantees but less tolerance to dropouts." msgstr "" -#: ../../source/ref-changelog.md:208 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" -"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " -"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " +"When `reconstruction_threshold` is a float, it is interpreted as the " +"proportion of the number of all selected clients needed for the " +"reconstruction of a private key. This feature enables flexibility in " +"setting the security threshold relative to the number of selected " +"clients." msgstr "" -#: ../../source/ref-changelog.md:212 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of msgid "" -"**Introduce new simulation engine** " -"([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"`reconstruction_threshold`, and the quantization parameters " +"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg " +"protocol." msgstr "" -#: ../../source/ref-changelog.md:214 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and" -" memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-" -"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +":py:obj:`collect_masked_vectors_stage " +"`\\ " +"\\(driver\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:216 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"Comprehensive documentation includes a new [how-to run " -"simulations](https://flower.ai/docs/framework/how-to-run-" -"simulations.html) guide, new [simulation-" -"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " -"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +":py:obj:`setup_stage `\\" +" \\(driver\\, context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:218 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"**Restructure Flower Docs** " -"([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +":py:obj:`share_keys_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:220 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 +#: of msgid "" -"Much effort went into a completely restructured Flower docs experience. " -"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " -"divided into Flower Framework, Flower Baselines, Flower Android SDK, " -"Flower iOS SDK, and code example projects." +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -#: ../../source/ref-changelog.md:222 -msgid "" -"**Introduce Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +#: ../../source/ref-api/flwr.simulation.rst:2 +msgid "simulation" msgstr "" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support" -" on iOS is improving, and alongside the Swift SDK and code example, there" -" is now also an iOS quickstart tutorial." +":py:obj:`start_simulation `\\ \\(\\*\\," +" client\\_fn\\[\\, ...\\]\\)" msgstr "" -#: ../../source/ref-changelog.md:226 -msgid "" -"**Introduce Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +#: ../../source/ref-api/flwr.simulation.rst:18::1 +#: flwr.simulation.app.start_simulation:1 of +msgid "Start a Ray-based Flower simulation server." msgstr "" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower " -"support on Android is improving, and alongside the Kotlin SDK and code " -"example, there is now also an Android quickstart tutorial." +":py:obj:`run_simulation `\\ " +"\\(server\\_app\\, client\\_app\\, ...\\)" msgstr "" -#: ../../source/ref-changelog.md:230 -msgid "" -"**Introduce new end-to-end testing infrastructure** " -"([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" +#: ../../source/ref-api/flwr.simulation.rst:18::1 +#: flwr.simulation.run_simulation.run_simulation:1 of +msgid "Run a Flower App using the Simulation Engine." msgstr "" -#: ../../source/ref-changelog.md:232 -msgid "" -"A new testing infrastructure ensures that new changes stay compatible " -"with existing framework integrations or strategies." +#: ../../source/ref-api/flwr.simulation.run_simulation.rst:2 +msgid "run\\_simulation" msgstr "" -#: ../../source/ref-changelog.md:234 -msgid "**Deprecate Python 3.7**" +#: flwr.simulation.run_simulation.run_simulation:3 of +msgid "" +"The `ServerApp` to be executed. It will send messages to different " +"`ClientApp` instances running on different (virtual) SuperNodes." msgstr "" -#: ../../source/ref-changelog.md:236 +#: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" -" Python 3.7 is now deprecated and will be removed in an upcoming release." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive" +" messages sent by the `ServerApp`." msgstr "" -#: ../../source/ref-changelog.md:238 +#: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"**Add new** `FedTrimmedAvg` **strategy** " -"([#1769](https://github.com/adap/flower/pull/1769), " -"[#1853](https://github.com/adap/flower/pull/1853))" +"Number of nodes that run a ClientApp. They can be sampled by a Driver in " +"the ServerApp and receive a Message describing what the ClientApp should " +"perform." msgstr "" -#: ../../source/ref-changelog.md:240 -msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)." +#: flwr.simulation.run_simulation.run_simulation:13 of +msgid "A simulation backend that runs `ClientApp`s." msgstr "" -#: ../../source/ref-changelog.md:242 +#: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"**Introduce start_driver** " -"([#1697](https://github.com/adap/flower/pull/1697))" +"'A dictionary, e.g {\"\": , \"\": } to " +"configure a backend. Values supported in are those included by " +"`flwr.common.typing.ConfigsRecordValues`." msgstr "" -#: ../../source/ref-changelog.md:244 +#: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"In addition to `start_server` and using the raw Driver API, there is a " -"new `start_driver` function that allows for running `start_server` " -"scripts as a Flower driver with only a single-line code change. Check out" -" the `mt-pytorch` code example to see a working example using " -"`start_driver`." +"A boolean to indicate whether to enable GPU growth on the main thread. " +"This is desirable if you make use of a TensorFlow model on your " +"`ServerApp` while having your `ClientApp` running on the same GPU. " +"Without enabling this, you might encounter an out-of-memory error because" +" TensorFlow, by default, allocates all GPU memory. Read more about how " +"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " +"documentation: https://www.tensorflow.org/api/stable." msgstr "" -#: ../../source/ref-changelog.md:246 +#: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** " -"([#1785](https://github.com/adap/flower/pull/1785))" +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" +" enabled, DEBUG-level logs will be displayed." msgstr "" -#: ../../source/ref-changelog.md:248 -msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a" -" driver script. The included `driver.py` and `server.py` have been " -"aligned to demonstrate both the low-level way and the high-level way of " -"building server-side logic." +#: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 +msgid "start\\_simulation" msgstr "" -#: ../../source/ref-changelog.md:250 +#: flwr.simulation.app.start_simulation:3 of msgid "" -"**Migrate experimental REST API to Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"A function creating client instances. The function must take a single " +"`str` argument called `cid`. It should return a single client instance of" +" type Client. Note that the created client instances are ephemeral and " +"will often be destroyed after a single method invocation. Since client " +"instances are not long-lived, they should not attempt to carry state over" +" method invocations. Any state required by the instance (model, dataset, " +"hyperparameters, ...) should be (re-)created in either the call to " +"`client_fn` or the call to any of the client methods (e.g., load " +"evaluation data in the `evaluate` method itself)." msgstr "" -#: ../../source/ref-changelog.md:252 +#: flwr.simulation.app.start_simulation:13 of msgid "" -"The (experimental) REST API used to be implemented in " -"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" -" use [Starlette](https://www.starlette.io/) directly." +"The total number of clients in this simulation. This must be set if " +"`clients_ids` is not set and vice-versa." msgstr "" -#: ../../source/ref-changelog.md:254 +#: flwr.simulation.app.start_simulation:16 of msgid "" -"Please note: The REST request-response API is still experimental and will" -" likely change significantly over time." +"List `client_id`s for each client. This is only required if `num_clients`" +" is not set. Setting both `num_clients` and `clients_ids` with " +"`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" -#: ../../source/ref-changelog.md:256 +#: flwr.simulation.app.start_simulation:20 of msgid "" -"**Introduce experimental gRPC request-response API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901))" +"CPU and GPU resources for a single client. Supported keys are `num_cpus` " +"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " +"as well as using custom resources, please consult the Ray documentation." msgstr "" -#: ../../source/ref-changelog.md:258 +#: flwr.simulation.app.start_simulation:25 of msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) " -"and the experimental REST API, there is now a new gRPC API that uses a " -"request-response model to communicate with client nodes." +"An implementation of the abstract base class `flwr.server.Server`. If no " +"instance is provided, then `start_server` will create one." msgstr "" -#: ../../source/ref-changelog.md:260 +#: flwr.simulation.app.start_simulation:31 of msgid "" -"Please note: The gRPC request-response API is still experimental and will" -" likely change significantly over time." +"An implementation of the abstract base class `flwr.server.Strategy`. If " +"no strategy is provided, then `start_server` will use " +"`flwr.server.strategy.FedAvg`." msgstr "" -#: ../../source/ref-changelog.md:262 +#: flwr.simulation.app.start_simulation:35 of msgid "" -"**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_simulation` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" -#: ../../source/ref-changelog.md:264 +#: flwr.simulation.app.start_simulation:39 of msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in " -"favour of a new argument `transport`. `start_client(transport=\"rest\")` " -"will yield the same behaviour as `start_client(rest=True)` did before. " -"All code should migrate to the new argument `transport`. The deprecated " -"argument `rest` will be removed in a future release." +"Optional dictionary containing arguments for the call to `ray.init`. If " +"ray_init_args is None (the default), Ray will be initialized with the " +"following default args: { \"ignore_reinit_error\": True, " +"\"include_dashboard\": False } An empty dictionary can be used " +"(ray_init_args={}) to prevent any arguments from being passed to " +"ray.init." msgstr "" -#: ../../source/ref-changelog.md:266 +#: flwr.simulation.app.start_simulation:39 of msgid "" -"**Add a new gRPC option** " -"([#2197](https://github.com/adap/flower/pull/2197))" +"Optional dictionary containing arguments for the call to `ray.init`. If " +"ray_init_args is None (the default), Ray will be initialized with the " +"following default args:" msgstr "" -#: ../../source/ref-changelog.md:268 -msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" -" option set to 0 by default. This prevents the clients from sending " -"keepalive pings when there is no outstanding stream." +#: flwr.simulation.app.start_simulation:43 of +msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" msgstr "" -#: ../../source/ref-changelog.md:270 +#: flwr.simulation.app.start_simulation:45 of msgid "" -"**Improve example notebooks** " -"([#2005](https://github.com/adap/flower/pull/2005))" +"An empty dictionary can be used (ray_init_args={}) to prevent any " +"arguments from being passed to ray.init." msgstr "" -#: ../../source/ref-changelog.md:272 -msgid "There's a new 30min Federated Learning PyTorch tutorial!" +#: flwr.simulation.app.start_simulation:48 of +msgid "" +"Set to True to prevent `ray.shutdown()` in case " +"`ray.is_initialized()=True`." msgstr "" -#: ../../source/ref-changelog.md:274 +#: flwr.simulation.app.start_simulation:50 of msgid "" -"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"Optionally specify the type of actor to use. The actor object, which " +"persists throughout the simulation, will be the process in charge of " +"executing a ClientApp wrapping input argument `client_fn`." msgstr "" -#: ../../source/ref-changelog.md:276 +#: flwr.simulation.app.start_simulation:54 of msgid "" -"Many examples have received significant updates, including simplified " -"advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A" -" major upgrade is that all code examples now have a `requirements.txt` " -"(in addition to `pyproject.toml`)." +"If you want to create your own Actor classes, you might need to pass some" +" input argument. You can use this dictionary for such purpose." msgstr "" -#: ../../source/ref-changelog.md:278 +#: flwr.simulation.app.start_simulation:57 of msgid "" -"**General improvements** " -"([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " +"the VCE to choose in which node the actor is placed. If you are an " +"advanced user needed more control you can use lower-level scheduling " +"strategies to pin actors to specific compute nodes (e.g. via " +"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." +" For all details, please refer to the Ray documentation: " +"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" msgstr "" -#: ../../source/ref-changelog.md:284 ../../source/ref-changelog.md:348 -#: ../../source/ref-changelog.md:406 ../../source/ref-changelog.md:475 -#: ../../source/ref-changelog.md:537 +#: flwr.simulation.app.start_simulation:66 of +msgid "**hist** -- Object containing metrics from training." +msgstr "" + +#: ../../source/ref-changelog.md:1 +msgid "Changelog" +msgstr "" + +#: ../../source/ref-changelog.md:3 +msgid "Unreleased" +msgstr "" + +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 +#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 +#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 +#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 +#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 +#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 +#: ../../source/ref-changelog.md:1022 +msgid "What's new?" +msgstr "" + +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 +#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 +#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 +#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 +#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 +msgid "Incompatible changes" +msgstr "" + +#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 +#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 +#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 +#: ../../source/ref-changelog.md:603 msgid "None" msgstr "" -#: ../../source/ref-changelog.md:286 -msgid "v1.4.0 (2023-04-21)" +#: ../../source/ref-changelog.md:11 +msgid "v1.8.0 (2024-04-03)" msgstr "" -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 +#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 +#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 +#: ../../source/ref-changelog.md:614 +msgid "Thanks to our contributors" +msgstr "" + +#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 +#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 +#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 +#: ../../source/ref-changelog.md:478 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:17 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " -"example)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " msgstr "" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:21 msgid "" -"XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" -" " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" and a [code example](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart) that demonstrates the usage of this new strategy in " -"an XGBoost project." +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" msgstr "" -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:23 msgid "" -"**Introduce iOS SDK (preview)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " +"this multi-run) and execute the same project in either simulation " +"environments or deployment environments without having to change a single" +" line of code. The best part? It's fully compatible with existing Flower " +"projects that use `Strategy`, `NumPyClient` & co." msgstr "" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:25 msgid "" -"This is a major update for anyone wanting to implement Federated Learning" -" on iOS mobile devices. We now have a swift iOS SDK present under " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" that will facilitate greatly the app creating process. To showcase its " -"use, the [iOS " -"example](https://github.com/adap/flower/tree/main/examples/ios) has also " -"been updated!" +"**Introduce Flower Next low-level API (preview)** " +"([#3062](https://github.com/adap/flower/pull/3062), " +"[#3034](https://github.com/adap/flower/pull/3034), " +"[#3069](https://github.com/adap/flower/pull/3069))" msgstr "" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:27 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** " -"([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" +"In addition to the Flower Next *high-level* API that uses `Strategy`, " +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " +"new Flower Next *low-level* API. The low-level API allows for granular " +"control of every aspect of the learning process by sending/receiving " +"individual messages to/from client nodes. The new `ServerApp` supports " +"registering a custom `main` function that allows writing custom training " +"loops for methods like async FL, cyclic training, or federated analytics." +" The new `ClientApp` supports registering `train`, `evaluate` and `query`" +" functions that can access the raw message received from the `ServerApp`." +" New abstractions like `RecordSet`, `Message` and `Context` further " +"enable sending multiple models, multiple sets of config values and " +"metrics, stateful computations on the client node and implementations of " +"custom SMPC protocols, to name just a few." msgstr "" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:29 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html) in our documentation explains the basics" -" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" -" Learning to start their journey with Flower. Forward it to anyone who's " -"interested in Federated Learning!" +"**Introduce Flower Mods (preview)** " +"([#3054](https://github.com/adap/flower/pull/3054), " +"[#2911](https://github.com/adap/flower/pull/2911), " +"[#3083](https://github.com/adap/flower/pull/3083))" msgstr "" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:31 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" +"Flower Modifiers (we call them Mods) can intercept messages and analyze, " +"edit or handle them directly. Mods can be used to develop pluggable " +"modules that work across different projects. Flower 1.8 already includes " +"mods to log the size of a message, the number of parameters sent over the" +" network, differential privacy with fixed clipping and adaptive clipping," +" local differential privacy and secure aggregation protocols SecAgg and " +"SecAgg+. The Flower Mods API is released as a preview, but researchers " +"can already use it to experiment with arbirtrary SMPC protocols." msgstr "" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:33 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated" -" Optimization in Heterogeneous Networks (Li et al., " -"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," -" which aims at making convergence more robust in heterogeneous settings." +"**Fine-tune LLMs with LLM FlowerTune** " +"([#3029](https://github.com/adap/flower/pull/3029), " +"[#3089](https://github.com/adap/flower/pull/3089), " +"[#3092](https://github.com/adap/flower/pull/3092), " +"[#3100](https://github.com/adap/flower/pull/3100), " +"[#3114](https://github.com/adap/flower/pull/3114), " +"[#3162](https://github.com/adap/flower/pull/3162), " +"[#3172](https://github.com/adap/flower/pull/3172))" msgstr "" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:35 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"We are introducing LLM FlowerTune, an introductory example that " +"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " +"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" +" different models and/or datasets. Read our blog post [LLM FlowerTune: " +"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" +"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:37 msgid "" -"This new baseline replicates an experiment evaluating the performance of " -"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " -"Benchmark for Federated Settings (Caldas et al., " -"2018)](https://arxiv.org/abs/1812.01097)." +"**Introduce built-in Differential Privacy (preview)** " +"([#2798](https://github.com/adap/flower/pull/2798), " +"[#2959](https://github.com/adap/flower/pull/2959), " +"[#3038](https://github.com/adap/flower/pull/3038), " +"[#3147](https://github.com/adap/flower/pull/3147), " +"[#2909](https://github.com/adap/flower/pull/2909), " +"[#2893](https://github.com/adap/flower/pull/2893), " +"[#2892](https://github.com/adap/flower/pull/2892), " +"[#3039](https://github.com/adap/flower/pull/3039), " +"[#3074](https://github.com/adap/flower/pull/3074))" msgstr "" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:39 msgid "" -"**Introduce (experimental) REST API** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" +"Built-in Differential Privacy is here! Flower supports both central and " +"local differential privacy (DP). Central DP can be configured with either" +" fixed or adaptive clipping. The clipping can happen either on the " +"server-side or the client-side. Local DP does both clipping and noising " +"on the client-side. A new documentation page [explains Differential " +"Privacy approaches](https://flower.ai/docs/framework/explanation-" +"differential-privacy.html) and a new how-to guide describes [how to use " +"the new Differential Privacy components](https://flower.ai/docs/framework" +"/how-to-use-differential-privacy.html) in Flower." msgstr "" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:41 msgid "" -"A new REST API has been introduced as an alternative to the gRPC-based " -"communication stack. In this initial version, the REST API only supports " -"anonymous clients." +"**Introduce built-in Secure Aggregation (preview)** " +"([#3120](https://github.com/adap/flower/pull/3120), " +"[#3110](https://github.com/adap/flower/pull/3110), " +"[#3108](https://github.com/adap/flower/pull/3108))" msgstr "" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:43 msgid "" -"Please note: The REST API is still experimental and will likely change " -"significantly over time." +"Built-in Secure Aggregation is here! Flower now supports different secure" +" aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In " +"this initial release, we inlcude support for SecAgg and SecAgg+, but more" +" protocols will be implemented shortly. We'll also add detailed docs that" +" explain secure aggregation and how to use it in Flower. You can already " +"check out the new code example that shows how to use Flower to easily " +"combine Federated Learning, Differential Privacy and Secure Aggregation " +"in the same project." msgstr "" -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:45 msgid "" -"**Improve the (experimental) Driver API** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**Introduce** `flwr` **CLI (preview)** " +"([#2942](https://github.com/adap/flower/pull/2942), " +"[#3055](https://github.com/adap/flower/pull/3055), " +"[#3111](https://github.com/adap/flower/pull/3111), " +"[#3130](https://github.com/adap/flower/pull/3130), " +"[#3136](https://github.com/adap/flower/pull/3136), " +"[#3094](https://github.com/adap/flower/pull/3094), " +"[#3059](https://github.com/adap/flower/pull/3059), " +"[#3049](https://github.com/adap/flower/pull/3049), " +"[#3142](https://github.com/adap/flower/pull/3142))" msgstr "" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:47 msgid "" -"The Driver API is still an experimental feature, but this release " -"introduces some major upgrades. One of the main improvements is the " -"introduction of an SQLite database to store server state on disk (instead" -" of in-memory). Another improvement is that tasks (instructions or " -"results) that have been delivered will now be deleted. This greatly " -"improves the memory efficiency of a long-running Flower server." +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" +" and then running them using the Simulation Engine (`flwr run`)." msgstr "" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:49 msgid "" -"**Fix spilling issues related to Ray during simulations** " -"([#1698](https://github.com/adap/flower/pull/1698))" +"**Introduce Flower Next Simulation Engine** " +"([#3024](https://github.com/adap/flower/pull/3024), " +"[#3061](https://github.com/adap/flower/pull/3061), " +"[#2997](https://github.com/adap/flower/pull/2997), " +"[#2783](https://github.com/adap/flower/pull/2783), " +"[#3184](https://github.com/adap/flower/pull/3184), " +"[#3075](https://github.com/adap/flower/pull/3075), " +"[#3047](https://github.com/adap/flower/pull/3047), " +"[#2998](https://github.com/adap/flower/pull/2998), " +"[#3009](https://github.com/adap/flower/pull/3009), " +"[#3008](https://github.com/adap/flower/pull/3008))" msgstr "" -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:51 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts" -" of data that would make the training unable to continue. This is now " -"fixed! 🎉" +"The Flower Simulation Engine can now run Flower Next projects. For " +"notebook environments, there's also a new `run_simulation` function that " +"can run `ServerApp` and `ClientApp`." msgstr "" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:53 msgid "" -"**Add new example using** `TabNet` **and Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"**Handle SuperNode connection errors** " +"([#2969](https://github.com/adap/flower/pull/2969))" msgstr "" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:55 msgid "" -"TabNet is a powerful and flexible framework for training machine learning" -" models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" -"/quickstart-tabnet)." +"A SuperNode will now try to reconnect indefinitely to the SuperLink in " +"case of connection errors. The arguments `--max-retries` and `--max-wait-" +"time` can now be passed to the `flower-client-app` command. `--max-" +"retries` will define the number of tentatives the client should make " +"before it gives up trying to reconnect to the SuperLink, and, `--max-" +"wait-time` defines the time before the SuperNode gives up trying to " +"reconnect to the SuperLink." msgstr "" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:57 msgid "" -"**Add new how-to guide for monitoring simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" +"**General updates to Flower Baselines** " +"([#2904](https://github.com/adap/flower/pull/2904), " +"[#2482](https://github.com/adap/flower/pull/2482), " +"[#2985](https://github.com/adap/flower/pull/2985), " +"[#2968](https://github.com/adap/flower/pull/2968))" msgstr "" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:59 msgid "" -"We now have a documentation guide to help users monitor their performance" -" during simulations." +"There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " +"baseline. Several other baselined have been updated as well." msgstr "" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:61 msgid "" -"**Add training metrics to** `History` **object during simulations** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**Improve documentation and translations** " +"([#3050](https://github.com/adap/flower/pull/3050), " +"[#3044](https://github.com/adap/flower/pull/3044), " +"[#3043](https://github.com/adap/flower/pull/3043), " +"[#2986](https://github.com/adap/flower/pull/2986), " +"[#3041](https://github.com/adap/flower/pull/3041), " +"[#3046](https://github.com/adap/flower/pull/3046), " +"[#3042](https://github.com/adap/flower/pull/3042), " +"[#2978](https://github.com/adap/flower/pull/2978), " +"[#2952](https://github.com/adap/flower/pull/2952), " +"[#3167](https://github.com/adap/flower/pull/3167), " +"[#2953](https://github.com/adap/flower/pull/2953), " +"[#3045](https://github.com/adap/flower/pull/3045), " +"[#2654](https://github.com/adap/flower/pull/2654), " +"[#3082](https://github.com/adap/flower/pull/3082), " +"[#2990](https://github.com/adap/flower/pull/2990), " +"[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:63 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training " -"metrics, but previous releases did not save the results in the `History` " -"object. This is now the case!" +"As usual, we merged many smaller and larger improvements to the " +"documentation. A special thank you goes to [Sebastian van der " +"Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:65 +msgid "" +"**General updates to Flower Examples** " +"([3134](https://github.com/adap/flower/pull/3134), " +"[2996](https://github.com/adap/flower/pull/2996), " +"[2930](https://github.com/adap/flower/pull/2930), " +"[2967](https://github.com/adap/flower/pull/2967), " +"[2467](https://github.com/adap/flower/pull/2467), " +"[2910](https://github.com/adap/flower/pull/2910), " +"[#2918](https://github.com/adap/flower/pull/2918), " +"[#2773](https://github.com/adap/flower/pull/2773), " +"[#3063](https://github.com/adap/flower/pull/3063), " +"[#3116](https://github.com/adap/flower/pull/3116), " +"[#3117](https://github.com/adap/flower/pull/3117))" +msgstr "" + +#: ../../source/ref-changelog.md:67 +msgid "" +"Two new examples show federated training of a Vision Transformer (ViT) " +"and federated learning in a medical context using the popular MONAI " +"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" +" new Flower Next `ServerApp` and `ClientApp`. Many other examples " +"received considerable updates as well." +msgstr "" + +#: ../../source/ref-changelog.md:69 msgid "" "**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" -msgstr "" - -#: ../../source/ref-changelog.md:350 -msgid "v1.3.0 (2023-02-06)" +"([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), " +"[3003](https://github.com/adap/flower/pull/3003), " +"[3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), " +"[3085](https://github.com/adap/flower/pull/3085), " +"[3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), " +"[2991](https://github.com/adap/flower/pull/2991), " +"[2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), " +"[3086](https://github.com/adap/flower/pull/3086), " +"[2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), " +"[2941](https://github.com/adap/flower/pull/2941), " +"[2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), " +"[2973](https://github.com/adap/flower/pull/2973), " +"[2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), " +"[3040](https://github.com/adap/flower/pull/3040), " +"[3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), " +"[2902](https://github.com/adap/flower/pull/2902), " +"[2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), " +"[3132](https://github.com/adap/flower/pull/3132), " +"[3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), " +"[3064](https://github.com/adap/flower/pull/3064), " +"[3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), " +"[3178](https://github.com/adap/flower/pull/3178), " +"[2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), " +"[3091](https://github.com/adap/flower/pull/3091), " +"[3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), " +"[3013](https://github.com/adap/flower/pull/3013), " +"[3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), " +"[3068](https://github.com/adap/flower/pull/3068), " +"[2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), " +"[2984](https://github.com/adap/flower/pull/2984), " +"[2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), " +"[3143](https://github.com/adap/flower/pull/3143), " +"[2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), " +"[2927](https://github.com/adap/flower/pull/2927), " +"[2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), " +"[2912](https://github.com/adap/flower/pull/2912), " +"[3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), " +"[2922](https://github.com/adap/flower/pull/2922), " +"[2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), " +"[3179](https://github.com/adap/flower/pull/3179), " +"[3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), " +"[3187](https://github.com/adap/flower/pull/3187), " +"[2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), " +"[3144](https://github.com/adap/flower/pull/3144), " +"[3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), " +"[#2836](https://github.com/adap/flower/pull/2836), " +"[#2929](https://github.com/adap/flower/pull/2929), " +"[#2943](https://github.com/adap/flower/pull/2943), " +"[#2955](https://github.com/adap/flower/pull/2955), " +"[#2954](https://github.com/adap/flower/pull/2954))" +msgstr "" + +#: ../../source/ref-changelog.md:75 +msgid "v1.7.0 (2024-02-05)" msgstr "" -#: ../../source/ref-changelog.md:356 +#: ../../source/ref-changelog.md:81 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " +"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " +"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " +"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " +"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " +"Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" -#: ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:85 msgid "" -"**Add support for** `workload_id` **and** `group_id` **in Driver API** " -"([#1595](https://github.com/adap/flower/pull/1595))" +"**Introduce stateful clients (experimental)** " +"([#2770](https://github.com/adap/flower/pull/2770), " +"[#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), " +"[#2643](https://github.com/adap/flower/pull/2643), " +"[#2769](https://github.com/adap/flower/pull/2769))" msgstr "" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:87 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be " -"used to identify which workload a task belongs to. It also supports a new" -" `group_id` that can be used, for example, to indicate the current " -"training round. Both the `workload_id` and `group_id` enable client nodes" -" to decide whether they want to handle a task or not." +"Subclasses of `Client` and `NumPyClient` can now store local state that " +"remains on the client. Let's start with the highlight first: this new " +"feature is compatible with both simulated clients (via " +"`start_simulation`) and networked clients (via `start_client`). It's also" +" the first preview of new abstractions like `Context` and `RecordSet`. " +"Clients can access state of type `RecordSet` via `state: RecordSet = " +"self.context.state`. Changes to this `RecordSet` are preserved across " +"different rounds of execution to enable stateful computations in a " +"unified way across simulation and deployment." msgstr "" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:89 msgid "" -"**Make Driver API and Fleet API address configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Improve performance** " +"([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:91 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) " -"can now configure the server address of both Driver API (via `--driver-" -"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" +"place aggregation to reduce memory consumption. The Flower client " +"serialization/deserialization has been rewritten from the ground up, " +"which results in significant speedups, especially when the client-side " +"training time is short." msgstr "" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:93 msgid "" -"`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " -"\"0.0.0.0:8086\"`" -msgstr "" - -#: ../../source/ref-changelog.md:370 -msgid "Both IPv4 and IPv6 addresses are supported." +"**Support Federated Learning with Apple MLX and Flower** " +"([#2693](https://github.com/adap/flower/pull/2693))" msgstr "" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:95 msgid "" -"**Add new example of Federated Learning using fastai and Flower** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"Flower has official support for federated learning using [Apple " +"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " +"example." msgstr "" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:97 msgid "" -"A new code example (`quickstart-fastai`) demonstrates federated learning " -"with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" -"/quickstart-fastai)." +"**Introduce new XGBoost cyclic strategy** " +"([#2666](https://github.com/adap/flower/pull/2666), " +"[#2668](https://github.com/adap/flower/pull/2668))" msgstr "" -#: ../../source/ref-changelog.md:376 +#: ../../source/ref-changelog.md:99 msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" -" versions of Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"A new strategy called `FedXgbCyclic` supports a client-by-client style of" +" training (often called cyclic). The `xgboost-comprehensive` code example" +" shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower " +"offers best-in-class XGBoost support." msgstr "" -#: ../../source/ref-changelog.md:378 +#: ../../source/ref-changelog.md:101 msgid "" -"The Android code example has received a substantial update: the project " -"is compatible with Flower 1.0 (and later), the UI received a full " -"refresh, and the project is updated to be compatible with newer Android " -"tooling." +"**Support Python 3.11** " +"([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" -#: ../../source/ref-changelog.md:380 +#: ../../source/ref-changelog.md:103 msgid "" -"**Add new `FedProx` strategy** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " +"ensure better support for users using more recent Python versions." msgstr "" -#: ../../source/ref-changelog.md:382 +#: ../../source/ref-changelog.md:105 msgid "" -"This " -"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" is almost identical to " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" but helps users replicate what is described in this " -"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " -"parameter called `proximal_mu` to regularize the local models with " -"respect to the global models." +"**Update gRPC and ProtoBuf dependencies** " +"([#2814](https://github.com/adap/flower/pull/2814))" msgstr "" -#: ../../source/ref-changelog.md:384 +#: ../../source/ref-changelog.md:107 msgid "" -"**Add new metrics to telemetry events** " -"([#1640](https://github.com/adap/flower/pull/1640))" +"The `grpcio` and `protobuf` dependencies were updated to their latest " +"versions for improved security and performance." msgstr "" -#: ../../source/ref-changelog.md:386 +#: ../../source/ref-changelog.md:109 msgid "" -"An updated event structure allows, for example, the clustering of events " -"within the same workload." +"**Introduce Docker image for Flower server** " +"([#2700](https://github.com/adap/flower/pull/2700), " +"[#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), " +"[#2695](https://github.com/adap/flower/pull/2695), " +"[#2747](https://github.com/adap/flower/pull/2747), " +"[#2746](https://github.com/adap/flower/pull/2746), " +"[#2680](https://github.com/adap/flower/pull/2680), " +"[#2682](https://github.com/adap/flower/pull/2682), " +"[#2701](https://github.com/adap/flower/pull/2701))" msgstr "" -#: ../../source/ref-changelog.md:388 +#: ../../source/ref-changelog.md:111 msgid "" -"**Add new custom strategy tutorial section** " -"[#1623](https://github.com/adap/flower/pull/1623)" +"The Flower server can now be run using an official Docker image. A new " +"how-to guide explains [how to run Flower using " +"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html). An official Flower client Docker image will follow." msgstr "" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:113 msgid "" -"The Flower tutorial now has a new section that covers implementing a " -"custom strategy from scratch: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"**Introduce** `flower-via-docker-compose` **example** " +"([#2626](https://github.com/adap/flower/pull/2626))" msgstr "" -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:115 msgid "" -"**Add new custom serialization tutorial section** " -"([#1622](https://github.com/adap/flower/pull/1622))" +"**Introduce** `quickstart-sklearn-tabular` **example** " +"([#2719](https://github.com/adap/flower/pull/2719))" msgstr "" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:117 msgid "" -"The Flower tutorial now has a new section that covers custom " -"serialization: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"**Introduce** `custom-metrics` **example** " +"([#1958](https://github.com/adap/flower/pull/1958))" msgstr "" -#: ../../source/ref-changelog.md:396 +#: ../../source/ref-changelog.md:119 msgid "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github.com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" +"**Update code examples to use Flower Datasets** " +"([#2450](https://github.com/adap/flower/pull/2450), " +"[#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), " +"[#2712](https://github.com/adap/flower/pull/2712))" msgstr "" -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:121 msgid "" -"**Updated documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" +"Several code examples were updated to use [Flower " +"Datasets](https://flower.ai/docs/datasets/)." msgstr "" -#: ../../source/ref-changelog.md:402 ../../source/ref-changelog.md:469 +#: ../../source/ref-changelog.md:123 msgid "" -"As usual, the documentation has improved quite a bit. It is another step " -"in our effort to make the Flower documentation the best documentation of " -"any project. Stay tuned and as always, feel free to provide feedback!" +"**General updates to Flower Examples** " +"([#2381](https://github.com/adap/flower/pull/2381), " +"[#2805](https://github.com/adap/flower/pull/2805), " +"[#2782](https://github.com/adap/flower/pull/2782), " +"[#2806](https://github.com/adap/flower/pull/2806), " +"[#2829](https://github.com/adap/flower/pull/2829), " +"[#2825](https://github.com/adap/flower/pull/2825), " +"[#2816](https://github.com/adap/flower/pull/2816), " +"[#2726](https://github.com/adap/flower/pull/2726), " +"[#2659](https://github.com/adap/flower/pull/2659), " +"[#2655](https://github.com/adap/flower/pull/2655))" msgstr "" -#: ../../source/ref-changelog.md:408 -msgid "v1.2.0 (2023-01-13)" +#: ../../source/ref-changelog.md:125 +msgid "Many Flower code examples received substantial updates." msgstr "" -#: ../../source/ref-changelog.md:414 -msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 +msgid "**Update Flower Baselines**" msgstr "" -#: ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:129 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " +"[#2771](https://github.com/adap/flower/pull/2771))" msgstr "" -#: ../../source/ref-changelog.md:420 -msgid "" -"Over the coming weeks, we will be releasing a number of new reference " -"implementations useful especially to FL newcomers. They will typically " -"revisit well known papers from the literature, and be suitable for " -"integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in " -"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" +#: ../../source/ref-changelog.md:130 +msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "" -#: ../../source/ref-changelog.md:422 -msgid "" -"**Improve GPU support in simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" +#: ../../source/ref-changelog.md:131 +msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "" -#: ../../source/ref-changelog.md:424 +#: ../../source/ref-changelog.md:132 +msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" +msgstr "" + +#: ../../source/ref-changelog.md:133 +msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" +msgstr "" + +#: ../../source/ref-changelog.md:134 +msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" +msgstr "" + +#: ../../source/ref-changelog.md:136 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" -" to improve GPU support. The update includes some of the hard-earned " -"lessons from scaling simulations in GPU cluster environments. New " -"defaults make running GPU-based simulations substantially more robust." +"**Improve documentation** " +"([#2674](https://github.com/adap/flower/pull/2674), " +"[#2480](https://github.com/adap/flower/pull/2480), " +"[#2826](https://github.com/adap/flower/pull/2826), " +"[#2727](https://github.com/adap/flower/pull/2727), " +"[#2761](https://github.com/adap/flower/pull/2761), " +"[#2900](https://github.com/adap/flower/pull/2900))" msgstr "" -#: ../../source/ref-changelog.md:426 +#: ../../source/ref-changelog.md:138 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" +"**Improved testing and development infrastructure** " +"([#2797](https://github.com/adap/flower/pull/2797), " +"[#2676](https://github.com/adap/flower/pull/2676), " +"[#2644](https://github.com/adap/flower/pull/2644), " +"[#2656](https://github.com/adap/flower/pull/2656), " +"[#2848](https://github.com/adap/flower/pull/2848), " +"[#2675](https://github.com/adap/flower/pull/2675), " +"[#2735](https://github.com/adap/flower/pull/2735), " +"[#2767](https://github.com/adap/flower/pull/2767), " +"[#2732](https://github.com/adap/flower/pull/2732), " +"[#2744](https://github.com/adap/flower/pull/2744), " +"[#2681](https://github.com/adap/flower/pull/2681), " +"[#2699](https://github.com/adap/flower/pull/2699), " +"[#2745](https://github.com/adap/flower/pull/2745), " +"[#2734](https://github.com/adap/flower/pull/2734), " +"[#2731](https://github.com/adap/flower/pull/2731), " +"[#2652](https://github.com/adap/flower/pull/2652), " +"[#2720](https://github.com/adap/flower/pull/2720), " +"[#2721](https://github.com/adap/flower/pull/2721), " +"[#2717](https://github.com/adap/flower/pull/2717), " +"[#2864](https://github.com/adap/flower/pull/2864), " +"[#2694](https://github.com/adap/flower/pull/2694), " +"[#2709](https://github.com/adap/flower/pull/2709), " +"[#2658](https://github.com/adap/flower/pull/2658), " +"[#2796](https://github.com/adap/flower/pull/2796), " +"[#2692](https://github.com/adap/flower/pull/2692), " +"[#2657](https://github.com/adap/flower/pull/2657), " +"[#2813](https://github.com/adap/flower/pull/2813), " +"[#2661](https://github.com/adap/flower/pull/2661), " +"[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" -#: ../../source/ref-changelog.md:428 +#: ../../source/ref-changelog.md:140 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to " -"use on GPU instances. We listened and made improvements to all of our " -"Jupyter notebooks! Check out the updated notebooks here:" +"The Flower testing and development infrastructure has received " +"substantial updates. This makes Flower 1.7 the most tested release ever." msgstr "" -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:142 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework" -"/tutorial-get-started-with-flower-pytorch.html)" +"**Update dependencies** " +"([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), " +"[#2739](https://github.com/adap/flower/pull/2739), " +"[#2837](https://github.com/adap/flower/pull/2837), " +"[#2788](https://github.com/adap/flower/pull/2788), " +"[#2811](https://github.com/adap/flower/pull/2811), " +"[#2774](https://github.com/adap/flower/pull/2774), " +"[#2790](https://github.com/adap/flower/pull/2790), " +"[#2751](https://github.com/adap/flower/pull/2751), " +"[#2850](https://github.com/adap/flower/pull/2850), " +"[#2812](https://github.com/adap/flower/pull/2812), " +"[#2872](https://github.com/adap/flower/pull/2872), " +"[#2736](https://github.com/adap/flower/pull/2736), " +"[#2756](https://github.com/adap/flower/pull/2756), " +"[#2857](https://github.com/adap/flower/pull/2857), " +"[#2757](https://github.com/adap/flower/pull/2757), " +"[#2810](https://github.com/adap/flower/pull/2810), " +"[#2740](https://github.com/adap/flower/pull/2740), " +"[#2789](https://github.com/adap/flower/pull/2789))" msgstr "" -#: ../../source/ref-changelog.md:431 +#: ../../source/ref-changelog.md:144 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework" -"/tutorial-use-a-federated-learning-strategy-pytorch.html)" +"**General improvements** " +"([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), " +"[#2877](https://github.com/adap/flower/pull/2877), " +"[#2690](https://github.com/adap/flower/pull/2690), " +"[#2889](https://github.com/adap/flower/pull/2889), " +"[#2874](https://github.com/adap/flower/pull/2874), " +"[#2819](https://github.com/adap/flower/pull/2819), " +"[#2689](https://github.com/adap/flower/pull/2689), " +"[#2457](https://github.com/adap/flower/pull/2457), " +"[#2870](https://github.com/adap/flower/pull/2870), " +"[#2669](https://github.com/adap/flower/pull/2669), " +"[#2876](https://github.com/adap/flower/pull/2876), " +"[#2885](https://github.com/adap/flower/pull/2885), " +"[#2858](https://github.com/adap/flower/pull/2858), " +"[#2867](https://github.com/adap/flower/pull/2867), " +"[#2351](https://github.com/adap/flower/pull/2351), " +"[#2886](https://github.com/adap/flower/pull/2886), " +"[#2860](https://github.com/adap/flower/pull/2860), " +"[#2828](https://github.com/adap/flower/pull/2828), " +"[#2869](https://github.com/adap/flower/pull/2869), " +"[#2875](https://github.com/adap/flower/pull/2875), " +"[#2733](https://github.com/adap/flower/pull/2733), " +"[#2488](https://github.com/adap/flower/pull/2488), " +"[#2646](https://github.com/adap/flower/pull/2646), " +"[#2879](https://github.com/adap/flower/pull/2879), " +"[#2821](https://github.com/adap/flower/pull/2821), " +"[#2855](https://github.com/adap/flower/pull/2855), " +"[#2800](https://github.com/adap/flower/pull/2800), " +"[#2807](https://github.com/adap/flower/pull/2807), " +"[#2801](https://github.com/adap/flower/pull/2801), " +"[#2804](https://github.com/adap/flower/pull/2804), " +"[#2851](https://github.com/adap/flower/pull/2851), " +"[#2787](https://github.com/adap/flower/pull/2787), " +"[#2852](https://github.com/adap/flower/pull/2852), " +"[#2672](https://github.com/adap/flower/pull/2672), " +"[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:148 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" -"-strategy-from-scratch-pytorch.html)" +"**Deprecate** `start_numpy_client` " +"([#2563](https://github.com/adap/flower/pull/2563), " +"[#2718](https://github.com/adap/flower/pull/2718))" msgstr "" -#: ../../source/ref-changelog.md:433 +#: ../../source/ref-changelog.md:150 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" -"customize-the-client-pytorch.html)" +"Until now, clients of type `NumPyClient` needed to be started via " +"`start_numpy_client`. In our efforts to consolidate framework APIs, we " +"have introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need " +"to first call the `.to_client()` method and then pass returned `Client` " +"object to `start_client`. The examples and the documentation have been " +"updated accordingly." msgstr "" -#: ../../source/ref-changelog.md:435 +#: ../../source/ref-changelog.md:152 msgid "" -"**Introduce optional telemetry** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" +"**Deprecate legacy DP wrappers** " +"([#2749](https://github.com/adap/flower/pull/2749))" msgstr "" -#: ../../source/ref-changelog.md:437 +#: ../../source/ref-changelog.md:154 msgid "" -"After a [request for " -"feedback](https://github.com/adap/flower/issues/1534) from the community," -" the Flower open-source project introduces optional collection of " -"*anonymous* usage metrics to make well-informed decisions to improve " -"Flower. Doing this enables the Flower team to understand how Flower is " -"used and what challenges users might face." +"Legacy DP wrapper classes are deprecated, but still functional. This is " +"in preparation for an all-new pluggable version of differential privacy " +"support in Flower." msgstr "" -#: ../../source/ref-changelog.md:439 +#: ../../source/ref-changelog.md:156 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users who do not want to share anonymous usage metrics. " -"[Read more.](https://flower.ai/docs/telemetry.html)." +"**Make optional arg** `--callable` **in** `flower-client` **a required " +"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" -#: ../../source/ref-changelog.md:441 +#: ../../source/ref-changelog.md:158 msgid "" -"**Introduce (experimental) Driver API** " -"([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " +"([#2890](https://github.com/adap/flower/pull/2890))" msgstr "" -#: ../../source/ref-changelog.md:443 +#: ../../source/ref-changelog.md:160 msgid "" -"Flower now has a new (experimental) Driver API which will enable fully " -"programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API" -" will be the abstraction that many upcoming features will be built on - " -"and you can start building those things now, too." +"**Drop experimental** `Task` **fields** " +"([#2866](https://github.com/adap/flower/pull/2866), " +"[#2865](https://github.com/adap/flower/pull/2865))" msgstr "" -#: ../../source/ref-changelog.md:445 +#: ../../source/ref-changelog.md:162 msgid "" -"The Driver API also enables a new execution mode in which the server runs" -" indefinitely. Multiple individual workloads can run concurrently and " -"start and stop their execution independent of the server. This is " -"especially useful for users who want to deploy Flower in production." +"Experimental fields `sa`, `legacy_server_message` and " +"`legacy_client_message` were removed from `Task` message. The removed " +"fields are superseded by the new `RecordSet` abstraction." msgstr "" -#: ../../source/ref-changelog.md:447 +#: ../../source/ref-changelog.md:164 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward " -"to you feedback!" +"**Retire MXNet examples** " +"([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" -#: ../../source/ref-changelog.md:449 +#: ../../source/ref-changelog.md:166 msgid "" -"Please note: *The Driver API is still experimental and will likely change" -" significantly over time.*" +"The development of the MXNet fremework has ended and the project is now " +"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " +"examples won't receive updates." +msgstr "" + +#: ../../source/ref-changelog.md:168 +msgid "v1.6.0 (2023-11-28)" msgstr "" -#: ../../source/ref-changelog.md:451 +#: ../../source/ref-changelog.md:174 msgid "" -"**Add new Federated Analytics with Pandas example** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " +"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," +" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " +"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " +"`cnxdeveloper`, `k3nfalt` " msgstr "" -#: ../../source/ref-changelog.md:453 +#: ../../source/ref-changelog.md:178 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics" -" with Pandas and Flower. You can find it here: [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." +"**Add experimental support for Python 3.12** " +"([#2565](https://github.com/adap/flower/pull/2565))" msgstr "" -#: ../../source/ref-changelog.md:455 +#: ../../source/ref-changelog.md:180 msgid "" -"**Add new strategies: Krum and MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"**Add new XGBoost examples** " +"([#2612](https://github.com/adap/flower/pull/2612), " +"[#2554](https://github.com/adap/flower/pull/2554), " +"[#2617](https://github.com/adap/flower/pull/2617), " +"[#2618](https://github.com/adap/flower/pull/2618), " +"[#2619](https://github.com/adap/flower/pull/2619), " +"[#2567](https://github.com/adap/flower/pull/2567))" msgstr "" -#: ../../source/ref-changelog.md:457 +#: ../../source/ref-changelog.md:182 msgid "" -"Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum " -"and MultiKrum in their workloads." +"We have added a new `xgboost-quickstart` example alongside a new " +"`xgboost-comprehensive` example that goes more in-depth." msgstr "" -#: ../../source/ref-changelog.md:459 +#: ../../source/ref-changelog.md:184 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"**Add Vertical FL example** " +"([#2598](https://github.com/adap/flower/pull/2598))" msgstr "" -#: ../../source/ref-changelog.md:461 +#: ../../source/ref-changelog.md:186 msgid "" -"The C++ code example has received a substantial update to make it " -"compatible with the latest version of Flower." +"We had many questions about Vertical Federated Learning using Flower, so " +"we decided to add an simple example for it on the [Titanic " +"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " +"tutorial (in the README)." msgstr "" -#: ../../source/ref-changelog.md:463 +#: ../../source/ref-changelog.md:188 msgid "" -"**General improvements** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**Support custom** `ClientManager` **in** `start_driver()` " +"([#2292](https://github.com/adap/flower/pull/2292))" msgstr "" -#: ../../source/ref-changelog.md:467 +#: ../../source/ref-changelog.md:190 msgid "" -"**Updated documentation** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" +"**Update REST API to support create and delete nodes** " +"([#2283](https://github.com/adap/flower/pull/2283))" msgstr "" -#: ../../source/ref-changelog.md:471 +#: ../../source/ref-changelog.md:192 msgid "" -"One highlight is the new [first time contributor " -"guide](https://flower.ai/docs/first-time-contributors.html): if you've " -"never contributed on GitHub before, this is the perfect place to start!" +"**Update the Android SDK** " +"([#2187](https://github.com/adap/flower/pull/2187))" msgstr "" -#: ../../source/ref-changelog.md:477 -msgid "v1.1.0 (2022-10-31)" +#: ../../source/ref-changelog.md:194 +msgid "Add gRPC request-response capability to the Android SDK." msgstr "" -#: ../../source/ref-changelog.md:481 +#: ../../source/ref-changelog.md:196 msgid "" -"We would like to give our **special thanks** to all the contributors who " -"made the new version of Flower possible (in `git shortlog` order):" +"**Update the C++ SDK** " +"([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" msgstr "" -#: ../../source/ref-changelog.md:483 -msgid "" -"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " -"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +#: ../../source/ref-changelog.md:198 +msgid "Add gRPC request-response capability to the C++ SDK." msgstr "" -#: ../../source/ref-changelog.md:487 +#: ../../source/ref-changelog.md:200 msgid "" -"**Introduce Differential Privacy wrappers (preview)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"**Make HTTPS the new default** " +"([#2591](https://github.com/adap/flower/pull/2591), " +"[#2636](https://github.com/adap/flower/pull/2636))" msgstr "" -#: ../../source/ref-changelog.md:489 +#: ../../source/ref-changelog.md:202 msgid "" -"The first (experimental) preview of pluggable Differential Privacy " -"wrappers enables easy configuration and usage of differential privacy " -"(DP). The pluggable DP wrappers enable framework-agnostic **and** " -"strategy-agnostic usage of both client-side DP and server-side DP. Head " -"over to the Flower docs, a new explainer goes into more detail." +"Flower is moving to HTTPS by default. The new `flower-server` requires " +"passing `--certificates`, but users can enable `--insecure` to use HTTP " +"for prototyping. The same applies to `flower-client`, which can either " +"use user-provided credentials or gRPC-bundled certificates to connect to " +"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " +"enable insecure HTTP connections." msgstr "" -#: ../../source/ref-changelog.md:491 +#: ../../source/ref-changelog.md:204 msgid "" -"**New iOS CoreML code example** " -"([#1289](https://github.com/adap/flower/pull/1289))" +"For backward compatibility, `start_client()` and `start_numpy_client()` " +"will still start in insecure mode by default. In a future release, " +"insecure connections will require user opt-in by passing `insecure=True`." msgstr "" -#: ../../source/ref-changelog.md:493 +#: ../../source/ref-changelog.md:206 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can " -"be built for iOS. The code example contains both Flower iOS SDK " -"components that can be used for many tasks, and one task example running " -"on CoreML." +"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" msgstr "" -#: ../../source/ref-changelog.md:495 +#: ../../source/ref-changelog.md:208 msgid "" -"**New FedMedian strategy** " -"([#1461](https://github.com/adap/flower/pull/1461))" +"Using the `client_fn`, Flower clients can interchangeably run as " +"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" +" `start_simulation`) without requiring changes to how the client class is" +" defined and instantiated. The `to_client()` function is introduced to " +"convert a `NumPyClient` to a `Client`." msgstr "" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:210 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by " -"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"**Add new** `Bulyan` **strategy** " +"([#1817](https://github.com/adap/flower/pull/1817), " +"[#1891](https://github.com/adap/flower/pull/1891))" msgstr "" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:212 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** " -"([#1493](https://github.com/adap/flower/pull/1493))" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " +"2018](https://arxiv.org/abs/1802.07927)" msgstr "" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:214 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default " -"and not just exposed to the configured `Strategy` (via the `failures` " -"argument)." +"**Add new** `XGB Bagging` **strategy** " +"([#2611](https://github.com/adap/flower/pull/2611))" msgstr "" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 msgid "" -"**Improve Virtual Client Engine internals** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" +"**Introduce `WorkloadState`** " +"([#2564](https://github.com/adap/flower/pull/2564), " +"[#2632](https://github.com/adap/flower/pull/2632))" msgstr "" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:222 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE " -"now uses Ray 2.0 under the hood, the value type of the `client_resources`" -" dictionary changed to `float` to allow fractions of resources to be " -"allocated." +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " +"[#2286](https://github.com/adap/flower/pull/2286), " +"[#2509](https://github.com/adap/flower/pull/2509))" msgstr "" -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:224 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400))" msgstr "" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:226 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and" -" `NumPyClient`) methods." +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " +"[#2507](https://github.com/adap/flower/pull/2507))" msgstr "" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:228 msgid "" -"**Provide type information to packages using** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" msgstr "" -#: ../../source/ref-changelog.md:513 -msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that " -"the package is typed. This enables typing support for projects or " -"packages that use `flwr` by enabling them to improve their code using " -"static type checkers like `mypy`." +#: ../../source/ref-changelog.md:230 +msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "" -#: ../../source/ref-changelog.md:515 -msgid "" -"**Updated code example** " -"([#1344](https://github.com/adap/flower/pull/1344), " -"[#1347](https://github.com/adap/flower/pull/1347))" +#: ../../source/ref-changelog.md:232 +msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "" -#: ../../source/ref-changelog.md:517 -msgid "" -"The code examples covering scikit-learn and PyTorch Lightning have been " -"updated to work with the latest version of Flower." +#: ../../source/ref-changelog.md:234 +msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "" -#: ../../source/ref-changelog.md:519 -msgid "" -"**Updated documentation** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +#: ../../source/ref-changelog.md:236 +msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "" -#: ../../source/ref-changelog.md:521 -msgid "" -"There have been so many documentation updates that it doesn't even make " -"sense to list them individually." +#: ../../source/ref-changelog.md:238 +msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "" -#: ../../source/ref-changelog.md:523 -msgid "" -"**Restructured documentation** " -"([#1387](https://github.com/adap/flower/pull/1387))" +#: ../../source/ref-changelog.md:240 +msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "" -#: ../../source/ref-changelog.md:525 -msgid "" -"The documentation has been restructured to make it easier to navigate. " -"This is just the first step in a larger effort to make the Flower " -"documentation the best documentation of any project ever. Stay tuned!" +#: ../../source/ref-changelog.md:242 +msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:244 msgid "" -"**Open in Colab button** " -"([#1389](https://github.com/adap/flower/pull/1389))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" msgstr "" -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:246 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a " -"new `Open in Colab` button. No need to install anything on your local " -"machine, you can now use and learn about Flower in your browser, it's " -"only a single click away." +"**General updates to Flower Examples** " +"([#2384](https://github.com/adap/flower/pull/2384), " +"[#2425](https://github.com/adap/flower/pull/2425), " +"[#2526](https://github.com/adap/flower/pull/2526), " +"[#2302](https://github.com/adap/flower/pull/2302), " +"[#2545](https://github.com/adap/flower/pull/2545))" msgstr "" -#: ../../source/ref-changelog.md:531 +#: ../../source/ref-changelog.md:248 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"**General updates to Flower Baselines** " +"([#2301](https://github.com/adap/flower/pull/2301), " +"[#2305](https://github.com/adap/flower/pull/2305), " +"[#2307](https://github.com/adap/flower/pull/2307), " +"[#2327](https://github.com/adap/flower/pull/2327), " +"[#2435](https://github.com/adap/flower/pull/2435), " +"[#2462](https://github.com/adap/flower/pull/2462), " +"[#2463](https://github.com/adap/flower/pull/2463), " +"[#2461](https://github.com/adap/flower/pull/2461), " +"[#2469](https://github.com/adap/flower/pull/2469), " +"[#2466](https://github.com/adap/flower/pull/2466), " +"[#2471](https://github.com/adap/flower/pull/2471), " +"[#2472](https://github.com/adap/flower/pull/2472), " +"[#2470](https://github.com/adap/flower/pull/2470))" msgstr "" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:250 msgid "" -"The Flower Federated Learning Tutorial has two brand-new parts covering " -"custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved " -"(many small changes and fixes)." +"**General updates to the simulation engine** " +"([#2331](https://github.com/adap/flower/pull/2331), " +"[#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), " +"[#2294](https://github.com/adap/flower/pull/2294))" msgstr "" -#: ../../source/ref-changelog.md:539 -msgid "v1.0.0 (2022-07-28)" +#: ../../source/ref-changelog.md:252 +msgid "" +"**General updates to Flower SDKs** " +"([#2288](https://github.com/adap/flower/pull/2288), " +"[#2429](https://github.com/adap/flower/pull/2429), " +"[#2555](https://github.com/adap/flower/pull/2555), " +"[#2543](https://github.com/adap/flower/pull/2543), " +"[#2544](https://github.com/adap/flower/pull/2544), " +"[#2597](https://github.com/adap/flower/pull/2597), " +"[#2623](https://github.com/adap/flower/pull/2623))" msgstr "" -#: ../../source/ref-changelog.md:541 -msgid "Highlights" +#: ../../source/ref-changelog.md:254 +msgid "" +"**General improvements** " +"([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), " +"[#2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[#2317](https://github.com/adap/flower/pull/2317), " +"[#2349](https://github.com/adap/flower/pull/2349), " +"[#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446), " +"[#2561](https://github.com/adap/flower/pull/2561), " +"[#2273](https://github.com/adap/flower/pull/2273), " +"[#2267](https://github.com/adap/flower/pull/2267), " +"[#2274](https://github.com/adap/flower/pull/2274), " +"[#2275](https://github.com/adap/flower/pull/2275), " +"[#2432](https://github.com/adap/flower/pull/2432), " +"[#2251](https://github.com/adap/flower/pull/2251), " +"[#2321](https://github.com/adap/flower/pull/2321), " +"[#1936](https://github.com/adap/flower/pull/1936), " +"[#2408](https://github.com/adap/flower/pull/2408), " +"[#2413](https://github.com/adap/flower/pull/2413), " +"[#2401](https://github.com/adap/flower/pull/2401), " +"[#2531](https://github.com/adap/flower/pull/2531), " +"[#2534](https://github.com/adap/flower/pull/2534), " +"[#2535](https://github.com/adap/flower/pull/2535), " +"[#2521](https://github.com/adap/flower/pull/2521), " +"[#2553](https://github.com/adap/flower/pull/2553), " +"[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" -#: ../../source/ref-changelog.md:543 -msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" +#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 +#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 +#: ../../source/ref-changelog.md:531 +msgid "Flower received many improvements under the hood, too many to list here." msgstr "" -#: ../../source/ref-changelog.md:544 -msgid "All `Client`/`NumPyClient` methods are now optional" +#: ../../source/ref-changelog.md:260 +msgid "" +"**Remove support for Python 3.7** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" msgstr "" -#: ../../source/ref-changelog.md:545 -msgid "Configurable `get_parameters`" +#: ../../source/ref-changelog.md:262 +msgid "" +"Python 3.7 support was deprecated in Flower 1.5, and this release removes" +" support. Flower now requires Python 3.8." msgstr "" -#: ../../source/ref-changelog.md:546 +#: ../../source/ref-changelog.md:264 msgid "" -"Tons of small API cleanups resulting in a more coherent developer " -"experience" +"**Remove experimental argument** `rest` **from** `start_client` " +"([#2324](https://github.com/adap/flower/pull/2324))" msgstr "" -#: ../../source/ref-changelog.md:550 +#: ../../source/ref-changelog.md:266 msgid "" -"We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +"The (still experimental) argument `rest` was removed from `start_client` " +"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " +"experimental REST API instead." +msgstr "" + +#: ../../source/ref-changelog.md:268 +msgid "v1.5.0 (2023-08-31)" msgstr "" -#: ../../source/ref-changelog.md:552 +#: ../../source/ref-changelog.md:274 msgid "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " msgstr "" -#: ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:278 msgid "" -"**All arguments must be passed as keyword arguments** " -"([#1338](https://github.com/adap/flower/pull/1338))" +"**Introduce new simulation engine** " +"([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" msgstr "" -#: ../../source/ref-changelog.md:558 +#: ../../source/ref-changelog.md:280 msgid "" -"Pass all arguments as keyword arguments, positional arguments are not " -"longer supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " -"for each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"The new simulation engine has been rewritten from the ground up, yet it " +"remains fully backwards compatible. It offers much improved stability and" +" memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-" +"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -#: ../../source/ref-changelog.md:560 +#: ../../source/ref-changelog.md:282 msgid "" -"**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" +"Comprehensive documentation includes a new [how-to run " +"simulations](https://flower.ai/docs/framework/how-to-run-" +"simulations.html) guide, new [simulation-" +"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " +"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" +"tensorflow.html) notebooks, and a new [YouTube tutorial " +"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" -#: ../../source/ref-changelog.md:562 +#: ../../source/ref-changelog.md:284 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " -"600.0}`, `start_server` and `start_simulation` now expect a configuration" -" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" -" arguments that as the previous config dict, but it makes writing type-" -"safe code easier and the default parameters values more transparent." +"**Restructure Flower Docs** " +"([#1824](https://github.com/adap/flower/pull/1824), " +"[#1865](https://github.com/adap/flower/pull/1865), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1887](https://github.com/adap/flower/pull/1887), " +"[#1919](https://github.com/adap/flower/pull/1919), " +"[#1922](https://github.com/adap/flower/pull/1922), " +"[#1920](https://github.com/adap/flower/pull/1920), " +"[#1923](https://github.com/adap/flower/pull/1923), " +"[#1924](https://github.com/adap/flower/pull/1924), " +"[#1962](https://github.com/adap/flower/pull/1962), " +"[#2006](https://github.com/adap/flower/pull/2006), " +"[#2133](https://github.com/adap/flower/pull/2133), " +"[#2203](https://github.com/adap/flower/pull/2203), " +"[#2215](https://github.com/adap/flower/pull/2215), " +"[#2122](https://github.com/adap/flower/pull/2122), " +"[#2223](https://github.com/adap/flower/pull/2223), " +"[#2219](https://github.com/adap/flower/pull/2219), " +"[#2232](https://github.com/adap/flower/pull/2232), " +"[#2233](https://github.com/adap/flower/pull/2233), " +"[#2234](https://github.com/adap/flower/pull/2234), " +"[#2235](https://github.com/adap/flower/pull/2235), " +"[#2237](https://github.com/adap/flower/pull/2237), " +"[#2238](https://github.com/adap/flower/pull/2238), " +"[#2242](https://github.com/adap/flower/pull/2242), " +"[#2231](https://github.com/adap/flower/pull/2231), " +"[#2243](https://github.com/adap/flower/pull/2243), " +"[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" -#: ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:286 msgid "" -"**Rename built-in strategy parameters for clarity** " -"([#1334](https://github.com/adap/flower/pull/1334))" +"Much effort went into a completely restructured Flower docs experience. " +"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " +"divided into Flower Framework, Flower Baselines, Flower Android SDK, " +"Flower iOS SDK, and code example projects." msgstr "" -#: ../../source/ref-changelog.md:566 +#: ../../source/ref-changelog.md:288 msgid "" -"The following built-in strategy parameters were renamed to improve " -"readability and consistency with other API's:" +"**Introduce Flower Swift SDK** " +"([#1858](https://github.com/adap/flower/pull/1858), " +"[#1897](https://github.com/adap/flower/pull/1897))" msgstr "" -#: ../../source/ref-changelog.md:568 -msgid "`fraction_eval` --> `fraction_evaluate`" +#: ../../source/ref-changelog.md:290 +msgid "" +"This is the first preview release of the Flower Swift SDK. Flower support" +" on iOS is improving, and alongside the Swift SDK and code example, there" +" is now also an iOS quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:569 -msgid "`min_eval_clients` --> `min_evaluate_clients`" +#: ../../source/ref-changelog.md:292 +msgid "" +"**Introduce Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" msgstr "" -#: ../../source/ref-changelog.md:570 -msgid "`eval_fn` --> `evaluate_fn`" +#: ../../source/ref-changelog.md:294 +msgid "" +"This is the first preview release of the Flower Kotlin SDK. Flower " +"support on Android is improving, and alongside the Kotlin SDK and code " +"example, there is now also an Android quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:572 +#: ../../source/ref-changelog.md:296 msgid "" -"**Update default arguments of built-in strategies** " -"([#1278](https://github.com/adap/flower/pull/1278))" +"**Introduce new end-to-end testing infrastructure** " +"([#1842](https://github.com/adap/flower/pull/1842), " +"[#2071](https://github.com/adap/flower/pull/2071), " +"[#2072](https://github.com/adap/flower/pull/2072), " +"[#2068](https://github.com/adap/flower/pull/2068), " +"[#2067](https://github.com/adap/flower/pull/2067), " +"[#2069](https://github.com/adap/flower/pull/2069), " +"[#2073](https://github.com/adap/flower/pull/2073), " +"[#2070](https://github.com/adap/flower/pull/2070), " +"[#2074](https://github.com/adap/flower/pull/2074), " +"[#2082](https://github.com/adap/flower/pull/2082), " +"[#2084](https://github.com/adap/flower/pull/2084), " +"[#2093](https://github.com/adap/flower/pull/2093), " +"[#2109](https://github.com/adap/flower/pull/2109), " +"[#2095](https://github.com/adap/flower/pull/2095), " +"[#2140](https://github.com/adap/flower/pull/2140), " +"[#2137](https://github.com/adap/flower/pull/2137), " +"[#2165](https://github.com/adap/flower/pull/2165))" msgstr "" -#: ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:298 msgid "" -"All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently " -"available clients for training and evaluation. Projects that relied on " -"the previous default values can get the previous behaviour by " -"initializing the strategy in the following way:" +"A new testing infrastructure ensures that new changes stay compatible " +"with existing framework integrations or strategies." msgstr "" -#: ../../source/ref-changelog.md:576 -msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" +#: ../../source/ref-changelog.md:300 +msgid "**Deprecate Python 3.7**" msgstr "" -#: ../../source/ref-changelog.md:578 +#: ../../source/ref-changelog.md:302 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" +" Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" -#: ../../source/ref-changelog.md:580 +#: ../../source/ref-changelog.md:304 msgid "" -"The `Strategy` method `evaluate` now receives the current round of " -"federated learning/evaluation as the first parameter." +"**Add new** `FedTrimmedAvg` **strategy** " +"([#1769](https://github.com/adap/flower/pull/1769), " +"[#1853](https://github.com/adap/flower/pull/1853))" msgstr "" -#: ../../source/ref-changelog.md:582 +#: ../../source/ref-changelog.md:306 msgid "" -"**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " +"2018](https://arxiv.org/abs/1803.01498)." msgstr "" -#: ../../source/ref-changelog.md:584 +#: ../../source/ref-changelog.md:308 msgid "" -"The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " -"three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), " -"and (3) a config dictionary (`config`)." +"**Introduce start_driver** " +"([#1697](https://github.com/adap/flower/pull/1697))" msgstr "" -#: ../../source/ref-changelog.md:586 +#: ../../source/ref-changelog.md:310 msgid "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"In addition to `start_server` and using the raw Driver API, there is a " +"new `start_driver` function that allows for running `start_server` " +"scripts as a Flower driver with only a single-line code change. Check out" +" the `mt-pytorch` code example to see a working example using " +"`start_driver`." msgstr "" -#: ../../source/ref-changelog.md:588 +#: ../../source/ref-changelog.md:312 msgid "" -"Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " -"`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. " -"To improve reaability and avoid confusion with *random*, this parameter " -"has been renamed from `rnd` to `server_round`." +"**Add parameter aggregation to** `mt-pytorch` **code example** " +"([#1785](https://github.com/adap/flower/pull/1785))" msgstr "" -#: ../../source/ref-changelog.md:590 +#: ../../source/ref-changelog.md:314 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" -msgstr "" - -#: ../../source/ref-changelog.md:592 -msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." +"The `mt-pytorch` example shows how to aggregate parameters when writing a" +" driver script. The included `driver.py` and `server.py` have been " +"aligned to demonstrate both the low-level way and the high-level way of " +"building server-side logic." msgstr "" -#: ../../source/ref-changelog.md:594 +#: ../../source/ref-changelog.md:316 msgid "" -"**Remove experimental strategies** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Migrate experimental REST API to Starlette** " +"([2171](https://github.com/adap/flower/pull/2171))" msgstr "" -#: ../../source/ref-changelog.md:596 +#: ../../source/ref-changelog.md:318 msgid "" -"Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " -"`FedFSv1`)." +"The (experimental) REST API used to be implemented in " +"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" +" use [Starlette](https://www.starlette.io/) directly." msgstr "" -#: ../../source/ref-changelog.md:598 +#: ../../source/ref-changelog.md:320 msgid "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"Please note: The REST request-response API is still experimental and will" +" likely change significantly over time." msgstr "" -#: ../../source/ref-changelog.md:600 +#: ../../source/ref-changelog.md:322 msgid "" -"`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " -"capture what this type is all about." +"**Introduce experimental gRPC request-response API** " +"([#1867](https://github.com/adap/flower/pull/1867), " +"[#1901](https://github.com/adap/flower/pull/1901))" msgstr "" -#: ../../source/ref-changelog.md:602 +#: ../../source/ref-changelog.md:324 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"In addition to the existing gRPC API (based on bidirectional streaming) " +"and the experimental REST API, there is now a new gRPC API that uses a " +"request-response model to communicate with client nodes." msgstr "" -#: ../../source/ref-changelog.md:604 +#: ../../source/ref-changelog.md:326 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been" -" a historic artefact, in this release it is finally gone for good." +"Please note: The gRPC request-response API is still experimental and will" +" likely change significantly over time." msgstr "" -#: ../../source/ref-changelog.md:606 +#: ../../source/ref-changelog.md:328 msgid "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Replace the experimental** `start_client(rest=True)` **with the new** " +"`start_client(transport=\"rest\")` " +"([#1880](https://github.com/adap/flower/pull/1880))" msgstr "" -#: ../../source/ref-changelog.md:608 +#: ../../source/ref-changelog.md:330 msgid "" -"The `get_parameters` method now accepts a configuration dictionary, just " -"like `get_properties`, `fit`, and `evaluate`." +"The (experimental) `start_client` argument `rest` was deprecated in " +"favour of a new argument `transport`. `start_client(transport=\"rest\")` " +"will yield the same behaviour as `start_client(rest=True)` did before. " +"All code should migrate to the new argument `transport`. The deprecated " +"argument `rest` will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:332 msgid "" -"**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " -"**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" +"**Add a new gRPC option** " +"([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:334 msgid "" -"The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the " -"consistency between `start_simulation` and `start_server` and makes " -"transitioning between the two easier." +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" +" option set to 0 by default. This prevents the clients from sending " +"keepalive pings when there is no outstanding stream." msgstr "" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:336 msgid "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +"**Improve example notebooks** " +"([#2005](https://github.com/adap/flower/pull/2005))" msgstr "" -#: ../../source/ref-changelog.md:618 -msgid "" -"The previous Flower release introduced experimental support for Python " -"3.10, this release declares Python 3.10 support as stable." +#: ../../source/ref-changelog.md:338 +msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "" -#: ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:340 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" msgstr "" -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:342 msgid "" -"The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that" -" implement, for example, only `fit`, but no other method. No need to " -"implement `evaluate` when using centralized evaluation!" +"Many examples have received significant updates, including simplified " +"advanced-tensorflow and advanced-pytorch examples, improved macOS " +"compatibility of TensorFlow examples, and code examples for simulation. A" +" major upgrade is that all code examples now have a `requirements.txt` " +"(in addition to `pyproject.toml`)." msgstr "" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:344 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**General improvements** " +"([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" msgstr "" -#: ../../source/ref-changelog.md:626 -msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server`" -" instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the" -" Virtual Client Engine." +#: ../../source/ref-changelog.md:352 +msgid "v1.4.0 (2023-04-21)" msgstr "" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:358 msgid "" -"**Update code examples** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:362 msgid "" -"Many code examples received small or even large maintenance updates, " -"among them are" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " +"example)** ([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" msgstr "" -#: ../../source/ref-changelog.md:632 -msgid "`scikit-learn`" +#: ../../source/ref-changelog.md:364 +msgid "" +"XGBoost is a tree-based ensemble machine learning algorithm that uses " +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" +" " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," +" and a [code example](https://github.com/adap/flower/tree/main/examples" +"/xgboost-quickstart) that demonstrates the usage of this new strategy in " +"an XGBoost project." msgstr "" -#: ../../source/ref-changelog.md:633 -msgid "`simulation_pytorch`" +#: ../../source/ref-changelog.md:366 +msgid "" +"**Introduce iOS SDK (preview)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" msgstr "" -#: ../../source/ref-changelog.md:634 -msgid "`quickstart_pytorch`" +#: ../../source/ref-changelog.md:368 +msgid "" +"This is a major update for anyone wanting to implement Federated Learning" +" on iOS mobile devices. We now have a swift iOS SDK present under " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" that will facilitate greatly the app creating process. To showcase its " +"use, the [iOS " +"example](https://github.com/adap/flower/tree/main/examples/ios) has also " +"been updated!" msgstr "" -#: ../../source/ref-changelog.md:635 -msgid "`quickstart_simulation`" +#: ../../source/ref-changelog.md:370 +msgid "" +"**Introduce new \"What is Federated Learning?\" tutorial** " +"([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721))" msgstr "" -#: ../../source/ref-changelog.md:636 -msgid "`quickstart_tensorflow`" +#: ../../source/ref-changelog.md:372 +msgid "" +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" +"what-is-federated-learning.html) in our documentation explains the basics" +" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" +" Learning to start their journey with Flower. Forward it to anyone who's " +"interested in Federated Learning!" msgstr "" -#: ../../source/ref-changelog.md:637 -msgid "`advanced_tensorflow`" +#: ../../source/ref-changelog.md:374 +msgid "" +"**Introduce new Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" msgstr "" -#: ../../source/ref-changelog.md:639 +#: ../../source/ref-changelog.md:376 msgid "" -"**Remove the obsolete simulation example** " -"([#1328](https://github.com/adap/flower/pull/1328))" +"This new baseline replicates the MNIST+CNN task from the paper [Federated" +" Optimization in Heterogeneous Networks (Li et al., " +"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," +" which aims at making convergence more robust in heterogeneous settings." msgstr "" -#: ../../source/ref-changelog.md:641 +#: ../../source/ref-changelog.md:378 msgid "" -"Removes the obsolete `simulation` example and renames " -"`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " -"naming of `simulation_pytorch`" +"**Introduce new Flower Baseline: FedAvg FEMNIST** " +"([#1655](https://github.com/adap/flower/pull/1655))" msgstr "" -#: ../../source/ref-changelog.md:643 +#: ../../source/ref-changelog.md:380 msgid "" -"**Update documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"This new baseline replicates an experiment evaluating the performance of " +"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " +"Benchmark for Federated Settings (Caldas et al., " +"2018)](https://arxiv.org/abs/1812.01097)." msgstr "" -#: ../../source/ref-changelog.md:645 +#: ../../source/ref-changelog.md:382 msgid "" -"One substantial documentation update fixes multiple smaller rendering " -"issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the " -"`flwr.common` module in the API reference, includes support for markdown-" -"based documentation, migrates the changelog from `.rst` to `.md`, and " -"fixes a number of smaller details!" +"**Introduce (experimental) REST API** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" msgstr "" -#: ../../source/ref-changelog.md:647 ../../source/ref-changelog.md:702 -#: ../../source/ref-changelog.md:771 ../../source/ref-changelog.md:810 -msgid "**Minor updates**" +#: ../../source/ref-changelog.md:384 +msgid "" +"A new REST API has been introduced as an alternative to the gRPC-based " +"communication stack. In this initial version, the REST API only supports " +"anonymous clients." msgstr "" -#: ../../source/ref-changelog.md:649 +#: ../../source/ref-changelog.md:386 msgid "" -"Add round number to fit and evaluate log messages " -"([#1266](https://github.com/adap/flower/pull/1266))" +"Please note: The REST API is still experimental and will likely change " +"significantly over time." msgstr "" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:388 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example " -"([#847](https://github.com/adap/flower/pull/847))" +"**Improve the (experimental) Driver API** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" msgstr "" -#: ../../source/ref-changelog.md:651 +#: ../../source/ref-changelog.md:390 msgid "" -"Update developer tooling " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"The Driver API is still an experimental feature, but this release " +"introduces some major upgrades. One of the main improvements is the " +"introduction of an SQLite database to store server state on disk (instead" +" of in-memory). Another improvement is that tasks (instructions or " +"results) that have been delivered will now be deleted. This greatly " +"improves the memory efficiency of a long-running Flower server." msgstr "" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:392 msgid "" -"Rename ProtoBuf messages to improve consistency " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Fix spilling issues related to Ray during simulations** " +"([#1698](https://github.com/adap/flower/pull/1698))" msgstr "" -#: ../../source/ref-changelog.md:654 -msgid "v0.19.0 (2022-05-18)" +#: ../../source/ref-changelog.md:394 +msgid "" +"While running long simulations, `ray` was sometimes spilling huge amounts" +" of data that would make the training unable to continue. This is now " +"fixed! 🎉" msgstr "" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:396 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Add new example using** `TabNet` **and Flower** " +"([#1725](https://github.com/adap/flower/pull/1725))" msgstr "" -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:398 msgid "" -"The first preview release of Flower Baselines has arrived! We're " -"kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " -"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " -"With this first preview release we're also inviting the community to " -"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" -"contribute-baselines.html)." +"TabNet is a powerful and flexible framework for training machine learning" +" models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" +"/quickstart-tabnet)." msgstr "" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:400 msgid "" -"**C++ client SDK (preview) and code example** " -"([#1111](https://github.com/adap/flower/pull/1111))" +"**Add new how-to guide for monitoring simulations** " +"([#1649](https://github.com/adap/flower/pull/1649))" msgstr "" -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:402 msgid "" -"Preview support for Flower clients written in C++. The C++ preview " -"includes a Flower client SDK and a quickstart code example that " -"demonstrates a simple C++ client using the SDK." +"We now have a documentation guide to help users monitor their performance" +" during simulations." msgstr "" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:404 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"**Add training metrics to** `History` **object during simulations** " +"([#1696](https://github.com/adap/flower/pull/1696))" msgstr "" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:406 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due" -" to be released in October. This Flower release adds experimental support" -" for both Python versions." +"The `fit_metrics_aggregation_fn` can be used to aggregate training " +"metrics, but previous releases did not save the results in the `History` " +"object. This is now the case!" msgstr "" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:408 msgid "" -"**Aggregate custom metrics through user-provided functions** " -"([#1144](https://github.com/adap/flower/pull/1144))" +"**General improvements** " +"([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/adap/flower/pull/1705), " +"[#1708](https://github.com/adap/flower/pull/1708), " +"[#1711](https://github.com/adap/flower/pull/1711), " +"[#1713](https://github.com/adap/flower/pull/1713), " +"[#1714](https://github.com/adap/flower/pull/1714), " +"[#1718](https://github.com/adap/flower/pull/1718), " +"[#1716](https://github.com/adap/flower/pull/1716), " +"[#1723](https://github.com/adap/flower/pull/1723), " +"[#1735](https://github.com/adap/flower/pull/1735), " +"[#1678](https://github.com/adap/flower/pull/1678), " +"[#1750](https://github.com/adap/flower/pull/1750), " +"[#1753](https://github.com/adap/flower/pull/1753), " +"[#1736](https://github.com/adap/flower/pull/1736), " +"[#1766](https://github.com/adap/flower/pull/1766), " +"[#1760](https://github.com/adap/flower/pull/1760), " +"[#1775](https://github.com/adap/flower/pull/1775), " +"[#1776](https://github.com/adap/flower/pull/1776), " +"[#1777](https://github.com/adap/flower/pull/1777), " +"[#1779](https://github.com/adap/flower/pull/1779), " +"[#1784](https://github.com/adap/flower/pull/1784), " +"[#1773](https://github.com/adap/flower/pull/1773), " +"[#1755](https://github.com/adap/flower/pull/1755), " +"[#1789](https://github.com/adap/flower/pull/1789), " +"[#1788](https://github.com/adap/flower/pull/1788), " +"[#1798](https://github.com/adap/flower/pull/1798), " +"[#1799](https://github.com/adap/flower/pull/1799), " +"[#1739](https://github.com/adap/flower/pull/1739), " +"[#1800](https://github.com/adap/flower/pull/1800), " +"[#1804](https://github.com/adap/flower/pull/1804), " +"[#1805](https://github.com/adap/flower/pull/1805))" msgstr "" -#: ../../source/ref-changelog.md:672 -msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" -" customize the strategy. Built-in strategies support two new arguments, " -"`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " -"allow passing custom metric aggregation functions." +#: ../../source/ref-changelog.md:416 +msgid "v1.3.0 (2023-02-06)" msgstr "" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:422 msgid "" -"**User-configurable round timeout** " -"([#1162](https://github.com/adap/flower/pull/1162))" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:426 msgid "" -"A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary " -"contains a `round_timeout` key (with a `float` value in seconds), the " -"server will wait *at least* `round_timeout` seconds before it closes the " -"connection." +"**Add support for** `workload_id` **and** `group_id` **in Driver API** " +"([#1595](https://github.com/adap/flower/pull/1595))" msgstr "" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:428 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used " -"at the same time in all built-in strategies** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"The (experimental) Driver API now supports a `workload_id` that can be " +"used to identify which workload a task belongs to. It also supports a new" +" `group_id` that can be used, for example, to indicate the current " +"training round. Both the `workload_id` and `group_id` enable client nodes" +" to decide whether they want to handle a task or not." msgstr "" -#: ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:430 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., " -"client-side) and centralized evaluation (i.e., server-side) in the same " -"round. Federated evaluation can be disabled by setting `fraction_eval` to" -" `0.0`." +"**Make Driver API and Fleet API address configurable** " +"([#1637](https://github.com/adap/flower/pull/1637))" msgstr "" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:432 msgid "" -"**Two new Jupyter Notebook tutorials** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"The (experimental) long-running Flower server (Driver API and Fleet API) " +"can now configure the server address of both Driver API (via `--driver-" +"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:434 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " -"basic and intermediate Flower features:" +"`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " +"\"0.0.0.0:8086\"`" msgstr "" -#: ../../source/ref-changelog.md:686 -msgid "" -"*An Introduction to Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +#: ../../source/ref-changelog.md:436 +msgid "Both IPv4 and IPv6 addresses are supported." msgstr "" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:438 msgid "" -"*Using Strategies in Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"**Add new example of Federated Learning using fastai and Flower** " +"([#1598](https://github.com/adap/flower/pull/1598))" msgstr "" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:440 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"A new code example (`quickstart-fastai`) demonstrates federated learning " +"with [fastai](https://www.fast.ai/) and Flower. You can find it here: " +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" +"/quickstart-fastai)." msgstr "" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:442 msgid "" -"The new `FedAvgM` strategy implements Federated Averaging with Server " -"Momentum \\[Hsu et al., 2019\\]." +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" +" versions of Android** " +"([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:444 msgid "" -"**New advanced PyTorch code example** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"The Android code example has received a substantial update: the project " +"is compatible with Flower 1.0 (and later), the UI received a full " +"refresh, and the project is updated to be compatible with newer Android " +"tooling." msgstr "" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:446 msgid "" -"A new code example (`advanced_pytorch`) demonstrates advanced Flower " -"concepts with PyTorch." +"**Add new `FedProx` strategy** " +"([#1619](https://github.com/adap/flower/pull/1619))" msgstr "" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:448 msgid "" -"**New JAX code example** " -"([#906](https://github.com/adap/flower/pull/906), " -"[#1143](https://github.com/adap/flower/pull/1143))" +"This " +"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" +" is almost identical to " +"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," +" but helps users replicate what is described in this " +"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " +"parameter called `proximal_mu` to regularize the local models with " +"respect to the global models." msgstr "" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:450 msgid "" -"A new code example (`jax_from_centralized_to_federated`) shows federated " -"learning with JAX and Flower." +"**Add new metrics to telemetry events** " +"([#1640](https://github.com/adap/flower/pull/1640))" msgstr "" -#: ../../source/ref-changelog.md:704 +#: ../../source/ref-changelog.md:452 msgid "" -"New option to keep Ray running if Ray was already initialized in " -"`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" +"An updated event structure allows, for example, the clustering of events " +"within the same workload." msgstr "" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:454 msgid "" -"Add support for custom `ClientManager` as a `start_simulation` parameter " -"([#1171](https://github.com/adap/flower/pull/1171))" +"**Add new custom strategy tutorial section** " +"[#1623](https://github.com/adap/flower/pull/1623)" msgstr "" -#: ../../source/ref-changelog.md:706 +#: ../../source/ref-changelog.md:456 msgid "" -"New documentation for [implementing " -"strategies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"The Flower tutorial now has a new section that covers implementing a " +"custom strategy from scratch: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:458 msgid "" -"New mobile-friendly documentation theme " -"([#1174](https://github.com/adap/flower/pull/1174))" +"**Add new custom serialization tutorial section** " +"([#1622](https://github.com/adap/flower/pull/1622))" msgstr "" -#: ../../source/ref-changelog.md:708 +#: ../../source/ref-changelog.md:460 msgid "" -"Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"The Flower tutorial now has a new section that covers custom " +"serialization: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:462 msgid "" -"**Remove deprecated support for Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" +"**General improvements** " +"([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github.com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github.com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/adap/flower/pull/1600), " +"[#1601](https://github.com/adap/flower/pull/1601), " +"[#1597](https://github.com/adap/flower/pull/1597), " +"[#1595](https://github.com/adap/flower/pull/1595), " +"[#1591](https://github.com/adap/flower/pull/1591), " +"[#1588](https://github.com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), " +"[#1587](https://github.com/adap/flower/pull/1587), " +"[#1573](https://github.com/adap/flower/pull/1573), " +"[#1581](https://github.com/adap/flower/pull/1581), " +"[#1578](https://github.com/adap/flower/pull/1578), " +"[#1574](https://github.com/adap/flower/pull/1574), " +"[#1572](https://github.com/adap/flower/pull/1572), " +"[#1586](https://github.com/adap/flower/pull/1586))" msgstr "" -#: ../../source/ref-changelog.md:713 +#: ../../source/ref-changelog.md:466 msgid "" -"**Remove deprecated KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" +"**Updated documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" msgstr "" -#: ../../source/ref-changelog.md:714 +#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 msgid "" -"**Remove deprecated no-op extra installs** " -"([#973](https://github.com/adap/flower/pull/973))" +"As usual, the documentation has improved quite a bit. It is another step " +"in our effort to make the Flower documentation the best documentation of " +"any project. Stay tuned and as always, feel free to provide feedback!" msgstr "" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:474 +msgid "v1.2.0 (2023-01-13)" +msgstr "" + +#: ../../source/ref-changelog.md:480 msgid "" -"**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " -"([#869](https://github.com/adap/flower/pull/869))" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." +" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:484 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"**Introduce new Flower Baseline: FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:486 msgid "" -"**Remove deprecated DefaultStrategy strategy** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"Over the coming weeks, we will be releasing a number of new reference " +"implementations useful especially to FL newcomers. They will typically " +"revisit well known papers from the literature, and be suitable for " +"integration in your own application or for experimentation, in order to " +"deepen your knowledge of FL in general. Today's release is the first in " +"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" +"pack-fedavg-mnist-cnn/)" msgstr "" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:488 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Improve GPU support in simulations** " +"([#1555](https://github.com/adap/flower/pull/1555))" msgstr "" -#: ../../source/ref-changelog.md:719 +#: ../../source/ref-changelog.md:490 msgid "" -"**Remove deprecated support for passing initial parameters as NumPy " -"ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" +" to improve GPU support. The update includes some of the hard-earned " +"lessons from scaling simulations in GPU cluster environments. New " +"defaults make running GPU-based simulations substantially more robust." msgstr "" -#: ../../source/ref-changelog.md:721 -msgid "v0.18.0 (2022-02-28)" +#: ../../source/ref-changelog.md:492 +msgid "" +"**Improve GPU support in Jupyter Notebook tutorials** " +"([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" msgstr "" -#: ../../source/ref-changelog.md:725 +#: ../../source/ref-changelog.md:494 msgid "" -"**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"Some users reported that Jupyter Notebooks have not always been easy to " +"use on GPU instances. We listened and made improvements to all of our " +"Jupyter notebooks! Check out the updated notebooks here:" msgstr "" -#: ../../source/ref-changelog.md:727 +#: ../../source/ref-changelog.md:496 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) " -"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " -"installing Flower with the `simulation` extra (`pip install " -"flwr[simulation]`)." +"[An Introduction to Federated Learning](https://flower.ai/docs/framework" +"/tutorial-get-started-with-flower-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:729 +#: ../../source/ref-changelog.md:497 msgid "" -"**New Jupyter Notebook code example** " -"([#833](https://github.com/adap/flower/pull/833))" +"[Strategies in Federated Learning](https://flower.ai/docs/framework" +"/tutorial-use-a-federated-learning-strategy-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:731 +#: ../../source/ref-changelog.md:498 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower " -"simulations using the Virtual Client Engine through Jupyter Notebook " -"(incl. Google Colab)." +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" +"-strategy-from-scratch-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:733 +#: ../../source/ref-changelog.md:499 msgid "" -"**Client properties (feature preview)** " -"([#795](https://github.com/adap/flower/pull/795))" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" +"customize-the-client-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:735 +#: ../../source/ref-changelog.md:501 msgid "" -"Clients can implement a new method `get_properties` to enable server-side" -" strategies to query client properties." +"**Introduce optional telemetry** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" msgstr "" -#: ../../source/ref-changelog.md:737 +#: ../../source/ref-changelog.md:503 msgid "" -"**Experimental Android support with TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" +"After a [request for " +"feedback](https://github.com/adap/flower/issues/1534) from the community," +" the Flower open-source project introduces optional collection of " +"*anonymous* usage metrics to make well-informed decisions to improve " +"Flower. Doing this enables the Flower team to understand how Flower is " +"used and what challenges users might face." msgstr "" -#: ../../source/ref-changelog.md:739 +#: ../../source/ref-changelog.md:505 msgid "" -"Android support has finally arrived in `main`! Flower is both client-" -"agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has " -"become a lot easier." +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users who do not want to share anonymous usage metrics. " +"[Read more.](https://flower.ai/docs/telemetry.html)." msgstr "" -#: ../../source/ref-changelog.md:741 +#: ../../source/ref-changelog.md:507 msgid "" -"The example uses TFLite on the client side, along with a new " -"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " -"still experimental, but they are a first step towards a fully-fledged " -"Android SDK and a unified `FedAvg` implementation that integrated the new" -" functionality from `FedAvgAndroid`." +"**Introduce (experimental) Driver API** " +"([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" msgstr "" -#: ../../source/ref-changelog.md:743 +#: ../../source/ref-changelog.md:509 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default " -"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" +"Flower now has a new (experimental) Driver API which will enable fully " +"programmable, async, and multi-tenant Federated Learning and Federated " +"Analytics applications. Phew, that's a lot! Going forward, the Driver API" +" will be the abstraction that many upcoming features will be built on - " +"and you can start building those things now, too." msgstr "" -#: ../../source/ref-changelog.md:745 +#: ../../source/ref-changelog.md:511 msgid "" -"The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, " -"Microsoft Azure). Users can configure the keepalive time to customize the" -" gRPC stack based on specific requirements." +"The Driver API also enables a new execution mode in which the server runs" +" indefinitely. Multiple individual workloads can run concurrently and " +"start and stop their execution independent of the server. This is " +"especially useful for users who want to deploy Flower in production." msgstr "" -#: ../../source/ref-changelog.md:747 +#: ../../source/ref-changelog.md:513 msgid "" -"**New differential privacy example using Opacus and PyTorch** " -"([#805](https://github.com/adap/flower/pull/805))" +"To learn more, check out the `mt-pytorch` code example. We look forward " +"to you feedback!" msgstr "" -#: ../../source/ref-changelog.md:749 +#: ../../source/ref-changelog.md:515 msgid "" -"A new code example (`opacus`) demonstrates differentially-private " -"federated learning with Opacus, PyTorch, and Flower." +"Please note: *The Driver API is still experimental and will likely change" +" significantly over time.*" msgstr "" -#: ../../source/ref-changelog.md:751 +#: ../../source/ref-changelog.md:517 msgid "" -"**New Hugging Face Transformers code example** " -"([#863](https://github.com/adap/flower/pull/863))" +"**Add new Federated Analytics with Pandas example** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" msgstr "" -#: ../../source/ref-changelog.md:753 +#: ../../source/ref-changelog.md:519 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of " -"Hugging Face Transformers with Flower." +"A new code example (`quickstart-pandas`) demonstrates federated analytics" +" with Pandas and Flower. You can find it here: [quickstart-" +"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" +"pandas)." msgstr "" -#: ../../source/ref-changelog.md:755 +#: ../../source/ref-changelog.md:521 msgid "" -"**New MLCube code example** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"**Add new strategies: Krum and MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" msgstr "" -#: ../../source/ref-changelog.md:757 +#: ../../source/ref-changelog.md:523 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " -"with Flower." +"Edoardo, a computer science student at the Sapienza University of Rome, " +"contributed a new `Krum` strategy that enables users to easily use Krum " +"and MultiKrum in their workloads." msgstr "" -#: ../../source/ref-changelog.md:759 +#: ../../source/ref-changelog.md:525 msgid "" -"**SSL-enabled server and client** " -"([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"**Update C++ example to be compatible with Flower v1.2.0** " +"([#1495](https://github.com/adap/flower/pull/1495))" msgstr "" -#: ../../source/ref-changelog.md:761 +#: ../../source/ref-changelog.md:527 msgid "" -"SSL enables secure encrypted connections between clients and servers. " -"This release open-sources the Flower secure gRPC implementation to make " -"encrypted communication channels accessible to all Flower users." +"The C++ code example has received a substantial update to make it " +"compatible with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:763 +#: ../../source/ref-changelog.md:529 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"**General improvements** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" msgstr "" -#: ../../source/ref-changelog.md:765 +#: ../../source/ref-changelog.md:533 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive " -"Federated Optimization paper." +"**Updated documentation** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" msgstr "" -#: ../../source/ref-changelog.md:767 +#: ../../source/ref-changelog.md:537 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** " -"([#860](https://github.com/adap/flower/pull/860))" +"One highlight is the new [first time contributor " +"guide](https://flower.ai/docs/first-time-contributors.html): if you've " +"never contributed on GitHub before, this is the perfect place to start!" msgstr "" -#: ../../source/ref-changelog.md:769 -msgid "" -"`start_simulation` can now be called with a list of client IDs " -"(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " -"`client_fn` whenever a client needs to be initialized, which can make it " -"easier to load data partitions that are not accessible through `int` " -"identifiers." +#: ../../source/ref-changelog.md:543 +msgid "v1.1.0 (2022-10-31)" msgstr "" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:547 msgid "" -"Update `num_examples` calculation in PyTorch code examples in " -"([#909](https://github.com/adap/flower/pull/909))" +"We would like to give our **special thanks** to all the contributors who " +"made the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:549 msgid "" -"Expose Flower version through `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " +"Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" msgstr "" -#: ../../source/ref-changelog.md:775 +#: ../../source/ref-changelog.md:553 msgid "" -"`start_server` in `app.py` now returns a `History` object containing " -"metrics from training ([#974](https://github.com/adap/flower/pull/974))" +"**Introduce Differential Privacy wrappers (preview)** " +"([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" msgstr "" -#: ../../source/ref-changelog.md:776 +#: ../../source/ref-changelog.md:555 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"The first (experimental) preview of pluggable Differential Privacy " +"wrappers enables easy configuration and usage of differential privacy " +"(DP). The pluggable DP wrappers enable framework-agnostic **and** " +"strategy-agnostic usage of both client-side DP and server-side DP. Head " +"over to the Flower docs, a new explainer goes into more detail." msgstr "" -#: ../../source/ref-changelog.md:777 +#: ../../source/ref-changelog.md:557 msgid "" -"Increase sleep time after server start to three seconds in all code " -"examples ([#1086](https://github.com/adap/flower/pull/1086))" +"**New iOS CoreML code example** " +"([#1289](https://github.com/adap/flower/pull/1289))" msgstr "" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:559 msgid "" -"Added a new FAQ section to the documentation " -"([#948](https://github.com/adap/flower/pull/948))" +"Flower goes iOS! A massive new code example shows how Flower clients can " +"be built for iOS. The code example contains both Flower iOS SDK " +"components that can be used for many tasks, and one task example running " +"on CoreML." msgstr "" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:561 msgid "" -"And many more under-the-hood changes, library updates, documentation " -"changes, and tooling improvements!" +"**New FedMedian strategy** " +"([#1461](https://github.com/adap/flower/pull/1461))" msgstr "" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:563 msgid "" -"**Removed** `flwr_example` **and** `flwr_experimental` **from release " -"build** ([#869](https://github.com/adap/flower/pull/869))" +"The new `FedMedian` strategy implements Federated Median (FedMedian) by " +"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:565 msgid "" -"The packages `flwr_example` and `flwr_experimental` have been deprecated " -"since Flower 0.12.0 and they are not longer included in Flower release " -"builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " -"an upcoming release." +"**Log** `Client` **exceptions in Virtual Client Engine** " +"([#1493](https://github.com/adap/flower/pull/1493))" msgstr "" -#: ../../source/ref-changelog.md:787 -msgid "v0.17.0 (2021-09-24)" +#: ../../source/ref-changelog.md:567 +msgid "" +"All `Client` exceptions happening in the VCE are now logged by default " +"and not just exposed to the configured `Strategy` (via the `failures` " +"argument)." msgstr "" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:569 msgid "" -"**Experimental virtual client engine** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"**Improve Virtual Client Engine internals** " +"([#1401](https://github.com/adap/flower/pull/1401), " +"[#1453](https://github.com/adap/flower/pull/1453))" msgstr "" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:571 msgid "" -"One of Flower's goals is to enable research at scale. This release " -"enables a first (experimental) peek at a major new feature, codenamed the" -" virtual client engine. Virtual clients enable simulations that scale to " -"a (very) large number of clients on a single machine or compute cluster. " -"The easiest way to test the new functionality is to look at the two new " -"code examples called `quickstart_simulation` and `simulation_pytorch`." +"Some internals of the Virtual Client Engine have been revamped. The VCE " +"now uses Ray 2.0 under the hood, the value type of the `client_resources`" +" dictionary changed to `float` to allow fractions of resources to be " +"allocated." msgstr "" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:573 msgid "" -"The feature is still experimental, so there's no stability guarantee for " -"the API. It's also not quite ready for prime time and comes with a few " -"known caveats. However, those who are curious are encouraged to try it " -"out and share their thoughts." +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " +"Client Engine**" msgstr "" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:575 msgid "" -"**New built-in strategies** " -"([#828](https://github.com/adap/flower/pull/828) " -"[#822](https://github.com/adap/flower/pull/822))" +"The Virtual Client Engine now has full support for optional `Client` (and" +" `NumPyClient`) methods." msgstr "" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:577 msgid "" -"FedYogi - Federated learning strategy using Yogi on server-side. " -"Implementation based on https://arxiv.org/abs/2003.00295" +"**Provide type information to packages using** `flwr` " +"([#1377](https://github.com/adap/flower/pull/1377))" msgstr "" -#: ../../source/ref-changelog.md:800 +#: ../../source/ref-changelog.md:579 msgid "" -"FedAdam - Federated learning strategy using Adam on server-side. " -"Implementation based on https://arxiv.org/abs/2003.00295" +"The package `flwr` is now bundled with a `py.typed` file indicating that " +"the package is typed. This enables typing support for projects or " +"packages that use `flwr` by enabling them to improve their code using " +"static type checkers like `mypy`." msgstr "" -#: ../../source/ref-changelog.md:802 +#: ../../source/ref-changelog.md:581 msgid "" -"**New PyTorch Lightning code example** " -"([#617](https://github.com/adap/flower/pull/617))" +"**Updated code example** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -#: ../../source/ref-changelog.md:804 +#: ../../source/ref-changelog.md:583 msgid "" -"**New Variational Auto-Encoder code example** " -"([#752](https://github.com/adap/flower/pull/752))" +"The code examples covering scikit-learn and PyTorch Lightning have been " +"updated to work with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:806 +#: ../../source/ref-changelog.md:585 msgid "" -"**New scikit-learn code example** " -"([#748](https://github.com/adap/flower/pull/748))" +"**Updated documentation** " +"([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github.com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" msgstr "" -#: ../../source/ref-changelog.md:808 +#: ../../source/ref-changelog.md:587 msgid "" -"**New experimental TensorBoard strategy** " -"([#789](https://github.com/adap/flower/pull/789))" +"There have been so many documentation updates that it doesn't even make " +"sense to list them individually." msgstr "" -#: ../../source/ref-changelog.md:812 +#: ../../source/ref-changelog.md:589 msgid "" -"Improved advanced TensorFlow code example " -"([#769](https://github.com/adap/flower/pull/769))" +"**Restructured documentation** " +"([#1387](https://github.com/adap/flower/pull/1387))" msgstr "" -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:591 msgid "" -"Warning when `min_available_clients` is misconfigured " -"([#830](https://github.com/adap/flower/pull/830))" +"The documentation has been restructured to make it easier to navigate. " +"This is just the first step in a larger effort to make the Flower " +"documentation the best documentation of any project ever. Stay tuned!" msgstr "" -#: ../../source/ref-changelog.md:814 +#: ../../source/ref-changelog.md:593 msgid "" -"Improved gRPC server docs " -"([#841](https://github.com/adap/flower/pull/841))" +"**Open in Colab button** " +"([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:595 msgid "" -"Improved error message in `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" +"The four parts of the Flower Federated Learning Tutorial now come with a " +"new `Open in Colab` button. No need to install anything on your local " +"machine, you can now use and learn about Flower in your browser, it's " +"only a single click away." msgstr "" -#: ../../source/ref-changelog.md:816 +#: ../../source/ref-changelog.md:597 msgid "" -"Improved PyTorch quickstart code example " -"([#852](https://github.com/adap/flower/pull/852))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" msgstr "" -#: ../../source/ref-changelog.md:820 +#: ../../source/ref-changelog.md:599 msgid "" -"**Disabled final distributed evaluation** " -"([#800](https://github.com/adap/flower/pull/800))" +"The Flower Federated Learning Tutorial has two brand-new parts covering " +"custom strategies (still WIP) and the distinction between `Client` and " +"`NumPyClient`. The existing parts one and two have also been improved " +"(many small changes and fixes)." msgstr "" -#: ../../source/ref-changelog.md:822 -msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on" -" all connected clients, which is often not required (e.g., when using " -"server-side evaluation). The prior behaviour can be enabled by passing " -"`force_final_distributed_eval=True` to `start_server`." +#: ../../source/ref-changelog.md:605 +msgid "v1.0.0 (2022-07-28)" msgstr "" -#: ../../source/ref-changelog.md:824 -msgid "" -"**Renamed q-FedAvg strategy** " -"([#802](https://github.com/adap/flower/pull/802))" +#: ../../source/ref-changelog.md:607 +msgid "Highlights" msgstr "" -#: ../../source/ref-changelog.md:826 -msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " -"the notation given in the original paper (q-FFL is the optimization " -"objective, q-FedAvg is the proposed solver). Note the original (now " -"deprecated) `QffedAvg` class is still available for compatibility reasons" -" (it will be removed in a future release)." +#: ../../source/ref-changelog.md:609 +msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "" -#: ../../source/ref-changelog.md:828 -msgid "" -"**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +#: ../../source/ref-changelog.md:610 +msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "" -#: ../../source/ref-changelog.md:830 -msgid "" -"This example has been replaced by a new example. The new example is based" -" on the experimental virtual client engine, which will become the new " -"default way of doing most types of large-scale simulations in Flower. The" -" existing example was kept for reference purposes, but it might be " -"removed in the future." +#: ../../source/ref-changelog.md:611 +msgid "Configurable `get_parameters`" msgstr "" -#: ../../source/ref-changelog.md:832 -msgid "v0.16.0 (2021-05-11)" +#: ../../source/ref-changelog.md:612 +msgid "" +"Tons of small API cleanups resulting in a more coherent developer " +"experience" msgstr "" -#: ../../source/ref-changelog.md:836 +#: ../../source/ref-changelog.md:616 msgid "" -"**New built-in strategies** " -"([#549](https://github.com/adap/flower/pull/549))" +"We would like to give our **special thanks** to all the contributors who " +"made Flower 1.0 possible (in reverse [GitHub " +"Contributors](https://github.com/adap/flower/graphs/contributors) order):" msgstr "" -#: ../../source/ref-changelog.md:838 -msgid "(abstract) FedOpt" +#: ../../source/ref-changelog.md:618 +msgid "" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), " +"[@mrinaald](https://github.com/mrinaald), " +"[@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), " +"[@sancarlim](https://github.com/sancarlim), " +"[@gubertoli](https://github.com/gubertoli), " +"[@Vingt100](https://github.com/Vingt100), " +"[@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), " +"[@jafermarq](https://github.com/jafermarq), " +"[@sisco0](https://github.com/sisco0), " +"[@akhilmathurs](https://github.com/akhilmathurs), " +"[@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), " +"[@pedropgusmao](https://github.com/pedropgusmao), " +"[@tanertopal](https://github.com/tanertopal), " +"[@danieljanes](https://github.com/danieljanes)." msgstr "" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:622 msgid "" -"**Custom metrics for server and strategies** " -"([#717](https://github.com/adap/flower/pull/717))" +"**All arguments must be passed as keyword arguments** " +"([#1338](https://github.com/adap/flower/pull/1338))" msgstr "" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:624 msgid "" -"The Flower server is now fully task-agnostic, all remaining instances of " -"task-specific metrics (such as `accuracy`) have been replaced by custom " -"metrics dictionaries. Flower 0.15 introduced the capability to pass a " -"dictionary containing custom metrics from client to server. As of this " -"release, custom metrics replace task-specific metrics on the server." +"Pass all arguments as keyword arguments, positional arguments are not " +"longer supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " +"for each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)." msgstr "" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:626 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are" -" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " -"they enable evaluation functions passed to built-in strategies (via " -"`eval_fn`) to return more than two evaluation metrics. Strategies can " -"even return *aggregated* metrics dictionaries for the server to keep " -"track of." +"**Introduce configuration object** `ServerConfig` **in** `start_server` " +"**and** `start_simulation` " +"([#1317](https://github.com/adap/flower/pull/1317))" msgstr "" -#: ../../source/ref-changelog.md:847 +#: ../../source/ref-changelog.md:628 msgid "" -"Strategy implementations should migrate their `aggregate_fit` and " -"`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate" -" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " +"600.0}`, `start_server` and `start_simulation` now expect a configuration" +" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" +" arguments that as the previous config dict, but it makes writing type-" +"safe code easier and the default parameters values more transparent." msgstr "" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:630 msgid "" -"Flower 0.15-style return types are deprecated (but still supported), " -"compatibility will be removed in a future release." +"**Rename built-in strategy parameters for clarity** " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:632 msgid "" -"**Migration warnings for deprecated functionality** " -"([#690](https://github.com/adap/flower/pull/690))" +"The following built-in strategy parameters were renamed to improve " +"readability and consistency with other API's:" msgstr "" -#: ../../source/ref-changelog.md:853 -msgid "" -"Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces " -"detailed warning messages if usage of deprecated APIs is detected. The " -"new warning messages often provide details on how to migrate to more " -"recent APIs, thus easing the transition from one release to another." +#: ../../source/ref-changelog.md:634 +msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:855 -msgid "" -"Improved docs and docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +#: ../../source/ref-changelog.md:635 +msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "" -#: ../../source/ref-changelog.md:857 -msgid "MXNet example and documentation" +#: ../../source/ref-changelog.md:636 +msgid "`eval_fn` --> `evaluate_fn`" msgstr "" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:638 msgid "" -"FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"**Update default arguments of built-in strategies** " +"([#1278](https://github.com/adap/flower/pull/1278))" msgstr "" -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:640 msgid "" -"**Serialization-agnostic server** " -"([#721](https://github.com/adap/flower/pull/721))" +"All built-in strategies now use `fraction_fit=1.0` and " +"`fraction_evaluate=1.0`, which means they select *all* currently " +"available clients for training and evaluation. Projects that relied on " +"the previous default values can get the previous behaviour by " +"initializing the strategy in the following way:" msgstr "" -#: ../../source/ref-changelog.md:865 -msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of " -"class `Weights` (which represents parameters as deserialized NumPy " -"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " -"`Parameters` objects are fully serialization-agnostic and represents " -"parameters as byte arrays, the `tensor_type` attributes indicates how " -"these byte arrays should be interpreted (e.g., for " -"serialization/deserialization)." +#: ../../source/ref-changelog.md:642 +msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "" -#: ../../source/ref-changelog.md:867 +#: ../../source/ref-changelog.md:644 msgid "" -"Built-in strategies implement this approach by handling serialization and" -" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " -"implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR " -"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" -" easily migrate to the new format." +"**Add** `server_round` **to** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:869 +#: ../../source/ref-changelog.md:646 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use " -"`flwr.server.Server.evaluate_round` instead " -"([#717](https://github.com/adap/flower/pull/717))" +"The `Strategy` method `evaluate` now receives the current round of " +"federated learning/evaluation as the first parameter." msgstr "" -#: ../../source/ref-changelog.md:871 -msgid "v0.15.0 (2021-03-12)" +#: ../../source/ref-changelog.md:648 +msgid "" +"**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:875 +#: ../../source/ref-changelog.md:650 msgid "" -"**Server-side parameter initialization** " -"([#658](https://github.com/adap/flower/pull/658))" +"The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " +"three parameters: (1) The current round of federated learning/evaluation " +"(`server_round`), (2) the model parameters to evaluate (`parameters`), " +"and (3) a config dictionary (`config`)." msgstr "" -#: ../../source/ref-changelog.md:877 +#: ../../source/ref-changelog.md:652 msgid "" -"Model parameters can now be initialized on the server-side. Server-side " -"parameter initialization works via a new `Strategy` method called " -"`initialize_parameters`." +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" msgstr "" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:654 msgid "" -"Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies " -"will provide these initial parameters to the server on startup and then " -"delete them to free the memory afterwards." +"Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " +"`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " +"current round of federated learning/evaluation as their first parameter. " +"To improve reaability and avoid confusion with *random*, this parameter " +"has been renamed from `rnd` to `server_round`." msgstr "" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:656 msgid "" -"If no initial parameters are provided to the strategy, the server will " -"continue to use the current behaviour (namely, it will ask one of the " -"connected clients for its parameters and use these as the initial global " -"parameters)." +"**Move** `flwr.dataset` **to** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" msgstr "" -#: ../../source/ref-changelog.md:900 -msgid "Deprecations" +#: ../../source/ref-changelog.md:658 +msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:660 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " -"`flwr.server.strategy.FedAvg`, which is equivalent)" -msgstr "" - -#: ../../source/ref-changelog.md:904 -msgid "v0.14.0 (2021-02-18)" +"**Remove experimental strategies** " +"([#1280](https://github.com/adap/flower/pull/1280))" msgstr "" -#: ../../source/ref-changelog.md:908 +#: ../../source/ref-changelog.md:662 msgid "" -"**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " +"`FedFSv1`)." msgstr "" -#: ../../source/ref-changelog.md:910 +#: ../../source/ref-changelog.md:664 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to " -"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " -"This means one can return almost arbitrary values from `fit`/`evaluate` " -"and make use of them on the server side!" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:912 +#: ../../source/ref-changelog.md:666 msgid "" -"This improvement also allowed for more consistent return types between " -"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " -"dict)` representing the loss, number of examples, and a dictionary " -"holding arbitrary problem-specific values like accuracy." +"`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " +"capture what this type is all about." msgstr "" -#: ../../source/ref-changelog.md:914 +#: ../../source/ref-changelog.md:668 msgid "" -"In case you wondered: this feature is compatible with existing projects, " -"the additional dictionary return value is optional. New code should " -"however migrate to the new return types to be compatible with upcoming " -"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " -"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " -"details." +"**Remove antiquated** `force_final_distributed_eval` **from** " +"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:916 +#: ../../source/ref-changelog.md:670 msgid "" -"*Code example:* note the additional dictionary return values in both " -"`FlwrClient.fit` and `FlwrClient.evaluate`:" +"The `start_server` parameter `force_final_distributed_eval` has long been" +" a historic artefact, in this release it is finally gone for good." msgstr "" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:672 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Make** `get_parameters` **configurable** " +"([#1242](https://github.com/adap/flower/pull/1242))" msgstr "" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:674 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means " -"that dictionary values were expected to be strings. The new release " -"generalizes this to enable values of the following types: `bool`, " -"`bytes`, `float`, `int`, `str`." +"The `get_parameters` method now accepts a configuration dictionary, just " +"like `get_properties`, `fit`, and `evaluate`." msgstr "" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:676 msgid "" -"This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" -"side and `int(config[\"epochs\"])` on the client side!" +"**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " +"**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:678 msgid "" -"*Code example:* note that the `config` dictionary now contains non-`str` " -"values in both `Client.fit` and `Client.evaluate`:" -msgstr "" - -#: ../../source/ref-changelog.md:954 -msgid "v0.13.0 (2021-01-08)" +"The `start_simulation` function now accepts a configuration dictionary " +"`config` instead of the `num_rounds` integer. This improves the " +"consistency between `start_simulation` and `start_server` and makes " +"transitioning between the two easier." msgstr "" -#: ../../source/ref-changelog.md:958 +#: ../../source/ref-changelog.md:682 msgid "" -"New example: PyTorch From Centralized To Federated " -"([#549](https://github.com/adap/flower/pull/549))" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" -#: ../../source/ref-changelog.md:959 -msgid "Improved documentation" +#: ../../source/ref-changelog.md:684 +msgid "" +"The previous Flower release introduced experimental support for Python " +"3.10, this release declares Python 3.10 support as stable." msgstr "" -#: ../../source/ref-changelog.md:960 -msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +#: ../../source/ref-changelog.md:686 +msgid "" +"**Make all** `Client` **and** `NumPyClient` **methods optional** " +"([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" msgstr "" -#: ../../source/ref-changelog.md:961 -msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" +#: ../../source/ref-changelog.md:688 +msgid "" +"The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " +"`fit`, and `evaluate` are all optional. This enables writing clients that" +" implement, for example, only `fit`, but no other method. No need to " +"implement `evaluate` when using centralized evaluation!" msgstr "" -#: ../../source/ref-changelog.md:962 +#: ../../source/ref-changelog.md:690 msgid "" -"Updated examples documentation " -"([#549](https://github.com/adap/flower/pull/549))" +"**Enable passing a** `Server` **instance to** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:963 +#: ../../source/ref-changelog.md:692 msgid "" -"Removed obsolete documentation " -"([#548](https://github.com/adap/flower/pull/548))" +"Similar to `start_server`, `start_simulation` now accepts a full `Server`" +" instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the" +" Virtual Client Engine." msgstr "" -#: ../../source/ref-changelog.md:965 -msgid "Bugfix:" +#: ../../source/ref-changelog.md:694 +msgid "" +"**Update code examples** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" msgstr "" -#: ../../source/ref-changelog.md:967 +#: ../../source/ref-changelog.md:696 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the" -" clients is now handled in `flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." +"Many code examples received small or even large maintenance updates, " +"among them are" msgstr "" -#: ../../source/ref-changelog.md:969 -msgid "v0.12.0 (2020-12-07)" +#: ../../source/ref-changelog.md:698 +msgid "`scikit-learn`" msgstr "" -#: ../../source/ref-changelog.md:971 ../../source/ref-changelog.md:987 -msgid "Important changes:" +#: ../../source/ref-changelog.md:699 +msgid "`simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:973 -msgid "" -"Added an example for embedded devices " -"([#507](https://github.com/adap/flower/pull/507))" +#: ../../source/ref-changelog.md:700 +msgid "`quickstart_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:974 -msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +#: ../../source/ref-changelog.md:701 +msgid "`quickstart_simulation`" msgstr "" -#: ../../source/ref-changelog.md:975 -msgid "" -"Deprecated `flwr_example` package and started to migrate examples into " -"the top-level `examples` directory " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +#: ../../source/ref-changelog.md:702 +msgid "`quickstart_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:977 -msgid "v0.11.0 (2020-11-30)" +#: ../../source/ref-changelog.md:703 +msgid "`advanced_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:979 -msgid "Incompatible changes:" +#: ../../source/ref-changelog.md:705 +msgid "" +"**Remove the obsolete simulation example** " +"([#1328](https://github.com/adap/flower/pull/1328))" msgstr "" -#: ../../source/ref-changelog.md:981 +#: ../../source/ref-changelog.md:707 msgid "" -"Renamed strategy methods " -"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " -"Flower's public APIs. Other public methods/functions (e.g., every method " -"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " -"which is why we're removing it from the four methods in Strategy. To " -"migrate rename the following `Strategy` methods accordingly:" +"Removes the obsolete `simulation` example and renames " +"`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " +"naming of `simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:982 -msgid "`on_configure_evaluate` => `configure_evaluate`" +#: ../../source/ref-changelog.md:709 +msgid "" +"**Update documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" msgstr "" -#: ../../source/ref-changelog.md:983 -msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" +#: ../../source/ref-changelog.md:711 +msgid "" +"One substantial documentation update fixes multiple smaller rendering " +"issues, makes titles more succinct to improve navigation, removes a " +"deprecated library, updates documentation dependencies, includes the " +"`flwr.common` module in the API reference, includes support for markdown-" +"based documentation, migrates the changelog from `.rst` to `.md`, and " +"fixes a number of smaller details!" msgstr "" -#: ../../source/ref-changelog.md:984 -msgid "`on_configure_fit` => `configure_fit`" +#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 +#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +msgid "**Minor updates**" msgstr "" -#: ../../source/ref-changelog.md:985 -msgid "`on_aggregate_fit` => `aggregate_fit`" +#: ../../source/ref-changelog.md:715 +msgid "" +"Add round number to fit and evaluate log messages " +"([#1266](https://github.com/adap/flower/pull/1266))" msgstr "" -#: ../../source/ref-changelog.md:989 +#: ../../source/ref-changelog.md:716 msgid "" -"Deprecated `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). To migrate use " -"`FedAvg` instead." +"Add secure gRPC connection to the `advanced_tensorflow` code example " +"([#847](https://github.com/adap/flower/pull/847))" msgstr "" -#: ../../source/ref-changelog.md:990 +#: ../../source/ref-changelog.md:717 msgid "" -"Simplified examples and baselines " -"([#484](https://github.com/adap/flower/pull/484))." +"Update developer tooling " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" msgstr "" -#: ../../source/ref-changelog.md:991 +#: ../../source/ref-changelog.md:718 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface " -"([#483](https://github.com/adap/flower/pull/483))." +"Rename ProtoBuf messages to improve consistency " +"([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:992 -msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +#: ../../source/ref-changelog.md:720 +msgid "v0.19.0 (2022-05-18)" msgstr "" -#: ../../source/ref-changelog.md:993 +#: ../../source/ref-changelog.md:724 msgid "" -"Improved `Strategy` docstrings " -"([#470](https://github.com/adap/flower/pull/470))." +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" msgstr "" -#: ../../source/ref-example-projects.rst:2 -msgid "Example projects" +#: ../../source/ref-changelog.md:726 +msgid "" +"The first preview release of Flower Baselines has arrived! We're " +"kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " +"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " +"With this first preview release we're also inviting the community to " +"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" +"contribute-baselines.html)." msgstr "" -#: ../../source/ref-example-projects.rst:4 +#: ../../source/ref-changelog.md:728 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate " -"how Flower can be used to federate different kinds of existing machine " -"learning pipelines, usually leveraging popular machine learning " -"frameworks such as `PyTorch `_ or `TensorFlow " -"`_." +"**C++ client SDK (preview) and code example** " +"([#1111](https://github.com/adap/flower/pull/1111))" msgstr "" -#: ../../source/ref-example-projects.rst:10 +#: ../../source/ref-changelog.md:730 msgid "" -"The following examples are available as standalone projects. Quickstart " -"TensorFlow/Keras ---------------------------" +"Preview support for Flower clients written in C++. The C++ preview " +"includes a Flower client SDK and a quickstart code example that " +"demonstrates a simple C++ client using the SDK." msgstr "" -#: ../../source/ref-example-projects.rst:14 +#: ../../source/ref-changelog.md:732 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image " -"classification with MobileNetV2:" +"**Add experimental support for Python 3.10 and Python 3.11** " +"([#1135](https://github.com/adap/flower/pull/1135))" msgstr "" -#: ../../source/ref-example-projects.rst:17 +#: ../../source/ref-changelog.md:734 msgid "" -"`Quickstart TensorFlow (Code) " -"`_" +"Python 3.10 is the latest stable release of Python and Python 3.11 is due" +" to be released in October. This Flower release adds experimental support" +" for both Python versions." msgstr "" -#: ../../source/ref-example-projects.rst:18 -msgid ":doc:`Quickstart TensorFlow (Tutorial) `" +#: ../../source/ref-changelog.md:736 +msgid "" +"**Aggregate custom metrics through user-provided functions** " +"([#1144](https://github.com/adap/flower/pull/1144))" msgstr "" -#: ../../source/ref-example-projects.rst:19 +#: ../../source/ref-changelog.md:738 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" +" customize the strategy. Built-in strategies support two new arguments, " +"`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " +"allow passing custom metric aggregation functions." msgstr "" -#: ../../source/ref-example-projects.rst:23 -#: ../../source/tutorial-quickstart-pytorch.rst:5 -msgid "Quickstart PyTorch" +#: ../../source/ref-changelog.md:740 +msgid "" +"**User-configurable round timeout** " +"([#1162](https://github.com/adap/flower/pull/1162))" msgstr "" -#: ../../source/ref-example-projects.rst:25 +#: ../../source/ref-changelog.md:742 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a" -" simple Convolutional Neural Network:" +"A new configuration value allows the round timeout to be set for " +"`start_server` and `start_simulation`. If the `config` dictionary " +"contains a `round_timeout` key (with a `float` value in seconds), the " +"server will wait *at least* `round_timeout` seconds before it closes the " +"connection." msgstr "" -#: ../../source/ref-example-projects.rst:28 +#: ../../source/ref-changelog.md:744 msgid "" -"`Quickstart PyTorch (Code) " -"`_" +"**Enable both federated evaluation and centralized evaluation to be used " +"at the same time in all built-in strategies** " +"([#1091](https://github.com/adap/flower/pull/1091))" msgstr "" -#: ../../source/ref-example-projects.rst:29 -msgid ":doc:`Quickstart PyTorch (Tutorial) `" +#: ../../source/ref-changelog.md:746 +msgid "" +"Built-in strategies can now perform both federated evaluation (i.e., " +"client-side) and centralized evaluation (i.e., server-side) in the same " +"round. Federated evaluation can be disabled by setting `fraction_eval` to" +" `0.0`." msgstr "" -#: ../../source/ref-example-projects.rst:33 -msgid "PyTorch: From Centralized To Federated" +#: ../../source/ref-changelog.md:748 +msgid "" +"**Two new Jupyter Notebook tutorials** " +"([#1141](https://github.com/adap/flower/pull/1141))" msgstr "" -#: ../../source/ref-example-projects.rst:35 +#: ../../source/ref-changelog.md:750 msgid "" -"This example shows how a regular PyTorch project can be federated using " -"Flower:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " +"basic and intermediate Flower features:" msgstr "" -#: ../../source/ref-example-projects.rst:37 +#: ../../source/ref-changelog.md:752 msgid "" -"`PyTorch: From Centralized To Federated (Code) " -"`_" +"*An Introduction to Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-example-projects.rst:38 +#: ../../source/ref-changelog.md:754 msgid "" -":doc:`PyTorch: From Centralized To Federated (Tutorial) `" +"*Using Strategies in Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-example-projects.rst:42 -msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" +#: ../../source/ref-changelog.md:756 +msgid "" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " +"([#1076](https://github.com/adap/flower/pull/1076))" msgstr "" -#: ../../source/ref-example-projects.rst:44 +#: ../../source/ref-changelog.md:758 msgid "" -"This example shows how Flower can be used to build a federated learning " -"system that run across Raspberry Pi and Nvidia Jetson:" +"The new `FedAvgM` strategy implements Federated Averaging with Server " +"Momentum \\[Hsu et al., 2019\\]." msgstr "" -#: ../../source/ref-example-projects.rst:46 +#: ../../source/ref-changelog.md:760 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " -"`_" +"**New advanced PyTorch code example** " +"([#1007](https://github.com/adap/flower/pull/1007))" msgstr "" -#: ../../source/ref-example-projects.rst:47 +#: ../../source/ref-changelog.md:762 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " -"`_" +"A new code example (`advanced_pytorch`) demonstrates advanced Flower " +"concepts with PyTorch." msgstr "" -#: ../../source/ref-faq.rst:4 +#: ../../source/ref-changelog.md:764 msgid "" -"This page collects answers to commonly asked questions about Federated " -"Learning with Flower." +"**New JAX code example** " +"([#906](https://github.com/adap/flower/pull/906), " +"[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" +#: ../../source/ref-changelog.md:766 +msgid "" +"A new code example (`jax_from_centralized_to_federated`) shows federated " +"learning with JAX and Flower." msgstr "" -#: ../../source/ref-faq.rst:8 +#: ../../source/ref-changelog.md:770 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to" -" make it work even better on Colab. Here's a quickstart example:" +"New option to keep Ray running if Ray was already initialized in " +"`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -#: ../../source/ref-faq.rst:10 +#: ../../source/ref-changelog.md:771 msgid "" -"`Flower simulation PyTorch " -"`_" +"Add support for custom `ClientManager` as a `start_simulation` parameter " +"([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -#: ../../source/ref-faq.rst:11 +#: ../../source/ref-changelog.md:772 msgid "" -"`Flower simulation TensorFlow/Keras " -"`_" +"New documentation for [implementing " +"strategies](https://flower.ai/docs/framework/how-to-implement-" +"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" +#: ../../source/ref-changelog.md:773 +msgid "" +"New mobile-friendly documentation theme " +"([#1174](https://github.com/adap/flower/pull/1174))" msgstr "" -#: ../../source/ref-faq.rst:15 +#: ../../source/ref-changelog.md:774 msgid "" -"Find the `blog post about federated learning on embedded device here " -"`_" -" and the corresponding `GitHub code example " -"`_." +"Limit version range for (optional) `ray` dependency to include only " +"compatible releases (`>=1.9.2,<1.12.0`) " +"([#1205](https://github.com/adap/flower/pull/1205))" msgstr "" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +#: ../../source/ref-changelog.md:778 +msgid "" +"**Remove deprecated support for Python 3.6** " +"([#871](https://github.com/adap/flower/pull/871))" msgstr "" -#: ../../source/ref-faq.rst:19 +#: ../../source/ref-changelog.md:779 msgid "" -"Yes, it does. Please take a look at our `blog post " -"`_ or check out the code examples:" +"**Remove deprecated KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" msgstr "" -#: ../../source/ref-faq.rst:21 +#: ../../source/ref-changelog.md:780 msgid "" -"`Android Kotlin example `_" +"**Remove deprecated no-op extra installs** " +"([#973](https://github.com/adap/flower/pull/973))" msgstr "" -#: ../../source/ref-faq.rst:22 -msgid "`Android Java example `_" +#: ../../source/ref-changelog.md:781 +msgid "" +"**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " +"([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Can I combine federated learning with blockchain?" +#: ../../source/ref-changelog.md:782 +msgid "" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " +"([#1107](https://github.com/adap/flower/pull/1107))" msgstr "" -#: ../../source/ref-faq.rst:26 +#: ../../source/ref-changelog.md:783 msgid "" -"Yes, of course. A list of available examples using Flower within a " -"blockchain environment is available here:" +"**Remove deprecated DefaultStrategy strategy** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-faq.rst:28 +#: ../../source/ref-changelog.md:784 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"**Remove deprecated support for eval_fn accuracy return value** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-faq.rst:29 +#: ../../source/ref-changelog.md:785 msgid "" -"`Flower meets Nevermined YouTube video " -"`_." +"**Remove deprecated support for passing initial parameters as NumPy " +"ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-faq.rst:30 -msgid "" -"`Flower meets KOSMoS `_." +#: ../../source/ref-changelog.md:787 +msgid "v0.18.0 (2022-02-28)" msgstr "" -#: ../../source/ref-faq.rst:31 +#: ../../source/ref-changelog.md:791 msgid "" -"`Flower meets Talan blog post `_ ." +"**Improved Virtual Client Engine compatibility with Jupyter Notebook / " +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -#: ../../source/ref-faq.rst:32 +#: ../../source/ref-changelog.md:793 msgid "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"Simulations (using the Virtual Client Engine through `start_simulation`) " +"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"installing Flower with the `simulation` extra (`pip install " +"flwr[simulation]`)." msgstr "" -#: ../../source/ref-telemetry.md:1 -msgid "Telemetry" +#: ../../source/ref-changelog.md:795 +msgid "" +"**New Jupyter Notebook code example** " +"([#833](https://github.com/adap/flower/pull/833))" msgstr "" -#: ../../source/ref-telemetry.md:3 +#: ../../source/ref-changelog.md:797 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to " -"make well-informed decisions to improve Flower. Doing this enables the " -"Flower team to understand how Flower is used and what challenges users " -"might face." +"A new code example (`quickstart_simulation`) demonstrates Flower " +"simulations using the Virtual Client Engine through Jupyter Notebook " +"(incl. Google Colab)." msgstr "" -#: ../../source/ref-telemetry.md:5 +#: ../../source/ref-changelog.md:799 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users that do not want to share anonymous usage metrics." +"**Client properties (feature preview)** " +"([#795](https://github.com/adap/flower/pull/795))" msgstr "" -#: ../../source/ref-telemetry.md:7 -msgid "Principles" +#: ../../source/ref-changelog.md:801 +msgid "" +"Clients can implement a new method `get_properties` to enable server-side" +" strategies to query client properties." msgstr "" -#: ../../source/ref-telemetry.md:9 -msgid "We follow strong principles guarding anonymous usage metrics collection:" +#: ../../source/ref-changelog.md:803 +msgid "" +"**Experimental Android support with TFLite** " +"([#865](https://github.com/adap/flower/pull/865))" msgstr "" -#: ../../source/ref-telemetry.md:11 +#: ../../source/ref-changelog.md:805 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to " -"learn “[How to opt-out](#how-to-opt-out)”." +"Android support has finally arrived in `main`! Flower is both client-" +"agnostic and framework-agnostic by design. One can integrate arbitrary " +"client platforms and with this release, using Flower on Android has " +"become a lot easier." msgstr "" -#: ../../source/ref-telemetry.md:12 +#: ../../source/ref-changelog.md:807 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not " -"contain any personally identifiable information (PII). See “[Collected " -"metrics](#collected-metrics)” to understand what metrics are being " -"reported." +"The example uses TFLite on the client side, along with a new " +"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " +"still experimental, but they are a first step towards a fully-fledged " +"Android SDK and a unified `FedAvg` implementation that integrated the new" +" functionality from `FedAvgAndroid`." msgstr "" -#: ../../source/ref-telemetry.md:13 +#: ../../source/ref-changelog.md:809 msgid "" -"**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-" -"to-inspect-what-is-being-reported)”" +"**Make gRPC keepalive time user-configurable and decrease default " +"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -#: ../../source/ref-telemetry.md:14 +#: ../../source/ref-changelog.md:811 msgid "" -"**Open for feedback:** You can always reach out to us if you have " -"feedback; see the section “[How to contact us](#how-to-contact-us)” for " -"details." +"The default gRPC keepalive time has been reduced to increase the " +"compatibility of Flower with more cloud environments (for example, " +"Microsoft Azure). Users can configure the keepalive time to customize the" +" gRPC stack based on specific requirements." msgstr "" -#: ../../source/ref-telemetry.md:16 -msgid "How to opt-out" +#: ../../source/ref-changelog.md:813 +msgid "" +"**New differential privacy example using Opacus and PyTorch** " +"([#805](https://github.com/adap/flower/pull/805))" msgstr "" -#: ../../source/ref-telemetry.md:18 +#: ../../source/ref-changelog.md:815 msgid "" -"When Flower starts, it will check for an environment variable called " -"`FLWR_TELEMETRY_ENABLED`. Telemetry can easily be disabled by setting " -"`FLWR_TELEMETRY_ENABLED=0`. Assuming you are starting a Flower server or " -"client, simply do so by prepending your command as in:" +"A new code example (`opacus`) demonstrates differentially-private " +"federated learning with Opacus, PyTorch, and Flower." msgstr "" -#: ../../source/ref-telemetry.md:24 +#: ../../source/ref-changelog.md:817 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," -" `.bashrc` (or whatever configuration file applies to your environment) " -"to disable Flower telemetry permanently." +"**New Hugging Face Transformers code example** " +"([#863](https://github.com/adap/flower/pull/863))" msgstr "" -#: ../../source/ref-telemetry.md:26 -msgid "Collected metrics" +#: ../../source/ref-changelog.md:819 +msgid "" +"A new code example (`quickstart_huggingface`) demonstrates usage of " +"Hugging Face Transformers with Flower." msgstr "" -#: ../../source/ref-telemetry.md:28 -msgid "Flower telemetry collects the following metrics:" +#: ../../source/ref-changelog.md:821 +msgid "" +"**New MLCube code example** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" msgstr "" -#: ../../source/ref-telemetry.md:30 +#: ../../source/ref-changelog.md:823 msgid "" -"**Flower version.** Understand which versions of Flower are currently " -"being used. This helps us to decide whether we should invest effort into " -"releasing a patch version for an older version of Flower or instead use " -"the bandwidth to build new features." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " +"with Flower." msgstr "" -#: ../../source/ref-telemetry.md:32 +#: ../../source/ref-changelog.md:825 msgid "" -"**Operating system.** Enables us to answer questions such as: *Should we " -"create more guides for Linux, macOS, or Windows?*" +"**SSL-enabled server and client** " +"([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" msgstr "" -#: ../../source/ref-telemetry.md:34 +#: ../../source/ref-changelog.md:827 msgid "" -"**Python version.** Knowing the Python version helps us, for example, to " -"decide whether we should invest effort into supporting old versions of " -"Python or stop supporting them and start taking advantage of new Python " -"features." +"SSL enables secure encrypted connections between clients and servers. " +"This release open-sources the Flower secure gRPC implementation to make " +"encrypted communication channels accessible to all Flower users." msgstr "" -#: ../../source/ref-telemetry.md:36 +#: ../../source/ref-changelog.md:829 msgid "" -"**Hardware properties.** Understanding the hardware environment that " -"Flower is being used in helps to decide whether we should, for example, " -"put more effort into supporting low-resource environments." +"**Updated** `FedAdam` **and** `FedYogi` **strategies** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" msgstr "" -#: ../../source/ref-telemetry.md:38 +#: ../../source/ref-changelog.md:831 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables " -"us to understand how heavily certain features are being used and better " -"prioritize based on that." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive " +"Federated Optimization paper." msgstr "" -#: ../../source/ref-telemetry.md:40 +#: ../../source/ref-changelog.md:833 msgid "" -"**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " -"time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete " -"them." +"**Initialize** `start_simulation` **with a list of client IDs** " +"([#860](https://github.com/adap/flower/pull/860))" msgstr "" -#: ../../source/ref-telemetry.md:42 +#: ../../source/ref-changelog.md:835 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in " -"`~/.flwr/source` the first time a telemetry event is generated. The " -"source ID is important to identify whether an issue is recurring or " -"whether an issue is triggered by multiple clusters running concurrently " -"(which often happens in simulation). For example, if a device runs " -"multiple workloads at the same time, and this results in an issue, then, " -"in order to reproduce the issue, multiple workloads must be started at " -"the same time." +"`start_simulation` can now be called with a list of client IDs " +"(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " +"`client_fn` whenever a client needs to be initialized, which can make it " +"easier to load data partitions that are not accessible through `int` " +"identifiers." msgstr "" -#: ../../source/ref-telemetry.md:44 +#: ../../source/ref-changelog.md:839 msgid "" -"You may delete the source ID at any time. If you wish for all events " -"logged under a specific source ID to be deleted, you can send a deletion " -"request mentioning the source ID to `telemetry@flower.ai`. All events " -"related to that source ID will then be permanently deleted." +"Update `num_examples` calculation in PyTorch code examples in " +"([#909](https://github.com/adap/flower/pull/909))" msgstr "" -#: ../../source/ref-telemetry.md:46 +#: ../../source/ref-changelog.md:840 msgid "" -"We will not collect any personally identifiable information. If you think" -" any of the metrics collected could be misused in any way, please [get in" -" touch with us](#how-to-contact-us). We will update this page to reflect " -"any changes to the metrics collected and publish changes in the " -"changelog." +"Expose Flower version through `flwr.__version__` " +"([#952](https://github.com/adap/flower/pull/952))" msgstr "" -#: ../../source/ref-telemetry.md:48 +#: ../../source/ref-changelog.md:841 msgid "" -"If you think other metrics would be helpful for us to better guide our " -"decisions, please let us know! We will carefully review them; if we are " -"confident that they do not compromise user privacy, we may add them." +"`start_server` in `app.py` now returns a `History` object containing " +"metrics from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -#: ../../source/ref-telemetry.md:50 -msgid "How to inspect what is being reported" +#: ../../source/ref-changelog.md:842 +msgid "" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " +"([#978](https://github.com/adap/flower/pull/978))" msgstr "" -#: ../../source/ref-telemetry.md:52 +#: ../../source/ref-changelog.md:843 msgid "" -"We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information" -" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " -"is disabled by default. You may use logging independently from " -"`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " -"without sending any metrics." +"Increase sleep time after server start to three seconds in all code " +"examples ([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" -#: ../../source/ref-telemetry.md:58 +#: ../../source/ref-changelog.md:844 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics," -" use both environment variables:" +"Added a new FAQ section to the documentation " +"([#948](https://github.com/adap/flower/pull/948))" msgstr "" -#: ../../source/ref-telemetry.md:64 -msgid "How to contact us" +#: ../../source/ref-changelog.md:845 +msgid "" +"And many more under-the-hood changes, library updates, documentation " +"changes, and tooling improvements!" msgstr "" -#: ../../source/ref-telemetry.md:66 +#: ../../source/ref-changelog.md:849 msgid "" -"We want to hear from you. If you have any feedback or ideas on how to " -"improve the way we handle anonymous usage metrics, reach out to us via " -"[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " -"(`telemetry@flower.ai`)." +"**Removed** `flwr_example` **and** `flwr_experimental` **from release " +"build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/tutorial-quickstart-android.rst:-1 +#: ../../source/ref-changelog.md:851 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android " -"app using Flower." +"The packages `flwr_example` and `flwr_experimental` have been deprecated " +"since Flower 0.12.0 and they are not longer included in Flower release " +"builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " +"an upcoming release." msgstr "" -#: ../../source/tutorial-quickstart-android.rst:5 -msgid "Quickstart Android" +#: ../../source/ref-changelog.md:853 +msgid "v0.17.0 (2021-09-24)" msgstr "" -#: ../../source/tutorial-quickstart-android.rst:10 +#: ../../source/ref-changelog.md:857 msgid "" -"Let's build a federated learning system using TFLite and Flower on " -"Android!" +"**Experimental virtual client engine** " +"([#781](https://github.com/adap/flower/pull/781) " +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/tutorial-quickstart-android.rst:12 +#: ../../source/ref-changelog.md:859 msgid "" -"Please refer to the `full code example " -"`_ to learn " -"more." +"One of Flower's goals is to enable research at scale. This release " +"enables a first (experimental) peek at a major new feature, codenamed the" +" virtual client engine. Virtual clients enable simulations that scale to " +"a (very) large number of clients on a single machine or compute cluster. " +"The easiest way to test the new functionality is to look at the two new " +"code examples called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -#: ../../source/tutorial-quickstart-fastai.rst:-1 +#: ../../source/ref-changelog.md:861 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with FastAI to train a vision model on CIFAR-10." -msgstr "" - -#: ../../source/tutorial-quickstart-fastai.rst:5 -msgid "Quickstart fastai" +"The feature is still experimental, so there's no stability guarantee for " +"the API. It's also not quite ready for prime time and comes with a few " +"known caveats. However, those who are curious are encouraged to try it " +"out and share their thoughts." msgstr "" -#: ../../source/tutorial-quickstart-fastai.rst:10 -msgid "Let's build a federated learning system using fastai and Flower!" +#: ../../source/ref-changelog.md:863 +msgid "" +"**New built-in strategies** " +"([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822))" msgstr "" -#: ../../source/tutorial-quickstart-fastai.rst:12 +#: ../../source/ref-changelog.md:865 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"FedYogi - Federated learning strategy using Yogi on server-side. " +"Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:-1 +#: ../../source/ref-changelog.md:866 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower " -"with HuggingFace Transformers in order to fine-tune an LLM." +"FedAdam - Federated learning strategy using Adam on server-side. " +"Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:5 -msgid "Quickstart 🤗 Transformers" +#: ../../source/ref-changelog.md:868 +msgid "" +"**New PyTorch Lightning code example** " +"([#617](https://github.com/adap/flower/pull/617))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:10 +#: ../../source/ref-changelog.md:870 msgid "" -"Let's build a federated learning system using Hugging Face Transformers " -"and Flower!" +"**New Variational Auto-Encoder code example** " +"([#752](https://github.com/adap/flower/pull/752))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:12 +#: ../../source/ref-changelog.md:872 msgid "" -"We will leverage Hugging Face to federate the training of language models" -" over multiple clients using Flower. More specifically, we will fine-tune" -" a pre-trained Transformer model (distilBERT) for sequence classification" -" over a dataset of IMDB ratings. The end goal is to detect if a movie " -"rating is positive or negative." +"**New scikit-learn code example** " +"([#748](https://github.com/adap/flower/pull/748))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:18 -msgid "Dependencies" +#: ../../source/ref-changelog.md:874 +msgid "" +"**New experimental TensorBoard strategy** " +"([#789](https://github.com/adap/flower/pull/789))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:20 +#: ../../source/ref-changelog.md:878 msgid "" -"To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " -":code:`torch`, and :code:`transformers`. This can be done using " -":code:`pip`:" +"Improved advanced TensorFlow code example " +"([#769](https://github.com/adap/flower/pull/769))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:30 -msgid "Standard Hugging Face workflow" +#: ../../source/ref-changelog.md:879 +msgid "" +"Warning when `min_available_clients` is misconfigured " +"([#830](https://github.com/adap/flower/pull/830))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:33 -msgid "Handling the data" +#: ../../source/ref-changelog.md:880 +msgid "" +"Improved gRPC server docs " +"([#841](https://github.com/adap/flower/pull/841))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:35 +#: ../../source/ref-changelog.md:881 msgid "" -"To fetch the IMDB dataset, we will use Hugging Face's :code:`datasets` " -"library. We then need to tokenize the data and create :code:`PyTorch` " -"dataloaders, this is all done in the :code:`load_data` function:" +"Improved error message in `NumPyClient` " +"([#851](https://github.com/adap/flower/pull/851))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:81 -msgid "Training and testing the model" +#: ../../source/ref-changelog.md:882 +msgid "" +"Improved PyTorch quickstart code example " +"([#852](https://github.com/adap/flower/pull/852))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:83 +#: ../../source/ref-changelog.md:886 msgid "" -"Once we have a way of creating our trainloader and testloader, we can " -"take care of the training and testing. This is very similar to any " -":code:`PyTorch` training or testing loop:" +"**Disabled final distributed evaluation** " +"([#800](https://github.com/adap/flower/pull/800))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:121 -msgid "Creating the model itself" +#: ../../source/ref-changelog.md:888 +msgid "" +"Prior behaviour was to perform a final round of distributed evaluation on" +" all connected clients, which is often not required (e.g., when using " +"server-side evaluation). The prior behaviour can be enabled by passing " +"`force_final_distributed_eval=True` to `start_server`." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:123 +#: ../../source/ref-changelog.md:890 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT" -" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"**Renamed q-FedAvg strategy** " +"([#802](https://github.com/adap/flower/pull/802))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:136 -msgid "Federating the example" +#: ../../source/ref-changelog.md:892 +msgid "" +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " +"the notation given in the original paper (q-FFL is the optimization " +"objective, q-FedAvg is the proposed solver). Note the original (now " +"deprecated) `QffedAvg` class is still available for compatibility reasons" +" (it will be removed in a future release)." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:139 -msgid "Creating the IMDBClient" +#: ../../source/ref-changelog.md:894 +msgid "" +"**Deprecated and renamed code example** `simulation_pytorch` **to** " +"`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:141 +#: ../../source/ref-changelog.md:896 msgid "" -"To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " -"This is very easy, as our model is a standard :code:`PyTorch` model:" +"This example has been replaced by a new example. The new example is based" +" on the experimental virtual client engine, which will become the new " +"default way of doing most types of large-scale simulations in Flower. The" +" existing example was kept for reference purposes, but it might be " +"removed in the future." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:169 -msgid "" -"The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the " -"server to send its parameters to the client. Finally, the :code:`fit` " -"function trains the model locally for the client, and the " -":code:`evaluate` function tests the model locally and returns the " -"relevant metrics." +#: ../../source/ref-changelog.md:898 +msgid "v0.16.0 (2021-05-11)" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:175 -msgid "Starting the server" +#: ../../source/ref-changelog.md:902 +msgid "" +"**New built-in strategies** " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:177 -msgid "" -"Now that we have a way to instantiate clients, we need to create our " -"server in order to aggregate the results. Using Flower, this can be done " -"very easily by first choosing a strategy (here, we are using " -":code:`FedAvg`, which will define the global weights as the average of " -"all the clients' weights at each round) and then using the " -":code:`flwr.server.start_server` function:" +#: ../../source/ref-changelog.md:904 +msgid "(abstract) FedOpt" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:205 +#: ../../source/ref-changelog.md:907 msgid "" -"The :code:`weighted_average` function is there to provide a way to " -"aggregate the metrics distributed amongst the clients (basically this " -"allows us to display a nice average accuracy and loss for every round)." +"**Custom metrics for server and strategies** " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:209 -msgid "Putting everything together" +#: ../../source/ref-changelog.md:909 +msgid "" +"The Flower server is now fully task-agnostic, all remaining instances of " +"task-specific metrics (such as `accuracy`) have been replaced by custom " +"metrics dictionaries. Flower 0.15 introduced the capability to pass a " +"dictionary containing custom metrics from client to server. As of this " +"release, custom metrics replace task-specific metrics on the server." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:211 -msgid "We can now start client instances using:" +#: ../../source/ref-changelog.md:911 +msgid "" +"Custom metric dictionaries are now used in two user-facing APIs: they are" +" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " +"they enable evaluation functions passed to built-in strategies (via " +"`eval_fn`) to return more than two evaluation metrics. Strategies can " +"even return *aggregated* metrics dictionaries for the server to keep " +"track of." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:221 +#: ../../source/ref-changelog.md:913 msgid "" -"And they will be able to connect to the server and start the federated " -"training." +"Strategy implementations should migrate their `aggregate_fit` and " +"`aggregate_evaluate` methods to the new return type (e.g., by simply " +"returning an empty `{}`), server-side evaluation functions should migrate" +" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:223 +#: ../../source/ref-changelog.md:915 msgid "" -"If you want to check out everything put together, you should check out " -"the `full code example `_ ." +"Flower 0.15-style return types are deprecated (but still supported), " +"compatibility will be removed in a future release." msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:226 +#: ../../source/ref-changelog.md:917 msgid "" -"Of course, this is a very basic example, and a lot can be added or " -"modified, it was just to showcase how simply we could federate a Hugging " -"Face workflow using Flower." +"**Migration warnings for deprecated functionality** " +"([#690](https://github.com/adap/flower/pull/690))" msgstr "" -#: ../../source/tutorial-quickstart-huggingface.rst:229 +#: ../../source/ref-changelog.md:919 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very" -" well used :code:`TensorFlow`." +"Earlier versions of Flower were often migrated to new APIs, while " +"maintaining compatibility with legacy APIs. This release introduces " +"detailed warning messages if usage of deprecated APIs is detected. The " +"new warning messages often provide details on how to migrate to more " +"recent APIs, thus easing the transition from one release to another." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:-1 +#: ../../source/ref-changelog.md:921 msgid "" -"Read this Federated Learning quickstart tutorial for creating an iOS app " -"using Flower to train a neural network on MNIST." +"Improved docs and docstrings " +"([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:5 -msgid "Quickstart iOS" +#: ../../source/ref-changelog.md:923 +msgid "MXNet example and documentation" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:10 +#: ../../source/ref-changelog.md:925 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST " -"using Flower and CoreML on iOS devices." +"FedBN implementation in example PyTorch: From Centralized To Federated " +"([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:12 +#: ../../source/ref-changelog.md:929 msgid "" -"First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv" -" `. For the Flower client " -"implementation in iOS, it is recommended to use Xcode as our IDE." +"**Serialization-agnostic server** " +"([#721](https://github.com/adap/flower/pull/721))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:15 +#: ../../source/ref-changelog.md:931 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that" -" all have the same model." +"The Flower server is now fully serialization-agnostic. Prior usage of " +"class `Weights` (which represents parameters as deserialized NumPy " +"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " +"`Parameters` objects are fully serialization-agnostic and represents " +"parameters as byte arrays, the `tensor_type` attributes indicates how " +"these byte arrays should be interpreted (e.g., for " +"serialization/deserialization)." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:17 +#: ../../source/ref-changelog.md:933 msgid "" -"*Clients* are responsible for generating individual weight updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"Built-in strategies implement this approach by handling serialization and" +" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"implementations should update to the slightly changed Strategy method " +"definitions. Strategy authors can consult PR " +"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" +" easily migrate to the new format." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:21 +#: ../../source/ref-changelog.md:935 msgid "" -"Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You" -" can do this by using pip:" +"Deprecated `flwr.server.Server.evaluate`, use " +"`flwr.server.Server.evaluate_round` instead " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:27 -msgid "Or Poetry:" +#: ../../source/ref-changelog.md:937 +msgid "v0.15.0 (2021-03-12)" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:34 -#: ../../source/tutorial-quickstart-mxnet.rst:36 -#: ../../source/tutorial-quickstart-pytorch.rst:37 -#: ../../source/tutorial-quickstart-scikitlearn.rst:40 -#: ../../source/tutorial-quickstart-tensorflow.rst:29 -#: ../../source/tutorial-quickstart-xgboost.rst:55 -msgid "Flower Client" +#: ../../source/ref-changelog.md:941 +msgid "" +"**Server-side parameter initialization** " +"([#658](https://github.com/adap/flower/pull/658))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:36 +#: ../../source/ref-changelog.md:943 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and " -"MNIST as our dataset. For simplicity reasons we will use the complete " -"Flower client with CoreML, that has been implemented and stored inside " -"the Swift SDK. The client implementation can be seen below:" +"Model parameters can now be initialized on the server-side. Server-side " +"parameter initialization works via a new `Strategy` method called " +"`initialize_parameters`." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:72 +#: ../../source/ref-changelog.md:945 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a" -" dependency in your project. For our application, we will store the logic" -" of our app in :code:`FLiOSModel.swift` and the UI elements in " -":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" -" in this quickstart. Please refer to the `full code example " -"`_ to learn more " -"about the app." +"Built-in strategies support a new constructor argument called " +"`initial_parameters` to set the initial parameters. Built-in strategies " +"will provide these initial parameters to the server on startup and then " +"delete them to free the memory afterwards." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:75 -msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" +#: ../../source/ref-changelog.md:964 +msgid "" +"If no initial parameters are provided to the strategy, the server will " +"continue to use the current behaviour (namely, it will ask one of the " +"connected clients for its parameters and use these as the initial global " +"parameters)." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:83 -msgid "" -"Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS " -"device. We need to pass the url to access mlmodel and run CoreML machine " -"learning processes, it can be retrieved by calling the function " -":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " -"into :code:`MLBatchProvider` object. The preprocessing is done inside " -":code:`DataLoader.swift`." +#: ../../source/ref-changelog.md:966 +msgid "Deprecations" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:99 +#: ../../source/ref-changelog.md:968 msgid "" -"Since CoreML does not allow the model parameters to be seen before " -"training, and accessing the model parameters during or after the training" -" can only be done by specifying the layer name, we need to know this " -"information beforehand, through looking at the model specification, which" -" are written as proto files. The implementation can be seen in " -":code:`MLModelInspect`." +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " +"`flwr.server.strategy.FedAvg`, which is equivalent)" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:102 -msgid "" -"After we have all of the necessary information, let's create our Flower " -"client." +#: ../../source/ref-changelog.md:970 +msgid "v0.14.0 (2021-02-18)" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:117 +#: ../../source/ref-changelog.md:974 msgid "" -"Then start the Flower gRPC client and start communicating to the server " -"by passing our Flower client to the function :code:`startFlwrGRPC`." +"**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " +"([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:124 +#: ../../source/ref-changelog.md:976 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " -"The attribute :code:`hostname` and :code:`port` tells the client which " -"server to connect to. This can be done by entering the hostname and port " -"in the application before clicking the start button to start the " -"federated learning process." +"Clients can now return an additional dictionary mapping `str` keys to " +"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " +"This means one can return almost arbitrary values from `fit`/`evaluate` " +"and make use of them on the server side!" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:129 -#: ../../source/tutorial-quickstart-mxnet.rst:226 -#: ../../source/tutorial-quickstart-pytorch.rst:203 -#: ../../source/tutorial-quickstart-scikitlearn.rst:157 -#: ../../source/tutorial-quickstart-tensorflow.rst:98 -#: ../../source/tutorial-quickstart-xgboost.rst:309 -msgid "Flower Server" +#: ../../source/ref-changelog.md:978 +msgid "" +"This improvement also allowed for more consistent return types between " +"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " +"dict)` representing the loss, number of examples, and a dictionary " +"holding arbitrary problem-specific values like accuracy." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:131 -#: ../../source/tutorial-quickstart-mxnet.rst:228 -#: ../../source/tutorial-quickstart-pytorch.rst:205 -#: ../../source/tutorial-quickstart-tensorflow.rst:100 +#: ../../source/ref-changelog.md:980 msgid "" -"For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named " -":code:`server.py`, import Flower and start the server:" +"In case you wondered: this feature is compatible with existing projects, " +"the additional dictionary return value is optional. New code should " +"however migrate to the new return types to be compatible with upcoming " +"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " +"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " +"details." msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:142 -#: ../../source/tutorial-quickstart-mxnet.rst:239 -#: ../../source/tutorial-quickstart-pytorch.rst:216 -#: ../../source/tutorial-quickstart-scikitlearn.rst:215 -#: ../../source/tutorial-quickstart-tensorflow.rst:112 -msgid "Train the model, federated!" +#: ../../source/ref-changelog.md:982 +msgid "" +"*Code example:* note the additional dictionary return values in both " +"`FlwrClient.fit` and `FlwrClient.evaluate`:" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:144 -#: ../../source/tutorial-quickstart-pytorch.rst:218 -#: ../../source/tutorial-quickstart-tensorflow.rst:114 -#: ../../source/tutorial-quickstart-xgboost.rst:525 +#: ../../source/ref-changelog.md:997 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and " -"multiple clients. We therefore have to start the server first:" -msgstr "" - -#: ../../source/tutorial-quickstart-ios.rst:152 -msgid "" -"Once the server is running we can start the clients in different " -"terminals. Build and run the client through your Xcode, one through Xcode" -" Simulator and the other by deploying it to your iPhone. To see more " -"about how to deploy your app to iPhone or Simulator visit `here " -"`_." +"**Generalized** `config` **argument in** `Client.fit` **and** " +"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -#: ../../source/tutorial-quickstart-ios.rst:156 +#: ../../source/ref-changelog.md:999 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code " -"`_ for this " -"example can be found in :code:`examples/ios`." +"The `config` argument used to be of type `Dict[str, str]`, which means " +"that dictionary values were expected to be strings. The new release " +"generalizes this to enable values of the following types: `bool`, " +"`bytes`, `float`, `int`, `str`." msgstr "" -#: ../../source/tutorial-quickstart-jax.rst:-1 +#: ../../source/ref-changelog.md:1001 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Jax to train a linear regression model on a scikit-learn dataset." -msgstr "" - -#: ../../source/tutorial-quickstart-jax.rst:5 -msgid "Quickstart JAX" +"This means one can now pass almost arbitrary values to `fit`/`evaluate` " +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" +"side and `int(config[\"epochs\"])` on the client side!" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:-1 +#: ../../source/ref-changelog.md:1003 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with MXNet to train a Sequential model on MNIST." +"*Code example:* note that the `config` dictionary now contains non-`str` " +"values in both `Client.fit` and `Client.evaluate`:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:5 -msgid "Quickstart MXNet" +#: ../../source/ref-changelog.md:1020 +msgid "v0.13.0 (2021-01-08)" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:7 +#: ../../source/ref-changelog.md:1024 msgid "" -"MXNet is no longer maintained and has been moved into `Attic " -"`_. As a result, we would " -"encourage you to use other ML frameworks alongside Flower, for example, " -"PyTorch. This tutorial might be removed in future versions of Flower." +"New example: PyTorch From Centralized To Federated " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:12 -msgid "" -"In this tutorial, we will learn how to train a :code:`Sequential` model " -"on MNIST using Flower and MXNet." +#: ../../source/ref-changelog.md:1025 +msgid "Improved documentation" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:14 -#: ../../source/tutorial-quickstart-scikitlearn.rst:12 -msgid "" -"It is recommended to create a virtual environment and run everything " -"within this :doc:`virtualenv `." +#: ../../source/ref-changelog.md:1026 +msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:16 -#: ../../source/tutorial-quickstart-pytorch.rst:17 -#: ../../source/tutorial-quickstart-scikitlearn.rst:14 -msgid "" -"Our example consists of one *server* and two *clients* all having the " -"same model." +#: ../../source/ref-changelog.md:1027 +msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:18 -#: ../../source/tutorial-quickstart-scikitlearn.rst:16 +#: ../../source/ref-changelog.md:1028 msgid "" -"*Clients* are responsible for generating individual model parameter " -"updates for the model based on their local datasets. These updates are " -"then sent to the *server* which will aggregate them to produce an updated" -" global model. Finally, the *server* sends this improved version of the " -"model back to each *client*. A complete cycle of parameters updates is " -"called a *round*." +"Updated examples documentation " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:22 -#: ../../source/tutorial-quickstart-scikitlearn.rst:20 +#: ../../source/ref-changelog.md:1029 msgid "" -"Now that we have a rough idea of what is going on, let's get started. We " -"first need to install Flower. You can do this by running:" +"Removed obsolete documentation " +"([#548](https://github.com/adap/flower/pull/548))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:28 -msgid "Since we want to use MXNet, let's go ahead and install it:" +#: ../../source/ref-changelog.md:1031 +msgid "Bugfix:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:38 +#: ../../source/ref-changelog.md:1033 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on MXNet´s `Hand-written " -"Digit Recognition tutorial " -"`_." +"`Server.fit` does not disconnect clients when finished, disconnecting the" +" clients is now handled in `flwr.server.start_server` " +"([#553](https://github.com/adap/flower/pull/553) " +"[#540](https://github.com/adap/flower/issues/540))." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:40 -msgid "" -"In a file called :code:`client.py`, import Flower and MXNet related " -"packages:" +#: ../../source/ref-changelog.md:1035 +msgid "v0.12.0 (2020-12-07)" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:55 -msgid "In addition, define the device allocation in MXNet with:" +#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +msgid "Important changes:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:61 +#: ../../source/ref-changelog.md:1039 msgid "" -"We use MXNet to load MNIST, a popular image classification dataset of " -"handwritten digits for machine learning. The MXNet utility " -":code:`mx.test_utils.get_mnist()` downloads the training and test data." +"Added an example for embedded devices " +"([#507](https://github.com/adap/flower/pull/507))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:75 +#: ../../source/ref-changelog.md:1040 msgid "" -"Define the training and loss with MXNet. We train the model by looping " -"over the dataset, measure the corresponding loss, and optimize it." +"Added a new NumPyClient (in addition to the existing KerasClient) " +"([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:113 +#: ../../source/ref-changelog.md:1041 msgid "" -"Next, we define the validation of our machine learning model. We loop " -"over the test set and measure both loss and accuracy on the test set." +"Deprecated `flwr_example` package and started to migrate examples into " +"the top-level `examples` directory " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:137 -msgid "" -"After defining the training and testing of a MXNet machine learning " -"model, we use these functions to implement a Flower client." +#: ../../source/ref-changelog.md:1043 +msgid "v0.11.0 (2020-11-30)" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:139 -msgid "Our Flower clients will use a simple :code:`Sequential` model:" +#: ../../source/ref-changelog.md:1045 +msgid "Incompatible changes:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:158 +#: ../../source/ref-changelog.md:1047 msgid "" -"After loading the dataset with :code:`load_data()` we perform one forward" -" propagation to initialize the model and model parameters with " -":code:`model(init)`. Next, we implement a Flower client." +"Renamed strategy methods " +"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " +"Flower's public APIs. Other public methods/functions (e.g., every method " +"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " +"which is why we're removing it from the four methods in Strategy. To " +"migrate rename the following `Strategy` methods accordingly:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:160 -#: ../../source/tutorial-quickstart-pytorch.rst:144 -#: ../../source/tutorial-quickstart-tensorflow.rst:54 -msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to train the neural network we defined earlier)." +#: ../../source/ref-changelog.md:1048 +msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:166 -msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses MXNet. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +#: ../../source/ref-changelog.md:1049 +msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:172 -#: ../../source/tutorial-quickstart-pytorch.rst:156 -#: ../../source/tutorial-quickstart-scikitlearn.rst:109 -msgid "return the model weight as a list of NumPy ndarrays" +#: ../../source/ref-changelog.md:1050 +msgid "`on_configure_fit` => `configure_fit`" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:173 -#: ../../source/tutorial-quickstart-pytorch.rst:157 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 -msgid ":code:`set_parameters` (optional)" +#: ../../source/ref-changelog.md:1051 +msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:174 -#: ../../source/tutorial-quickstart-pytorch.rst:158 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 +#: ../../source/ref-changelog.md:1055 msgid "" -"update the local model weights with the parameters received from the " -"server" +"Deprecated `DefaultStrategy` " +"([#479](https://github.com/adap/flower/pull/479)). To migrate use " +"`FedAvg` instead." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:176 -#: ../../source/tutorial-quickstart-pytorch.rst:160 -#: ../../source/tutorial-quickstart-scikitlearn.rst:114 -msgid "set the local model weights" +#: ../../source/ref-changelog.md:1056 +msgid "" +"Simplified examples and baselines " +"([#484](https://github.com/adap/flower/pull/484))." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:177 -#: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 -msgid "train the local model" +#: ../../source/ref-changelog.md:1057 +msgid "" +"Removed presently unused `on_conclude_round` from strategy interface " +"([#483](https://github.com/adap/flower/pull/483))." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:178 -#: ../../source/tutorial-quickstart-pytorch.rst:162 -#: ../../source/tutorial-quickstart-scikitlearn.rst:116 -msgid "receive the updated local model weights" +#: ../../source/ref-changelog.md:1058 +msgid "" +"Set minimal Python version to 3.6.1 instead of 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:180 -#: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 -msgid "test the local model" +#: ../../source/ref-changelog.md:1059 +msgid "" +"Improved `Strategy` docstrings " +"([#470](https://github.com/adap/flower/pull/470))." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:182 -msgid "They can be implemented in the following way:" +#: ../../source/ref-example-projects.rst:2 +msgid "Example projects" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:212 +#: ../../source/ref-example-projects.rst:4 msgid "" -"We can now create an instance of our class :code:`MNISTClient` and add " -"one line to actually run this client:" +"Flower comes with a number of usage examples. The examples demonstrate " +"how Flower can be used to federate different kinds of existing machine " +"learning pipelines, usually leveraging popular machine learning " +"frameworks such as `PyTorch `_ or `TensorFlow " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:219 +#: ../../source/ref-example-projects.rst:10 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()` or " -":code:`fl.client.start_numpy_client()`. The string " -":code:`\"0.0.0.0:8080\"` tells the client which server to connect to. In " -"our case we can run the server and the client on the same machine, " -"therefore we use :code:`\"0.0.0.0:8080\"`. If we run a truly federated " -"workload with the server and clients running on different machines, all " -"that needs to change is the :code:`server_address` we pass to the client." +"The following examples are available as standalone projects. Quickstart " +"TensorFlow/Keras ---------------------------" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:241 +#: ../../source/ref-example-projects.rst:14 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We therefore have to start the server first:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image " +"classification with MobileNetV2:" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:249 -#: ../../source/tutorial-quickstart-pytorch.rst:226 -#: ../../source/tutorial-quickstart-scikitlearn.rst:224 -#: ../../source/tutorial-quickstart-tensorflow.rst:122 -#: ../../source/tutorial-quickstart-xgboost.rst:533 +#: ../../source/ref-example-projects.rst:17 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Open a new terminal and start the first client:" +"`Quickstart TensorFlow (Code) " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:256 -#: ../../source/tutorial-quickstart-pytorch.rst:233 -#: ../../source/tutorial-quickstart-scikitlearn.rst:231 -#: ../../source/tutorial-quickstart-tensorflow.rst:129 -#: ../../source/tutorial-quickstart-xgboost.rst:540 -msgid "Open another terminal and start the second client:" +#: ../../source/ref-example-projects.rst:18 +msgid ":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:262 -#: ../../source/tutorial-quickstart-pytorch.rst:239 -#: ../../source/tutorial-quickstart-scikitlearn.rst:237 -#: ../../source/tutorial-quickstart-xgboost.rst:546 +#: ../../source/ref-example-projects.rst:19 msgid "" -"Each client will have its own dataset. You should now see how the " -"training does in the very first terminal (the one that started the " -"server):" +"`Quickstart TensorFlow (Blog Post) `_" +msgstr "" + +#: ../../source/ref-example-projects.rst:23 +#: ../../source/tutorial-quickstart-pytorch.rst:5 +msgid "Quickstart PyTorch" msgstr "" -#: ../../source/tutorial-quickstart-mxnet.rst:294 +#: ../../source/ref-example-projects.rst:25 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-mxnet`." +"The PyTorch quickstart example shows CIFAR-10 image classification with a" +" simple Convolutional Neural Network:" msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:-1 +#: ../../source/ref-example-projects.rst:28 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Pandas to perform Federated Analytics." +"`Quickstart PyTorch (Code) " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:5 -msgid "Quickstart Pandas" +#: ../../source/ref-example-projects.rst:29 +msgid ":doc:`Quickstart PyTorch (Tutorial) `" msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:10 -msgid "Let's build a federated analytics system using Pandas and Flower!" +#: ../../source/ref-example-projects.rst:33 +msgid "PyTorch: From Centralized To Federated" msgstr "" -#: ../../source/tutorial-quickstart-pandas.rst:12 +#: ../../source/ref-example-projects.rst:35 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"This example shows how a regular PyTorch project can be federated using " +"Flower:" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:-1 +#: ../../source/ref-example-projects.rst:37 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch to train a CNN model on MNIST." +"`PyTorch: From Centralized To Federated (Code) " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:13 +#: ../../source/ref-example-projects.rst:38 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural " -"Network on CIFAR10 using Flower and PyTorch." +":doc:`PyTorch: From Centralized To Federated (Tutorial) `" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:15 -#: ../../source/tutorial-quickstart-xgboost.rst:39 -msgid "" -"First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +#: ../../source/ref-example-projects.rst:42 +msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:19 +#: ../../source/ref-example-projects.rst:44 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"This example shows how Flower can be used to build a federated learning " +"system that run across Raspberry Pi and Nvidia Jetson:" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:23 +#: ../../source/ref-example-projects.rst:46 msgid "" -"Now that we have a rough idea of what is going on, let's get started. We " -"first need to install Flower. You can do this by running :" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:29 +#: ../../source/ref-example-projects.rst:47 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go " -"ahead and install PyTorch and the **torchvision** library:" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:39 +#: ../../source/ref-faq.rst:4 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on PyTorch's `Deep Learning " -"with PyTorch " -"`_." +"This page collects answers to commonly asked questions about Federated " +"Learning with Flower." msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:41 -msgid "" -"In a file called :code:`client.py`, import Flower and PyTorch related " -"packages:" +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:56 -msgid "In addition, we define the device allocation in PyTorch with:" +#: ../../source/ref-faq.rst:8 +msgid "" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to" +" make it work even better on Colab. Here's a quickstart example:" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:62 +#: ../../source/ref-faq.rst:10 msgid "" -"We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " -"the training and test data that are then normalized." +"`Flower simulation PyTorch " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:78 +#: ../../source/ref-faq.rst:11 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset " -"is done by looping over the dataset, measure the corresponding loss and " -"optimize it." +"`Flower simulation TensorFlow/Keras " +"`_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:94 -msgid "" -"Define then the validation of the machine learning network. We loop over" -" the test set and measure the loss and accuracy of the test set." +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:113 +#: ../../source/ref-faq.rst:15 msgid "" -"After defining the training and testing of a PyTorch machine learning " -"model, we use the functions for the Flower clients." +"Find the `blog post about federated learning on embedded device here " +"`_" +" and the corresponding `GitHub code example " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:115 -msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " -"Minute Blitz':" +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:142 +#: ../../source/ref-faq.rst:19 msgid "" -"After loading the data set with :code:`load_data()` we define the Flower " -"interface." +"Yes, it does. Please take a look at our `blog post " +"`_ or check out the code examples:" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:150 +#: ../../source/ref-faq.rst:21 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"`Android Kotlin example `_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:166 -msgid "which can be implemented in the following way:" +#: ../../source/ref-faq.rst:22 +msgid "`Android Java example `_" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:189 -#: ../../source/tutorial-quickstart-tensorflow.rst:82 -msgid "" -"We can now create an instance of our class :code:`CifarClient` and add " -"one line to actually run this client:" +#: ../../source/ref-faq.rst +msgid ":fa:`eye,mr-1` Can I combine federated learning with blockchain?" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:196 -#: ../../source/tutorial-quickstart-tensorflow.rst:90 +#: ../../source/ref-faq.rst:26 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " -"the client which server to connect to. In our case we can run the server " -"and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"Yes, of course. A list of available examples using Flower within a " +"blockchain environment is available here:" msgstr "" -#: ../../source/tutorial-quickstart-pytorch.rst:271 +#: ../../source/ref-faq.rst:28 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-pytorch`." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 +#: ../../source/ref-faq.rst:29 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch Lightning to train an Auto Encoder model on MNIST." +"`Flower meets Nevermined YouTube video " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 -msgid "Quickstart PyTorch Lightning" +#: ../../source/ref-faq.rst:30 +msgid "" +"`Flower meets KOSMoS `_." msgstr "" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 +#: ../../source/ref-faq.rst:31 msgid "" -"Let's build a horizontal federated learning system using PyTorch " -"Lightning and Flower!" +"`Flower meets Talan blog post `_ ." msgstr "" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 +#: ../../source/ref-faq.rst:32 msgid "" -"Please refer to the `full code example " -"`_ to learn more." +"`Flower meets Talan GitHub Repository " +"`_ ." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 -msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with scikit-learn to train a linear regression model." +#: ../../source/ref-telemetry.md:1 +msgid "Telemetry" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:5 -msgid "Quickstart scikit-learn" +#: ../../source/ref-telemetry.md:3 +msgid "" +"The Flower open-source project collects **anonymous** usage metrics to " +"make well-informed decisions to improve Flower. Doing this enables the " +"Flower team to understand how Flower is used and what challenges users " +"might face." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:10 +#: ../../source/ref-telemetry.md:5 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic " -"Regression` model on MNIST using Flower and scikit-learn." +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users that do not want to share anonymous usage metrics." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:26 -msgid "Since we want to use scikit-learn, let's go ahead and install it:" +#: ../../source/ref-telemetry.md:7 +msgid "Principles" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:32 -msgid "Or simply install all dependencies using Poetry:" +#: ../../source/ref-telemetry.md:9 +msgid "We follow strong principles guarding anonymous usage metrics collection:" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:42 +#: ../../source/ref-telemetry.md:11 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that" -" we need for our federated learning setup within :code:`utils.py`. The " -":code:`utils.py` contains different functions defining all the machine " -"learning basics:" +"**Optional:** You will always be able to disable telemetry; read on to " +"learn “[How to opt-out](#how-to-opt-out)”." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:45 -msgid ":code:`get_model_parameters()`" +#: ../../source/ref-telemetry.md:12 +msgid "" +"**Anonymous:** The reported usage metrics are anonymous and do not " +"contain any personally identifiable information (PII). See “[Collected " +"metrics](#collected-metrics)” to understand what metrics are being " +"reported." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:46 -msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" +#: ../../source/ref-telemetry.md:13 +msgid "" +"**Transparent:** You can easily inspect what anonymous metrics are being " +"reported; see the section “[How to inspect what is being reported](#how-" +"to-inspect-what-is-being-reported)”" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:47 -msgid ":code:`set_model_params()`" +#: ../../source/ref-telemetry.md:14 +msgid "" +"**Open for feedback:** You can always reach out to us if you have " +"feedback; see the section “[How to contact us](#how-to-contact-us)” for " +"details." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:48 -msgid "Sets the parameters of a :code:`sklean` LogisticRegression model" +#: ../../source/ref-telemetry.md:16 +msgid "How to opt-out" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:49 -msgid ":code:`set_initial_params()`" +#: ../../source/ref-telemetry.md:18 +msgid "" +"When Flower starts, it will check for an environment variable called " +"`FLWR_TELEMETRY_ENABLED`. Telemetry can easily be disabled by setting " +"`FLWR_TELEMETRY_ENABLED=0`. Assuming you are starting a Flower server or " +"client, simply do so by prepending your command as in:" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:50 -msgid "Initializes the model parameters that the Flower server will ask for" +#: ../../source/ref-telemetry.md:24 +msgid "" +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," +" `.bashrc` (or whatever configuration file applies to your environment) " +"to disable Flower telemetry permanently." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:51 -msgid ":code:`load_mnist()`" +#: ../../source/ref-telemetry.md:26 +msgid "Collected metrics" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:52 -msgid "Loads the MNIST dataset using OpenML" +#: ../../source/ref-telemetry.md:28 +msgid "Flower telemetry collects the following metrics:" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:53 -msgid ":code:`shuffle()`" +#: ../../source/ref-telemetry.md:30 +msgid "" +"**Flower version.** Understand which versions of Flower are currently " +"being used. This helps us to decide whether we should invest effort into " +"releasing a patch version for an older version of Flower or instead use " +"the bandwidth to build new features." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:54 -msgid "Shuffles data and its label" +#: ../../source/ref-telemetry.md:32 +msgid "" +"**Operating system.** Enables us to answer questions such as: *Should we " +"create more guides for Linux, macOS, or Windows?*" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid ":code:`partition()`" +#: ../../source/ref-telemetry.md:34 +msgid "" +"**Python version.** Knowing the Python version helps us, for example, to " +"decide whether we should invest effort into supporting old versions of " +"Python or stop supporting them and start taking advantage of new Python " +"features." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid "Splits datasets into a number of partitions" +#: ../../source/ref-telemetry.md:36 +msgid "" +"**Hardware properties.** Understanding the hardware environment that " +"Flower is being used in helps to decide whether we should, for example, " +"put more effort into supporting low-resource environments." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:58 +#: ../../source/ref-telemetry.md:38 msgid "" -"Please check out :code:`utils.py` `here " -"`_ for more details. The pre-defined functions are used in" -" the :code:`client.py` and imported. The :code:`client.py` also requires " -"to import several packages such as Flower and scikit-learn:" +"**Execution mode.** Knowing what execution mode Flower starts in enables " +"us to understand how heavily certain features are being used and better " +"prioritize based on that." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:73 +#: ../../source/ref-telemetry.md:40 msgid "" -"We load the MNIST dataset from `OpenML " -"`_, a popular " -"image classification dataset of handwritten digits for machine learning. " -"The utility :code:`utils.load_mnist()` downloads the training and test " -"data. The training set is split afterwards into 10 partitions with " -":code:`utils.partition()`." +"**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " +"time a Flower workload starts. This allows us to understand which device " +"types not only start Flower workloads but also successfully complete " +"them." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:85 +#: ../../source/ref-telemetry.md:42 msgid "" -"Next, the logistic regression model is defined and initialized with " -":code:`utils.set_initial_params()`." +"**Source.** Flower telemetry tries to store a random source ID in " +"`~/.flwr/source` the first time a telemetry event is generated. The " +"source ID is important to identify whether an issue is recurring or " +"whether an issue is triggered by multiple clusters running concurrently " +"(which often happens in simulation). For example, if a device runs " +"multiple workloads at the same time, and this results in an issue, then, " +"in order to reproduce the issue, multiple workloads must be started at " +"the same time." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:97 +#: ../../source/ref-telemetry.md:44 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to fit the logistic regression we defined earlier)." +"You may delete the source ID at any time. If you wish for all events " +"logged under a specific source ID to be deleted, you can send a deletion " +"request mentioning the source ID to `telemetry@flower.ai`. All events " +"related to that source ID will then be permanently deleted." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:103 +#: ../../source/ref-telemetry.md:46 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " -"means defining the following methods (:code:`set_parameters` is optional " -"though):" +"We will not collect any personally identifiable information. If you think" +" any of the metrics collected could be misused in any way, please [get in" +" touch with us](#how-to-contact-us). We will update this page to reflect " +"any changes to the metrics collected and publish changes in the " +"changelog." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:112 -msgid "is directly imported with :code:`utils.set_model_params()`" +#: ../../source/ref-telemetry.md:48 +msgid "" +"If you think other metrics would be helpful for us to better guide our " +"decisions, please let us know! We will carefully review them; if we are " +"confident that they do not compromise user privacy, we may add them." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:120 -msgid "The methods can be implemented in the following way:" +#: ../../source/ref-telemetry.md:50 +msgid "How to inspect what is being reported" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:143 +#: ../../source/ref-telemetry.md:52 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add " -"one line to actually run this client:" +"We wanted to make it very easy for you to inspect what anonymous usage " +"metrics are reported. You can view all the reported telemetry information" +" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " +"is disabled by default. You may use logging independently from " +"`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " +"without sending any metrics." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:150 +#: ../../source/ref-telemetry.md:58 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" -" the client which server to connect to. In our case we can run the server" -" and the client on the same machine, therefore we use " -":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we pass to the client." +"The inspect Flower telemetry without sending any anonymous usage metrics," +" use both environment variables:" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:159 -msgid "" -"The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import " -"again all required libraries such as Flower and scikit-learn." +#: ../../source/ref-telemetry.md:64 +msgid "How to contact us" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:162 -msgid ":code:`server.py`, import Flower and start the server:" +#: ../../source/ref-telemetry.md:66 +msgid "" +"We want to hear from you. If you have any feedback or ideas on how to " +"improve the way we handle anonymous usage metrics, reach out to us via " +"[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " +"(`telemetry@flower.ai`)." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:173 +#: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and" -" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " -"function is called after each federated learning round and gives you " -"information about loss and accuracy." +"Read this Federated Learning quickstart tutorial for creating an Android " +"app using Flower." msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:198 -msgid "" -"The :code:`main` contains the server-side parameter initialization " -":code:`utils.set_initial_params()` as well as the aggregation strategy " -":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " -"federated averaging (or FedAvg), with two clients and evaluation after " -"each federated learning round. The server can be started with the command" -" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +#: ../../source/tutorial-quickstart-android.rst:5 +msgid "Quickstart Android" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:217 +#: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server " -"first:" +"Let's build a federated learning system using TFLite and Flower on " +"Android!" msgstr "" -#: ../../source/tutorial-quickstart-scikitlearn.rst:271 +#: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples/sklearn-logreg-" -"mnist`." +"Please refer to the `full code example " +"`_ to learn " +"more." msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:-1 +#: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" "Check out this Federated Learning quickstart tutorial for using Flower " -"with TensorFlow to train a MobilNetV2 model on CIFAR-10." +"with FastAI to train a vision model on CIFAR-10." msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:5 -msgid "Quickstart TensorFlow" +#: ../../source/tutorial-quickstart-fastai.rst:5 +msgid "Quickstart fastai" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:13 -msgid "Let's build a federated learning system in less than 20 lines of code!" +#: ../../source/tutorial-quickstart-fastai.rst:10 +msgid "Let's build a federated learning system using fastai and Flower!" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:15 -msgid "Before Flower can be imported we have to install it:" +#: ../../source/tutorial-quickstart-fastai.rst:12 +msgid "" +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:21 +#: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install" -" TF as well:" +"Check out this Federating Learning quickstart tutorial for using Flower " +"with HuggingFace Transformers in order to fine-tune an LLM." msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:31 -msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" +#: ../../source/tutorial-quickstart-huggingface.rst:5 +msgid "Quickstart 🤗 Transformers" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:38 +#: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image" -" classification dataset for machine learning. The call to " -":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " -"it locally, and then returns the entire training and test set as NumPy " -"ndarrays." +"Let's build a federated learning system using Hugging Face Transformers " +"and Flower!" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:47 +#: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use " -"MobilNetV2 with 10 output classes:" +"We will leverage Hugging Face to federate the training of language models" +" over multiple clients using Flower. More specifically, we will fine-tune" +" a pre-trained Transformer model (distilBERT) for sequence classification" +" over a dataset of IMDB ratings. The end goal is to detect if a movie " +"rating is positive or negative." msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:60 -msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses Keras. The :code:`NumPyClient` interface defines three " -"methods which can be implemented in the following way:" +#: ../../source/tutorial-quickstart-huggingface.rst:18 +msgid "Dependencies" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:135 -msgid "Each client will have its own dataset." +#: ../../source/tutorial-quickstart-huggingface.rst:20 +msgid "" +"To follow along this tutorial you will need to install the following " +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " +":code:`torch`, and :code:`transformers`. This can be done using " +":code:`pip`:" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:137 -msgid "" -"You should now see how the training does in the very first terminal (the " -"one that started the server):" +#: ../../source/tutorial-quickstart-huggingface.rst:30 +msgid "Standard Hugging Face workflow" msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:169 -msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this can be found in :code:`examples" -"/quickstart-tensorflow/client.py`." +#: ../../source/tutorial-quickstart-huggingface.rst:33 +msgid "Handling the data" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:-1 +#: ../../source/tutorial-quickstart-huggingface.rst:35 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with XGBoost to train classification models on trees." +"To fetch the IMDB dataset, we will use Hugging Face's :code:`datasets` " +"library. We then need to tokenize the data and create :code:`PyTorch` " +"dataloaders, this is all done in the :code:`load_data` function:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:5 -msgid "Quickstart XGBoost" +#: ../../source/tutorial-quickstart-huggingface.rst:81 +msgid "Training and testing the model" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:14 -msgid "Federated XGBoost" +#: ../../source/tutorial-quickstart-huggingface.rst:83 +msgid "" +"Once we have a way of creating our trainloader and testloader, we can " +"take care of the training and testing. This is very similar to any " +":code:`PyTorch` training or testing loop:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:16 -msgid "" -"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that " -"maximises the computational boundaries for boosted tree methods. It's " -"primarily designed to enhance both the performance and computational " -"speed of machine learning models. In XGBoost, trees are constructed " -"concurrently, unlike the sequential approach taken by GBDT." +#: ../../source/tutorial-quickstart-huggingface.rst:121 +msgid "Creating the model itself" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:20 +#: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning " -"techniques." +"To create the model itself, we will just load the pre-trained distillBERT" +" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:23 -msgid "Why federated XGBoost?" +#: ../../source/tutorial-quickstart-huggingface.rst:136 +msgid "Federating the example" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:25 -msgid "" -"Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems " -"for specialised applications, like survival analysis and financial fraud " -"detection." +#: ../../source/tutorial-quickstart-huggingface.rst:139 +msgid "Creating the IMDBClient" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:27 +#: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" -"Federated learning ensures that raw data remains on the local device, " -"making it an attractive approach for sensitive domains where data " -"security and privacy are paramount. Given the robustness and efficiency " -"of XGBoost, combining it with federated learning offers a promising " -"solution for these specific challenges." +"To federate our example to multiple clients, we first need to write our " +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " +"This is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:30 +#: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" -"In this tutorial we will learn how to train a federated XGBoost model on " -"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart " -"`_)" -" with two *clients* and one *server* to demonstrate how federated XGBoost" -" works, and then we dive into a more complex example (`full code xgboost-" -"comprehensive `_) to run various experiments." +"The :code:`get_parameters` function lets the server get the client's " +"parameters. Inversely, the :code:`set_parameters` function allows the " +"server to send its parameters to the client. Finally, the :code:`fit` " +"function trains the model locally for the client, and the " +":code:`evaluate` function tests the model locally and returns the " +"relevant metrics." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:37 -msgid "Environment Setup" +#: ../../source/tutorial-quickstart-huggingface.rst:175 +msgid "Starting the server" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:41 +#: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"We first need to install Flower and Flower Datasets. You can do this by " -"running :" +"Now that we have a way to instantiate clients, we need to create our " +"server in order to aggregate the results. Using Flower, this can be done " +"very easily by first choosing a strategy (here, we are using " +":code:`FedAvg`, which will define the global weights as the average of " +"all the clients' weights at each round) and then using the " +":code:`flwr.server.start_server` function:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:47 +#: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"Since we want to use :code:`xgboost` package to build up XGBoost trees, " -"let's go ahead and install :code:`xgboost`:" +"The :code:`weighted_average` function is there to provide a way to " +"aggregate the metrics distributed amongst the clients (basically this " +"allows us to display a nice average accuracy and loss for every round)." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:57 -msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. Now that we have all our " -"dependencies installed, let's run a simple distributed training with two " -"clients and one server." +#: ../../source/tutorial-quickstart-huggingface.rst:209 +msgid "Putting everything together" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:60 -msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower " -"Datasets and other related functions:" +#: ../../source/tutorial-quickstart-huggingface.rst:211 +msgid "We can now start client instances using:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:87 -msgid "Dataset partition and hyper-parameter selection" +#: ../../source/tutorial-quickstart-huggingface.rst:221 +msgid "" +"And they will be able to connect to the server and start the federated " +"training." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:89 +#: ../../source/tutorial-quickstart-huggingface.rst:223 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower" -" Datasets and conduct data partitioning for FL:" +"If you want to check out everything put together, you should check out " +"the `full code example `_ ." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:102 +#: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " -"the partition for the given client based on :code:`node_id`:" +"Of course, this is a very basic example, and a lot can be added or " +"modified, it was just to showcase how simply we could federate a Hugging " +"Face workflow using Flower." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:121 +#: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"After that, we do train/test splitting on the given partition (client's " -"local data), and transform data format for :code:`xgboost` package." +"Note that in this example we used :code:`PyTorch`, but we could have very" +" well used :code:`TensorFlow`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:134 +#: ../../source/tutorial-quickstart-ios.rst:-1 msgid "" -"The functions of :code:`train_test_split` and " -":code:`transform_dataset_to_dmatrix` are defined as below:" +"Read this Federated Learning quickstart tutorial for creating an iOS app " +"using Flower to train a neural network on MNIST." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:158 -msgid "Finally, we define the hyper-parameters used for XGBoost training." +#: ../../source/tutorial-quickstart-ios.rst:5 +msgid "Quickstart iOS" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:174 +#: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"The :code:`num_local_round` represents the number of iterations for local" -" tree boost. We use CPU for the training in default. One can shift it to " -"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " -"evaluation metric." -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:181 -msgid "Flower client definition for XGBoost" +"In this tutorial we will learn how to train a Neural Network on MNIST " +"using Flower and CoreML on iOS devices." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:183 +#: ../../source/tutorial-quickstart-ios.rst:12 msgid "" -"After loading the dataset we define the Flower client. We follow the " -"general rule to define :code:`XgbClient` class inherited from " -":code:`fl.client.Client`." +"First of all, for running the Flower Python server, it is recommended to " +"create a virtual environment and run everything within a :doc:`virtualenv" +" `. For the Flower client " +"implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:193 +#: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"The :code:`self.bst` is used to keep the Booster objects that remain " -"consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures" -" for training." +"Our example consists of one Python *server* and two iPhone *clients* that" +" all have the same model." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:196 +#: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and " -":code:`evaluate` methods insides :code:`XgbClient` class as follows." +"*Clients* are responsible for generating individual weight updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:210 +#: ../../source/tutorial-quickstart-ios.rst:21 msgid "" -"Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use " -":code:`get_parameters` and :code:`set_parameters` to initialise model " -"parameters for XGBoost. As a result, let's return an empty tensor in " -":code:`get_parameters` when it is called by the server at the first " -"round." +"Now that we have a rough idea of what is going on, let's get started to " +"setup our Flower server environment. We first need to install Flower. You" +" can do this by using pip:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:251 -msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " -"up the first set of trees. the returned Booster object and config are " -"stored in :code:`self.bst` and :code:`self.config`, respectively. From " -"the second round, we load the global model sent from server to " -":code:`self.bst`, and then update model weights on local training data " -"with function :code:`local_boost` as follows:" +#: ../../source/tutorial-quickstart-ios.rst:27 +msgid "Or Poetry:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:269 -msgid "" -"Given :code:`num_local_round`, we update trees by calling " -":code:`self.bst.update` method. After training, the last " -":code:`N=num_local_round` trees will be extracted to send to the server." +#: ../../source/tutorial-quickstart-ios.rst:34 +#: ../../source/tutorial-quickstart-pytorch.rst:37 +#: ../../source/tutorial-quickstart-scikitlearn.rst:40 +#: ../../source/tutorial-quickstart-tensorflow.rst:29 +#: ../../source/tutorial-quickstart-xgboost.rst:55 +msgid "Flower Client" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:291 +#: ../../source/tutorial-quickstart-ios.rst:36 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " -"conduct evaluation on valid set. The AUC value will be returned." +"Now that we have all our dependencies installed, let's run a simple " +"distributed training using CoreML as our local training pipeline and " +"MNIST as our dataset. For simplicity reasons we will use the complete " +"Flower client with CoreML, that has been implemented and stored inside " +"the Swift SDK. The client implementation can be seen below:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:294 +#: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one" -" line to actually run this client:" +"Let's create a new application project in Xcode and add :code:`flwr` as a" +" dependency in your project. For our application, we will store the logic" +" of our app in :code:`FLiOSModel.swift` and the UI elements in " +":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" +" in this quickstart. Please refer to the `full code example " +"`_ to learn more " +"about the app." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:300 -msgid "" -"That's it for the client. We only have to implement :code:`Client`and " -"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " -"tells the client which server to connect to. In our case we can run the " -"server and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +#: ../../source/tutorial-quickstart-ios.rst:75 +msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:311 +#: ../../source/tutorial-quickstart-ios.rst:83 msgid "" -"These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version" -" of the model back to each *client* to finish a complete FL round." +"Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " +"will be bundled inside the application during deployment to your iOS " +"device. We need to pass the url to access mlmodel and run CoreML machine " +"learning processes, it can be retrieved by calling the function " +":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " +"into :code:`MLBatchProvider` object. The preprocessing is done inside " +":code:`DataLoader.swift`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:314 +#: ../../source/tutorial-quickstart-ios.rst:99 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from " -":code:`flwr.server.strategy`." +"Since CoreML does not allow the model parameters to be seen before " +"training, and accessing the model parameters during or after the training" +" can only be done by specifying the layer name, we need to know this " +"information beforehand, through looking at the model specification, which" +" are written as proto files. The implementation can be seen in " +":code:`MLModelInspect`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:316 -msgid "We first define a strategy for XGBoost bagging aggregation." +#: ../../source/tutorial-quickstart-ios.rst:102 +msgid "" +"After we have all of the necessary information, let's create our Flower " +"client." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:339 +#: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"We use two clients for this example. An " -":code:`evaluate_metrics_aggregation` function is defined to collect and " -"wighted average the AUC values from clients." +"Then start the Flower gRPC client and start communicating to the server " +"by passing our Flower client to the function :code:`startFlwrGRPC`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:342 -msgid "Then, we start the server:" +#: ../../source/tutorial-quickstart-ios.rst:124 +msgid "" +"That's it for the client. We only have to implement :code:`Client` or " +"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " +"The attribute :code:`hostname` and :code:`port` tells the client which " +"server to connect to. This can be done by entering the hostname and port " +"in the application before clicking the start button to start the " +"federated learning process." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:354 -msgid "Tree-based bagging aggregation" +#: ../../source/tutorial-quickstart-ios.rst:129 +#: ../../source/tutorial-quickstart-pytorch.rst:203 +#: ../../source/tutorial-quickstart-scikitlearn.rst:167 +#: ../../source/tutorial-quickstart-tensorflow.rst:98 +#: ../../source/tutorial-quickstart-xgboost.rst:309 +msgid "Flower Server" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:356 +#: ../../source/tutorial-quickstart-ios.rst:131 +#: ../../source/tutorial-quickstart-pytorch.rst:205 +#: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" -"You must be curious about how bagging aggregation works. Let's look into " -"the details." +"For simple workloads we can start a Flower server and leave all the " +"configuration possibilities at their default values. In a file named " +":code:`server.py`, import Flower and start the server:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:358 -msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " -":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." -" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " -"and :code:`evaluate` methods as follows:" +#: ../../source/tutorial-quickstart-ios.rst:142 +#: ../../source/tutorial-quickstart-pytorch.rst:216 +#: ../../source/tutorial-quickstart-scikitlearn.rst:230 +#: ../../source/tutorial-quickstart-tensorflow.rst:112 +msgid "Train the model, federated!" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:454 +#: ../../source/tutorial-quickstart-ios.rst:144 +#: ../../source/tutorial-quickstart-pytorch.rst:218 +#: ../../source/tutorial-quickstart-tensorflow.rst:114 +#: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" -"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " -"trees by calling :code:`aggregate()` function:" +"With both client and server ready, we can now run everything and see " +"federated learning in action. FL systems usually have a server and " +"multiple clients. We therefore have to start the server first:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:513 +#: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling " -":code:`_get_tree_nums`. Then, the fetched information will be aggregated." -" After that, the trees (containing model weights) are aggregated to " -"generate a new tree model." -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:518 -msgid "" -"After traversal of all clients' models, a new global model is generated, " -"followed by the serialisation, and sending back to each client." -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:523 -msgid "Launch Federated XGBoost!" +"Once the server is running we can start the clients in different " +"terminals. Build and run the client through your Xcode, one through Xcode" +" Simulator and the other by deploying it to your iPhone. To see more " +"about how to deploy your app to iPhone or Simulator visit `here " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:585 +#: ../../source/tutorial-quickstart-ios.rst:156 msgid "" "Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in " -":code:`metrics_distributed`. One can see that the average AUC increases " -"over FL rounds." +"learning system in your ios device. The full `source code " +"`_ for this " +"example can be found in :code:`examples/ios`." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:590 +#: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"The full `source code `_ for this example can be found in :code:`examples" -"/xgboost-quickstart`." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Jax to train a linear regression model on a scikit-learn dataset." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:594 -msgid "Comprehensive Federated XGBoost" +#: ../../source/tutorial-quickstart-jax.rst:5 +msgid "Quickstart JAX" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:596 +#: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time" -" to run some more comprehensive experiments by customising the " -"experimental settings. In the xgboost-comprehensive example (`full code " -"`_), we provide more options to define various experimental" -" setups, including aggregation strategies, data partitioning and " -"centralised/distributed evaluation. We also support :doc:`Flower " -"simulation ` making it easy to simulate large " -"client cohorts in a resource-aware manner. Let's take a look!" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Pandas to perform Federated Analytics." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:603 -msgid "Cyclic training" +#: ../../source/tutorial-quickstart-pandas.rst:5 +msgid "Quickstart Pandas" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:605 -msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, " -"which performs FL in a client-by-client fashion. Instead of aggregating " -"multiple clients, there is only one single client participating in the " -"training per round in the cyclic training scenario. The trained local " -"XGBoost trees will be passed to the next client as an initialised model " -"for next round's boosting." +#: ../../source/tutorial-quickstart-pandas.rst:10 +msgid "Let's build a federated analytics system using Pandas and Flower!" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:609 +#: ../../source/tutorial-quickstart-pandas.rst:12 msgid "" -"To do this, we first customise a :code:`ClientManager` in " -":code:`server_utils.py`:" +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:649 +#: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"The customised :code:`ClientManager` samples all available clients in " -"each FL round based on the order of connection to the server. Then, we " -"define a new strategy :code:`FedXgbCyclic` in " -":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " -"select only one client in given round and pass the received model to next" -" client." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch to train a CNN model on MNIST." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:690 +#: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model" -" by overriding :code:`aggregate_fit`." +"In this tutorial we will learn how to train a Convolutional Neural " +"Network on CIFAR10 using Flower and PyTorch." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:693 +#: ../../source/tutorial-quickstart-pytorch.rst:15 +#: ../../source/tutorial-quickstart-xgboost.rst:39 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" -" methods ensure the clients to be sequentially selected given FL round:" +"First of all, it is recommended to create a virtual environment and run " +"everything within a :doc:`virtualenv `." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:757 -msgid "Customised data partitioning" +#: ../../source/tutorial-quickstart-pytorch.rst:17 +#: ../../source/tutorial-quickstart-scikitlearn.rst:14 +msgid "" +"Our example consists of one *server* and two *clients* all having the " +"same model." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:759 +#: ../../source/tutorial-quickstart-pytorch.rst:19 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" -" to instantiate the data partitioner based on the given " -":code:`num_partitions` and :code:`partitioner_type`. Currently, we " -"provide four supported partitioner type to simulate the uniformity/non-" -"uniformity in data quantity (uniform, linear, square, exponential)." +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:790 -msgid "Customised centralised/distributed evaluation" +#: ../../source/tutorial-quickstart-pytorch.rst:23 +msgid "" +"Now that we have a rough idea of what is going on, let's get started. We " +"first need to install Flower. You can do this by running :" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:792 +#: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"To facilitate centralised evaluation, we define a function in " -":code:`server_utils.py`:" +"Since we want to use PyTorch to solve a computer vision task, let's go " +"ahead and install PyTorch and the **torchvision** library:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:824 +#: ../../source/tutorial-quickstart-pytorch.rst:39 msgid "" -"This function returns a evaluation function which instantiates a " -":code:`Booster` object and loads the global model weights to it. The " -"evaluation is conducted by calling :code:`eval_set()` method, and the " -"tested AUC value is reported." +"Now that we have all our dependencies installed, let's run a simple " +"distributed training with two clients and one server. Our training " +"procedure and network architecture are based on PyTorch's `Deep Learning " +"with PyTorch " +"`_." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:827 +#: ../../source/tutorial-quickstart-pytorch.rst:41 msgid "" -"As for distributed evaluation on the clients, it's same as the quick-" -"start example by overriding the :code:`evaluate()` method insides the " -":code:`XgbClient` class in :code:`client_utils.py`." +"In a file called :code:`client.py`, import Flower and PyTorch related " +"packages:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:831 -msgid "Flower simulation" +#: ../../source/tutorial-quickstart-pytorch.rst:56 +msgid "In addition, we define the device allocation in PyTorch with:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:832 +#: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" -"We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a" -" single machine or a cluster of machines." +"We use PyTorch to load CIFAR10, a popular colored image classification " +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " +"the training and test data that are then normalized." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:866 +#: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"After importing all required packages, we define a :code:`main()` " -"function to perform the simulation process:" +"Define the loss and optimizer with PyTorch. The training of the dataset " +"is done by looping over the dataset, measure the corresponding loss and " +"optimize it." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:921 +#: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, " -"the clients won't need to pre-process their partitions again." +"Define then the validation of the machine learning network. We loop over" +" the test set and measure the loss and accuracy of the test set." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:924 -msgid "Then, we define the strategies and other hyper-parameters:" +#: ../../source/tutorial-quickstart-pytorch.rst:113 +msgid "" +"After defining the training and testing of a PyTorch machine learning " +"model, we use the functions for the Flower clients." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:975 +#: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"After that, we start the simulation by calling " -":code:`fl.simulation.start_simulation`:" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " +"Minute Blitz':" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:995 +#: ../../source/tutorial-quickstart-pytorch.rst:142 msgid "" -"One of key parameters for :code:`start_simulation` is :code:`client_fn` " -"which returns a function to construct a client. We define it as follows:" +"After loading the data set with :code:`load_data()` we define the Flower " +"interface." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1038 -msgid "Arguments parser" +#: ../../source/tutorial-quickstart-pytorch.rst:144 +#: ../../source/tutorial-quickstart-tensorflow.rst:54 +msgid "" +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to train the neural network we defined earlier)." msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1040 +#: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server " -"and simulation, allowing users to specify different experimental " -"settings. Let's first see the sever side:" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " +"defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1086 -msgid "" -"This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and" -" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" -" will do centralised evaluation and all functionalities for client " -"evaluation will be disabled." +#: ../../source/tutorial-quickstart-pytorch.rst:156 +#: ../../source/tutorial-quickstart-scikitlearn.rst:119 +msgid "return the model weight as a list of NumPy ndarrays" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1090 -msgid "Then, the argument parser on client side:" +#: ../../source/tutorial-quickstart-pytorch.rst:157 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 +msgid ":code:`set_parameters` (optional)" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1144 +#: ../../source/tutorial-quickstart-pytorch.rst:158 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 msgid "" -"This defines various options for client data partitioning. Besides, " -"clients also have an option to conduct evaluation on centralised test set" -" by setting :code:`--centralised-eval`, as well as an option to perform " -"scaled learning rate based on the number of clients by setting :code" -":`--scaled-lr`." +"update the local model weights with the parameters received from the " +"server" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1148 -msgid "We also have an argument parser for simulation:" +#: ../../source/tutorial-quickstart-pytorch.rst:160 +#: ../../source/tutorial-quickstart-scikitlearn.rst:124 +msgid "set the local model weights" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1226 -msgid "This integrates all arguments for both client and server sides." +#: ../../source/tutorial-quickstart-pytorch.rst:161 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 +msgid "train the local model" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1229 -msgid "Example commands" +#: ../../source/tutorial-quickstart-pytorch.rst:162 +#: ../../source/tutorial-quickstart-scikitlearn.rst:126 +msgid "receive the updated local model weights" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1231 -msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 " -"clients with exponential distribution for 50 rounds, we first start the " -"server as below:" +#: ../../source/tutorial-quickstart-pytorch.rst:164 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 +msgid "test the local model" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1238 -msgid "Then, on each client terminal, we start the clients:" -msgstr "" +#: ../../source/tutorial-quickstart-pytorch.rst:166 +msgid "which can be implemented in the following way:" +msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1244 -msgid "To run the same experiment with Flower simulation:" +#: ../../source/tutorial-quickstart-pytorch.rst:189 +#: ../../source/tutorial-quickstart-tensorflow.rst:82 +msgid "" +"We can now create an instance of our class :code:`CifarClient` and add " +"one line to actually run this client:" msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:1250 +#: ../../source/tutorial-quickstart-pytorch.rst:196 +#: ../../source/tutorial-quickstart-tensorflow.rst:90 msgid "" -"The full `code `_ for this comprehensive example can be found in" -" :code:`examples/xgboost-comprehensive`." +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " +"the client which server to connect to. In our case we can run the server " +"and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 -msgid "Build a strategy from scratch" +#: ../../source/tutorial-quickstart-pytorch.rst:226 +#: ../../source/tutorial-quickstart-scikitlearn.rst:239 +#: ../../source/tutorial-quickstart-tensorflow.rst:122 +#: ../../source/tutorial-quickstart-xgboost.rst:533 +msgid "" +"Once the server is running we can start the clients in different " +"terminals. Open a new terminal and start the first client:" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 +#: ../../source/tutorial-quickstart-pytorch.rst:233 +#: ../../source/tutorial-quickstart-scikitlearn.rst:246 +#: ../../source/tutorial-quickstart-tensorflow.rst:129 +#: ../../source/tutorial-quickstart-xgboost.rst:540 +msgid "Open another terminal and start the second client:" +msgstr "" + +#: ../../source/tutorial-quickstart-pytorch.rst:239 +#: ../../source/tutorial-quickstart-scikitlearn.rst:252 +#: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Welcome to the third part of the Flower federated learning tutorial. In " -"previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies " -"can be used to customize the execution on both the server and the clients" -" (`part 2 `__)." +"Each client will have its own dataset. You should now see how the " +"training does in the very first terminal (the one that started the " +"server):" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 +#: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" -"In this notebook, we'll continue to customize the federated learning " -"system we built previously by creating a custom version of FedAvg (again," -" using `Flower `__ and `PyTorch " -"`__)." +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples" +"/quickstart-pytorch`." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the Flower community on Slack to connect, ask questions, and get help: " -"`Join Slack `__ 🌼 We'd love to hear from " -"you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch Lightning to train an Auto Encoder model on MNIST." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 -msgid "Let's build a new ``Strategy`` from scratch!" +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 +msgid "Quickstart PyTorch Lightning" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 -msgid "Preparation" +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 +msgid "" +"Let's build a horizontal federated learning system using PyTorch " +"Lightning and Flower!" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"Before we begin with the actual code, let's make sure that we have " -"everything we need." +"Please refer to the `full code example " +"`_ to learn more." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 -msgid "Installing dependencies" +#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with scikit-learn to train a linear regression model." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 -msgid "First, we install the necessary packages:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:5 +msgid "Quickstart scikit-learn" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 +#: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"Now that we have all dependencies installed, we can import everything we " -"need for this tutorial:" +"In this tutorial, we will learn how to train a :code:`Logistic " +"Regression` model on MNIST using Flower and scikit-learn." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 +#: ../../source/tutorial-quickstart-scikitlearn.rst:12 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " -"GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is recommended to create a virtual environment and run everything " +"within this :doc:`virtualenv `." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 -msgid "Data loading" +#: ../../source/tutorial-quickstart-scikitlearn.rst:16 +msgid "" +"*Clients* are responsible for generating individual model parameter " +"updates for the model based on their local datasets. These updates are " +"then sent to the *server* which will aggregate them to produce an updated" +" global model. Finally, the *server* sends this improved version of the " +"model back to each *client*. A complete cycle of parameters updates is " +"called a *round*." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 +#: ../../source/tutorial-quickstart-scikitlearn.rst:20 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``. We introduce a new parameter" -" ``num_clients`` which allows us to call ``load_datasets`` with different" -" numbers of clients." +"Now that we have a rough idea of what is going on, let's get started. We " +"first need to install Flower. You can do this by running:" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 -msgid "Model training/evaluation" +#: ../../source/tutorial-quickstart-scikitlearn.rst:26 +msgid "Since we want to use scikit-learn, let's go ahead and install it:" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 +#: ../../source/tutorial-quickstart-scikitlearn.rst:32 +msgid "Or simply install all dependencies using Poetry:" +msgstr "" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:42 msgid "" -"Let's continue with the usual model definition (including " -"``set_parameters`` and ``get_parameters``), training and test functions:" +"Now that we have all our dependencies installed, let's run a simple " +"distributed training with two clients and one server. However, before " +"setting up the client and server, we will define all functionalities that" +" we need for our federated learning setup within :code:`utils.py`. The " +":code:`utils.py` contains different functions defining all the machine " +"learning basics:" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 -msgid "Flower client" +#: ../../source/tutorial-quickstart-scikitlearn.rst:45 +msgid ":code:`get_model_parameters()`" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 -msgid "" -"To implement the Flower client, we (again) create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " -"``cid`` to the client and use it log additional details:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:46 +msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 -msgid "Let's test what we have so far before we continue:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:47 +msgid ":code:`set_model_params()`" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 -msgid "Build a Strategy from scratch" +#: ../../source/tutorial-quickstart-scikitlearn.rst:48 +msgid "Sets the parameters of a :code:`sklearn` LogisticRegression model" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 -msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher" -" learning rate (potentially also other hyperparameters) to the optimizer " -"of a fraction of the clients. We will keep the sampling of the clients as" -" it is in ``FedAvg`` and then change the configuration dictionary (one of" -" the ``FitIns`` attributes)." +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid ":code:`set_initial_params()`" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 -msgid "" -"The only thing left is to use the newly created custom Strategy " -"``FedCustom`` when starting the experiment:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid "Initializes the model parameters that the Flower server will ask for" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 -msgid "Recap" +#: ../../source/tutorial-quickstart-scikitlearn.rst:52 +msgid "" +"Please check out :code:`utils.py` `here " +"`_ for more details. The pre-defined functions are used in" +" the :code:`client.py` and imported. The :code:`client.py` also requires " +"to import several packages such as Flower and scikit-learn:" msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 +#: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom" -" strategy enables granular control over client node configuration, result" -" aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``." -" To make custom strategies even more powerful, you can pass custom " -"functions to the constructor of your new class (``__init__``) and then " -"call these functions whenever needed." +"Prior to local training, we need to load the MNIST dataset, a popular " +"image classification dataset of handwritten digits for machine learning, " +"and partition the dataset for FL. This can be conveniently achieved using" +" `Flower Datasets `_. The " +":code:`FederatedDataset.load_partition()` method loads the partitioned " +"training set for each partition ID defined in the :code:`--partition-id` " +"argument." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 +#: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" -"Before you continue, make sure to join the Flower community on Slack: " -"`Join Slack `__" +"Next, the logistic regression model is defined and initialized with " +":code:`utils.set_initial_params()`." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 +#: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd " -"also love to hear who you are in ``#introductions``!" +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to fit the logistic regression we defined earlier)." msgstr "" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 +#: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 " -"`__ introduces ``Client``, the flexible API underlying " -"``NumPyClient``." +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " +"means defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 -msgid "Customize the client" +#: ../../source/tutorial-quickstart-scikitlearn.rst:122 +msgid "is directly imported with :code:`utils.set_model_params()`" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 -msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In " -"the previous parts of this tutorial, we introduced federated learning " -"with PyTorch and Flower (`part 1 `__), we learned how " -"strategies can be used to customize the execution on both the server and " -"the clients (`part 2 `__), and we built our own " -"custom strategy from scratch (`part 3 `__)." +#: ../../source/tutorial-quickstart-scikitlearn.rst:130 +msgid "The methods can be implemented in the following way:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 +#: ../../source/tutorial-quickstart-scikitlearn.rst:153 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new " -"baseclass for building clients, simply named ``Client``. In previous " -"parts of this tutorial, we've based our client on ``NumPyClient``, a " -"convenience class which makes it easy to work with machine learning " -"libraries that have good NumPy interoperability. With ``Client``, we gain" -" a lot of flexibility that we didn't have before, but we'll also have to " -"do a few things the we didn't have to do before." +"We can now create an instance of our class :code:`MnistClient` and add " +"one line to actually run this client:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 +#: ../../source/tutorial-quickstart-scikitlearn.rst:160 msgid "" -"Let's go deeper and see what it takes to move from ``NumPyClient`` to " -"``Client``!" -msgstr "" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 -msgid "Step 0: Preparation" +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" +" the client which server to connect to. In our case we can run the server" +" and the client on the same machine, therefore we use " +":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we pass to the client." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 +#: ../../source/tutorial-quickstart-scikitlearn.rst:169 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``." +"The following Flower server is a little bit more advanced and returns an " +"evaluation function for the server-side evaluation. First, we import " +"again all required libraries such as Flower and scikit-learn." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 -msgid "Step 1: Revisiting NumPyClient" +#: ../../source/tutorial-quickstart-scikitlearn.rst:172 +msgid ":code:`server.py`, import Flower and start the server:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 +#: ../../source/tutorial-quickstart-scikitlearn.rst:185 msgid "" -"So far, we've implemented our client by subclassing " -"``flwr.client.NumPyClient``. The three methods we implemented are " -"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " -"creation of instances of this class in a function called ``client_fn``:" +"The number of federated learning rounds is set in :code:`fit_round()` and" +" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"function is called after each federated learning round and gives you " +"information about loss and accuracy. Note that we also make use of Flower" +" Datasets here to load the test split of the MNIST dataset for server-" +"side evaluation." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 +#: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"We've seen this before, there's nothing new so far. The only *tiny* " -"difference compared to the previous notebook is naming, we've changed " -"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " -"``numpyclient_fn``. Let's run it to see the output we get:" +"The :code:`main` contains the server-side parameter initialization " +":code:`utils.set_initial_params()` as well as the aggregation strategy " +":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " +"federated averaging (or FedAvg), with two clients and evaluation after " +"each federated learning round. The server can be started with the command" +" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 +#: ../../source/tutorial-quickstart-scikitlearn.rst:232 msgid "" -"This works as expected, two clients are training for three rounds of " -"federated learning." +"With both client and server ready, we can now run everything and see " +"federated learning in action. Federated learning systems usually have a " +"server and multiple clients. We, therefore, have to start the server " +"first:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 +#: ../../source/tutorial-quickstart-scikitlearn.rst:286 msgid "" -"Let's dive a little bit deeper and discuss how Flower executes this " -"simulation. Whenever a client is selected to do some work, " -"``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and " -"the data)." +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples/sklearn-logreg-" +"mnist`." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 +#: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " -"makes it look like a subclass of ``flwr.client.Client``, not " -"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " -"know how to handle ``NumPyClient``'s, it only knows how to handle " -"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " -"top of ``Client``." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with TensorFlow to train a MobilNetV2 model on CIFAR-10." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 -msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on " -"top of ``Client``." +#: ../../source/tutorial-quickstart-tensorflow.rst:5 +msgid "Quickstart TensorFlow" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 -msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" +#: ../../source/tutorial-quickstart-tensorflow.rst:13 +msgid "Let's build a federated learning system in less than 20 lines of code!" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 -msgid "" -"Let's try to do the same thing using ``Client`` instead of " -"``NumPyClient``." +#: ../../source/tutorial-quickstart-tensorflow.rst:15 +msgid "Before Flower can be imported we have to install it:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 +#: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta " -"make sure our new ``Client``-based client works, right?" +"Since we want to use the Keras API of TensorFlow (TF), we have to install" +" TF as well:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 -msgid "" -"That's it, we're now using ``Client``. It probably looks similar to what " -"we've done with ``NumPyClient``. So what's the difference?" +#: ../../source/tutorial-quickstart-tensorflow.rst:31 +msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 +#: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " -"serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image" +" classification dataset for machine learning. The call to " +":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " +"it locally, and then returns the entire training and test set as NumPy " +"ndarrays." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 +#: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It " -"can do so because it expects you to return parameters as NumPy ndarray's," -" and it knows how to handle these. This makes working with machine " -"learning libraries that have good NumPy support (most of them) a breeze." +"Next, we need a model. For the purpose of this tutorial, we use " +"MobilNetV2 with 10 output classes:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 +#: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " -"``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses Keras. The :code:`NumPyClient` interface defines three " +"methods which can be implemented in the following way:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 -msgid "Step 3: Custom serialization" +#: ../../source/tutorial-quickstart-tensorflow.rst:135 +msgid "Each client will have its own dataset." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 +#: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"Here we will explore how to implement custom serialization with a simple " -"example." +"You should now see how the training does in the very first terminal (the " +"one that started the server):" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 +#: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" -"But first what is serialization? Serialization is just the process of " -"converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an " -"object. This is very useful for network communication. Indeed, without " -"serialization, you could not just a Python object through the internet." +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this can be found in :code:`examples" +"/quickstart-tensorflow/client.py`." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 +#: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Federated Learning relies heavily on internet communication for training " -"by sending Python objects back and forth between the clients and the " -"server. This means that serialization is an essential part of Federated " -"Learning." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with XGBoost to train classification models on trees." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 -msgid "" -"In the following section, we will write a basic example where instead of " -"sending a serialized version of our ``ndarray``\\ s containing our " -"parameters, we will first convert the ``ndarray`` into sparse matrices, " -"before sending them. This technique can be used to save bandwidth, as in " -"certain cases where the weights of a model are sparse (containing many 0 " -"entries), converting them to a sparse matrix can greatly improve their " -"bytesize." +#: ../../source/tutorial-quickstart-xgboost.rst:5 +msgid "Quickstart XGBoost" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 -msgid "Our custom serialization/deserialization functions" +#: ../../source/tutorial-quickstart-xgboost.rst:14 +msgid "Federated XGBoost" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 +#: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" -"This is where the real serialization/deserialization will happen, " -"especially in ``ndarray_to_sparse_bytes`` for serialization and " -"``sparse_bytes_to_ndarray`` for deserialization." +"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " +"implementation of gradient-boosted decision tree (**GBDT**), that " +"maximises the computational boundaries for boosted tree methods. It's " +"primarily designed to enhance both the performance and computational " +"speed of machine learning models. In XGBoost, trees are constructed " +"concurrently, unlike the sequential approach taken by GBDT." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 +#: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert " -"our arrays." +"Often, for tabular data on medium-sized datasets with fewer than 10k " +"training examples, XGBoost surpasses the results of deep learning " +"techniques." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 -msgid "Client-side" +#: ../../source/tutorial-quickstart-xgboost.rst:23 +msgid "Why federated XGBoost?" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 +#: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " -"will just have to call our custom functions in our " -"``flwr.client.Client``." +"Indeed, as the demand for data privacy and decentralized learning grows, " +"there's an increasing requirement to implement federated XGBoost systems " +"for specialised applications, like survival analysis and financial fraud " +"detection." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 -msgid "" -"Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` " -"defined above." -msgstr "" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 +#: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we " -"need to serialize our local results with " -"``ndarrays_to_sparse_parameters``." +"Federated learning ensures that raw data remains on the local device, " +"making it an attractive approach for sensitive domains where data " +"security and privacy are paramount. Given the robustness and efficiency " +"of XGBoost, combining it with federated learning offers a promising " +"solution for these specific challenges." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +#: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters " -"with our custom function." +"In this tutorial we will learn how to train a federated XGBoost model on " +"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " +"example (`full code xgboost-quickstart " +"`_)" +" with two *clients* and one *server* to demonstrate how federated XGBoost" +" works, and then we dive into a more complex example (`full code xgboost-" +"comprehensive `_) to run various experiments." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 -msgid "Server-side" +#: ../../source/tutorial-quickstart-xgboost.rst:37 +msgid "Environment Setup" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 +#: ../../source/tutorial-quickstart-xgboost.rst:41 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change " -"the serialization and deserialization here, we only need to reimplement " -"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" -" functions of the strategy will be inherited from the super class " -"``FedAvg``." +"We first need to install Flower and Flower Datasets. You can do this by " +"running :" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 -msgid "As you can see only one line as change in ``evaluate``:" +#: ../../source/tutorial-quickstart-xgboost.rst:47 +msgid "" +"Since we want to use :code:`xgboost` package to build up XGBoost trees, " +"let's go ahead and install :code:`xgboost`:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 +#: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"And for ``aggregate_fit``, we will first deserialize every result we " -"received:" +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. Now that we have all our " +"dependencies installed, let's run a simple distributed training with two " +"clients and one server." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 -msgid "And then serialize the aggregated result:" +#: ../../source/tutorial-quickstart-xgboost.rst:60 +msgid "" +"In a file called :code:`client.py`, import xgboost, Flower, Flower " +"Datasets and other related functions:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 -msgid "We can now run our custom serialization example!" +#: ../../source/tutorial-quickstart-xgboost.rst:87 +msgid "Dataset partition and hyper-parameter selection" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 +#: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"In this part of the tutorial, we've seen how we can build clients by " -"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine " -"learning libraries that have good NumPy interoperability. ``Client`` is a" -" more flexible abstraction that allows us to do things that are not " -"possible in ``NumPyClient``. In order to do so, it requires us to handle " -"parameter serialization and deserialization ourselves." +"Prior to local training, we require loading the HIGGS dataset from Flower" +" Datasets and conduct data partitioning for FL:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 +#: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" -"This is the final part of the Flower tutorial (for now!), " -"congratulations! You're now well equipped to understand the rest of the " -"documentation. There are many topics we didn't cover in the tutorial, we " -"recommend the following resources:" +"In this example, we split the dataset into two partitions with uniform " +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " +"the partition for the given client based on :code:`node_id`:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 -msgid "`Read Flower Docs `__" +#: ../../source/tutorial-quickstart-xgboost.rst:121 +msgid "" +"After that, we do train/test splitting on the given partition (client's " +"local data), and transform data format for :code:`xgboost` package." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 +#: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"`Check out Flower Code Examples " -"`__" +"The functions of :code:`train_test_split` and " +":code:`transform_dataset_to_dmatrix` are defined as below:" msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 -msgid "" -"`Use Flower Baselines for your research " -"`__" +#: ../../source/tutorial-quickstart-xgboost.rst:158 +msgid "Finally, we define the hyper-parameters used for XGBoost training." msgstr "" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 +#: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"`Watch Flower Summit 2023 videos `__" +"The :code:`num_local_round` represents the number of iterations for local" +" tree boost. We use CPU for the training in default. One can shift it to " +"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " +"evaluation metric." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 -msgid "Get started with Flower" +#: ../../source/tutorial-quickstart-xgboost.rst:181 +msgid "Flower client definition for XGBoost" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 -msgid "Welcome to the Flower federated learning tutorial!" +#: ../../source/tutorial-quickstart-xgboost.rst:183 +msgid "" +"After loading the dataset we define the Flower client. We follow the " +"general rule to define :code:`XgbClient` class inherited from " +":code:`fl.client.Client`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 +#: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" -"In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In " -"part 1, we use PyTorch for the model training pipeline and data loading. " -"In part 2, we continue to federate the PyTorch-based pipeline using " -"Flower." +"The :code:`self.bst` is used to keep the Booster objects that remain " +"consistent across rounds, allowing them to store predictions from trees " +"integrated in earlier rounds and maintain other essential data structures" +" for training." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 -msgid "Let's get stated!" +#: ../../source/tutorial-quickstart-xgboost.rst:196 +msgid "" +"Then, we override :code:`get_parameters`, :code:`fit` and " +":code:`evaluate` methods insides :code:`XgbClient` class as follows." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 +#: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" -"Before we begin with any actual code, let's make sure that we have " -"everything we need." +"Unlike neural network training, XGBoost trees are not started from a " +"specified random weights. In this case, we do not use " +":code:`get_parameters` and :code:`set_parameters` to initialise model " +"parameters for XGBoost. As a result, let's return an empty tensor in " +":code:`get_parameters` when it is called by the server at the first " +"round." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 +#: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " -"(``flwr``):" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " +"up the first set of trees. the returned Booster object and config are " +"stored in :code:`self.bst` and :code:`self.config`, respectively. From " +"the second round, we load the global model sent from server to " +":code:`self.bst`, and then update model weights on local training data " +"with function :code:`local_boost` as follows:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 +#: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" -" GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"Given :code:`num_local_round`, we update trees by calling " +":code:`self.bst.update` method. After training, the last " +":code:`N=num_local_round` trees will be extracted to send to the server." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 -msgid "Loading the data" +#: ../../source/tutorial-quickstart-xgboost.rst:291 +msgid "" +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " +"conduct evaluation on valid set. The AUC value will be returned." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 +#: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"Federated learning can be applied to many different types of tasks across" -" different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular " -"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " -"distinguish between images from ten different classes: 'airplane', " -"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " -"'truck'." +"Now, we can create an instance of our class :code:`XgbClient` and add one" +" line to actually run this client:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 +#: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the" -" original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely " -"for experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the " -"data is naturally partitioned)." +"That's it for the client. We only have to implement :code:`Client`and " +"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " +"tells the client which server to connect to. In our case we can run the " +"server and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 +#: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" -"Each organization will act as a client in the federated learning system. " -"So having ten organizations participate in a federation means having ten " -"clients connected to the federated learning server." +"These updates are then sent to the *server* which will aggregate them to " +"produce a better model. Finally, the *server* sends this improved version" +" of the model back to each *client* to finish a complete FL round." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +#: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training " -"and test set for each edge device and wrap each of them into a PyTorch " -"``DataLoader``:" +"In a file named :code:`server.py`, import Flower and FedXgbBagging from " +":code:`flwr.server.strategy`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 -msgid "" -"We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten " -"different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4500 training examples and 500 validation examples. There's also a " -"single ``testloader`` (we did not split the test set). Again, this is " -"only necessary for building research or educational systems, actual " -"federated learning systems have their data naturally distributed across " -"multiple partitions." +#: ../../source/tutorial-quickstart-xgboost.rst:316 +msgid "We first define a strategy for XGBoost bagging aggregation." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 +#: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"Let's take a look at the first batch of images and labels in the first " -"training set (i.e., ``trainloaders[0]``) before we move on:" +"We use two clients for this example. An " +":code:`evaluate_metrics_aggregation` function is defined to collect and " +"wighted average the AUC values from clients." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 -msgid "" -"The output above shows a random batch of images from the first " -"``trainloader`` in our list of ten ``trainloaders``. It also prints the " -"labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another " -"batch of images." +#: ../../source/tutorial-quickstart-xgboost.rst:342 +msgid "Then, we start the server:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 -msgid "Step 1: Centralized Training with PyTorch" +#: ../../source/tutorial-quickstart-xgboost.rst:354 +msgid "Tree-based bagging aggregation" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 +#: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"Next, we're going to use PyTorch to define a simple convolutional neural " -"network. This introduction assumes basic familiarity with PyTorch, so it " -"doesn't cover the PyTorch-related aspects in full detail. If you want to " -"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ " -"`__." +"You must be curious about how bagging aggregation works. Let's look into " +"the details." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 -msgid "Defining the model" +#: ../../source/tutorial-quickstart-xgboost.rst:358 +msgid "" +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " +":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." +" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " +"and :code:`evaluate` methods as follows:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 +#: ../../source/tutorial-quickstart-xgboost.rst:454 msgid "" -"We use the simple CNN described in the `PyTorch tutorial " -"`__:" +"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " +"trees by calling :code:`aggregate()` function:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 -msgid "Let's continue with the usual training and test functions:" +#: ../../source/tutorial-quickstart-xgboost.rst:513 +msgid "" +"In this function, we first fetch the number of trees and the number of " +"parallel trees for the current and previous model by calling " +":code:`_get_tree_nums`. Then, the fetched information will be aggregated." +" After that, the trees (containing model weights) are aggregated to " +"generate a new tree model." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 -msgid "Training the model" +#: ../../source/tutorial-quickstart-xgboost.rst:518 +msgid "" +"After traversal of all clients' models, a new global model is generated, " +"followed by the serialisation, and sending back to each client." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 +#: ../../source/tutorial-quickstart-xgboost.rst:523 +msgid "Launch Federated XGBoost!" +msgstr "" + +#: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" -"We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train " -"the model on the dataset of one of our organizations " -"(``trainloaders[0]``). This simulates the reality of most machine " -"learning projects today: each organization has their own data and trains " -"models only on this internal data:" +"Congratulations! You've successfully built and run your first federated " +"XGBoost system. The AUC values can be checked in " +":code:`metrics_distributed`. One can see that the average AUC increases " +"over FL rounds." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 +#: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " -"in a test set accuracy of about 41%, which is not good, but at the same " -"time, it doesn't really matter for the purposes of this tutorial. The " -"intent was just to show a simplistic centralized training pipeline that " -"sets the stage for what comes next - federated learning!" +"The full `source code `_ for this example can be found in :code:`examples" +"/xgboost-quickstart`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 -msgid "Step 2: Federated Learning with Flower" +#: ../../source/tutorial-quickstart-xgboost.rst:594 +msgid "Comprehensive Federated XGBoost" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 +#: ../../source/tutorial-quickstart-xgboost.rst:596 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was " -"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." -" Next, we'll simulate a situation where we have multiple datasets in " -"multiple organizations and where we train a model over these " -"organizations using federated learning." +"Now that you have known how federated XGBoost work with Flower, it's time" +" to run some more comprehensive experiments by customising the " +"experimental settings. In the xgboost-comprehensive example (`full code " +"`_), we provide more options to define various experimental" +" setups, including aggregation strategies, data partitioning and " +"centralised/distributed evaluation. We also support :doc:`Flower " +"simulation ` making it easy to simulate large " +"client cohorts in a resource-aware manner. Let's take a look!" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 -msgid "Updating model parameters" +#: ../../source/tutorial-quickstart-xgboost.rst:603 +msgid "Cyclic training" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 +#: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"In federated learning, the server sends the global model parameters to " -"the client, and the client updates the local model with the parameters " -"received from the server. It then trains the model on the local data " -"(which changes the model parameters locally) and sends the " -"updated/changed model parameters back to the server (or, alternatively, " -"it sends just the gradients back to the server, not the full model " -"parameters)." +"In addition to bagging aggregation, we offer a cyclic training scheme, " +"which performs FL in a client-by-client fashion. Instead of aggregating " +"multiple clients, there is only one single client participating in the " +"training per round in the cyclic training scenario. The trained local " +"XGBoost trees will be passed to the next client as an initialised model " +"for next round's boosting." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 +#: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the" -" local model: ``set_parameters`` and ``get_parameters``. The following " -"two functions do just that for the PyTorch model above." +"To do this, we first customise a :code:`ClientManager` in " +":code:`server_utils.py`:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 +#: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"The details of how this works are not really important here (feel free to" -" consult the PyTorch documentation if you want to learn more). In " -"essence, we use ``state_dict`` to access PyTorch model parameter tensors." -" The parameter tensors are then converted to/from a list of NumPy " -"ndarray's (which Flower knows how to serialize/deserialize):" +"The customised :code:`ClientManager` samples all available clients in " +"each FL round based on the order of connection to the server. Then, we " +"define a new strategy :code:`FedXgbCyclic` in " +":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " +"select only one client in given round and pass the received model to next" +" client." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 -msgid "Implementing a Flower client" +#: ../../source/tutorial-quickstart-xgboost.rst:690 +msgid "" +"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " +"Instead, we just make a copy of the received client model as global model" +" by overriding :code:`aggregate_fit`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 +#: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"With that out of the way, let's move on to the interesting part. " -"Federated learning systems consist of a server and multiple clients. In " -"Flower, we create clients by implementing subclasses of " -"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " -"``NumPyClient`` in this tutorial because it is easier to implement and " -"requires us to write less boilerplate." +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" +" methods ensure the clients to be sequentially selected given FL round:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 +#: ../../source/tutorial-quickstart-xgboost.rst:757 +msgid "Customised data partitioning" +msgstr "" + +#: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"To implement the Flower client, we create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``:" +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" +" to instantiate the data partitioner based on the given " +":code:`num_partitions` and :code:`partitioner_type`. Currently, we " +"provide four supported partitioner type to simulate the uniformity/non-" +"uniformity in data quantity (uniform, linear, square, exponential)." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 -msgid "``get_parameters``: Return the current local model parameters" +#: ../../source/tutorial-quickstart-xgboost.rst:790 +msgid "Customised centralised/distributed evaluation" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 +#: ../../source/tutorial-quickstart-xgboost.rst:792 msgid "" -"``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters " -"to the server" +"To facilitate centralised evaluation, we define a function in " +":code:`server_utils.py`:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 +#: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the " -"model parameters on the local data, and return the evaluation result to " -"the server" +"This function returns a evaluation function which instantiates a " +":code:`Booster` object and loads the global model weights to it. The " +"evaluation is conducted by calling :code:`eval_set()` method, and the " +"tested AUC value is reported." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 +#: ../../source/tutorial-quickstart-xgboost.rst:827 msgid "" -"We mentioned that our clients will use the previously defined PyTorch " -"components for model training and evaluation. Let's see a simple Flower " -"client implementation that brings everything together:" +"As for distributed evaluation on the clients, it's same as the quick-" +"start example by overriding the :code:`evaluate()` method insides the " +":code:`XgbClient` class in :code:`client_utils.py`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 -msgid "" -"Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." +#: ../../source/tutorial-quickstart-xgboost.rst:831 +msgid "Flower simulation" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 -msgid "Using the Virtual Client Engine" +#: ../../source/tutorial-quickstart-xgboost.rst:832 +msgid "" +"We also provide an example code (:code:`sim.py`) to use the simulation " +"capabilities of Flower to simulate federated XGBoost training on either a" +" single machine or a cluster of machines." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 +#: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"In this notebook, we want to simulate a federated learning system with 10" -" clients on a single machine. This means that the server and all 10 " -"clients will live on a single machine and share resources such as CPU, " -"GPU, and memory. Having 10 clients would mean having 10 instances of " -"``FlowerClient`` in memory. Doing this on a single machine can quickly " -"exhaust the available memory resources, even if only a subset of these " -"clients participates in a single round of federated learning." +"After importing all required packages, we define a :code:`main()` " +"function to perform the simulation process:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 +#: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" -"In addition to the regular capabilities where server and clients run on " -"multiple machines, Flower, therefore, provides special simulation " -"capabilities that create ``FlowerClient`` instances only when they are " -"actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" +"We first load the dataset and perform data partitioning, and the pre-" +"processed data is stored in a :code:`list`. After the simulation begins, " +"the clients won't need to pre-process their partitions again." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 -msgid "Starting the training" +#: ../../source/tutorial-quickstart-xgboost.rst:924 +msgid "Then, we define the strategies and other hyper-parameters:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 +#: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"We now have the class ``FlowerClient`` which defines client-side " -"training/evaluation and ``client_fn`` which allows Flower to create " -"``FlowerClient`` instances whenever it needs to call ``fit`` or " -"``evaluate`` on one particular client. The last step is to start the " -"actual simulation using ``flwr.simulation.start_simulation``." +"After that, we start the simulation by calling " +":code:`fl.simulation.start_simulation`:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +#: ../../source/tutorial-quickstart-xgboost.rst:995 msgid "" -"The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the " -"number of clients to simulate (``num_clients``), the number of federated " -"learning rounds (``num_rounds``), and the strategy. The strategy " -"encapsulates the federated learning approach/algorithm, for example, " -"*Federated Averaging* (FedAvg)." +"One of key parameters for :code:`start_simulation` is :code:`client_fn` " +"which returns a function to construct a client. We define it as follows:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 -msgid "" -"Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated" -" learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last " -"step is the actual call to ``start_simulation`` which - you guessed it - " -"starts the simulation:" -msgstr "" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 -msgid "Behind the scenes" -msgstr "" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 -msgid "So how does this work? How does Flower execute this simulation?" +#: ../../source/tutorial-quickstart-xgboost.rst:1038 +msgid "Arguments parser" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 -#, python-format +#: ../../source/tutorial-quickstart-xgboost.rst:1040 msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 " -"clients (``num_clients=10``). Flower then goes ahead an asks the " -"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " -"select 100% of the available clients (``fraction_fit=1.0``), so it goes " -"ahead and selects 10 random clients (i.e., 100% of 10)." +"In :code:`utils.py`, we define the arguments parsers for clients, server " +"and simulation, allowing users to specify different experimental " +"settings. Let's first see the sever side:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 +#: ../../source/tutorial-quickstart-xgboost.rst:1086 msgid "" -"Flower then asks the selected 10 clients to train the model. When the " -"server receives the model parameter updates from the clients, it hands " -"those updates over to the strategy (*FedAvg*) for aggregation. The " -"strategy aggregates those updates and returns the new global model, which" -" then gets used in the next round of federated learning." +"This allows user to specify training strategies / the number of total " +"clients / FL rounds / participating clients / clients for evaluation, and" +" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" +" will do centralised evaluation and all functionalities for client " +"evaluation will be disabled." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 -msgid "Where's the accuracy?" +#: ../../source/tutorial-quickstart-xgboost.rst:1090 +msgid "Then, the argument parser on client side:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 +#: ../../source/tutorial-quickstart-xgboost.rst:1144 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` " -"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"This defines various options for client data partitioning. Besides, " +"clients also have an option to conduct evaluation on centralised test set" +" by setting :code:`--centralised-eval`, as well as an option to perform " +"scaled learning rate based on the number of clients by setting :code" +":`--scaled-lr`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 -msgid "" -"Flower can automatically aggregate losses returned by individual clients," -" but it cannot do the same for metrics in the generic metrics dictionary " -"(the one with the ``accuracy`` key). Metrics dictionaries can contain " -"very different kinds of metrics and even key/value pairs that are not " -"metrics at all, so the framework does not (and can not) know how to " -"handle these automatically." +#: ../../source/tutorial-quickstart-xgboost.rst:1148 +msgid "We also have an argument parser for simulation:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 -msgid "" -"As users, we need to tell the framework how to handle/aggregate these " -"custom metrics, and we do so by passing metric aggregation functions to " -"the strategy. The strategy will then call these functions whenever it " -"receives fit or evaluate metrics from clients. The two possible functions" -" are ``fit_metrics_aggregation_fn`` and " -"``evaluate_metrics_aggregation_fn``." +#: ../../source/tutorial-quickstart-xgboost.rst:1226 +msgid "This integrates all arguments for both client and server sides." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 -msgid "" -"Let's create a simple weighted averaging function to aggregate the " -"``accuracy`` metric we return from ``evaluate``:" +#: ../../source/tutorial-quickstart-xgboost.rst:1229 +msgid "Example commands" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 +#: ../../source/tutorial-quickstart-xgboost.rst:1231 msgid "" -"The only thing left to do is to tell the strategy to call this function " -"whenever it receives evaluation metric dictionaries from the clients:" +"To run a centralised evaluated experiment with bagging strategy on 5 " +"clients with exponential distribution for 50 rounds, we first start the " +"server as below:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 -msgid "" -"We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom" -" evaluation metrics and calculates a single ``accuracy`` metric across " -"all clients on the server side." +#: ../../source/tutorial-quickstart-xgboost.rst:1238 +msgid "Then, on each client terminal, we start the clients:" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 +#: ../../source/tutorial-quickstart-xgboost.rst:1244 +msgid "To run the same experiment with Flower simulation:" +msgstr "" + +#: ../../source/tutorial-quickstart-xgboost.rst:1250 msgid "" -"The other two categories of metrics (``losses_centralized`` and " -"``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial " -"will cover centralized evaluation." +"The full `code `_ for this comprehensive example can be found in" +" :code:`examples/xgboost-comprehensive`." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 -msgid "Final remarks" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 +msgid "Build a strategy from scratch" msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 msgid "" -"Congratulations, you just trained a convolutional neural network, " -"federated over 10 clients! With that, you understand the basics of " -"federated learning with Flower. The same approach you've seen can be used" -" with other machine learning frameworks (not just PyTorch) and tasks (not" -" just CIFAR-10 images classification), for example NLP with Hugging Face " -"Transformers or speech with SpeechBrain." +"Welcome to the third part of the Flower federated learning tutorial. In " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__) and we learned how strategies " +"can be used to customize the execution on both the server and the clients" +" (`part 2 `__)." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. " -"Want to customize your strategy? Initialize parameters on the server " -"side? Or evaluate the aggregated model on the server side? We'll cover " -"all this and more in the next tutorial." +"In this notebook, we'll continue to customize the federated learning " +"system we built previously by creating a custom version of FedAvg (again," +" using `Flower `__ and `PyTorch " +"`__)." msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 " -"`__ goes into more depth about strategies and all " -"the advanced things you can build with them." +"`Star Flower on GitHub `__ ⭐️ and join " +"the Flower community on Slack to connect, ask questions, and get help: " +"`Join Slack `__ 🌼 We'd love to hear from " +"you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 -msgid "Use a federated learning strategy" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 +msgid "Let's build a new ``Strategy`` from scratch!" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 -msgid "" -"Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and" -" Flower (`part 1 `__)." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 +msgid "Preparation" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 msgid "" -"In this notebook, we'll begin to customize the federated learning system " -"we built in the introductory notebook (again, using `Flower " -"`__ and `PyTorch `__)." +"Before we begin with the actual code, let's make sure that we have " +"everything we need." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 -msgid "Let's move beyond FedAvg with Flower strategies!" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 +msgid "Installing dependencies" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 -msgid "Strategy customization" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 +msgid "First, we install the necessary packages:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 msgid "" -"So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of " -"new features." -msgstr "" - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 -msgid "Server-side parameter **initialization**" +"Now that we have all dependencies installed, we can import everything we " +"need for this tutorial:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"Flower, by default, initializes the global model by asking one random " -"client for the initial parameters. In many cases, we want more control " -"over parameter initialization though. Flower therefore allows you to " -"directly pass the initial parameters to the Strategy:" +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " +"GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 -msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" -" from asking one of the clients for the initial parameters. If we look " -"closely, we can see that the logs do not show any calls to the " -"``FlowerClient.get_parameters`` method." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 +msgid "Data loading" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 -msgid "Starting with a customized strategy" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 +msgid "" +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``. We introduce a new parameter" +" ``num_clients`` which allows us to call ``load_datasets`` with different" +" numbers of clients." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 -msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number " -"of arguments, amongst them the ``client_fn`` used to create " -"``FlowerClient`` instances, the number of clients to simulate " -"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 +msgid "Model training/evaluation" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " -"strategy this time:" +"Let's continue with the usual model definition (including " +"``set_parameters`` and ``get_parameters``), training and test functions:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 -msgid "Server-side parameter **evaluation**" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 +msgid "Flower client" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the " -"client-side. Client-side and server-side evaluation are similar in some " -"ways, but different in others." +"To implement the Flower client, we (again) create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " +"``cid`` to the client and use it log additional details:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 -msgid "" -"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " -"simple: it works the same way that evaluation in centralized machine " -"learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly " -"aggregated model after each round of training without having to send the " -"model to clients. We're also fortunate in the sense that our entire " -"evaluation dataset is available at all times." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 +msgid "Let's test what we have so far before we continue:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 -msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, " -"but also more powerful: it doesn't require a centralized dataset and " -"allows us to evaluate models over a larger set of data, which often " -"yields more realistic evaluation results. In fact, many scenarios require" -" us to use **Federated Evaluation** if we want to get representative " -"evaluation results at all. But this power comes at a cost: once we start " -"to evaluate on the client side, we should be aware that our evaluation " -"dataset can change over consecutive rounds of learning if those clients " -"are not always available. Moreover, the dataset held by each client can " -"also change over consecutive rounds. This can lead to evaluation results " -"that are not stable, so even if we would not change the model, we'd see " -"our evaluation results fluctuate over consecutive rounds." +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 +msgid "Build a Strategy from scratch" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " -"how we can evaluate aggregated model parameters on the server-side:" +"Let’s overwrite the ``configure_fit`` method such that it passes a higher" +" learning rate (potentially also other hyperparameters) to the optimizer " +"of a fraction of the clients. We will keep the sampling of the clients as" +" it is in ``FedAvg`` and then change the configuration dictionary (one of" +" the ``FitIns`` attributes)." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 -msgid "Sending/receiving arbitrary values to/from clients" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 +msgid "" +"The only thing left is to use the newly created custom Strategy " +"``FedCustom`` when starting the experiment:" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 -msgid "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 +msgid "Recap" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"So how can we send this config dictionary from server to clients? The " -"built-in Flower Strategies provide way to do this, and it works similarly" -" to the way server-side evaluation works. We provide a function to the " -"strategy, and the strategy calls this function for every round of " -"federated learning:" +"In this notebook, we’ve seen how to implement a custom strategy. A custom" +" strategy enables granular control over client node configuration, result" +" aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``." +" To make custom strategies even more powerful, you can pass custom " +"functions to the constructor of your new class (``__init__``) and then " +"call these functions whenever needed." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before " -"starting the simulation:" +"Before you continue, make sure to join the Flower community on Slack: " +"`Join Slack `__" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"As we can see, the client logs now include the current round of federated" -" learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second" -" round of federated learning, and then for two epochs during the third " -"round." +"There's a dedicated ``#questions`` channel if you need help, but we'd " +"also love to hear who you are in ``#introductions``!" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " -"used this concept throughout this notebook without mentioning it " -"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" -" key/value pair as the third return value in ``evaluate``." +"The `Flower Federated Learning Tutorial - Part 4 " +"`__ introduces ``Client``, the flexible API underlying " +"``NumPyClient``." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 -msgid "Scaling federated learning" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 +msgid "Customize the client" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"As a last step in this notebook, let's see how we can use Flower to " -"experiment with a large number of clients." +"Welcome to the fourth part of the Flower federated learning tutorial. In " +"the previous parts of this tutorial, we introduced federated learning " +"with PyTorch and Flower (`part 1 `__), we learned how " +"strategies can be used to customize the execution on both the server and " +"the clients (`part 2 `__), and we built our own " +"custom strategy from scratch (`part 3 `__)." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 -#, python-format +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is " -"quite small, we should probably train the model a bit longer, so we " -"configure the clients to perform 3 local training epochs. We should also " -"adjust the fraction of clients selected for training during each round " -"(we don't want all 1000 clients participating in every round), so we " -"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " -"available clients (so 50 clients) will be selected for training each " -"round:" +"In this notebook, we revisit ``NumPyClient`` and introduce a new " +"baseclass for building clients, simply named ``Client``. In previous " +"parts of this tutorial, we've based our client on ``NumPyClient``, a " +"convenience class which makes it easy to work with machine learning " +"libraries that have good NumPy interoperability. With ``Client``, we gain" +" a lot of flexibility that we didn't have before, but we'll also have to " +"do a few things the we didn't have to do before." msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 msgid "" -"In this notebook, we've seen how we can gradually enhance our system by " -"customizing the strategy, initializing parameters on the server side, " -"choosing a different strategy, and evaluating models on the server-side. " -"That's quite a bit of flexibility with so little code, right?" +"Let's go deeper and see what it takes to move from ``NumPyClient`` to " +"``Client``!" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 -msgid "" -"In the later sections, we've seen how we can communicate arbitrary values" -" between server and clients to fully customize client-side execution. " -"With that capability, we built a large-scale Federated Learning " -"simulation using the Flower Virtual Client Engine and ran an experiment " -"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 +msgid "Step 0: Preparation" msgstr "" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 " -"`__ shows how to build a fully custom ``Strategy`` from " -"scratch." +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 -msgid "What is Federated Learning?" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 +msgid "Step 1: Revisiting NumPyClient" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"In this tutorial, you will learn what federated learning is, build your " -"first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated " -"learning systems that approach the current state of the art in the field." +"So far, we've implemented our client by subclassing " +"``flwr.client.NumPyClient``. The three methods we implemented are " +"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " +"creation of instances of this class in a function called ``client_fn``:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " -"federated learning. Only a basic understanding of data science and Python" -" programming is assumed." +"We've seen this before, there's nothing new so far. The only *tiny* " +"difference compared to the previous notebook is naming, we've changed " +"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " +"``numpyclient_fn``. Let's run it to see the output we get:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the open-source Flower community on Slack to connect, ask questions, and " -"get help: `Join Slack `__ 🌼 We'd love to " -"hear from you in the ``#introductions`` channel! And if anything is " -"unclear, head over to the ``#questions`` channel." +"This works as expected, two clients are training for three rounds of " +"federated learning." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 -msgid "Let's get started!" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 +msgid "" +"Let's dive a little bit deeper and discuss how Flower executes this " +"simulation. Whenever a client is selected to do some work, " +"``start_simulation`` calls the function ``numpyclient_fn`` to create an " +"instance of our ``FlowerNumPyClient`` (along with loading the model and " +"the data)." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 -msgid "Classic machine learning" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 +msgid "" +"But here's the perhaps surprising part: Flower doesn't actually use the " +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " +"makes it look like a subclass of ``flwr.client.Client``, not " +"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " +"know how to handle ``NumPyClient``'s, it only knows how to handle " +"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " +"top of ``Client``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how " -"most machine learning works today." +"Instead of building on top of ``NumPyClient``, we can directly build on " +"top of ``Client``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 -msgid "" -"In machine learning, we have a model, and we have data. The model could " -"be a neural network (as depicted here), or something else, like classical" -" linear regression." +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 +msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|2b5c62c529f6416f840c594cce062fbb|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 +msgid "" +"Let's try to do the same thing using ``Client`` instead of " +"``NumPyClient``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 -msgid "Model and data" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 +msgid "" +"Before we discuss the code in more detail, let's try to run it! Gotta " +"make sure our new ``Client``-based client works, right?" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 msgid "" -"We train the model using the data to perform a useful task. A task could " -"be to detect objects in images, transcribe an audio recording, or play a " -"game like Go." +"That's it, we're now using ``Client``. It probably looks similar to what " +"we've done with ``NumPyClient``. So what's the difference?" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|90b334680cb7467d9a04d39b8e8dca9f|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 +msgid "" +"First of all, it's more code. But why? The difference comes from the fact" +" that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the " +"network, it eventually needs to turn these parameters into ``bytes``. " +"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"serialization. Turning raw bytes into something more useful (like NumPy " +"``ndarray``'s) is called deserialization. Flower needs to do both: it " +"needs to serialize parameters on the server-side and send them to the " +"client, the client needs to deserialize them to use them for local " +"training, and then serialize the updated parameters again to send them " +"back to the server, which (finally!) deserializes them again in order to " +"aggregate them with the updates received from other clients." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 -msgid "Train model using data" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 +msgid "" +"The only *real* difference between Client and NumPyClient is that " +"NumPyClient takes care of serialization and deserialization for you. It " +"can do so because it expects you to return parameters as NumPy ndarray's," +" and it knows how to handle these. This makes working with machine " +"learning libraries that have good NumPy support (most of them) a breeze." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"Now, in practice, the training data we work with doesn't originate on the" -" machine we train the model on. It gets created somewhere else." +"In terms of API, there's one major difference: all methods in Client take" +" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " +"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"``NumPyClient`` on the other hand have multiple arguments (e.g., " +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" +" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These " +"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " +"values you're used to from ``NumPyClient``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 -msgid "" -"It originates on a smartphone by the user interacting with an app, a car " -"collecting sensor data, a laptop receiving input via the keyboard, or a " -"smart speaker listening to someone trying to sing a song." +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 +msgid "Step 3: Custom serialization" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|65764ceee89f4335bfd93fd0b115e831|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 +msgid "" +"Here we will explore how to implement custom serialization with a simple " +"example." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 -msgid "Data on a phone" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 +msgid "" +"But first what is serialization? Serialization is just the process of " +"converting an object into raw bytes, and equally as important, " +"deserialization is the process of converting raw bytes back into an " +"object. This is very useful for network communication. Indeed, without " +"serialization, you could not just a Python object through the internet." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 msgid "" -"What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running" -" the same app. But it could also be several organizations, all generating" -" data for the same task." +"Federated Learning relies heavily on internet communication for training " +"by sending Python objects back and forth between the clients and the " +"server. This means that serialization is an essential part of Federated " +"Learning." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 +msgid "" +"In the following section, we will write a basic example where instead of " +"sending a serialized version of our ``ndarray``\\ s containing our " +"parameters, we will first convert the ``ndarray`` into sparse matrices, " +"before sending them. This technique can be used to save bandwidth, as in " +"certain cases where the weights of a model are sparse (containing many 0 " +"entries), converting them to a sparse matrix can greatly improve their " +"bytesize." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 -msgid "Data is on many devices" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 +msgid "Our custom serialization/deserialization functions" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"So to use machine learning, or any kind of data analysis, the approach " -"that has been used in the past was to collect all data on a central " -"server. This server can be somewhere in a data center, or somewhere in " -"the cloud." +"This is where the real serialization/deserialization will happen, " +"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"``sparse_bytes_to_ndarray`` for deserialization." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|11e95ac83a8548d8b3505b4663187d07|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 +msgid "" +"Note that we imported the ``scipy.sparse`` library in order to convert " +"our arrays." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 -msgid "Central data collection" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 +msgid "Client-side" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"Once all the data is collected in one place, we can finally use machine " -"learning algorithms to train our model on the data. This is the machine " -"learning approach that we've basically always relied on." +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " +"will just have to call our custom functions in our " +"``flwr.client.Client``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|1dab2f3a23674abc8a6731f20fa10730|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 +msgid "" +"Indeed, in ``get_parameters`` we need to serialize the parameters we got " +"from our network using our custom ``ndarrays_to_sparse_parameters`` " +"defined above." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 -msgid "Central model training" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 +msgid "" +"In ``fit``, we first need to deserialize the parameters coming from the " +"server using our custom ``sparse_parameters_to_ndarrays`` and then we " +"need to serialize our local results with " +"``ndarrays_to_sparse_parameters``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 -msgid "Challenges of classical machine learning" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +msgid "" +"In ``evaluate``, we will only need to deserialize the global parameters " +"with our custom function." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 -msgid "" -"The classic machine learning approach we've just seen can be used in some" -" cases. Great examples include categorizing holiday photos, or analyzing " -"web traffic. Cases, where all the data is naturally available on a " -"centralized server." +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 +msgid "Server-side" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|7f0ee162da38450788493a21627306f7|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 +msgid "" +"For this example, we will just use ``FedAvg`` as a strategy. To change " +"the serialization and deserialization here, we only need to reimplement " +"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" +" functions of the strategy will be inherited from the super class " +"``FedAvg``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 -msgid "Centralized possible" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 +msgid "As you can see only one line as change in ``evaluate``:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 msgid "" -"But the approach can not be used in many other cases. Cases, where the " -"data is not available on a centralized server, or cases where the data " -"available on one server is not enough to train a good model." +"And for ``aggregate_fit``, we will first deserialize every result we " +"received:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 +msgid "And then serialize the aggregated result:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 -msgid "Centralized impossible" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 +msgid "We can now run our custom serialization example!" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 msgid "" -"There are many reasons why the classic centralized machine learning " -"approach does not work for a large number of highly important real-world " -"use cases. Those reasons include:" +"In this part of the tutorial, we've seen how we can build clients by " +"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " +"convenience abstraction that makes it easier to work with machine " +"learning libraries that have good NumPy interoperability. ``Client`` is a" +" more flexible abstraction that allows us to do things that are not " +"possible in ``NumPyClient``. In order to do so, it requires us to handle " +"parameter serialization and deserialization ourselves." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " -"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " -"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " -"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " -"protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own " -"users' data for artificial intelligence training because those users live" -" in different parts of the world, and their data is governed by different" -" data protection regulations." +"This is the final part of the Flower tutorial (for now!), " +"congratulations! You're now well equipped to understand the rest of the " +"documentation. There are many topics we didn't cover in the tutorial, we " +"recommend the following resources:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 -msgid "" -"**User preference**: In addition to regulation, there are use cases where" -" users just expect that no data leaves their device, ever. If you type " -"your passwords and credit card info into the digital keyboard of your " -"phone, you don't expect those passwords to end up on the server of the " -"company that developed that keyboard, do you? In fact, that use case was " -"the reason federated learning was invented in the first place." +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 +msgid "`Read Flower Docs `__" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data " -"volume that it is neither feasible nor economic to collect all the data " -"(due to, for example, bandwidth or communication efficiency). Think about" -" a national rail service with hundreds of train stations across the " -"country. If each of these train stations is outfitted with a number of " -"security cameras, the volume of raw on-device data they produce requires " -"incredibly powerful and exceedingly expensive infrastructure to process " -"and store. And most of the data isn't even useful." -msgstr "" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 -msgid "Examples where centralized machine learning does not work include:" +"`Check out Flower Code Examples " +"`__" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"Sensitive healthcare records from multiple hospitals to train cancer " -"detection models" +"`Use Flower Baselines for your research " +"`__" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"Financial information from different organizations to detect financial " -"fraud" +"`Watch Flower Summit 2023 videos `__" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 -msgid "Location data from your electric car to make better range prediction" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 +msgid "Get started with Flower" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 -msgid "End-to-end encrypted messages to train better auto-complete models" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 +msgid "Welcome to the Flower federated learning tutorial!" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 msgid "" -"The popularity of privacy-enhancing systems like the `Brave " -"`__ browser or the `Signal `__ " -"messenger shows that users care about privacy. In fact, they choose the " -"privacy-enhancing version over other alternatives, if such an alternative" -" exists. But what can we do to apply machine learning and data science to" -" these cases to utilize private data? After all, these are all areas that" -" would benefit significantly from recent advances in AI." +"In this notebook, we'll build a federated learning system using Flower, " +"`Flower Datasets `__ and PyTorch. In " +"part 1, we use PyTorch for the model training pipeline and data loading. " +"In part 2, we continue to federate the PyTorch-based pipeline using " +"Flower." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 -msgid "Federated learning" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 +msgid "Let's get started!" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 msgid "" -"Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead " -"of moving the data to the training. Here's the single-sentence " -"explanation:" -msgstr "" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 -msgid "Central machine learning: move the data to the computation" -msgstr "" - -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 -msgid "Federated (machine) learning: move the computation to the data" +"Before we begin with any actual code, let's make sure that we have " +"everything we need." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 msgid "" -"By doing so, it enables us to use machine learning (and other data " -"science approaches) in areas where it wasn't possible before. We can now " -"train excellent medical AI models by enabling different hospitals to work" -" together. We can solve financial fraud by training AI models on the data" -" of different financial institutions. We can build novel privacy-" -"enhancing applications (such as secure messaging) that have better built-" -"in AI than their non-privacy-enhancing alternatives. And those are just a" -" few of the examples that come to mind. As we deploy federated learning, " -"we discover more and more areas that can suddenly be reinvented because " -"they now have access to vast amounts of previously inaccessible data." +"Next, we install the necessary packages for PyTorch (``torch`` and " +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " +"(``flwr``):" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 msgid "" -"So how does federated learning work, exactly? Let's start with an " -"intuitive explanation." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" +" GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 -msgid "Federated learning in five steps" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 +msgid "Loading the data" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 -msgid "Step 0: Initialize global model" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 +msgid "" +"Federated learning can be applied to many different types of tasks across" +" different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular " +"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " +"distinguish between images from ten different classes: 'airplane', " +"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " +"'truck'." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" -"We start by initializing the model on the server. This is exactly the " -"same in classic centralized learning: we initialize the model parameters," -" either randomly or from a previously saved checkpoint." +"We simulate having multiple datasets from multiple organizations (also " +"called the \"cross-silo\" setting in federated learning) by splitting the" +" original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely " +"for experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the " +"data is naturally partitioned)." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|5b1408eec0d746cdb91162a9107b6089|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 +msgid "" +"Each organization will act as a client in the federated learning system. " +"So having ten organizations participate in a federation means having ten " +"clients connected to the federated learning server." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 -msgid "Initialize global model" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +msgid "" +"Let's now create the Federated Dataset abstraction that from ``flwr-" +"datasets`` that partitions the CIFAR-10. We will create small training " +"and test set for each edge device and wrap each of them into a PyTorch " +"``DataLoader``:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client" -" nodes)" +"We now have a list of ten training sets and ten validation sets " +"(``trainloaders`` and ``valloaders``) representing the data of ten " +"different organizations. Each ``trainloader``/``valloader`` pair contains" +" 4000 training examples and 1000 validation examples. There's also a " +"single ``testloader`` (we did not split the test set). Again, this is " +"only necessary for building research or educational systems, actual " +"federated learning systems have their data naturally distributed across " +"multiple partitions." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 msgid "" -"Next, we send the parameters of the global model to the connected client " -"nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts " -"their local training using the same model parameters. We often use only a" -" few of the connected nodes instead of all nodes. The reason for this is " -"that selecting more and more client nodes has diminishing returns." +"Let's take a look at the first batch of images and labels in the first " +"training set (i.e., ``trainloaders[0]``) before we move on:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 +msgid "" +"The output above shows a random batch of images from the first " +"``trainloader`` in our list of ten ``trainloaders``. It also prints the " +"labels associated with each image (i.e., one of the ten possible labels " +"we've seen above). If you run the cell again, you should see another " +"batch of images." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 -msgid "Send global model" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 +msgid "Step 1: Centralized Training with PyTorch" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 msgid "" -"Step 2: Train model locally on the data of each organization/device " -"(client node)" +"Next, we're going to use PyTorch to define a simple convolutional neural " +"network. This introduction assumes basic familiarity with PyTorch, so it " +"doesn't cover the PyTorch-related aspects in full detail. If you want to " +"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " +"MINUTE BLITZ " +"`__." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 +msgid "Defining the model" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"Now that all (selected) client nodes have the latest version of the " -"global model parameters, they start the local training. They use their " -"own local dataset to train their own local model. They don't train the " -"model until full convergence, but they only train for a little while. " -"This could be as little as one epoch on the local data, or even just a " -"few steps (mini-batches)." +"We use the simple CNN described in the `PyTorch tutorial " +"`__:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 +msgid "Let's continue with the usual training and test functions:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 -msgid "Train on local data" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 +msgid "Training the model" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 -msgid "Step 3: Return model updates back to the server" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 +msgid "" +"We now have all the basic building blocks we need: a dataset, a model, a " +"training function, and a test function. Let's put them together to train " +"the model on the dataset of one of our organizations " +"(``trainloaders[0]``). This simulates the reality of most machine " +"learning projects today: each organization has their own data and trains " +"models only on this internal data:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"After local training, each client node has a slightly different version " -"of the model parameters they originally received. The parameters are all " -"different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the " -"server. The model updates they send can either be the full model " -"parameters or just the gradients that were accumulated during local " -"training." +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " +"in a test set accuracy of about 41%, which is not good, but at the same " +"time, it doesn't really matter for the purposes of this tutorial. The " +"intent was just to show a simplistic centralized training pipeline that " +"sets the stage for what comes next - federated learning!" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|ec1fe880237247e0975f52766775ab84|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 +msgid "Step 2: Federated Learning with Flower" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 -msgid "Send model updates" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 +msgid "" +"Step 1 demonstrated a simple centralized training pipeline. All data was " +"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." +" Next, we'll simulate a situation where we have multiple datasets in " +"multiple organizations and where we train a model over these " +"organizations using federated learning." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 -msgid "Step 4: Aggregate model updates into a new global model" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 +msgid "Updating model parameters" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of " -"the original global model, each trained on the local data of one client. " -"But didn't we want to have one model that contains the learnings from the" -" data of all 100 client nodes?" +"In federated learning, the server sends the global model parameters to " +"the client, and the client updates the local model with the parameters " +"received from the server. It then trains the model on the local data " +"(which changes the model parameters locally) and sends the " +"updated/changed model parameters back to the server (or, alternatively, " +"it sends just the gradients back to the server, not the full model " +"parameters)." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." +"We need two helper functions to update the local model with parameters " +"received from the server and to get the updated model parameters from the" +" local model: ``set_parameters`` and ``get_parameters``. The following " +"two functions do just that for the PyTorch model above." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 +msgid "" +"The details of how this works are not really important here (feel free to" +" consult the PyTorch documentation if you want to learn more). In " +"essence, we use ``state_dict`` to access PyTorch model parameter tensors." +" The parameter tensors are then converted to/from a list of NumPy " +"ndarray's (which Flower knows how to serialize/deserialize):" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 -msgid "Aggregate model updates" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 +msgid "Implementing a Flower client" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 -msgid "Step 5: Repeat steps 1 to 4 until the model converges" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 +msgid "" +"With that out of the way, let's move on to the interesting part. " +"Federated learning systems consist of a server and multiple clients. In " +"Flower, we create clients by implementing subclasses of " +"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " +"``NumPyClient`` in this tutorial because it is easier to implement and " +"requires us to write less boilerplate." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step " -"1), the client nodes train on their local data (step 2), they send their " -"updated models to the server (step 3), and the server then aggregates the" -" model updates to get a new version of the global model (step 4)." +"To implement the Flower client, we create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 +msgid "``get_parameters``: Return the current local model parameters" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" -"During a single round, each client node that participates in that " -"iteration only trains for a little while. This means that after the " -"aggregation step (step 4), we have a model that has been trained on all " -"the data of all participating client nodes, but only for a little while. " -"We then have to repeat this training process over and over again to " -"eventually arrive at a fully trained model that performs well across the " -"data of all client nodes." +"``fit``: Receive model parameters from the server, train the model " +"parameters on the local data, and return the (updated) model parameters " +"to the server" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning" -" in a nutshell. In later parts of this tutorial, we will go into more " -"detail. Interesting questions include: How can we select the best client " -"nodes that should participate in the next round? What's the best way to " -"aggregate model updates? How can we handle failing client nodes " -"(stragglers)?" +"``evaluate``: Receive model parameters from the server, evaluate the " +"model parameters on the local data, and return the evaluation result to " +"the server" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 msgid "" -"Just like we can train a model on the decentralized data of different " -"client nodes, we can also evaluate the model on that data to receive " -"valuable metrics. This is called federated evaluation, sometimes " -"abbreviated as FE. In fact, federated evaluation is an integral part of " -"most federated learning systems." +"We mentioned that our clients will use the previously defined PyTorch " +"components for model training and evaluation. Let's see a simple Flower " +"client implementation that brings everything together:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 -msgid "Federated analytics" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 +msgid "" +"Our class ``FlowerClient`` defines how local training/evaluation will be " +"performed and allows Flower to call the local training/evaluation through" +" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" +" *single client* in our federated learning system. Federated learning " +"systems have multiple clients (otherwise, there's not much to federate), " +"so each client will be represented by its own instance of " +"``FlowerClient``. If we have, for example, three clients in our workload," +" then we'd have three instances of ``FlowerClient``. Flower calls " +"``FlowerClient.fit`` on the respective instance when the server selects a" +" particular client for training (and ``FlowerClient.evaluate`` for " +"evaluation)." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 +msgid "Using the Virtual Client Engine" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In many cases, machine learning isn't necessary to derive value from " -"data. Data analysis can yield valuable insights, but again, there's often" -" not enough data to get a clear answer. What's the average age at which " -"people develop a certain type of health condition? Federated analytics " -"enables such queries over multiple client nodes. It is usually used in " -"conjunction with other privacy-enhancing technologies like secure " -"aggregation to prevent the server from seeing the results submitted by " -"individual client nodes." +"In this notebook, we want to simulate a federated learning system with 10" +" clients on a single machine. This means that the server and all 10 " +"clients will live on a single machine and share resources such as CPU, " +"GPU, and memory. Having 10 clients would mean having 10 instances of " +"``FlowerClient`` in memory. Doing this on a single machine can quickly " +"exhaust the available memory resources, even if only a subset of these " +"clients participates in a single round of federated learning." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 msgid "" -"Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and " -"sharing statistical data, ensuring the privacy of individual " -"participants. DP achieves this by adding statistical noise to the model " -"updates, ensuring any individual participants’ information cannot be " -"distinguished or re-identified. This technique can be considered an " -"optimization that provides a quantifiable privacy protection measure." +"In addition to the regular capabilities where server and clients run on " +"multiple machines, Flower, therefore, provides special simulation " +"capabilities that create ``FlowerClient`` instances only when they are " +"actually necessary for training or evaluation. To enable the Flower " +"framework to create clients when necessary, we need to implement a " +"function called ``client_fn`` that creates a ``FlowerClient`` instance on" +" demand. Flower calls ``client_fn`` whenever it needs an instance of one " +"particular client to call ``fit`` or ``evaluate`` (those instances are " +"usually discarded after use, so they should not keep any local state). " +"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " +"be used, for example, to load different local data partitions for " +"different clients, as can be seen below:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 -msgid "Flower" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 +msgid "Starting the training" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"Federated learning, federated evaluation, and federated analytics require" -" infrastructure to move machine learning models back and forth, train and" -" evaluate them on local data, and then aggregate the updated models. " -"Flower provides the infrastructure to do exactly that in an easy, " -"scalable, and secure way. In short, Flower presents a unified approach to" -" federated learning, analytics, and evaluation. It allows the user to " -"federate any workload, any ML framework, and any programming language." +"We now have the class ``FlowerClient`` which defines client-side " +"training/evaluation and ``client_fn`` which allows Flower to create " +"``FlowerClient`` instances whenever it needs to call ``fit`` or " +"``evaluate`` on one particular client. The last step is to start the " +"actual simulation using ``flwr.simulation.start_simulation``." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|ff726bc5505e432388ee2fdd6ef420b9|" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +msgid "" +"The function ``start_simulation`` accepts a number of arguments, amongst " +"them the ``client_fn`` used to create ``FlowerClient`` instances, the " +"number of clients to simulate (``num_clients``), the number of federated " +"learning rounds (``num_rounds``), and the strategy. The strategy " +"encapsulates the federated learning approach/algorithm, for example, " +"*Federated Averaging* (FedAvg)." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal" -" computer, roomba, and phone)" +"Flower has a number of built-in strategies, but we can also use our own " +"strategy implementations to customize nearly all aspects of the federated" +" learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last " +"step is the actual call to ``start_simulation`` which - you guessed it - " +"starts the simulation:" msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 +msgid "Behind the scenes" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 +msgid "So how does this work? How does Flower execute this simulation?" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 +#, python-format msgid "" -"Congratulations, you just learned the basics of federated learning and " -"how it relates to the classic (centralized) machine learning!" +"When we call ``start_simulation``, we tell Flower that there are 10 " +"clients (``num_clients=10``). Flower then goes ahead an asks the " +"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " +"select 100% of the available clients (``fraction_fit=1.0``), so it goes " +"ahead and selects 10 random clients (i.e., 100% of 10)." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 +msgid "" +"Flower then asks the selected 10 clients to train the model. When the " +"server receives the model parameter updates from the clients, it hands " +"those updates over to the strategy (*FedAvg*) for aggregation. The " +"strategy aggregates those updates and returns the new global model, which" +" then gets used in the next round of federated learning." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 +msgid "Where's the accuracy?" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 +msgid "" +"You may have noticed that all metrics except for ``losses_distributed`` " +"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 +msgid "" +"Flower can automatically aggregate losses returned by individual clients," +" but it cannot do the same for metrics in the generic metrics dictionary " +"(the one with the ``accuracy`` key). Metrics dictionaries can contain " +"very different kinds of metrics and even key/value pairs that are not " +"metrics at all, so the framework does not (and can not) know how to " +"handle these automatically." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 +msgid "" +"As users, we need to tell the framework how to handle/aggregate these " +"custom metrics, and we do so by passing metric aggregation functions to " +"the strategy. The strategy will then call these functions whenever it " +"receives fit or evaluate metrics from clients. The two possible functions" +" are ``fit_metrics_aggregation_fn`` and " +"``evaluate_metrics_aggregation_fn``." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 +msgid "" +"Let's create a simple weighted averaging function to aggregate the " +"``accuracy`` metric we return from ``evaluate``:" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 +msgid "" +"The only thing left to do is to tell the strategy to call this function " +"whenever it receives evaluation metric dictionaries from the clients:" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 +msgid "" +"We now have a full system that performs federated training and federated " +"evaluation. It uses the ``weighted_average`` function to aggregate custom" +" evaluation metrics and calculates a single ``accuracy`` metric across " +"all clients on the server side." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 +msgid "" +"The other two categories of metrics (``losses_centralized`` and " +"``metrics_centralized``) are still empty because they only apply when " +"centralized evaluation is being used. Part two of the Flower tutorial " +"will cover centralized evaluation." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 +msgid "Final remarks" +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 +msgid "" +"Congratulations, you just trained a convolutional neural network, " +"federated over 10 clients! With that, you understand the basics of " +"federated learning with Flower. The same approach you've seen can be used" +" with other machine learning frameworks (not just PyTorch) and tasks (not" +" just CIFAR-10 images classification), for example NLP with Hugging Face " +"Transformers or speech with SpeechBrain." +msgstr "" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 +msgid "" +"In the next notebook, we're going to cover some more advanced concepts. " +"Want to customize your strategy? Initialize parameters on the server " +"side? Or evaluate the aggregated model on the server side? We'll cover " +"all this and more in the next tutorial." msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 -msgid "" -"In the next part of this tutorial, we are going to build a first " -"federated learning system with Flower." -msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 +msgid "" +"The `Flower Federated Learning Tutorial - Part 2 " +"`__ goes into more depth about strategies and all " +"the advanced things you can build with them." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 +msgid "Use a federated learning strategy" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 +msgid "" +"Welcome to the next part of the federated learning tutorial. In previous " +"parts of this tutorial, we introduced federated learning with PyTorch and" +" Flower (`part 1 `__)." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 +msgid "" +"In this notebook, we'll begin to customize the federated learning system " +"we built in the introductory notebook (again, using `Flower " +"`__ and `PyTorch `__)." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 +msgid "Let's move beyond FedAvg with Flower strategies!" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 +msgid "Strategy customization" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 +msgid "" +"So far, everything should look familiar if you've worked through the " +"introductory notebook. With that, we're ready to introduce a number of " +"new features." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 +msgid "Server-side parameter **initialization**" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 +msgid "" +"Flower, by default, initializes the global model by asking one random " +"client for the initial parameters. In many cases, we want more control " +"over parameter initialization though. Flower therefore allows you to " +"directly pass the initial parameters to the Strategy:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 +msgid "" +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" +" from asking one of the clients for the initial parameters. If we look " +"closely, we can see that the logs do not show any calls to the " +"``FlowerClient.get_parameters`` method." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 +msgid "Starting with a customized strategy" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 +msgid "" +"We've seen the function ``start_simulation`` before. It accepts a number " +"of arguments, amongst them the ``client_fn`` used to create " +"``FlowerClient`` instances, the number of clients to simulate " +"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 +msgid "" +"The strategy encapsulates the federated learning approach/algorithm, for " +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " +"strategy this time:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 +msgid "Server-side parameter **evaluation**" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 +msgid "" +"Flower can evaluate the aggregated model on the server-side or on the " +"client-side. Client-side and server-side evaluation are similar in some " +"ways, but different in others." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 +msgid "" +"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " +"simple: it works the same way that evaluation in centralized machine " +"learning does. If there is a server-side dataset that can be used for " +"evaluation purposes, then that's great. We can evaluate the newly " +"aggregated model after each round of training without having to send the " +"model to clients. We're also fortunate in the sense that our entire " +"evaluation dataset is available at all times." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 +msgid "" +"**Federated Evaluation** (or *client-side evaluation*) is more complex, " +"but also more powerful: it doesn't require a centralized dataset and " +"allows us to evaluate models over a larger set of data, which often " +"yields more realistic evaluation results. In fact, many scenarios require" +" us to use **Federated Evaluation** if we want to get representative " +"evaluation results at all. But this power comes at a cost: once we start " +"to evaluate on the client side, we should be aware that our evaluation " +"dataset can change over consecutive rounds of learning if those clients " +"are not always available. Moreover, the dataset held by each client can " +"also change over consecutive rounds. This can lead to evaluation results " +"that are not stable, so even if we would not change the model, we'd see " +"our evaluation results fluctuate over consecutive rounds." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +msgid "" +"We've seen how federated evaluation works on the client side (i.e., by " +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " +"how we can evaluate aggregated model parameters on the server-side:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 +msgid "Sending/receiving arbitrary values to/from clients" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 +msgid "" +"In some situations, we want to configure client-side execution (training," +" evaluation) from the server-side. One example for that is the server " +"asking the clients to train for a certain number of local epochs. Flower " +"provides a way to send configuration values from the server to the " +"clients using a dictionary. Let's look at an example where the clients " +"receive values from the server through the ``config`` parameter in " +"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " +"method receives the configuration dictionary through the ``config`` " +"parameter and can then read values from this dictionary. In this example," +" it reads ``server_round`` and ``local_epochs`` and uses those values to " +"improve the logging and configure the number of local training epochs:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 +msgid "" +"So how can we send this config dictionary from server to clients? The " +"built-in Flower Strategies provide way to do this, and it works similarly" +" to the way server-side evaluation works. We provide a function to the " +"strategy, and the strategy calls this function for every round of " +"federated learning:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 +msgid "" +"Next, we'll just pass this function to the FedAvg strategy before " +"starting the simulation:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 +msgid "" +"As we can see, the client logs now include the current round of federated" +" learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second" +" round of federated learning, and then for two epochs during the third " +"round." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 +msgid "" +"Clients can also return arbitrary values to the server. To do so, they " +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " +"used this concept throughout this notebook without mentioning it " +"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" +" key/value pair as the third return value in ``evaluate``." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 +msgid "Scaling federated learning" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 +msgid "" +"As a last step in this notebook, let's see how we can use Flower to " +"experiment with a large number of clients." +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 +#, python-format +msgid "" +"We now have 1000 partitions, each holding 45 training and 5 validation " +"examples. Given that the number of training examples on each client is " +"quite small, we should probably train the model a bit longer, so we " +"configure the clients to perform 3 local training epochs. We should also " +"adjust the fraction of clients selected for training during each round " +"(we don't want all 1000 clients participating in every round), so we " +"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " +"available clients (so 50 clients) will be selected for training each " +"round:" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 +msgid "" +"In this notebook, we've seen how we can gradually enhance our system by " +"customizing the strategy, initializing parameters on the server side, " +"choosing a different strategy, and evaluating models on the server-side. " +"That's quite a bit of flexibility with so little code, right?" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 +msgid "" +"In the later sections, we've seen how we can communicate arbitrary values" +" between server and clients to fully customize client-side execution. " +"With that capability, we built a large-scale Federated Learning " +"simulation using the Flower Virtual Client Engine and ran an experiment " +"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +msgstr "" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 +msgid "" +"The `Flower Federated Learning Tutorial - Part 3 " +"`__ shows how to build a fully custom ``Strategy`` from " +"scratch." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 +msgid "What is Federated Learning?" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 +msgid "" +"In this tutorial, you will learn what federated learning is, build your " +"first system in Flower, and gradually extend it. If you work through all " +"parts of the tutorial, you will be able to build advanced federated " +"learning systems that approach the current state of the art in the field." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 +msgid "" +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " +"federated learning. Only a basic understanding of data science and Python" +" programming is assumed." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 +msgid "" +"`Star Flower on GitHub `__ ⭐️ and join " +"the open-source Flower community on Slack to connect, ask questions, and " +"get help: `Join Slack `__ 🌼 We'd love to " +"hear from you in the ``#introductions`` channel! And if anything is " +"unclear, head over to the ``#questions`` channel." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 +msgid "Classic machine learning" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 +msgid "" +"Before we begin to discuss federated learning, let us quickly recap how " +"most machine learning works today." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 +msgid "" +"In machine learning, we have a model, and we have data. The model could " +"be a neural network (as depicted here), or something else, like classical" +" linear regression." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 +msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 +msgid "Model and data" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 +msgid "" +"We train the model using the data to perform a useful task. A task could " +"be to detect objects in images, transcribe an audio recording, or play a " +"game like Go." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 +msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 +msgid "Train model using data" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 +msgid "" +"Now, in practice, the training data we work with doesn't originate on the" +" machine we train the model on. It gets created somewhere else." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 +msgid "" +"It originates on a smartphone by the user interacting with an app, a car " +"collecting sensor data, a laptop receiving input via the keyboard, or a " +"smart speaker listening to someone trying to sing a song." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 +msgid "|2bc8e069228d4873804061ff4a95048c|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 +msgid "Data on a phone" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 +msgid "" +"What's also important to mention, this \"somewhere else\" is usually not " +"just one place, it's many places. It could be several devices all running" +" the same app. But it could also be several organizations, all generating" +" data for the same task." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 +msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 +msgid "Data is on many devices" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 +msgid "" +"So to use machine learning, or any kind of data analysis, the approach " +"that has been used in the past was to collect all data on a central " +"server. This server can be somewhere in a data center, or somewhere in " +"the cloud." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 +msgid "|d5f962c3f4ec48529efda980868c14b0|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 +msgid "Central data collection" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 +msgid "" +"Once all the data is collected in one place, we can finally use machine " +"learning algorithms to train our model on the data. This is the machine " +"learning approach that we've basically always relied on." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 +msgid "|a5eccea18d4c43a68b54b65043cabef8|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 +msgid "Central model training" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 +msgid "Challenges of classical machine learning" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 +msgid "" +"The classic machine learning approach we've just seen can be used in some" +" cases. Great examples include categorizing holiday photos, or analyzing " +"web traffic. Cases, where all the data is naturally available on a " +"centralized server." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 +msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 +msgid "Centralized possible" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 +msgid "" +"But the approach can not be used in many other cases. Cases, where the " +"data is not available on a centralized server, or cases where the data " +"available on one server is not enough to train a good model." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 +msgid "|241fc906441a4f038c625a19d30d01b2|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 +msgid "Centralized impossible" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 +msgid "" +"There are many reasons why the classic centralized machine learning " +"approach does not work for a large number of highly important real-world " +"use cases. Those reasons include:" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 +msgid "" +"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " +"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " +"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " +"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " +"protect sensitive data from being moved. In fact, those regulations " +"sometimes even prevent single organizations from combining their own " +"users' data for artificial intelligence training because those users live" +" in different parts of the world, and their data is governed by different" +" data protection regulations." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 +msgid "" +"**User preference**: In addition to regulation, there are use cases where" +" users just expect that no data leaves their device, ever. If you type " +"your passwords and credit card info into the digital keyboard of your " +"phone, you don't expect those passwords to end up on the server of the " +"company that developed that keyboard, do you? In fact, that use case was " +"the reason federated learning was invented in the first place." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 +msgid "" +"**Data volume**: Some sensors, like cameras, produce such a high data " +"volume that it is neither feasible nor economic to collect all the data " +"(due to, for example, bandwidth or communication efficiency). Think about" +" a national rail service with hundreds of train stations across the " +"country. If each of these train stations is outfitted with a number of " +"security cameras, the volume of raw on-device data they produce requires " +"incredibly powerful and exceedingly expensive infrastructure to process " +"and store. And most of the data isn't even useful." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 +msgid "Examples where centralized machine learning does not work include:" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 +msgid "" +"Sensitive healthcare records from multiple hospitals to train cancer " +"detection models" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 +msgid "" +"Financial information from different organizations to detect financial " +"fraud" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 +msgid "Location data from your electric car to make better range prediction" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 +msgid "End-to-end encrypted messages to train better auto-complete models" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 +msgid "" +"The popularity of privacy-enhancing systems like the `Brave " +"`__ browser or the `Signal `__ " +"messenger shows that users care about privacy. In fact, they choose the " +"privacy-enhancing version over other alternatives, if such an alternative" +" exists. But what can we do to apply machine learning and data science to" +" these cases to utilize private data? After all, these are all areas that" +" would benefit significantly from recent advances in AI." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 +msgid "Federated learning" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 +msgid "" +"Federated learning simply reverses this approach. It enables machine " +"learning on distributed data by moving the training to the data, instead " +"of moving the data to the training. Here's the single-sentence " +"explanation:" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 +msgid "Central machine learning: move the data to the computation" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 +msgid "Federated (machine) learning: move the computation to the data" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 +msgid "" +"By doing so, it enables us to use machine learning (and other data " +"science approaches) in areas where it wasn't possible before. We can now " +"train excellent medical AI models by enabling different hospitals to work" +" together. We can solve financial fraud by training AI models on the data" +" of different financial institutions. We can build novel privacy-" +"enhancing applications (such as secure messaging) that have better built-" +"in AI than their non-privacy-enhancing alternatives. And those are just a" +" few of the examples that come to mind. As we deploy federated learning, " +"we discover more and more areas that can suddenly be reinvented because " +"they now have access to vast amounts of previously inaccessible data." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 +msgid "" +"So how does federated learning work, exactly? Let's start with an " +"intuitive explanation." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 +msgid "Federated learning in five steps" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 +msgid "Step 0: Initialize global model" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 +msgid "" +"We start by initializing the model on the server. This is exactly the " +"same in classic centralized learning: we initialize the model parameters," +" either randomly or from a previously saved checkpoint." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 +msgid "|0aa5aa05810b44b6a835cecce28f3137|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 +msgid "Initialize global model" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 +msgid "" +"Step 1: Send model to a number of connected organizations/devices (client" +" nodes)" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 +msgid "" +"Next, we send the parameters of the global model to the connected client " +"nodes (think: edge devices like smartphones or servers belonging to " +"organizations). This is to ensure that each participating node starts " +"their local training using the same model parameters. We often use only a" +" few of the connected nodes instead of all nodes. The reason for this is " +"that selecting more and more client nodes has diminishing returns." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 +msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 +msgid "Send global model" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 +msgid "" +"Step 2: Train model locally on the data of each organization/device " +"(client node)" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 +msgid "" +"Now that all (selected) client nodes have the latest version of the " +"global model parameters, they start the local training. They use their " +"own local dataset to train their own local model. They don't train the " +"model until full convergence, but they only train for a little while. " +"This could be as little as one epoch on the local data, or even just a " +"few steps (mini-batches)." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 +msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 +msgid "Train on local data" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 +msgid "Step 3: Return model updates back to the server" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 +msgid "" +"After local training, each client node has a slightly different version " +"of the model parameters they originally received. The parameters are all " +"different because each client node has different examples in its local " +"dataset. The client nodes then send those model updates back to the " +"server. The model updates they send can either be the full model " +"parameters or just the gradients that were accumulated during local " +"training." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 +msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 +msgid "Send model updates" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 +msgid "Step 4: Aggregate model updates into a new global model" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 +msgid "" +"The server receives model updates from the selected client nodes. If it " +"selected 100 client nodes, it now has 100 slightly different versions of " +"the original global model, each trained on the local data of one client. " +"But didn't we want to have one model that contains the learnings from the" +" data of all 100 client nodes?" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 +msgid "" +"In order to get one single model, we have to combine all the model " +"updates we received from the client nodes. This process is called " +"*aggregation*, and there are many different ways to do it. The most basic" +" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " +"`__), often abbreviated as *FedAvg*. " +"*FedAvg* takes the 100 model updates and, as the name suggests, averages " +"them. To be more precise, it takes the *weighted average* of the model " +"updates, weighted by the number of examples each client used for " +"training. The weighting is important to make sure that each data example " +"has the same \"influence\" on the resulting global model. If one client " +"has 10 examples, and another client has 100 examples, then - without " +"weighting - each of the 10 examples would influence the global model ten " +"times as much as each of the 100 examples." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 +msgid "|72939caf6e294b0986fee6dde96614d7|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 +msgid "Aggregate model updates" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 +msgid "Step 5: Repeat steps 1 to 4 until the model converges" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 +msgid "" +"Steps 1 to 4 are what we call a single round of federated learning. The " +"global model parameters get sent to the participating client nodes (step " +"1), the client nodes train on their local data (step 2), they send their " +"updated models to the server (step 3), and the server then aggregates the" +" model updates to get a new version of the global model (step 4)." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 +msgid "" +"During a single round, each client node that participates in that " +"iteration only trains for a little while. This means that after the " +"aggregation step (step 4), we have a model that has been trained on all " +"the data of all participating client nodes, but only for a little while. " +"We then have to repeat this training process over and over again to " +"eventually arrive at a fully trained model that performs well across the " +"data of all client nodes." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 +msgid "" +"Congratulations, you now understand the basics of federated learning. " +"There's a lot more to discuss, of course, but that was federated learning" +" in a nutshell. In later parts of this tutorial, we will go into more " +"detail. Interesting questions include: How can we select the best client " +"nodes that should participate in the next round? What's the best way to " +"aggregate model updates? How can we handle failing client nodes " +"(stragglers)?" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 +msgid "" +"Just like we can train a model on the decentralized data of different " +"client nodes, we can also evaluate the model on that data to receive " +"valuable metrics. This is called federated evaluation, sometimes " +"abbreviated as FE. In fact, federated evaluation is an integral part of " +"most federated learning systems." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 +msgid "Federated analytics" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 +msgid "" +"In many cases, machine learning isn't necessary to derive value from " +"data. Data analysis can yield valuable insights, but again, there's often" +" not enough data to get a clear answer. What's the average age at which " +"people develop a certain type of health condition? Federated analytics " +"enables such queries over multiple client nodes. It is usually used in " +"conjunction with other privacy-enhancing technologies like secure " +"aggregation to prevent the server from seeing the results submitted by " +"individual client nodes." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 +msgid "" +"Differential privacy (DP) is often mentioned in the context of Federated " +"Learning. It is a privacy-preserving method used when analyzing and " +"sharing statistical data, ensuring the privacy of individual " +"participants. DP achieves this by adding statistical noise to the model " +"updates, ensuring any individual participants’ information cannot be " +"distinguished or re-identified. This technique can be considered an " +"optimization that provides a quantifiable privacy protection measure." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 +msgid "Flower" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 +msgid "" +"Federated learning, federated evaluation, and federated analytics require" +" infrastructure to move machine learning models back and forth, train and" +" evaluate them on local data, and then aggregate the updated models. " +"Flower provides the infrastructure to do exactly that in an easy, " +"scalable, and secure way. In short, Flower presents a unified approach to" +" federated learning, analytics, and evaluation. It allows the user to " +"federate any workload, any ML framework, and any programming language." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 +msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 +msgid "" +"Flower federated learning server and client nodes (car, scooter, personal" +" computer, roomba, and phone)" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 +msgid "" +"Congratulations, you just learned the basics of federated learning and " +"how it relates to the classic (centralized) machine learning!" +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 +msgid "" +"In the next part of this tutorial, we are going to build a first " +"federated learning system with Flower." +msgstr "" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 +msgid "" +"The `Flower Federated Learning Tutorial - Part 1 " +"`__ shows how to build a simple federated learning system " +"with PyTorch and Flower." +msgstr "" + +#~ msgid "" +#~ "Configuring and setting up the " +#~ ":code:`Dockerfile` as well the configuration" +#~ " for the devcontainer can be a " +#~ "bit more involved. The good thing " +#~ "is you want have to do it. " +#~ "Usually it should be enough to " +#~ "install Docker on your system and " +#~ "ensure its available on your command " +#~ "line. Additionally, install the `VSCode " +#~ "Containers Extension `_." +#~ msgstr "" + +#~ msgid "" +#~ "``flwr = { path = " +#~ "\"../../dist/flwr-1.0.0-py3-none-any.whl\" }`` " +#~ "(without extras)" +#~ msgstr "" + +#~ msgid "" +#~ "``flwr = { path = " +#~ "\"../../dist/flwr-1.0.0-py3-none-any.whl\", extras =" +#~ " [\"simulation\"] }`` (with extras)" +#~ msgstr "" + +#~ msgid "Upload the whl (e.g., ``flwr-1.7.0-py3-none-any.whl``)" +#~ msgstr "" + +#~ msgid "" +#~ "Change ``!pip install -q 'flwr[simulation]'" +#~ " torch torchvision matplotlib`` to ``!pip" +#~ " install -q 'flwr-1.7.0-py3-none-" +#~ "any.whl[simulation]' torch torchvision matplotlib``" +#~ msgstr "" + +#~ msgid "Before the release" +#~ msgstr "" + +#~ msgid "" +#~ "Update the changelog (``changelog.md``) with" +#~ " all relevant changes that happened " +#~ "after the last release. If the " +#~ "last release was tagged ``v1.2.0``, you" +#~ " can use the following URL to " +#~ "see all commits that got merged " +#~ "into ``main`` since then:" +#~ msgstr "" + +#~ msgid "" +#~ "`GitHub: Compare v1.2.0...main " +#~ "`_" +#~ msgstr "" + +#~ msgid "" +#~ "Thank the authors who contributed since" +#~ " the last release. This can be " +#~ "done by running the ``./dev/add-" +#~ "shortlog.sh`` convenience script (it can " +#~ "be ran multiple times and will " +#~ "update the names in the list if" +#~ " new contributors were added in the" +#~ " meantime)." +#~ msgstr "" + +#~ msgid "" +#~ "Update the ``changelog.md`` section header " +#~ "``Unreleased`` to contain the version " +#~ "number and date for the release " +#~ "you are building. Create a pull " +#~ "request with the change." +#~ msgstr "" + +#~ msgid "" +#~ "Tag the release commit with the " +#~ "version number as soon as the PR" +#~ " is merged: ``git tag v0.12.3``, then" +#~ " ``git push --tags``. This will " +#~ "create a draft release on GitHub " +#~ "containing the correct artifacts and the" +#~ " relevant part of the changelog." +#~ msgstr "" + +#~ msgid "" +#~ "Note that, in order to build the" +#~ " documentation locally (with ``poetry run" +#~ " make html``, like described below), " +#~ "`Pandoc _` needs " +#~ "to be installed on the system." +#~ msgstr "" + +#~ msgid "" +#~ "If you're familiar with how contributing" +#~ " on GitHub works, you can directly" +#~ " checkout our `getting started guide " +#~ "for contributors `_ and examples " +#~ "of `good first contributions " +#~ "`_." +#~ msgstr "" + +#~ msgid "" +#~ "This will create a `flower/` (or " +#~ "the name of your fork if you " +#~ "renamed it) folder in the current " +#~ "working directory." +#~ msgstr "" + +#~ msgid "Otherwise you can always find this option in the `Branches` page." +#~ msgstr "" + +#~ msgid "" +#~ "Once you click the `Compare & pull" +#~ " request` button, you should see " +#~ "something similar to this:" +#~ msgstr "" + +#~ msgid "Find the source file in `doc/source`" +#~ msgstr "" + +#~ msgid "" +#~ "Make the change in the `.rst` file" +#~ " (beware, the dashes under the title" +#~ " should be the same length as " +#~ "the title itself)" +#~ msgstr "" + +#~ msgid "Change the file name to `save-progress.rst`" +#~ msgstr "" + +#~ msgid "Add a redirect rule to `doc/source/conf.py`" +#~ msgstr "" + +#~ msgid "" +#~ "This will cause a redirect from " +#~ "`saving-progress.html` to `save-progress.html`," +#~ " old links will continue to work." +#~ msgstr "" + +#~ msgid "" +#~ "For the lateral navigation bar to " +#~ "work properly, it is very important " +#~ "to update the `index.rst` file as " +#~ "well. This is where we define the" +#~ " whole arborescence of the navbar." +#~ msgstr "" + +#~ msgid "Find and modify the file name in `index.rst`" +#~ msgstr "" + +#~ msgid "Add CI job to deploy the staging system when the `main` branch changes" +#~ msgstr "" + +#~ msgid "`Python 3.7 `_ or above" +#~ msgstr "" + +#~ msgid "" +#~ "First, clone the `Flower repository " +#~ "`_ from GitHub::" +#~ msgstr "" + +#~ msgid "" +#~ "Second, create a virtual environment " +#~ "(and activate it). If you chose to" +#~ " use :code:`pyenv` (with the :code" +#~ ":`pyenv-virtualenv` plugin) and already " +#~ "have it installed , you can use" +#~ " the following convenience script (by " +#~ "default it will use :code:`Python " +#~ "3.8.17`, but you can change it by" +#~ " providing a specific :code:``)::" +#~ msgstr "" + +#~ msgid "" +#~ "If you don't have :code:`pyenv` " +#~ "installed, you can use the following " +#~ "script that will install pyenv, set " +#~ "it up and create the virtual " +#~ "environment (with :code:`Python 3.8.17` by " +#~ "default)::" +#~ msgstr "" + +#~ msgid "" +#~ "Third, install the Flower package in " +#~ "development mode (think :code:`pip install " +#~ "-e`) along with all necessary " +#~ "dependencies::" +#~ msgstr "" + +#~ msgid "" +#~ "Developers could run the full set " +#~ "of Github Actions workflows under their" +#~ " local environment by using `Act " +#~ "_`. Please refer to" +#~ " the installation instructions under the" +#~ " linked repository and run the next" +#~ " command under Flower main cloned " +#~ "repository folder::" +#~ msgstr "" + +#~ msgid "" +#~ "Please note that these components are" +#~ " still experimental, the correct " +#~ "configuration of DP for a specific " +#~ "task is still an unsolved problem." +#~ msgstr "" + +#~ msgid "" +#~ "The distribution of the update norm " +#~ "has been shown to vary from " +#~ "task-to-task and to evolve as " +#~ "training progresses. Therefore, we use " +#~ "an adaptive approach [andrew]_ that " +#~ "continuously adjusts the clipping threshold" +#~ " to track a prespecified quantile of" +#~ " the update norm distribution." +#~ msgstr "" + +#~ msgid "" +#~ "We make (and attempt to enforce) a" +#~ " number of assumptions that must be" +#~ " satisfied to ensure that the " +#~ "training process actually realises the " +#~ ":math:`(\\epsilon, \\delta)` guarantees the " +#~ "user has in mind when configuring " +#~ "the setup." +#~ msgstr "" + +#~ msgid "" +#~ "The first two are useful for " +#~ "eliminating a multitude of complications " +#~ "associated with calibrating the noise to" +#~ " the clipping threshold while the " +#~ "third one is required to comply " +#~ "with the assumptions of the privacy " +#~ "analysis." +#~ msgstr "" + +#~ msgid "" +#~ "The first version of our solution " +#~ "was to define a decorator whose " +#~ "constructor accepted, among other things, " +#~ "a boolean valued variable indicating " +#~ "whether adaptive clipping was to be " +#~ "enabled or not. We quickly realized " +#~ "that this would clutter its " +#~ ":code:`__init__()` function with variables " +#~ "corresponding to hyperparameters of adaptive" +#~ " clipping that would remain unused " +#~ "when it was disabled. A cleaner " +#~ "implementation could be achieved by " +#~ "splitting the functionality into two " +#~ "decorators, :code:`DPFedAvgFixed` and " +#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" +#~ " classing the former. The constructors " +#~ "for both classes accept a boolean " +#~ "parameter :code:`server_side_noising`, which, as " +#~ "the name suggests, determines where " +#~ "noising is to be performed." +#~ msgstr "" + +#~ msgid "" +#~ ":code:`aggregate_fit()`: We check whether any" +#~ " of the sampled clients dropped out" +#~ " or failed to upload an update " +#~ "before the round timed out. In " +#~ "that case, we need to abort the" +#~ " current round, discarding any successful" +#~ " updates that were received, and move" +#~ " on to the next one. On the " +#~ "other hand, if all clients responded " +#~ "successfully, we must force the " +#~ "averaging of the updates to happen " +#~ "in an unweighted manner by intercepting" +#~ " the :code:`parameters` field of " +#~ ":code:`FitRes` for each received update " +#~ "and setting it to 1. Furthermore, " +#~ "if :code:`server_side_noising=true`, each update " +#~ "is perturbed with an amount of " +#~ "noise equal to what it would have" +#~ " been subjected to had client-side" +#~ " noising being enabled. This entails " +#~ "*pre*-processing of the arguments to " +#~ "this method before passing them on " +#~ "to the wrappee's implementation of " +#~ ":code:`aggregate_fit()`." +#~ msgstr "" + +#~ msgid "" +#~ "McMahan, H. Brendan, et al. \"Learning" +#~ " differentially private recurrent language " +#~ "models.\" arXiv preprint arXiv:1710.06963 " +#~ "(2017)." +#~ msgstr "" + +#~ msgid "" +#~ "Andrew, Galen, et al. \"Differentially " +#~ "private learning with adaptive clipping.\" " +#~ "Advances in Neural Information Processing " +#~ "Systems 34 (2021): 17455-17466." +#~ msgstr "" + +#~ msgid "" +#~ "The following command can be used " +#~ "to verfiy if Flower was successfully " +#~ "installed. If everything worked, it " +#~ "should print the version of Flower " +#~ "to the command line::" +#~ msgstr "" + +#~ msgid "flwr (Python API reference)" +#~ msgstr "" + +#~ msgid "start_client" +#~ msgstr "" + +#~ msgid "start_numpy_client" +#~ msgstr "" + +#~ msgid "start_simulation" +#~ msgstr "" + +#~ msgid "server.start_server" +#~ msgstr "" + +#~ msgid "server.strategy" +#~ msgstr "" + +#~ msgid "server.strategy.Strategy" +#~ msgstr "" + +#~ msgid "server.strategy.FedAvg" +#~ msgstr "" + +#~ msgid "server.strategy.FedAvgM" +#~ msgstr "" + +#~ msgid "server.strategy.FedMedian" +#~ msgstr "" + +#~ msgid "server.strategy.QFedAvg" +#~ msgstr "" + +#~ msgid "server.strategy.FaultTolerantFedAvg" +#~ msgstr "" + +#~ msgid "server.strategy.FedOpt" +#~ msgstr "" + +#~ msgid "server.strategy.FedProx" +#~ msgstr "" + +#~ msgid "server.strategy.FedAdagrad" +#~ msgstr "" + +#~ msgid "server.strategy.FedAdam" +#~ msgstr "" + +#~ msgid "server.strategy.FedYogi" +#~ msgstr "" + +#~ msgid "server.strategy.FedTrimmedAvg" +#~ msgstr "" + +#~ msgid "server.strategy.Krum" +#~ msgstr "" + +#~ msgid "server.strategy.FedXgbNnAvg" +#~ msgstr "" + +#~ msgid "server.strategy.DPFedAvgAdaptive" +#~ msgstr "" + +#~ msgid "server.strategy.DPFedAvgFixed" +#~ msgstr "" + +#~ msgid "" +#~ "**Fix the incorrect return types of " +#~ "Strategy** " +#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" +#~ msgstr "" + +#~ msgid "" +#~ "The types of the return values in" +#~ " the docstrings in two methods " +#~ "(`aggregate_fit` and `aggregate_evaluate`) now " +#~ "match the hint types in the code." +#~ msgstr "" + +#~ msgid "" +#~ "Using the `client_fn`, Flower clients " +#~ "can interchangeably run as standalone " +#~ "processes (i.e. via `start_client`) or " +#~ "in simulation (i.e. via `start_simulation`)" +#~ " without requiring changes to how the" +#~ " client class is defined and " +#~ "instantiated. Calling `start_numpy_client` is " +#~ "now deprecated." +#~ msgstr "" + +#~ msgid "" +#~ "**Update Flower Examples** " +#~ "([#2384](https://github.com/adap/flower/pull/2384)), " +#~ "([#2425](https://github.com/adap/flower/pull/2425))" +#~ msgstr "" + +#~ msgid "" +#~ "**General updates to baselines** " +#~ "([#2301](https://github.com/adap/flower/pull/2301), " +#~ "[#2305](https://github.com/adap/flower/pull/2305), " +#~ "[#2307](https://github.com/adap/flower/pull/2307), " +#~ "[#2327](https://github.com/adap/flower/pull/2327), " +#~ "[#2435](https://github.com/adap/flower/pull/2435))" +#~ msgstr "" + +#~ msgid "" +#~ "**General updates to the simulation " +#~ "engine** ([#2331](https://github.com/adap/flower/pull/2331), " +#~ "[#2447](https://github.com/adap/flower/pull/2447), " +#~ "[#2448](https://github.com/adap/flower/pull/2448))" +#~ msgstr "" + +#~ msgid "" +#~ "**General improvements** " +#~ "([#2309](https://github.com/adap/flower/pull/2309), " +#~ "[#2310](https://github.com/adap/flower/pull/2310), " +#~ "[2313](https://github.com/adap/flower/pull/2313), " +#~ "[#2316](https://github.com/adap/flower/pull/2316), " +#~ "[2317](https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/flower/pull/2349)," +#~ " [#2360](https://github.com/adap/flower/pull/2360), " +#~ "[#2402](https://github.com/adap/flower/pull/2402), " +#~ "[#2446](https://github.com/adap/flower/pull/2446))" +#~ msgstr "" + +#~ msgid "" +#~ "`flower-superlink --driver-api-address " +#~ "\"0.0.0.0:8081\" --fleet-api-address " +#~ "\"0.0.0.0:8086\"`" +#~ msgstr "" + +#~ msgid "" +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()`. The string " +#~ ":code:`\"0.0.0.0:8080\"` tells the client " +#~ "which server to connect to. In our" +#~ " case we can run the server and" +#~ " the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" +#~ " we run a truly federated workload" +#~ " with the server and clients running" +#~ " on different machines, all that " +#~ "needs to change is the " +#~ ":code:`server_address` we pass to the " +#~ "client." +#~ msgstr "" + +#~ msgid "" +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()`. The string " +#~ ":code:`\"[::]:8080\"` tells the client which" +#~ " server to connect to. In our " +#~ "case we can run the server and " +#~ "the client on the same machine, " +#~ "therefore we use :code:`\"[::]:8080\"`. If " +#~ "we run a truly federated workload " +#~ "with the server and clients running " +#~ "on different machines, all that needs" +#~ " to change is the :code:`server_address`" +#~ " we point the client at." +#~ msgstr "" + +#~ msgid "" +#~ "Let's build a horizontal federated " +#~ "learning system using XGBoost and " +#~ "Flower!" +#~ msgstr "" + +#~ msgid "" +#~ "Please refer to the `full code " +#~ "example `_ to learn " +#~ "more." +#~ msgstr "" + +#~ msgid "" +#~ "In this notebook, we'll build a " +#~ "federated learning system using Flower " +#~ "and PyTorch. In part 1, we use " +#~ "PyTorch for the model training pipeline" +#~ " and data loading. In part 2, " +#~ "we continue to federate the PyTorch-" +#~ "based pipeline using Flower." +#~ msgstr "" + +#~ msgid "" +#~ "Next, we install the necessary packages" +#~ " for PyTorch (``torch`` and " +#~ "``torchvision``) and Flower (``flwr``):" +#~ msgstr "" + +#~ msgid "" +#~ "Federated learning can be applied to " +#~ "many different types of tasks across " +#~ "different domains. In this tutorial, we" +#~ " introduce federated learning by training" +#~ " a simple convolutional neural network " +#~ "(CNN) on the popular CIFAR-10 dataset." +#~ " CIFAR-10 can be used to train " +#~ "image classifiers that distinguish between " +#~ "images from ten different classes:" +#~ msgstr "" + +#~ msgid "" +#~ "Each organization will act as a " +#~ "client in the federated learning system." +#~ " So having ten organizations participate" +#~ " in a federation means having ten " +#~ "clients connected to the federated " +#~ "learning server:" +#~ msgstr "" + +#~ msgid "" +#~ "Let's now load the CIFAR-10 training " +#~ "and test set, partition them into " +#~ "ten smaller datasets (each split into" +#~ " training and validation set), and " +#~ "wrap the resulting partitions by " +#~ "creating a PyTorch ``DataLoader`` for " +#~ "each of them:" +#~ msgstr "" + +#~ msgid "|ed6498a023f2477a9ccd57ee4514bda4|" +#~ msgstr "" + +#~ msgid "|5a4f742489ac4f819afefdd4dc9ab272|" +#~ msgstr "" + +#~ msgid "|3331c80cd05045f6a56524d8e3e76d0c|" +#~ msgstr "" + +#~ msgid "|4987b26884ec4b2c8f06c1264bcebe60|" +#~ msgstr "" + +#~ msgid "|ec8ae2d778aa493a986eb2fa29c220e5|" +#~ msgstr "" + +#~ msgid "|b8949d0669fe4f8eadc9a4932f4e9c57|" +#~ msgstr "" + +#~ msgid "|94ff30bdcd09443e8488b5f29932a541|" +#~ msgstr "" + +#~ msgid "|48dccf1d6d0544bba8917d2783a47719|" +#~ msgstr "" + +#~ msgid "|0366618db96b4f329f0d4372d1150fde|" +#~ msgstr "" + +#~ msgid "|ac80eddc76e6478081b1ca35eed029c0|" +#~ msgstr "" + +#~ msgid "|1ac94140c317450e89678db133c7f3c2|" +#~ msgstr "" + +#~ msgid "|f8850c6e96fc4430b55e53bba237a7c0|" +#~ msgstr "" + +#~ msgid "|4a368fdd3fc34adabd20a46752a68582|" +#~ msgstr "" + +#~ msgid "|40f69c17bb444652a7c8dfe577cd120e|" +#~ msgstr "" + +#~ msgid "" +#~ "Please follow the first section on " +#~ "`Run Flower using Docker " +#~ "`_ which covers this" +#~ " step in more detail." +#~ msgstr "" + +#~ msgid "" +#~ "Since `Flower 1.5 `_ we have " +#~ "introduced translations to our doc " +#~ "pages, but, as you might have " +#~ "noticed, the translations are often " +#~ "imperfect. If you speak languages other" +#~ " than English, you might be able " +#~ "to help us in our effort to " +#~ "make Federated Learning accessible to as" +#~ " many people as possible by " +#~ "contributing to those translations! This " +#~ "might also be a great opportunity " +#~ "for those wanting to become open " +#~ "source contributors with little prerequistes." +#~ msgstr "" + +#~ msgid "" +#~ "You input your translation in the " +#~ "textbox at the top and then, once" +#~ " you are happy with it, you " +#~ "either press ``Save and continue`` (to" +#~ " save the translation and go to " +#~ "the next untranslated string), ``Save " +#~ "and stay`` (to save the translation " +#~ "and stay on the same page), " +#~ "``Suggest`` (to add your translation to" +#~ " suggestions for other users to " +#~ "view), or ``Skip`` (to go to the" +#~ " next untranslated string without saving" +#~ " anything)." +#~ msgstr "" + +#~ msgid "" +#~ "The first thing we need to do " +#~ "is to define a message type for" +#~ " the RPC system in :code:`transport.proto`." +#~ " Note that we have to do it " +#~ "for both the request and response " +#~ "messages. For more details on the " +#~ "syntax of proto3, please see the " +#~ "`official documentation `_." +#~ msgstr "" + +#~ msgid "" +#~ "Source: `Official VSCode documentation " +#~ "`_" +#~ msgstr "" + +#~ msgid "" +#~ "`Developing inside a Container " +#~ "`_" +#~ msgstr "" + +#~ msgid "" +#~ "`Remote development in Containers " +#~ "`_" +#~ msgstr "" + +#~ msgid "" +#~ "If you are not familiar with " +#~ "Flower Baselines, you should probably " +#~ "check-out our `contributing guide for " +#~ "baselines `_." +#~ msgstr "" + +#~ msgid "" +#~ "You should then check out the open" +#~ " `issues " +#~ "`_" +#~ " for baseline requests. If you find" +#~ " a baseline that you'd like to " +#~ "work on and that has no assignes," +#~ " feel free to assign it to " +#~ "yourself and start working on it!" +#~ msgstr "" + +#~ msgid "" +#~ "If you're familiar with how contributing" +#~ " on GitHub works, you can directly" +#~ " checkout our `getting started guide " +#~ "for contributors `_." +#~ msgstr "" + +#~ msgid "" +#~ "Git is a distributed version control " +#~ "tool. This allows for an entire " +#~ "codebase's history to be stored and " +#~ "every developer's machine. It is a " +#~ "software that will need to be " +#~ "installed on your local machine, you " +#~ "can follow this `guide " +#~ "`_ to set it up." +#~ msgstr "" + +#~ msgid "" +#~ "A fork is a personal copy of " +#~ "a GitHub repository. To create one " +#~ "for Flower, you must navigate to " +#~ "https://github.com/adap/flower (while connected to" +#~ " your GitHub account) and click the" +#~ " ``Fork`` button situated on the top" +#~ " right of the page." +#~ msgstr "" + +#~ msgid "" +#~ "Now we will add an upstream " +#~ "address to our repository. Still in " +#~ "the same directroy, we must run " +#~ "the following command:" +#~ msgstr "" + +#~ msgid "" +#~ "This can be achieved by following " +#~ "this `getting started guide for " +#~ "contributors`_ (note that you won't need" +#~ " to clone the repository). Once you" +#~ " are able to write code and " +#~ "test it, you can finally start " +#~ "making changes!" +#~ msgstr "" + +#~ msgid "" +#~ "For our documentation, we’ve started to" +#~ " use the `Diàtaxis framework " +#~ "`_." +#~ msgstr "" + +#~ msgid "" +#~ "Our “How to” guides should have " +#~ "titles that continue the sencence “How" +#~ " to …”, for example, “How to " +#~ "upgrade to Flower 1.0”." +#~ msgstr "" + +#~ msgid "" +#~ "This issue is about changing the " +#~ "title of a doc from present " +#~ "continious to present simple." +#~ msgstr "" + +#~ msgid "" +#~ "Let's take the example of “Saving " +#~ "Progress” which we changed to “Save " +#~ "Progress”. Does this pass our check?" +#~ msgstr "" + +#~ msgid "Before: ”How to saving progress” ❌" +#~ msgstr "" + +#~ msgid "After: ”How to save progress” ✅" +#~ msgstr "" + +#~ msgid "" +#~ "This is a tiny change, but it’ll" +#~ " allow us to test your end-" +#~ "to-end setup. After cloning and " +#~ "setting up the Flower repo, here’s " +#~ "what you should do:" +#~ msgstr "" + +#~ msgid "" +#~ "Build the docs and check the " +#~ "result: ``_" +#~ msgstr "" + +#~ msgid "Here’s how to change the file name:" +#~ msgstr "" + +#~ msgid "" +#~ "Commit the changes (commit messages are" +#~ " always imperative: “Do something”, in " +#~ "this case “Change …”)" +#~ msgstr "" + +#~ msgid "" +#~ "`Good first contributions " +#~ "`_, where you should" +#~ " particularly look into the " +#~ ":code:`baselines` contributions." +#~ msgstr "" + +#~ msgid "" +#~ "If the section is completely empty " +#~ "(without any token) or non-existant, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." +#~ msgstr "" + +#~ msgid "" +#~ "Flower uses :code:`pyproject.toml` to manage" +#~ " dependencies and configure development " +#~ "tools (the ones which support it). " +#~ "Poetry is a build tool which " +#~ "supports `PEP 517 " +#~ "`_." +#~ msgstr "" + +#~ msgid "" +#~ "This tutorial will show you how to" +#~ " use Flower to build a federated " +#~ "version of an existing machine learning" +#~ " workload with `FedBN `_, a federated training strategy" +#~ " designed for non-iid data. We " +#~ "are using PyTorch to train a " +#~ "Convolutional Neural Network(with Batch " +#~ "Normalization layers) on the CIFAR-10 " +#~ "dataset. When applying FedBN, only few" +#~ " changes needed compared to `Example: " +#~ "PyTorch - From Centralized To Federated" +#~ " `_." +#~ msgstr "" + +#~ msgid "" +#~ "All files are revised based on " +#~ "`Example: PyTorch - From Centralized To" +#~ " Federated `_. The " +#~ "only thing to do is modifying the" +#~ " file called :code:`cifar.py`, revised part" +#~ " is shown below:" +#~ msgstr "" + +#~ msgid "" +#~ "So far this should all look fairly" +#~ " familiar if you've used PyTorch " +#~ "before. Let's take the next step " +#~ "and use what we've built to create" +#~ " a federated learning system within " +#~ "FedBN, the sytstem consists of one " +#~ "server and two clients." +#~ msgstr "" + +#~ msgid "" +#~ "If you have read `Example: PyTorch " +#~ "- From Centralized To Federated " +#~ "`_, the following" +#~ " parts are easy to follow, onyl " +#~ ":code:`get_parameters` and :code:`set_parameters` " +#~ "function in :code:`client.py` needed to " +#~ "revise. If not, please read the " +#~ "`Example: PyTorch - From Centralized To" +#~ " Federated `_. first." +#~ msgstr "" + +#~ msgid "Example: Walk-Through PyTorch & MNIST" +#~ msgstr "" + +#~ msgid "" +#~ "In this tutorial we will learn, " +#~ "how to train a Convolutional Neural " +#~ "Network on MNIST using Flower and " +#~ "PyTorch." +#~ msgstr "" + +#~ msgid "" +#~ "Since we want to use PyTorch to" +#~ " solve a computer vision task, let's" +#~ " go ahead an install PyTorch and " +#~ "the **torchvision** library:" +#~ msgstr "" + +#~ msgid "Ready... Set... Train!" +#~ msgstr "" + +#~ msgid "" +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on PyTorch's `Basic MNIST Example" +#~ " `_. " +#~ "This will allow you see how easy" +#~ " it is to wrap your code with" +#~ " Flower and begin training in a " +#~ "federated way. We provide you with " +#~ "two helper scripts, namely *run-" +#~ "server.sh*, and *run-clients.sh*. Don't " +#~ "be afraid to look inside, they are" +#~ " simple enough =)." +#~ msgstr "" + +#~ msgid "" +#~ "Go ahead and launch on a terminal" +#~ " the *run-server.sh* script first as" +#~ " follows:" +#~ msgstr "" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 -msgid "" -"The `Flower Federated Learning Tutorial - Part 1 " -"`__ shows how to build a simple federated learning system " -"with PyTorch and Flower." -msgstr "" +#~ msgid "Now that the server is up and running, go ahead and launch the clients." +#~ msgstr "" #~ msgid "" -#~ "Configuring and setting up the " -#~ ":code:`Dockerfile` as well the configuration" -#~ " for the devcontainer can be a " -#~ "bit more involved. The good thing " -#~ "is you want have to do it. " -#~ "Usually it should be enough to " -#~ "install Docker on your system and " -#~ "ensure its available on your command " -#~ "line. Additionally, install the `VSCode " -#~ "Containers Extension `_." +#~ "Et voilà! You should be seeing the" +#~ " training procedure and, after a few" +#~ " iterations, the test accuracy for " +#~ "each client." +#~ msgstr "" + +#~ msgid "Now, let's see what is really happening inside." #~ msgstr "" #~ msgid "" -#~ "``flwr = { path = " -#~ "\"../../dist/flwr-1.0.0-py3-none-any.whl\" }`` " -#~ "(without extras)" +#~ "Inside the server helper script *run-" +#~ "server.sh* you will find the following" +#~ " code that basically runs the " +#~ ":code:`server.py`" #~ msgstr "" #~ msgid "" -#~ "``flwr = { path = " -#~ "\"../../dist/flwr-1.0.0-py3-none-any.whl\", extras =" -#~ " [\"simulation\"] }`` (with extras)" +#~ "We can go a bit deeper and " +#~ "see that :code:`server.py` simply launches " +#~ "a server that will coordinate three " +#~ "rounds of training. Flower Servers are" +#~ " very customizable, but for simple " +#~ "workloads, we can start a server " +#~ "using the :ref:`start_server ` function and leave " +#~ "all the configuration possibilities at " +#~ "their default values, as seen below." #~ msgstr "" -#~ msgid "Upload the whl (e.g., ``flwr-1.7.0-py3-none-any.whl``)" +#~ msgid "" +#~ "Next, let's take a look at the " +#~ "*run-clients.sh* file. You will see " +#~ "that it contains the main loop " +#~ "that starts a set of *clients*." #~ msgstr "" #~ msgid "" -#~ "Change ``!pip install -q 'flwr[simulation]'" -#~ " torch torchvision matplotlib`` to ``!pip" -#~ " install -q 'flwr-1.7.0-py3-none-" -#~ "any.whl[simulation]' torch torchvision matplotlib``" +#~ "**cid**: is the client ID. It is" +#~ " an integer that uniquely identifies " +#~ "client identifier." #~ msgstr "" -#~ msgid "Before the release" +#~ msgid "**sever_address**: String that identifies IP and port of the server." #~ msgstr "" #~ msgid "" -#~ "Update the changelog (``changelog.md``) with" -#~ " all relevant changes that happened " -#~ "after the last release. If the " -#~ "last release was tagged ``v1.2.0``, you" -#~ " can use the following URL to " -#~ "see all commits that got merged " -#~ "into ``main`` since then:" +#~ "**nb_clients**: This defines the number " +#~ "of clients being created. This piece " +#~ "of information is not required by " +#~ "the client, but it helps us " +#~ "partition the original MNIST dataset to" +#~ " make sure that every client is " +#~ "working on unique subsets of both " +#~ "*training* and *test* sets." #~ msgstr "" #~ msgid "" -#~ "`GitHub: Compare v1.2.0...main " -#~ "`_" +#~ "Again, we can go deeper and look" +#~ " inside :code:`flwr_example/quickstart-" +#~ "pytorch/client.py`. After going through the" +#~ " argument parsing code at the " +#~ "beginning of our :code:`main` function, " +#~ "you will find a call to " +#~ ":code:`mnist.load_data`. This function is " +#~ "responsible for partitioning the original " +#~ "MNIST datasets (*training* and *test*) " +#~ "and returning a :code:`torch.utils.data.DataLoader`" +#~ " s for each of them. We then" +#~ " instantiate a :code:`PytorchMNISTClient` object" +#~ " with our client ID, our DataLoaders," +#~ " the number of epochs in each " +#~ "round, and which device we want to" +#~ " use for training (CPU or GPU)." #~ msgstr "" #~ msgid "" -#~ "Thank the authors who contributed since" -#~ " the last release. This can be " -#~ "done by running the ``./dev/add-" -#~ "shortlog.sh`` convenience script (it can " -#~ "be ran multiple times and will " -#~ "update the names in the list if" -#~ " new contributors were added in the" -#~ " meantime)." +#~ "The :code:`PytorchMNISTClient` object when " +#~ "finally passed to :code:`fl.client.start_client` " +#~ "along with the server's address as " +#~ "the training process begins." #~ msgstr "" -#~ msgid "" -#~ "Update the ``changelog.md`` section header " -#~ "``Unreleased`` to contain the version " -#~ "number and date for the release " -#~ "you are building. Create a pull " -#~ "request with the change." +#~ msgid "A Closer Look" #~ msgstr "" #~ msgid "" -#~ "Tag the release commit with the " -#~ "version number as soon as the PR" -#~ " is merged: ``git tag v0.12.3``, then" -#~ " ``git push --tags``. This will " -#~ "create a draft release on GitHub " -#~ "containing the correct artifacts and the" -#~ " relevant part of the changelog." +#~ "Now, let's look closely into the " +#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" +#~ ".quickstart-pytorch.mnist` and see what it" +#~ " is doing:" #~ msgstr "" #~ msgid "" -#~ "Note that, in order to build the" -#~ " documentation locally (with ``poetry run" -#~ " make html``, like described below), " -#~ "`Pandoc _` needs " -#~ "to be installed on the system." +#~ "The first thing to notice is that" +#~ " :code:`PytorchMNISTClient` instantiates a CNN" +#~ " model inside its constructor" #~ msgstr "" #~ msgid "" -#~ "If you're familiar with how contributing" -#~ " on GitHub works, you can directly" -#~ " checkout our `getting started guide " -#~ "for contributors `_ and examples " -#~ "of `good first contributions " -#~ "`_." +#~ "The code for the CNN is available" +#~ " under :code:`quickstart-pytorch.mnist` and " +#~ "it is reproduced below. It is the" +#~ " same network found in `Basic MNIST" +#~ " Example " +#~ "`_." #~ msgstr "" #~ msgid "" -#~ "This will create a `flower/` (or " -#~ "the name of your fork if you " -#~ "renamed it) folder in the current " -#~ "working directory." +#~ "The second thing to notice is that" +#~ " :code:`PytorchMNISTClient` class inherits from" +#~ " the :code:`fl.client.Client`, and hence it" +#~ " must implement the following methods:" #~ msgstr "" -#~ msgid "Otherwise you can always find this option in the `Branches` page." +#~ msgid "" +#~ "When comparing the abstract class to " +#~ "its derived class :code:`PytorchMNISTClient` " +#~ "you will notice that :code:`fit` calls" +#~ " a :code:`train` function and that " +#~ ":code:`evaluate` calls a :code:`test`: " +#~ "function." #~ msgstr "" #~ msgid "" -#~ "Once you click the `Compare & pull" -#~ " request` button, you should see " -#~ "something similar to this:" +#~ "These functions can both be found " +#~ "inside the same :code:`quickstart-" +#~ "pytorch.mnist` module:" #~ msgstr "" -#~ msgid "Find the source file in `doc/source`" +#~ msgid "" +#~ "Observe that these functions encapsulate " +#~ "regular training and test loops and " +#~ "provide :code:`fit` and :code:`evaluate` with" +#~ " final statistics for each round. You" +#~ " could substitute them with your " +#~ "custom train and test loops and " +#~ "change the network architecture, and the" +#~ " entire example would still work " +#~ "flawlessly. As a matter of fact, " +#~ "why not try and modify the code" +#~ " to an example of your liking?" #~ msgstr "" -#~ msgid "" -#~ "Make the change in the `.rst` file" -#~ " (beware, the dashes under the title" -#~ " should be the same length as " -#~ "the title itself)" +#~ msgid "Give It a Try" #~ msgstr "" -#~ msgid "Change the file name to `save-progress.rst`" +#~ msgid "" +#~ "Looking through the quickstart code " +#~ "description above will have given a " +#~ "good understanding of how *clients* and" +#~ " *servers* work in Flower, how to " +#~ "run a simple experiment, and the " +#~ "internals of a client wrapper. Here " +#~ "are a few things you could try " +#~ "on your own and get more " +#~ "experience with Flower:" #~ msgstr "" -#~ msgid "Add a redirect rule to `doc/source/conf.py`" +#~ msgid "" +#~ "Try and change :code:`PytorchMNISTClient` so" +#~ " it can accept different architectures." #~ msgstr "" #~ msgid "" -#~ "This will cause a redirect from " -#~ "`saving-progress.html` to `save-progress.html`," -#~ " old links will continue to work." +#~ "Modify the :code:`train` function so " +#~ "that it accepts different optimizers" #~ msgstr "" #~ msgid "" -#~ "For the lateral navigation bar to " -#~ "work properly, it is very important " -#~ "to update the `index.rst` file as " -#~ "well. This is where we define the" -#~ " whole arborescence of the navbar." +#~ "Modify the :code:`test` function so that" +#~ " it proves not only the top-1 " +#~ "(regular accuracy) but also the top-5" +#~ " accuracy?" #~ msgstr "" -#~ msgid "Find and modify the file name in `index.rst`" +#~ msgid "" +#~ "Go larger! Try to adapt the code" +#~ " to larger images and datasets. Why" +#~ " not try training on ImageNet with" +#~ " a ResNet-50?" #~ msgstr "" -#~ msgid "Add CI job to deploy the staging system when the `main` branch changes" +#~ msgid "You are ready now. Enjoy learning in a federated way!" #~ msgstr "" -#~ msgid "`Python 3.7 `_ or above" +#~ msgid "Differential privacy" #~ msgstr "" #~ msgid "" -#~ "First, clone the `Flower repository " -#~ "`_ from GitHub::" +#~ "Flower provides differential privacy (DP) " +#~ "wrapper classes for the easy integration" +#~ " of the central DP guarantees " +#~ "provided by DP-FedAvg into training " +#~ "pipelines defined in any of the " +#~ "various ML frameworks that Flower is " +#~ "compatible with." #~ msgstr "" #~ msgid "" -#~ "Second, create a virtual environment " -#~ "(and activate it). If you chose to" -#~ " use :code:`pyenv` (with the :code" -#~ ":`pyenv-virtualenv` plugin) and already " -#~ "have it installed , you can use" -#~ " the following convenience script (by " -#~ "default it will use :code:`Python " -#~ "3.8.17`, but you can change it by" -#~ " providing a specific :code:``)::" +#~ "Please note that these components are" +#~ " still experimental; the correct " +#~ "configuration of DP for a specific " +#~ "task is still an unsolved problem." #~ msgstr "" #~ msgid "" -#~ "If you don't have :code:`pyenv` " -#~ "installed, you can use the following " -#~ "script that will install pyenv, set " -#~ "it up and create the virtual " -#~ "environment (with :code:`Python 3.8.17` by " -#~ "default)::" +#~ "The name DP-FedAvg is misleading " +#~ "since it can be applied on top " +#~ "of any FL algorithm that conforms " +#~ "to the general structure prescribed by" +#~ " the FedOpt family of algorithms." +#~ msgstr "" + +#~ msgid "DP-FedAvg" #~ msgstr "" #~ msgid "" -#~ "Third, install the Flower package in " -#~ "development mode (think :code:`pip install " -#~ "-e`) along with all necessary " -#~ "dependencies::" +#~ "DP-FedAvg, originally proposed by " +#~ "McMahan et al. [mcmahan]_ and extended" +#~ " by Andrew et al. [andrew]_, is " +#~ "essentially FedAvg with the following " +#~ "modifications." #~ msgstr "" #~ msgid "" -#~ "Developers could run the full set " -#~ "of Github Actions workflows under their" -#~ " local environment by using `Act " -#~ "_`. Please refer to" -#~ " the installation instructions under the" -#~ " linked repository and run the next" -#~ " command under Flower main cloned " -#~ "repository folder::" +#~ "**Clipping** : The influence of each " +#~ "client's update is bounded by clipping" +#~ " it. This is achieved by enforcing" +#~ " a cap on the L2 norm of " +#~ "the update, scaling it down if " +#~ "needed." #~ msgstr "" #~ msgid "" -#~ "Please note that these components are" -#~ " still experimental, the correct " -#~ "configuration of DP for a specific " -#~ "task is still an unsolved problem." +#~ "**Noising** : Gaussian noise, calibrated " +#~ "to the clipping threshold, is added " +#~ "to the average computed at the " +#~ "server." #~ msgstr "" #~ msgid "" #~ "The distribution of the update norm " #~ "has been shown to vary from " #~ "task-to-task and to evolve as " -#~ "training progresses. Therefore, we use " -#~ "an adaptive approach [andrew]_ that " -#~ "continuously adjusts the clipping threshold" -#~ " to track a prespecified quantile of" -#~ " the update norm distribution." +#~ "training progresses. This variability is " +#~ "crucial in understanding its impact on" +#~ " differential privacy guarantees, emphasizing " +#~ "the need for an adaptive approach " +#~ "[andrew]_ that continuously adjusts the " +#~ "clipping threshold to track a " +#~ "prespecified quantile of the update norm" +#~ " distribution." +#~ msgstr "" + +#~ msgid "Simplifying Assumptions" #~ msgstr "" #~ msgid "" #~ "We make (and attempt to enforce) a" #~ " number of assumptions that must be" #~ " satisfied to ensure that the " -#~ "training process actually realises the " +#~ "training process actually realizes the " #~ ":math:`(\\epsilon, \\delta)` guarantees the " #~ "user has in mind when configuring " #~ "the setup." #~ msgstr "" +#~ msgid "" +#~ "**Fixed-size subsampling** :Fixed-size " +#~ "subsamples of the clients must be " +#~ "taken at each round, as opposed to" +#~ " variable-sized Poisson subsamples." +#~ msgstr "" + +#~ msgid "" +#~ "**Unweighted averaging** : The contributions" +#~ " from all the clients must weighted" +#~ " equally in the aggregate to " +#~ "eliminate the requirement for the server" +#~ " to know in advance the sum of" +#~ " the weights of all clients available" +#~ " for selection." +#~ msgstr "" + +#~ msgid "" +#~ "**No client failures** : The set " +#~ "of available clients must stay constant" +#~ " across all rounds of training. In" +#~ " other words, clients cannot drop out" +#~ " or fail." +#~ msgstr "" + #~ msgid "" #~ "The first two are useful for " #~ "eliminating a multitude of complications " #~ "associated with calibrating the noise to" -#~ " the clipping threshold while the " +#~ " the clipping threshold, while the " #~ "third one is required to comply " #~ "with the assumptions of the privacy " #~ "analysis." #~ msgstr "" +#~ msgid "" +#~ "These restrictions are in line with " +#~ "constraints imposed by Andrew et al. " +#~ "[andrew]_." +#~ msgstr "" + +#~ msgid "Customizable Responsibility for Noise injection" +#~ msgstr "" + +#~ msgid "" +#~ "In contrast to other implementations " +#~ "where the addition of noise is " +#~ "performed at the server, you can " +#~ "configure the site of noise injection" +#~ " to better match your threat model." +#~ " We provide users with the " +#~ "flexibility to set up the training " +#~ "such that each client independently adds" +#~ " a small amount of noise to the" +#~ " clipped update, with the result that" +#~ " simply aggregating the noisy updates " +#~ "is equivalent to the explicit addition" +#~ " of noise to the non-noisy " +#~ "aggregate at the server." +#~ msgstr "" + +#~ msgid "" +#~ "To be precise, if we let :math:`m`" +#~ " be the number of clients sampled " +#~ "each round and :math:`\\sigma_\\Delta` be " +#~ "the scale of the total Gaussian " +#~ "noise that needs to be added to" +#~ " the sum of the model updates, " +#~ "we can use simple maths to show" +#~ " that this is equivalent to each " +#~ "client adding noise with scale " +#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ msgstr "" + +#~ msgid "Wrapper-based approach" +#~ msgstr "" + +#~ msgid "" +#~ "Introducing DP to an existing workload" +#~ " can be thought of as adding an" +#~ " extra layer of security around it." +#~ " This inspired us to provide the " +#~ "additional server and client-side logic" +#~ " needed to make the training process" +#~ " differentially private as wrappers for " +#~ "instances of the :code:`Strategy` and " +#~ ":code:`NumPyClient` abstract classes respectively." +#~ " This wrapper-based approach has the" +#~ " advantage of being easily composable " +#~ "with other wrappers that someone might" +#~ " contribute to the Flower library in" +#~ " the future, e.g., for secure " +#~ "aggregation. Using Inheritance instead can " +#~ "be tedious because that would require" +#~ " the creation of new sub- classes " +#~ "every time a new class implementing " +#~ ":code:`Strategy` or :code:`NumPyClient` is " +#~ "defined." +#~ msgstr "" + +#~ msgid "Server-side logic" +#~ msgstr "" + #~ msgid "" #~ "The first version of our solution " #~ "was to define a decorator whose " #~ "constructor accepted, among other things, " -#~ "a boolean valued variable indicating " +#~ "a boolean-valued variable indicating " #~ "whether adaptive clipping was to be " #~ "enabled or not. We quickly realized " #~ "that this would clutter its " @@ -19753,6 +22117,34 @@ msgstr "" #~ "noising is to be performed." #~ msgstr "" +#~ msgid "" +#~ "The server-side capabilities required " +#~ "for the original version of DP-" +#~ "FedAvg, i.e., the one which performed" +#~ " fixed clipping, can be completely " +#~ "captured with the help of wrapper " +#~ "logic for just the following two " +#~ "methods of the :code:`Strategy` abstract " +#~ "class." +#~ msgstr "" + +#~ msgid "" +#~ ":code:`configure_fit()` : The config " +#~ "dictionary being sent by the wrapped " +#~ ":code:`Strategy` to each client needs to" +#~ " be augmented with an additional " +#~ "value equal to the clipping threshold" +#~ " (keyed under :code:`dpfedavg_clip_norm`) and," +#~ " if :code:`server_side_noising=true`, another one" +#~ " equal to the scale of the " +#~ "Gaussian noise that needs to be " +#~ "added at the client (keyed under " +#~ ":code:`dpfedavg_noise_stddev`). This entails " +#~ "*post*-processing of the results returned " +#~ "by the wrappee's implementation of " +#~ ":code:`configure_fit()`." +#~ msgstr "" + #~ msgid "" #~ ":code:`aggregate_fit()`: We check whether any" #~ " of the sampled clients dropped out" @@ -19772,1682 +22164,1747 @@ msgstr "" #~ "if :code:`server_side_noising=true`, each update " #~ "is perturbed with an amount of " #~ "noise equal to what it would have" -#~ " been subjected to had client-side" -#~ " noising being enabled. This entails " -#~ "*pre*-processing of the arguments to " -#~ "this method before passing them on " -#~ "to the wrappee's implementation of " -#~ ":code:`aggregate_fit()`." -#~ msgstr "" - -#~ msgid "" -#~ "McMahan, H. Brendan, et al. \"Learning" -#~ " differentially private recurrent language " -#~ "models.\" arXiv preprint arXiv:1710.06963 " -#~ "(2017)." -#~ msgstr "" - -#~ msgid "" -#~ "Andrew, Galen, et al. \"Differentially " -#~ "private learning with adaptive clipping.\" " -#~ "Advances in Neural Information Processing " -#~ "Systems 34 (2021): 17455-17466." -#~ msgstr "" - -#~ msgid "" -#~ "The following command can be used " -#~ "to verfiy if Flower was successfully " -#~ "installed. If everything worked, it " -#~ "should print the version of Flower " -#~ "to the command line::" -#~ msgstr "" - -#~ msgid "flwr (Python API reference)" -#~ msgstr "" - -#~ msgid "start_client" -#~ msgstr "" - -#~ msgid "start_numpy_client" -#~ msgstr "" - -#~ msgid "start_simulation" -#~ msgstr "" - -#~ msgid "server.start_server" -#~ msgstr "" - -#~ msgid "server.strategy" -#~ msgstr "" - -#~ msgid "server.strategy.Strategy" -#~ msgstr "" - -#~ msgid "server.strategy.FedAvg" -#~ msgstr "" - -#~ msgid "server.strategy.FedAvgM" -#~ msgstr "" - -#~ msgid "server.strategy.FedMedian" -#~ msgstr "" - -#~ msgid "server.strategy.QFedAvg" -#~ msgstr "" - -#~ msgid "server.strategy.FaultTolerantFedAvg" +#~ " been subjected to had client-side" +#~ " noising being enabled. This entails " +#~ "*pre*-processing of the arguments to " +#~ "this method before passing them on " +#~ "to the wrappee's implementation of " +#~ ":code:`aggregate_fit()`." #~ msgstr "" -#~ msgid "server.strategy.FedOpt" +#~ msgid "" +#~ "We can't directly change the aggregation" +#~ " function of the wrapped strategy to" +#~ " force it to add noise to the" +#~ " aggregate, hence we simulate client-" +#~ "side noising to implement server-side" +#~ " noising." #~ msgstr "" -#~ msgid "server.strategy.FedProx" +#~ msgid "" +#~ "These changes have been put together " +#~ "into a class called :code:`DPFedAvgFixed`, " +#~ "whose constructor accepts the strategy " +#~ "being decorated, the clipping threshold " +#~ "and the number of clients sampled " +#~ "every round as compulsory arguments. The" +#~ " user is expected to specify the " +#~ "clipping threshold since the order of" +#~ " magnitude of the update norms is " +#~ "highly dependent on the model being " +#~ "trained and providing a default value" +#~ " would be misleading. The number of" +#~ " clients sampled at every round is" +#~ " required to calculate the amount of" +#~ " noise that must be added to " +#~ "each individual update, either by the" +#~ " server or the clients." #~ msgstr "" -#~ msgid "server.strategy.FedAdagrad" +#~ msgid "" +#~ "The additional functionality required to " +#~ "facilitate adaptive clipping has been " +#~ "provided in :code:`DPFedAvgAdaptive`, a " +#~ "subclass of :code:`DPFedAvgFixed`. It " +#~ "overrides the above-mentioned methods to" +#~ " do the following." #~ msgstr "" -#~ msgid "server.strategy.FedAdam" +#~ msgid "" +#~ ":code:`configure_fit()` : It intercepts the" +#~ " config dict returned by " +#~ ":code:`super.configure_fit()` to add the " +#~ "key-value pair " +#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " +#~ "which the client interprets as an " +#~ "instruction to include an indicator bit" +#~ " (1 if update norm <= clipping " +#~ "threshold, 0 otherwise) in the results" +#~ " returned by it." #~ msgstr "" -#~ msgid "server.strategy.FedYogi" +#~ msgid "" +#~ ":code:`aggregate_fit()` : It follows a " +#~ "call to :code:`super.aggregate_fit()` with one" +#~ " to :code:`__update_clip_norm__()`, a procedure" +#~ " which adjusts the clipping threshold " +#~ "on the basis of the indicator bits" +#~ " received from the sampled clients." #~ msgstr "" -#~ msgid "server.strategy.FedTrimmedAvg" +#~ msgid "Client-side logic" #~ msgstr "" -#~ msgid "server.strategy.Krum" +#~ msgid "" +#~ "The client-side capabilities required " +#~ "can be completely captured through " +#~ "wrapper logic for just the :code:`fit()`" +#~ " method of the :code:`NumPyClient` abstract" +#~ " class. To be precise, we need " +#~ "to *post-process* the update computed" +#~ " by the wrapped client to clip " +#~ "it, if necessary, to the threshold " +#~ "value supplied by the server as " +#~ "part of the config dictionary. In " +#~ "addition to this, it may need to" +#~ " perform some extra work if either" +#~ " (or both) of the following keys " +#~ "are also present in the dict." #~ msgstr "" -#~ msgid "server.strategy.FedXgbNnAvg" +#~ msgid "" +#~ ":code:`dpfedavg_noise_stddev` : Generate and " +#~ "add the specified amount of noise " +#~ "to the clipped update." #~ msgstr "" -#~ msgid "server.strategy.DPFedAvgAdaptive" +#~ msgid "" +#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" +#~ " metrics dict in the :code:`FitRes` " +#~ "object being returned to the server " +#~ "with an indicator bit, calculated as " +#~ "described earlier." #~ msgstr "" -#~ msgid "server.strategy.DPFedAvgFixed" +#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" #~ msgstr "" #~ msgid "" -#~ "**Fix the incorrect return types of " -#~ "Strategy** " -#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" +#~ "Assume you have trained for :math:`n`" +#~ " rounds with sampling fraction :math:`q`" +#~ " and noise multiplier :math:`z`. In " +#~ "order to calculate the :math:`\\epsilon` " +#~ "value this would result in for a" +#~ " particular :math:`\\delta`, the following " +#~ "script may be used." #~ msgstr "" #~ msgid "" -#~ "The types of the return values in" -#~ " the docstrings in two methods " -#~ "(`aggregate_fit` and `aggregate_evaluate`) now " -#~ "match the hint types in the code." +#~ "McMahan et al. \"Learning Differentially " +#~ "Private Recurrent Language Models.\" " +#~ "International Conference on Learning " +#~ "Representations (ICLR), 2017." #~ msgstr "" #~ msgid "" -#~ "Using the `client_fn`, Flower clients " -#~ "can interchangeably run as standalone " -#~ "processes (i.e. via `start_client`) or " -#~ "in simulation (i.e. via `start_simulation`)" -#~ " without requiring changes to how the" -#~ " client class is defined and " -#~ "instantiated. Calling `start_numpy_client` is " -#~ "now deprecated." +#~ "Andrew, Galen, et al. \"Differentially " +#~ "Private Learning with Adaptive Clipping.\" " +#~ "Advances in Neural Information Processing " +#~ "Systems (NeurIPS), 2021." #~ msgstr "" #~ msgid "" -#~ "**Update Flower Examples** " -#~ "([#2384](https://github.com/adap/flower/pull/2384)), " -#~ "([#2425](https://github.com/adap/flower/pull/2425))" +#~ "This can be achieved by customizing " +#~ "an existing strategy or by `implementing" +#~ " a custom strategy from scratch " +#~ "`_. Here's a nonsensical " +#~ "example that customizes :code:`FedAvg` by " +#~ "adding a custom ``\"hello\": \"world\"`` " +#~ "configuration key/value pair to the " +#~ "config dict of a *single client* " +#~ "(only the first client in the " +#~ "list, the other clients in this " +#~ "round to not receive this \"special\"" +#~ " config value):" #~ msgstr "" #~ msgid "" -#~ "**General updates to baselines** " -#~ "([#2301](https://github.com/adap/flower/pull/2301), " -#~ "[#2305](https://github.com/adap/flower/pull/2305), " -#~ "[#2307](https://github.com/adap/flower/pull/2307), " -#~ "[#2327](https://github.com/adap/flower/pull/2327), " -#~ "[#2435](https://github.com/adap/flower/pull/2435))" +#~ "More sophisticated implementations can use " +#~ ":code:`configure_fit` to implement custom " +#~ "client selection logic. A client will" +#~ " only participate in a round if " +#~ "the corresponding :code:`ClientProxy` is " +#~ "included in the the list returned " +#~ "from :code:`configure_fit`." #~ msgstr "" #~ msgid "" -#~ "**General updates to the simulation " -#~ "engine** ([#2331](https://github.com/adap/flower/pull/2331), " -#~ "[#2447](https://github.com/adap/flower/pull/2447), " -#~ "[#2448](https://github.com/adap/flower/pull/2448))" +#~ "More sophisticated implementations can use " +#~ ":code:`configure_evaluate` to implement custom " +#~ "client selection logic. A client will" +#~ " only participate in a round if " +#~ "the corresponding :code:`ClientProxy` is " +#~ "included in the the list returned " +#~ "from :code:`configure_evaluate`." #~ msgstr "" #~ msgid "" -#~ "**General improvements** " -#~ "([#2309](https://github.com/adap/flower/pull/2309), " -#~ "[#2310](https://github.com/adap/flower/pull/2310), " -#~ "[2313](https://github.com/adap/flower/pull/2313), " -#~ "[#2316](https://github.com/adap/flower/pull/2316), " -#~ "[2317](https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/flower/pull/2349)," -#~ " [#2360](https://github.com/adap/flower/pull/2360), " -#~ "[#2402](https://github.com/adap/flower/pull/2402), " -#~ "[#2446](https://github.com/adap/flower/pull/2446))" +#~ "`How to run Flower using Docker " +#~ "`_" #~ msgstr "" #~ msgid "" -#~ "`flower-superlink --driver-api-address " -#~ "\"0.0.0.0:8081\" --fleet-api-address " -#~ "\"0.0.0.0:8086\"`" +#~ "Ray Dashboard: ``_" #~ msgstr "" #~ msgid "" -#~ "That's it for the client. We only" -#~ " have to implement :code:`Client` or " -#~ ":code:`NumPyClient` and call " -#~ ":code:`fl.client.start_client()`. The string " -#~ ":code:`\"0.0.0.0:8080\"` tells the client " -#~ "which server to connect to. In our" -#~ " case we can run the server and" -#~ " the client on the same machine, " -#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" -#~ " we run a truly federated workload" -#~ " with the server and clients running" -#~ " on different machines, all that " -#~ "needs to change is the " -#~ ":code:`server_address` we pass to the " -#~ "client." +#~ "Ray Metrics: ``_" #~ msgstr "" -#~ msgid "" -#~ "That's it for the client. We only" -#~ " have to implement :code:`Client` or " -#~ ":code:`NumPyClient` and call " -#~ ":code:`fl.client.start_client()`. The string " -#~ ":code:`\"[::]:8080\"` tells the client which" -#~ " server to connect to. In our " -#~ "case we can run the server and " -#~ "the client on the same machine, " -#~ "therefore we use :code:`\"[::]:8080\"`. If " -#~ "we run a truly federated workload " -#~ "with the server and clients running " -#~ "on different machines, all that needs" -#~ " to change is the :code:`server_address`" -#~ " we point the client at." +#~ msgid "Enjoy building more robust and flexible ``ClientApp``s with mods!" #~ msgstr "" #~ msgid "" -#~ "Let's build a horizontal federated " -#~ "learning system using XGBoost and " -#~ "Flower!" +#~ ":py:obj:`ClientApp `\\ " +#~ "\\(client\\_fn\\[\\, mods\\]\\)" #~ msgstr "" -#~ msgid "" -#~ "Please refer to the `full code " -#~ "example `_ to learn " -#~ "more." +#~ msgid ":py:obj:`flwr.server.driver `\\" #~ msgstr "" -#~ msgid "" -#~ "In this notebook, we'll build a " -#~ "federated learning system using Flower " -#~ "and PyTorch. In part 1, we use " -#~ "PyTorch for the model training pipeline" -#~ " and data loading. In part 2, " -#~ "we continue to federate the PyTorch-" -#~ "based pipeline using Flower." +#~ msgid "Flower driver SDK." #~ msgstr "" -#~ msgid "" -#~ "Next, we install the necessary packages" -#~ " for PyTorch (``torch`` and " -#~ "``torchvision``) and Flower (``flwr``):" +#~ msgid "driver" #~ msgstr "" #~ msgid "" -#~ "Federated learning can be applied to " -#~ "many different types of tasks across " -#~ "different domains. In this tutorial, we" -#~ " introduce federated learning by training" -#~ " a simple convolutional neural network " -#~ "(CNN) on the popular CIFAR-10 dataset." -#~ " CIFAR-10 can be used to train " -#~ "image classifiers that distinguish between " -#~ "images from ten different classes:" +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" #~ msgstr "" #~ msgid "" -#~ "Each organization will act as a " -#~ "client in the federated learning system." -#~ " So having ten organizations participate" -#~ " in a federation means having ten " -#~ "clients connected to the federated " -#~ "learning server:" +#~ ":py:obj:`Driver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" #~ msgid "" -#~ "Let's now load the CIFAR-10 training " -#~ "and test set, partition them into " -#~ "ten smaller datasets (each split into" -#~ " training and validation set), and " -#~ "wrap the resulting partitions by " -#~ "creating a PyTorch ``DataLoader`` for " -#~ "each of them:" +#~ ":py:obj:`GrpcDriver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ msgid "|ed6498a023f2477a9ccd57ee4514bda4|" +#~ msgid "`GrpcDriver` provides access to the gRPC Driver API/service." #~ msgstr "" -#~ msgid "|5a4f742489ac4f819afefdd4dc9ab272|" +#~ msgid ":py:obj:`get_nodes `\\ \\(\\)" #~ msgstr "" -#~ msgid "|3331c80cd05045f6a56524d8e3e76d0c|" +#~ msgid "" +#~ ":py:obj:`pull_task_res " +#~ "`\\ \\(task\\_ids\\)" #~ msgstr "" -#~ msgid "|4987b26884ec4b2c8f06c1264bcebe60|" +#~ msgid "Get task results." #~ msgstr "" -#~ msgid "|ec8ae2d778aa493a986eb2fa29c220e5|" +#~ msgid "" +#~ ":py:obj:`push_task_ins " +#~ "`\\ " +#~ "\\(task\\_ins\\_list\\)" #~ msgstr "" -#~ msgid "|b8949d0669fe4f8eadc9a4932f4e9c57|" +#~ msgid "Schedule tasks." #~ msgstr "" -#~ msgid "|94ff30bdcd09443e8488b5f29932a541|" +#~ msgid "GrpcDriver" #~ msgstr "" -#~ msgid "|48dccf1d6d0544bba8917d2783a47719|" +#~ msgid ":py:obj:`connect `\\ \\(\\)" #~ msgstr "" -#~ msgid "|0366618db96b4f329f0d4372d1150fde|" +#~ msgid "Connect to the Driver API." #~ msgstr "" -#~ msgid "|ac80eddc76e6478081b1ca35eed029c0|" +#~ msgid "" +#~ ":py:obj:`create_run " +#~ "`\\ \\(req\\)" #~ msgstr "" -#~ msgid "|1ac94140c317450e89678db133c7f3c2|" +#~ msgid "Request for run ID." #~ msgstr "" -#~ msgid "|f8850c6e96fc4430b55e53bba237a7c0|" +#~ msgid "" +#~ ":py:obj:`disconnect " +#~ "`\\ \\(\\)" #~ msgstr "" -#~ msgid "|4a368fdd3fc34adabd20a46752a68582|" +#~ msgid "Disconnect from the Driver API." #~ msgstr "" -#~ msgid "|40f69c17bb444652a7c8dfe577cd120e|" +#~ msgid "" +#~ ":py:obj:`get_nodes `\\" +#~ " \\(req\\)" +#~ msgstr "" + +#~ msgid "Get client IDs." #~ msgstr "" #~ msgid "" -#~ "Please follow the first section on " -#~ "`Run Flower using Docker " -#~ "`_ which covers this" -#~ " step in more detail." +#~ ":py:obj:`pull_task_res " +#~ "`\\ \\(req\\)" #~ msgstr "" #~ msgid "" -#~ "Since `Flower 1.5 `_ we have " -#~ "introduced translations to our doc " -#~ "pages, but, as you might have " -#~ "noticed, the translations are often " -#~ "imperfect. If you speak languages other" -#~ " than English, you might be able " -#~ "to help us in our effort to " -#~ "make Federated Learning accessible to as" -#~ " many people as possible by " -#~ "contributing to those translations! This " -#~ "might also be a great opportunity " -#~ "for those wanting to become open " -#~ "source contributors with little prerequistes." +#~ ":py:obj:`push_task_ins " +#~ "`\\ \\(req\\)" #~ msgstr "" #~ msgid "" -#~ "You input your translation in the " -#~ "textbox at the top and then, once" -#~ " you are happy with it, you " -#~ "either press ``Save and continue`` (to" -#~ " save the translation and go to " -#~ "the next untranslated string), ``Save " -#~ "and stay`` (to save the translation " -#~ "and stay on the same page), " -#~ "``Suggest`` (to add your translation to" -#~ " suggestions for other users to " -#~ "view), or ``Skip`` (to go to the" -#~ " next untranslated string without saving" -#~ " anything)." +#~ "Optionally specify the type of actor " +#~ "to use. The actor object, which " +#~ "persists throughout the simulation, will " +#~ "be the process in charge of " +#~ "running the clients' jobs (i.e. their" +#~ " `fit()` method)." #~ msgstr "" #~ msgid "" -#~ "The first thing we need to do " -#~ "is to define a message type for" -#~ " the RPC system in :code:`transport.proto`." -#~ " Note that we have to do it " -#~ "for both the request and response " -#~ "messages. For more details on the " -#~ "syntax of proto3, please see the " -#~ "`official documentation `_." +#~ "Much effort went into a completely " +#~ "restructured Flower docs experience. The " +#~ "documentation on [flower.ai/docs](flower.ai/docs) is" +#~ " now divided into Flower Framework, " +#~ "Flower Baselines, Flower Android SDK, " +#~ "Flower iOS SDK, and code example " +#~ "projects." #~ msgstr "" #~ msgid "" -#~ "Source: `Official VSCode documentation " -#~ "`_" +#~ "The first preview release of Flower " +#~ "Baselines has arrived! We're kickstarting " +#~ "Flower Baselines with implementations of " +#~ "FedOpt (FedYogi, FedAdam, FedAdagrad), FedBN," +#~ " and FedAvgM. Check the documentation " +#~ "on how to use [Flower " +#~ "Baselines](https://flower.ai/docs/using-baselines.html). " +#~ "With this first preview release we're" +#~ " also inviting the community to " +#~ "[contribute their own " +#~ "baselines](https://flower.ai/docs/contributing-baselines.html)." #~ msgstr "" #~ msgid "" -#~ "`Developing inside a Container " -#~ "`_" +#~ "Flower usage examples used to be " +#~ "bundled with Flower in a package " +#~ "called ``flwr_example``. We are migrating " +#~ "those examples to standalone projects to" +#~ " make them easier to use. All " +#~ "new examples are based in the " +#~ "directory `examples " +#~ "`_." +#~ msgstr "" + +#~ msgid "The following examples are available as standalone projects." +#~ msgstr "" + +#~ msgid "Quickstart TensorFlow/Keras" #~ msgstr "" #~ msgid "" -#~ "`Remote development in Containers " -#~ "`_" +#~ "`Quickstart TensorFlow (Tutorial) " +#~ "`_" #~ msgstr "" #~ msgid "" -#~ "If you are not familiar with " -#~ "Flower Baselines, you should probably " -#~ "check-out our `contributing guide for " -#~ "baselines `_." +#~ "`Quickstart PyTorch (Tutorial) " +#~ "`_" #~ msgstr "" #~ msgid "" -#~ "You should then check out the open" -#~ " `issues " -#~ "`_" -#~ " for baseline requests. If you find" -#~ " a baseline that you'd like to " -#~ "work on and that has no assignes," -#~ " feel free to assign it to " -#~ "yourself and start working on it!" +#~ "`PyTorch: From Centralized To Federated " +#~ "(Tutorial) `_" +#~ msgstr "" + +#~ msgid "Legacy Examples (`flwr_example`)" #~ msgstr "" #~ msgid "" -#~ "If you're familiar with how contributing" -#~ " on GitHub works, you can directly" -#~ " checkout our `getting started guide " -#~ "for contributors `_." +#~ "The useage examples in `flwr_example` " +#~ "are deprecated and will be removed " +#~ "in the future. New examples are " +#~ "provided as standalone projects in " +#~ "`examples `_." +#~ msgstr "" + +#~ msgid "Extra Dependencies" #~ msgstr "" #~ msgid "" -#~ "Git is a distributed version control " -#~ "tool. This allows for an entire " -#~ "codebase's history to be stored and " -#~ "every developer's machine. It is a " -#~ "software that will need to be " -#~ "installed on your local machine, you " -#~ "can follow this `guide " -#~ "`_ to set it up." +#~ "The core Flower framework keeps a " +#~ "minimal set of dependencies. The " +#~ "examples demonstrate Flower in the " +#~ "context of different machine learning " +#~ "frameworks, so additional dependencies need" +#~ " to be installed before an example" +#~ " can be run." +#~ msgstr "" + +#~ msgid "For PyTorch examples::" +#~ msgstr "" + +#~ msgid "For TensorFlow examples::" +#~ msgstr "" + +#~ msgid "For both PyTorch and TensorFlow examples::" #~ msgstr "" #~ msgid "" -#~ "A fork is a personal copy of " -#~ "a GitHub repository. To create one " -#~ "for Flower, you must navigate to " -#~ "https://github.com/adap/flower (while connected to" -#~ " your GitHub account) and click the" -#~ " ``Fork`` button situated on the top" -#~ " right of the page." +#~ "Please consult :code:`pyproject.toml` for a" +#~ " full list of possible extras " +#~ "(section :code:`[tool.poetry.extras]`)." +#~ msgstr "" + +#~ msgid "PyTorch Examples" #~ msgstr "" #~ msgid "" -#~ "Now we will add an upstream " -#~ "address to our repository. Still in " -#~ "the same directroy, we must run " -#~ "the following command:" +#~ "Our PyTorch examples are based on " +#~ "PyTorch 1.7. They should work with " +#~ "other releases as well. So far, we" +#~ " provide the following examples." +#~ msgstr "" + +#~ msgid "CIFAR-10 Image Classification" #~ msgstr "" #~ msgid "" -#~ "This can be achieved by following " -#~ "this `getting started guide for " -#~ "contributors`_ (note that you won't need" -#~ " to clone the repository). Once you" -#~ " are able to write code and " -#~ "test it, you can finally start " -#~ "making changes!" +#~ "`CIFAR-10 and CIFAR-100 " +#~ "`_ are " +#~ "popular RGB image datasets. The Flower" +#~ " CIFAR-10 example uses PyTorch to " +#~ "train a simple CNN classifier in a" +#~ " federated learning setup with two " +#~ "clients." +#~ msgstr "" + +#~ msgid "First, start a Flower server:" +#~ msgstr "" + +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" +#~ msgstr "" + +#~ msgid "Then, start the two clients in a new terminal window:" +#~ msgstr "" + +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" #~ msgstr "" -#~ msgid "" -#~ "For our documentation, we’ve started to" -#~ " use the `Diàtaxis framework " -#~ "`_." +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." #~ msgstr "" -#~ msgid "" -#~ "Our “How to” guides should have " -#~ "titles that continue the sencence “How" -#~ " to …”, for example, “How to " -#~ "upgrade to Flower 1.0”." +#~ msgid "ImageNet-2012 Image Classification" #~ msgstr "" #~ msgid "" -#~ "This issue is about changing the " -#~ "title of a doc from present " -#~ "continious to present simple." +#~ "`ImageNet-2012 `_ is " +#~ "one of the major computer vision " +#~ "datasets. The Flower ImageNet example " +#~ "uses PyTorch to train a ResNet-18 " +#~ "classifier in a federated learning setup" +#~ " with ten clients." #~ msgstr "" -#~ msgid "" -#~ "Let's take the example of “Saving " -#~ "Progress” which we changed to “Save " -#~ "Progress”. Does this pass our check?" +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" #~ msgstr "" -#~ msgid "Before: ”How to saving progress” ❌" +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" #~ msgstr "" -#~ msgid "After: ”How to save progress” ✅" +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." #~ msgstr "" -#~ msgid "" -#~ "This is a tiny change, but it’ll" -#~ " allow us to test your end-" -#~ "to-end setup. After cloning and " -#~ "setting up the Flower repo, here’s " -#~ "what you should do:" +#~ msgid "TensorFlow Examples" #~ msgstr "" #~ msgid "" -#~ "Build the docs and check the " -#~ "result: ``_" +#~ "Our TensorFlow examples are based on " +#~ "TensorFlow 2.0 or newer. So far, " +#~ "we provide the following examples." #~ msgstr "" -#~ msgid "Here’s how to change the file name:" +#~ msgid "Fashion-MNIST Image Classification" #~ msgstr "" #~ msgid "" -#~ "Commit the changes (commit messages are" -#~ " always imperative: “Do something”, in " -#~ "this case “Change …”)" +#~ "`Fashion-MNIST `_ is often used as " +#~ "the \"Hello, world!\" of machine " +#~ "learning. We follow this tradition and" +#~ " provide an example which samples " +#~ "random local datasets from Fashion-MNIST" +#~ " and trains a simple image " +#~ "classification model over those partitions." #~ msgstr "" -#~ msgid "" -#~ "`Good first contributions " -#~ "`_, where you should" -#~ " particularly look into the " -#~ ":code:`baselines` contributions." +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgstr "" + +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" #~ msgstr "" #~ msgid "" -#~ "If the section is completely empty " -#~ "(without any token) or non-existant, " -#~ "the changelog will just contain the " -#~ "title of the PR for the changelog" -#~ " entry, without any description." +#~ "For more details, see " +#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." +#~ msgstr "" + +#~ msgid ":fa:`eye,mr-1` Can Flower run on Juptyter Notebooks / Google Colab?" #~ msgstr "" #~ msgid "" -#~ "Flower uses :code:`pyproject.toml` to manage" -#~ " dependencies and configure development " -#~ "tools (the ones which support it). " -#~ "Poetry is a build tool which " -#~ "supports `PEP 517 " -#~ "`_." +#~ "`Flower meets KOSMoS `_." #~ msgstr "" #~ msgid "" -#~ "This tutorial will show you how to" -#~ " use Flower to build a federated " -#~ "version of an existing machine learning" -#~ " workload with `FedBN `_, a federated training strategy" -#~ " designed for non-iid data. We " -#~ "are using PyTorch to train a " -#~ "Convolutional Neural Network(with Batch " -#~ "Normalization layers) on the CIFAR-10 " -#~ "dataset. When applying FedBN, only few" -#~ " changes needed compared to `Example: " -#~ "PyTorch - From Centralized To Federated" -#~ " `_." +#~ "If you want to check out " +#~ "everything put together, you should " +#~ "check out the full code example: " +#~ "[https://github.com/adap/flower/tree/main/examples/quickstart-" +#~ "huggingface](https://github.com/adap/flower/tree/main/examples" +#~ "/quickstart-huggingface)." #~ msgstr "" #~ msgid "" -#~ "All files are revised based on " -#~ "`Example: PyTorch - From Centralized To" -#~ " Federated `_. The " -#~ "only thing to do is modifying the" -#~ " file called :code:`cifar.py`, revised part" -#~ " is shown below:" +#~ "First of all, for running the " +#~ "Flower Python server, it is recommended" +#~ " to create a virtual environment and" +#~ " run everything within a `virtualenv " +#~ "`_. " +#~ "For the Flower client implementation in" +#~ " iOS, it is recommended to use " +#~ "Xcode as our IDE." #~ msgstr "" #~ msgid "" -#~ "So far this should all look fairly" -#~ " familiar if you've used PyTorch " -#~ "before. Let's take the next step " -#~ "and use what we've built to create" -#~ " a federated learning system within " -#~ "FedBN, the sytstem consists of one " -#~ "server and two clients." +#~ "Since CoreML does not allow the " +#~ "model parameters to be seen before " +#~ "training, and accessing the model " +#~ "parameters during or after the training" +#~ " can only be done by specifying " +#~ "the layer name, we need to know" +#~ " this informations beforehand, through " +#~ "looking at the model specification, " +#~ "which are written as proto files. " +#~ "The implementation can be seen in " +#~ ":code:`MLModelInspect`." #~ msgstr "" #~ msgid "" -#~ "If you have read `Example: PyTorch " -#~ "- From Centralized To Federated " -#~ "`_, the following" -#~ " parts are easy to follow, onyl " -#~ ":code:`get_parameters` and :code:`set_parameters` " -#~ "function in :code:`client.py` needed to " -#~ "revise. If not, please read the " -#~ "`Example: PyTorch - From Centralized To" -#~ " Federated `_. first." +#~ "After we have all of the necessary" +#~ " informations, let's create our Flower " +#~ "client." #~ msgstr "" -#~ msgid "Example: Walk-Through PyTorch & MNIST" +#~ msgid "" +#~ "MXNet is no longer maintained and " +#~ "has been moved into `Attic " +#~ "`_. As a " +#~ "result, we would encourage you to " +#~ "use other ML frameworks alongise Flower," +#~ " for example, PyTorch. This tutorial " +#~ "might be removed in future versions " +#~ "of Flower." #~ msgstr "" #~ msgid "" -#~ "In this tutorial we will learn, " -#~ "how to train a Convolutional Neural " -#~ "Network on MNIST using Flower and " -#~ "PyTorch." +#~ "It is recommended to create a " +#~ "virtual environment and run everything " +#~ "within this `virtualenv `_." #~ msgstr "" #~ msgid "" -#~ "Since we want to use PyTorch to" -#~ " solve a computer vision task, let's" -#~ " go ahead an install PyTorch and " -#~ "the **torchvision** library:" +#~ "First of all, it is recommended to" +#~ " create a virtual environment and run" +#~ " everything within a `virtualenv " +#~ "`_." #~ msgstr "" -#~ msgid "Ready... Set... Train!" +#~ msgid "Since we want to use scikt-learn, let's go ahead and install it:" #~ msgstr "" #~ msgid "" -#~ "Now that we have all our " -#~ "dependencies installed, let's run a " -#~ "simple distributed training with two " -#~ "clients and one server. Our training " -#~ "procedure and network architecture are " -#~ "based on PyTorch's `Basic MNIST Example" -#~ " `_. " -#~ "This will allow you see how easy" -#~ " it is to wrap your code with" -#~ " Flower and begin training in a " -#~ "federated way. We provide you with " -#~ "two helper scripts, namely *run-" -#~ "server.sh*, and *run-clients.sh*. Don't " -#~ "be afraid to look inside, they are" -#~ " simple enough =)." +#~ "We load the MNIST dataset from " +#~ "`OpenML `_, a popular" +#~ " image classification dataset of " +#~ "handwritten digits for machine learning. " +#~ "The utility :code:`utils.load_mnist()` downloads " +#~ "the training and test data. The " +#~ "training set is split afterwards into" +#~ " 10 partitions with :code:`utils.partition()`." #~ msgstr "" #~ msgid "" -#~ "Go ahead and launch on a terminal" -#~ " the *run-server.sh* script first as" -#~ " follows:" +#~ "Now that you have known how " +#~ "federated XGBoost work with Flower, it's" +#~ " time to run some more comprehensive" +#~ " experiments by customising the " +#~ "experimental settings. In the xgboost-" +#~ "comprehensive example (`full code " +#~ "`_), we provide more options " +#~ "to define various experimental setups, " +#~ "including aggregation strategies, data " +#~ "partitioning and centralised/distributed evaluation." +#~ " We also support `Flower simulation " +#~ "`_ making it easy to " +#~ "simulate large client cohorts in a " +#~ "resource-aware manner. Let's take a " +#~ "look!" #~ msgstr "" -#~ msgid "Now that the server is up and running, go ahead and launch the clients." +#~ msgid "|31e4b1afa87c4b968327bbeafbf184d4|" #~ msgstr "" -#~ msgid "" -#~ "Et voilà! You should be seeing the" -#~ " training procedure and, after a few" -#~ " iterations, the test accuracy for " -#~ "each client." +#~ msgid "|c9d935b4284e4c389a33d86b33e07c0a|" #~ msgstr "" -#~ msgid "Now, let's see what is really happening inside." +#~ msgid "|00727b5faffb468f84dd1b03ded88638|" #~ msgstr "" -#~ msgid "" -#~ "Inside the server helper script *run-" -#~ "server.sh* you will find the following" -#~ " code that basically runs the " -#~ ":code:`server.py`" +#~ msgid "|daf0cf0ff4c24fd29439af78416cf47b|" #~ msgstr "" -#~ msgid "" -#~ "We can go a bit deeper and " -#~ "see that :code:`server.py` simply launches " -#~ "a server that will coordinate three " -#~ "rounds of training. Flower Servers are" -#~ " very customizable, but for simple " -#~ "workloads, we can start a server " -#~ "using the :ref:`start_server ` function and leave " -#~ "all the configuration possibilities at " -#~ "their default values, as seen below." +#~ msgid "|9f093007080d471d94ca90d3e9fde9b6|" #~ msgstr "" - -#~ msgid "" -#~ "Next, let's take a look at the " -#~ "*run-clients.sh* file. You will see " -#~ "that it contains the main loop " -#~ "that starts a set of *clients*." + +#~ msgid "|46a26e6150e0479fbd3dfd655f36eb13|" #~ msgstr "" -#~ msgid "" -#~ "**cid**: is the client ID. It is" -#~ " an integer that uniquely identifies " -#~ "client identifier." +#~ msgid "|3daba297595c4c7fb845d90404a6179a|" #~ msgstr "" -#~ msgid "**sever_address**: String that identifies IP and port of the server." +#~ msgid "|5769874fa9c4455b80b2efda850d39d7|" #~ msgstr "" -#~ msgid "" -#~ "**nb_clients**: This defines the number " -#~ "of clients being created. This piece " -#~ "of information is not required by " -#~ "the client, but it helps us " -#~ "partition the original MNIST dataset to" -#~ " make sure that every client is " -#~ "working on unique subsets of both " -#~ "*training* and *test* sets." +#~ msgid "|ba47ffb421814b0f8f9fa5719093d839|" #~ msgstr "" -#~ msgid "" -#~ "Again, we can go deeper and look" -#~ " inside :code:`flwr_example/quickstart-" -#~ "pytorch/client.py`. After going through the" -#~ " argument parsing code at the " -#~ "beginning of our :code:`main` function, " -#~ "you will find a call to " -#~ ":code:`mnist.load_data`. This function is " -#~ "responsible for partitioning the original " -#~ "MNIST datasets (*training* and *test*) " -#~ "and returning a :code:`torch.utils.data.DataLoader`" -#~ " s for each of them. We then" -#~ " instantiate a :code:`PytorchMNISTClient` object" -#~ " with our client ID, our DataLoaders," -#~ " the number of epochs in each " -#~ "round, and which device we want to" -#~ " use for training (CPU or GPU)." +#~ msgid "|aeac5bf79cbf497082e979834717e01b|" #~ msgstr "" -#~ msgid "" -#~ "The :code:`PytorchMNISTClient` object when " -#~ "finally passed to :code:`fl.client.start_client` " -#~ "along with the server's address as " -#~ "the training process begins." +#~ msgid "|ce27ed4bbe95459dba016afc42486ba2|" #~ msgstr "" -#~ msgid "A Closer Look" +#~ msgid "|ae94a7f71dda443cbec2385751427d41|" #~ msgstr "" -#~ msgid "" -#~ "Now, let's look closely into the " -#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" -#~ ".quickstart-pytorch.mnist` and see what it" -#~ " is doing:" +#~ msgid "|e61fce4d43d243e7bb08bdde97d81ce6|" #~ msgstr "" -#~ msgid "" -#~ "The first thing to notice is that" -#~ " :code:`PytorchMNISTClient` instantiates a CNN" -#~ " model inside its constructor" +#~ msgid "|08cb60859b07461588fe44e55810b050|" #~ msgstr "" +#~ msgid "``BASE_IMAGE_TAG``" +#~ msgstr "``BASE_IMAGE_TAG``" + +#~ msgid "The image tag of the base image." +#~ msgstr "A tag da imagem da imagem base." + #~ msgid "" -#~ "The code for the CNN is available" -#~ " under :code:`quickstart-pytorch.mnist` and " -#~ "it is reproduced below. It is the" -#~ " same network found in `Basic MNIST" -#~ " Example " -#~ "`_." +#~ "Open the notebook ``doc/source/tutorial-" +#~ "get-started-with-flower-pytorch.ipynb``:" #~ msgstr "" #~ msgid "" -#~ "The second thing to notice is that" -#~ " :code:`PytorchMNISTClient` class inherits from" -#~ " the :code:`fl.client.Client`, and hence it" -#~ " must implement the following methods:" +#~ "https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +#~ "/tutorial-get-started-with-flower-" +#~ "pytorch.ipynb" #~ msgstr "" #~ msgid "" -#~ "When comparing the abstract class to " -#~ "its derived class :code:`PytorchMNISTClient` " -#~ "you will notice that :code:`fit` calls" -#~ " a :code:`train` function and that " -#~ ":code:`evaluate` calls a :code:`test`: " -#~ "function." +#~ "https://colab.research.google.com/github/adap/flower/blob/branch-" +#~ "name/doc/source/tutorial-get-started-with-" +#~ "flower-pytorch.ipynb" #~ msgstr "" -#~ msgid "" -#~ "These functions can both be found " -#~ "inside the same :code:`quickstart-" -#~ "pytorch.mnist` module:" +#~ msgid "Virutualenv with Pyenv/Virtualenv" #~ msgstr "" #~ msgid "" -#~ "Observe that these functions encapsulate " -#~ "regular training and test loops and " -#~ "provide :code:`fit` and :code:`evaluate` with" -#~ " final statistics for each round. You" -#~ " could substitute them with your " -#~ "custom train and test loops and " -#~ "change the network architecture, and the" -#~ " entire example would still work " -#~ "flawlessly. As a matter of fact, " -#~ "why not try and modify the code" -#~ " to an example of your liking?" +#~ "It is important to follow the " +#~ "instructions described in comments. For " +#~ "instance, in order to not break " +#~ "how our changelog system works, you " +#~ "should read the information above the" +#~ " ``Changelog entry`` section carefully. You" +#~ " can also checkout some examples and" +#~ " details in the :ref:`changelogentry` " +#~ "appendix." #~ msgstr "" -#~ msgid "Give It a Try" +#~ msgid "Open a PR (as shown above)" #~ msgstr "" -#~ msgid "" -#~ "Looking through the quickstart code " -#~ "description above will have given a " -#~ "good understanding of how *clients* and" -#~ " *servers* work in Flower, how to " -#~ "run a simple experiment, and the " -#~ "internals of a client wrapper. Here " -#~ "are a few things you could try " -#~ "on your own and get more " -#~ "experience with Flower:" +#~ msgid "How to write a good PR title" #~ msgstr "" #~ msgid "" -#~ "Try and change :code:`PytorchMNISTClient` so" -#~ " it can accept different architectures." +#~ "A well-crafted PR title helps team" +#~ " members quickly understand the purpose " +#~ "and scope of the changes being " +#~ "proposed. Here's a guide to help " +#~ "you write a good GitHub PR title:" #~ msgstr "" #~ msgid "" -#~ "Modify the :code:`train` function so " -#~ "that it accepts different optimizers" +#~ "1. Be Clear and Concise: Provide a" +#~ " clear summary of the changes in " +#~ "a concise manner. 1. Use Actionable " +#~ "Verbs: Start with verbs like \"Add,\"" +#~ " \"Update,\" or \"Fix\" to indicate " +#~ "the purpose. 1. Include Relevant " +#~ "Information: Mention the affected feature " +#~ "or module for context. 1. Keep it" +#~ " Short: Avoid lengthy titles for easy" +#~ " readability. 1. Use Proper Capitalization" +#~ " and Punctuation: Follow grammar rules " +#~ "for clarity." #~ msgstr "" #~ msgid "" -#~ "Modify the :code:`test` function so that" -#~ " it proves not only the top-1 " -#~ "(regular accuracy) but also the top-5" -#~ " accuracy?" +#~ "Let's start with a few examples " +#~ "for titles that should be avoided " +#~ "because they do not provide meaningful" +#~ " information:" #~ msgstr "" -#~ msgid "" -#~ "Go larger! Try to adapt the code" -#~ " to larger images and datasets. Why" -#~ " not try training on ImageNet with" -#~ " a ResNet-50?" +#~ msgid "Implement Algorithm" #~ msgstr "" -#~ msgid "You are ready now. Enjoy learning in a federated way!" +#~ msgid "Database" #~ msgstr "" -#~ msgid "Differential privacy" +#~ msgid "Add my_new_file.py to codebase" #~ msgstr "" -#~ msgid "" -#~ "Flower provides differential privacy (DP) " -#~ "wrapper classes for the easy integration" -#~ " of the central DP guarantees " -#~ "provided by DP-FedAvg into training " -#~ "pipelines defined in any of the " -#~ "various ML frameworks that Flower is " -#~ "compatible with." +#~ msgid "Improve code in module" #~ msgstr "" -#~ msgid "" -#~ "Please note that these components are" -#~ " still experimental; the correct " -#~ "configuration of DP for a specific " -#~ "task is still an unsolved problem." +#~ msgid "Change SomeModule" #~ msgstr "" #~ msgid "" -#~ "The name DP-FedAvg is misleading " -#~ "since it can be applied on top " -#~ "of any FL algorithm that conforms " -#~ "to the general structure prescribed by" -#~ " the FedOpt family of algorithms." +#~ "Here are a few positive examples " +#~ "which provide helpful information without " +#~ "repeating how they do it, as that" +#~ " is already visible in the \"Files" +#~ " changed\" section of the PR:" #~ msgstr "" -#~ msgid "DP-FedAvg" +#~ msgid "Update docs banner to mention Flower Summit 2023" #~ msgstr "" -#~ msgid "" -#~ "DP-FedAvg, originally proposed by " -#~ "McMahan et al. [mcmahan]_ and extended" -#~ " by Andrew et al. [andrew]_, is " -#~ "essentially FedAvg with the following " -#~ "modifications." +#~ msgid "Remove unnecessary XGBoost dependency" #~ msgstr "" -#~ msgid "" -#~ "**Clipping** : The influence of each " -#~ "client's update is bounded by clipping" -#~ " it. This is achieved by enforcing" -#~ " a cap on the L2 norm of " -#~ "the update, scaling it down if " -#~ "needed." +#~ msgid "Remove redundant attributes in strategies subclassing FedAvg" #~ msgstr "" #~ msgid "" -#~ "**Noising** : Gaussian noise, calibrated " -#~ "to the clipping threshold, is added " -#~ "to the average computed at the " -#~ "server." +#~ "Add CI job to deploy the staging" +#~ " system when the ``main`` branch " +#~ "changes" #~ msgstr "" #~ msgid "" -#~ "The distribution of the update norm " -#~ "has been shown to vary from " -#~ "task-to-task and to evolve as " -#~ "training progresses. This variability is " -#~ "crucial in understanding its impact on" -#~ " differential privacy guarantees, emphasizing " -#~ "the need for an adaptive approach " -#~ "[andrew]_ that continuously adjusts the " -#~ "clipping threshold to track a " -#~ "prespecified quantile of the update norm" -#~ " distribution." +#~ "Add new amazing library which will " +#~ "be used to improve the simulation " +#~ "engine" #~ msgstr "" -#~ msgid "Simplifying Assumptions" +#~ msgid "Changelog entry" #~ msgstr "" #~ msgid "" -#~ "We make (and attempt to enforce) a" -#~ " number of assumptions that must be" -#~ " satisfied to ensure that the " -#~ "training process actually realizes the " -#~ ":math:`(\\epsilon, \\delta)` guarantees the " -#~ "user has in mind when configuring " -#~ "the setup." +#~ "When opening a new PR, inside its" +#~ " description, there should be a " +#~ "``Changelog entry`` header." #~ msgstr "" #~ msgid "" -#~ "**Fixed-size subsampling** :Fixed-size " -#~ "subsamples of the clients must be " -#~ "taken at each round, as opposed to" -#~ " variable-sized Poisson subsamples." +#~ "Above this header you should see " +#~ "the following comment that explains how" +#~ " to write your changelog entry:" #~ msgstr "" #~ msgid "" -#~ "**Unweighted averaging** : The contributions" -#~ " from all the clients must weighted" -#~ " equally in the aggregate to " -#~ "eliminate the requirement for the server" -#~ " to know in advance the sum of" -#~ " the weights of all clients available" -#~ " for selection." +#~ "Inside the following 'Changelog entry' " +#~ "section, you should put the description" +#~ " of your changes that will be " +#~ "added to the changelog alongside your" +#~ " PR title." #~ msgstr "" #~ msgid "" -#~ "**No client failures** : The set " -#~ "of available clients must stay constant" -#~ " across all rounds of training. In" -#~ " other words, clients cannot drop out" -#~ " or fail." +#~ "If the section is completely empty " +#~ "(without any token) or non-existent, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." #~ msgstr "" #~ msgid "" -#~ "The first two are useful for " -#~ "eliminating a multitude of complications " -#~ "associated with calibrating the noise to" -#~ " the clipping threshold, while the " -#~ "third one is required to comply " -#~ "with the assumptions of the privacy " -#~ "analysis." +#~ "If the section contains some text " +#~ "other than tokens, it will use it" +#~ " to add a description to the " +#~ "change." #~ msgstr "" #~ msgid "" -#~ "These restrictions are in line with " -#~ "constraints imposed by Andrew et al. " -#~ "[andrew]_." +#~ "If the section contains one of the" +#~ " following tokens it will ignore any" +#~ " other text and put the PR " +#~ "under the corresponding section of the" +#~ " changelog:" #~ msgstr "" -#~ msgid "Customizable Responsibility for Noise injection" +#~ msgid " is for classifying a PR as a general improvement." #~ msgstr "" -#~ msgid "" -#~ "In contrast to other implementations " -#~ "where the addition of noise is " -#~ "performed at the server, you can " -#~ "configure the site of noise injection" -#~ " to better match your threat model." -#~ " We provide users with the " -#~ "flexibility to set up the training " -#~ "such that each client independently adds" -#~ " a small amount of noise to the" -#~ " clipped update, with the result that" -#~ " simply aggregating the noisy updates " -#~ "is equivalent to the explicit addition" -#~ " of noise to the non-noisy " -#~ "aggregate at the server." +#~ msgid " is to not add the PR to the changelog" #~ msgstr "" -#~ msgid "" -#~ "To be precise, if we let :math:`m`" -#~ " be the number of clients sampled " -#~ "each round and :math:`\\sigma_\\Delta` be " -#~ "the scale of the total Gaussian " -#~ "noise that needs to be added to" -#~ " the sum of the model updates, " -#~ "we can use simple maths to show" -#~ " that this is equivalent to each " -#~ "client adding noise with scale " -#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ msgid " is to add a general baselines change to the PR" #~ msgstr "" -#~ msgid "Wrapper-based approach" +#~ msgid " is to add a general examples change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general sdk change to the PR" +#~ msgstr "" + +#~ msgid " is to add a general simulations change to the PR" +#~ msgstr "" + +#~ msgid "Note that only one token should be used." #~ msgstr "" #~ msgid "" -#~ "Introducing DP to an existing workload" -#~ " can be thought of as adding an" -#~ " extra layer of security around it." -#~ " This inspired us to provide the " -#~ "additional server and client-side logic" -#~ " needed to make the training process" -#~ " differentially private as wrappers for " -#~ "instances of the :code:`Strategy` and " -#~ ":code:`NumPyClient` abstract classes respectively." -#~ " This wrapper-based approach has the" -#~ " advantage of being easily composable " -#~ "with other wrappers that someone might" -#~ " contribute to the Flower library in" -#~ " the future, e.g., for secure " -#~ "aggregation. Using Inheritance instead can " -#~ "be tedious because that would require" -#~ " the creation of new sub- classes " -#~ "every time a new class implementing " -#~ ":code:`Strategy` or :code:`NumPyClient` is " -#~ "defined." +#~ "Its content must have a specific " +#~ "format. We will break down what " +#~ "each possibility does:" +#~ msgstr "" + +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains nothing or doesn't exist, " +#~ "the following text will be added " +#~ "to the changelog::" #~ msgstr "" -#~ msgid "Server-side logic" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains a description (and no " +#~ "token), the following text will be " +#~ "added to the changelog::" #~ msgstr "" #~ msgid "" -#~ "The first version of our solution " -#~ "was to define a decorator whose " -#~ "constructor accepted, among other things, " -#~ "a boolean-valued variable indicating " -#~ "whether adaptive clipping was to be " -#~ "enabled or not. We quickly realized " -#~ "that this would clutter its " -#~ ":code:`__init__()` function with variables " -#~ "corresponding to hyperparameters of adaptive" -#~ " clipping that would remain unused " -#~ "when it was disabled. A cleaner " -#~ "implementation could be achieved by " -#~ "splitting the functionality into two " -#~ "decorators, :code:`DPFedAvgFixed` and " -#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" -#~ " classing the former. The constructors " -#~ "for both classes accept a boolean " -#~ "parameter :code:`server_side_noising`, which, as " -#~ "the name suggests, determines where " -#~ "noising is to be performed." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, nothing will change" +#~ " in the changelog." #~ msgstr "" #~ msgid "" -#~ "The server-side capabilities required " -#~ "for the original version of DP-" -#~ "FedAvg, i.e., the one which performed" -#~ " fixed clipping, can be completely " -#~ "captured with the help of wrapper " -#~ "logic for just the following two " -#~ "methods of the :code:`Strategy` abstract " -#~ "class." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text" +#~ " will be added to the changelog::" #~ msgstr "" #~ msgid "" -#~ ":code:`configure_fit()` : The config " -#~ "dictionary being sent by the wrapped " -#~ ":code:`Strategy` to each client needs to" -#~ " be augmented with an additional " -#~ "value equal to the clipping threshold" -#~ " (keyed under :code:`dpfedavg_clip_norm`) and," -#~ " if :code:`server_side_noising=true`, another one" -#~ " equal to the scale of the " -#~ "Gaussian noise that needs to be " -#~ "added at the client (keyed under " -#~ ":code:`dpfedavg_noise_stddev`). This entails " -#~ "*post*-processing of the results returned " -#~ "by the wrappee's implementation of " -#~ ":code:`configure_fit()`." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" #~ msgstr "" #~ msgid "" -#~ ":code:`aggregate_fit()`: We check whether any" -#~ " of the sampled clients dropped out" -#~ " or failed to upload an update " -#~ "before the round timed out. In " -#~ "that case, we need to abort the" -#~ " current round, discarding any successful" -#~ " updates that were received, and move" -#~ " on to the next one. On the " -#~ "other hand, if all clients responded " -#~ "successfully, we must force the " -#~ "averaging of the updates to happen " -#~ "in an unweighted manner by intercepting" -#~ " the :code:`parameters` field of " -#~ ":code:`FitRes` for each received update " -#~ "and setting it to 1. Furthermore, " -#~ "if :code:`server_side_noising=true`, each update " -#~ "is perturbed with an amount of " -#~ "noise equal to what it would have" -#~ " been subjected to had client-side" -#~ " noising being enabled. This entails " -#~ "*pre*-processing of the arguments to " -#~ "this method before passing them on " -#~ "to the wrappee's implementation of " -#~ ":code:`aggregate_fit()`." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" #~ msgstr "" #~ msgid "" -#~ "We can't directly change the aggregation" -#~ " function of the wrapped strategy to" -#~ " force it to add noise to the" -#~ " aggregate, hence we simulate client-" -#~ "side noising to implement server-side" -#~ " noising." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text " +#~ "will be added to the changelog::" #~ msgstr "" #~ msgid "" -#~ "These changes have been put together " -#~ "into a class called :code:`DPFedAvgFixed`, " -#~ "whose constructor accepts the strategy " -#~ "being decorated, the clipping threshold " -#~ "and the number of clients sampled " -#~ "every round as compulsory arguments. The" -#~ " user is expected to specify the " -#~ "clipping threshold since the order of" -#~ " magnitude of the update norms is " -#~ "highly dependent on the model being " -#~ "trained and providing a default value" -#~ " would be misleading. The number of" -#~ " clients sampled at every round is" -#~ " required to calculate the amount of" -#~ " noise that must be added to " -#~ "each individual update, either by the" -#~ " server or the clients." +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" #~ msgstr "" #~ msgid "" -#~ "The additional functionality required to " -#~ "facilitate adaptive clipping has been " -#~ "provided in :code:`DPFedAvgAdaptive`, a " -#~ "subclass of :code:`DPFedAvgFixed`. It " -#~ "overrides the above-mentioned methods to" -#~ " do the following." +#~ "Note that only one token must be" +#~ " provided, otherwise, only the first " +#~ "action (in the order listed above), " +#~ "will be performed." +#~ msgstr "" + +#~ msgid "Example: MXNet - Run MXNet Federated" #~ msgstr "" #~ msgid "" -#~ ":code:`configure_fit()` : It intercepts the" -#~ " config dict returned by " -#~ ":code:`super.configure_fit()` to add the " -#~ "key-value pair " -#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " -#~ "which the client interprets as an " -#~ "instruction to include an indicator bit" -#~ " (1 if update norm <= clipping " -#~ "threshold, 0 otherwise) in the results" -#~ " returned by it." +#~ "This tutorial will show you how to" +#~ " use Flower to build a federated " +#~ "version of an existing MXNet workload." +#~ " We are using MXNet to train a" +#~ " Sequential model on the MNIST " +#~ "dataset. We will structure the example" +#~ " similar to our `PyTorch - From " +#~ "Centralized To Federated " +#~ "`_ walkthrough. " +#~ "MXNet and PyTorch are very similar " +#~ "and a very good comparison between " +#~ "MXNet and PyTorch is given `here " +#~ "`_. First, " +#~ "we build a centralized training approach" +#~ " based on the `Handwritten Digit " +#~ "Recognition " +#~ "`_" +#~ " tutorial. Then, we build upon the" +#~ " centralized training code to run the" +#~ " training in a federated fashion." #~ msgstr "" #~ msgid "" -#~ ":code:`aggregate_fit()` : It follows a " -#~ "call to :code:`super.aggregate_fit()` with one" -#~ " to :code:`__update_clip_norm__()`, a procedure" -#~ " which adjusts the clipping threshold " -#~ "on the basis of the indicator bits" -#~ " received from the sampled clients." +#~ "Before we start setting up our " +#~ "MXNet example, we install the " +#~ ":code:`mxnet` and :code:`flwr` packages:" #~ msgstr "" -#~ msgid "Client-side logic" +#~ msgid "MNIST Training with MXNet" #~ msgstr "" #~ msgid "" -#~ "The client-side capabilities required " -#~ "can be completely captured through " -#~ "wrapper logic for just the :code:`fit()`" -#~ " method of the :code:`NumPyClient` abstract" -#~ " class. To be precise, we need " -#~ "to *post-process* the update computed" -#~ " by the wrapped client to clip " -#~ "it, if necessary, to the threshold " -#~ "value supplied by the server as " -#~ "part of the config dictionary. In " -#~ "addition to this, it may need to" -#~ " perform some extra work if either" -#~ " (or both) of the following keys " -#~ "are also present in the dict." +#~ "We begin with a brief description " +#~ "of the centralized training code based" +#~ " on a :code:`Sequential` model. If " +#~ "you want a more in-depth " +#~ "explanation of what's going on then " +#~ "have a look at the official `MXNet" +#~ " tutorial " +#~ "`_." #~ msgstr "" #~ msgid "" -#~ ":code:`dpfedavg_noise_stddev` : Generate and " -#~ "add the specified amount of noise " -#~ "to the clipped update." +#~ "Let's create a new file " +#~ "called:code:`mxnet_mnist.py` with all the " +#~ "components required for a traditional " +#~ "(centralized) MNIST training. First, the " +#~ "MXNet package :code:`mxnet` needs to be" +#~ " imported. You can see that we " +#~ "do not yet import the :code:`flwr` " +#~ "package for federated learning. This " +#~ "will be done later." #~ msgstr "" #~ msgid "" -#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" -#~ " metrics dict in the :code:`FitRes` " -#~ "object being returned to the server " -#~ "with an indicator bit, calculated as " -#~ "described earlier." +#~ "The :code:`load_data()` function loads the " +#~ "MNIST training and test sets." #~ msgstr "" -#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" +#~ msgid "" +#~ "As already mentioned, we will use " +#~ "the MNIST dataset for this machine " +#~ "learning workload. The model architecture " +#~ "(a very simple :code:`Sequential` model) " +#~ "is defined in :code:`model()`." #~ msgstr "" #~ msgid "" -#~ "Assume you have trained for :math:`n`" -#~ " rounds with sampling fraction :math:`q`" -#~ " and noise multiplier :math:`z`. In " -#~ "order to calculate the :math:`\\epsilon` " -#~ "value this would result in for a" -#~ " particular :math:`\\delta`, the following " -#~ "script may be used." +#~ "We now need to define the training" +#~ " (function :code:`train()`) which loops " +#~ "over the training set and measures " +#~ "the loss for each batch of " +#~ "training examples." #~ msgstr "" #~ msgid "" -#~ "McMahan et al. \"Learning Differentially " -#~ "Private Recurrent Language Models.\" " -#~ "International Conference on Learning " -#~ "Representations (ICLR), 2017." +#~ "The evaluation of the model is " +#~ "defined in function :code:`test()`. The " +#~ "function loops over all test samples " +#~ "and measures the loss and accuracy " +#~ "of the model based on the test " +#~ "dataset." #~ msgstr "" #~ msgid "" -#~ "Andrew, Galen, et al. \"Differentially " -#~ "Private Learning with Adaptive Clipping.\" " -#~ "Advances in Neural Information Processing " -#~ "Systems (NeurIPS), 2021." +#~ "Having defined the data loading, model" +#~ " architecture, training, and evaluation we" +#~ " can put everything together and " +#~ "train our model on MNIST. Note " +#~ "that the GPU/CPU device for the " +#~ "training and testing is defined within" +#~ " the :code:`ctx` (context)." +#~ msgstr "" + +#~ msgid "You can now run your (centralized) MXNet machine learning workload:" #~ msgstr "" #~ msgid "" -#~ "This can be achieved by customizing " -#~ "an existing strategy or by `implementing" -#~ " a custom strategy from scratch " -#~ "`_. Here's a nonsensical " -#~ "example that customizes :code:`FedAvg` by " -#~ "adding a custom ``\"hello\": \"world\"`` " -#~ "configuration key/value pair to the " -#~ "config dict of a *single client* " -#~ "(only the first client in the " -#~ "list, the other clients in this " -#~ "round to not receive this \"special\"" -#~ " config value):" +#~ "So far this should all look fairly" +#~ " familiar if you've used MXNet (or" +#~ " even PyTorch) before. Let's take the" +#~ " next step and use what we've " +#~ "built to create a simple federated " +#~ "learning system consisting of one server" +#~ " and two clients." +#~ msgstr "" + +#~ msgid "MXNet meets Flower" #~ msgstr "" #~ msgid "" -#~ "More sophisticated implementations can use " -#~ ":code:`configure_fit` to implement custom " -#~ "client selection logic. A client will" -#~ " only participate in a round if " -#~ "the corresponding :code:`ClientProxy` is " -#~ "included in the the list returned " -#~ "from :code:`configure_fit`." +#~ "So far, it was not easily possible" +#~ " to use MXNet workloads for federated" +#~ " learning because federated learning is " +#~ "not supported in MXNet. Since Flower " +#~ "is fully agnostic towards the underlying" +#~ " machine learning framework, it can " +#~ "be used to federated arbitrary machine" +#~ " learning workloads. This section will " +#~ "show you how Flower can be used" +#~ " to federate our centralized MXNet " +#~ "workload." #~ msgstr "" #~ msgid "" -#~ "More sophisticated implementations can use " -#~ ":code:`configure_evaluate` to implement custom " -#~ "client selection logic. A client will" -#~ " only participate in a round if " -#~ "the corresponding :code:`ClientProxy` is " -#~ "included in the the list returned " -#~ "from :code:`configure_evaluate`." +#~ "The concept to federate an existing " +#~ "workload is always the same and " +#~ "easy to understand. We have to " +#~ "start a *server* and then use the" +#~ " code in :code:`mxnet_mnist.py` for the " +#~ "*clients* that are connected to the " +#~ "*server*. The *server* sends model " +#~ "parameters to the clients. The *clients*" +#~ " run the training and update the " +#~ "parameters. The updated parameters are " +#~ "sent back to the *server* which " +#~ "averages all received parameter updates. " +#~ "This describes one round of the " +#~ "federated learning process and we repeat" +#~ " this for multiple rounds." #~ msgstr "" #~ msgid "" -#~ "`How to run Flower using Docker " -#~ "`_" +#~ "Finally, we will define our *client* " +#~ "logic in :code:`client.py` and build " +#~ "upon the previously defined MXNet " +#~ "training in :code:`mxnet_mnist.py`. Our " +#~ "*client* needs to import :code:`flwr`, " +#~ "but also :code:`mxnet` to update the " +#~ "parameters on our MXNet model:" #~ msgstr "" #~ msgid "" -#~ "Ray Dashboard: ``_" +#~ "Implementing a Flower *client* basically " +#~ "means implementing a subclass of either" +#~ " :code:`flwr.client.Client` or " +#~ ":code:`flwr.client.NumPyClient`. Our implementation " +#~ "will be based on " +#~ ":code:`flwr.client.NumPyClient` and we'll call " +#~ "it :code:`MNISTClient`. :code:`NumPyClient` is " +#~ "slightly easier to implement than " +#~ ":code:`Client` if you use a framework" +#~ " with good NumPy interoperability (like " +#~ "PyTorch or MXNet) because it avoids " +#~ "some of the boilerplate that would " +#~ "otherwise be necessary. :code:`MNISTClient` " +#~ "needs to implement four methods, two " +#~ "methods for getting/setting model parameters," +#~ " one method for training the model," +#~ " and one method for testing the " +#~ "model:" +#~ msgstr "" + +#~ msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" #~ msgstr "" #~ msgid "" -#~ "Ray Metrics: ``_" +#~ "The challenging part is to transform " +#~ "the MXNet parameters from :code:`NDArray` " +#~ "to :code:`NumPy Arrays` to make it " +#~ "readable for Flower." #~ msgstr "" -#~ msgid "Enjoy building more robust and flexible ``ClientApp``s with mods!" +#~ msgid "" +#~ "The two :code:`NumPyClient` methods " +#~ ":code:`fit` and :code:`evaluate` make use " +#~ "of the functions :code:`train()` and " +#~ ":code:`test()` previously defined in " +#~ ":code:`mxnet_mnist.py`. So what we really " +#~ "do here is we tell Flower through" +#~ " our :code:`NumPyClient` subclass which of" +#~ " our already defined functions to " +#~ "call for training and evaluation. We " +#~ "included type annotations to give you" +#~ " a better understanding of the data" +#~ " types that get passed around." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`ClientApp `\\ " -#~ "\\(client\\_fn\\[\\, mods\\]\\)" +#~ "Having defined data loading, model " +#~ "architecture, training, and evaluation we " +#~ "can put everything together and train" +#~ " our :code:`Sequential` model on MNIST." #~ msgstr "" -#~ msgid ":py:obj:`flwr.server.driver `\\" +#~ msgid "" +#~ "in each window (make sure that the" +#~ " server is still running before you" +#~ " do so) and see your MXNet " +#~ "project run federated learning across " +#~ "two clients. Congratulations!" #~ msgstr "" -#~ msgid "Flower driver SDK." +#~ msgid "" +#~ "The full source code for this " +#~ "example: `MXNet: From Centralized To " +#~ "Federated (Code) " +#~ "`_. Our " +#~ "example is of course somewhat over-" +#~ "simplified because both clients load the" +#~ " exact same dataset, which isn't " +#~ "realistic. You're now prepared to " +#~ "explore this topic further. How about" +#~ " using a CNN or using a " +#~ "different dataset? How about adding more" +#~ " clients?" #~ msgstr "" -#~ msgid "driver" +#~ msgid "" +#~ "This guide describes how to a " +#~ "SSL-enabled secure Flower server can " +#~ "be started and how a Flower client" +#~ " can establish a secure connections " +#~ "to it." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`start_driver `\\ " -#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" +#~ "The code example comes with a " +#~ "README.md file which will explain how" +#~ " to start it. Although it is " +#~ "already SSL-enabled, it might be " +#~ "less descriptive on how. Stick to " +#~ "this guide for a deeper introduction " +#~ "to the topic." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`Driver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" +#~ "Using SSL-enabled connections requires " +#~ "certificates to be passed to the " +#~ "server and client. For the purpose " +#~ "of this guide we are going to " +#~ "generate self-signed certificates. As " +#~ "this can become quite complex we " +#~ "are going to ask you to run " +#~ "the script in :code:`examples/advanced-" +#~ "tensorflow/certificates/generate.sh`" +#~ msgstr "" + +#~ msgid "with the following command sequence:" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`GrpcDriver `\\ " -#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" +#~ "The approach how the SSL certificates" +#~ " are generated in this example can" +#~ " serve as an inspiration and starting" +#~ " point but should not be taken " +#~ "as complete for production environments. " +#~ "Please refer to other sources regarding" +#~ " the issue of correctly generating " +#~ "certificates for production environments." #~ msgstr "" -#~ msgid "`GrpcDriver` provides access to the gRPC Driver API/service." +#~ msgid "" +#~ "In case you are a researcher you" +#~ " might be just fine using the " +#~ "self-signed certificates generated using " +#~ "the scripts which are part of this" +#~ " guide." #~ msgstr "" -#~ msgid ":py:obj:`get_nodes `\\ \\(\\)" +#~ msgid "" +#~ "We are now going to show how " +#~ "to write a sever which uses the" +#~ " previously generated scripts." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(task\\_ids\\)" +#~ "When providing certificates, the server " +#~ "expects a tuple of three certificates." +#~ " :code:`Path` can be used to easily" +#~ " read the contents of those files " +#~ "into byte strings, which is the " +#~ "data type :code:`start_server` expects." #~ msgstr "" -#~ msgid "Get task results." +#~ msgid "" +#~ "We are now going to show how " +#~ "to write a client which uses the" +#~ " previously generated scripts:" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ " -#~ "\\(task\\_ins\\_list\\)" +#~ "When setting :code:`root_certificates`, the " +#~ "client expects the PEM-encoded root " +#~ "certificates as a byte string. We " +#~ "are again using :code:`Path` to simplify" +#~ " reading those as byte strings." #~ msgstr "" -#~ msgid "Schedule tasks." +#~ msgid "" +#~ "You should now have learned how to" +#~ " generate self-signed certificates using" +#~ " the given script, start a SSL-" +#~ "enabled server, and have a client " +#~ "establish a secure connection to it." #~ msgstr "" -#~ msgid "GrpcDriver" +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`_." #~ msgstr "" -#~ msgid ":py:obj:`connect `\\ \\(\\)" +#~ msgid "Flower server" #~ msgstr "" -#~ msgid "Connect to the Driver API." +#~ msgid "" +#~ "The command will pull the Docker " +#~ "image with the tag " +#~ "``1.7.0-py3.11-ubuntu22.04`` from Docker Hub. " +#~ "The tag contains the information which" +#~ " Flower, Python and Ubuntu is used." +#~ " In this case, it uses Flower " +#~ "1.7.0, Python 3.11 and Ubuntu 22.04. " +#~ "The ``--rm`` flag tells Docker to " +#~ "remove the container after it exits." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`create_run " -#~ "`\\ \\(req\\)" +#~ "By default, the Flower server keeps " +#~ "state in-memory. When using the " +#~ "Docker flag ``--rm``, the state is " +#~ "not persisted between container starts. " +#~ "We will show below how to save " +#~ "the state in a file on your " +#~ "host system." #~ msgstr "" -#~ msgid "Request for run ID." +#~ msgid "" +#~ "The ``-p :`` flag tells " +#~ "Docker to map the ports " +#~ "``9091``/``9092`` of the host to " +#~ "``9091``/``9092`` of the container, allowing" +#~ " you to access the Driver API " +#~ "on ``http://localhost:9091`` and the Fleet " +#~ "API on ``http://localhost:9092``. Lastly, any" +#~ " flag that comes after the tag " +#~ "is passed to the Flower server. " +#~ "Here, we are passing the flag " +#~ "``--insecure``." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`disconnect " -#~ "`\\ \\(\\)" +#~ "The ``--insecure`` flag enables insecure " +#~ "communication (using HTTP, not HTTPS) " +#~ "and should only be used for " +#~ "testing purposes. We strongly recommend " +#~ "enabling `SSL `_ when " +#~ "deploying to a production environment." #~ msgstr "" -#~ msgid "Disconnect from the Driver API." +#~ msgid "" +#~ "You can use ``--help`` to view all" +#~ " available flags that the server " +#~ "supports:" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`get_nodes `\\" -#~ " \\(req\\)" +#~ "If you want to persist the state" +#~ " of the server on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``-v`` to" +#~ " mount the user's home directory " +#~ "(``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." #~ msgstr "" -#~ msgid "Get client IDs." +#~ msgid "" +#~ "As soon as the server starts, the" +#~ " file ``state.db`` is created in the" +#~ " user's home directory on your host" +#~ " system. If the file already exists," +#~ " the server tries to restore the " +#~ "state from the file. To start the" +#~ " server with an empty database, " +#~ "simply remove the ``state.db`` file." +#~ msgstr "" + +#~ msgid "" +#~ "To enable SSL, you will need a " +#~ "CA certificate, a server certificate and" +#~ " a server private key." +#~ msgstr "" + +#~ msgid "" +#~ "For testing purposes, you can generate" +#~ " your own self-signed certificates. " +#~ "The `Enable SSL connections " +#~ "`_ page contains " +#~ "a section that will guide you " +#~ "through the process." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``-v`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the server to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the server with the " +#~ "``--certificates`` flag." +#~ msgstr "" + +#~ msgid "Using a different Flower or Python version" #~ msgstr "" #~ msgid "" -#~ ":py:obj:`pull_task_res " -#~ "`\\ \\(req\\)" +#~ "If you want to use a different " +#~ "version of Flower or Python, you " +#~ "can do so by changing the tag. " +#~ "All versions we provide are available" +#~ " on `Docker Hub " +#~ "`_." #~ msgstr "" #~ msgid "" -#~ ":py:obj:`push_task_ins " -#~ "`\\ \\(req\\)" +#~ "The following command returns the " +#~ "current image hash referenced by the " +#~ "``server:1.7.0-py3.11-ubuntu22.04`` tag:" #~ msgstr "" -#~ msgid "" -#~ "Optionally specify the type of actor " -#~ "to use. The actor object, which " -#~ "persists throughout the simulation, will " -#~ "be the process in charge of " -#~ "running the clients' jobs (i.e. their" -#~ " `fit()` method)." +#~ msgid "Next, we can pin the hash when running a new server container:" #~ msgstr "" #~ msgid "" -#~ "Much effort went into a completely " -#~ "restructured Flower docs experience. The " -#~ "documentation on [flower.ai/docs](flower.ai/docs) is" -#~ " now divided into Flower Framework, " -#~ "Flower Baselines, Flower Android SDK, " -#~ "Flower iOS SDK, and code example " -#~ "projects." +#~ "QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:`TensorFlow " +#~ "` | :doc:`🤗 " +#~ "Transformers ` " +#~ "| :doc:`JAX ` |" +#~ " :doc:`Pandas ` " +#~ "| :doc:`fastai `" +#~ " | :doc:`PyTorch Lightning ` | :doc:`MXNet " +#~ "` | :doc" +#~ ":`scikit-learn `" +#~ " | :doc:`XGBoost ` | :doc:`Android ` | :doc:`iOS `" #~ msgstr "" -#~ msgid "" -#~ "The first preview release of Flower " -#~ "Baselines has arrived! We're kickstarting " -#~ "Flower Baselines with implementations of " -#~ "FedOpt (FedYogi, FedAdam, FedAdagrad), FedBN," -#~ " and FedAvgM. Check the documentation " -#~ "on how to use [Flower " -#~ "Baselines](https://flower.ai/docs/using-baselines.html). " -#~ "With this first preview release we're" -#~ " also inviting the community to " -#~ "[contribute their own " -#~ "baselines](https://flower.ai/docs/contributing-baselines.html)." +#~ msgid "flower-driver-api" #~ msgstr "" -#~ msgid "" -#~ "Flower usage examples used to be " -#~ "bundled with Flower in a package " -#~ "called ``flwr_example``. We are migrating " -#~ "those examples to standalone projects to" -#~ " make them easier to use. All " -#~ "new examples are based in the " -#~ "directory `examples " -#~ "`_." +#~ msgid "flower-fleet-api" #~ msgstr "" -#~ msgid "The following examples are available as standalone projects." +#~ msgid "" +#~ "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +#~ "[:py:class:`str`, :py:obj:`~typing.Union`\\ " +#~ "[:py:class:`int`, :py:class:`float`, :py:class:`str`, " +#~ ":py:class:`bytes`, :py:class:`bool`, " +#~ ":py:class:`~typing.List`\\ [:py:class:`int`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`float`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`str`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`bytes`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`bool`]]]" #~ msgstr "" -#~ msgid "Quickstart TensorFlow/Keras" +#~ msgid "" +#~ ":py:obj:`create_error_reply " +#~ "`\\ \\(error\\, " +#~ "ttl\\)" #~ msgstr "" #~ msgid "" -#~ "`Quickstart TensorFlow (Tutorial) " -#~ "`_" +#~ ":py:obj:`create_reply `\\ " +#~ "\\(content\\, ttl\\)" #~ msgstr "" #~ msgid "" -#~ "`Quickstart PyTorch (Tutorial) " -#~ "`_" +#~ "Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +#~ "[:py:class:`str`, :py:obj:`~typing.Union`\\ " +#~ "[:py:class:`int`, :py:class:`float`, " +#~ ":py:class:`~typing.List`\\ [:py:class:`int`], " +#~ ":py:class:`~typing.List`\\ [:py:class:`float`]]]" +#~ msgstr "" + +#~ msgid "Run Flower server (Driver API and Fleet API)." #~ msgstr "" #~ msgid "" -#~ "`PyTorch: From Centralized To Federated " -#~ "(Tutorial) `_" +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" #~ msgstr "" -#~ msgid "Legacy Examples (`flwr_example`)" +#~ msgid "Start a Flower Driver API server." #~ msgstr "" #~ msgid "" -#~ "The useage examples in `flwr_example` " -#~ "are deprecated and will be removed " -#~ "in the future. New examples are " -#~ "provided as standalone projects in " -#~ "`examples `_." +#~ ":py:obj:`Driver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ msgid "Extra Dependencies" +#~ msgid "`Driver` class provides an interface to the Driver API." #~ msgstr "" #~ msgid "" -#~ "The core Flower framework keeps a " -#~ "minimal set of dependencies. The " -#~ "examples demonstrate Flower in the " -#~ "context of different machine learning " -#~ "frameworks, so additional dependencies need" -#~ " to be installed before an example" -#~ " can be run." +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:9091\"`." #~ msgstr "" -#~ msgid "For PyTorch examples::" +#~ msgid ":py:obj:`close `\\ \\(\\)" #~ msgstr "" -#~ msgid "For TensorFlow examples::" +#~ msgid "Disconnect from the SuperLink if connected." #~ msgstr "" -#~ msgid "For both PyTorch and TensorFlow examples::" +#~ msgid "" +#~ ":py:obj:`create_message `\\" +#~ " \\(content\\, message\\_type\\, ...\\)" #~ msgstr "" #~ msgid "" -#~ "Please consult :code:`pyproject.toml` for a" -#~ " full list of possible extras " -#~ "(section :code:`[tool.poetry.extras]`)." +#~ "Time-to-live for the round trip" +#~ " of this message, i.e., the time " +#~ "from sending this message to receiving" +#~ " a reply. It specifies the duration" +#~ " for which the message and its " +#~ "potential reply are considered valid." #~ msgstr "" -#~ msgid "PyTorch Examples" +#~ msgid "start\\_driver" #~ msgstr "" #~ msgid "" -#~ "Our PyTorch examples are based on " -#~ "PyTorch 1.7. They should work with " -#~ "other releases as well. So far, we" -#~ " provide the following examples." +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:8080\"`." #~ msgstr "" -#~ msgid "CIFAR-10 Image Classification" +#~ msgid "" +#~ "A server implementation, either " +#~ "`flwr.server.Server` or a subclass thereof." +#~ " If no instance is provided, then " +#~ "`start_driver` will create one." #~ msgstr "" #~ msgid "" -#~ "`CIFAR-10 and CIFAR-100 " -#~ "`_ are " -#~ "popular RGB image datasets. The Flower" -#~ " CIFAR-10 example uses PyTorch to " -#~ "train a simple CNN classifier in a" -#~ " federated learning setup with two " -#~ "clients." +#~ "An implementation of the class " +#~ "`flwr.server.ClientManager`. If no implementation" +#~ " is provided, then `start_driver` will " +#~ "use `flwr.server.SimpleClientManager`." #~ msgstr "" -#~ msgid "First, start a Flower server:" +#~ msgid "The Driver object to use." #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" +#~ msgid "Starting a driver that connects to an insecure server:" #~ msgstr "" -#~ msgid "Then, start the two clients in a new terminal window:" +#~ msgid "Starting a driver that connects to an SSL-enabled server:" #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" +#~ msgid "" +#~ ":py:obj:`run_simulation_from_cli " +#~ "`\\ \\(\\)" #~ msgstr "" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." +#~ msgid "Run Simulation Engine from the CLI." #~ msgstr "" -#~ msgid "ImageNet-2012 Image Classification" +#~ msgid "run\\_simulation\\_from\\_cli" #~ msgstr "" #~ msgid "" -#~ "`ImageNet-2012 `_ is " -#~ "one of the major computer vision " -#~ "datasets. The Flower ImageNet example " -#~ "uses PyTorch to train a ResNet-18 " -#~ "classifier in a federated learning setup" -#~ " with ten clients." +#~ "Check out this Federated Learning " +#~ "quickstart tutorial for using Flower " +#~ "with MXNet to train a Sequential " +#~ "model on MNIST." #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" +#~ msgid "Quickstart MXNet" #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" +#~ msgid "" +#~ "MXNet is no longer maintained and " +#~ "has been moved into `Attic " +#~ "`_. As a " +#~ "result, we would encourage you to " +#~ "use other ML frameworks alongside " +#~ "Flower, for example, PyTorch. This " +#~ "tutorial might be removed in future " +#~ "versions of Flower." #~ msgstr "" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." +#~ msgid "" +#~ "In this tutorial, we will learn " +#~ "how to train a :code:`Sequential` model" +#~ " on MNIST using Flower and MXNet." #~ msgstr "" -#~ msgid "TensorFlow Examples" +#~ msgid "Since we want to use MXNet, let's go ahead and install it:" #~ msgstr "" #~ msgid "" -#~ "Our TensorFlow examples are based on " -#~ "TensorFlow 2.0 or newer. So far, " -#~ "we provide the following examples." +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on MXNet´s `Hand-written Digit " +#~ "Recognition tutorial " +#~ "`_." #~ msgstr "" -#~ msgid "Fashion-MNIST Image Classification" +#~ msgid "" +#~ "In a file called :code:`client.py`, " +#~ "import Flower and MXNet related " +#~ "packages:" +#~ msgstr "" + +#~ msgid "In addition, define the device allocation in MXNet with:" #~ msgstr "" #~ msgid "" -#~ "`Fashion-MNIST `_ is often used as " -#~ "the \"Hello, world!\" of machine " -#~ "learning. We follow this tradition and" -#~ " provide an example which samples " -#~ "random local datasets from Fashion-MNIST" -#~ " and trains a simple image " -#~ "classification model over those partitions." +#~ "We use MXNet to load MNIST, a " +#~ "popular image classification dataset of " +#~ "handwritten digits for machine learning. " +#~ "The MXNet utility :code:`mx.test_utils.get_mnist()`" +#~ " downloads the training and test " +#~ "data." #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgid "" +#~ "Define the training and loss with " +#~ "MXNet. We train the model by " +#~ "looping over the dataset, measure the" +#~ " corresponding loss, and optimize it." #~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" +#~ msgid "" +#~ "Next, we define the validation of " +#~ "our machine learning model. We loop " +#~ "over the test set and measure both" +#~ " loss and accuracy on the test " +#~ "set." #~ msgstr "" #~ msgid "" -#~ "For more details, see " -#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." +#~ "After defining the training and testing" +#~ " of a MXNet machine learning model," +#~ " we use these functions to implement" +#~ " a Flower client." #~ msgstr "" -#~ msgid ":fa:`eye,mr-1` Can Flower run on Juptyter Notebooks / Google Colab?" +#~ msgid "Our Flower clients will use a simple :code:`Sequential` model:" #~ msgstr "" #~ msgid "" -#~ "`Flower meets KOSMoS `_." +#~ "After loading the dataset with " +#~ ":code:`load_data()` we perform one forward " +#~ "propagation to initialize the model and" +#~ " model parameters with :code:`model(init)`. " +#~ "Next, we implement a Flower client." #~ msgstr "" #~ msgid "" -#~ "If you want to check out " -#~ "everything put together, you should " -#~ "check out the full code example: " -#~ "[https://github.com/adap/flower/tree/main/examples/quickstart-" -#~ "huggingface](https://github.com/adap/flower/tree/main/examples" -#~ "/quickstart-huggingface)." +#~ "Flower provides a convenience class " +#~ "called :code:`NumPyClient` which makes it " +#~ "easier to implement the :code:`Client` " +#~ "interface when your workload uses MXNet." +#~ " Implementing :code:`NumPyClient` usually means" +#~ " defining the following methods " +#~ "(:code:`set_parameters` is optional though):" #~ msgstr "" -#~ msgid "" -#~ "First of all, for running the " -#~ "Flower Python server, it is recommended" -#~ " to create a virtual environment and" -#~ " run everything within a `virtualenv " -#~ "`_. " -#~ "For the Flower client implementation in" -#~ " iOS, it is recommended to use " -#~ "Xcode as our IDE." +#~ msgid "They can be implemented in the following way:" #~ msgstr "" #~ msgid "" -#~ "Since CoreML does not allow the " -#~ "model parameters to be seen before " -#~ "training, and accessing the model " -#~ "parameters during or after the training" -#~ " can only be done by specifying " -#~ "the layer name, we need to know" -#~ " this informations beforehand, through " -#~ "looking at the model specification, " -#~ "which are written as proto files. " -#~ "The implementation can be seen in " -#~ ":code:`MLModelInspect`." +#~ "We can now create an instance of" +#~ " our class :code:`MNISTClient` and add " +#~ "one line to actually run this " +#~ "client:" #~ msgstr "" #~ msgid "" -#~ "After we have all of the necessary" -#~ " informations, let's create our Flower " +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()` or " +#~ ":code:`fl.client.start_numpy_client()`. The string " +#~ ":code:`\"0.0.0.0:8080\"` tells the client " +#~ "which server to connect to. In our" +#~ " case we can run the server and" +#~ " the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" +#~ " we run a truly federated workload" +#~ " with the server and clients running" +#~ " on different machines, all that " +#~ "needs to change is the " +#~ ":code:`server_address` we pass to the " #~ "client." #~ msgstr "" #~ msgid "" -#~ "MXNet is no longer maintained and " -#~ "has been moved into `Attic " -#~ "`_. As a " -#~ "result, we would encourage you to " -#~ "use other ML frameworks alongise Flower," -#~ " for example, PyTorch. This tutorial " -#~ "might be removed in future versions " -#~ "of Flower." +#~ "With both client and server ready, " +#~ "we can now run everything and see" +#~ " federated learning in action. Federated" +#~ " learning systems usually have a " +#~ "server and multiple clients. We " +#~ "therefore have to start the server " +#~ "first:" #~ msgstr "" #~ msgid "" -#~ "It is recommended to create a " -#~ "virtual environment and run everything " -#~ "within this `virtualenv `_." +#~ "Congratulations! You've successfully built and" +#~ " run your first federated learning " +#~ "system. The full `source code " +#~ "`_ for this example can " +#~ "be found in :code:`examples/quickstart-mxnet`." #~ msgstr "" -#~ msgid "" -#~ "First of all, it is recommended to" -#~ " create a virtual environment and run" -#~ " everything within a `virtualenv " -#~ "`_." +#~ msgid "Sets the parameters of a :code:`sklean` LogisticRegression model" #~ msgstr "" -#~ msgid "Since we want to use scikt-learn, let's go ahead and install it:" +#~ msgid ":code:`load_mnist()`" +#~ msgstr "" + +#~ msgid "Loads the MNIST dataset using OpenML" +#~ msgstr "" + +#~ msgid ":code:`shuffle()`" +#~ msgstr "" + +#~ msgid "Shuffles data and its label" +#~ msgstr "" + +#~ msgid ":code:`partition()`" +#~ msgstr "" + +#~ msgid "Splits datasets into a number of partitions" #~ msgstr "" #~ msgid "" #~ "We load the MNIST dataset from " -#~ "`OpenML `_, a popular" -#~ " image classification dataset of " -#~ "handwritten digits for machine learning. " -#~ "The utility :code:`utils.load_mnist()` downloads " -#~ "the training and test data. The " +#~ "`OpenML " +#~ "`_, a" +#~ " popular image classification dataset of" +#~ " handwritten digits for machine learning." +#~ " The utility :code:`utils.load_mnist()` downloads" +#~ " the training and test data. The " #~ "training set is split afterwards into" #~ " 10 partitions with :code:`utils.partition()`." #~ msgstr "" #~ msgid "" -#~ "Now that you have known how " -#~ "federated XGBoost work with Flower, it's" -#~ " time to run some more comprehensive" -#~ " experiments by customising the " -#~ "experimental settings. In the xgboost-" -#~ "comprehensive example (`full code " -#~ "`_), we provide more options " -#~ "to define various experimental setups, " -#~ "including aggregation strategies, data " -#~ "partitioning and centralised/distributed evaluation." -#~ " We also support `Flower simulation " -#~ "`_ making it easy to " -#~ "simulate large client cohorts in a " -#~ "resource-aware manner. Let's take a " -#~ "look!" +#~ "The number of federated learning rounds" +#~ " is set in :code:`fit_round()` and " +#~ "the evaluation is defined in " +#~ ":code:`get_evaluate_fn()`. The evaluation function" +#~ " is called after each federated " +#~ "learning round and gives you information" +#~ " about loss and accuracy." #~ msgstr "" -#~ msgid "|31e4b1afa87c4b968327bbeafbf184d4|" +#~ msgid "Let's get stated!" #~ msgstr "" -#~ msgid "|c9d935b4284e4c389a33d86b33e07c0a|" +#~ msgid "" +#~ "We now have a list of ten " +#~ "training sets and ten validation sets" +#~ " (``trainloaders`` and ``valloaders``) " +#~ "representing the data of ten different" +#~ " organizations. Each ``trainloader``/``valloader`` " +#~ "pair contains 4500 training examples and" +#~ " 500 validation examples. There's also " +#~ "a single ``testloader`` (we did not " +#~ "split the test set). Again, this " +#~ "is only necessary for building research" +#~ " or educational systems, actual federated" +#~ " learning systems have their data " +#~ "naturally distributed across multiple " +#~ "partitions." #~ msgstr "" -#~ msgid "|00727b5faffb468f84dd1b03ded88638|" +#~ msgid "|2b5c62c529f6416f840c594cce062fbb|" #~ msgstr "" -#~ msgid "|daf0cf0ff4c24fd29439af78416cf47b|" +#~ msgid "|90b334680cb7467d9a04d39b8e8dca9f|" #~ msgstr "" -#~ msgid "|9f093007080d471d94ca90d3e9fde9b6|" +#~ msgid "|65764ceee89f4335bfd93fd0b115e831|" #~ msgstr "" -#~ msgid "|46a26e6150e0479fbd3dfd655f36eb13|" +#~ msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" #~ msgstr "" -#~ msgid "|3daba297595c4c7fb845d90404a6179a|" +#~ msgid "|11e95ac83a8548d8b3505b4663187d07|" #~ msgstr "" -#~ msgid "|5769874fa9c4455b80b2efda850d39d7|" +#~ msgid "|1dab2f3a23674abc8a6731f20fa10730|" #~ msgstr "" -#~ msgid "|ba47ffb421814b0f8f9fa5719093d839|" +#~ msgid "|7f0ee162da38450788493a21627306f7|" #~ msgstr "" -#~ msgid "|aeac5bf79cbf497082e979834717e01b|" +#~ msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" #~ msgstr "" -#~ msgid "|ce27ed4bbe95459dba016afc42486ba2|" +#~ msgid "|5b1408eec0d746cdb91162a9107b6089|" #~ msgstr "" -#~ msgid "|ae94a7f71dda443cbec2385751427d41|" +#~ msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" #~ msgstr "" -#~ msgid "|e61fce4d43d243e7bb08bdde97d81ce6|" +#~ msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" #~ msgstr "" -#~ msgid "|08cb60859b07461588fe44e55810b050|" +#~ msgid "|ec1fe880237247e0975f52766775ab84|" +#~ msgstr "" + +#~ msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" +#~ msgstr "" + +#~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" + diff --git a/doc/locales/pt_BR/LC_MESSAGES/sphinx.po b/doc/locales/pt_BR/LC_MESSAGES/sphinx.po index 79be6ffce144..45f362cca809 100644 --- a/doc/locales/pt_BR/LC_MESSAGES/sphinx.po +++ b/doc/locales/pt_BR/LC_MESSAGES/sphinx.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-19 07:55+0200\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: pt_BR\n" @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.12.1\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/_templates/base.html:18 msgid "About these documents" @@ -28,6 +28,7 @@ msgid "Index" msgstr "" #: ../../source/_templates/base.html:24 +#: ../../source/_templates/sidebar/search.html:2 msgid "Search" msgstr "" @@ -35,3 +36,7 @@ msgstr "" msgid "Copyright" msgstr "" +#: ../../source/_templates/sidebar/search.html:2 +msgid "Type / to search" +msgstr "" + diff --git a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po index 253dfe0ccc86..47be2dfda762 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po @@ -7,18 +7,17 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-03-15 14:23+0000\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: 2024-05-10 06:59+0000\n" "Last-Translator: Yan Gao \n" -"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" +"Language-Team: Chinese (Simplified) \n" +"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.5.4-rc\n" -"Generated-By: Babel 2.14.0\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 msgid "Flower Architecture" @@ -30,8 +29,8 @@ msgstr "边缘客户端引擎" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" -"`Flower `_ core framework architecture with Edge Client " -"Engine" +"`Flower `_ core framework architecture with Edge " +"Client Engine" msgstr "具有边缘客户端引擎的`Flower `核心架构" #: ../../source/contributor-explanation-architecture.rst:13 @@ -50,10 +49,9 @@ msgstr "可同步进行的虚拟客户端引擎和边缘客户端引擎" #: ../../source/contributor-explanation-architecture.rst:23 msgid "" -"`Flower `_ core framework architecture with both Virtual " -"Client Engine and Edge Client Engine" -msgstr "" -"具有虚拟客户端引擎和边缘客户端引擎的`Flower `核心架构" +"`Flower `_ core framework architecture with both " +"Virtual Client Engine and Edge Client Engine" +msgstr "具有虚拟客户端引擎和边缘客户端引擎的`Flower `核心架构" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" @@ -62,17 +60,16 @@ msgstr "如何在本地搭建Docker Flower images" #: ../../source/contributor-how-to-build-docker-images.rst:4 #, fuzzy msgid "" -"Flower provides pre-made docker images on `Docker Hub `_ that include all necessary dependencies for " -"running the server. You can also build your own custom docker images from " -"scratch with a different version of Python or Ubuntu if that is what you " -"need. In this guide, we will explain what images exist and how to build them " -"locally." +"Flower provides pre-made docker images on `Docker Hub " +"`_ that include all necessary dependencies" +" for running the SuperLink. You can also build your own custom docker " +"images from scratch with a different version of Python or Ubuntu if that " +"is what you need. In this guide, we will explain what images exist and " +"how to build them locally." msgstr "" -"Flower 在 `Docker Hub `_ 上提供了" -"预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要,也可以使" -"用不同版本的 Python 或 Ubuntu 从头开始构建自己的定制 docker 镜像。在本指南" -"中,我们将介绍有哪些镜像,以及如何在本地构建它们。" +"Flower 在 `Docker Hub `_ " +"上提供了预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要,也可以使用不同版本的 Python 或 Ubuntu " +"从头开始构建自己的定制 docker 镜像。在本指南中,我们将介绍有哪些镜像,以及如何在本地构建它们。" #: ../../source/contributor-how-to-build-docker-images.rst:9 #, fuzzy @@ -87,58 +84,56 @@ msgid "Clone the flower repository." msgstr "**叉花仓库**" #: ../../source/contributor-how-to-build-docker-images.rst:17 +#: ../../source/how-to-run-flower-using-docker.rst:144 #, fuzzy msgid "Verify the Docker daemon is running." msgstr "验证 Docker 守护进程是否正在运行。" #: ../../source/contributor-how-to-build-docker-images.rst:19 +#: ../../source/how-to-run-flower-using-docker.rst:146 #, fuzzy msgid "" -"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." +"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -"请阅读 :doc:`Run Flower using Docker ` 的第一" -"节,其中更详细地介绍了这一步骤。" +"请阅读 :doc:`Run Flower using Docker ` " +"的第一节,其中更详细地介绍了这一步骤。" #: ../../source/contributor-how-to-build-docker-images.rst:23 #, fuzzy msgid "" -"Currently, Flower provides two images, a base image and a server image. " -"There will also be a client image soon. The base image, as the name " -"suggests, contains basic dependencies that both the server and the client " -"need. This includes system dependencies, Python and Python tools. The server " -"image is based on the base image, but it additionally installs the Flower " -"server using ``pip``." +"Currently, Flower provides two images, a ``base`` image and a " +"``superlink`` image. The base image, as the name suggests, contains basic" +" dependencies that the SuperLink needs. This includes system " +"dependencies, Python and Python tools. The SuperLink image is based on " +"the base image, but it additionally installs the SuperLink using ``pip``." msgstr "" -"目前,Flower 提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜" -"像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依" -"赖项、Python 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` 额外" -"安装 Flower 服务器。" +"目前,Flower " +"提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依赖项、Python" +" 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` 额外安装 Flower 服务器。" #: ../../source/contributor-how-to-build-docker-images.rst:28 #, fuzzy msgid "" "The build instructions that assemble the images are located in the " -"respective Dockerfiles. You can find them in the subdirectories of ``src/" -"docker``." -msgstr "" -"组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` 的子目录" -"中找到它们。" +"respective Dockerfiles. You can find them in the subdirectories of " +"``src/docker``." +msgstr "组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` 的子目录中找到它们。" #: ../../source/contributor-how-to-build-docker-images.rst:31 #, fuzzy msgid "" -"Both, base and server image are configured via build arguments. Through " -"build arguments, we can make our build more flexible. For example, in the " -"base image, we can specify the version of Python to install using the " -"``PYTHON_VERSION`` build argument. Some of the build arguments have default " -"values, others must be specified when building the image. All available " -"build arguments for each image are listed in one of the tables below." +"Both, base and SuperLink image are configured via build arguments. " +"Through build arguments, we can make our build more flexible. For " +"example, in the base image, we can specify the version of Python to " +"install using the ``PYTHON_VERSION`` build argument. Some of the build " +"arguments have default values, others must be specified when building the" +" image. All available build arguments for each image are listed in one of" +" the tables below." msgstr "" -"基础镜像和服务器镜像都是通过构建参数配置的。通过联编参数,我们可以使联编更加" -"灵活。例如,在基础镜像中,我们可以使用 ``PYTHON_VERSION`` 联编参数指定要安装" -"的 Python 版本。有些联编参数有默认值,有些则必须在联编映像时指定。每个映像的" -"所有可用联编参数都列在下表中。" +"基础镜像和服务器镜像都是通过构建参数配置的。通过联编参数,我们可以使联编更加灵活。例如,在基础镜像中,我们可以使用 " +"``PYTHON_VERSION`` 联编参数指定要安装的 Python " +"版本。有些联编参数有默认值,有些则必须在联编映像时指定。每个映像的所有可用联编参数都列在下表中。" #: ../../source/contributor-how-to-build-docker-images.rst:38 #, fuzzy @@ -170,6 +165,7 @@ msgid "Example" msgstr "实例" #: ../../source/contributor-how-to-build-docker-images.rst:48 +#: ../../source/contributor-how-to-build-docker-images.rst:94 #, fuzzy msgid "``PYTHON_VERSION``" msgstr "Python 版本" @@ -182,7 +178,7 @@ msgstr "要安装的 ``python`` 版本。" #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 #: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:100 +#: ../../source/contributor-how-to-build-docker-images.rst:108 #, fuzzy msgid "Yes" msgstr "类型" @@ -223,6 +219,7 @@ msgid "``69.0.2``" msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-build-docker-images.rst:60 +#: ../../source/contributor-how-to-build-docker-images.rst:98 #, fuzzy msgid "``UBUNTU_VERSION``" msgstr "``UBUNTU_VERSION``" @@ -240,25 +237,21 @@ msgstr "默认为 ``22.04``。" #: ../../source/contributor-how-to-build-docker-images.rst:65 #, fuzzy msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1 " -"and setuptools 69.0.2:" -msgstr "" -"下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 创建了基本映" -"像:" +"The following example creates a base image with Python 3.11.0, pip 23.0.1" +" and setuptools 69.0.2:" +msgstr "下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 创建了基本映像:" #: ../../source/contributor-how-to-build-docker-images.rst:76 #, fuzzy msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the " -"build arguments as well as the name and tag can be adapted to your needs. " -"These values serve as examples only." -msgstr "" -"图像名称为 ``flwr_base``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都" -"可以根据需要进行调整。这些值仅供参考。" +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " +"the build arguments as well as the name and tag can be adapted to your " +"needs. These values serve as examples only." +msgstr "图像名称为 ``flwr_base``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" #: ../../source/contributor-how-to-build-docker-images.rst:80 #, fuzzy -msgid "Building the server image" +msgid "Building the SuperLink image" msgstr "启动服务器" #: ../../source/contributor-how-to-build-docker-images.rst:90 @@ -273,72 +266,85 @@ msgstr "基础镜像的存储库名称。" #: ../../source/contributor-how-to-build-docker-images.rst:92 #, fuzzy -msgid "Defaults to ``flwr/server``." +msgid "Defaults to ``flwr/base``." msgstr "默认为 ``flwr/server``。" -#: ../../source/contributor-how-to-build-docker-images.rst:94 -#, fuzzy -msgid "``BASE_IMAGE_TAG``" -msgstr "基本图像标签" - #: ../../source/contributor-how-to-build-docker-images.rst:95 #, fuzzy -msgid "The image tag of the base image." -msgstr "基础图像的图像标记。" +msgid "The Python version of the base image." +msgstr "基础镜像的存储库名称。" #: ../../source/contributor-how-to-build-docker-images.rst:96 #, fuzzy -msgid "Defaults to ``py3.11-ubuntu22.04``." +msgid "Defaults to ``py3.11``." +msgstr "默认为 ``22.04``。" + +#: ../../source/contributor-how-to-build-docker-images.rst:99 +#, fuzzy +msgid "The Ubuntu version of the base image." +msgstr "基础镜像的存储库名称。" + +#: ../../source/contributor-how-to-build-docker-images.rst:100 +#, fuzzy +msgid "Defaults to ``ubuntu22.04``." msgstr "默认为 ``py3.11-ubuntu22.04``。" -#: ../../source/contributor-how-to-build-docker-images.rst:98 +#: ../../source/contributor-how-to-build-docker-images.rst:102 +#, fuzzy +msgid "``FLWR_PACKAGE``" +msgstr "``FLWR_VERSION``" + +#: ../../source/contributor-how-to-build-docker-images.rst:103 +msgid "The PyPI package to install." +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:104 +#, fuzzy +msgid "Defaults to ``flwr``." +msgstr "默认为 ``flwr/server``。" + +#: ../../source/contributor-how-to-build-docker-images.rst:106 #, fuzzy msgid "``FLWR_VERSION``" msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:99 +#: ../../source/contributor-how-to-build-docker-images.rst:107 #, fuzzy msgid "Version of Flower to be installed." msgstr "要安装的 Flower 版本。" -#: ../../source/contributor-how-to-build-docker-images.rst:101 +#: ../../source/contributor-how-to-build-docker-images.rst:109 #, fuzzy -msgid "``1.7.0``" +msgid "``1.8.0``" msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 +#: ../../source/contributor-how-to-build-docker-images.rst:112 #, fuzzy msgid "" -"The following example creates a server image with the official Flower base " -"image py3.11-ubuntu22.04 and Flower 1.7.0:" -msgstr "" -"下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 创建" -"了一个服务器镜像:" +"The following example creates a SuperLink image with the official Flower " +"base image py3.11-ubuntu22.04 and Flower 1.8.0:" +msgstr "下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 创建了一个服务器镜像:" -#: ../../source/contributor-how-to-build-docker-images.rst:114 +#: ../../source/contributor-how-to-build-docker-images.rst:122 #, fuzzy msgid "" -"The name of image is ``flwr_server`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." -msgstr "" -"图像名称为 ``flwr_server``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记" -"都可以根据需要进行调整。这些值仅供参考。" +"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " +"that the build arguments as well as the name and tag can be adapted to " +"your needs. These values serve as examples only." +msgstr "图像名称为 ``flwr_server``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" -#: ../../source/contributor-how-to-build-docker-images.rst:117 +#: ../../source/contributor-how-to-build-docker-images.rst:125 #, fuzzy msgid "" -"If you want to use your own base image instead of the official Flower base " -"image, all you need to do is set the ``BASE_REPOSITORY`` and " -"``BASE_IMAGE_TAG`` build arguments. The value of ``BASE_REPOSITORY`` must " -"match the name of your image and the value of ``BASE_IMAGE_TAG`` must match " -"the tag of your image." +"If you want to use your own base image instead of the official Flower " +"base image, all you need to do is set the ``BASE_REPOSITORY``, " +"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." msgstr "" -"如果您想使用自己的基础图片而不是 Flower 官方的基础图片,只需设置 " -"``BASE_REPOSITORY`` 和 ``BASE_IMAGE_TAG`` 联编参数即可。`BASE_REPOSITORY``的" -"值必须与您的图像名称一致,`BASE_IMAGE_TAG``的值必须与您的图像标签一致。" +"如果您想使用自己的基础图片而不是 Flower 官方的基础图片,只需设置 ``BASE_REPOSITORY`` 和 " +"``BASE_IMAGE_TAG`` " +"联编参数即可。`BASE_REPOSITORY``的值必须与您的图像名称一致,`BASE_IMAGE_TAG``的值必须与您的图像标签一致。" -#: ../../source/contributor-how-to-build-docker-images.rst:131 +#: ../../source/contributor-how-to-build-docker-images.rst:138 #, fuzzy msgid "After creating the image, we can test whether the image is working:" msgstr "创建图像后,我们可以测试图像是否正常工作:" @@ -350,26 +356,25 @@ msgstr "贡献译文" #: ../../source/contributor-how-to-contribute-translations.rst:4 #, fuzzy msgid "" -"Since `Flower 1.5 `_ we have introduced translations to our doc pages, " -"but, as you might have noticed, the translations are often imperfect. If you " -"speak languages other than English, you might be able to help us in our " -"effort to make Federated Learning accessible to as many people as possible " -"by contributing to those translations! This might also be a great " -"opportunity for those wanting to become open source contributors with little " -"prerequisites." +"Since `Flower 1.5 `_ we have introduced translations to " +"our doc pages, but, as you might have noticed, the translations are often" +" imperfect. If you speak languages other than English, you might be able " +"to help us in our effort to make Federated Learning accessible to as many" +" people as possible by contributing to those translations! This might " +"also be a great opportunity for those wanting to become open source " +"contributors with little prerequisites." msgstr "" -"从 `Flower 1.5 `_ 开始,我们在文档页面中引入了翻译,但正如你可能已经" -"注意到的,这些翻译往往并不完美。如果您会说英语以外的语言,也许您可以帮助我们" -"翻译这些文档,让更多的人了解 Federated Learning!对于那些想成为开源贡献者的人" -"来说,这也是一个很好的机会。" +"从 `Flower 1.5 `_ " +"开始,我们在文档页面中引入了翻译,但正如你可能已经注意到的,这些翻译往往并不完美。如果您会说英语以外的语言,也许您可以帮助我们翻译这些文档,让更多的人了解" +" Federated Learning!对于那些想成为开源贡献者的人来说,这也是一个很好的机会。" #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" -"Our translation project is publicly available over on `Weblate `_, this where most of " -"the work will happen." +"Our translation project is publicly available over on `Weblate " +"`_, this " +"where most of the work will happen." msgstr "" "我们的翻译项目已在 \"Weblate `_\"上公开,大部分工作都将在这里进行。" @@ -380,41 +385,39 @@ msgstr "为现有语言作出贡献" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" -"The first thing you will need to do in order to contribute is to create a " -"free Weblate account on this `page `_. More information about profile settings can be found `here " +"The first thing you will need to do in order to contribute is to create a" +" free Weblate account on this `page " +"`_. More information about" +" profile settings can be found `here " "`_." msgstr "" -"您需要做的第一件事就是在本`网页`_上创建一个免费的Weblate帐户。有关个人资料设置的更多信息,请参阅`这里 " -"`_。" +"您需要做的第一件事就是在本`网页`_上创建一个免费的Weblate帐户。有关个人资料设置的更多信息,请参阅`这里" +" `_。" #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" -"Once you are signed in to Weblate, you can navigate to the `Flower Framework " -"project `_. " -"Here, you should see the different existing languages that can be found on " -"the website." +"Once you are signed in to Weblate, you can navigate to the `Flower " +"Framework project `_. Here, you should see the different existing languages" +" that can be found on the website." msgstr "" -"登录到Weblate后,您可以导航到 \"Flower Framework \"项目`_。在这里,您可以看到网站上现有" -"的各种语言。" +"登录到Weblate后,您可以导航到 \"Flower Framework " +"\"项目`_。在这里,您可以看到网站上现有的各种语言。" #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" -"Once you have selected the language you want to contribute to, you should " -"see a similar interface to this:" +"Once you have selected the language you want to contribute to, you should" +" see a similar interface to this:" msgstr "选择您要贡献的语言后,您应该会看到与此类似的界面:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" "The most straight forward option here is to click on the ``Translate`` " -"button on the top right (in the ``Translation status`` section). This will " -"automatically bring you to the translation interface for untranslated " -"strings." -msgstr "" -"最简单的方法是点击右上角(\"翻译状态 \"部分)的 \"翻译 \"按钮。这将自动带您进" -"入未翻译字符串的翻译界面。" +"button on the top right (in the ``Translation status`` section). This " +"will automatically bring you to the translation interface for " +"untranslated strings." +msgstr "最简单的方法是点击右上角(\"翻译状态 \"部分)的 \"翻译 \"按钮。这将自动带您进入未翻译字符串的翻译界面。" #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" @@ -423,46 +426,43 @@ msgstr "这就是界面的样子:" #: ../../source/contributor-how-to-contribute-translations.rst:47 #, fuzzy msgid "" -"You input your translation in the text box at the top and then, once you are " -"happy with it, you either press ``Save and continue`` (to save the " -"translation and go to the next untranslated string), ``Save and stay`` (to " -"save the translation and stay on the same page), ``Suggest`` (to add your " -"translation to suggestions for other users to view), or ``Skip`` (to go to " -"the next untranslated string without saving anything)." +"You input your translation in the text box at the top and then, once you " +"are happy with it, you either press ``Save and continue`` (to save the " +"translation and go to the next untranslated string), ``Save and stay`` " +"(to save the translation and stay on the same page), ``Suggest`` (to add " +"your translation to suggestions for other users to view), or ``Skip`` (to" +" go to the next untranslated string without saving anything)." msgstr "" -"您可以在顶部的文本框中输入翻译内容,满意后按 \"保存并继续\"(保存翻译内容并转" -"到下一个未翻译的字符串)、\"保存并停留\"(保存翻译内容并停留在同一页" -"面)、\"建议\"(将您的翻译添加到建议中供其他用户查看)或 \"跳过\"(转到下一个" -"未翻译的字符串而不保存任何内容)。" +"您可以在顶部的文本框中输入翻译内容,满意后按 " +"\"保存并继续\"(保存翻译内容并转到下一个未翻译的字符串)、\"保存并停留\"(保存翻译内容并停留在同一页面)、\"建议\"(将您的翻译添加到建议中供其他用户查看)或" +" \"跳过\"(转到下一个未翻译的字符串而不保存任何内容)。" #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" "In order to help with the translations, you can see on the bottom the " "``Nearby strings``, the ``Comments`` (from other contributors), the " "``Automatic suggestions`` (from machine translation engines), the " -"translations in ``Other languages``, and the ``History`` of translations for " -"this string." +"translations in ``Other languages``, and the ``History`` of translations " +"for this string." msgstr "" -"为了帮助翻译,您可以在底部看到 \"邻近字符串\"、\"评论\"(来自其他贡献" -"者)、\"自动建议\"(来自机器翻译引擎)、\"其他语言 \"中的翻译以及该字符串的 " -"\"历史翻译\"。" +"为了帮助翻译,您可以在底部看到 \"邻近字符串\"、\"评论\"(来自其他贡献者)、\"自动建议\"(来自机器翻译引擎)、\"其他语言 " +"\"中的翻译以及该字符串的 \"历史翻译\"。" #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" -"On the right, under the ``String information`` section, you can also click " -"the link under ``Source string location`` in order to view the source of the " -"doc file containing the string." -msgstr "" -"在右侧的 \"字符串信息 \"部分,您还可以单击 \"源字符串位置 \"下的链接,以查看" -"包含字符串的 doc 文件的源文件。" +"On the right, under the ``String information`` section, you can also " +"click the link under ``Source string location`` in order to view the " +"source of the doc file containing the string." +msgstr "在右侧的 \"字符串信息 \"部分,您还可以单击 \"源字符串位置 \"下的链接,以查看包含字符串的 doc 文件的源文件。" #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" -"For more information about translating using Weblate, you can check out this " -"`in-depth guide `_." +"For more information about translating using Weblate, you can check out " +"this `in-depth guide " +"`_." msgstr "" -"有关使用 Weblate 进行翻译的更多信息,您可以查看本 \"深入指南 `_\"。" +"有关使用 Weblate 进行翻译的更多信息,您可以查看本 \"深入指南 " +"`_\"。" #: ../../source/contributor-how-to-contribute-translations.rst:67 msgid "Add new languages" @@ -470,13 +470,12 @@ msgstr "添加新语言" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" -"If you want to add a new language, you will first have to contact us, either " -"on `Slack `_, or by opening an issue on our " -"`GitHub repo `_." +"If you want to add a new language, you will first have to contact us, " +"either on `Slack `_, or by opening an issue" +" on our `GitHub repo `_." msgstr "" -"如果您想添加新语言,请先联系我们,可以在 `Slack `_ 上联系,也可以在我们的 `GitHub repo `_ 上提交问题。" +"如果您想添加新语言,请先联系我们,可以在 `Slack `_ 上联系,也可以在我们的 " +"`GitHub repo `_ 上提交问题。" #: ../../source/contributor-how-to-create-new-messages.rst:2 msgid "Creating New Messages" @@ -484,16 +483,15 @@ msgstr "创建新信息" #: ../../source/contributor-how-to-create-new-messages.rst:4 msgid "" -"This is a simple guide for creating a new type of message between the server " -"and clients in Flower." +"This is a simple guide for creating a new type of message between the " +"server and clients in Flower." msgstr "这是一个如何用Flower在服务器和客户端之间创建新类型的信息的简要指导。" #: ../../source/contributor-how-to-create-new-messages.rst:6 msgid "" -"Let's suppose we have the following example functions in :code:`server.py` " -"and :code:`numpy_client.py`..." -msgstr "" -"假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." +"Let's suppose we have the following example functions in " +":code:`server.py` and :code:`numpy_client.py`..." +msgstr "假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." #: ../../source/contributor-how-to-create-new-messages.rst:8 msgid "Server's side:" @@ -505,11 +503,9 @@ msgstr "在客户端:" #: ../../source/contributor-how-to-create-new-messages.rst:26 msgid "" -"Let's now see what we need to implement in order to get this simple function " -"between the server and client to work!" -msgstr "" -"现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要" -"实现哪些功能!" +"Let's now see what we need to implement in order to get this simple " +"function between the server and client to work!" +msgstr "现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要实现哪些功能!" #: ../../source/contributor-how-to-create-new-messages.rst:30 msgid "Message Types for Protocol Buffers" @@ -518,15 +514,15 @@ msgstr "协议缓冲区的信息类型" #: ../../source/contributor-how-to-create-new-messages.rst:32 #, fuzzy msgid "" -"The first thing we need to do is to define a message type for the RPC system " -"in :code:`transport.proto`. Note that we have to do it for both the request " -"and response messages. For more details on the syntax of proto3, please see " -"the `official documentation `_." +"The first thing we need to do is to define a message type for the RPC " +"system in :code:`transport.proto`. Note that we have to do it for both " +"the request and response messages. For more details on the syntax of " +"proto3, please see the `official documentation `_." msgstr "" -"我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC 系统的消息类型。" -"请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请" -"参阅官方文档 `_。" +"我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC " +"系统的消息类型。请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请参阅官方文档 " +"`_。" #: ../../source/contributor-how-to-create-new-messages.rst:35 msgid "Within the :code:`ServerMessage` block:" @@ -538,8 +534,8 @@ msgstr "在 ClientMessage 代码块中:" #: ../../source/contributor-how-to-create-new-messages.rst:70 msgid "" -"Make sure to also add a field of the newly created message type in :code:" -"`oneof msg`." +"Make sure to also add a field of the newly created message type in " +":code:`oneof msg`." msgstr "确保在 :code:`oneof msg` 中也添加一个新创建的消息类型字段。" #: ../../source/contributor-how-to-create-new-messages.rst:72 @@ -560,9 +556,8 @@ msgid "" "datatypes to or from our defined RPC message types. You should add these " "functions in :code:`serde.py`." msgstr "" -"下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC 消息" -"类型或从我们定义的 RPC 消息类型反序列化和反序列化 Python 数据类型。您应该在 :" -"code:`serde.py` 中添加这些函数。" +"下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC 消息类型或从我们定义的 RPC 消息类型反序列化和反序列化 " +"Python 数据类型。您应该在 :code:`serde.py` 中添加这些函数。" #: ../../source/contributor-how-to-create-new-messages.rst:91 msgid "The four functions:" @@ -574,11 +569,9 @@ msgstr "从服务器发送信息" #: ../../source/contributor-how-to-create-new-messages.rst:114 msgid "" -"Now write the request function in your Client Proxy class (e.g., :code:" -"`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "" -"现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 " -"serde 函数编写请求函数:" +"Now write the request function in your Client Proxy class (e.g., " +":code:`grpc_client_proxy.py`) using the serde functions you just created:" +msgstr "现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 serde 函数编写请求函数:" #: ../../source/contributor-how-to-create-new-messages.rst:128 msgid "Receiving the Message by the Client" @@ -586,12 +579,12 @@ msgstr "由客户端接收信息" #: ../../source/contributor-how-to-create-new-messages.rst:130 msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the field " -"of your message and call the :code:`example_response` function. Remember to " -"use the serde functions!" +"Last step! Modify the code in :code:`message_handler.py` to check the " +"field of your message and call the :code:`example_response` function. " +"Remember to use the serde functions!" msgstr "" -"最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用 :" -"code:`example_response` 函数。记住使用 serde 函数!" +"最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用 " +":code:`example_response` 函数。记住使用 serde 函数!" #: ../../source/contributor-how-to-create-new-messages.rst:132 msgid "Within the handle function:" @@ -611,51 +604,46 @@ msgstr "使用 VSCode Dev Containers 进行开发" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" -"When working on the Flower framework we want to ensure that all contributors " -"use the same developer environment to format code or run tests. For this " -"purpose we are using the VSCode Remote Containers extension. What is it? " -"Read the following quote:" +"When working on the Flower framework we want to ensure that all " +"contributors use the same developer environment to format code or run " +"tests. For this purpose we are using the VSCode Remote Containers " +"extension. What is it? Read the following quote:" msgstr "" -"在开发 Flower 框架时,我们希望确保所有贡献者使用相同的开发环境来格式化代码或" -"运行测试。为此,我们使用了 VSCode 远程容器扩展。这是什么?请阅读下面这段话:" +"在开发 Flower 框架时,我们希望确保所有贡献者使用相同的开发环境来格式化代码或运行测试。为此,我们使用了 VSCode " +"远程容器扩展。这是什么?请阅读下面这段话:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" -"The Visual Studio Code Remote - Containers extension lets you use a Docker " -"container as a fully-featured development environment. It allows you to open " -"any folder inside (or mounted into) a container and take advantage of Visual " -"Studio Code's full feature set. A :code:`devcontainer.json` file in your " -"project tells VS Code how to access (or create) a development container with " -"a well-defined tool and runtime stack. This container can be used to run an " -"application or to separate tools, libraries, or runtimes needed for working " -"with a codebase." -msgstr "" -"Visual Studio Code Remote - Containers扩展可让你将Docker容器用作功能齐全的开" -"发环境。它允许你打开容器内(或挂载到容器内)的任何文件夹,并利用 Visual " -"Studio Code 的全部功能集。项目中的 :code:`devcontainer.json` 文件会告诉 VS " -"Code 如何访问(或创建)一个带有定义明确的工具和运行时栈的开发容器。该容器可用" -"于运行应用程序,也可用于分离处理代码库所需的工具、库或运行时。" +"The Visual Studio Code Remote - Containers extension lets you use a " +"Docker container as a fully-featured development environment. It allows " +"you to open any folder inside (or mounted into) a container and take " +"advantage of Visual Studio Code's full feature set. A " +":code:`devcontainer.json` file in your project tells VS Code how to " +"access (or create) a development container with a well-defined tool and " +"runtime stack. This container can be used to run an application or to " +"separate tools, libraries, or runtimes needed for working with a " +"codebase." +msgstr "" +"Visual Studio Code Remote - " +"Containers扩展可让你将Docker容器用作功能齐全的开发环境。它允许你打开容器内(或挂载到容器内)的任何文件夹,并利用 Visual " +"Studio Code 的全部功能集。项目中的 :code:`devcontainer.json` 文件会告诉 VS Code " +"如何访问(或创建)一个带有定义明确的工具和运行时栈的开发容器。该容器可用于运行应用程序,也可用于分离处理代码库所需的工具、库或运行时。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" -"Workspace files are mounted from the local file system or copied or cloned " -"into the container. Extensions are installed and run inside the container, " -"where they have full access to the tools, platform, and file system. This " -"means that you can seamlessly switch your entire development environment " -"just by connecting to a different container." -msgstr "" -"工作区文件从本地文件系统加载,或复制或克隆到容器中。扩展在容器内安装和运行," -"在容器内它们可以完全访问工具、平台和文件系统。这意味着,只需连接到不同的容" -"器,就能无缝切换整个开发环境。" +"Workspace files are mounted from the local file system or copied or " +"cloned into the container. Extensions are installed and run inside the " +"container, where they have full access to the tools, platform, and file " +"system. This means that you can seamlessly switch your entire development" +" environment just by connecting to a different container." +msgstr "工作区文件从本地文件系统加载,或复制或克隆到容器中。扩展在容器内安装和运行,在容器内它们可以完全访问工具、平台和文件系统。这意味着,只需连接到不同的容器,就能无缝切换整个开发环境。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 #, fuzzy msgid "" -"Source: `Official VSCode documentation `_" -msgstr "" -"来源:`VSCode 官方文档 `_" +"Source: `Official VSCode documentation " +"`_" +msgstr "来源:`VSCode 官方文档 `_" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 msgid "Getting started" @@ -664,43 +652,42 @@ msgstr "开始" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 #, fuzzy msgid "" -"Configuring and setting up the :code:`Dockerfile` as well the configuration " -"for the devcontainer can be a bit more involved. The good thing is you don't " -"have to do it. Usually it should be enough to install `Docker `_ on your system and ensure its available on " -"your command line. Additionally, install the `VSCode Containers Extension " -"`_." +"Configuring and setting up the :code:`Dockerfile` as well the " +"configuration for the devcontainer can be a bit more involved. The good " +"thing is you don't have to do it. Usually it should be enough to install " +"`Docker `_ on your system and " +"ensure its available on your command line. Additionally, install the " +"`VSCode Containers Extension `_." msgstr "" -"配置和设置 :code:`Dockerfile` 以及 devcontainer 的配置可能比较复杂。好在你想" -"做就得做。通常只需在系统中安装 Docker 并确保其在命令行中可用即可。此外,请安" -"装 `VSCode Containers Extension `_。" +"配置和设置 :code:`Dockerfile` 以及 devcontainer 的配置可能比较复杂。好在你想做就得做。通常只需在系统中安装 " +"Docker 并确保其在命令行中可用即可。此外,请安装 `VSCode Containers Extension " +"`_。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" -"Now you should be good to go. When starting VSCode, it will ask you to run " -"in the container environment and - if you confirm - automatically build the " -"container and use it. To manually instruct VSCode to use the devcontainer, " -"you can, after installing the extension, click the green area in the bottom " -"left corner of your VSCode window and select the option *(Re)Open Folder in " -"Container*." +"Now you should be good to go. When starting VSCode, it will ask you to " +"run in the container environment and - if you confirm - automatically " +"build the container and use it. To manually instruct VSCode to use the " +"devcontainer, you can, after installing the extension, click the green " +"area in the bottom left corner of your VSCode window and select the " +"option *(Re)Open Folder in Container*." msgstr "" -"现在你应该可以开始了。启动 VSCode 时,它会要求你在容器环境中运行,如果你确" -"认,它会自动构建容器并使用它。要手动指示 VSCode 使用 devcontainer,可以在安装" -"扩展后,点击 VSCode 窗口左下角的绿色区域,然后选择 \"*(重新)在容器中打开文" -"件夹*\"选项。" +"现在你应该可以开始了。启动 VSCode 时,它会要求你在容器环境中运行,如果你确认,它会自动构建容器并使用它。要手动指示 VSCode 使用 " +"devcontainer,可以在安装扩展后,点击 VSCode 窗口左下角的绿色区域,然后选择 \"*(重新)在容器中打开文件夹*\"选项。" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" -"In some cases your setup might be more involved. For those cases consult the " -"following sources:" +"In some cases your setup might be more involved. For those cases consult " +"the following sources:" msgstr "在某些情况下,您的设置可能更复杂。有关这些情况,请参考以下资料:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 #, fuzzy msgid "" -"`Developing inside a Container `_" +"`Developing inside a Container " +"`_" msgstr "" "在容器内开发 `_" @@ -708,11 +695,9 @@ msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 #, fuzzy msgid "" -"`Remote development in Containers `_" -msgstr "" -"容器中的远程开发 `_" +"`Remote development in Containers " +"`_" +msgstr "容器中的远程开发 `_" #: ../../source/contributor-how-to-install-development-versions.rst:2 msgid "Install development versions" @@ -728,21 +713,19 @@ msgstr "使用诗歌(推荐)" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" -"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency in " -"``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." -"lock`` (``rm poetry.lock``) before running ``poetry install``)." +"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency " +"in ``pyproject.toml`` and then reinstall (don't forget to delete " +"``poetry.lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" "安装来自 PyPI 的 ``flwr`` 预发布版本:更新 ``pyproject.toml`` 中的 ``flwr`` " -"依赖关系,然后重新安装(运行 ``poetry install` 前,别忘了删除 ``poetry.lock` " -"(``rm poetry.lock`))。" +"依赖关系,然后重新安装(运行 ``poetry install` 前,别忘了删除 ``poetry.lock` (``rm " +"poetry.lock`))。" #: ../../source/contributor-how-to-install-development-versions.rst:12 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (without " "extras)" -msgstr "" -"``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (不含额外内" -"容)" +msgstr "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (不含额外内容)" #: ../../source/contributor-how-to-install-development-versions.rst:13 msgid "" @@ -754,8 +737,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" -"Install ``flwr`` from a local copy of the Flower source code via ``pyproject." -"toml``:" +"Install ``flwr`` from a local copy of the Flower source code via " +"``pyproject.toml``:" msgstr "通过 ``pyproject.toml`` 从 Flower 源代码的本地副本安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:17 @@ -764,11 +747,11 @@ msgstr "``flwr = { path = \"../../\", develop = true }`` (不含额外内容 #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " -"(with extras)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " +"}`` (with extras)" msgstr "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " -"(包含额外内容)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " +"}`` (包含额外内容)" #: ../../source/contributor-how-to-install-development-versions.rst:20 msgid "Install ``flwr`` from a local wheel file via ``pyproject.toml``:" @@ -777,11 +760,9 @@ msgstr "通过 ``pyproject.toml`` 从本地轮子文件安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:22 #, fuzzy msgid "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " -"extras)" -msgstr "" -"``flwr = { path = \"../../dist/flwr-1.0.0-py3-none-any.whl\" }``(无额外内" -"容)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without" +" extras)" +msgstr "``flwr = { path = \"../../dist/flwr-1.0.0-py3-none-any.whl\" }``(无额外内容)" #: ../../source/contributor-how-to-install-development-versions.rst:23 #, fuzzy @@ -798,8 +779,8 @@ msgid "" "Dependency Specification `_" msgstr "" -"有关详细信息,请参阅 Poetry 文档: 诗歌依赖性规范 `_" +"有关详细信息,请参阅 Poetry 文档: 诗歌依赖性规范 `_" #: ../../source/contributor-how-to-install-development-versions.rst:28 msgid "Using pip (recommended on Colab)" @@ -821,8 +802,7 @@ msgstr "`pip install -U -pre flwr[simulation]``(包含额外功能)" msgid "" "Python packages can be installed from git repositories. Use one of the " "following commands to install the Flower directly from GitHub." -msgstr "" -"Python 软件包可以从 git 仓库安装。使用以下命令之一直接从 GitHub 安装 Flower。" +msgstr "Python 软件包可以从 git 仓库安装。使用以下命令之一直接从 GitHub 安装 Flower。" #: ../../source/contributor-how-to-install-development-versions.rst:37 msgid "Install ``flwr`` from the default GitHub branch (``main``):" @@ -830,17 +810,17 @@ msgstr "从 GitHub 的默认分支 (``main`) 安装 ``flwr``:" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" -"``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" -msgstr "" -"`pip install flwr@git+https://github.com/adap/flower.git`` (不含额外功能)" +"``pip install flwr@git+https://github.com/adap/flower.git`` (without " +"extras)" +msgstr "`pip install flwr@git+https://github.com/adap/flower.git`` (不含额外功能)" #: ../../source/contributor-how-to-install-development-versions.rst:40 msgid "" "``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` " "(with extras)" msgstr "" -"`pip install flwr[simulation]@git+https://github.com/adap/flower.git``(带附" -"加功能)" +"`pip install " +"flwr[simulation]@git+https://github.com/adap/flower.git``(带附加功能)" #: ../../source/contributor-how-to-install-development-versions.rst:42 msgid "Install ``flwr`` from a specific GitHub branch (``branch-name``):" @@ -851,51 +831,51 @@ msgid "" "``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " "(without extras)" msgstr "" -"`pip install flwr@git+https://github.com/adap/flower.git@branch-name`` (不含" -"附加功能)" +"`pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " +"(不含附加功能)" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" -"name`` (with extras)" -msgstr "" -"`pip安装flwr[模拟]@git+https://github.com/adap/flower.git@分支名``(带附加功" -"能)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" +"@branch-name`` (with extras)" +msgstr "`pip安装flwr[模拟]@git+https://github.com/adap/flower.git@分支名``(带附加功能)" #: ../../source/contributor-how-to-install-development-versions.rst:49 msgid "Open Jupyter Notebooks on Google Colab" msgstr "在谷歌 Colab 上打开 Jupyter 笔记本" #: ../../source/contributor-how-to-install-development-versions.rst:51 +#, fuzzy msgid "" -"Open the notebook ``doc/source/tutorial-get-started-with-flower-pytorch." -"ipynb``:" -msgstr "" -"打开笔记本 ``doc/source/tutorial-get-started-with-flower-pytorch.ipynb``:" +"Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" +"pytorch.ipynb``:" +msgstr "打开笔记本 ``doc/source/tutorial-get-started-with-flower-pytorch.ipynb``:" #: ../../source/contributor-how-to-install-development-versions.rst:53 +#, fuzzy msgid "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" -"tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" -"tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" -"Open a development version of the same notebook from branch `branch-name` by " -"changing ``main`` to ``branch-name`` (right after ``blob``):" +"Open a development version of the same notebook from branch `branch-name`" +" by changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" -"将 ``main`` 改为 ``branch-name``(紧跟在 ``blob``之后),从分支 `branch-" -"name` 打开同一笔记本的开发版本:" +"将 ``main`` 改为 ``branch-name``(紧跟在 ``blob``之后),从分支 `branch-name` " +"打开同一笔记本的开发版本:" #: ../../source/contributor-how-to-install-development-versions.rst:57 +#, fuzzy msgid "" -"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" -"source/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-" +"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" -"source/tutorial-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-" +"name/doc/source/tutorial-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:59 msgid "Install a `whl` on Google Colab:" @@ -903,8 +883,8 @@ msgstr "在 Google Colab 上安装 `whl`:" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" -"In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " -"to session storage``" +"In the vertical icon grid on the left hand side, select ``Files`` > " +"``Upload to session storage``" msgstr "在左侧的垂直图标网格中,选择 \"文件\">\"上传到会话存储\"" #: ../../source/contributor-how-to-install-development-versions.rst:62 @@ -915,13 +895,13 @@ msgstr "更新 whl (e.g., ``flwr-1.7.0-py3-none-any.whl``)" #: ../../source/contributor-how-to-install-development-versions.rst:63 #, fuzzy msgid "" -"Change ``!pip install -q 'flwr[simulation]' torch torchvision matplotlib`` " -"to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " -"torchvision matplotlib``" +"Change ``!pip install -q 'flwr[simulation]' torch torchvision " +"matplotlib`` to ``!pip install -q 'flwr-1.8.0-py3-none-" +"any.whl[simulation]' torch torchvision matplotlib``" msgstr "" -"把``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``变为``!" -"pip install -q 'flwr-1.7.0-py3-none-any.whl[simulation]' torch torchvision " -"matplotlib``" +"把``!pip install -q 'flwr[simulation]' torch torchvision " +"matplotlib``变为``!pip install -q 'flwr-1.7.0-py3-none-any.whl[simulation]'" +" torch torchvision matplotlib``" #: ../../source/contributor-how-to-release-flower.rst:2 msgid "Release Flower" @@ -939,11 +919,10 @@ msgstr "在发布期间" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" -"The version number of a release is stated in ``pyproject.toml``. To release " -"a new version of Flower, the following things need to happen (in that order):" -msgstr "" -"版本号在 ``pyproject.toml`` 中说明。要发布 Flower 的新版本,需要完成以下工作" -"(按顺序排列):" +"The version number of a release is stated in ``pyproject.toml``. To " +"release a new version of Flower, the following things need to happen (in " +"that order):" +msgstr "版本号在 ``pyproject.toml`` 中说明。要发布 Flower 的新版本,需要完成以下工作(按顺序排列):" #: ../../source/contributor-how-to-release-flower.rst:11 #, fuzzy @@ -952,40 +931,37 @@ msgid "" "order to add every new change to the changelog (feel free to make manual " "changes to the changelog afterwards until it looks good)." msgstr "" -"运行 ``python3 src/py/flwr_tool/update_changelog.py `` 以将每" -"项新更改添加到更新日志中(之后可对更新日志进行手动更改,直到看起来不错为" -"止)。" +"运行 ``python3 src/py/flwr_tool/update_changelog.py `` " +"以将每项新更改添加到更新日志中(之后可对更新日志进行手动更改,直到看起来不错为止)。" #: ../../source/contributor-how-to-release-flower.rst:12 #, fuzzy msgid "" -"Once the changelog has been updated with all the changes, run ``./dev/" -"prepare-release-changelog.sh v``, where ```` is " -"the version stated in ``pyproject.toml`` (notice the ``v`` added before it). " -"This will replace the ``Unreleased`` header of the changelog by the version " -"and current date, and it will add a thanking message for the contributors. " -"Open a pull request with those changes." +"Once the changelog has been updated with all the changes, run ``./dev" +"/prepare-release-changelog.sh v``, where ```` " +"is the version stated in ``pyproject.toml`` (notice the ``v`` added " +"before it). This will replace the ``Unreleased`` header of the changelog " +"by the version and current date, and it will add a thanking message for " +"the contributors. Open a pull request with those changes." msgstr "" -"更新更新日志后,运行``./dev/prepare-release-changelog.sh v``,其" -"中````是``pyproject.toml``中的版本(注意前面的``v``)。这将用版" -"本和当前日期替换更新日志中的 ``Unreleased`` 标头,并为贡献者添加一条感谢信" -"息。打开一个包含这些更改的拉取请求。" +"更新更新日志后,运行``./dev/prepare-release-changelog.sh " +"v``,其中````是``pyproject.toml``中的版本(注意前面的``v``)。这将用版本和当前日期替换更新日志中的" +" ``Unreleased`` 标头,并为贡献者添加一条感谢信息。打开一个包含这些更改的拉取请求。" #: ../../source/contributor-how-to-release-flower.rst:13 #, fuzzy msgid "" "Once the pull request is merged, tag the release commit with the version " -"number as soon as the PR is merged: ``git tag v`` (notice the " -"``v`` added before the version number), then ``git push --tags``. This will " -"create a draft release on GitHub containing the correct artifacts and the " -"relevant part of the changelog." +"number as soon as the PR is merged: ``git tag v`` (notice " +"the ``v`` added before the version number), then ``git push --tags``. " +"This will create a draft release on GitHub containing the correct " +"artifacts and the relevant part of the changelog." msgstr "" -"在 PR 合并后立即用版本号标记发布提交:``git tag v0.12.3``,然后``git push --" -"tags``。这将在 GitHub 上创建一个包含正确工件和更新日志相关部分的发布草案。" +"在 PR 合并后立即用版本号标记发布提交:``git tag v0.12.3``,然后``git push --tags``。这将在 GitHub" +" 上创建一个包含正确工件和更新日志相关部分的发布草案。" #: ../../source/contributor-how-to-release-flower.rst:14 -msgid "" -"Check the draft release on GitHub, and if everything is good, publish it." +msgid "Check the draft release on GitHub, and if everything is good, publish it." msgstr "检查 GitHub 上的发布稿,如果一切正常,就发布它。" #: ../../source/contributor-how-to-release-flower.rst:17 @@ -1010,8 +986,8 @@ msgstr "在 ``changelog.md`` 中添加新的 ``Unreleased`` 部分。" #: ../../source/contributor-how-to-release-flower.rst:25 msgid "" -"Merge the pull request on the same day (i.e., before a new nightly release " -"gets published to PyPI)." +"Merge the pull request on the same day (i.e., before a new nightly " +"release gets published to PyPI)." msgstr "在同一天合并拉取请求(即在新版本发布到 PyPI 之前)。" #: ../../source/contributor-how-to-release-flower.rst:28 @@ -1024,11 +1000,9 @@ msgstr "释放前命名" #: ../../source/contributor-how-to-release-flower.rst:33 msgid "" -"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases " -"MUST use one of the following naming patterns:" -msgstr "" -"PyPI 支持预发布版本(alpha、beta、release candidate)。预发布版本必须使用以下" -"命名模式之一:" +"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" +" MUST use one of the following naming patterns:" +msgstr "PyPI 支持预发布版本(alpha、beta、release candidate)。预发布版本必须使用以下命名模式之一:" #: ../../source/contributor-how-to-release-flower.rst:35 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" @@ -1074,41 +1048,38 @@ msgstr "`PEP-440 `_" #: ../../source/contributor-how-to-release-flower.rst:50 msgid "" -"`PyPA Choosing a versioning scheme `_" +"`PyPA Choosing a versioning scheme " +"`_" msgstr "" -"`PyPA 选择版本控制方案 `_" +"`PyPA 选择版本控制方案 `_" #: ../../source/contributor-how-to-release-flower.rst:52 msgid "" -"Note that the approach defined by PyPA is not compatible with SemVer 2.0.0 " -"spec, for details consult the `Semantic Versioning Specification `_ (specifically item 11 on " -"precedence)." +"Note that the approach defined by PyPA is not compatible with SemVer " +"2.0.0 spec, for details consult the `Semantic Versioning Specification " +"`_ (specifically item " +"11 on precedence)." msgstr "" -"请注意,PyPA 所定义的方法与 SemVer 2.0.0 规范不兼容,详情请查阅《语义版本规" -"范》`_(特别是关于优先级的" -"第 11 项)。" +"请注意,PyPA 所定义的方法与 SemVer 2.0.0 " +"规范不兼容,详情请查阅《语义版本规范》`_(特别是关于优先级的第 11 项)。" #: ../../source/contributor-how-to-release-flower.rst:55 msgid "Pre-release classification" msgstr "发布前分类" #: ../../source/contributor-how-to-release-flower.rst:57 -msgid "" -"Should the next pre-release be called alpha, beta, or release candidate?" +msgid "Should the next pre-release be called alpha, beta, or release candidate?" msgstr "下一个预发布版应该叫阿尔法版、贝塔版还是候选发布版?" #: ../../source/contributor-how-to-release-flower.rst:59 msgid "" -"RC: feature complete, no known issues (apart from issues that are classified " -"as \"won't fix\" for the next stable release) - if no issues surface this " -"will become the next stable release" -msgstr "" -"RC:功能完整,无已知问题(除了下一个稳定版中被列为 \"不会修复 \"的问题)--如" -"果没有问题出现,这将成为下一个稳定版" +"RC: feature complete, no known issues (apart from issues that are " +"classified as \"won't fix\" for the next stable release) - if no issues " +"surface this will become the next stable release" +msgstr "RC:功能完整,无已知问题(除了下一个稳定版中被列为 \"不会修复 \"的问题)--如果没有问题出现,这将成为下一个稳定版" #: ../../source/contributor-how-to-release-flower.rst:60 msgid "Beta: feature complete, allowed to have known issues" @@ -1126,12 +1097,11 @@ msgstr "建立虚拟环境" msgid "" "It is recommended to run your Python setup within a virtual environment. " "This guide shows three different examples how to create a virtual " -"environment with pyenv virtualenv, poetry, or Anaconda. You can follow the " -"instructions or choose your preferred setup." +"environment with pyenv virtualenv, poetry, or Anaconda. You can follow " +"the instructions or choose your preferred setup." msgstr "" -"建议在虚拟环境中运行 Python 设置。本指南展示了如何使用 pyenv virtualenv、" -"poes 或 Anaconda 创建虚拟环境的三个不同示例。您可以按照说明或选择您喜欢的设" -"置。" +"建议在虚拟环境中运行 Python 设置。本指南展示了如何使用 pyenv virtualenv、poes 或 Anaconda " +"创建虚拟环境的三个不同示例。您可以按照说明或选择您喜欢的设置。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 msgid "Python Version" @@ -1140,92 +1110,100 @@ msgstr "Python 版本" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 msgid "" -"Flower requires at least `Python 3.8 `_, but " -"`Python 3.10 `_ or above is recommended." +"Flower requires at least `Python 3.8 `_, " +"but `Python 3.10 `_ or above is " +"recommended." msgstr "" -"Flower 至少需要 `Python 3.8 `_,但建议使用 " -"`Python 3.10 `_或更高版本。" +"Flower 至少需要 `Python 3.8 `_,但建议使用 `Python " +"3.10 `_或更高版本。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 -msgid "Virutualenv with Pyenv/Virtualenv" +msgid "" +"Due to a known incompatibility with `ray " +"`_, we currently recommend utilizing at " +"most `Python 3.11 `_ for running Flower " +"simulations." +msgstr "" + +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 +#, fuzzy +msgid "Virtualenv with Pyenv/Virtualenv" msgstr "Virutualenv 和 Pyenv/Virtualenv" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:16 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" -"One of the recommended virtual environment is `pyenv `_/`virtualenv `_. " -"Please see `Flower examples `_ for details." +"One of the recommended virtual environment is `pyenv " +"`_/`virtualenv `_. Please see `Flower examples " +"`_ for details." msgstr "" -"其中一个推荐的虚拟环境是 `pyenv `_/" -"`virtualenv `_。详情请参见 " -"`Flower 示例 `_。" +"其中一个推荐的虚拟环境是 `pyenv `_/`virtualenv " +"`_。详情请参见 `Flower 示例 " +"`_。" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:18 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " "`_ or above:" -msgstr "" -"一旦设置好 Pyenv,就可以用它来安装 `Python 3.10 `_ 或更高版本:" +msgstr "一旦设置好 Pyenv,就可以用它来安装 `Python 3.10 `_ 或更高版本:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:24 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:29 msgid "Create the virtualenv with:" msgstr "创建虚拟环境:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:31 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:36 msgid "Activate the virtualenv by running the following command:" msgstr "运行以下命令激活 virtualenv:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:39 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:44 msgid "Virtualenv with Poetry" msgstr "有诗意的 Virtualenv" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:41 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" -"The Flower examples are based on `Poetry `_ " -"to manage dependencies. After installing Poetry you simply create a virtual " -"environment with:" +"The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " +"simply create a virtual environment with:" msgstr "" -"Flower 示例基于 `Poetry `_ 来管理依赖关系。" -"安装 Poetry 后,只需创建一个虚拟环境即可:" +"Flower 示例基于 `Poetry `_ 来管理依赖关系。安装 Poetry" +" 后,只需创建一个虚拟环境即可:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:47 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" -"If you open a new terminal you can activate the previously created virtual " -"environment with the following command:" +"If you open a new terminal you can activate the previously created " +"virtual environment with the following command:" msgstr "如果打开一个新终端,可以使用以下命令激活之前创建的虚拟环境:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:55 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 msgid "Virtualenv with Anaconda" msgstr "使用 Anaconda 的 Virtualenv" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:57 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" -"If you prefer to use Anaconda for your virtual environment then install and " -"setup the `conda `_ package. After setting it up you can create a virtual " -"environment with:" +"If you prefer to use Anaconda for your virtual environment then install " +"and setup the `conda `_ package. After setting it up you can " +"create a virtual environment with:" msgstr "" -"如果你更喜欢在虚拟环境中使用 Anaconda,那么请安装并设置 `conda `_ 软件包。设" -"置完成后,您就可以使用以下工具创建虚拟环境:" +"如果你更喜欢在虚拟环境中使用 Anaconda,那么请安装并设置 `conda " +"`_ 软件包。设置完成后,您就可以使用以下工具创建虚拟环境:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:63 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:68 msgid "and activate the virtual environment with:" msgstr "并激活虚拟环境:" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:71 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:76 msgid "And then?" msgstr "然后呢?" -#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:73 +#: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" -"As soon as you created your virtual environment you clone one of the `Flower " -"examples `_." +"As soon as you created your virtual environment you clone one of the " +"`Flower examples `_." msgstr "" -"创建虚拟环境后,您可以克隆一个 `Flower 示例 `_。" +"创建虚拟环境后,您可以克隆一个 `Flower 示例 " +"`_。" #: ../../source/contributor-how-to-write-documentation.rst:2 msgid "Write documentation" @@ -1237,23 +1215,24 @@ msgstr "项目布局" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" -"The Flower documentation lives in the ``doc`` directory. The Sphinx-based " -"documentation system supports both reStructuredText (``.rst`` files) and " -"Markdown (``.md`` files)." +"The Flower documentation lives in the ``doc`` directory. The Sphinx-based" +" documentation system supports both reStructuredText (``.rst`` files) and" +" Markdown (``.md`` files)." msgstr "" -"Flower 文档位于 ``doc`` 目录中。基于 Sphinx 的文档系统支持 reStructuredText" -"(``.rst`` 文件)和 Markdown(``.md`` 文件)。" +"Flower 文档位于 ``doc`` 目录中。基于 Sphinx 的文档系统支持 reStructuredText(``.rst`` 文件)和 " +"Markdown(``.md`` 文件)。" #: ../../source/contributor-how-to-write-documentation.rst:10 -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 #, fuzzy msgid "" -"Note that, in order to build the documentation locally (with ``poetry run " -"make html``, like described below), `Pandoc `_ needs to be installed on the system." +"Note that, in order to build the documentation locally (with ``poetry run" +" make html``, like described below), `Pandoc " +"`_ needs to be installed on the " +"system." msgstr "" -"请注意,要在本地构建文档(使用 ``poetry run make html``,如下所述),系统上必" -"须安装 ``Pandoc _`。" +"请注意,要在本地构建文档(使用 ``poetry run make html``,如下所述),系统上必须安装 ``Pandoc " +"_`。" #: ../../source/contributor-how-to-write-documentation.rst:14 msgid "Edit an existing page" @@ -1295,13 +1274,13 @@ msgstr "首次代码贡献" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" -"We welcome contributions to Flower! However, it is not always easy to know " -"where to start. We therefore put together a few recommendations on where to " -"start to increase your chances of getting your PR accepted into the Flower " -"codebase." +"We welcome contributions to Flower! However, it is not always easy to " +"know where to start. We therefore put together a few recommendations on " +"where to start to increase your chances of getting your PR accepted into " +"the Flower codebase." msgstr "" -"我们欢迎为Flower做出代码贡献!然而,要知道从哪里开始并非易事。因此,我们提出" -"了一些建议,告诉您从哪里开始,以增加您的 PR 被 Flower 代码库接受的机会。" +"我们欢迎为Flower做出代码贡献!然而,要知道从哪里开始并非易事。因此,我们提出了一些建议,告诉您从哪里开始,以增加您的 PR 被 Flower" +" 代码库接受的机会。" #: ../../source/contributor-ref-good-first-contributions.rst:11 msgid "Where to start" @@ -1309,12 +1288,10 @@ msgstr "从哪里开始" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" -"Until the Flower core library matures it will be easier to get PR's accepted " -"if they only touch non-core areas of the codebase. Good candidates to get " -"started are:" -msgstr "" -"在 Flower 核心库成熟之前,如果 PR 只涉及代码库中的非核心区域,则会更容易被接" -"受。可以从以下方面入手:" +"Until the Flower core library matures it will be easier to get PR's " +"accepted if they only touch non-core areas of the codebase. Good " +"candidates to get started are:" +msgstr "在 Flower 核心库成熟之前,如果 PR 只涉及代码库中的非核心区域,则会更容易被接受。可以从以下方面入手:" #: ../../source/contributor-ref-good-first-contributions.rst:17 msgid "Documentation: What's missing? What could be expressed more clearly?" @@ -1335,9 +1312,9 @@ msgstr "Flower Baselines的申请" #: ../../source/contributor-ref-good-first-contributions.rst:25 #, fuzzy msgid "" -"If you are not familiar with Flower Baselines, you should probably check-out " -"our `contributing guide for baselines `_." +"If you are not familiar with Flower Baselines, you should probably check-" +"out our `contributing guide for baselines " +"`_." msgstr "" "如果您对 Flower Baselines 还不熟悉,也许可以看看我们的 `Baselines贡献指南 " "`_。" @@ -1345,22 +1322,21 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:27 #, fuzzy msgid "" -"You should then check out the open `issues `_ for baseline " -"requests. If you find a baseline that you'd like to work on and that has no " -"assignees, feel free to assign it to yourself and start working on it!" +"You should then check out the open `issues " +"`_" +" for baseline requests. If you find a baseline that you'd like to work on" +" and that has no assignees, feel free to assign it to yourself and start " +"working on it!" msgstr "" -"然后查看开放的 `issues `_ baseline请求。如果您发现" -"了自己想做的baseline,而它还没有被分配,请随时把它分配给自己,然后开始工作!" +"然后查看开放的 `issues " +"`_" +" baseline请求。如果您发现了自己想做的baseline,而它还没有被分配,请随时把它分配给自己,然后开始工作!" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" -"Otherwise, if you don't find a baseline you'd like to work on, be sure to " -"open a new issue with the baseline request template!" -msgstr "" -"如果您没有找到想要做的baseline,请务必使用baseline请求模板打开一个新问题" -"(GitHub issue)!" +"Otherwise, if you don't find a baseline you'd like to work on, be sure to" +" open a new issue with the baseline request template!" +msgstr "如果您没有找到想要做的baseline,请务必使用baseline请求模板打开一个新问题(GitHub issue)!" #: ../../source/contributor-ref-good-first-contributions.rst:34 msgid "Request for examples" @@ -1369,11 +1345,9 @@ msgstr "示例请求" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" "We wish we had more time to write usage examples because we believe they " -"help users to get started with building what they want to build. Here are a " -"few ideas where we'd be happy to accept a PR:" -msgstr "" -"我们希望有更多的时间来撰写使用示例,因为我们相信这些示例可以帮助用户开始构建" -"他们想要的东西。以下是我们乐意接受 PR 的几个想法:" +"help users to get started with building what they want to build. Here are" +" a few ideas where we'd be happy to accept a PR:" +msgstr "我们希望有更多的时间来撰写使用示例,因为我们相信这些示例可以帮助用户开始构建他们想要的东西。以下是我们乐意接受 PR 的几个想法:" #: ../../source/contributor-ref-good-first-contributions.rst:40 msgid "Llama 2 fine-tuning, with Hugging Face Transformers and PyTorch" @@ -1393,13 +1367,13 @@ msgstr "安全聚合协议" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" -"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg protocol " -"has not been implemented yet, so its diagram and abstraction may not be " -"accurate in practice. The SecAgg protocol can be considered as a special " -"case of the SecAgg+ protocol." +"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg " +"protocol has not been implemented yet, so its diagram and abstraction may" +" not be accurate in practice. The SecAgg protocol can be considered as a " +"special case of the SecAgg+ protocol." msgstr "" -"包括 SecAgg、SecAgg+ 和 LightSecAgg 协议。LightSecAgg 协议尚未实施,因此其图" -"表和抽象在实践中可能并不准确。SecAgg 协议可视为 SecAgg+ 协议的特例。" +"包括 SecAgg、SecAgg+ 和 LightSecAgg 协议。LightSecAgg " +"协议尚未实施,因此其图表和抽象在实践中可能并不准确。SecAgg 协议可视为 SecAgg+ 协议的特例。" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 msgid "The :code:`SecAgg+` abstraction" @@ -1409,17 +1383,17 @@ msgstr "代码:`SecAgg+` 抽象" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 msgid "" "In this implementation, each client will be assigned with a unique index " -"(int) for secure aggregation, and thus many python dictionaries used have " -"keys of int type rather than ClientProxy type." +"(int) for secure aggregation, and thus many python dictionaries used have" +" keys of int type rather than ClientProxy type." msgstr "" -"在此实现中,将为每个客户端分配一个唯一索引(int),以确保聚合的安全性,因此使" -"用的许多 python 字典的键都是 int 类型,而不是 ClientProxy 类型。" +"在此实现中,将为每个客户端分配一个唯一索引(int),以确保聚合的安全性,因此使用的许多 python 字典的键都是 int 类型,而不是 " +"ClientProxy 类型。" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" -"The Flower server will execute and process received results in the following " -"order:" +"The Flower server will execute and process received results in the " +"following order:" msgstr "Flower 服务器将按以下顺序执行和处理收到的结果:" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 @@ -1436,20 +1410,20 @@ msgstr "在 GitHub 上投稿" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" -"This guide is for people who want to get involved with Flower, but who are " -"not used to contributing to GitHub projects." +"This guide is for people who want to get involved with Flower, but who " +"are not used to contributing to GitHub projects." msgstr "本指南适用于想参与 Flower,但不习惯为 GitHub 项目贡献的人。" #: ../../source/contributor-tutorial-contribute-on-github.rst:6 #, fuzzy msgid "" -"If you're familiar with how contributing on GitHub works, you can directly " -"checkout our :doc:`getting started guide for contributors `." +"If you're familiar with how contributing on GitHub works, you can " +"directly checkout our :doc:`getting started guide for contributors " +"`." msgstr "" -"如果您熟悉如何在 GitHub 上贡献,可以直接查看我们的 \"贡献者入门指南\" " -"`_ 和 \"优秀的" -"首次贡献示例\" `_。" +"如果您熟悉如何在 GitHub 上贡献,可以直接查看我们的 \"贡献者入门指南\" `_ 和 \"优秀的首次贡献示例\" " +"`_。" #: ../../source/contributor-tutorial-contribute-on-github.rst:10 msgid "Setting up the repository" @@ -1465,38 +1439,34 @@ msgid "" "Git is a distributed version control tool. This allows for an entire " "codebase's history to be stored and every developer's machine. It is a " "software that will need to be installed on your local machine, you can " -"follow this `guide `_ to set it up." +"follow this `guide `_ to set it up." msgstr "" -"Git 是一种分布式版本控制工具。它可以将整个代码库的历史记录保存在每个开发人员" -"的机器上。您需要在本地计算机上安装该软件,可以按照本指南 `_ 进行设置。" +"Git 是一种分布式版本控制工具。它可以将整个代码库的历史记录保存在每个开发人员的机器上。您需要在本地计算机上安装该软件,可以按照本指南 " +"`_ 进行设置。" #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" "GitHub, itself, is a code hosting platform for version control and " -"collaboration. It allows for everyone to collaborate and work from anywhere " -"on remote repositories." -msgstr "" -"GitHub 本身是一个用于版本控制和协作的代码托管平台。它允许每个人在任何地方对远" -"程仓库进行协作和工作。" +"collaboration. It allows for everyone to collaborate and work from " +"anywhere on remote repositories." +msgstr "GitHub 本身是一个用于版本控制和协作的代码托管平台。它允许每个人在任何地方对远程仓库进行协作和工作。" #: ../../source/contributor-tutorial-contribute-on-github.rst:18 msgid "" "If you haven't already, you will need to create an account on `GitHub " "`_." -msgstr "" -"如果还没有,您需要在 `GitHub `_ 上创建一个账户。" +msgstr "如果还没有,您需要在 `GitHub `_ 上创建一个账户。" #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" -"The idea behind the generic Git and GitHub workflow boils down to this: you " -"download code from a remote repository on GitHub, make changes locally and " -"keep track of them using Git and then you upload your new history back to " -"GitHub." +"The idea behind the generic Git and GitHub workflow boils down to this: " +"you download code from a remote repository on GitHub, make changes " +"locally and keep track of them using Git and then you upload your new " +"history back to GitHub." msgstr "" -"通用的 Git 和 GitHub 工作流程背后的理念可以归结为:从 GitHub 上的远程仓库下载" -"代码,在本地进行修改并使用 Git 进行跟踪,然后将新的历史记录上传回 GitHub。" +"通用的 Git 和 GitHub 工作流程背后的理念可以归结为:从 GitHub 上的远程仓库下载代码,在本地进行修改并使用 Git " +"进行跟踪,然后将新的历史记录上传回 GitHub。" #: ../../source/contributor-tutorial-contribute-on-github.rst:32 msgid "**Forking the Flower repository**" @@ -1505,25 +1475,23 @@ msgstr "**叉花仓库**" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 #, fuzzy msgid "" -"A fork is a personal copy of a GitHub repository. To create one for Flower, " -"you must navigate to ``_ (while connected to " -"your GitHub account) and click the ``Fork`` button situated on the top right " -"of the page." +"A fork is a personal copy of a GitHub repository. To create one for " +"Flower, you must navigate to ``_ (while " +"connected to your GitHub account) and click the ``Fork`` button situated " +"on the top right of the page." msgstr "" "fork 是 GitHub 仓库的个人副本。要为 Flower 创建一个 fork,您必须导航到 " -"https://github.com/adap/flower(同时连接到您的 GitHub 账户),然后点击页面右" -"上方的 ``Fork`` 按钮。" +"https://github.com/adap/flower(同时连接到您的 GitHub 账户),然后点击页面右上方的 ``Fork`` 按钮。" #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" "You can change the name if you want, but this is not necessary as this " -"version of Flower will be yours and will sit inside your own account (i.e., " -"in your own list of repositories). Once created, you should see on the top " -"left corner that you are looking at your own version of Flower." +"version of Flower will be yours and will sit inside your own account " +"(i.e., in your own list of repositories). Once created, you should see on" +" the top left corner that you are looking at your own version of Flower." msgstr "" -"您可以更改名称,但没有必要,因为这个版本的 Flower 将是您自己的,并位于您自己" -"的账户中(即,在您自己的版本库列表中)。创建完成后,您会在左上角看到自己的 " -"Flower 版本。" +"您可以更改名称,但没有必要,因为这个版本的 Flower " +"将是您自己的,并位于您自己的账户中(即,在您自己的版本库列表中)。创建完成后,您会在左上角看到自己的 Flower 版本。" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "**Cloning your forked repository**" @@ -1532,29 +1500,25 @@ msgstr "**克隆你的分叉仓库**" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" "The next step is to download the forked repository on your machine to be " -"able to make changes to it. On your forked repository page, you should first " -"click on the ``Code`` button on the right, this will give you the ability to " -"copy the HTTPS link of the repository." +"able to make changes to it. On your forked repository page, you should " +"first click on the ``Code`` button on the right, this will give you the " +"ability to copy the HTTPS link of the repository." msgstr "" -"下一步是在你的机器上下载分叉版本库,以便对其进行修改。在分叉版本库页面上,首" -"先点击右侧的 \"代码 \"按钮,这样就能复制版本库的 HTTPS 链接。" +"下一步是在你的机器上下载分叉版本库,以便对其进行修改。在分叉版本库页面上,首先点击右侧的 \"代码 \"按钮,这样就能复制版本库的 HTTPS " +"链接。" #: ../../source/contributor-tutorial-contribute-on-github.rst:41 msgid "" "Once you copied the \\, you can open a terminal on your machine, " "navigate to the place you want to download the repository to and type:" -msgstr "" -"一旦复制了 (),你就可以在你的机器上打开一个终端,导航到你想下载软件" -"源的地方,然后键入:" +msgstr "一旦复制了 (),你就可以在你的机器上打开一个终端,导航到你想下载软件源的地方,然后键入:" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 #, fuzzy msgid "" -"This will create a ``flower/`` (or the name of your fork if you renamed it) " -"folder in the current working directory." -msgstr "" -"这将在当前工作目录下创建一个 `flower/`(如果重命名了,则使用 fork 的名称)文" -"件夹。" +"This will create a ``flower/`` (or the name of your fork if you renamed " +"it) folder in the current working directory." +msgstr "这将在当前工作目录下创建一个 `flower/`(如果重命名了,则使用 fork 的名称)文件夹。" #: ../../source/contributor-tutorial-contribute-on-github.rst:66 msgid "**Add origin**" @@ -1566,14 +1530,13 @@ msgstr "然后,您就可以进入存储库文件夹:" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" -"And here we will need to add an origin to our repository. The origin is the " -"\\ of the remote fork repository. To obtain it, we can do as " -"previously mentioned by going to our fork repository on our GitHub account " -"and copying the link." +"And here we will need to add an origin to our repository. The origin is " +"the \\ of the remote fork repository. To obtain it, we can do as " +"previously mentioned by going to our fork repository on our GitHub " +"account and copying the link." msgstr "" "在这里,我们需要为我们的版本库添加一个 origin。origin 是远程 fork 仓库的 " -"\\。要获得它,我们可以像前面提到的那样,访问 GitHub 账户上的分叉仓库并" -"复制链接。" +"\\。要获得它,我们可以像前面提到的那样,访问 GitHub 账户上的分叉仓库并复制链接。" #: ../../source/contributor-tutorial-contribute-on-github.rst:61 msgid "" @@ -1590,33 +1553,28 @@ msgstr "**增加上游**" msgid "" "Now we will add an upstream address to our repository. Still in the same " "directory, we must run the following command:" -msgstr "" -"现在,我们要为版本库添加一个上游地址。还是在同一目录下,我们必须运行以下命" -"令:" +msgstr "现在,我们要为版本库添加一个上游地址。还是在同一目录下,我们必须运行以下命令:" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 -msgid "" -"The following diagram visually explains what we did in the previous steps:" +msgid "The following diagram visually explains what we did in the previous steps:" msgstr "下图直观地解释了我们在前面步骤中的操作:" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" -"The upstream is the GitHub remote address of the parent repository (in this " -"case Flower), i.e. the one we eventually want to contribute to and therefore " -"need an up-to-date history of. The origin is just the GitHub remote address " -"of the forked repository we created, i.e. the copy (fork) in our own account." +"The upstream is the GitHub remote address of the parent repository (in " +"this case Flower), i.e. the one we eventually want to contribute to and " +"therefore need an up-to-date history of. The origin is just the GitHub " +"remote address of the forked repository we created, i.e. the copy (fork) " +"in our own account." msgstr "" -"上游是父版本库(这里是 Flower)的 GitHub 远程地址,即我们最终要贡献的版本库," -"因此需要最新的历史记录。origin 只是我们创建的分叉仓库的 GitHub 远程地址,即我" -"们自己账户中的副本(分叉)。" +"上游是父版本库(这里是 Flower)的 GitHub 远程地址,即我们最终要贡献的版本库,因此需要最新的历史记录。origin " +"只是我们创建的分叉仓库的 GitHub 远程地址,即我们自己账户中的副本(分叉)。" #: ../../source/contributor-tutorial-contribute-on-github.rst:84 msgid "" "To make sure our local version of the fork is up-to-date with the latest " "changes from the Flower repository, we can execute the following command:" -msgstr "" -"为了确保本地版本的分叉程序与 Flower 代码库的最新更改保持一致,我们可以执行以" -"下命令:" +msgstr "为了确保本地版本的分叉程序与 Flower 代码库的最新更改保持一致,我们可以执行以下命令:" #: ../../source/contributor-tutorial-contribute-on-github.rst:93 msgid "Setting up the coding environment" @@ -1626,12 +1584,10 @@ msgstr "设置编码环境" #, fuzzy msgid "" "This can be achieved by following this :doc:`getting started guide for " -"contributors ` (note that " -"you won't need to clone the repository). Once you are able to write code and " -"test it, you can finally start making changes!" -msgstr "" -"您可以按照这份 \"贡献者入门指南\"__(注意,您不需要克隆版本库)来实现这一点。" -"一旦您能够编写代码并进行测试,您就可以开始修改了!" +"contributors ` (note " +"that you won't need to clone the repository). Once you are able to write " +"code and test it, you can finally start making changes!" +msgstr "您可以按照这份 \"贡献者入门指南\"__(注意,您不需要克隆版本库)来实现这一点。一旦您能够编写代码并进行测试,您就可以开始修改了!" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 msgid "Making changes" @@ -1639,7 +1595,8 @@ msgstr "做出改变" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" -"Before making any changes make sure you are up-to-date with your repository:" +"Before making any changes make sure you are up-to-date with your " +"repository:" msgstr "在进行任何更改之前,请确保您的版本库是最新的:" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 @@ -1652,15 +1609,15 @@ msgstr "**创建一个新分支**" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" -"To make the history cleaner and easier to work with, it is good practice to " -"create a new branch for each feature/project that needs to be implemented." -msgstr "" -"为了使历史记录更简洁、更易于操作,为每个需要实现的功能/项目创建一个新分支是个" -"不错的做法。" +"To make the history cleaner and easier to work with, it is good practice " +"to create a new branch for each feature/project that needs to be " +"implemented." +msgstr "为了使历史记录更简洁、更易于操作,为每个需要实现的功能/项目创建一个新分支是个不错的做法。" #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" -"To do so, just run the following command inside the repository's directory:" +"To do so, just run the following command inside the repository's " +"directory:" msgstr "为此,只需在版本库目录下运行以下命令即可:" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 @@ -1668,8 +1625,7 @@ msgid "**Make changes**" msgstr "**进行修改**" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 -msgid "" -"Write great code and create wonderful changes using your favorite editor!" +msgid "Write great code and create wonderful changes using your favorite editor!" msgstr "使用您最喜欢的编辑器编写优秀的代码并创建精彩的更改!" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 @@ -1678,12 +1634,10 @@ msgstr "**测试并格式化您的代码**" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" -"Don't forget to test and format your code! Otherwise your code won't be able " -"to be merged into the Flower repository. This is done so the codebase stays " -"consistent and easy to understand." -msgstr "" -"不要忘记测试和格式化您的代码!否则您的代码将无法并入 Flower 代码库。这样做是" -"为了使代码库保持一致并易于理解。" +"Don't forget to test and format your code! Otherwise your code won't be " +"able to be merged into the Flower repository. This is done so the " +"codebase stays consistent and easy to understand." +msgstr "不要忘记测试和格式化您的代码!否则您的代码将无法并入 Flower 代码库。这样做是为了使代码库保持一致并易于理解。" #: ../../source/contributor-tutorial-contribute-on-github.rst:131 msgid "To do so, we have written a few scripts that you can execute:" @@ -1695,8 +1649,8 @@ msgstr "**舞台变化**" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" -"Before creating a commit that will update your history, you must specify to " -"Git which files it needs to take into account." +"Before creating a commit that will update your history, you must specify " +"to Git which files it needs to take into account." msgstr "在创建更新历史记录的提交之前,必须向 Git 说明需要考虑哪些文件。" #: ../../source/contributor-tutorial-contribute-on-github.rst:143 @@ -1705,12 +1659,10 @@ msgstr "这可以通过:" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" -"To check which files have been modified compared to the last version (last " -"commit) and to see which files are staged for commit, you can use the :code:" -"`git status` command." -msgstr "" -"要查看与上一版本(上次提交)相比哪些文件已被修改,以及哪些文件处于提交阶段," -"可以使用 :code:`git status` 命令。" +"To check which files have been modified compared to the last version " +"(last commit) and to see which files are staged for commit, you can use " +"the :code:`git status` command." +msgstr "要查看与上一版本(上次提交)相比哪些文件已被修改,以及哪些文件处于提交阶段,可以使用 :code:`git status` 命令。" #: ../../source/contributor-tutorial-contribute-on-github.rst:160 msgid "**Commit changes**" @@ -1720,17 +1672,16 @@ msgstr "**提交更改**" msgid "" "Once you have added all the files you wanted to commit using :code:`git " "add`, you can finally create your commit using this command:" -msgstr "" -"使用 :code:`git add` 添加完所有要提交的文件后,就可以使用此命令创建提交了:" +msgstr "使用 :code:`git add` 添加完所有要提交的文件后,就可以使用此命令创建提交了:" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" -"The \\ is there to explain to others what the commit does. " -"It should be written in an imperative style and be concise. An example would " -"be :code:`git commit -m \"Add images to README\"`." +"The \\ is there to explain to others what the commit " +"does. It should be written in an imperative style and be concise. An " +"example would be :code:`git commit -m \"Add images to README\"`." msgstr "" -" 用于向他人解释提交的作用。它应该以命令式风格书写,并且简明" -"扼要。例如 :code:`git commit -m \"Add images to README\"`。" +" 用于向他人解释提交的作用。它应该以命令式风格书写,并且简明扼要。例如 :code:`git commit " +"-m \"Add images to README\"`。" #: ../../source/contributor-tutorial-contribute-on-github.rst:171 msgid "**Push the changes to the fork**" @@ -1738,32 +1689,29 @@ msgstr "**将更改推送到分叉**" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" -"Once we have committed our changes, we have effectively updated our local " -"history, but GitHub has no way of knowing this unless we push our changes to " -"our origin's remote address:" -msgstr "" -"一旦提交了修改,我们就有效地更新了本地历史记录,但除非我们将修改推送到原点的" -"远程地址,否则 GitHub 无法得知:" +"Once we have committed our changes, we have effectively updated our local" +" history, but GitHub has no way of knowing this unless we push our " +"changes to our origin's remote address:" +msgstr "一旦提交了修改,我们就有效地更新了本地历史记录,但除非我们将修改推送到原点的远程地址,否则 GitHub 无法得知:" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 msgid "" "Once this is done, you will see on the GitHub that your forked repo was " "updated with the changes you have made." -msgstr "" -"完成此操作后,您将在 GitHub 上看到您的分叉仓库已根据您所做的更改进行了更新。" +msgstr "完成此操作后,您将在 GitHub 上看到您的分叉仓库已根据您所做的更改进行了更新。" #: ../../source/contributor-tutorial-contribute-on-github.rst:174 msgid "Creating and merging a pull request (PR)" msgstr "创建和合并拉取请求 (PR)" -#: ../../source/contributor-tutorial-contribute-on-github.rst:205 +#: ../../source/contributor-tutorial-contribute-on-github.rst:206 msgid "**Create the PR**" msgstr "**创建 PR**" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" -"Once you have pushed changes, on the GitHub webpage of your repository you " -"should see the following message:" +"Once you have pushed changes, on the GitHub webpage of your repository " +"you should see the following message:" msgstr "推送更改后,在仓库的 GitHub 网页上应该会看到以下信息:" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 @@ -1779,393 +1727,282 @@ msgid "" msgstr "点击 \"比较和拉取请求 \"按钮后,您应该会看到类似下面的内容:" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 -msgid "" -"At the top you have an explanation of which branch will be merged where:" +msgid "At the top you have an explanation of which branch will be merged where:" msgstr "在顶部,你可以看到关于哪个分支将被合并的说明:" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" -"In this example you can see that the request is to merge the branch ``doc-" -"fixes`` from my forked repository to branch ``main`` from the Flower " -"repository." -msgstr "" -"在这个例子中,你可以看到请求将我分叉的版本库中的分支 ``doc-fixes`` 合并到 " -"Flower 版本库中的分支 ``main``。" +"In this example you can see that the request is to merge the branch " +"``doc-fixes`` from my forked repository to branch ``main`` from the " +"Flower repository." +msgstr "在这个例子中,你可以看到请求将我分叉的版本库中的分支 ``doc-fixes`` 合并到 Flower 版本库中的分支 ``main``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" -"The input box in the middle is there for you to describe what your PR does " -"and to link it to existing issues. We have placed comments (that won't be " -"rendered once the PR is opened) to guide you through the process." +"The title should be changed to adhere to the :ref:`pr_title_format` " +"guidelines, otherwise it won't be possible to merge the PR. So in this " +"case, a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" -"中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释" -"(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 -#, fuzzy msgid "" -"It is important to follow the instructions described in comments. For " -"instance, in order to not break how our changelog system works, you should " -"read the information above the ``Changelog entry`` section carefully. You " -"can also checkout some examples and details in the :ref:`changelogentry` " -"appendix." +"The input box in the middle is there for you to describe what your PR " +"does and to link it to existing issues. We have placed comments (that " +"won't be rendered once the PR is opened) to guide you through the " +"process." +msgstr "中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:199 +msgid "It is important to follow the instructions described in comments." msgstr "" -"请务必遵守注释中的说明。例如,为了不破坏我们的更新日志系统,你应该仔细阅读\"`" -"更新日志条目``\"部分上面的信息。您还可以查看 :ref:`changelogentry` 附录中的一" -"些示例和细节。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:200 +#: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " -"reviewers that a new PR has been opened and that they should look over it to " -"merge or to request changes." -msgstr "" -"在底部,您可以找到打开 PR 的按钮。这将通知审核人员新的 PR 已经打开,他们应该" -"查看该 PR 以进行合并或要求修改。" +"reviewers that a new PR has been opened and that they should look over it" +" to merge or to request changes." +msgstr "在底部,您可以找到打开 PR 的按钮。这将通知审核人员新的 PR 已经打开,他们应该查看该 PR 以进行合并或要求修改。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:203 +#: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" -"If your PR is not yet ready for review, and you don't want to notify anyone, " -"you have the option to create a draft pull request:" -msgstr "" -"如果您的 PR 尚未准备好接受审核,而且您不想通知任何人,您可以选择创建一个草案" -"拉取请求:" +"If your PR is not yet ready for review, and you don't want to notify " +"anyone, you have the option to create a draft pull request:" +msgstr "如果您的 PR 尚未准备好接受审核,而且您不想通知任何人,您可以选择创建一个草案拉取请求:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "**Making new changes**" msgstr "**作出新的改变**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:208 +#: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " -"commits to it the same way we did before, by making changes to the branch " -"associated with the PR." -msgstr "" -"一旦 PR 被打开(无论是否作为草案),你仍然可以像以前一样,通过修改与 PR 关联" -"的分支来推送新的提交。" +"commits to it the same way we did before, by making changes to the branch" +" associated with the PR." +msgstr "一旦 PR 被打开(无论是否作为草案),你仍然可以像以前一样,通过修改与 PR 关联的分支来推送新的提交。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:230 +#: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" msgstr "**审查 PR**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:211 +#: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" -"Once the PR has been opened or once the draft PR has been marked as ready, a " -"review from code owners will be automatically requested:" +"Once the PR has been opened or once the draft PR has been marked as " +"ready, a review from code owners will be automatically requested:" msgstr "一旦 PR 被打开或 PR 草案被标记为就绪,就会自动要求代码所有者进行审核:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:215 +#: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" -"Code owners will then look into the code, ask questions, request changes or " -"validate the PR." +"Code owners will then look into the code, ask questions, request changes " +"or validate the PR." msgstr "然后,代码所有者会查看代码、提出问题、要求修改或验证 PR。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:217 +#: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." msgstr "如果有正在进行的更改请求,合并将被阻止。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:221 +#: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" -"To resolve them, just push the necessary changes to the branch associated " -"with the PR:" +"To resolve them, just push the necessary changes to the branch associated" +" with the PR:" msgstr "要解决这些问题,只需将必要的更改推送到与 PR 关联的分支即可:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:225 +#: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" msgstr "并解决对话:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:229 +#: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" -"Once all the conversations have been resolved, you can re-request a review." +"Once all the conversations have been resolved, you can re-request a " +"review." msgstr "一旦所有对话都得到解决,您就可以重新申请审核。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:250 +#: ../../source/contributor-tutorial-contribute-on-github.rst:251 msgid "**Once the PR is merged**" msgstr "**一旦 PR 被合并**" -#: ../../source/contributor-tutorial-contribute-on-github.rst:233 +#: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" -"If all the automatic tests have passed and reviewers have no more changes to " -"request, they can approve the PR and merge it." -msgstr "" -"如果所有自动测试都已通过,且审核员不再需要修改,他们就可以批准 PR 并将其合" -"并。" +"If all the automatic tests have passed and reviewers have no more changes" +" to request, they can approve the PR and merge it." +msgstr "如果所有自动测试都已通过,且审核员不再需要修改,他们就可以批准 PR 并将其合并。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:237 +#: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" -msgstr "" -"合并后,您可以在 GitHub 上删除该分支(会出现一个删除按钮),也可以在本地删除" -"该分支:" +msgstr "合并后,您可以在 GitHub 上删除该分支(会出现一个删除按钮),也可以在本地删除该分支:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:244 +#: ../../source/contributor-tutorial-contribute-on-github.rst:245 msgid "Then you should update your forked repository by doing:" msgstr "然后,你应该更新你的分叉仓库:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:253 +#: ../../source/contributor-tutorial-contribute-on-github.rst:254 msgid "Example of first contribution" msgstr "首次捐款实例" -#: ../../source/contributor-tutorial-contribute-on-github.rst:256 +#: ../../source/contributor-tutorial-contribute-on-github.rst:257 msgid "Problem" msgstr "问题" -#: ../../source/contributor-tutorial-contribute-on-github.rst:258 +#: ../../source/contributor-tutorial-contribute-on-github.rst:259 #, fuzzy msgid "" -"For our documentation, we've started to use the `Diàtaxis framework `_." -msgstr "" -"对于我们的文档,我们已经开始使用 \"Diàtaxis 框架 `_\"。" +"For our documentation, we've started to use the `Diàtaxis framework " +"`_." +msgstr "对于我们的文档,我们已经开始使用 \"Diàtaxis 框架 `_\"。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:260 +#: ../../source/contributor-tutorial-contribute-on-github.rst:261 #, fuzzy msgid "" -"Our \"How to\" guides should have titles that continue the sentence \"How to " -"…\", for example, \"How to upgrade to Flower 1.0\"." -msgstr "" -"我们的 \"如何 \"指南的标题应延续 \"如何...... \"的句式,例如 \"如何升级到 " -"Flower 1.0\"。" +"Our \"How to\" guides should have titles that continue the sentence \"How" +" to …\", for example, \"How to upgrade to Flower 1.0\"." +msgstr "我们的 \"如何 \"指南的标题应延续 \"如何...... \"的句式,例如 \"如何升级到 Flower 1.0\"。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:262 +#: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." -msgstr "" -"我们的大多数指南还没有采用这种新格式,而更改其标题(不幸的是)比人们想象的要" -"复杂得多。" +msgstr "我们的大多数指南还没有采用这种新格式,而更改其标题(不幸的是)比人们想象的要复杂得多。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:264 +#: ../../source/contributor-tutorial-contribute-on-github.rst:265 #, fuzzy msgid "" -"This issue is about changing the title of a doc from present continuous to " -"present simple." +"This issue is about changing the title of a doc from present continuous " +"to present simple." msgstr "这个问题是关于将文档标题从现在进行时改为现在进行时。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:266 +#: ../../source/contributor-tutorial-contribute-on-github.rst:267 #, fuzzy msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" -msgstr "" -"以 \"保存进度 \"为例,我们将其改为 \"保存进度\"。这是否通过了我们的检查?" +msgstr "以 \"保存进度 \"为例,我们将其改为 \"保存进度\"。这是否通过了我们的检查?" -#: ../../source/contributor-tutorial-contribute-on-github.rst:268 +#: ../../source/contributor-tutorial-contribute-on-github.rst:269 #, fuzzy msgid "Before: \"How to saving progress\" ❌" msgstr "之前: \"如何保存进度\" ❌" -#: ../../source/contributor-tutorial-contribute-on-github.rst:270 +#: ../../source/contributor-tutorial-contribute-on-github.rst:271 #, fuzzy msgid "After: \"How to save progress\" ✅" msgstr "之后: \"如何保存进度\"✅" -#: ../../source/contributor-tutorial-contribute-on-github.rst:273 +#: ../../source/contributor-tutorial-contribute-on-github.rst:274 msgid "Solution" msgstr "解决方案" -#: ../../source/contributor-tutorial-contribute-on-github.rst:275 +#: ../../source/contributor-tutorial-contribute-on-github.rst:276 #, fuzzy msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " "After cloning and setting up the Flower repo, here's what you should do:" -msgstr "" -"这只是一个很小的改动,但可以让我们测试你的端到端设置。克隆并设置好 Flower " -"repo 后,你应该这样做:" +msgstr "这只是一个很小的改动,但可以让我们测试你的端到端设置。克隆并设置好 Flower repo 后,你应该这样做:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:277 +#: ../../source/contributor-tutorial-contribute-on-github.rst:278 #, fuzzy msgid "Find the source file in ``doc/source``" msgstr "在 `doc/source` 中查找源文件" -#: ../../source/contributor-tutorial-contribute-on-github.rst:278 +#: ../../source/contributor-tutorial-contribute-on-github.rst:279 #, fuzzy msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " "should be the same length as the title itself)" msgstr "在 `.rst` 文件中进行修改(注意,标题下的破折号应与标题本身的长度相同)" -#: ../../source/contributor-tutorial-contribute-on-github.rst:279 +#: ../../source/contributor-tutorial-contribute-on-github.rst:280 #, fuzzy msgid "" -"Build the docs and `check the result `_" +"Build the docs and `check the result `_" msgstr "" -"构建文档并检查结果: ``_" +"构建文档并检查结果: ``_" -#: ../../source/contributor-tutorial-contribute-on-github.rst:282 +#: ../../source/contributor-tutorial-contribute-on-github.rst:283 msgid "Rename file" msgstr "重命名文件" -#: ../../source/contributor-tutorial-contribute-on-github.rst:284 +#: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" -"You might have noticed that the file name still reflects the old wording. If " -"we just change the file, then we break all existing links to it - it is " -"**very important** to avoid that, breaking links can harm our search engine " -"ranking." +"You might have noticed that the file name still reflects the old wording." +" If we just change the file, then we break all existing links to it - it " +"is **very important** to avoid that, breaking links can harm our search " +"engine ranking." msgstr "" -"您可能已经注意到,文件名仍然反映了旧的措辞。如果我们只是更改文件,那么就会破" -"坏与该文件的所有现有链接--避免这种情况是***重要的,破坏链接会损害我们的搜索引" -"擎排名。" +"您可能已经注意到,文件名仍然反映了旧的措辞。如果我们只是更改文件,那么就会破坏与该文件的所有现有链接--" +"避免这种情况是***重要的,破坏链接会损害我们的搜索引擎排名。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:287 +#: ../../source/contributor-tutorial-contribute-on-github.rst:288 #, fuzzy msgid "Here's how to change the file name:" msgstr "下面是更改文件名的方法:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:289 +#: ../../source/contributor-tutorial-contribute-on-github.rst:290 #, fuzzy msgid "Change the file name to ``save-progress.rst``" msgstr "将文件名改为`save-progress.rst`" -#: ../../source/contributor-tutorial-contribute-on-github.rst:290 +#: ../../source/contributor-tutorial-contribute-on-github.rst:291 #, fuzzy msgid "Add a redirect rule to ``doc/source/conf.py``" msgstr "在 `doc/source/conf.py` 中添加重定向规则" -#: ../../source/contributor-tutorial-contribute-on-github.rst:292 +#: ../../source/contributor-tutorial-contribute-on-github.rst:293 #, fuzzy msgid "" -"This will cause a redirect from ``saving-progress.html`` to ``save-progress." -"html``, old links will continue to work." -msgstr "" -"这将导致从 `saving-progress.html` 重定向到 `save-progress.html`,旧链接将继续" -"工作。" +"This will cause a redirect from ``saving-progress.html`` to ``save-" +"progress.html``, old links will continue to work." +msgstr "这将导致从 `saving-progress.html` 重定向到 `save-progress.html`,旧链接将继续工作。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:295 +#: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" msgstr "应用索引文件中的更改" -#: ../../source/contributor-tutorial-contribute-on-github.rst:297 +#: ../../source/contributor-tutorial-contribute-on-github.rst:298 #, fuzzy msgid "" "For the lateral navigation bar to work properly, it is very important to " "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." -msgstr "" -"要使横向导航栏正常工作,更新 `index.rst` 文件也非常重要。我们就是在这里定义整" -"个导航栏的结构。" +msgstr "要使横向导航栏正常工作,更新 `index.rst` 文件也非常重要。我们就是在这里定义整个导航栏的结构。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:300 +#: ../../source/contributor-tutorial-contribute-on-github.rst:301 #, fuzzy msgid "Find and modify the file name in ``index.rst``" msgstr "查找并修改 `index.rst` 中的文件名" -#: ../../source/contributor-tutorial-contribute-on-github.rst:303 +#: ../../source/contributor-tutorial-contribute-on-github.rst:304 msgid "Open PR" msgstr "开放式 PR" -#: ../../source/contributor-tutorial-contribute-on-github.rst:305 +#: ../../source/contributor-tutorial-contribute-on-github.rst:306 #, fuzzy msgid "" -"Commit the changes (commit messages are always imperative: \"Do something\", " -"in this case \"Change …\")" +"Commit the changes (commit messages are always imperative: \"Do " +"something\", in this case \"Change …\")" msgstr "提交更改(提交信息总是命令式的:\"做某事\",这里是 \"更改......\")" -#: ../../source/contributor-tutorial-contribute-on-github.rst:306 +#: ../../source/contributor-tutorial-contribute-on-github.rst:307 msgid "Push the changes to your fork" msgstr "将更改推送到分叉" -#: ../../source/contributor-tutorial-contribute-on-github.rst:307 -msgid "Open a PR (as shown above)" -msgstr "打开 PR(如上图所示)" - #: ../../source/contributor-tutorial-contribute-on-github.rst:308 +msgid "" +"Open a PR (as shown above) with title ``docs(framework) Update how-to " +"guide title``" +msgstr "" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" msgstr "等待审批!" -#: ../../source/contributor-tutorial-contribute-on-github.rst:309 +#: ../../source/contributor-tutorial-contribute-on-github.rst:310 msgid "Congrats! 🥳 You're now officially a Flower contributor!" msgstr "祝贺你 🥳 您现在正式成为 \"Flower \"贡献者!" -#: ../../source/contributor-tutorial-contribute-on-github.rst:313 -msgid "How to write a good PR title" -msgstr "如何撰写好的公关标题" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:315 -msgid "" -"A well-crafted PR title helps team members quickly understand the purpose " -"and scope of the changes being proposed. Here's a guide to help you write a " -"good GitHub PR title:" -msgstr "" -"一个精心撰写的公关标题能帮助团队成员迅速了解所提修改的目的和范围。以下指南可" -"帮助您撰写一个好的 GitHub PR 标题:" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:317 -msgid "" -"1. Be Clear and Concise: Provide a clear summary of the changes in a concise " -"manner. 1. Use Actionable Verbs: Start with verbs like \"Add,\" \"Update,\" " -"or \"Fix\" to indicate the purpose. 1. Include Relevant Information: Mention " -"the affected feature or module for context. 1. Keep it Short: Avoid lengthy " -"titles for easy readability. 1. Use Proper Capitalization and Punctuation: " -"Follow grammar rules for clarity." -msgstr "" -"1. 简明扼要: 以简明扼要的方式清楚地概述变化。1. 使用可操作的动词: 使用 \"添" -"加\"、\"更新 \"或 \"修复 \"等动词来表明目的。1. 包含相关信息: 提及受影响的功" -"能或模块以了解上下文。1. 简短:避免冗长的标题,以方便阅读。1. 使用正确的大小" -"写和标点符号: 遵守语法规则,以确保清晰。" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:323 -msgid "" -"Let's start with a few examples for titles that should be avoided because " -"they do not provide meaningful information:" -msgstr "让我们先举例说明几个应该避免使用的标题,因为它们不能提供有意义的信息:" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:325 -msgid "Implement Algorithm" -msgstr "执行算法" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:326 -msgid "Database" -msgstr "数据库" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:327 -msgid "Add my_new_file.py to codebase" -msgstr "在代码库中添加 my_new_file.py" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:328 -msgid "Improve code in module" -msgstr "改进模块中的代码" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:329 -msgid "Change SomeModule" -msgstr "更改 SomeModule" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:331 -msgid "" -"Here are a few positive examples which provide helpful information without " -"repeating how they do it, as that is already visible in the \"Files " -"changed\" section of the PR:" -msgstr "" -"这里有几个正面的例子,提供了有用的信息,但没有重复他们是如何做的,因为在 PR " -"的 \"已更改文件 \"部分已经可以看到:" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:333 -msgid "Update docs banner to mention Flower Summit 2023" -msgstr "更新文件横幅,提及 2023 年 Flower 峰会" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:334 -msgid "Remove unnecessary XGBoost dependency" -msgstr "移除不必要的 XGBoost 依赖性" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:335 -msgid "Remove redundant attributes in strategies subclassing FedAvg" -msgstr "删除 FedAvg 子类化策略中的多余属性" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:336 -#, fuzzy -msgid "" -"Add CI job to deploy the staging system when the ``main`` branch changes" -msgstr "添加 CI 作业,以便在 \"主 \"分支发生变化时部署暂存系统" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:337 -msgid "" -"Add new amazing library which will be used to improve the simulation engine" -msgstr "添加新的惊人库,用于改进模拟引擎" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:341 +#: ../../source/contributor-tutorial-contribute-on-github.rst:314 #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:548 #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:946 #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:727 @@ -2174,205 +2011,104 @@ msgstr "添加新的惊人库,用于改进模拟引擎" msgid "Next steps" msgstr "接下来的步骤" -#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +#: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" -"Once you have made your first PR, and want to contribute more, be sure to " -"check out the following :" +"Once you have made your first PR, and want to contribute more, be sure to" +" check out the following :" msgstr "一旦您完成了第一份 PR,并希望做出更多贡献,请务必查看以下内容:" -#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +#: ../../source/contributor-tutorial-contribute-on-github.rst:318 #, fuzzy msgid "" -":doc:`Good first contributions `, " -"where you should particularly look into the :code:`baselines` contributions." +":doc:`Good first contributions `, where you should particularly look into the " +":code:`baselines` contributions." msgstr "" "`优秀的首次贡献 `_,在这里你应该特别看看 :code:`baselines` 的贡献。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +#: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 msgid "Appendix" msgstr "附录" -#: ../../source/contributor-tutorial-contribute-on-github.rst:354 -#, fuzzy -msgid "Changelog entry" -msgstr "更新日志" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:356 -#, fuzzy -msgid "" -"When opening a new PR, inside its description, there should be a ``Changelog " -"entry`` header." -msgstr "打开一个新 PR 时,在其描述中应有一个 ``Changelog entry`` 标头。" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:358 -#, fuzzy -msgid "" -"Above this header you should see the following comment that explains how to " -"write your changelog entry:" -msgstr "在页眉上方,你会看到以下注释,说明如何编写更新日志条目:" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:360 -#, fuzzy -msgid "" -"Inside the following 'Changelog entry' section, you should put the " -"description of your changes that will be added to the changelog alongside " -"your PR title." +#: ../../source/contributor-tutorial-contribute-on-github.rst:327 +msgid "PR title format" msgstr "" -"在下面的 \"更新日志条目 \"部分中,您应该在 PR 标题旁边写上将添加到更新日志中" -"的更改描述。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:363 -#, fuzzy -msgid "" -"If the section is completely empty (without any token) or non-existent, the " -"changelog will just contain the title of the PR for the changelog entry, " -"without any description." +#: ../../source/contributor-tutorial-contribute-on-github.rst:329 +msgid "We enforce the following PR title format:" msgstr "" -"如果该部分完全为空(没有任何标记)或不存在,更新日志将只包含更新日志条目的 " -"PR 标题,而不包含任何描述。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:366 -#, fuzzy +#: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"If the section contains some text other than tokens, it will use it to add a " -"description to the change." -msgstr "如果该部分包含标记以外的文本,它将使用这些文本为更改添加说明。" +"(or ``(:skip) `` to ignore the PR in the " +"changelog)" +msgstr "" -#: ../../source/contributor-tutorial-contribute-on-github.rst:368 -#, fuzzy +#: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"If the section contains one of the following tokens it will ignore any other " -"text and put the PR under the corresponding section of the changelog:" +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " +"break}``, ```` should be in ``{framework, baselines, datasets, " +"examples, or '*' when modifying multiple projects which requires the " +"':skip' flag to be used}``, and ```` starts with a capitalised " +"verb in the imperative mood." msgstr "" -"如果该部分包含以下标记之一,它将忽略任何其他文本,并将 PR 放在更新日志的相应" -"部分下:" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:370 -#, fuzzy -msgid " is for classifying a PR as a general improvement." -msgstr " 用于将 PR 划分为一般改进。" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:372 -#, fuzzy -msgid " is to not add the PR to the changelog" -msgstr "表示不将 PR 添加到更新日志中" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:374 -#, fuzzy -msgid " is to add a general baselines change to the PR" -msgstr " 是指在 PR 中添加一般基线更改" -#: ../../source/contributor-tutorial-contribute-on-github.rst:376 -#, fuzzy -msgid " is to add a general examples change to the PR" -msgstr " 是在 PR 中添加对一般示例的修改" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:378 -#, fuzzy -msgid " is to add a general sdk change to the PR" -msgstr " 是指在 PR 中添加一般的 sdk 更改" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:380 -#, fuzzy -msgid " is to add a general simulations change to the PR" -msgstr "(模拟)是在 PR 中添加一般模拟变更" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:382 -#, fuzzy -msgid "Note that only one token should be used." -msgstr "请注意,只能使用一个标记。" - -#: ../../source/contributor-tutorial-contribute-on-github.rst:384 +#: ../../source/contributor-tutorial-contribute-on-github.rst:341 #, fuzzy -msgid "" -"Its content must have a specific format. We will break down what each " -"possibility does:" -msgstr "其内容必须有特定的格式。我们将分析每种可能性的作用:" +msgid "Valid examples:" +msgstr "实例" -#: ../../source/contributor-tutorial-contribute-on-github.rst:386 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains nothing or doesn't exist, " -"the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:343 +msgid "``feat(framework) Add flwr build CLI command``" msgstr "" -"如果 ``#### Changelog entry`` 部分不包含任何内容或不存在,则会在更新日志中添" -"加以下文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:390 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains a description (and no " -"token), the following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:344 +msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" msgstr "" -"如果 ``#### Changelog entry`` 部分包含描述(但没有标记),则会在更新日志中添" -"加以下文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:396 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains ````, nothing will " -"change in the changelog." +#: ../../source/contributor-tutorial-contribute-on-github.rst:345 +msgid "``ci(*:skip) Enforce PR title format``" msgstr "" -"如果 ``#### Changelog entry`` 部分包含 ````,更新日志中将不会有任何更" -"改。" -#: ../../source/contributor-tutorial-contribute-on-github.rst:398 +#: ../../source/contributor-tutorial-contribute-on-github.rst:347 #, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains ````, the following " -"text will be added to the changelog::" +msgid "Invalid examples:" +msgstr "模拟示例" + +#: ../../source/contributor-tutorial-contribute-on-github.rst:349 +msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" msgstr "" -"如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加以下" -"文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:402 -#, fuzzy +#: ../../source/contributor-tutorial-contribute-on-github.rst:350 msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +"``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " +"``*``)" msgstr "" -"如果``### 更新日志条目``部分包含``<基准线>``,则会在更新日志中添加以下文" -"本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:406 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:351 +msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" msgstr "" -"如果``### 更新日志条目``部分包含``<示例>``,则会在更新日志中添加以下文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:410 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains ````, the following " -"text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:352 +msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" msgstr "" -"如果``### 更新日志条目``部分包含````,则会在更新日志中添加以下文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:414 -#, fuzzy -msgid "" -"If the ``### Changelog entry`` section contains ````, the " -"following text will be added to the changelog::" +#: ../../source/contributor-tutorial-contribute-on-github.rst:353 +msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" msgstr "" -"如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加" -"以下文本::" -#: ../../source/contributor-tutorial-contribute-on-github.rst:418 -#, fuzzy -msgid "" -"Note that only one token must be provided, otherwise, only the first action " -"(in the order listed above), will be performed." -msgstr "请注意,必须只提供一个标记,否则将只执行第一个操作(按上述顺序)。" +#: ../../source/contributor-tutorial-contribute-on-github.rst:354 +msgid "``Add flwr build CLI command.`` (missing ``()``)" +msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 msgid "Get started as a contributor" msgstr "成为贡献者" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 +#: ../../source/how-to-run-flower-using-docker.rst:132 msgid "Prerequisites" msgstr "先决条件" @@ -2390,21 +2126,18 @@ msgid "(Optional) `pyenv `_" msgstr "(可选) `pyenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 -msgid "" -"(Optional) `pyenv-virtualenv `_" -msgstr "" -"(可选) `pyenv-virtualenv `_" +msgid "(Optional) `pyenv-virtualenv `_" +msgstr "(可选) `pyenv-virtualenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 #, fuzzy msgid "" "Flower uses :code:`pyproject.toml` to manage dependencies and configure " -"development tools (the ones which support it). Poetry is a build tool which " -"supports `PEP 517 `_." +"development tools (the ones which support it). Poetry is a build tool " +"which supports `PEP 517 `_." msgstr "" -"Flower 使用 :code:`pyproject.toml` 来管理依赖关系和配置开发工具(支持它的)。" -"Poetry 是一种支持 `PEP 517 `_ 的构" -"建工具。" +"Flower 使用 :code:`pyproject.toml` 来管理依赖关系和配置开发工具(支持它的)。Poetry 是一种支持 `PEP " +"517 `_ 的构建工具。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 msgid "Developer Machine Setup" @@ -2428,17 +2161,15 @@ msgstr "适用于 macOS" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 #, fuzzy msgid "" -"Install `homebrew `_. Don't forget the post-installation " -"actions to add `brew` to your PATH." -msgstr "" -"安装 `homebrew `_。别忘了安装后的操作,将 `brew` 添加到你" -"的 PATH。" +"Install `homebrew `_. Don't forget the post-" +"installation actions to add `brew` to your PATH." +msgstr "安装 `homebrew `_。别忘了安装后的操作,将 `brew` 添加到你的 PATH。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 #, fuzzy msgid "" -"Install `xz` (to install different Python versions) and `pandoc` to build " -"the docs::" +"Install `xz` (to install different Python versions) and `pandoc` to build" +" the docs::" msgstr "安装 `xz`(用于安装不同的 Python 版本)和 `pandoc` 以构建文档::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 @@ -2449,8 +2180,8 @@ msgstr "针对 Ubuntu" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 #, fuzzy msgid "" -"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all necessary " -"packages::" +"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " +"necessary packages::" msgstr "确保您的系统(Ubuntu 22.04+)为最新版本,并安装了所有必要的软件包::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 @@ -2463,50 +2194,46 @@ msgstr "创建/删除虚拟环境" msgid "" "1. Clone the `Flower repository `_ from " "GitHub::" -msgstr "" -"首先,从 GitHub 克隆 \"Flower 存储库 `_\":" +msgstr "首先,从 GitHub 克隆 \"Flower 存储库 `_\":" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 #, fuzzy msgid "" -"Let's create the Python environment for all-things Flower. If you wish to " -"use :code:`pyenv`, we provide two convenience scripts that you can use. If " -"you prefer using something else than :code:`pyenv`, create a new " +"Let's create the Python environment for all-things Flower. If you wish to" +" use :code:`pyenv`, we provide two convenience scripts that you can use. " +"If you prefer using something else than :code:`pyenv`, create a new " "environment, activate and skip to the last point where all packages are " "installed." msgstr "" -"让我们为 Flower 创建一个 Python 环境。如果您想使用 :code:`pyenv`,我们提供了" -"两个方便的脚本供您使用。如果你不喜欢使用 :code:`pyenv`,请创建一个新环境,激" -"活并跳到最后一点,即安装所有软件包。" +"让我们为 Flower 创建一个 Python 环境。如果您想使用 :code:`pyenv`,我们提供了两个方便的脚本供您使用。如果你不喜欢使用" +" :code:`pyenv`,请创建一个新环境,激活并跳到最后一点,即安装所有软件包。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 #, fuzzy msgid "" -"If you don't have :code:`pyenv` installed, the following script that will " -"install it, set it up, and create the virtual environment (with :code:" -"`Python 3.8.17` by default)::" +"If you don't have :code:`pyenv` installed, the following script that will" +" install it, set it up, and create the virtual environment (with " +":code:`Python 3.8.17` by default)::" msgstr "" -"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境" -"(默认使用 :code:`Python3.8.17)::" +"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境(默认使用 " +":code:`Python3.8.17)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 #, fuzzy msgid "" "If you already have :code:`pyenv` installed (along with the :code:`pyenv-" -"virtualenv` plugin), you can use the following convenience script (with :" -"code:`Python 3.8.17` by default)::" +"virtualenv` plugin), you can use the following convenience script (with " +":code:`Python 3.8.17` by default)::" msgstr "" -"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境" -"(默认使用 :code:`Python3.8.17)::" +"如果没有安装 :code:`pyenv`,可以使用以下脚本安装 pyenv、设置并创建虚拟环境(默认使用 " +":code:`Python3.8.17)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 #, fuzzy msgid "" -"3. Install the Flower package in development mode (think :code:`pip install -" -"e`) along with all necessary dependencies::" -msgstr "" -"第三,在开发模式下安装 Flower 软件包(想想 :code:`pip install -e`)以及所有必" -"要的依赖项::" +"3. Install the Flower package in development mode (think :code:`pip " +"install -e`) along with all necessary dependencies::" +msgstr "第三,在开发模式下安装 Flower 软件包(想想 :code:`pip install -e`)以及所有必要的依赖项::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 msgid "Convenience Scripts" @@ -2515,12 +2242,10 @@ msgstr "便捷脚本" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" "The Flower repository contains a number of convenience scripts to make " -"recurring development tasks easier and less error-prone. See the :code:`/" -"dev` subdirectory for a full list. The following scripts are amongst the " -"most important ones:" -msgstr "" -"Flower 软件仓库包含大量便捷脚本,可使重复性开发任务更轻松、更不易出错。完整列" -"表请参见 :code:`/dev` 子目录。以下是最重要的脚本:" +"recurring development tasks easier and less error-prone. See the " +":code:`/dev` subdirectory for a full list. The following scripts are " +"amongst the most important ones:" +msgstr "Flower 软件仓库包含大量便捷脚本,可使重复性开发任务更轻松、更不易出错。完整列表请参见 :code:`/dev` 子目录。以下是最重要的脚本:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 msgid "Create/Delete Virtual Environment" @@ -2539,58 +2264,101 @@ msgid "Run Linters and Tests" msgstr "运行分类器和测试" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:106 +msgid "Add a pre-commit hook" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 +msgid "" +"Developers may integrate a pre-commit hook into their workflow utilizing " +"the `pre-commit `_ library. The pre-" +"commit hook is configured to execute two primary operations: " +"``./dev/format.sh`` and ``./dev/test.sh`` scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 +msgid "There are multiple ways developers can use this:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 +msgid "Install the pre-commit hook to your local git directory by simply running:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 +msgid "" +"Each ``git commit`` will trigger the execution of formatting and " +"linting/test scripts." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 +msgid "" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " +"commit`` command. ::" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 +msgid "" +"For developers who prefer not to install the hook permanently, it is " +"possible to execute a one-time check prior to committing changes by using" +" the following command:" +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 +msgid "" +"This executes the formatting and linting checks/tests on all the files " +"without modifying the default behavior of ``git commit``." +msgstr "" + +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 msgid "Run Github Actions (CI) locally" msgstr "在本地运行 Github 操作 (CI)" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 #, fuzzy msgid "" -"Developers could run the full set of Github Actions workflows under their " -"local environment by using `Act `_. Please " -"refer to the installation instructions under the linked repository and run " -"the next command under Flower main cloned repository folder::" +"Developers could run the full set of Github Actions workflows under their" +" local environment by using `Act `_. " +"Please refer to the installation instructions under the linked repository" +" and run the next command under Flower main cloned repository folder::" msgstr "" -"开发人员可以使用 `Act _` 在本地环境下运行全套 " -"Github Actions 工作流程。请参考链接仓库下的安装说明,并在 Flower 主克隆仓库文" -"件夹下运行下一条命令::" +"开发人员可以使用 `Act _` 在本地环境下运行全套 Github Actions" +" 工作流程。请参考链接仓库下的安装说明,并在 Flower 主克隆仓库文件夹下运行下一条命令::" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:115 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 msgid "" "The Flower default workflow would run by setting up the required Docker " "machines underneath." msgstr "Flower 默认工作流程将通过在下面设置所需的 Docker 机器来运行。" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:120 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:147 msgid "Build Release" msgstr "版本发布" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:122 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" -"Flower uses Poetry to build releases. The necessary command is wrapped in a " -"simple script::" +"Flower uses Poetry to build releases. The necessary command is wrapped in" +" a simple script::" msgstr "Flower 使用 Poetry 创建发布版本。必要的命令封装在一个简单的脚本中::" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:127 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" -"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in " -"the :code:`/dist` subdirectory." -msgstr "" -"生成的 :code:`.whl` 和 :code:`.tar.gz` 版本将存储在 :code:`/dist` 子目录中。" +"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" +" the :code:`/dist` subdirectory." +msgstr "生成的 :code:`.whl` 和 :code:`.tar.gz` 版本将存储在 :code:`/dist` 子目录中。" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:132 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 msgid "Build Documentation" msgstr "构建文档" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:134 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" -"Flower's documentation uses `Sphinx `_. There's " -"no convenience script to re-build the documentation yet, but it's pretty " -"easy::" +"Flower's documentation uses `Sphinx `_. " +"There's no convenience script to re-build the documentation yet, but it's" +" pretty easy::" msgstr "" -"Flower 的文档使用 `Sphinx `_。目前还没有很方便的" -"脚本来重新构建文档,不过这很容易::" +"Flower 的文档使用 `Sphinx `_。目前还没有很方便的脚本来重新构建文档,不过这很容易::" -#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:140 +#: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 msgid "This will generate HTML documentation in ``doc/build/html``." msgstr "这将在 ``doc/build/html`` 中生成 HTML 文档。" @@ -2601,19 +2369,19 @@ msgstr "示例: PyTorch 中的 FedBN - 从集中式到联邦式" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 #, fuzzy msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing machine learning workload with `FedBN `_, a federated training strategy designed for non-iid data. We " -"are using PyTorch to train a Convolutional Neural Network(with Batch " -"Normalization layers) on the CIFAR-10 dataset. When applying FedBN, only few " -"changes needed compared to :doc:`Example: PyTorch - From Centralized To " -"Federated `." +"This tutorial will show you how to use Flower to build a federated " +"version of an existing machine learning workload with `FedBN " +"`_, a federated training strategy " +"designed for non-iid data. We are using PyTorch to train a Convolutional " +"Neural Network(with Batch Normalization layers) on the CIFAR-10 dataset. " +"When applying FedBN, only few changes needed compared to :doc:`Example: " +"PyTorch - From Centralized To Federated `." msgstr "" -"本教程将向您展示如何使用 Flower 为现有的机器学习框架构建一个联邦学习的版本," -"并使用 \"FedBN `_\"(一种针对非 iid 数据设" -"计的联邦训练策略)。我们使用 PyTorch 在 CIFAR-10 数据集上训练一个卷积神经网络" -"(带有Batch Normalization层)。在应用 FedBN 时,只需对 `示例: PyTorch - 从集" -"中式到联邦式 `_\"(一种针对非 iid 数据设计的联邦训练策略)。我们使用 PyTorch 在 CIFAR-10 " +"数据集上训练一个卷积神经网络(带有Batch Normalization层)。在应用 FedBN 时,只需对 `示例: PyTorch - " +"从集中式到联邦式 `_ 做少量改动。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 @@ -2624,14 +2392,14 @@ msgstr "集中式训练" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 #, fuzzy msgid "" -"All files are revised based on :doc:`Example: PyTorch - From Centralized To " -"Federated `. The only thing " -"to do is modifying the file called :code:`cifar.py`, revised part is shown " -"below:" +"All files are revised based on :doc:`Example: PyTorch - From Centralized " +"To Federated `. The only " +"thing to do is modifying the file called :code:`cifar.py`, revised part " +"is shown below:" msgstr "" -"所有文件均根据 `示例: PyTorch -从集中式到联邦式 `_。唯一要做的就是修改名" -"为 :code:`cifar.py` 的文件,修改部分如下所示:" +"所有文件均根据 `示例: PyTorch -从集中式到联邦式 `_。唯一要做的就是修改名为 :code:`cifar.py` " +"的文件,修改部分如下所示:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:13 msgid "" @@ -2647,14 +2415,13 @@ msgstr "现在,您可以运行您的机器学习工作了:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 #, fuzzy msgid "" -"So far this should all look fairly familiar if you've used PyTorch before. " -"Let's take the next step and use what we've built to create a federated " -"learning system within FedBN, the system consists of one server and two " -"clients." +"So far this should all look fairly familiar if you've used PyTorch " +"before. Let's take the next step and use what we've built to create a " +"federated learning system within FedBN, the system consists of one server" +" and two clients." msgstr "" -"到目前为止,如果您以前使用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下" -"一步,使用我们所构建的内容在 FedBN 中创建一个联邦学习系统,该系统由一个服务器" -"和两个客户端组成。" +"到目前为止,如果您以前使用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下一步,使用我们所构建的内容在 FedBN " +"中创建一个联邦学习系统,该系统由一个服务器和两个客户端组成。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 #: ../../source/example-pytorch-from-centralized-to-federated.rst:167 @@ -2665,37 +2432,34 @@ msgstr "联邦培训" #, fuzzy msgid "" "If you have read :doc:`Example: PyTorch - From Centralized To Federated " -"`, the following parts are " -"easy to follow, only :code:`get_parameters` and :code:`set_parameters` " -"function in :code:`client.py` needed to revise. If not, please read the :doc:" -"`Example: PyTorch - From Centralized To Federated `. first." -msgstr "" -"如果你读过 `示例: PyTorch - 从集中式到联邦式 `_,下面的部分就很容易理" -"解了,只需要修改 :code:`get_parameters` 和 :code:`set_parameters` 中的 :code:" -"`client.py` 函数。如果没有,请阅读 `示例: PyTorch - 从集中式到联邦式 " -"`_。" +"`, the following parts are" +" easy to follow, only :code:`get_parameters` and :code:`set_parameters` " +"function in :code:`client.py` needed to revise. If not, please read the " +":doc:`Example: PyTorch - From Centralized To Federated `. first." +msgstr "" +"如果你读过 `示例: PyTorch - 从集中式到联邦式 `_,下面的部分就很容易理解了,只需要修改 " +":code:`get_parameters` 和 :code:`set_parameters` 中的 :code:`client.py` " +"函数。如果没有,请阅读 `示例: PyTorch - 从集中式到联邦式 `_。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" -"Our example consists of one *server* and two *clients*. In FedBN, :code:" -"`server.py` keeps unchanged, we can start the server directly." -msgstr "" -"我们的示例包括一个*服务器*和两个*客户端*。在 FedBN 中,:code:`server.py` 保持" -"不变,我们可以直接启动服务器。" +"Our example consists of one *server* and two *clients*. In FedBN, " +":code:`server.py` keeps unchanged, we can start the server directly." +msgstr "我们的示例包括一个*服务器*和两个*客户端*。在 FedBN 中,:code:`server.py` 保持不变,我们可以直接启动服务器。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" -"Finally, we will revise our *client* logic by changing :code:" -"`get_parameters` and :code:`set_parameters` in :code:`client.py`, we will " -"exclude batch normalization parameters from model parameter list when " -"sending to or receiving from the server." +"Finally, we will revise our *client* logic by changing " +":code:`get_parameters` and :code:`set_parameters` in :code:`client.py`, " +"we will exclude batch normalization parameters from model parameter list " +"when sending to or receiving from the server." msgstr "" -"最后,我们将修改 *client* 的逻辑,修改 :code:`client.py` 中的 :code:" -"`get_parameters` 和 :code:`set_parameters`,在向服务器发送或从服务器接收时," -"我们将从模型参数列表中排除batch normalization层的参数。" +"最后,我们将修改 *client* 的逻辑,修改 :code:`client.py` 中的 :code:`get_parameters` 和 " +":code:`set_parameters`,在向服务器发送或从服务器接收时,我们将从模型参数列表中排除batch " +"normalization层的参数。" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 msgid "Now, you can now open two additional terminal windows and run" @@ -2703,16 +2467,13 @@ msgstr "现在,您可以打开另外两个终端窗口并运行程序" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" -"in each window (make sure that the server is still running before you do so) " -"and see your (previously centralized) PyTorch project run federated learning " -"with FedBN strategy across two clients. Congratulations!" -msgstr "" -"确保服务器仍在运行后,然后您就能看到您的 PyTorch 项目(之前是集中式的)通过 " -"FedBN 策略在两个客户端上运行联合学习。祝贺!" +"in each window (make sure that the server is still running before you do " +"so) and see your (previously centralized) PyTorch project run federated " +"learning with FedBN strategy across two clients. Congratulations!" +msgstr "确保服务器仍在运行后,然后您就能看到您的 PyTorch 项目(之前是集中式的)通过 FedBN 策略在两个客户端上运行联合学习。祝贺!" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 -#: ../../source/example-mxnet-walk-through.rst:356 #: ../../source/example-pytorch-from-centralized-to-federated.rst:310 #: ../../source/tutorial-quickstart-jax.rst:283 msgid "Next Steps" @@ -2720,17 +2481,18 @@ msgstr "下一步工作" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" -"The full source code for this example can be found `here `_. Our " -"example is of course somewhat over-simplified because both clients load the " -"exact same dataset, which isn't realistic. You're now prepared to explore " -"this topic further. How about using different subsets of CIFAR-10 on each " -"client? How about adding more clients?" +"The full source code for this example can be found `here " +"`_. Our example is of course somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using different subsets of CIFAR-10 on each client? How about adding more" +" clients?" msgstr "" -"本示例的完整源代码可在 `_ 找到。当然,我们的示例有些过于简单," -"因为两个客户端都加载了完全相同的数据集,这并不真实。让我们准备好进一步探讨这" -"一主题。如在每个客户端使用不同的 CIFAR-10 子集,或者增加客户端的数量。" +"本示例的完整源代码可在 `_ " +"找到。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。让我们准备好进一步探讨这一主题。如在每个客户端使用不同的 " +"CIFAR-10 子集,或者增加客户端的数量。" #: ../../source/example-jax-from-centralized-to-federated.rst:2 msgid "Example: JAX - Run JAX Federated" @@ -2739,32 +2501,32 @@ msgstr "示例: JAX - 运行联邦式 JAX" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing JAX workload. We are using JAX to train a linear regression " -"model on a scikit-learn dataset. We will structure the example similar to " -"our `PyTorch - From Centralized To Federated `_ walkthrough. " -"First, we build a centralized training approach based on the `Linear " -"Regression with JAX `_ tutorial`. Then, we build upon the centralized " -"training code to run the training in a federated fashion." -msgstr "" -"本教程将向您展示如何使用 Flower 构建现有 JAX 的联邦学习版本。我们将使用 JAX " -"在 scikit-learn 数据集上训练线性回归模型。我们将采用与 `PyTorch - 从集中式到" -"联邦式 `_ 教程中类似的示例结构。首先,我们根据 `JAX 的线性" -"回归 `_ 教程构建集中式训练方法。然后,我们在集中式训练代码的基础上以联邦方式" -"运行训练。" +"This tutorial will show you how to use Flower to build a federated " +"version of an existing JAX workload. We are using JAX to train a linear " +"regression model on a scikit-learn dataset. We will structure the example" +" similar to our `PyTorch - From Centralized To Federated " +"`_ walkthrough. First, we build a centralized " +"training approach based on the `Linear Regression with JAX " +"`_" +" tutorial`. Then, we build upon the centralized training code to run the " +"training in a federated fashion." +msgstr "" +"本教程将向您展示如何使用 Flower 构建现有 JAX 的联邦学习版本。我们将使用 JAX 在 scikit-learn " +"数据集上训练线性回归模型。我们将采用与 `PyTorch - 从集中式到联邦式 " +"`_ 教程中类似的示例结构。首先,我们根据 `JAX 的线性回归 " +"`_" +" 教程构建集中式训练方法。然后,我们在集中式训练代码的基础上以联邦方式运行训练。" #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 msgid "" -"Before we start building our JAX example, we need install the packages :code:" -"`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" +"Before we start building our JAX example, we need install the packages " +":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" -"在开始构建 JAX 示例之前,我们需要安装软件包 :code:`jax`、:code:`jaxlib`、:" -"code:`scikit-learn` 和 :code:`flwr`:" +"在开始构建 JAX 示例之前,我们需要安装软件包 :code:`jax`、:code:`jaxlib`、:code:`scikit-learn` " +"和 :code:`flwr`:" #: ../../source/example-jax-from-centralized-to-federated.rst:18 #: ../../source/tutorial-quickstart-jax.rst:24 @@ -2774,83 +2536,77 @@ msgstr "使用 JAX 进行线性回归" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 msgid "" -"We begin with a brief description of the centralized training code based on " -"a :code:`Linear Regression` model. If you want a more in-depth explanation " -"of what's going on then have a look at the official `JAX documentation " -"`_." +"We begin with a brief description of the centralized training code based " +"on a :code:`Linear Regression` model. If you want a more in-depth " +"explanation of what's going on then have a look at the official `JAX " +"documentation `_." msgstr "" -"首先,我们将简要介绍基于 :code:`Linear Regression` 模型的集中式训练代码。如果" -"您想获得更深入的解释,请参阅官方的 `JAX 文档 `_。" +"首先,我们将简要介绍基于 :code:`Linear Regression` 模型的集中式训练代码。如果您想获得更深入的解释,请参阅官方的 " +"`JAX 文档 `_。" #: ../../source/example-jax-from-centralized-to-federated.rst:23 #: ../../source/tutorial-quickstart-jax.rst:29 msgid "" "Let's create a new file called :code:`jax_training.py` with all the " "components required for a traditional (centralized) linear regression " -"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to be " -"imported. In addition, we need to import :code:`sklearn` since we use :code:" -"`make_regression` for the dataset and :code:`train_test_split` to split the " -"dataset into a training and test set. You can see that we do not yet import " -"the :code:`flwr` package for federated learning. This will be done later." -msgstr "" -"让我们创建一个名为 :code:`jax_training.py` 的新文件,其中包含传统(集中式)线" -"性回归训练所需的所有组件。首先,需要导入 JAX 包 :code:`jax` 和 :code:" -"`jaxlib`。此外,我们还需要导入 :code:`sklearn`,因为我们使用 :code:" -"`make_regression` 创建数据集,并使用 :code:`train_test_split` 将数据集拆分成" -"训练集和测试集。您可以看到,我们还没有导入用于联邦学习的 :code:`flwr` 软件" -"包,这将在稍后完成。" +"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to " +"be imported. In addition, we need to import :code:`sklearn` since we use " +":code:`make_regression` for the dataset and :code:`train_test_split` to " +"split the dataset into a training and test set. You can see that we do " +"not yet import the :code:`flwr` package for federated learning. This will" +" be done later." +msgstr "" +"让我们创建一个名为 :code:`jax_training.py` 的新文件,其中包含传统(集中式)线性回归训练所需的所有组件。首先,需要导入 " +"JAX 包 :code:`jax` 和 :code:`jaxlib`。此外,我们还需要导入 :code:`sklearn`,因为我们使用 " +":code:`make_regression` 创建数据集,并使用 :code:`train_test_split` " +"将数据集拆分成训练集和测试集。您可以看到,我们还没有导入用于联邦学习的 :code:`flwr` 软件包,这将在稍后完成。" #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" -"The :code:`load_data()` function loads the mentioned training and test sets." +"The :code:`load_data()` function loads the mentioned training and test " +"sets." msgstr ":code:`load_data()` 函数会加载上述训练集和测试集。" #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" -"The model architecture (a very simple :code:`Linear Regression` model) is " -"defined in :code:`load_model()`." -msgstr "" -"模型结构(一个非常简单的 :code:`Linear Regression` 线性回归模型)在 :code:" -"`load_model()` 中定义。" +"The model architecture (a very simple :code:`Linear Regression` model) is" +" defined in :code:`load_model()`." +msgstr "模型结构(一个非常简单的 :code:`Linear Regression` 线性回归模型)在 :code:`load_model()` 中定义。" #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 msgid "" -"We now need to define the training (function :code:`train()`), which loops " -"over the training set and measures the loss (function :code:`loss_fn()`) for " -"each batch of training examples. The loss function is separate since JAX " -"takes derivatives with a :code:`grad()` function (defined in the :code:" -"`main()` function and called in :code:`train()`)." +"We now need to define the training (function :code:`train()`), which " +"loops over the training set and measures the loss (function " +":code:`loss_fn()`) for each batch of training examples. The loss function" +" is separate since JAX takes derivatives with a :code:`grad()` function " +"(defined in the :code:`main()` function and called in :code:`train()`)." msgstr "" -"现在,我们需要定义训练函数( :code:`train()`)。它循环遍历训练集,并计算每批" -"训练数据的损失值(函数 :code:`loss_fn()`)。由于 JAX 使用 :code:`grad()` 函数" -"提取导数(在 :code:`main()` 函数中定义,并在 :code:`train()` 中调用),因此损" -"失函数是独立的。" +"现在,我们需要定义训练函数( :code:`train()`)。它循环遍历训练集,并计算每批训练数据的损失值(函数 " +":code:`loss_fn()`)。由于 JAX 使用 :code:`grad()` 函数提取导数(在 :code:`main()` " +"函数中定义,并在 :code:`train()` 中调用),因此损失函数是独立的。" #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 msgid "" -"The evaluation of the model is defined in the function :code:`evaluation()`. " -"The function takes all test examples and measures the loss of the linear " -"regression model." -msgstr "" -"模型的评估在函数 :code:`evaluation()` 中定义。该函数获取所有测试数据,并计算" -"线性回归模型的损失值。" +"The evaluation of the model is defined in the function " +":code:`evaluation()`. The function takes all test examples and measures " +"the loss of the linear regression model." +msgstr "模型的评估在函数 :code:`evaluation()` 中定义。该函数获取所有测试数据,并计算线性回归模型的损失值。" #: ../../source/example-jax-from-centralized-to-federated.rst:88 #: ../../source/tutorial-quickstart-jax.rst:94 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model using JAX. As " -"already mentioned, the :code:`jax.grad()` function is defined in :code:" -"`main()` and passed to :code:`train()`." +"evaluation we can put everything together and train our model using JAX. " +"As already mentioned, the :code:`jax.grad()` function is defined in " +":code:`main()` and passed to :code:`train()`." msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以把这些放在一起,使用 " -"JAX 训练我们的模型了。如前所述,:code:`jax.grad()` 函数在 :code:`main()` 中定" -"义,并传递给 :code:`train()`。" +"在定义了数据加载、模型架构、训练和评估之后,我们就可以把这些放在一起,使用 JAX " +"训练我们的模型了。如前所述,:code:`jax.grad()` 函数在 :code:`main()` 中定义,并传递给 " +":code:`train()`。" #: ../../source/example-jax-from-centralized-to-federated.rst:105 #: ../../source/tutorial-quickstart-jax.rst:111 @@ -2860,12 +2616,10 @@ msgstr "现在您可以运行(集中式)JAX 线性回归工作了:" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 msgid "" -"So far this should all look fairly familiar if you've used JAX before. Let's " -"take the next step and use what we've built to create a simple federated " -"learning system consisting of one server and two clients." -msgstr "" -"到目前为止,如果你以前使用过 JAX,就会对这一切感到很熟悉。下一步,让我们利用" -"已构建的代码创建一个简单的联邦学习系统(一个服务器和两个客户端)。" +"So far this should all look fairly familiar if you've used JAX before. " +"Let's take the next step and use what we've built to create a simple " +"federated learning system consisting of one server and two clients." +msgstr "到目前为止,如果你以前使用过 JAX,就会对这一切感到很熟悉。下一步,让我们利用已构建的代码创建一个简单的联邦学习系统(一个服务器和两个客户端)。" #: ../../source/example-jax-from-centralized-to-federated.rst:115 #: ../../source/tutorial-quickstart-jax.rst:121 @@ -2875,37 +2629,31 @@ msgstr "JAX 结合 Flower" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 msgid "" -"The concept of federating an existing workload is always the same and easy " -"to understand. We have to start a *server* and then use the code in :code:" -"`jax_training.py` for the *clients* that are connected to the *server*. The " -"*server* sends model parameters to the clients. The *clients* run the " -"training and update the parameters. The updated parameters are sent back to " -"the *server*, which averages all received parameter updates. This describes " -"one round of the federated learning process, and we repeat this for multiple " -"rounds." -msgstr "" -"把现有工作联邦化的概念始终是相同的,也很容易理解。我们要启动一个*服务器*,然" -"后对连接到*服务器*的*客户端*运行 :code:`jax_training.py`中的代码。*服务器*向" -"客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*," -"然后服务器对所有收到的参数进行平均聚合。以上的描述构成了一轮联邦学习,我们将" -"重复进行多轮学习。" +"The concept of federating an existing workload is always the same and " +"easy to understand. We have to start a *server* and then use the code in " +":code:`jax_training.py` for the *clients* that are connected to the " +"*server*. The *server* sends model parameters to the clients. The " +"*clients* run the training and update the parameters. The updated " +"parameters are sent back to the *server*, which averages all received " +"parameter updates. This describes one round of the federated learning " +"process, and we repeat this for multiple rounds." +msgstr "" +"把现有工作联邦化的概念始终是相同的,也很容易理解。我们要启动一个*服务器*,然后对连接到*服务器*的*客户端*运行 " +":code:`jax_training.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后服务器对所有收到的参数进行平均聚合。以上的描述构成了一轮联邦学习,我们将重复进行多轮学习。" #: ../../source/example-jax-from-centralized-to-federated.rst:123 -#: ../../source/example-mxnet-walk-through.rst:204 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" -"Our example consists of one *server* and two *clients*. Let's set up :code:" -"`server.py` first. The *server* needs to import the Flower package :code:" -"`flwr`. Next, we use the :code:`start_server` function to start a server and " -"tell it to perform three rounds of federated learning." +"Our example consists of one *server* and two *clients*. Let's set up " +":code:`server.py` first. The *server* needs to import the Flower package " +":code:`flwr`. Next, we use the :code:`start_server` function to start a " +"server and tell it to perform three rounds of federated learning." msgstr "" -"我们的示例包括一个*服务器*和两个*客户端*。让我们先设置 :code:`server.py`。*服" -"务器*需要导入 Flower 软件包 :code:`flwr`。接下来,我们使用 :code:" -"`start_server` 函数启动服务器,并让它执行三轮联邦学习。" +"我们的示例包括一个*服务器*和两个*客户端*。让我们先设置 :code:`server.py`。*服务器*需要导入 Flower 软件包 " +":code:`flwr`。接下来,我们使用 :code:`start_server` 函数启动服务器,并让它执行三轮联邦学习。" #: ../../source/example-jax-from-centralized-to-federated.rst:133 -#: ../../source/example-mxnet-walk-through.rst:214 #: ../../source/example-pytorch-from-centralized-to-federated.rst:191 #: ../../source/tutorial-quickstart-jax.rst:139 msgid "We can already start the *server*:" @@ -2914,47 +2662,47 @@ msgstr "我们已经可以启动*服务器*了:" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build " -"upon the previously defined JAX training in :code:`jax_training.py`. Our " -"*client* needs to import :code:`flwr`, but also :code:`jax` and :code:" -"`jaxlib` to update the parameters on our JAX model:" +"Finally, we will define our *client* logic in :code:`client.py` and build" +" upon the previously defined JAX training in :code:`jax_training.py`. Our" +" *client* needs to import :code:`flwr`, but also :code:`jax` and " +":code:`jaxlib` to update the parameters on our JAX model:" msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" -"code:`jax_training.py` 中定义的 JAX 训练为基础。我们的 *client* 需要导入 :" -"code:`flwr`,还需要导入 :code:`jax` 和 :code:`jaxlib` 以更新 JAX 模型的参数:" +"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 " +":code:`jax_training.py` 中定义的 JAX 训练为基础。我们的 *client* 需要导入 " +":code:`flwr`,还需要导入 :code:`jax` 和 :code:`jaxlib` 以更新 JAX 模型的参数:" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of " -"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " -"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " -"call it :code:`FlowerClient`. :code:`NumPyClient` is slightly easier to " -"implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like JAX) because it avoids some of the boilerplate that " -"would otherwise be necessary. :code:`FlowerClient` needs to implement four " -"methods, two methods for getting/setting model parameters, one method for " -"training the model, and one method for testing the model:" -msgstr "" -"实现一个 Flower *client*基本上意味着去实现一个 :code:`flwr.client.Client` " -"或 :code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr." -"client.NumPyClient`,并将其命名为 :code:`FlowerClient`。如果使用具有良好 " -"NumPy 互操作性的框架(如 JAX),:code:`NumPyClient` 比 :code:`Client`更容易实" -"现,因为它避免了一些不必要的操作。:code:`FlowerClient` 需要实现四个方法,两个" -"用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" +"Implementing a Flower *client* basically means implementing a subclass of" +" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " +"Our implementation will be based on :code:`flwr.client.NumPyClient` and " +"we'll call it :code:`FlowerClient`. :code:`NumPyClient` is slightly " +"easier to implement than :code:`Client` if you use a framework with good " +"NumPy interoperability (like JAX) because it avoids some of the " +"boilerplate that would otherwise be necessary. :code:`FlowerClient` needs" +" to implement four methods, two methods for getting/setting model " +"parameters, one method for training the model, and one method for testing" +" the model:" +msgstr "" +"实现一个 Flower *client*基本上意味着去实现一个 :code:`flwr.client.Client` 或 " +":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " +":code:`flwr.client.NumPyClient`,并将其命名为 :code:`FlowerClient`。如果使用具有良好 " +"NumPy 互操作性的框架(如 JAX),:code:`NumPyClient` 比 " +":code:`Client`更容易实现,因为它避免了一些不必要的操作。:code:`FlowerClient` " +"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" #: ../../source/example-jax-from-centralized-to-federated.rst:161 -#: ../../source/example-mxnet-walk-through.rst:242 #: ../../source/tutorial-quickstart-jax.rst:167 msgid ":code:`set_parameters (optional)`" msgstr ":code:`set_parameters (可选)`" #: ../../source/example-jax-from-centralized-to-federated.rst:160 -#: ../../source/example-mxnet-walk-through.rst:241 #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" -"set the model parameters on the local model that are received from the server" +"set the model parameters on the local model that are received from the " +"server" msgstr "在本地模型上设置从服务器接收的模型参数" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2963,62 +2711,51 @@ msgid "transform parameters to NumPy :code:`ndarray`'s" msgstr "将参数转换为 NumPy :code:`ndarray`格式" #: ../../source/example-jax-from-centralized-to-federated.rst:162 -#: ../../source/example-mxnet-walk-through.rst:243 #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" -"loop over the list of model parameters received as NumPy :code:`ndarray`'s " -"(think list of neural network layers)" -msgstr "" -"循环遍历以 NumPy :code:`ndarray` 形式接收的模型参数列表(可以看作神经网络的列" -"表)" +"loop over the list of model parameters received as NumPy " +":code:`ndarray`'s (think list of neural network layers)" +msgstr "循环遍历以 NumPy :code:`ndarray` 形式接收的模型参数列表(可以看作神经网络的列表)" #: ../../source/example-jax-from-centralized-to-federated.rst:163 -#: ../../source/example-mxnet-walk-through.rst:244 #: ../../source/example-pytorch-from-centralized-to-federated.rst:221 #: ../../source/tutorial-quickstart-jax.rst:169 -#: ../../source/tutorial-quickstart-mxnet.rst:171 #: ../../source/tutorial-quickstart-pytorch.rst:155 -#: ../../source/tutorial-quickstart-scikitlearn.rst:108 +#: ../../source/tutorial-quickstart-scikitlearn.rst:118 msgid ":code:`get_parameters`" msgstr ":code:`get_parameters`" #: ../../source/example-jax-from-centralized-to-federated.rst:164 -#: ../../source/example-mxnet-walk-through.rst:245 #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" -"get the model parameters and return them as a list of NumPy :code:" -"`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" +"get the model parameters and return them as a list of NumPy " +":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" -"获取模型参数,并以 NumPy :code:`ndarray`的列表形式返回(这正是 :code:`flwr." -"client.NumPyClient`所匹配的格式)" +"获取模型参数,并以 NumPy :code:`ndarray`的列表形式返回(这正是 " +":code:`flwr.client.NumPyClient`所匹配的格式)" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 -#: ../../source/tutorial-quickstart-mxnet.rst:177 #: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 msgid ":code:`fit`" msgstr ":code:`fit`" #: ../../source/example-jax-from-centralized-to-federated.rst:166 #: ../../source/example-jax-from-centralized-to-federated.rst:170 -#: ../../source/example-mxnet-walk-through.rst:247 -#: ../../source/example-mxnet-walk-through.rst:251 #: ../../source/example-pytorch-from-centralized-to-federated.rst:224 #: ../../source/example-pytorch-from-centralized-to-federated.rst:228 #: ../../source/tutorial-quickstart-jax.rst:172 #: ../../source/tutorial-quickstart-jax.rst:176 msgid "" -"update the parameters of the local model with the parameters received from " -"the server" +"update the parameters of the local model with the parameters received " +"from the server" msgstr "用从服务器接收到的参数更新本地模型的参数" #: ../../source/example-jax-from-centralized-to-federated.rst:167 -#: ../../source/example-mxnet-walk-through.rst:248 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 msgid "train the model on the local training set" @@ -3030,17 +2767,14 @@ msgid "get the updated local model parameters and return them to the server" msgstr "获取更新后的本地模型参数并返回服务器" #: ../../source/example-jax-from-centralized-to-federated.rst:172 -#: ../../source/example-mxnet-walk-through.rst:253 #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 #: ../../source/tutorial-quickstart-jax.rst:178 -#: ../../source/tutorial-quickstart-mxnet.rst:180 #: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 msgid ":code:`evaluate`" msgstr ":code:`evaluate`" #: ../../source/example-jax-from-centralized-to-federated.rst:171 -#: ../../source/example-mxnet-walk-through.rst:252 #: ../../source/example-pytorch-from-centralized-to-federated.rst:229 #: ../../source/tutorial-quickstart-jax.rst:177 msgid "evaluate the updated model on the local test set" @@ -3054,28 +2788,28 @@ msgstr "向服务器返回本地损失值" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 msgid "" -"The challenging part is to transform the JAX model parameters from :code:" -"`DeviceArray` to :code:`NumPy ndarray` to make them compatible with " -"`NumPyClient`." +"The challenging part is to transform the JAX model parameters from " +":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" +" `NumPyClient`." msgstr "" -"具有挑战性的部分是将 JAX 模型参数从 :code:`DeviceArray` 转换为 :code:`NumPy " -"ndarray`,使其与 `NumPyClient` 兼容。" +"具有挑战性的部分是将 JAX 模型参数从 :code:`DeviceArray` 转换为 :code:`NumPy ndarray`,使其与 " +"`NumPyClient` 兼容。" #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " -"use of the functions :code:`train()` and :code:`evaluate()` previously " +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" +" use of the functions :code:`train()` and :code:`evaluate()` previously " "defined in :code:`jax_training.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type annotations " -"to give you a better understanding of the data types that get passed around." +"Flower through our :code:`NumPyClient` subclass which of our already " +"defined functions to call for training and evaluation. We included type " +"annotations to give you a better understanding of the data types that get" +" passed around." msgstr "" -"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前" -"在 :code:`jax_training.py` 中定义的函数 :code:`train()` 和 :code:" -"`evaluate()`。因此,我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 " -"Flower 在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好" -"地理解传递的数据类型。" +"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前在 " +":code:`jax_training.py` 中定义的函数 :code:`train()` 和 " +":code:`evaluate()`。因此,我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 Flower " +"在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" #: ../../source/example-jax-from-centralized-to-federated.rst:245 #: ../../source/tutorial-quickstart-jax.rst:251 @@ -3083,7 +2817,6 @@ msgid "Having defined the federation process, we can run it." msgstr "定义了联邦进程后,我们就可以运行它了。" #: ../../source/example-jax-from-centralized-to-federated.rst:268 -#: ../../source/example-mxnet-walk-through.rst:347 #: ../../source/example-pytorch-from-centralized-to-federated.rst:301 #: ../../source/tutorial-quickstart-jax.rst:274 msgid "And that's it. You can now open two additional terminal windows and run" @@ -3092,286 +2825,30 @@ msgstr "就是这样,现在你可以打开另外两个终端窗口,然后运 #: ../../source/example-jax-from-centralized-to-federated.rst:274 #: ../../source/tutorial-quickstart-jax.rst:280 msgid "" -"in each window (make sure that the server is still running before you do so) " -"and see your JAX project run federated learning across two clients. " +"in each window (make sure that the server is still running before you do " +"so) and see your JAX project run federated learning across two clients. " "Congratulations!" -msgstr "" -"确保服务器仍在运行,然后在每个客户端窗口就能看到你的 JAX 项目在两个客户端上运" -"行联邦学习了。祝贺!" +msgstr "确保服务器仍在运行,然后在每个客户端窗口就能看到你的 JAX 项目在两个客户端上运行联邦学习了。祝贺!" #: ../../source/example-jax-from-centralized-to-federated.rst:279 #: ../../source/tutorial-quickstart-jax.rst:285 msgid "" "The source code of this example was improved over time and can be found " -"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " +"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" -"此示例的源代码经过长期改进,可在此处找到: `Quickstart JAX `_。我们的示例有些过于简" -"单,因为两个客户端都加载了相同的数据集。" +"此示例的源代码经过长期改进,可在此处找到: `Quickstart JAX " +"`_。我们的示例有些过于简单,因为两个客户端都加载了相同的数据集。" #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 msgid "" -"You're now prepared to explore this topic further. How about using a more " -"sophisticated model or using a different dataset? How about adding more " +"You're now prepared to explore this topic further. How about using a more" +" sophisticated model or using a different dataset? How about adding more " "clients?" -msgstr "" -"现在,您已准备好进行更深一步探索了。例如使用更复杂的模型或使用不同的数据集会" -"如何?增加更多客户端会如何?" - -#: ../../source/example-mxnet-walk-through.rst:2 -msgid "Example: MXNet - Run MXNet Federated" -msgstr "示例: MXNet - 运行联邦式 MXNet" - -#: ../../source/example-mxnet-walk-through.rst:4 -msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing MXNet workload. We are using MXNet to train a Sequential " -"model on the MNIST dataset. We will structure the example similar to our " -"`PyTorch - From Centralized To Federated `_ walkthrough. " -"MXNet and PyTorch are very similar and a very good comparison between MXNet " -"and PyTorch is given `here `_. First, we " -"build a centralized training approach based on the `Handwritten Digit " -"Recognition `_ tutorial. Then, we build upon " -"the centralized training code to run the training in a federated fashion." -msgstr "" -"本教程将向您展示如何使用 Flower 构建现有 MXNet 的联学习版本。我们将使用 " -"MXNet 在 MNIST 数据集上训练一个序列模型。另外,我们将采用与我们的 `PyTorch - " -"从集中式到联邦式 `_ 教程类似的示例结构。MXNet 和 PyTorch 非常相" -"似,参考 `此处 `_对 MXNet 和 PyTorch 进行了" -"详细的比较。首先,我们根据 `手写数字识别 ` 教" -"程 建立了集中式训练方法。然后,我们在集中式训练代码的基础上,以联邦方式运行训" -"练。" - -#: ../../source/example-mxnet-walk-through.rst:10 -msgid "" -"Before we start setting up our MXNet example, we install the :code:`mxnet` " -"and :code:`flwr` packages:" -msgstr "" -"在开始设置 MXNet 示例之前,我们先安装 :code:`mxnet` 和 :code:`flwr` 软件包:" - -#: ../../source/example-mxnet-walk-through.rst:19 -msgid "MNIST Training with MXNet" -msgstr "使用 MXNet 进行 MNIST 训练" - -#: ../../source/example-mxnet-walk-through.rst:21 -msgid "" -"We begin with a brief description of the centralized training code based on " -"a :code:`Sequential` model. If you want a more in-depth explanation of " -"what's going on then have a look at the official `MXNet tutorial `_." -msgstr "" -"首先,我们将简要介绍基于 :code:`Sequential` 模型的集中式训练代码。如果您想获" -"得更深入的解释,请参阅官方的 `MXNet教程 `_。" - -#: ../../source/example-mxnet-walk-through.rst:24 -msgid "" -"Let's create a new file called:code:`mxnet_mnist.py` with all the components " -"required for a traditional (centralized) MNIST training. First, the MXNet " -"package :code:`mxnet` needs to be imported. You can see that we do not yet " -"import the :code:`flwr` package for federated learning. This will be done " -"later." -msgstr "" -"让我们创建一个名为:code:`mxnet_mnist.py`的新文件,其中包含传统(集中式)" -"MNIST 训练所需的所有组件。首先,需要导入 MXNet 包 :code:`mxnet`。您可以看到," -"我们尚未导入用于联合学习的 :code:`flwr` 包,这将在稍后完成。" - -#: ../../source/example-mxnet-walk-through.rst:42 -msgid "" -"The :code:`load_data()` function loads the MNIST training and test sets." -msgstr ":code:`load_data()` 函数加载 MNIST 训练集和测试集。" - -#: ../../source/example-mxnet-walk-through.rst:57 -msgid "" -"As already mentioned, we will use the MNIST dataset for this machine " -"learning workload. The model architecture (a very simple :code:`Sequential` " -"model) is defined in :code:`model()`." -msgstr "" -"如前所述,我们将使用 MNIST 数据集进行机器学习。模型架构(一个非常简单的 :" -"code:`Sequential` 模型)在 :code:`model()` 中定义。" - -#: ../../source/example-mxnet-walk-through.rst:70 -msgid "" -"We now need to define the training (function :code:`train()`) which loops " -"over the training set and measures the loss for each batch of training " -"examples." -msgstr "" -"现在,我们需要定义训练函数( :code:`train()`),该函数在训练集上循环训练,并" -"计算每批训练示例的损失值。" - -#: ../../source/example-mxnet-walk-through.rst:123 -msgid "" -"The evaluation of the model is defined in function :code:`test()`. The " -"function loops over all test samples and measures the loss and accuracy of " -"the model based on the test dataset." -msgstr "" -"模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并根据测" -"试数据集计算模型的损失值和准确度。" - -#: ../../source/example-mxnet-walk-through.rst:158 -msgid "" -"Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model on MNIST. Note " -"that the GPU/CPU device for the training and testing is defined within the :" -"code:`ctx` (context)." -msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以把所有放在一起,在 " -"MNIST 上训练我们的模型了。请注意,用于训练和测试的 GPU/CPU 设备是在 :code:" -"`ctx`中定义的。" - -#: ../../source/example-mxnet-walk-through.rst:184 -msgid "You can now run your (centralized) MXNet machine learning workload:" -msgstr "现在,您可以运行(集中式)MXNet 机器学习工作:" - -#: ../../source/example-mxnet-walk-through.rst:190 -msgid "" -"So far this should all look fairly familiar if you've used MXNet (or even " -"PyTorch) before. Let's take the next step and use what we've built to create " -"a simple federated learning system consisting of one server and two clients." -msgstr "" -"到目前为止,如果你以前使用过 MXNet(甚至 PyTorch),这一切看起来应该相当熟" -"悉。下一步,让我们利用已构建的内容创建一个简单联邦学习系统(由一个服务器和两" -"个客户端组成)。" - -#: ../../source/example-mxnet-walk-through.rst:194 -msgid "MXNet meets Flower" -msgstr "MXNet 结合 Flower" - -#: ../../source/example-mxnet-walk-through.rst:196 -msgid "" -"So far, it was not easily possible to use MXNet workloads for federated " -"learning because federated learning is not supported in MXNet. Since Flower " -"is fully agnostic towards the underlying machine learning framework, it can " -"be used to federated arbitrary machine learning workloads. This section will " -"show you how Flower can be used to federate our centralized MXNet workload." -msgstr "" -"由于 MXNet 目前不支持联邦学习,因此无法轻松地直接将 MXNet 用于联邦学习之中。" -"Flower 与底层机器学习框架完全无关,因此它可用于任意联邦式机器学习工作。本节将" -"向你展示如何使用 Flower 将我们的集中式 MXNet 改为联邦式训练。" - -#: ../../source/example-mxnet-walk-through.rst:198 -msgid "" -"The concept to federate an existing workload is always the same and easy to " -"understand. We have to start a *server* and then use the code in :code:" -"`mxnet_mnist.py` for the *clients* that are connected to the *server*. The " -"*server* sends model parameters to the clients. The *clients* run the " -"training and update the parameters. The updated parameters are sent back to " -"the *server* which averages all received parameter updates. This describes " -"one round of the federated learning process and we repeat this for multiple " -"rounds." -msgstr "" -"将现有模型框架联邦化的概念始终是相同的,也很容易理解。我们必须启动一个*服务器" -"*,然后对连接到*服务器*的*客户端*使用 :code:`mxnet_mnist.py`中的代码。*服务器" -"*向客户端发送模型参数,然后*客户端*运行训练并更新参数。更新后的参数被发回*服" -"务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程," -"我们将重复进行多轮学习。" - -#: ../../source/example-mxnet-walk-through.rst:220 -msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build " -"upon the previously defined MXNet training in :code:`mxnet_mnist.py`. Our " -"*client* needs to import :code:`flwr`, but also :code:`mxnet` to update the " -"parameters on our MXNet model:" -msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" -"code:`mxnet_mnist.py` 中定义的 MXNet 训练为基础。我们的 *client* 不仅需要导" -"入 :code:`flwr`,还需要导入 :code:`mxnet`,以更新 MXNet 模型的参数:" - -#: ../../source/example-mxnet-walk-through.rst:235 -msgid "" -"Implementing a Flower *client* basically means implementing a subclass of " -"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " -"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " -"call it :code:`MNISTClient`. :code:`NumPyClient` is slightly easier to " -"implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or MXNet) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`MNISTClient` needs to " -"implement four methods, two methods for getting/setting model parameters, " -"one method for training the model, and one method for testing the model:" -msgstr "" -"实现 Flower *client*基本上意味着要实现 :code:`flwr.client.Client` 或 :code:" -"`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr.client." -"NumPyClient`,并将其命名为 :code:`MNISTClient`。如果使用具有良好 NumPy 互操作" -"性的框架(如 PyTorch 或 MXNet),:code:`NumPyClient` 比 :code:`Client`更容易" -"实现,因为它避免了一些不必要的操作。:code:`MNISTClient` 需要实现四个方法,两" -"个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" - -#: ../../source/example-mxnet-walk-through.rst:242 -msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" -msgstr "将 MXNet :code:`NDArray` 转换为 NumPy :code:`ndarray`" - -#: ../../source/example-mxnet-walk-through.rst:249 -#: ../../source/example-pytorch-from-centralized-to-federated.rst:226 -msgid "get the updated local model weights and return them to the server" -msgstr "获取更新后的本地模型参数并发送回服务器" - -#: ../../source/example-mxnet-walk-through.rst:253 -#: ../../source/example-pytorch-from-centralized-to-federated.rst:230 -msgid "return the local loss and accuracy to the server" -msgstr "向服务器返回本地损失值和精确度" - -#: ../../source/example-mxnet-walk-through.rst:255 -msgid "" -"The challenging part is to transform the MXNet parameters from :code:" -"`NDArray` to :code:`NumPy Arrays` to make it readable for Flower." -msgstr "" -"具有挑战性的部分是将 MXNet 参数从 :code:`NDArray` 转换为 :code:`NumPy " -"Arrays` 以便 Flower 可以读取。" - -#: ../../source/example-mxnet-walk-through.rst:257 -msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " -"use of the functions :code:`train()` and :code:`test()` previously defined " -"in :code:`mxnet_mnist.py`. So what we really do here is we tell Flower " -"through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type annotations " -"to give you a better understanding of the data types that get passed around." -msgstr "" -"这两个 :code:`NumPyClient` 方法 :code:`fit` 和 :code:`evaluate` 使用了之前" -"在 :code:`mxnet_mnist.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因" -"此,我们要做的就是通过 :code:`NumPyClient` 子类告知 Flower 在训练和评估时要调" -"用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" - -#: ../../source/example-mxnet-walk-through.rst:319 -msgid "" -"Having defined data loading, model architecture, training, and evaluation we " -"can put everything together and train our :code:`Sequential` model on MNIST." -msgstr "" -"在定义了数据加载、模型架构、训练和评估之后,我们就可以将所有内容整合在一起," -"在 MNIST 上训练我们的 :code:`Sequential` 模型。" - -#: ../../source/example-mxnet-walk-through.rst:353 -msgid "" -"in each window (make sure that the server is still running before you do so) " -"and see your MXNet project run federated learning across two clients. " -"Congratulations!" -msgstr "" -"确保服务器仍在运行后,然后就能在每个窗口中看到 MXNet 项目在两个客户端上运行联" -"邦学习了。祝贺!" - -#: ../../source/example-mxnet-walk-through.rst:358 -msgid "" -"The full source code for this example: `MXNet: From Centralized To Federated " -"(Code) `_. Our example is of course somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using a CNN or using a different dataset? How about adding more clients?" -msgstr "" -"此示例的完整源代码在:\"MXNet: From Centralized To Federated (Code) " -"`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的" -"数据集,这并不真实。现在您已经准备好进一步探讨了。使用 CNN 或使用不同的数据集" -"会如何?添加更多客户端会如何?" +msgstr "现在,您已准备好进行更深一步探索了。例如使用更复杂的模型或使用不同的数据集会如何?增加更多客户端会如何?" #: ../../source/example-pytorch-from-centralized-to-federated.rst:2 msgid "Example: PyTorch - From Centralized To Federated" @@ -3379,44 +2856,41 @@ msgstr "实例: PyTorch - 从集中式到联邦式" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing machine learning workload. We are using PyTorch to train a " -"Convolutional Neural Network on the CIFAR-10 dataset. First, we introduce " -"this machine learning task with a centralized training approach based on the " -"`Deep Learning with PyTorch `_ tutorial. Then, we build upon the centralized " -"training code to run the training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated " +"version of an existing machine learning workload. We are using PyTorch to" +" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " +"introduce this machine learning task with a centralized training approach" +" based on the `Deep Learning with PyTorch " +"`_ " +"tutorial. Then, we build upon the centralized training code to run the " +"training in a federated fashion." msgstr "" -"本教程将向您展示如何使用 Flower 构建现有机器学习工作的联邦版本。我们使用 " -"PyTorch 在 CIFAR-10 数据集上训练一个卷积神经网络。首先,我们基于 \"Deep " -"Learning with PyTorch `_\"教程,采用集中式训练方法介绍了这项机器学习任务。然" -"后,我们在集中式训练代码的基础上以联邦方式运行训练。" +"本教程将向您展示如何使用 Flower 构建现有机器学习工作的联邦版本。我们使用 PyTorch 在 CIFAR-10 " +"数据集上训练一个卷积神经网络。首先,我们基于 \"Deep Learning with PyTorch " +"`_\"教程,采用集中式训练方法介绍了这项机器学习任务。然后,我们在集中式训练代码的基础上以联邦方式运行训练。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"We begin with a brief description of the centralized CNN training code. If " -"you want a more in-depth explanation of what's going on then have a look at " -"the official `PyTorch tutorial `_." +"We begin with a brief description of the centralized CNN training code. " +"If you want a more in-depth explanation of what's going on then have a " +"look at the official `PyTorch tutorial " +"`_." msgstr "" -"我们首先简要介绍一下集中式 CNN 训练代码。如果您想获得更深入的解释,请参阅 " -"PyTorch 官方教程`PyTorch tutorial `_。" +"我们首先简要介绍一下集中式 CNN 训练代码。如果您想获得更深入的解释,请参阅 PyTorch 官方教程`PyTorch tutorial " +"`_。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" "Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all " -"required packages (such as :code:`torch` and :code:`torchvision`) need to be " -"imported. You can see that we do not import any package for federated " -"learning. You can keep all these imports as they are even when we add the " -"federated learning components at a later point." +"required for a traditional (centralized) training on CIFAR-10. First, all" +" required packages (such as :code:`torch` and :code:`torchvision`) need " +"to be imported. You can see that we do not import any package for " +"federated learning. You can keep all these imports as they are even when " +"we add the federated learning components at a later point." msgstr "" -"让我们创建一个名为 :code:`cifar.py` 的新文件,其中包含 CIFAR-10 传统(集中)" -"培训所需的所有组件。首先,需要导入所有必需的软件包(如 :code:`torch` 和 :" -"code:`torchvision`)。您可以看到,我们没有导入任何用于联邦学习的软件包。即使" -"在以后添加联邦学习组件时,也可以保留所有这些导入。" +"让我们创建一个名为 :code:`cifar.py` 的新文件,其中包含 CIFAR-10 " +"传统(集中)培训所需的所有组件。首先,需要导入所有必需的软件包(如 :code:`torch` 和 " +":code:`torchvision`)。您可以看到,我们没有导入任何用于联邦学习的软件包。即使在以后添加联邦学习组件时,也可以保留所有这些导入。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" @@ -3424,178 +2898,166 @@ msgid "" "learning workload. The model architecture (a very simple Convolutional " "Neural Network) is defined in :code:`class Net()`." msgstr "" -"如前所述,我们将使用 CIFAR-10 数据集进行机器学习。模型架构(一个非常简单的卷" -"积神经网络)在 :code:`class Net()` 中定义。" +"如前所述,我们将使用 CIFAR-10 数据集进行机器学习。模型架构(一个非常简单的卷积神经网络)在 :code:`class Net()` " +"中定义。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test sets. " -"The :code:`transform` normalized the data after loading." +"The :code:`load_data()` function loads the CIFAR-10 training and test " +"sets. The :code:`transform` normalized the data after loading." msgstr "" -":code:`load_data()` 函数加载 CIFAR-10 训练集和测试集。加载数据后,:code:" -"`transform`函数对数据进行了归一化处理。" +":code:`load_data()` 函数加载 CIFAR-10 " +"训练集和测试集。加载数据后,:code:`transform`函数对数据进行了归一化处理。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" -"We now need to define the training (function :code:`train()`) which loops " -"over the training set, measures the loss, backpropagates it, and then takes " -"one optimizer step for each batch of training examples." -msgstr "" -"现在,我们需要定义训练函数(:code:`train()`),该函数在训练集上循环训练,计算" -"损失值并反向传播,然后为每批训练数据在优化器上执行一个优化步骤。" +"We now need to define the training (function :code:`train()`) which loops" +" over the training set, measures the loss, backpropagates it, and then " +"takes one optimizer step for each batch of training examples." +msgstr "现在,我们需要定义训练函数(:code:`train()`),该函数在训练集上循环训练,计算损失值并反向传播,然后为每批训练数据在优化器上执行一个优化步骤。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in the function :code:`test()`. The " -"function loops over all test samples and measures the loss of the model " -"based on the test dataset." -msgstr "" -"模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并计算测" -"试数据集的模型损失值。" +"The evaluation of the model is defined in the function :code:`test()`. " +"The function loops over all test samples and measures the loss of the " +"model based on the test dataset." +msgstr "模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并计算测试数据集的模型损失值。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " "evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "" -"在确定了数据加载、模型架构、训练和评估之后,我们就可以将所有整合在一起,在 " -"CIFAR-10 上训练我们的 CNN。" +msgstr "在确定了数据加载、模型架构、训练和评估之后,我们就可以将所有整合在一起,在 CIFAR-10 上训练我们的 CNN。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far, this should all look fairly familiar if you've used PyTorch before. " -"Let's take the next step and use what we've built to create a simple " -"federated learning system consisting of one server and two clients." +"So far, this should all look fairly familiar if you've used PyTorch " +"before. Let's take the next step and use what we've built to create a " +"simple federated learning system consisting of one server and two " +"clients." msgstr "" -"到目前为止,如果你以前用过 PyTorch,这一切看起来应该相当熟悉。让我们进行下一" -"步,利用我们所构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组" -"成)。" +"到目前为止,如果你以前用过 " +"PyTorch,这一切看起来应该相当熟悉。让我们进行下一步,利用我们所构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组成)。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" -"The simple machine learning project discussed in the previous section trains " -"the model on a single dataset (CIFAR-10), we call this centralized learning. " -"This concept of centralized learning, as shown in the previous section, is " -"probably known to most of you, and many of you have used it previously. " -"Normally, if you'd want to run machine learning workloads in a federated " -"fashion, then you'd have to change most of your code and set everything up " -"from scratch. This can be a considerable effort." -msgstr "" -"上一节讨论的简单机器学习项目在单一数据集(CIFAR-10)上训练模型,我们称之为集" -"中学习。如上一节所示,集中学习的概念可能为大多数人所熟知,而且很多人以前都使" -"用过。通常情况下,如果要以联邦方式运行机器学习工作,就必须更改大部分代码,并" -"从头开始设置一切。这可能是一个相当大的工作量。" +"The simple machine learning project discussed in the previous section " +"trains the model on a single dataset (CIFAR-10), we call this centralized" +" learning. This concept of centralized learning, as shown in the previous" +" section, is probably known to most of you, and many of you have used it " +"previously. Normally, if you'd want to run machine learning workloads in " +"a federated fashion, then you'd have to change most of your code and set " +"everything up from scratch. This can be a considerable effort." +msgstr "上一节讨论的简单机器学习项目在单一数据集(CIFAR-10)上训练模型,我们称之为集中学习。如上一节所示,集中学习的概念可能为大多数人所熟知,而且很多人以前都使用过。通常情况下,如果要以联邦方式运行机器学习工作,就必须更改大部分代码,并从头开始设置一切。这可能是一个相当大的工作量。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"However, with Flower you can evolve your pre-existing code into a federated " -"learning setup without the need for a major rewrite." -msgstr "" -"不过,有了 Flower,您可以轻松地将已有的代码转变成联邦学习的模式,无需进行大量" -"重写。" +"However, with Flower you can evolve your pre-existing code into a " +"federated learning setup without the need for a major rewrite." +msgstr "不过,有了 Flower,您可以轻松地将已有的代码转变成联邦学习的模式,无需进行大量重写。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept is easy to understand. We have to start a *server* and then use " -"the code in :code:`cifar.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The *clients* " -"run the training and update the parameters. The updated parameters are sent " -"back to the *server* which averages all received parameter updates. This " -"describes one round of the federated learning process and we repeat this for " -"multiple rounds." +"The concept is easy to understand. We have to start a *server* and then " +"use the code in :code:`cifar.py` for the *clients* that are connected to " +"the *server*. The *server* sends model parameters to the clients. The " +"*clients* run the training and update the parameters. The updated " +"parameters are sent back to the *server* which averages all received " +"parameter updates. This describes one round of the federated learning " +"process and we repeat this for multiple rounds." msgstr "" -"这个概念很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*" -"使用 :code:`cifar.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练" -"并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚" -"合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" +"这个概念很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*使用 " +":code:`cifar.py`中的代码。*服务器*向客户端发送模型参数,*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build " -"upon the previously defined centralized training in :code:`cifar.py`. Our " -"*client* needs to import :code:`flwr`, but also :code:`torch` to update the " -"parameters on our PyTorch model:" +"Finally, we will define our *client* logic in :code:`client.py` and build" +" upon the previously defined centralized training in :code:`cifar.py`. " +"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " +"update the parameters on our PyTorch model:" msgstr "" -"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :" -"code:`cifar.py` 中定义的集中式训练为基础。我们的 *client* 不仅需要导入 :code:" -"`flwr`,还需要导入 :code:`torch`,以更新 PyTorch 模型的参数:" +"最后,我们将在 :code:`client.py` 中定义我们的 *client* 逻辑,并以之前在 :code:`cifar.py` " +"中定义的集中式训练为基础。我们的 *client* 不仅需要导入 :code:`flwr`,还需要导入 :code:`torch`,以更新 " +"PyTorch 模型的参数:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of " -"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " -"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " -"call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier to " -"implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids some " -"of the boilerplate that would otherwise be necessary. :code:`CifarClient` " -"needs to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing " -"the model:" -msgstr "" -"实现 Flower *client*基本上意味着实现 :code:`flwr.client.Client` 或 :code:" -"`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 :code:`flwr.client." -"NumPyClient`,并将其命名为 :code:`CifarClient`。如果使用具有良好 NumPy 互操作" -"性的框架(如 PyTorch 或 TensorFlow/Keras),:code:`NumPyClient`的实现比 :" -"code:`Client`略微容易一些,因为它避免了一些不必要的操作。:code:`CifarClient` " -"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模" -"型:" +"Implementing a Flower *client* basically means implementing a subclass of" +" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " +"Our implementation will be based on :code:`flwr.client.NumPyClient` and " +"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" +" to implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " +"some of the boilerplate that would otherwise be necessary. " +":code:`CifarClient` needs to implement four methods, two methods for " +"getting/setting model parameters, one method for training the model, and " +"one method for testing the model:" +msgstr "" +"实现 Flower *client*基本上意味着实现 :code:`flwr.client.Client` 或 " +":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " +":code:`flwr.client.NumPyClient`,并将其命名为 :code:`CifarClient`。如果使用具有良好 NumPy" +" 互操作性的框架(如 PyTorch 或 TensorFlow/Keras),:code:`NumPyClient`的实现比 " +":code:`Client`略微容易一些,因为它避免了一些不必要的操作。:code:`CifarClient` " +"需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 msgid ":code:`set_parameters`" msgstr ":code:`set_parameters`" +#: ../../source/example-pytorch-from-centralized-to-federated.rst:226 +msgid "get the updated local model weights and return them to the server" +msgstr "获取更新后的本地模型参数并发送回服务器" + +#: ../../source/example-pytorch-from-centralized-to-federated.rst:230 +msgid "return the local loss and accuracy to the server" +msgstr "向服务器返回本地损失值和精确度" + #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " -"use of the functions :code:`train()` and :code:`test()` previously defined " -"in :code:`cifar.py`. So what we really do here is we tell Flower through " -"our :code:`NumPyClient` subclass which of our already defined functions to " -"call for training and evaluation. We included type annotations to give you a " -"better understanding of the data types that get passed around." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" +" use of the functions :code:`train()` and :code:`test()` previously " +"defined in :code:`cifar.py`. So what we really do here is we tell Flower " +"through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type " +"annotations to give you a better understanding of the data types that get" +" passed around." msgstr "" -"这两个 :code:`NumPyClient` 中的方法 :code:`fit` 和 :code:`evaluate` 使用了之" -"前在 :code:`cifar.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因此," -"我们在这里要做的就是通过 :code:`NumPyClient` 子类告知 Flower 在训练和评估时要" -"调用哪些已定义的函数。我们加入了类型注解,以便让你更好地理解传递的数据类型。" +"这两个 :code:`NumPyClient` 中的方法 :code:`fit` 和 :code:`evaluate` 使用了之前在 " +":code:`cifar.py` 中定义的函数 :code:`train()` 和 :code:`test()`。因此,我们在这里要做的就是通过 " +":code:`NumPyClient` 子类告知 Flower " +"在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让你更好地理解传递的数据类型。" #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" "All that's left to do it to define a function that loads both model and " -"data, creates a :code:`CifarClient`, and starts this client. You load your " -"data and model by using :code:`cifar.py`. Start :code:`CifarClient` with the " -"function :code:`fl.client.start_client()` by pointing it at the same IP " -"address we used in :code:`server.py`:" -msgstr "" -"剩下的就是定义模型和数据加载函数了。创建一个:code:`CifarClient`类,并运行这个" -"客服端。您将通过:code:`cifar.py`加载数据和模型。另外,通过:code:`fl.client." -"start_client()`函数来运行客户端:code:`CifarClient`,需要保证IP地址和:code:" -"`server.py`中所使用的一致:" +"data, creates a :code:`CifarClient`, and starts this client. You load " +"your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " +"with the function :code:`fl.client.start_client()` by pointing it at the " +"same IP address we used in :code:`server.py`:" +msgstr "剩下的就是定义模型和数据加载函数了。创建一个:code:`CifarClient`类,并运行这个客服端。您将通过:code:`cifar.py`加载数据和模型。另外,通过:code:`fl.client.start_client()`函数来运行客户端:code:`CifarClient`,需要保证IP地址和:code:`server.py`中所使用的一致:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" -"in each window (make sure that the server is running before you do so) and " -"see your (previously centralized) PyTorch project run federated learning " -"across two clients. Congratulations!" -msgstr "" -"确保服务器正在运行后,您就能看到您的 PyTorch 项目(之前是集中式的)在两个客户" -"端上运行联邦学习了。祝贺!" +"in each window (make sure that the server is running before you do so) " +"and see your (previously centralized) PyTorch project run federated " +"learning across two clients. Congratulations!" +msgstr "确保服务器正在运行后,您就能看到您的 PyTorch 项目(之前是集中式的)在两个客户端上运行联邦学习了。祝贺!" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" "The full source code for this example: `PyTorch: From Centralized To " -"Federated (Code) `_. Our example is, of course, somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using different subsets of CIFAR-10 on each client? How about adding more " -"clients?" -msgstr "" -"本示例的完整源代码为:`PyTorch: 从集中式到联合式 `_。当然,我" -"们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现" -"在,您已经准备好进一步探讨这一主题了。比如在每个客户端使用不同的 CIFAR-10 子" -"集会如何?增加更多客户端会如何?" +"Federated (Code) `_. Our example is, of course, " +"somewhat over-simplified because both clients load the exact same " +"dataset, which isn't realistic. You're now prepared to explore this topic" +" further. How about using different subsets of CIFAR-10 on each client? " +"How about adding more clients?" +msgstr "" +"本示例的完整源代码为:`PyTorch: 从集中式到联合式 " +"`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现在,您已经准备好进一步探讨这一主题了。比如在每个客户端使用不同的" +" CIFAR-10 子集会如何?增加更多客户端会如何?" #: ../../source/explanation-differential-privacy.rst:2 #: ../../source/explanation-differential-privacy.rst:11 @@ -3606,24 +3068,21 @@ msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:3 #, fuzzy msgid "" -"The information in datasets like healthcare, financial transactions, user " -"preferences, etc., is valuable and has the potential for scientific " -"breakthroughs and provides important business insights. However, such data " -"is also sensitive and there is a risk of compromising individual privacy." -msgstr "" -"医疗保健、金融交易、用户偏好等数据集中的信息非常宝贵,有可能带来科学突破并提" -"供重要的商业见解。然而,这些数据也是敏感数据,存在泄露个人隐私的风险。" +"The information in datasets like healthcare, financial transactions, user" +" preferences, etc., is valuable and has the potential for scientific " +"breakthroughs and provides important business insights. However, such " +"data is also sensitive and there is a risk of compromising individual " +"privacy." +msgstr "医疗保健、金融交易、用户偏好等数据集中的信息非常宝贵,有可能带来科学突破并提供重要的商业见解。然而,这些数据也是敏感数据,存在泄露个人隐私的风险。" #: ../../source/explanation-differential-privacy.rst:6 #, fuzzy msgid "" "Traditional methods like anonymization alone would not work because of " -"attacks like Re-identification and Data Linkage. That's where differential " -"privacy comes in. It provides the possibility of analyzing data while " -"ensuring the privacy of individuals." -msgstr "" -"单靠匿名等传统方法是行不通的,因为会受到重新识别和数据链接等攻击。这就是差异" -"化隐私的用武之地。它提供了在分析数据的同时确保个人隐私的可能性。" +"attacks like Re-identification and Data Linkage. That's where " +"differential privacy comes in. It provides the possibility of analyzing " +"data while ensuring the privacy of individuals." +msgstr "单靠匿名等传统方法是行不通的,因为会受到重新识别和数据链接等攻击。这就是差异化隐私的用武之地。它提供了在分析数据的同时确保个人隐私的可能性。" #: ../../source/explanation-differential-privacy.rst:12 #, fuzzy @@ -3632,13 +3091,12 @@ msgid "" "instance, Alice's data). Differential Privacy (DP) guarantees that any " "analysis (M), like calculating the average income, will produce nearly " "identical results for both datasets (O and O' would be similar). This " -"preserves group patterns while obscuring individual details, ensuring the " -"individual's information remains hidden in the crowd." +"preserves group patterns while obscuring individual details, ensuring the" +" individual's information remains hidden in the crowd." msgstr "" -"试想一下,两个数据集除了一条记录(例如 Alice 的数据)之外完全相同。差分隐私" -"(DP)可以保证任何分析(M),比如计算平均收入,对两个数据集都会产生几乎相同的" -"结果(O 和 O' 将是相似的)。这既保留了群体模式,又掩盖了个人细节,确保个人的" -"信息隐藏在人群中。" +"试想一下,两个数据集除了一条记录(例如 Alice " +"的数据)之外完全相同。差分隐私(DP)可以保证任何分析(M),比如计算平均收入,对两个数据集都会产生几乎相同的结果(O 和 O' " +"将是相似的)。这既保留了群体模式,又掩盖了个人细节,确保个人的信息隐藏在人群中。" #: ../../source/explanation-differential-privacy.rst:-1 #, fuzzy @@ -3650,10 +3108,9 @@ msgstr "DP 介绍" msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " -"individual in the data while preserving the overall accuracy of the analysis." -msgstr "" -"实现 DP 的最常用机制之一是在分析输出中加入足够的噪音,以掩盖数据中每个个体的" -"贡献,同时保持分析的整体准确性。" +"individual in the data while preserving the overall accuracy of the " +"analysis." +msgstr "实现 DP 的最常用机制之一是在分析输出中加入足够的噪音,以掩盖数据中每个个体的贡献,同时保持分析的整体准确性。" #: ../../source/explanation-differential-privacy.rst:25 #, fuzzy @@ -3665,18 +3122,17 @@ msgstr "编译 ProtoBuf 定义" msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " -"algorithm. It provides an unconditional upper bound on the influence of a " -"single individual on the output of the algorithm by adding noise [1]. A " -"randomized mechanism M provides (:math:`\\epsilon`, :math:`\\delta`)-" -"differential privacy if for any two neighboring databases, D :sub:`1` and D :" -"sub:`2`, that differ in only a single record, and for all possible outputs S " -"⊆ Range(A):" -msgstr "" -"差分隐私(Differential Privacy,DP)针对对手通过随机算法的输出所能推断出的信" -"息提供统计保证。它为单个个体通过添加噪声对算法输出的影响提供了一个无条件的上" -"限[1]。如果任意两个相邻的数据库D :sub:`1`和D :sub:`2`只有一条记录不同,并且对" -"于所有可能的输出S ⊆ Range(A),随机化机制M提供(:math:`epsilon`,:math:" -"`\\delta`)差异隐私:" +"algorithm. It provides an unconditional upper bound on the influence of a" +" single individual on the output of the algorithm by adding noise [1]. A " +"randomized mechanism M provides (:math:`\\epsilon`, " +":math:`\\delta`)-differential privacy if for any two neighboring " +"databases, D :sub:`1` and D :sub:`2`, that differ in only a single " +"record, and for all possible outputs S ⊆ Range(A):" +msgstr "" +"差分隐私(Differential " +"Privacy,DP)针对对手通过随机算法的输出所能推断出的信息提供统计保证。它为单个个体通过添加噪声对算法输出的影响提供了一个无条件的上限[1]。如果任意两个相邻的数据库D" +" :sub:`1`和D :sub:`2`只有一条记录不同,并且对于所有可能的输出S ⊆ " +"Range(A),随机化机制M提供(:math:`epsilon`,:math:`\\delta`)差异隐私:" #: ../../source/explanation-differential-privacy.rst:32 #, fuzzy @@ -3693,16 +3149,14 @@ msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " "lower :math:`\\epsilon` values indicate higher levels of privacy but are " -"likely to reduce utility as well. The :math:`\\delta` parameter accounts for " -"a small probability on which the upper bound :math:`\\epsilon` does not " -"hold. The amount of noise needed to achieve differential privacy is " -"proportional to the sensitivity of the output, which measures the maximum " -"change in the output due to the inclusion or removal of a single record." +"likely to reduce utility as well. The :math:`\\delta` parameter accounts " +"for a small probability on which the upper bound :math:`\\epsilon` does " +"not hold. The amount of noise needed to achieve differential privacy is " +"proportional to the sensitivity of the output, which measures the maximum" +" change in the output due to the inclusion or removal of a single record." msgstr "" -":math:`\\epsilon`参数也称为隐私预算,是衡量隐私损失的指标。较低的 :math:" -"`\\epsilon` 值表示较高的隐私级别,但也可能降低效用。:math:`\\delta`参数考虑" -"了:math:`\\epsilon`上限不成立的小概率。实现差异化隐私所需的噪声量与输出的灵敏" -"度成正比,而输出的灵敏度是指由于包含或删除一条记录而导致的输出的最大变化。" +":math:`\\epsilon`参数也称为隐私预算,是衡量隐私损失的指标。较低的 :math:`\\epsilon` " +"值表示较高的隐私级别,但也可能降低效用。:math:`\\delta`参数考虑了:math:`\\epsilon`上限不成立的小概率。实现差异化隐私所需的噪声量与输出的灵敏度成正比,而输出的灵敏度是指由于包含或删除一条记录而导致的输出的最大变化。" #: ../../source/explanation-differential-privacy.rst:45 #, fuzzy @@ -3714,20 +3168,20 @@ msgstr "差分隐私" msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " -"designed in a way to prevent the algorithm to learn any specific information " -"about any individual data points and subsequently prevent the model from " -"revealing sensitive information. Depending on the stage at which noise is " -"introduced, various methods exist for applying DP to machine learning " -"algorithms. One approach involves adding noise to the training data (either " -"to the features or labels), while another method entails injecting noise " -"into the gradients of the loss function during model training. Additionally, " -"such noise can be incorporated into the model's output." -msgstr "" -"机器学习中可以利用 DP 来保护训练数据的隐私。差分保密机器学习算法的设计方式是" -"防止算法学习到任何单个数据点的任何特定信息,从而防止模型泄露敏感信息。根据引" -"入噪声的阶段,有多种方法可将 DP 应用于机器学习算法。一种方法是在训练数据(特" -"征或标签)中添加噪声,另一种方法是在模型训练过程中向损失函数的梯度注入噪声。" -"此外,这种噪声还可以被纳入模型的输出中。" +"designed in a way to prevent the algorithm to learn any specific " +"information about any individual data points and subsequently prevent the" +" model from revealing sensitive information. Depending on the stage at " +"which noise is introduced, various methods exist for applying DP to " +"machine learning algorithms. One approach involves adding noise to the " +"training data (either to the features or labels), while another method " +"entails injecting noise into the gradients of the loss function during " +"model training. Additionally, such noise can be incorporated into the " +"model's output." +msgstr "" +"机器学习中可以利用 DP " +"来保护训练数据的隐私。差分保密机器学习算法的设计方式是防止算法学习到任何单个数据点的任何特定信息,从而防止模型泄露敏感信息。根据引入噪声的阶段,有多种方法可将" +" DP " +"应用于机器学习算法。一种方法是在训练数据(特征或标签)中添加噪声,另一种方法是在模型训练过程中向损失函数的梯度注入噪声。此外,这种噪声还可以被纳入模型的输出中。" #: ../../source/explanation-differential-privacy.rst:53 #, fuzzy @@ -3740,56 +3194,47 @@ msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " "However, federated learning also introduces new privacy challenges. The " -"model updates between parties and the central server can leak information " -"about the local data. These leaks can be exploited by attacks such as " +"model updates between parties and the central server can leak information" +" about the local data. These leaks can be exploited by attacks such as " "membership inference and property inference attacks, or model inversion " "attacks." -msgstr "" -"联合学习是一种数据最小化方法,允许多方在不共享原始数据的情况下合作训练一个模" -"型。然而,联合学习也带来了新的隐私挑战。各方与中央服务器之间的模型更新可能会" -"泄露本地数据信息。这些泄漏信息可能会被攻击利用,如成员推断攻击、属性推断攻击" -"或模型反转攻击。" +msgstr "联合学习是一种数据最小化方法,允许多方在不共享原始数据的情况下合作训练一个模型。然而,联合学习也带来了新的隐私挑战。各方与中央服务器之间的模型更新可能会泄露本地数据信息。这些泄漏信息可能会被攻击利用,如成员推断攻击、属性推断攻击或模型反转攻击。" #: ../../source/explanation-differential-privacy.rst:58 #, fuzzy msgid "" -"DP can play a crucial role in federated learning to provide privacy for the " -"clients' data." +"DP can play a crucial role in federated learning to provide privacy for " +"the clients' data." msgstr "DP 可以在联合学习中发挥重要作用,为客户数据提供隐私保护。" #: ../../source/explanation-differential-privacy.rst:60 #, fuzzy msgid "" -"Depending on the granularity of privacy provision or the location of noise " -"addition, different forms of DP exist in federated learning. In this " -"explainer, we focus on two approaches of DP utilization in federated " -"learning based on where the noise is added: at the server (also known as the " -"center) or at the client (also known as the local)." +"Depending on the granularity of privacy provision or the location of " +"noise addition, different forms of DP exist in federated learning. In " +"this explainer, we focus on two approaches of DP utilization in federated" +" learning based on where the noise is added: at the server (also known as" +" the center) or at the client (also known as the local)." msgstr "" -"根据提供隐私的粒度或添加噪声的位置,联合学习中存在不同形式的 DP。在本说明中," -"我们将根据添加噪声的位置,重点介绍联合学习中利用 DP 的两种方法:在服务器(也" -"称为中心)或客户端(也称为本地)。" +"根据提供隐私的粒度或添加噪声的位置,联合学习中存在不同形式的 DP。在本说明中,我们将根据添加噪声的位置,重点介绍联合学习中利用 DP " +"的两种方法:在服务器(也称为中心)或客户端(也称为本地)。" #: ../../source/explanation-differential-privacy.rst:63 #, fuzzy msgid "" -"**Central Differential Privacy**: DP is applied by the server and the goal " -"is to prevent the aggregated model from leaking information about each " -"client's data." -msgstr "" -"**中央差分隐私**: DP 由服务器应用,目标是防止聚合模型泄露每个客户的数据信" -"息。" +"**Central Differential Privacy**: DP is applied by the server and the " +"goal is to prevent the aggregated model from leaking information about " +"each client's data." +msgstr "**中央差分隐私**: DP 由服务器应用,目标是防止聚合模型泄露每个客户的数据信息。" #: ../../source/explanation-differential-privacy.rst:65 #, fuzzy msgid "" "**Local Differential Privacy**: DP is applied on the client side before " -"sending any information to the server and the goal is to prevent the updates " -"that are sent to the server from leaking any information about the client's " -"data." -msgstr "" -"**本地差分隐私**: 在向服务器发送任何信息之前,在客户端应用 DP,目的是防止向" -"服务器发送的更新泄露任何有关客户端数据的信息。" +"sending any information to the server and the goal is to prevent the " +"updates that are sent to the server from leaking any information about " +"the client's data." +msgstr "**本地差分隐私**: 在向服务器发送任何信息之前,在客户端应用 DP,目的是防止向服务器发送的更新泄露任何有关客户端数据的信息。" #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:68 @@ -3801,34 +3246,28 @@ msgstr "差分隐私" #: ../../source/explanation-differential-privacy.rst:69 #, fuzzy msgid "" -"In this approach, which is also known as user-level DP, the central server " -"is responsible for adding noise to the globally aggregated parameters. It " -"should be noted that trust in the server is required." -msgstr "" -"在这种方法(也称为用户级 DP)中,中央服务器负责在全局汇总参数中添加噪声。需要" -"注意的是,这需要对服务器的信任。" +"In this approach, which is also known as user-level DP, the central " +"server is responsible for adding noise to the globally aggregated " +"parameters. It should be noted that trust in the server is required." +msgstr "在这种方法(也称为用户级 DP)中,中央服务器负责在全局汇总参数中添加噪声。需要注意的是,这需要对服务器的信任。" #: ../../source/explanation-differential-privacy.rst:76 #, fuzzy msgid "" -"While there are various ways to implement central DP in federated learning, " -"we concentrate on the algorithms proposed by [2] and [3]. The overall " -"approach is to clip the model updates sent by the clients and add some " -"amount of noise to the aggregated model. In each iteration, a random set of " -"clients is chosen with a specific probability for training. Each client " -"performs local training on its own data. The update of each client is then " -"clipped by some value `S` (sensitivity `S`). This would limit the impact of " -"any individual client which is crucial for privacy and often beneficial for " -"robustness. A common approach to achieve this is by restricting the `L2` " -"norm of the clients' model updates, ensuring that larger updates are scaled " -"down to fit within the norm `S`." -msgstr "" -"虽然在联合学习中实现中央数据处理的方法有很多种,但我们将重点放在[2]和[3]提出" -"的算法上。总体方法是剪辑客户端发送的模型更新,并在聚合模型中添加一定量的噪" -"声。在每次迭代中,以特定概率随机选择一组客户端进行训练。每个客户端对自己的数" -"据进行局部训练。然后,每个客户端的更新会被某个值`S`(灵敏度`S`)剪切。这将限" -"制任何单个客户端的影响,这对隐私至关重要,通常也有利于稳健性。实现这一点的常" -"用方法是限制客户机模型更新的 `L2` 准则,确保较大的更新被缩减以适应 `S` 准则。" +"While there are various ways to implement central DP in federated " +"learning, we concentrate on the algorithms proposed by [2] and [3]. The " +"overall approach is to clip the model updates sent by the clients and add" +" some amount of noise to the aggregated model. In each iteration, a " +"random set of clients is chosen with a specific probability for training." +" Each client performs local training on its own data. The update of each " +"client is then clipped by some value `S` (sensitivity `S`). This would " +"limit the impact of any individual client which is crucial for privacy " +"and often beneficial for robustness. A common approach to achieve this is" +" by restricting the `L2` norm of the clients' model updates, ensuring " +"that larger updates are scaled down to fit within the norm `S`." +msgstr "" +"虽然在联合学习中实现中央数据处理的方法有很多种,但我们将重点放在[2]和[3]提出的算法上。总体方法是剪辑客户端发送的模型更新,并在聚合模型中添加一定量的噪声。在每次迭代中,以特定概率随机选择一组客户端进行训练。每个客户端对自己的数据进行局部训练。然后,每个客户端的更新会被某个值`S`(灵敏度`S`)剪切。这将限制任何单个客户端的影响,这对隐私至关重要,通常也有利于稳健性。实现这一点的常用方法是限制客户机模型更新的" +" `L2` 准则,确保较大的更新被缩减以适应 `S` 准则。" #: ../../source/explanation-differential-privacy.rst:-1 #, fuzzy @@ -3838,15 +3277,14 @@ msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:89 #, fuzzy msgid "" -"Afterwards, the Gaussian mechanism is used to add noise in order to distort " -"the sum of all clients' updates. The amount of noise is scaled to the " -"sensitivity value to obtain a privacy guarantee. The Gaussian mechanism is " -"used with a noise sampled from `N (0, σ²)` where `σ = ( noise_scale * S ) / " -"(number of sampled clients)`." +"Afterwards, the Gaussian mechanism is used to add noise in order to " +"distort the sum of all clients' updates. The amount of noise is scaled to" +" the sensitivity value to obtain a privacy guarantee. The Gaussian " +"mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " +"noise_scale * S ) / (number of sampled clients)`." msgstr "" -"然后,使用高斯机制添加噪声,以扭曲所有客户端的更新总和。噪声量与灵敏度值成正" -"比,以获得隐私保证。高斯机制的噪声采样范围为 `N (0, σ²)` ,其中 σ = ( 噪声规" -"模 * S ) / (采样客户数)`。" +"然后,使用高斯机制添加噪声,以扭曲所有客户端的更新总和。噪声量与灵敏度值成正比,以获得隐私保证。高斯机制的噪声采样范围为 `N (0, σ²)` " +",其中 σ = ( 噪声规模 * S ) / (采样客户数)`。" #: ../../source/explanation-differential-privacy.rst:94 #, fuzzy @@ -3856,40 +3294,34 @@ msgstr "剪贴" #: ../../source/explanation-differential-privacy.rst:96 #, fuzzy msgid "" -"There are two forms of clipping commonly used in Central DP: Fixed Clipping " -"and Adaptive Clipping." +"There are two forms of clipping commonly used in Central DP: Fixed " +"Clipping and Adaptive Clipping." msgstr "中央处理器常用的剪切有两种形式:固定剪切和自适应剪切。" #: ../../source/explanation-differential-privacy.rst:98 #, fuzzy msgid "" -"**Fixed Clipping** : A predefined fix threshold is set for the magnitude of " -"clients' updates. Any update exceeding this threshold is clipped back to the " -"threshold value." -msgstr "" -"** 固定削波** : 为客户端更新的大小设置了一个预定义的固定阈值。任何超过该阈值" -"的更新都会被剪切回阈值。" +"**Fixed Clipping** : A predefined fix threshold is set for the magnitude " +"of clients' updates. Any update exceeding this threshold is clipped back " +"to the threshold value." +msgstr "** 固定削波** : 为客户端更新的大小设置了一个预定义的固定阈值。任何超过该阈值的更新都会被剪切回阈值。" #: ../../source/explanation-differential-privacy.rst:100 #, fuzzy msgid "" -"**Adaptive Clipping** : The clipping threshold dynamically adjusts based on " -"the observed update distribution [4]. It means that the clipping value is " -"tuned during the rounds with respect to the quantile of the update norm " -"distribution." -msgstr "" -"** 自适应削波** : 削波阈值根据观察到的更新分布动态调整[4]。这意味着,在各轮" -"中,会根据更新规范分布的量化值调整削波值。" +"**Adaptive Clipping** : The clipping threshold dynamically adjusts based " +"on the observed update distribution [4]. It means that the clipping value" +" is tuned during the rounds with respect to the quantile of the update " +"norm distribution." +msgstr "** 自适应削波** : 削波阈值根据观察到的更新分布动态调整[4]。这意味着,在各轮中,会根据更新规范分布的量化值调整削波值。" #: ../../source/explanation-differential-privacy.rst:102 #, fuzzy msgid "" -"The choice between fixed and adaptive clipping depends on various factors " -"such as privacy requirements, data distribution, model complexity, and " +"The choice between fixed and adaptive clipping depends on various factors" +" such as privacy requirements, data distribution, model complexity, and " "others." -msgstr "" -"在固定剪切和自适应剪切之间做出选择取决于各种因素,如隐私要求、数据分布、模型" -"复杂性等。" +msgstr "在固定剪切和自适应剪切之间做出选择取决于各种因素,如隐私要求、数据分布、模型复杂性等。" #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:105 @@ -3902,13 +3334,12 @@ msgstr "差分隐私" #, fuzzy msgid "" "In this approach, each client is responsible for performing DP. Local DP " -"avoids the need for a fully trusted aggregator, but it should be noted that " -"local DP leads to a decrease in accuracy but better privacy in comparison to " -"central DP." +"avoids the need for a fully trusted aggregator, but it should be noted " +"that local DP leads to a decrease in accuracy but better privacy in " +"comparison to central DP." msgstr "" -"在这种方法中,每个客户端都负责执行 DP。本地 DP 避免了对完全可信的聚合器的需" -"求,但需要注意的是,与中央 DP 相比,本地 DP 会降低准确性,但却能更好地保护隐" -"私。" +"在这种方法中,每个客户端都负责执行 DP。本地 DP 避免了对完全可信的聚合器的需求,但需要注意的是,与中央 DP 相比,本地 DP " +"会降低准确性,但却能更好地保护隐私。" #: ../../source/explanation-differential-privacy.rst:116 #, fuzzy @@ -3919,25 +3350,24 @@ msgstr "在本说明中,我们将重点介绍实现本地 DP 的两种形式 #, fuzzy msgid "" "Each client adds noise to the local updates before sending them to the " -"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering the " -"sensitivity of the local model to be ∆, Gaussian noise is applied with a " -"noise scale of σ where:" +"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " +"the sensitivity of the local model to be ∆, Gaussian noise is applied " +"with a noise scale of σ where:" msgstr "" -"每个客户端在向服务器发送本地更新之前,都会在本地更新中加入噪声。为了实现(:" -"math:`\\epsilon`, :math:`\\delta`)-DP,考虑到本地模型的灵敏度为 ∆,应用了高" -"斯噪声,噪声尺度为 σ,其中:" +"每个客户端在向服务器发送本地更新之前,都会在本地更新中加入噪声。为了实现(:math:`\\epsilon`, " +":math:`\\delta`)-DP,考虑到本地模型的灵敏度为 ∆,应用了高斯噪声,噪声尺度为 σ,其中:" #: ../../source/explanation-differential-privacy.rst:120 #, fuzzy msgid "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" -"{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times " +"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" "\n" msgstr "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" -"{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times " +"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" "\n" #: ../../source/explanation-differential-privacy.rst:125 @@ -3946,9 +3376,7 @@ msgid "" "Each client adds noise to the gradients of the model during the local " "training (DP-SGD). More specifically, in this approach, gradients are " "clipped and an amount of calibrated noise is injected into the gradients." -msgstr "" -"在局部训练过程中,每个客户端都会向模型的梯度添加噪声(DP-SGD)。更具体地说," -"在这种方法中,梯度会被剪切,并在梯度中注入一定量的校准噪声。" +msgstr "在局部训练过程中,每个客户端都会向模型的梯度添加噪声(DP-SGD)。更具体地说,在这种方法中,梯度会被剪切,并在梯度中注入一定量的校准噪声。" #: ../../source/explanation-differential-privacy.rst:128 #, fuzzy @@ -3970,25 +3398,26 @@ msgstr "[1] Dwork 等:《差分隐私的算法基础》。" #: ../../source/explanation-differential-privacy.rst:135 #, fuzzy msgid "" -"[2] McMahan et al. Learning Differentially Private Recurrent Language Models." +"[2] McMahan et al. Learning Differentially Private Recurrent Language " +"Models." msgstr "" -"McMahan, H. Brendan等. \"Learning differentially private recurrent language " -"models.\" arXiv preprint arXiv:1710.06963 (2017)." +"McMahan, H. Brendan等. \"Learning differentially private recurrent " +"language models.\" arXiv preprint arXiv:1710.06963 (2017)." #: ../../source/explanation-differential-privacy.rst:137 #, fuzzy msgid "" -"[3] Geyer et al. Differentially Private Federated Learning: A Client Level " -"Perspective." +"[3] Geyer et al. Differentially Private Federated Learning: A Client " +"Level Perspective." msgstr "[3] Geyer 等人。差异化化私人联合学习:客户层面的视角。" #: ../../source/explanation-differential-privacy.rst:139 #, fuzzy -msgid "" -"[4] Galen et al. Differentially Private Learning with Adaptive Clipping." +msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." msgstr "" -"Andrew, Galen等. \"Differentially private learning with adaptive clipping.\" " -"Advances in Neural Information Processing Systems 34 (2021): 17455-17466." +"Andrew, Galen等. \"Differentially private learning with adaptive " +"clipping.\" Advances in Neural Information Processing Systems 34 (2021): " +"17455-17466." #: ../../source/explanation-federated-evaluation.rst:2 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:292 @@ -3998,11 +3427,9 @@ msgstr "联邦学习评估" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" "There are two main approaches to evaluating models in federated learning " -"systems: centralized (or server-side) evaluation and federated (or client-" -"side) evaluation." -msgstr "" -"评估联合学习系统中的模型主要有两种方法:集中(或服务器端)评估和联邦(或客户" -"端)评估。" +"systems: centralized (or server-side) evaluation and federated (or " +"client-side) evaluation." +msgstr "评估联合学习系统中的模型主要有两种方法:集中(或服务器端)评估和联邦(或客户端)评估。" #: ../../source/explanation-federated-evaluation.rst:8 msgid "Centralized Evaluation" @@ -4018,9 +3445,7 @@ msgid "" "evaluation function during initialization. An evaluation function is any " "function that can take the current global model parameters as input and " "return evaluation results:" -msgstr "" -"所有内置策略都通过在初始化过程中提供一个评估函数来支持集中评估。评估函数是任" -"何可以将当前全局模型参数作为输入并返回评估结果的函数:" +msgstr "所有内置策略都通过在初始化过程中提供一个评估函数来支持集中评估。评估函数是任何可以将当前全局模型参数作为输入并返回评估结果的函数:" #: ../../source/explanation-federated-evaluation.rst:58 msgid "Custom Strategies" @@ -4028,14 +3453,14 @@ msgstr "定制策略" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" -"The :code:`Strategy` abstraction provides a method called :code:`evaluate` " -"that can directly be used to evaluate the current global model parameters. " -"The current server implementation calls :code:`evaluate` after parameter " -"aggregation and before federated evaluation (see next paragraph)." +"The :code:`Strategy` abstraction provides a method called " +":code:`evaluate` that can directly be used to evaluate the current global" +" model parameters. The current server implementation calls " +":code:`evaluate` after parameter aggregation and before federated " +"evaluation (see next paragraph)." msgstr "" -":code:`Strategy` 抽象提供了一个名为 :code:`evaluate` 的方法,可直接用于评估当" -"前的全局模型参数。服务器会在参数聚合后和联邦评估前调用 :code:`evaluate`(见下" -"段)。" +":code:`Strategy` 抽象提供了一个名为 :code:`evaluate` " +"的方法,可直接用于评估当前的全局模型参数。服务器会在参数聚合后和联邦评估前调用 :code:`evaluate`(见下段)。" #: ../../source/explanation-federated-evaluation.rst:65 msgid "Federated Evaluation" @@ -4047,10 +3472,9 @@ msgstr "实现联邦评估" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" -"Client-side evaluation happens in the :code:`Client.evaluate` method and can " -"be configured from the server side." -msgstr "" -"客户端评估在 :code:`Client.evaluate` 方法中进行,并可从服务器端进行配置。" +"Client-side evaluation happens in the :code:`Client.evaluate` method and " +"can be configured from the server side." +msgstr "客户端评估在 :code:`Client.evaluate` 方法中进行,并可从服务器端进行配置。" #: ../../source/explanation-federated-evaluation.rst:101 msgid "Configuring Federated Evaluation" @@ -4064,55 +3488,51 @@ msgstr "联邦评估可从服务器端进行配置。内置策略支持以下参 #: ../../source/explanation-federated-evaluation.rst:105 msgid "" -":code:`fraction_evaluate`: a :code:`float` defining the fraction of clients " -"that will be selected for evaluation. If :code:`fraction_evaluate` is set " -"to :code:`0.1` and :code:`100` clients are connected to the server, then :" -"code:`10` will be randomly selected for evaluation. If :code:" -"`fraction_evaluate` is set to :code:`0.0`, federated evaluation will be " -"disabled." +":code:`fraction_evaluate`: a :code:`float` defining the fraction of " +"clients that will be selected for evaluation. If " +":code:`fraction_evaluate` is set to :code:`0.1` and :code:`100` clients " +"are connected to the server, then :code:`10` will be randomly selected " +"for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " +"federated evaluation will be disabled." msgstr "" -":code:`fraction_evaluate`: :code:`float`,定义了被选中进行评估的客户端的比" -"例。如果 :code:`fraction_evaluate` 设置为 :code:`0.1`,并且 :code:`100` 个客" -"户端连接到服务器,那么 :code:`10` 个客户端将被随机选中进行评估。如果 :code:" -"`fraction_evaluate` 设置为 :code:`0.0`,联邦评估将被禁用。" +":code:`fraction_evaluate`: :code:`float`,定义了被选中进行评估的客户端的比例。如果 " +":code:`fraction_evaluate` 设置为 :code:`0.1`,并且 :code:`100` 个客户端连接到服务器,那么 " +":code:`10` 个客户端将被随机选中进行评估。如果 :code:`fraction_evaluate` 设置为 " +":code:`0.0`,联邦评估将被禁用。" #: ../../source/explanation-federated-evaluation.rst:106 msgid "" -":code:`min_evaluate_clients`: an :code:`int`: the minimum number of clients " -"to be selected for evaluation. If :code:`fraction_evaluate` is set to :code:" -"`0.1`, :code:`min_evaluate_clients` is set to 20, and :code:`100` clients " -"are connected to the server, then :code:`20` clients will be selected for " -"evaluation." +":code:`min_evaluate_clients`: an :code:`int`: the minimum number of " +"clients to be selected for evaluation. If :code:`fraction_evaluate` is " +"set to :code:`0.1`, :code:`min_evaluate_clients` is set to 20, and " +":code:`100` clients are connected to the server, then :code:`20` clients " +"will be selected for evaluation." msgstr "" -":code:`min_evaluate_clients`:一个 :code:`int`,需要评估的客户的最小数量。如" -"果 :code:`fraction_evaluate` 设置为 :code:`0.1`,:code:" -"`min_evaluate_clients` 设置为 20,并且有 :code:`100` 个客户端已连接到服务器," -"那么 :code:`20` 个客户端将被选中进行评估。" +":code:`min_evaluate_clients`:一个 :code:`int`,需要评估的客户的最小数量。如果 " +":code:`fraction_evaluate` 设置为 :code:`0.1`,:code:`min_evaluate_clients` " +"设置为 20,并且有 :code:`100` 个客户端已连接到服务器,那么 :code:`20` 个客户端将被选中进行评估。" #: ../../source/explanation-federated-evaluation.rst:107 msgid "" ":code:`min_available_clients`: an :code:`int` that defines the minimum " -"number of clients which need to be connected to the server before a round of " -"federated evaluation can start. If fewer than :code:`min_available_clients` " -"are connected to the server, the server will wait until more clients are " -"connected before it continues to sample clients for evaluation." +"number of clients which need to be connected to the server before a round" +" of federated evaluation can start. If fewer than " +":code:`min_available_clients` are connected to the server, the server " +"will wait until more clients are connected before it continues to sample " +"clients for evaluation." msgstr "" -":code:`min_available_clients`: :code:`int`,定义了在一轮联邦评估开始之前,需" -"要连接到服务器的最小客户端数量。如果连接到服务器的客户端数量少于 :code:" -"`min_available_clients`,服务器将等待更多客户端连接后,才继续采样客户端进行评" -"估。" +":code:`min_available_clients`: " +":code:`int`,定义了在一轮联邦评估开始之前,需要连接到服务器的最小客户端数量。如果连接到服务器的客户端数量少于 " +":code:`min_available_clients`,服务器将等待更多客户端连接后,才继续采样客户端进行评估。" #: ../../source/explanation-federated-evaluation.rst:108 msgid "" ":code:`on_evaluate_config_fn`: a function that returns a configuration " -"dictionary which will be sent to the selected clients. The function will be " -"called during each round and provides a convenient way to customize client-" -"side evaluation from the server side, for example, to configure the number " -"of validation steps performed." -msgstr "" -"code:`on_evaluate_config_fn`:返回配置字典的函数,该字典将发送给选定的客户" -"端。该函数将在每一轮中被调用,并提供了一种方便的方法来从服务器端自定义客户端" -"评估,例如,配置执行的验证步骤数。" +"dictionary which will be sent to the selected clients. The function will " +"be called during each round and provides a convenient way to customize " +"client-side evaluation from the server side, for example, to configure " +"the number of validation steps performed." +msgstr "code:`on_evaluate_config_fn`:返回配置字典的函数,该字典将发送给选定的客户端。该函数将在每一轮中被调用,并提供了一种方便的方法来从服务器端自定义客户端评估,例如,配置执行的验证步骤数。" #: ../../source/explanation-federated-evaluation.rst:135 msgid "Evaluating Local Model Updates During Training" @@ -4120,11 +3540,10 @@ msgstr "评估训练期间的本地模型更新" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" -"Model parameters can also be evaluated during training. :code:`Client.fit` " -"can return arbitrary evaluation results as a dictionary:" -msgstr "" -"模型参数也可在训练过程中进行评估。 :code:`Client.fit`可以字典形式返回任意评估" -"结果:" +"Model parameters can also be evaluated during training. " +":code:`Client.fit` can return arbitrary evaluation results as a " +"dictionary:" +msgstr "模型参数也可在训练过程中进行评估。 :code:`Client.fit`可以字典形式返回任意评估结果:" #: ../../source/explanation-federated-evaluation.rst:177 msgid "Full Code Example" @@ -4132,14 +3551,14 @@ msgstr "完整代码示例" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" -"For a full code example that uses both centralized and federated evaluation, " -"see the *Advanced TensorFlow Example* (the same approach can be applied to " -"workloads implemented in any other framework): https://github.com/adap/" -"flower/tree/main/examples/advanced-tensorflow" +"For a full code example that uses both centralized and federated " +"evaluation, see the *Advanced TensorFlow Example* (the same approach can " +"be applied to workloads implemented in any other framework): " +"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" msgstr "" "有关同时使用集中评估和联邦评估的完整代码示例,请参阅 *Advanced TensorFlow " -"Example*(同样的方法也可应用于任何其他框架中): https://github.com/adap/" -"flower/tree/main/examples/advanced-tensorflow" +"Example*(同样的方法也可应用于任何其他框架中): " +"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" #: ../../source/fed/0000-20200102-fed-template.md:10 msgid "FED Template" @@ -4312,12 +3731,10 @@ msgstr "保留 GitHub 问题,用于跟踪进行中的工作" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" -"ensure community participants can successfully drive changes to completion " -"across one or more releases while stakeholders are adequately represented " -"throughout the process" -msgstr "" -"确保社区参与者能够成功推动改动,完成一个或多个版本,同时利益相关者在整个过程" -"中得到充分展现" +"ensure community participants can successfully drive changes to " +"completion across one or more releases while stakeholders are adequately " +"represented throughout the process" +msgstr "确保社区参与者能够成功推动改动,完成一个或多个版本,同时利益相关者在整个过程中得到充分展现" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 msgid "Hence, an Enhancement Doc combines aspects of" @@ -4344,69 +3761,61 @@ msgstr "该文件是与社区合作逐步创建的。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" "For far-fetching changes or features proposed to Flower, an abstraction " -"beyond a single GitHub issue or pull request is required to understand and " -"communicate upcoming changes to the project." +"beyond a single GitHub issue or pull request is required to understand " +"and communicate upcoming changes to the project." msgstr "" -"对于向 Flower 提出的远期变更或功能,需要一个超越单个 GitHub 问题或拉取请求" -"(pull request)的抽象概念,以了解和沟通项目即将发生的变更。" +"对于向 Flower 提出的远期变更或功能,需要一个超越单个 GitHub 问题或拉取请求(pull " +"request)的抽象概念,以了解和沟通项目即将发生的变更。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" -"The purpose of this process is to reduce the amount of \"tribal knowledge\" " -"in our community. By moving decisions from Slack threads, video calls, and " -"hallway conversations into a well-tracked artifact, this process aims to " -"enhance communication and discoverability." +"The purpose of this process is to reduce the amount of \"tribal " +"knowledge\" in our community. By moving decisions from Slack threads, " +"video calls, and hallway conversations into a well-tracked artifact, this" +" process aims to enhance communication and discoverability." msgstr "" -"这一流程的目的是减少我们社区中 \"部落知识 \"的数量。通过将决策从 Slack 线程、" -"视频通话和走廊对话转移到一个跟踪良好的工作环境中,该流程旨在加强沟通和可发现" -"性。" +"这一流程的目的是减少我们社区中 \"部落知识 \"的数量。通过将决策从 Slack " +"线程、视频通话和走廊对话转移到一个跟踪良好的工作环境中,该流程旨在加强沟通和可发现性。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" -"Roughly any larger, user-facing enhancement should follow the Enhancement " -"process. If an enhancement would be described in either written or verbal " -"communication to anyone besides the author or developer, then consider " -"creating an Enhancement Doc." -msgstr "" -"任何较大的、面向用户的增强都应遵循增强流程。如果要以书面或口头形式向作者或开" -"发人员以外的任何人描述增强功能,则应考虑创建改善文档。" +"Roughly any larger, user-facing enhancement should follow the Enhancement" +" process. If an enhancement would be described in either written or " +"verbal communication to anyone besides the author or developer, then " +"consider creating an Enhancement Doc." +msgstr "任何较大的、面向用户的增强都应遵循增强流程。如果要以书面或口头形式向作者或开发人员以外的任何人描述增强功能,则应考虑创建改善文档。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" -"Similarly, any technical effort (refactoring, major architectural change) " -"that will impact a large section of the development community should also be " -"communicated widely. The Enhancement process is suited for this even if it " -"will have zero impact on the typical user or operator." -msgstr "" -"同样,任何会对开发社区的大部分人产生影响的技术工作(重构、重大架构变更)也应" -"广泛传播。即使对典型用户或操作员的影响为零,改进流程也适用于这种情况。" +"Similarly, any technical effort (refactoring, major architectural change)" +" that will impact a large section of the development community should " +"also be communicated widely. The Enhancement process is suited for this " +"even if it will have zero impact on the typical user or operator." +msgstr "同样,任何会对开发社区的大部分人产生影响的技术工作(重构、重大架构变更)也应广泛传播。即使对典型用户或操作员的影响为零,改进流程也适用于这种情况。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" -"For small changes and additions, going through the Enhancement process would " -"be time-consuming and unnecessary. This includes, for example, adding new " -"Federated Learning algorithms, as these only add features without changing " -"how Flower works or is used." +"For small changes and additions, going through the Enhancement process " +"would be time-consuming and unnecessary. This includes, for example, " +"adding new Federated Learning algorithms, as these only add features " +"without changing how Flower works or is used." msgstr "" -"对于小的改动和添加,通过 \"改善\"程序既耗时又没有必要。例如,这包括添加新的联" -"邦学习算法,因为这只会增加功能,而不会改变 \"Flower \"的工作或使用方式。" +"对于小的改动和添加,通过 \"改善\"程序既耗时又没有必要。例如,这包括添加新的联邦学习算法,因为这只会增加功能,而不会改变 \"Flower " +"\"的工作或使用方式。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " -"providing a laid-out path for implementation and are championed by members " -"of the community." -msgstr "" -"增强功能与功能请求不同,因为它们已经提供了实施路径,并得到了社区成员的支持。" +"providing a laid-out path for implementation and are championed by " +"members of the community." +msgstr "增强功能与功能请求不同,因为它们已经提供了实施路径,并得到了社区成员的支持。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" "An Enhancement is captured in a Markdown file that follows a defined " -"template and a workflow to review and store enhancement docs for reference " -"— the Enhancement Doc." -msgstr "" -"增强功能被记录在一个 Markdown 文件中,该文件遵循已定义的模板和工作流程,用于" -"审查和存储增强功能文档(即增强功能文档)以供参考。" +"template and a workflow to review and store enhancement docs for " +"reference — the Enhancement Doc." +msgstr "增强功能被记录在一个 Markdown 文件中,该文件遵循已定义的模板和工作流程,用于审查和存储增强功能文档(即增强功能文档)以供参考。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:69 msgid "Enhancement Doc Template" @@ -4457,11 +3866,9 @@ msgstr "描述数据" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" -"**fed-number** (Required) The `fed-number` of the last Flower Enhancement " -"Doc + 1. With this number, it becomes easy to reference other proposals." -msgstr "" -"**fed-number**(必填)上一个Flower增强文件的 \"fed-number \"+1。有了这个编" -"号,就很容易参考其他提案。" +"**fed-number** (Required) The `fed-number` of the last Flower Enhancement" +" Doc + 1. With this number, it becomes easy to reference other proposals." +msgstr "**fed-number**(必填)上一个Flower增强文件的 \"fed-number \"+1。有了这个编号,就很容易参考其他提案。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 msgid "**title** (Required) The title of the proposal in plain language." @@ -4469,22 +3876,20 @@ msgstr "**标题** (必填)用简明语言写出提案的标题。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" -"**status** (Required) The current status of the proposal. See [workflow]" -"(#workflow) for the possible states." -msgstr "" -"**status** (必填)提案的当前状态。有关可能的状态,请参阅 [工作流程]" -"(#workflow)。" +"**status** (Required) The current status of the proposal. See " +"[workflow](#workflow) for the possible states." +msgstr "**status** (必填)提案的当前状态。有关可能的状态,请参阅 [工作流程](#workflow)。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" -"**authors** (Required) A list of authors of the proposal. This is simply the " -"GitHub ID." +"**authors** (Required) A list of authors of the proposal. This is simply " +"the GitHub ID." msgstr "**作者**(必填) 提案的作者列表。这只是 GitHub ID。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" -"**creation-date** (Required) The date that the proposal was first submitted " -"in a PR." +"**creation-date** (Required) The date that the proposal was first " +"submitted in a PR." msgstr "**创建日期**(必填) 建议书在 PR 中首次提交的日期。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 @@ -4495,8 +3900,8 @@ msgstr "**最后更新** (可选)提案最后一次重大修改的日期。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" -"**see-also** (Optional) A list of other proposals that are relevant to this " -"one." +"**see-also** (Optional) A list of other proposals that are relevant to " +"this one." msgstr "**另见** (可选)与本提案相关的其他提案清单。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 @@ -4504,8 +3909,7 @@ msgid "**replaces** (Optional) A list of proposals that this one replaces." msgstr "**取代**(可选) 这份提案所取代的提案列表。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 -msgid "" -"**superseded-by** (Optional) A list of proposals that this one supersedes." +msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." msgstr "**被取代者** (可选) 此提案取代的提案列表。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 @@ -4515,52 +3919,46 @@ msgstr "工作流程" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" "The idea forming the enhancement should already have been discussed or " -"pitched in the community. As such, it needs a champion, usually the author, " -"who shepherds the enhancement. This person also has to find committers to " -"Flower willing to review the proposal." -msgstr "" -"形成增强功能的想法应该已经在社区中讨论过或提出过。因此,它需要一个支持者(通" -"常是作者)来引导增强。这个人还必须找到愿意审核提案的提交者。" +"pitched in the community. As such, it needs a champion, usually the " +"author, who shepherds the enhancement. This person also has to find " +"committers to Flower willing to review the proposal." +msgstr "形成增强功能的想法应该已经在社区中讨论过或提出过。因此,它需要一个支持者(通常是作者)来引导增强。这个人还必须找到愿意审核提案的提交者。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" "New enhancements are checked in with a file name in the form of `NNNN-" -"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement Doc " -"number, to `enhancements`. All enhancements start in `provisional` state as " -"part of a pull request. Discussions are done as part of the pull request " -"review." +"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement " +"Doc number, to `enhancements`. All enhancements start in `provisional` " +"state as part of a pull request. Discussions are done as part of the pull" +" request review." msgstr "" -"新的增强功能以 `NNNN-YYYYMMDD-enhancement-title.md` 的文件名签入,其中 " -"`NNNN` 是花朵增强文档的编号,并将其转入 `enhancements`。作为拉取请求(pull " -"request)的一部分,所有增强功能都从 `provisional` 状态开始。讨论是作为拉取请" -"求审查的一部分进行的。" +"新的增强功能以 `NNNN-YYYYMMDD-enhancement-title.md` 的文件名签入,其中 `NNNN` " +"是花朵增强文档的编号,并将其转入 `enhancements`。作为拉取请求(pull request)的一部分,所有增强功能都从 " +"`provisional` 状态开始。讨论是作为拉取请求审查的一部分进行的。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" -"Once an enhancement has been reviewed and approved, its status is changed to " -"`implementable`. The actual implementation is then done in separate pull " -"requests. These pull requests should mention the respective enhancement as " -"part of their description. After the implementation is done, the proposal " -"status is changed to `implemented`." +"Once an enhancement has been reviewed and approved, its status is changed" +" to `implementable`. The actual implementation is then done in separate " +"pull requests. These pull requests should mention the respective " +"enhancement as part of their description. After the implementation is " +"done, the proposal status is changed to `implemented`." msgstr "" -"一旦增强功能通过审核和批准,其状态就会变为 `可实施`。实际的实施工作将在单独的" -"拉取请求中完成。这些拉取请求应在其描述中提及相应的增强功能。实施完成后,提案" -"状态将更改为 `已实施`。" +"一旦增强功能通过审核和批准,其状态就会变为 " +"`可实施`。实际的实施工作将在单独的拉取请求中完成。这些拉取请求应在其描述中提及相应的增强功能。实施完成后,提案状态将更改为 `已实施`。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" -"Under certain conditions, other states are possible. An Enhancement has the " -"following states:" +"Under certain conditions, other states are possible. An Enhancement has " +"the following states:" msgstr "在某些条件下,还可能出现其他状态。增强提案具有以下状态:" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" "`provisional`: The enhancement has been proposed and is actively being " -"defined. This is the starting state while the proposal is being fleshed out " -"and actively defined and discussed." -msgstr "" -"`暂定`: 已提出改进建议并正在积极定义。这是在提案得到充实、积极定义和讨论时的" -"起始状态。" +"defined. This is the starting state while the proposal is being fleshed " +"out and actively defined and discussed." +msgstr "`暂定`: 已提出改进建议并正在积极定义。这是在提案得到充实、积极定义和讨论时的起始状态。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 msgid "`implementable`: The enhancement has been reviewed and approved." @@ -4573,14 +3971,13 @@ msgid "" msgstr "`已实施`: 增强功能已实施,不再主动更改。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 -msgid "" -"`deferred`: The enhancement is proposed but not actively being worked on." +msgid "`deferred`: The enhancement is proposed but not actively being worked on." msgstr "`推迟`: 已提出改进建议,但尚未积极开展工作。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" -"`rejected`: The authors and reviewers have decided that this enhancement is " -"not moving forward." +"`rejected`: The authors and reviewers have decided that this enhancement " +"is not moving forward." msgstr "`拒绝`: 作者和审稿人已决定不再推进该增强功能。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 @@ -4593,21 +3990,17 @@ msgstr "`已替换`: 增强功能已被新的增强功能取代。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" -"Adding an additional process to the ones already provided by GitHub (Issues " -"and Pull Requests) adds more complexity and can be a barrier for potential " -"first-time contributors." -msgstr "" -"在 GitHub 已提供的流程(问题和拉取请求)之外再增加一个流程,会增加复杂性,并" -"可能成为潜在首次贡献者的障碍。" +"Adding an additional process to the ones already provided by GitHub " +"(Issues and Pull Requests) adds more complexity and can be a barrier for " +"potential first-time contributors." +msgstr "在 GitHub 已提供的流程(问题和拉取请求)之外再增加一个流程,会增加复杂性,并可能成为潜在首次贡献者的障碍。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" "Expanding the proposal template beyond the single-sentence description " -"currently required in the features issue template may be a heavy burden for " -"non-native English speakers." -msgstr "" -"对于英语非母语者来说,将提案模板扩展到目前要求的单句描述之外可能是一个沉重的" -"负担。" +"currently required in the features issue template may be a heavy burden " +"for non-native English speakers." +msgstr "对于英语非母语者来说,将提案模板扩展到目前要求的单句描述之外可能是一个沉重的负担。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 msgid "GitHub Issues" @@ -4616,17 +4009,16 @@ msgstr "GitHub 问题" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" "Using GitHub Issues for these kinds of enhancements is doable. One could " -"use, for example, tags, to differentiate and filter them from other issues. " -"The main issue is in discussing and reviewing an enhancement: GitHub issues " -"only have a single thread for comments. Enhancements usually have multiple " -"threads of discussion at the same time for various parts of the doc. " -"Managing these multiple discussions can be confusing when using GitHub " -"Issues." -msgstr "" -"使用 GitHub Issues 进行此类改进是可行的。例如,我们可以使用标签来区分和过滤这" -"些问题。主要的问题在于讨论和审查增强功能: GitHub 问题只有一个评论线程。而增" -"强功能通常会同时有多个讨论线程,针对文档的不同部分。在使用 GitHub 问题时,管" -"理这些多重讨论会很混乱。" +"use, for example, tags, to differentiate and filter them from other " +"issues. The main issue is in discussing and reviewing an enhancement: " +"GitHub issues only have a single thread for comments. Enhancements " +"usually have multiple threads of discussion at the same time for various " +"parts of the doc. Managing these multiple discussions can be confusing " +"when using GitHub Issues." +msgstr "" +"使用 GitHub Issues 进行此类改进是可行的。例如,我们可以使用标签来区分和过滤这些问题。主要的问题在于讨论和审查增强功能: " +"GitHub 问题只有一个评论线程。而增强功能通常会同时有多个讨论线程,针对文档的不同部分。在使用 GitHub " +"问题时,管理这些多重讨论会很混乱。" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 msgid "Google Docs" @@ -4634,15 +4026,15 @@ msgstr "谷歌文档" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" -"Google Docs allow for multiple threads of discussions. But as Google Docs " -"are hosted outside the project, their discoverability by the community needs " -"to be taken care of. A list of links to all proposals has to be managed and " -"made available for the community. Compared to shipping proposals as part of " -"Flower's repository, the potential for missing links is much higher." +"Google Docs allow for multiple threads of discussions. But as Google Docs" +" are hosted outside the project, their discoverability by the community " +"needs to be taken care of. A list of links to all proposals has to be " +"managed and made available for the community. Compared to shipping " +"proposals as part of Flower's repository, the potential for missing links" +" is much higher." msgstr "" -"谷歌文档允许多线程讨论。但是,由于谷歌文档是在项目之外托管的,因此需要注意它" -"们是否能被社区发现。我们必须管理所有提案的链接列表,并提供给社区使用。与作为 " -"Flower 资源库一部分的提案相比,丢失链接的可能性要大得多。" +"谷歌文档允许多线程讨论。但是,由于谷歌文档是在项目之外托管的,因此需要注意它们是否能被社区发现。我们必须管理所有提案的链接列表,并提供给社区使用。与作为" +" Flower 资源库一部分的提案相比,丢失链接的可能性要大得多。" #: ../../source/fed/index.md:1 msgid "FED - Flower Enhancement Doc" @@ -4654,10 +4046,9 @@ msgstr "整合评估结果" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" -"The Flower server does not prescribe a way to aggregate evaluation results, " -"but it enables the user to fully customize result aggregation." -msgstr "" -"Flower 服务器没有规定整合评估结果的方法,但用户可以完全自定义如何整合。" +"The Flower server does not prescribe a way to aggregate evaluation " +"results, but it enables the user to fully customize result aggregation." +msgstr "Flower 服务器没有规定整合评估结果的方法,但用户可以完全自定义如何整合。" #: ../../source/how-to-aggregate-evaluation-results.rst:8 msgid "Aggregate Custom Evaluation Results" @@ -4665,12 +4056,10 @@ msgstr "自定义整合评估结果" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" -"The same :code:`Strategy`-customization approach can be used to aggregate " -"custom evaluation results coming from individual clients. Clients can return " -"custom metrics to the server by returning a dictionary:" -msgstr "" -"同样的 :code:`Strategy` 定制方法也可用于汇总来自单个客户端的自定义评估结果。" -"客户端可以通过返回字典的方式向服务器返回自定义指标:" +"The same :code:`Strategy`-customization approach can be used to aggregate" +" custom evaluation results coming from individual clients. Clients can " +"return custom metrics to the server by returning a dictionary:" +msgstr "同样的 :code:`Strategy` 定制方法也可用于汇总来自单个客户端的自定义评估结果。客户端可以通过返回字典的方式向服务器返回自定义指标:" #: ../../source/how-to-aggregate-evaluation-results.rst:36 msgid "" @@ -4678,6 +4067,165 @@ msgid "" "provided in these dictionaries:" msgstr "然后,服务器可以使用定制的策略来汇总这些字典中提供的指标:" +#: ../../source/how-to-authenticate-supernodes.rst:2 +msgid "Authenticate SuperNodes" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:4 +msgid "" +"Flower has built-in support for authenticated SuperNodes that you can use" +" to verify the identities of each SuperNode connecting to a SuperLink. " +"Flower node authentication works similar to how GitHub SSH authentication" +" works:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:7 +msgid "SuperLink (server) stores a list of known (client) node public keys" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:8 +msgid "" +"Using ECDH, both SuperNode and SuperLink independently derive a shared " +"secret" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:9 +msgid "" +"Shared secret is used to compute the HMAC value of the message sent from " +"SuperNode to SuperLink as a token" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:10 +msgid "SuperLink verifies the token" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:12 +#, fuzzy +msgid "" +"We recommend you to check out the complete `code example " +"`_ demonstrating federated learning with Flower in an " +"authenticated setting." +msgstr "" +"请参阅`完整代码示例 " +"`_了解更多信息。" + +#: ../../source/how-to-authenticate-supernodes.rst:15 +msgid "" +"This guide covers a preview feature that might change in future versions " +"of Flower." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:18 +msgid "" +"For increased security, node authentication can only be used when " +"encrypted connections (SSL/TLS) are enabled." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:21 +msgid "Enable node authentication in :code:`SuperLink`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:23 +msgid "" +"To enable node authentication, first you need to configure SSL/TLS " +"connections to secure the SuperLink<>SuperNode communication. You can " +"find the complete guide `here `_. After configuring secure connections, you" +" can enable client authentication in a long-running Flower " +":code:`SuperLink`. Use the following terminal command to start a Flower " +":code:`SuperNode` that has both secure connections and node " +"authentication enabled:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:36 +msgid "Let's break down the authentication flags:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:38 +msgid "" +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " +"file storing all known node public keys. You need to store all known node" +" public keys that are allowed to participate in a federation in one CSV " +"file (:code:`.csv`)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:40 +msgid "" +"A valid CSV file storing known node public keys should list the keys in " +"OpenSSH format, separated by commas and without any comments. For an " +"example, refer to our code sample, which contains a CSV file with two " +"known node public keys." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:42 +msgid "" +"The second and third flags :code:`--auth-superlink-private-key` and :code" +":`--auth-superlink-public-key` expect paths to the server's private and " +"public keys. For development purposes, you can generate a private and " +"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:45 +msgid "" +"In Flower 1.9, there is no support for dynamically removing, editing, or " +"adding known node public keys to the SuperLink. To change the set of " +"known nodes, you need to shut the server down, edit the CSV file, and " +"start the server again. Support for dynamically changing the set of known" +" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:51 +msgid "Enable node authentication in :code:`SuperNode`" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:53 +msgid "" +"Similar to the long-running Flower server (:code:`SuperLink`), you can " +"easily enable node authentication in the long-running Flower client " +"(:code:`SuperNode`). Use the following terminal command to start an " +"authenticated :code:`SuperNode`:" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:64 +msgid "" +"The :code:`--auth-supernode-private-key` flag expects a path to the " +"node's private key file and the :code:`--auth-supernode-public-key` flag " +"expects a path to the node's public key file. For development purposes, " +"you can generate a private and public key pair using :code:`ssh-keygen -t" +" ecdsa -b 384`." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:68 +msgid "Security notice" +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:70 +msgid "" +"The system's security relies on the credentials of the SuperLink and each" +" SuperNode. Therefore, it is imperative to safeguard and safely store the" +" credentials to avoid security risks such as Public Key Infrastructure " +"(PKI) impersonation attacks. The node authentication mechanism also " +"involves human interaction, so please ensure that all of the " +"communication is done in a secure manner, using trusted communication " +"methods." +msgstr "" + +#: ../../source/how-to-authenticate-supernodes.rst:75 +#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-use-built-in-mods.rst:85 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 +msgid "Conclusion" +msgstr "总结" + +#: ../../source/how-to-authenticate-supernodes.rst:77 +msgid "" +"You should now have learned how to start a long-running Flower server " +"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " +"authentication enabled. You should also know the significance of the " +"private key and store it safely to minimize security risks." +msgstr "" + #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" msgstr "配置客户端" @@ -4685,12 +4233,10 @@ msgstr "配置客户端" #: ../../source/how-to-configure-clients.rst:4 msgid "" "Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are, " -"for example, a popular way to control client-side hyperparameters from the " -"server." -msgstr "" -"除了模型参数,Flower 还可以向客户端发送配置值。配置值有多种用途。它们是一种从" -"服务器控制客户端超参数的常用方法。" +"clients. Configuration values can be used for various purposes. They are," +" for example, a popular way to control client-side hyperparameters from " +"the server." +msgstr "除了模型参数,Flower 还可以向客户端发送配置值。配置值有多种用途。它们是一种从服务器控制客户端超参数的常用方法。" #: ../../source/how-to-configure-clients.rst:7 msgid "Configuration values" @@ -4698,45 +4244,41 @@ msgstr "配置值" #: ../../source/how-to-configure-clients.rst:9 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys and " -"values of type ``bool``, ``bytes``, ``double`` (64-bit precision float), " -"``int``, or ``str`` (or equivalent types in different languages). Here is an " -"example of a configuration dictionary in Python:" +"Configuration values are represented as a dictionary with ``str`` keys " +"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " +"float), ``int``, or ``str`` (or equivalent types in different languages)." +" Here is an example of a configuration dictionary in Python:" msgstr "" -"配置值以字典的形式表示,字典的键为 ``str``,值的类型为 ``bool``、``bytes``、" -"``double``(64 位精度浮点型)、``int``或 ``str`(或不同语言中的等效类型)。下" -"面是一个 Python 配置字典的示例:" +"配置值以字典的形式表示,字典的键为 ``str``,值的类型为 ``bool``、``bytes``、``double``(64 " +"位精度浮点型)、``int``或 ``str`(或不同语言中的等效类型)。下面是一个 Python 配置字典的示例:" #: ../../source/how-to-configure-clients.rst:20 msgid "" "Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client using " -"gRPC, and then deserializes them back to Python dictionaries." +"short) to their ProtoBuf representation, transports them to the client " +"using gRPC, and then deserializes them back to Python dictionaries." msgstr "" -"Flower 将这些配置字典(简称 *config dict*)序列化为 ProtoBuf 表示形式,使用 " -"gRPC 将其传输到客户端,然后再反序列化为 Python 字典。" +"Flower 将这些配置字典(简称 *config dict*)序列化为 ProtoBuf 表示形式,使用 gRPC " +"将其传输到客户端,然后再反序列化为 Python 字典。" #: ../../source/how-to-configure-clients.rst:24 msgid "" -"Currently, there is no support for directly sending collection types (e.g., " -"``Set``, ``List``, ``Map``) as values in configuration dictionaries. There " -"are several workarounds to send collections as values by converting them to " -"one of the supported value types (and converting them back on the client-" -"side)." +"Currently, there is no support for directly sending collection types " +"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " +"dictionaries. There are several workarounds to send collections as values" +" by converting them to one of the supported value types (and converting " +"them back on the client-side)." msgstr "" "目前,还不支持在配置字典中直接发送作为值的集合类型(例如,`Set``, `List`, " -"`Map``)。有几种变通方法可将集合转换为支持的值类型之一(并在客户端将其转换" -"回),从而将集合作为值发送。" +"`Map``)。有几种变通方法可将集合转换为支持的值类型之一(并在客户端将其转换回),从而将集合作为值发送。" #: ../../source/how-to-configure-clients.rst:26 msgid "" "One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and " -"then convert the JSON string back to a list of floating-point numbers on the " -"client." -msgstr "" -"例如,可以将浮点数列表转换为 JSON 字符串,然后使用配置字典发送 JSON 字符串," -"再在客户端将 JSON 字符串转换回浮点数列表。" +"string, then send the JSON string using the configuration dictionary, and" +" then convert the JSON string back to a list of floating-point numbers on" +" the client." +msgstr "例如,可以将浮点数列表转换为 JSON 字符串,然后使用配置字典发送 JSON 字符串,再在客户端将 JSON 字符串转换回浮点数列表。" #: ../../source/how-to-configure-clients.rst:30 msgid "Configuration through built-in strategies" @@ -4744,65 +4286,57 @@ msgstr "通过内置策略进行配置" #: ../../source/how-to-configure-clients.rst:32 msgid "" -"The easiest way to send configuration values to clients is to use a built-in " -"strategy like :code:`FedAvg`. Built-in strategies support so-called " -"configuration functions. A configuration function is a function that the " -"built-in strategy calls to get the configuration dictionary for the current " -"round. It then forwards the configuration dictionary to all the clients " -"selected during that round." +"The easiest way to send configuration values to clients is to use a " +"built-in strategy like :code:`FedAvg`. Built-in strategies support so-" +"called configuration functions. A configuration function is a function " +"that the built-in strategy calls to get the configuration dictionary for " +"the current round. It then forwards the configuration dictionary to all " +"the clients selected during that round." msgstr "" -"向客户端发送配置值的最简单方法是使用内置策略,如 :code:`FedAvg`。内置策略支持" -"所谓的配置函数。配置函数是内置策略调用的函数,用于获取当前轮的配置字典。然" -"后,它会将配置字典转发给该轮中选择的所有客户端。" +"向客户端发送配置值的最简单方法是使用内置策略,如 " +":code:`FedAvg`。内置策略支持所谓的配置函数。配置函数是内置策略调用的函数,用于获取当前轮的配置字典。然后,它会将配置字典转发给该轮中选择的所有客户端。" #: ../../source/how-to-configure-clients.rst:34 msgid "" "Let's start with a simple example. Imagine we want to send (a) the batch " -"size that the client should use, (b) the current global round of federated " -"learning, and (c) the number of epochs to train on the client-side. Our " -"configuration function could look like this:" -msgstr "" -"让我们从一个简单的例子开始。想象一下,我们想要发送给客户端(a)应该使用的批次" -"大小,(b)当前联邦学习的全局轮次,以及(c)客户端训练的遍历数。我们的配置函" -"数可以是这样的:" +"size that the client should use, (b) the current global round of " +"federated learning, and (c) the number of epochs to train on the client-" +"side. Our configuration function could look like this:" +msgstr "让我们从一个简单的例子开始。想象一下,我们想要发送给客户端(a)应该使用的批次大小,(b)当前联邦学习的全局轮次,以及(c)客户端训练的遍历数。我们的配置函数可以是这样的:" #: ../../source/how-to-configure-clients.rst:47 msgid "" "To make the built-in strategies use this function, we can pass it to " -"``FedAvg`` during initialization using the parameter :code:" -"`on_fit_config_fn`:" -msgstr "" -"为了让内置策略使用这个函数,我们可以在初始化时使用参数 :code:" -"`on_fit_config_fn` 将它传递给 ``FedAvg`` :" +"``FedAvg`` during initialization using the parameter " +":code:`on_fit_config_fn`:" +msgstr "为了让内置策略使用这个函数,我们可以在初始化时使用参数 :code:`on_fit_config_fn` 将它传递给 ``FedAvg`` :" #: ../../source/how-to-configure-clients.rst:56 -msgid "" -"One the client side, we receive the configuration dictionary in ``fit``:" +msgid "One the client side, we receive the configuration dictionary in ``fit``:" msgstr "在客户端,我们在 ``fit`` 中接收配置字典:" #: ../../source/how-to-configure-clients.rst:67 msgid "" "There is also an `on_evaluate_config_fn` to configure evaluation, which " -"works the same way. They are separate functions because one might want to " -"send different configuration values to `evaluate` (for example, to use a " -"different batch size)." +"works the same way. They are separate functions because one might want to" +" send different configuration values to `evaluate` (for example, to use a" +" different batch size)." msgstr "" -"还有一个 `on_evaluate_config_fn` 用于配置评估,其工作方式相同。它们是不同的函" -"数,因为可能需要向 `evaluate` 发送不同的配置值(例如,使用不同的批量大小)。" +"还有一个 `on_evaluate_config_fn` 用于配置评估,其工作方式相同。它们是不同的函数,因为可能需要向 `evaluate` " +"发送不同的配置值(例如,使用不同的批量大小)。" #: ../../source/how-to-configure-clients.rst:69 msgid "" -"The built-in strategies call this function every round (that is, every time " -"`Strategy.configure_fit` or `Strategy.configure_evaluate` runs). Calling " -"`on_evaluate_config_fn` every round allows us to vary/change the config dict " -"over consecutive rounds. If we wanted to implement a hyperparameter " -"schedule, for example, to increase the number of local epochs during later " -"rounds, we could do the following:" +"The built-in strategies call this function every round (that is, every " +"time `Strategy.configure_fit` or `Strategy.configure_evaluate` runs). " +"Calling `on_evaluate_config_fn` every round allows us to vary/change the " +"config dict over consecutive rounds. If we wanted to implement a " +"hyperparameter schedule, for example, to increase the number of local " +"epochs during later rounds, we could do the following:" msgstr "" -"内置策略每轮都会调用此函数(即每次运行 `Strategy.configure_fit` 或 `Strategy." -"configure_evaluate` 时)。每轮调用 `on_evaluate_config_fn` 允许我们在连续几轮" -"中改变配置指令。例如,如果我们想实现一个超参数时间表,以增加后几轮的本地遍历" -"次数,我们可以这样做:" +"内置策略每轮都会调用此函数(即每次运行 `Strategy.configure_fit` 或 " +"`Strategy.configure_evaluate` 时)。每轮调用 `on_evaluate_config_fn` " +"允许我们在连续几轮中改变配置指令。例如,如果我们想实现一个超参数时间表,以增加后几轮的本地遍历次数,我们可以这样做:" #: ../../source/how-to-configure-clients.rst:82 msgid "The :code:`FedAvg` strategy will call this function *every round*." @@ -4821,18 +4355,19 @@ msgstr "在某些情况下,有必要向不同的客户端发送不同的配置 #: ../../source/how-to-configure-clients.rst:89 #, fuzzy msgid "" -"This can be achieved by customizing an existing strategy or by :doc:" -"`implementing a custom strategy from scratch `. " -"Here's a nonsensical example that customizes :code:`FedAvg` by adding a " -"custom ``\"hello\": \"world\"`` configuration key/value pair to the config " -"dict of a *single client* (only the first client in the list, the other " -"clients in this round to not receive this \"special\" config value):" +"This can be achieved by customizing an existing strategy or by " +":doc:`implementing a custom strategy from scratch `. Here's a nonsensical example that customizes :code:`FedAvg`" +" by adding a custom ``\"hello\": \"world\"`` configuration key/value pair" +" to the config dict of a *single client* (only the first client in the " +"list, the other clients in this round to not receive this \"special\" " +"config value):" msgstr "" -"这可以通过定制现有策略或 `从头开始实施一个定制策略 `_来实现。下面是一个无厘头的例子," -"`FedAvg`通过在*单个客户端*的配置指令(config dict)中添加自定义的" -"``\"hello\": \"world\"``配置键/值对添加到此的配置 dict 中(仅列表中的第一个" -"客户端,本轮中的其他客户端不会收到此 \"特殊 \"配置值):" +"这可以通过定制现有策略或 `从头开始实施一个定制策略 `_来实现。下面是一个无厘头的例子,`FedAvg`通过在*单个客户端*的配置指令(config " +"dict)中添加自定义的``\"hello\": \"world\"``配置键/值对添加到此的配置 dict " +"中(仅列表中的第一个客户端,本轮中的其他客户端不会收到此 \"特殊 \"配置值):" #: ../../source/how-to-configure-logging.rst:2 msgid "Configure logging" @@ -4841,21 +4376,19 @@ msgstr "配置日志记录" #: ../../source/how-to-configure-logging.rst:4 msgid "" "The Flower logger keeps track of all core events that take place in " -"federated learning workloads. It presents information by default following a " -"standard message format:" -msgstr "" -"Flower 日志记录器会跟踪联邦学习工作负载中发生的所有核心事件。它默认按照标准信" -"息格式提供信息:" +"federated learning workloads. It presents information by default " +"following a standard message format:" +msgstr "Flower 日志记录器会跟踪联邦学习工作负载中发生的所有核心事件。它默认按照标准信息格式提供信息:" #: ../../source/how-to-configure-logging.rst:13 msgid "" -"containing relevant information including: log message level (e.g. :code:" -"`INFO`, :code:`DEBUG`), a timestamp, the line where the logging took place " -"from, as well as the log message itself. In this way, the logger would " -"typically display information on your terminal as follows:" +"containing relevant information including: log message level (e.g. " +":code:`INFO`, :code:`DEBUG`), a timestamp, the line where the logging " +"took place from, as well as the log message itself. In this way, the " +"logger would typically display information on your terminal as follows:" msgstr "" -"相关信息包括:日志信息级别(例如 :code:`INFO`、:code:`DEBUG`)、时间戳、日志" -"记录的行以及日志信息本身。这样,日志记录器通常会在终端上显示如下信息:" +"相关信息包括:日志信息级别(例如 " +":code:`INFO`、:code:`DEBUG`)、时间戳、日志记录的行以及日志信息本身。这样,日志记录器通常会在终端上显示如下信息:" #: ../../source/how-to-configure-logging.rst:34 msgid "Saving log to file" @@ -4865,30 +4398,31 @@ msgstr "将日志保存到文件" msgid "" "By default, the Flower log is outputted to the terminal where you launch " "your Federated Learning workload from. This applies for both gRPC-based " -"federation (i.e. when you do :code:`fl.server.start_server`) and when using " -"the :code:`VirtualClientEngine` (i.e. when you do :code:`fl.simulation." -"start_simulation`). In some situations you might want to save this log to " -"disk. You can do so by calling the `fl.common.logger.configure() `_ function. " -"For example:" -msgstr "" -"默认情况下,Flower 日志会输出到启动联邦学习工作负载的终端。这既适用于基于 " -"gRPC 的联邦学习(即执行 :code:`fl.server.start_server` 时),也适用于使用 :" -"code:`VirtualClientEngine` 时(即执行 :code:`fl.simulation.start_simulation` " -"时)。在某些情况下,您可能希望将此日志保存到磁盘。为此,您可以调用 `fl." -"common.logger.configure() `_ 函数。例如:" +"federation (i.e. when you do :code:`fl.server.start_server`) and when " +"using the :code:`VirtualClientEngine` (i.e. when you do " +":code:`fl.simulation.start_simulation`). In some situations you might " +"want to save this log to disk. You can do so by calling the " +"`fl.common.logger.configure() " +"`_" +" function. For example:" +msgstr "" +"默认情况下,Flower 日志会输出到启动联邦学习工作负载的终端。这既适用于基于 gRPC 的联邦学习(即执行 " +":code:`fl.server.start_server` 时),也适用于使用 :code:`VirtualClientEngine` " +"时(即执行 :code:`fl.simulation.start_simulation` " +"时)。在某些情况下,您可能希望将此日志保存到磁盘。为此,您可以调用 `fl.common.logger.configure() " +"`_" +" 函数。例如:" #: ../../source/how-to-configure-logging.rst:53 msgid "" -"With the above, Flower will record the log you see on your terminal to :code:" -"`log.txt`. This file will be created in the same directory as were you are " -"running the code from. If we inspect we see the log above is also recorded " -"but prefixing with :code:`identifier` each line:" +"With the above, Flower will record the log you see on your terminal to " +":code:`log.txt`. This file will be created in the same directory as were " +"you are running the code from. If we inspect we see the log above is also" +" recorded but prefixing with :code:`identifier` each line:" msgstr "" -"通过上述操作,Flower 会将您在终端上看到的日志记录到 :code:`log.txt`。该文件将" -"创建在运行代码的同一目录下。如果我们检查一下,就会发现上面的日志也被记录了下" -"来,但每一行都以 :code:`identifier` 作为前缀:" +"通过上述操作,Flower 会将您在终端上看到的日志记录到 " +":code:`log.txt`。该文件将创建在运行代码的同一目录下。如果我们检查一下,就会发现上面的日志也被记录了下来,但每一行都以 " +":code:`identifier` 作为前缀:" #: ../../source/how-to-configure-logging.rst:74 msgid "Log your own messages" @@ -4896,19 +4430,16 @@ msgstr "记录自己的信息" #: ../../source/how-to-configure-logging.rst:76 msgid "" -"You might expand the information shown by default with the Flower logger by " -"adding more messages relevant to your application. You can achieve this " -"easily as follows." -msgstr "" -"您可以通过添加更多与应用程序相关的信息来扩展 Flower 日志记录器默认显示的信" -"息。您可以通过以下方法轻松实现这一目标。" +"You might expand the information shown by default with the Flower logger " +"by adding more messages relevant to your application. You can achieve " +"this easily as follows." +msgstr "您可以通过添加更多与应用程序相关的信息来扩展 Flower 日志记录器默认显示的信息。您可以通过以下方法轻松实现这一目标。" #: ../../source/how-to-configure-logging.rst:102 msgid "" -"In this way your logger will show, in addition to the default messages, the " -"ones introduced by the clients as specified above." -msgstr "" -"这样,除默认信息外,您的日志记录器还将显示由客户引入的信息,如上文所述。" +"In this way your logger will show, in addition to the default messages, " +"the ones introduced by the clients as specified above." +msgstr "这样,除默认信息外,您的日志记录器还将显示由客户引入的信息,如上文所述。" #: ../../source/how-to-configure-logging.rst:128 msgid "Log to a remote service" @@ -4916,167 +4447,149 @@ msgstr "登录远程服务" #: ../../source/how-to-configure-logging.rst:130 msgid "" -"The :code:`fl.common.logger.configure` function, also allows specifying a " -"host to which logs can be pushed (via :code:`POST`) through a native Python :" -"code:`logging.handler.HTTPHandler`. This is a particularly useful feature " -"in :code:`gRPC`-based Federated Learning workloads where otherwise gathering " -"logs from all entities (i.e. the server and the clients) might be " -"cumbersome. Note that in Flower simulation, the server automatically " -"displays all logs. You can still specify a :code:`HTTPHandler` should you " -"wish to backup or analyze the logs somewhere else." -msgstr "" -"此外,:code:`fl.common.logger.configure`函数还允许指定主机,通过本地 Python :" -"code:`logging.handler.HTTPHandler`,向该主机推送日志(通过 :code:`POST`)。在" -"基于 :code:`gRPC` 的联邦学习工作负载中,这是一个特别有用的功能,否则从所有实" -"体(即服务器和客户端)收集日志可能会很麻烦。请注意,在 Flower 模拟器中,服务" -"器会自动显示所有日志。如果希望在其他地方备份或分析日志,仍可指定 :code:" -"`HTTPHandler`。" +"The :code:`fl.common.logger.configure` function, also allows specifying a" +" host to which logs can be pushed (via :code:`POST`) through a native " +"Python :code:`logging.handler.HTTPHandler`. This is a particularly useful" +" feature in :code:`gRPC`-based Federated Learning workloads where " +"otherwise gathering logs from all entities (i.e. the server and the " +"clients) might be cumbersome. Note that in Flower simulation, the server " +"automatically displays all logs. You can still specify a " +":code:`HTTPHandler` should you wish to backup or analyze the logs " +"somewhere else." +msgstr "" +"此外,:code:`fl.common.logger.configure`函数还允许指定主机,通过本地 Python " +":code:`logging.handler.HTTPHandler`,向该主机推送日志(通过 :code:`POST`)。在基于 " +":code:`gRPC` 的联邦学习工作负载中,这是一个特别有用的功能,否则从所有实体(即服务器和客户端)收集日志可能会很麻烦。请注意,在 " +"Flower 模拟器中,服务器会自动显示所有日志。如果希望在其他地方备份或分析日志,仍可指定 :code:`HTTPHandler`。" #: ../../source/how-to-enable-ssl-connections.rst:2 msgid "Enable SSL connections" msgstr "启用 SSL 连接" #: ../../source/how-to-enable-ssl-connections.rst:4 +#, fuzzy msgid "" -"This guide describes how to a SSL-enabled secure Flower server can be " -"started and how a Flower client can establish a secure connections to it." -msgstr "" -"本指南介绍如何启动启用 SSL 的安全 Flower 服务器,以及 Flower 客户端如何与其建" -"立安全连接。" +"This guide describes how to a SSL-enabled secure Flower server " +"(:code:`SuperLink`) can be started and how a Flower client " +"(:code:`SuperNode`) can establish a secure connections to it." +msgstr "本指南介绍如何启动启用 SSL 的安全 Flower 服务器,以及 Flower 客户端如何与其建立安全连接。" #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" -"A complete code example demonstrating a secure connection can be found `here " -"`_." +"A complete code example demonstrating a secure connection can be found " +"`here `_." msgstr "" -"有关安全连接的完整代码示例,请参见 `_ 。" +"有关安全连接的完整代码示例,请参见 `_ 。" #: ../../source/how-to-enable-ssl-connections.rst:10 +#, fuzzy msgid "" -"The code example comes with a README.md file which will explain how to start " -"it. Although it is already SSL-enabled, it might be less descriptive on how. " -"Stick to this guide for a deeper introduction to the topic." -msgstr "" -"代码示例附带的 README.md 文件将解释如何启动它。虽然它已经启用了 SSL,但对如何" -"启用可能描述较少。请参考本指南,了解更深入的相关介绍。" +"The code example comes with a :code:`README.md` file which explains how " +"to start it. Although it is already SSL-enabled, it might be less " +"descriptive on how it does so. Stick to this guide for a deeper " +"introduction to the topic." +msgstr "代码示例附带的 README.md 文件将解释如何启动它。虽然它已经启用了 SSL,但对如何启用可能描述较少。请参考本指南,了解更深入的相关介绍。" #: ../../source/how-to-enable-ssl-connections.rst:16 msgid "Certificates" msgstr "证书" #: ../../source/how-to-enable-ssl-connections.rst:18 +#, fuzzy msgid "" "Using SSL-enabled connections requires certificates to be passed to the " -"server and client. For the purpose of this guide we are going to generate " -"self-signed certificates. As this can become quite complex we are going to " -"ask you to run the script in :code:`examples/advanced-tensorflow/" -"certificates/generate.sh`" +"server and client. For the purpose of this guide we are going to generate" +" self-signed certificates. As this can become quite complex we are going " +"to ask you to run the script in :code:`examples/advanced-" +"tensorflow/certificates/generate.sh` with the following command sequence:" msgstr "" -"使用支持 SSL 的连接需要向服务器和客户端传递证书。在本指南中,我们将生成自签名" -"证书。由于这可能会变得相当复杂,我们将要求你运行 :code:`examples/advanced-" -"tensorflow/certificates/generate.sh` 中的脚本" - -#: ../../source/how-to-enable-ssl-connections.rst:23 -msgid "with the following command sequence:" -msgstr "使用以下命令序列:" +"使用支持 SSL 的连接需要向服务器和客户端传递证书。在本指南中,我们将生成自签名证书。由于这可能会变得相当复杂,我们将要求你运行 " +":code:`examples/advanced-tensorflow/certificates/generate.sh` 中的脚本" -#: ../../source/how-to-enable-ssl-connections.rst:30 +#: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" -"This will generate the certificates in :code:`examples/advanced-tensorflow/." -"cache/certificates`." -msgstr "" -"这将在 :code:`examples/advanced-tensorflow/.cache/certificates` 中生成证书。" +"This will generate the certificates in :code:`examples/advanced-" +"tensorflow/.cache/certificates`." +msgstr "这将在 :code:`examples/advanced-tensorflow/.cache/certificates` 中生成证书。" -#: ../../source/how-to-enable-ssl-connections.rst:32 +#: ../../source/how-to-enable-ssl-connections.rst:31 +#, fuzzy msgid "" -"The approach how the SSL certificates are generated in this example can " -"serve as an inspiration and starting point but should not be taken as " -"complete for production environments. Please refer to other sources " -"regarding the issue of correctly generating certificates for production " -"environments." -msgstr "" -"本示例中生成 SSL 证书的方法可作为启发和起点,但不应被视为生产环境的完整方法。" -"有关在生产环境中正确生成证书的问题,请参考其他资料。" +"The approach for generating SSL certificates in the context of this " +"example can serve as an inspiration and starting point, but it should not" +" be used as a reference for production environments. Please refer to " +"other sources regarding the issue of correctly generating certificates " +"for production environments. For non-critical prototyping or research " +"projects, it might be sufficient to use the self-signed certificates " +"generated using the scripts mentioned in this guide." +msgstr "本示例中生成 SSL 证书的方法可作为启发和起点,但不应被视为生产环境的完整方法。有关在生产环境中正确生成证书的问题,请参考其他资料。" -#: ../../source/how-to-enable-ssl-connections.rst:36 -msgid "" -"In case you are a researcher you might be just fine using the self-signed " -"certificates generated using the scripts which are part of this guide." -msgstr "如果你是一名研究人员,使用本指南中的脚本生成的自签名证书就可以了。" +#: ../../source/how-to-enable-ssl-connections.rst:39 +#, fuzzy +msgid "Server (SuperLink)" +msgstr "flower-superlink" #: ../../source/how-to-enable-ssl-connections.rst:41 -#: ../../source/ref-api/flwr.server.Server.rst:2 -msgid "Server" -msgstr "服务器" - -#: ../../source/how-to-enable-ssl-connections.rst:43 +#, fuzzy msgid "" -"We are now going to show how to write a sever which uses the previously " -"generated scripts." -msgstr "现在,我们将展示如何编写一个使用先前生成的脚本的服务器。" +"Use the following terminal command to start a sever (SuperLink) that uses" +" the previously generated certificates:" +msgstr "现在我们将演示如何编写一个客户端,使用之前生成的脚本:" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:47 +#, fuzzy msgid "" "When providing certificates, the server expects a tuple of three " -"certificates. :code:`Path` can be used to easily read the contents of those " -"files into byte strings, which is the data type :code:`start_server` expects." -msgstr "" -"在提供证书时,服务器希望得到由三个证书组成的元组。 :code:`Path` 可用于轻松地" -"将这些文件的内容读取为字节字符串,这就是 :code:`start_server` 期望的数据类" -"型。" +"certificates paths: CA certificate, server certificate and server private" +" key." +msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" -#: ../../source/how-to-enable-ssl-connections.rst:65 -#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 -#: ../../source/ref-api/flwr.client.Client.rst:2 -msgid "Client" -msgstr "客户端" +#: ../../source/how-to-enable-ssl-connections.rst:51 +#, fuzzy +msgid "Client (SuperNode)" +msgstr "客户端状态代码。" -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:53 +#, fuzzy msgid "" -"We are now going to show how to write a client which uses the previously " -"generated scripts:" +"Use the following terminal command to start a client (SuperNode) that " +"uses the previously generated certificates:" msgstr "现在我们将演示如何编写一个客户端,使用之前生成的脚本:" -#: ../../source/how-to-enable-ssl-connections.rst:84 +#: ../../source/how-to-enable-ssl-connections.rst:61 +#, fuzzy msgid "" -"When setting :code:`root_certificates`, the client expects the PEM-encoded " -"root certificates as a byte string. We are again using :code:`Path` to " -"simplify reading those as byte strings." +"When setting :code:`root_certificates`, the client expects a file path to" +" PEM-encoded root certificates." msgstr "" -"当设置 :code:`root_certificates` 时,客户端希望 PEM 编码的根证书是字节字符" -"串。我们再次使用 :code:`Path` 来简化以字节字符串形式读取证书的过程。" - -#: ../../source/how-to-enable-ssl-connections.rst:89 -#: ../../source/how-to-use-built-in-mods.rst:85 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 -msgid "Conclusion" -msgstr "总结" +"当设置 :code:`root_certificates` 时,客户端希望 PEM 编码的根证书是字节字符串。我们再次使用 " +":code:`Path` 来简化以字节字符串形式读取证书的过程。" -#: ../../source/how-to-enable-ssl-connections.rst:91 +#: ../../source/how-to-enable-ssl-connections.rst:67 +#, fuzzy msgid "" -"You should now have learned how to generate self-signed certificates using " -"the given script, start a SSL-enabled server, and have a client establish a " -"secure connection to it." -msgstr "" -"现在,你应该已经学会了如何使用给定的脚本生成自签名证书、启动启用 SSL 的服务器" -"并让客户端与其建立安全连接。" +"You should now have learned how to generate self-signed certificates " +"using the given script, start an SSL-enabled server and have a client " +"establish a secure connection to it." +msgstr "现在,你应该已经学会了如何使用给定的脚本生成自签名证书、启动启用 SSL 的服务器并让客户端与其建立安全连接。" -#: ../../source/how-to-enable-ssl-connections.rst:96 +#: ../../source/how-to-enable-ssl-connections.rst:72 msgid "Additional resources" msgstr "补充资源" -#: ../../source/how-to-enable-ssl-connections.rst:98 +#: ../../source/how-to-enable-ssl-connections.rst:74 msgid "" -"These additional sources might be relevant if you would like to dive deeper " -"into the topic of certificates:" +"These additional sources might be relevant if you would like to dive " +"deeper into the topic of certificates:" msgstr "如果您想更深入地了解证书主题,这些额外的资料来源可能有帮助:" -#: ../../source/how-to-enable-ssl-connections.rst:100 +#: ../../source/how-to-enable-ssl-connections.rst:76 msgid "`Let's Encrypt `_" msgstr "`让我们加密 `_" -#: ../../source/how-to-enable-ssl-connections.rst:101 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "`certbot `_" msgstr "`certbot `_" @@ -5086,16 +4599,15 @@ msgstr "实施策略" #: ../../source/how-to-implement-strategies.rst:4 msgid "" -"The strategy abstraction enables implementation of fully custom strategies. " -"A strategy is basically the federated learning algorithm that runs on the " -"server. Strategies decide how to sample clients, how to configure clients " -"for training, how to aggregate updates, and how to evaluate models. Flower " -"provides a few built-in strategies which are based on the same API described " -"below." +"The strategy abstraction enables implementation of fully custom " +"strategies. A strategy is basically the federated learning algorithm that" +" runs on the server. Strategies decide how to sample clients, how to " +"configure clients for training, how to aggregate updates, and how to " +"evaluate models. Flower provides a few built-in strategies which are " +"based on the same API described below." msgstr "" -"策略抽象类可以实现完全定制的策略。策略基本上就是在服务器上运行的联邦学习算" -"法。策略决定如何对客户端进行采样、如何配置客户端进行训练、如何聚合参数更新以" -"及如何评估模型。Flower 提供了一些内置策略,这些策略基于下文所述的相同 API。" +"策略抽象类可以实现完全定制的策略。策略基本上就是在服务器上运行的联邦学习算法。策略决定如何对客户端进行采样、如何配置客户端进行训练、如何聚合参数更新以及如何评估模型。Flower" +" 提供了一些内置策略,这些策略基于下文所述的相同 API。" #: ../../source/how-to-implement-strategies.rst:11 msgid "The :code:`Strategy` abstraction" @@ -5103,13 +4615,14 @@ msgstr ":code:`策略 ` 抽象类" #: ../../source/how-to-implement-strategies.rst:13 msgid "" -"All strategy implementation are derived from the abstract base class :code:" -"`flwr.server.strategy.Strategy`, both built-in implementations and third " -"party implementations. This means that custom strategy implementations have " -"the exact same capabilities at their disposal as built-in ones." +"All strategy implementation are derived from the abstract base class " +":code:`flwr.server.strategy.Strategy`, both built-in implementations and " +"third party implementations. This means that custom strategy " +"implementations have the exact same capabilities at their disposal as " +"built-in ones." msgstr "" -"所有策略实现均源自抽象基类 :code:`flwr.server.strategy.Strategy`,包括内置实" -"现和第三方实现。这意味着自定义策略实现与内置实现具有完全相同的功能。" +"所有策略实现均源自抽象基类 " +":code:`flwr.server.strategy.Strategy`,包括内置实现和第三方实现。这意味着自定义策略实现与内置实现具有完全相同的功能。" #: ../../source/how-to-implement-strategies.rst:18 msgid "" @@ -5119,12 +4632,10 @@ msgstr "策略抽象定义了一些需要实现的抽象方法:" #: ../../source/how-to-implement-strategies.rst:75 msgid "" -"Creating a new strategy means implementing a new :code:`class` (derived from " -"the abstract base class :code:`Strategy`) that implements for the previously " -"shown abstract methods:" -msgstr "" -"创建一个新策略意味着要实现一个新的 :code:`class`(从抽象基类 :code:" -"`Strategy` 派生),该类要实现前面显示的抽象方法:" +"Creating a new strategy means implementing a new :code:`class` (derived " +"from the abstract base class :code:`Strategy`) that implements for the " +"previously shown abstract methods:" +msgstr "创建一个新策略意味着要实现一个新的 :code:`class`(从抽象基类 :code:`Strategy` 派生),该类要实现前面显示的抽象方法:" #: ../../source/how-to-implement-strategies.rst:100 msgid "The Flower server calls these methods in the following order:" @@ -5140,48 +4651,44 @@ msgstr ":code:`初始化参数` 方法" #: ../../source/how-to-implement-strategies.rst:182 msgid "" -":code:`initialize_parameters` is called only once, at the very beginning of " -"an execution. It is responsible for providing the initial global model " -"parameters in a serialized form (i.e., as a :code:`Parameters` object)." +":code:`initialize_parameters` is called only once, at the very beginning " +"of an execution. It is responsible for providing the initial global model" +" parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" -":code:`initialize_parameters` 只调用一次,即在执行开始时。它负责以序列化形式" -"(即 :code:`Parameters` 对象)提供初始全局模型参数。" +":code:`initialize_parameters` 只调用一次,即在执行开始时。它负责以序列化形式(即 " +":code:`Parameters` 对象)提供初始全局模型参数。" #: ../../source/how-to-implement-strategies.rst:184 msgid "" -"Built-in strategies return user-provided initial parameters. The following " -"example shows how initial parameters can be passed to :code:`FedAvg`:" -msgstr "" -"内置策略会返回用户提供的初始参数。下面的示例展示了如何将初始参数传递给 :code:" -"`FedAvg`:" +"Built-in strategies return user-provided initial parameters. The " +"following example shows how initial parameters can be passed to " +":code:`FedAvg`:" +msgstr "内置策略会返回用户提供的初始参数。下面的示例展示了如何将初始参数传递给 :code:`FedAvg`:" #: ../../source/how-to-implement-strategies.rst:209 msgid "" "The Flower server will call :code:`initialize_parameters`, which either " -"returns the parameters that were passed to :code:`initial_parameters`, or :" -"code:`None`. If no parameters are returned from :code:" -"`initialize_parameters` (i.e., :code:`None`), the server will randomly " -"select one client and ask it to provide its parameters. This is a " -"convenience feature and not recommended in practice, but it can be useful " -"for prototyping. In practice, it is recommended to always use server-side " -"parameter initialization." -msgstr "" -"Flower 服务器将调用 :code:`initialize_parameters`,返回传给 :code:" -"`initial_parameters` 的参数或 :code:`None`。如果 :code:" -"`initialize_parameters` 没有返回任何参数(即 :code:`None`),服务器将随机选择" -"一个客户端并要求其提供参数。这只是一个便捷的功能,在实际应用中并不推荐使用," -"但在原型开发中可能很有用。在实践中,建议始终使用服务器端参数初始化。" +"returns the parameters that were passed to :code:`initial_parameters`, or" +" :code:`None`. If no parameters are returned from " +":code:`initialize_parameters` (i.e., :code:`None`), the server will " +"randomly select one client and ask it to provide its parameters. This is " +"a convenience feature and not recommended in practice, but it can be " +"useful for prototyping. In practice, it is recommended to always use " +"server-side parameter initialization." +msgstr "" +"Flower 服务器将调用 :code:`initialize_parameters`,返回传给 " +":code:`initial_parameters` 的参数或 :code:`None`。如果 " +":code:`initialize_parameters` 没有返回任何参数(即 " +":code:`None`),服务器将随机选择一个客户端并要求其提供参数。这只是一个便捷的功能,在实际应用中并不推荐使用,但在原型开发中可能很有用。在实践中,建议始终使用服务器端参数初始化。" #: ../../source/how-to-implement-strategies.rst:213 msgid "" "Server-side parameter initialization is a powerful mechanism. It can be " -"used, for example, to resume training from a previously saved checkpoint. It " -"is also the fundamental capability needed to implement hybrid approaches, " -"for example, to fine-tune a pre-trained model using federated learning." -msgstr "" -"服务器端参数初始化是一种强大的机制。例如,它可以用来从先前保存的检查点恢复训" -"练。它也是实现混合方法所需的基本能力,例如,使用联邦学习对预先训练好的模型进" -"行微调。" +"used, for example, to resume training from a previously saved checkpoint." +" It is also the fundamental capability needed to implement hybrid " +"approaches, for example, to fine-tune a pre-trained model using federated" +" learning." +msgstr "服务器端参数初始化是一种强大的机制。例如,它可以用来从先前保存的检查点恢复训练。它也是实现混合方法所需的基本能力,例如,使用联邦学习对预先训练好的模型进行微调。" #: ../../source/how-to-implement-strategies.rst:216 msgid "The :code:`configure_fit` method" @@ -5189,23 +4696,21 @@ msgstr ":code:`configure_fit`方法" #: ../../source/how-to-implement-strategies.rst:218 msgid "" -":code:`configure_fit` is responsible for configuring the upcoming round of " -"training. What does *configure* mean in this context? Configuring a round " -"means selecting clients and deciding what instructions to send to these " -"clients. The signature of :code:`configure_fit` makes this clear:" +":code:`configure_fit` is responsible for configuring the upcoming round " +"of training. What does *configure* mean in this context? Configuring a " +"round means selecting clients and deciding what instructions to send to " +"these clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" -":code:`configure_fit` 负责配置即将开始的一轮训练。*配置*在这里是什么意思?配" -"置一轮训练意味着选择客户并决定向这些客户发送什么指令。:code:`configure_fit` " -"说明了这一点:" +":code:`configure_fit` " +"负责配置即将开始的一轮训练。*配置*在这里是什么意思?配置一轮训练意味着选择客户并决定向这些客户发送什么指令。:code:`configure_fit`" +" 说明了这一点:" #: ../../source/how-to-implement-strategies.rst:231 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations usually " -"perform the following steps in :code:`configure_fit`:" -msgstr "" -"返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :" -"code:`configure_fit` 中执行以下步骤:" +"that will be sent to a particular client. Strategy implementations " +"usually perform the following steps in :code:`configure_fit`:" +msgstr "返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :code:`configure_fit` 中执行以下步骤:" #: ../../source/how-to-implement-strategies.rst:233 #: ../../source/how-to-implement-strategies.rst:280 @@ -5213,40 +4718,39 @@ msgid "" "Use the :code:`client_manager` to randomly sample all (or a subset of) " "available clients (each represented as a :code:`ClientProxy` object)" msgstr "" -"使用 :code:`client_manager` 随机抽样所有(或部分)可用客户端(每个客户端都表" -"示为 :code:`ClientProxy` 对象)" +"使用 :code:`client_manager` 随机抽样所有(或部分)可用客户端(每个客户端都表示为 :code:`ClientProxy` " +"对象)" #: ../../source/how-to-implement-strategies.rst:234 msgid "" "Pair each :code:`ClientProxy` with the same :code:`FitIns` holding the " "current global model :code:`parameters` and :code:`config` dict" msgstr "" -"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:" -"`config` dict 的 :code:`FitIns` 配对" +"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:`config` " +"dict 的 :code:`FitIns` 配对" #: ../../source/how-to-implement-strategies.rst:236 #, fuzzy msgid "" "More sophisticated implementations can use :code:`configure_fit` to " -"implement custom client selection logic. A client will only participate in a " -"round if the corresponding :code:`ClientProxy` is included in the list " -"returned from :code:`configure_fit`." +"implement custom client selection logic. A client will only participate " +"in a round if the corresponding :code:`ClientProxy` is included in the " +"list returned from :code:`configure_fit`." msgstr "" -"更复杂的实现可以使用 :code:`configure_fit` 来实现自定义的客户端选择逻辑。只有" -"当相应的 :code:`ClientProxy` 包含在 :code:`configure_fit` 返回的列表中时,客" -"户端才会参与进来。" +"更复杂的实现可以使用 :code:`configure_fit` 来实现自定义的客户端选择逻辑。只有当相应的 " +":code:`ClientProxy` 包含在 :code:`configure_fit` 返回的列表中时,客户端才会参与进来。" #: ../../source/how-to-implement-strategies.rst:240 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies to " -"train, for example, different models on different clients, or use different " -"hyperparameters on different clients (via the :code:`config` dict)." +"instructions can be sent to each client. This enables custom strategies " +"to train, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` " +"dict)." msgstr "" -"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向" -"每个客户端发送不同的指令。这使得自定义策略成为可能,例如在不同的客户端上训练" -"不同的模型,或在不同的客户端上使用不同的超参数(通过 :code:`config` dict)。" +"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向每个客户端发送不同的指令。这使得自定义策略成为可能,例如在不同的客户端上训练不同的模型,或在不同的客户端上使用不同的超参数(通过" +" :code:`config` dict)。" #: ../../source/how-to-implement-strategies.rst:243 msgid "The :code:`aggregate_fit` method" @@ -5254,33 +4758,31 @@ msgstr ":code:`aggregate_fit` 方法" #: ../../source/how-to-implement-strategies.rst:245 msgid "" -":code:`aggregate_fit` is responsible for aggregating the results returned by " -"the clients that were selected and asked to train in :code:`configure_fit`." -msgstr "" -":code:`aggregate_fit` 负责汇总在 :code:`configure_fit` 中选择并要求训练的客户" -"端所返回的结果。" +":code:`aggregate_fit` is responsible for aggregating the results returned" +" by the clients that were selected and asked to train in " +":code:`configure_fit`." +msgstr ":code:`aggregate_fit` 负责汇总在 :code:`configure_fit` 中选择并要求训练的客户端所返回的结果。" #: ../../source/how-to-implement-strategies.rst:258 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via :code:" -"`configure_fit`). :code:`aggregate_fit` therefore receives a list of :code:" -"`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via " +":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " +"of :code:`results`, but also a list of :code:`failures`." msgstr "" -"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:" -"`configure_fit`)的所有客户端获得结果。因此 :code:`aggregate_fit` 会收到 :" -"code:`results` 的列表,但也会收到 :code:`failures` 的列表。" +"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:`configure_fit`)的所有客户端获得结果。因此 " +":code:`aggregate_fit` 会收到 :code:`results` 的列表,但也会收到 :code:`failures` 的列表。" #: ../../source/how-to-implement-strategies.rst:260 msgid "" -":code:`aggregate_fit` returns an optional :code:`Parameters` object and a " -"dictionary of aggregated metrics. The :code:`Parameters` return value is " -"optional because :code:`aggregate_fit` might decide that the results " +":code:`aggregate_fit` returns an optional :code:`Parameters` object and a" +" dictionary of aggregated metrics. The :code:`Parameters` return value is" +" optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" -":code:`aggregate_fit` 返回一个可选的 :code:`Parameters` 对象和一个聚合度量的" -"字典。:code:`Parameters` 返回值是可选的,因为 :code:`aggregate_fit` 可能会认" -"为所提供的结果不足以进行聚合(例如,失败次数过多)。" +":code:`aggregate_fit` 返回一个可选的 :code:`Parameters` " +"对象和一个聚合度量的字典。:code:`Parameters` 返回值是可选的,因为 :code:`aggregate_fit` " +"可能会认为所提供的结果不足以进行聚合(例如,失败次数过多)。" #: ../../source/how-to-implement-strategies.rst:263 msgid "The :code:`configure_evaluate` method" @@ -5288,55 +4790,53 @@ msgstr ":code:`configure_evaluate`方法" #: ../../source/how-to-implement-strategies.rst:265 msgid "" -":code:`configure_evaluate` is responsible for configuring the upcoming round " -"of evaluation. What does *configure* mean in this context? Configuring a " -"round means selecting clients and deciding what instructions to send to " -"these clients. The signature of :code:`configure_evaluate` makes this clear:" +":code:`configure_evaluate` is responsible for configuring the upcoming " +"round of evaluation. What does *configure* mean in this context? " +"Configuring a round means selecting clients and deciding what " +"instructions to send to these clients. The signature of " +":code:`configure_evaluate` makes this clear:" msgstr "" -":code:`configure_evaluate` 负责配置下一轮评估。*配置*在这里是什么意思?配置一" -"轮评估意味着选择客户端并决定向这些客户端发送什么指令。:code:" -"`configure_evaluate` 说明了这一点:" +":code:`configure_evaluate` " +"负责配置下一轮评估。*配置*在这里是什么意思?配置一轮评估意味着选择客户端并决定向这些客户端发送什么指令。:code:`configure_evaluate`" +" 说明了这一点:" #: ../../source/how-to-implement-strategies.rst:278 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations usually " -"perform the following steps in :code:`configure_evaluate`:" -msgstr "" -"返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :" -"code:`configure_evaluate` 中执行以下步骤:" +"that will be sent to a particular client. Strategy implementations " +"usually perform the following steps in :code:`configure_evaluate`:" +msgstr "返回值是一个元组列表,每个元组代表将发送到特定客户端的指令。策略实现通常在 :code:`configure_evaluate` 中执行以下步骤:" #: ../../source/how-to-implement-strategies.rst:281 msgid "" -"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding the " -"current global model :code:`parameters` and :code:`config` dict" +"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " +"the current global model :code:`parameters` and :code:`config` dict" msgstr "" -"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:" -"`config` dict 的 :code:`EvaluateIns` 配对" +"将每个 :code:`ClientProxy` 与持有当前全局模型 :code:`parameters` 和 :code:`config` " +"dict 的 :code:`EvaluateIns` 配对" #: ../../source/how-to-implement-strategies.rst:283 #, fuzzy msgid "" "More sophisticated implementations can use :code:`configure_evaluate` to " -"implement custom client selection logic. A client will only participate in a " -"round if the corresponding :code:`ClientProxy` is included in the list " -"returned from :code:`configure_evaluate`." +"implement custom client selection logic. A client will only participate " +"in a round if the corresponding :code:`ClientProxy` is included in the " +"list returned from :code:`configure_evaluate`." msgstr "" -"更复杂的实现可以使用 :code:`configure_evaluate` 来实现自定义的客户端选择逻" -"辑。只有当相应的 :code:`ClientProxy` 包含在 :code:`configure_evaluate` 返回的" -"列表中时,客户端才会参与进来。" +"更复杂的实现可以使用 :code:`configure_evaluate` 来实现自定义的客户端选择逻辑。只有当相应的 " +":code:`ClientProxy` 包含在 :code:`configure_evaluate` 返回的列表中时,客户端才会参与进来。" #: ../../source/how-to-implement-strategies.rst:287 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies to " -"evaluate, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` dict)." +"instructions can be sent to each client. This enables custom strategies " +"to evaluate, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` " +"dict)." msgstr "" -"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向" -"每个客户端发送不同的指令。这使得自定义策略可以在不同客户端上评估不同的模型," -"或在不同客户端上使用不同的超参数(通过 :code:`config` dict)。" +"该返回值的结构为用户提供了很大的灵活性。由于指令是按客户端定义的,因此可以向每个客户端发送不同的指令。这使得自定义策略可以在不同客户端上评估不同的模型,或在不同客户端上使用不同的超参数(通过" +" :code:`config` dict)。" #: ../../source/how-to-implement-strategies.rst:291 msgid "The :code:`aggregate_evaluate` method" @@ -5345,34 +4845,33 @@ msgstr ":code:`aggregate_evaluate` 方法" #: ../../source/how-to-implement-strategies.rst:293 msgid "" ":code:`aggregate_evaluate` is responsible for aggregating the results " -"returned by the clients that were selected and asked to evaluate in :code:" -"`configure_evaluate`." +"returned by the clients that were selected and asked to evaluate in " +":code:`configure_evaluate`." msgstr "" -":code:`aggregate_evaluate` 负责汇总在 :code:`configure_evaluate` 中选择并要求" -"评估的客户端返回的结果。" +":code:`aggregate_evaluate` 负责汇总在 :code:`configure_evaluate` " +"中选择并要求评估的客户端返回的结果。" #: ../../source/how-to-implement-strategies.rst:306 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via :code:" -"`configure_evaluate`). :code:`aggregate_evaluate` therefore receives a list " -"of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via " +":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " +"receives a list of :code:`results`, but also a list of :code:`failures`." msgstr "" -"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 :code:" -"`configure_evaluate`)的所有客户端获得结果。因此, :code:" -"`aggregate_evaluate` 会接收 :code:`results` 的列表,但也会接收 :code:" -"`failures` 的列表。" +"当然,失败是有可能发生的,因此无法保证服务器会从它发送指令(通过 " +":code:`configure_evaluate`)的所有客户端获得结果。因此, :code:`aggregate_evaluate` 会接收 " +":code:`results` 的列表,但也会接收 :code:`failures` 的列表。" #: ../../source/how-to-implement-strategies.rst:308 msgid "" -":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a " -"dictionary of aggregated metrics. The :code:`float` return value is optional " -"because :code:`aggregate_evaluate` might decide that the results provided " -"are not sufficient for aggregation (e.g., too many failures)." +":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a" +" dictionary of aggregated metrics. The :code:`float` return value is " +"optional because :code:`aggregate_evaluate` might decide that the results" +" provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" -":code:`aggregate_evaluate` 返回一个可选的 :code:`float`(损失值)和一个聚合指" -"标字典。:code:`float` 返回值是可选的,因为 :code:`aggregate_evaluate` 可能会" -"认为所提供的结果不足以进行聚合(例如,失败次数过多)。" +":code:`aggregate_evaluate` 返回一个可选的 " +":code:`float`(损失值)和一个聚合指标字典。:code:`float` 返回值是可选的,因为 " +":code:`aggregate_evaluate` 可能会认为所提供的结果不足以进行聚合(例如,失败次数过多)。" #: ../../source/how-to-implement-strategies.rst:311 msgid "The :code:`evaluate` method" @@ -5381,24 +4880,23 @@ msgstr ":code:`evaluate`方法" #: ../../source/how-to-implement-strategies.rst:313 msgid "" ":code:`evaluate` is responsible for evaluating model parameters on the " -"server-side. Having :code:`evaluate` in addition to :code:" -"`configure_evaluate`/:code:`aggregate_evaluate` enables strategies to " -"perform both servers-side and client-side (federated) evaluation." +"server-side. Having :code:`evaluate` in addition to " +":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " +"to perform both servers-side and client-side (federated) evaluation." msgstr "" -":code:`evaluate` 负责在服务器端评估模型参数。除了 :code:" -"`configure_evaluate`/:code:`aggregate_evaluate` 之外,:code:`evaluate` 可以使" -"策略同时执行服务器端和客户端(联邦)评估。" +":code:`evaluate` 负责在服务器端评估模型参数。除了 " +":code:`configure_evaluate`/:code:`aggregate_evaluate` 之外,:code:`evaluate`" +" 可以使策略同时执行服务器端和客户端(联邦)评估。" #: ../../source/how-to-implement-strategies.rst:323 msgid "" -"The return value is again optional because the strategy might not need to " -"implement server-side evaluation or because the user-defined :code:" -"`evaluate` method might not complete successfully (e.g., it might fail to " -"load the server-side evaluation data)." +"The return value is again optional because the strategy might not need to" +" implement server-side evaluation or because the user-defined " +":code:`evaluate` method might not complete successfully (e.g., it might " +"fail to load the server-side evaluation data)." msgstr "" -"返回值也是可选的,因为策略可能不需要执行服务器端评估,或者因为用户定义的 :" -"code:`evaluate` 方法可能无法成功完成(例如,它可能无法加载服务器端评估数" -"据)。" +"返回值也是可选的,因为策略可能不需要执行服务器端评估,或者因为用户定义的 :code:`evaluate` " +"方法可能无法成功完成(例如,它可能无法加载服务器端评估数据)。" #: ../../source/how-to-install-flower.rst:2 msgid "Install Flower" @@ -5413,13 +4911,15 @@ msgid "Install stable release" msgstr "安装稳定版" #: ../../source/how-to-install-flower.rst:15 +#: ../../source/how-to-upgrade-to-flower-next.rst:46 #, fuzzy msgid "Using pip" msgstr "使用 pip" #: ../../source/how-to-install-flower.rst:17 msgid "" -"Stable releases are available on `PyPI `_::" +"Stable releases are available on `PyPI " +"`_::" msgstr "稳定版本可在 `PyPI `_::" #: ../../source/how-to-install-flower.rst:21 @@ -5441,15 +4941,15 @@ msgstr "Flower 也可以从 ``conda-forge`` 频道安装。" #: ../../source/how-to-install-flower.rst:31 #, fuzzy msgid "" -"If you have not added ``conda-forge`` to your channels, you will first need " -"to run the following::" +"If you have not added ``conda-forge`` to your channels, you will first " +"need to run the following::" msgstr "如果您尚未在频道中添加 ``conda-forge``,则首先需要运行以下程序::" #: ../../source/how-to-install-flower.rst:36 #, fuzzy msgid "" -"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be installed " -"with ``conda``::" +"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " +"installed with ``conda``::" msgstr "一旦启用了 ``conda-forge`` 频道,就可以使用 ``conda``: 安装 ``flwr``:" #: ../../source/how-to-install-flower.rst:40 @@ -5465,11 +4965,9 @@ msgstr "验证安装" #, fuzzy msgid "" "The following command can be used to verify if Flower was successfully " -"installed. If everything worked, it should print the version of Flower to " -"the command line::" -msgstr "" -"可以使用以下命令来验证 Flower 是否安装成功。如果一切正常,它将在命令行中打印 " -"Flower 的版本::" +"installed. If everything worked, it should print the version of Flower to" +" the command line::" +msgstr "可以使用以下命令来验证 Flower 是否安装成功。如果一切正常,它将在命令行中打印 Flower 的版本::" #: ../../source/how-to-install-flower.rst:55 msgid "Advanced installation options" @@ -5493,19 +4991,16 @@ msgstr "安装预发布版本" #: ../../source/how-to-install-flower.rst:65 msgid "" -"New (possibly unstable) versions of Flower are sometimes available as pre-" -"release versions (alpha, beta, release candidate) before the stable release " -"happens::" -msgstr "" -"在稳定版发布之前,Flower 的新版本(可能是不稳定版)有时会作为预发布版本" -"(alpha、beta、候选发布版本)提供::" +"New (possibly unstable) versions of Flower are sometimes available as " +"pre-release versions (alpha, beta, release candidate) before the stable " +"release happens::" +msgstr "在稳定版发布之前,Flower 的新版本(可能是不稳定版)有时会作为预发布版本(alpha、beta、候选发布版本)提供::" #: ../../source/how-to-install-flower.rst:69 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases " -"should be installed with the ``simulation`` extra::" -msgstr "" -"对于使用虚拟客户端引擎的模拟,`flwr``预发行版应与`simulation``一起安装:" +"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" +" should be installed with the ``simulation`` extra::" +msgstr "对于使用虚拟客户端引擎的模拟,`flwr``预发行版应与`simulation``一起安装:" #: ../../source/how-to-install-flower.rst:74 msgid "Install nightly release" @@ -5513,14 +5008,14 @@ msgstr "安装隔夜版本" #: ../../source/how-to-install-flower.rst:76 msgid "" -"The latest (potentially unstable) changes in Flower are available as nightly " -"releases::" +"The latest (potentially unstable) changes in Flower are available as " +"nightly releases::" msgstr "Flower 中最新(可能不稳定)的更改以隔夜发布的形式提供::" #: ../../source/how-to-install-flower.rst:80 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr-nightly`` should " -"be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr-nightly`` " +"should be installed with the ``simulation`` extra::" msgstr "对于使用虚拟客户端引擎的模拟,`flwr-nightly`应与`simulation`一起安装:" #: ../../source/how-to-monitor-simulation.rst:2 @@ -5529,23 +5024,20 @@ msgstr "监控模拟" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" -"Flower allows you to monitor system resources while running your simulation. " -"Moreover, the Flower simulation engine is powerful and enables you to decide " -"how to allocate resources per client manner and constrain the total usage. " -"Insights from resource consumption can help you make smarter decisions and " -"speed up the execution time." +"Flower allows you to monitor system resources while running your " +"simulation. Moreover, the Flower simulation engine is powerful and " +"enables you to decide how to allocate resources per client manner and " +"constrain the total usage. Insights from resource consumption can help " +"you make smarter decisions and speed up the execution time." msgstr "" -"Flower 允许您在运行模拟时监控系统资源。此外,Flower 仿真引擎功能强大,能让您" -"决定如何按客户端方式分配资源并限制总使用量。从资源消耗中获得的观察可以帮助您" -"做出更明智的决策,并加快执行时间。" +"Flower 允许您在运行模拟时监控系统资源。此外,Flower " +"仿真引擎功能强大,能让您决定如何按客户端方式分配资源并限制总使用量。从资源消耗中获得的观察可以帮助您做出更明智的决策,并加快执行时间。" #: ../../source/how-to-monitor-simulation.rst:6 msgid "" -"The specific instructions assume you are using macOS and have the `Homebrew " -"`_ package manager installed." -msgstr "" -"具体说明假定你使用的是 macOS,并且安装了 `Homebrew `_ 软件" -"包管理器。" +"The specific instructions assume you are using macOS and have the " +"`Homebrew `_ package manager installed." +msgstr "具体说明假定你使用的是 macOS,并且安装了 `Homebrew `_ 软件包管理器。" #: ../../source/how-to-monitor-simulation.rst:10 msgid "Downloads" @@ -5553,14 +5045,14 @@ msgstr "下载" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" -"`Prometheus `_ is used for data collection, while " -"`Grafana `_ will enable you to visualize the collected " -"data. They are both well integrated with `Ray `_ which " -"Flower uses under the hood." +"`Prometheus `_ is used for data collection, while" +" `Grafana `_ will enable you to visualize the " +"collected data. They are both well integrated with `Ray " +"`_ which Flower uses under the hood." msgstr "" -"`Prometheus `_ 用于收集数据,而 `Grafana `_ 则能让你将收集到的数据可视化。它们都与 Flower 在引擎下使用的 " -"`Ray `_ 紧密集成。" +"`Prometheus `_ 用于收集数据,而 `Grafana " +"`_ 则能让你将收集到的数据可视化。它们都与 Flower 在引擎下使用的 `Ray " +"`_ 紧密集成。" #: ../../source/how-to-monitor-simulation.rst:18 msgid "" @@ -5578,26 +5070,23 @@ msgstr "在上一代英特尔 Mac 设备上,应该是这样:" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" -"Open the respective configuration files and change them. Depending on your " -"device, use one of the two following commands:" +"Open the respective configuration files and change them. Depending on " +"your device, use one of the two following commands:" msgstr "打开相应的配置文件并修改它们。根据设备情况,使用以下两个命令之一:" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" -"and then delete all the text in the file and paste a new Prometheus config " -"you see below. You may adjust the time intervals to your requirements:" -msgstr "" -"然后删除文件中的所有文本,粘贴一个新的 Prometheus 配置文件,如下所示。您可以" -"根据需要调整时间间隔:" +"and then delete all the text in the file and paste a new Prometheus " +"config you see below. You may adjust the time intervals to your " +"requirements:" +msgstr "然后删除文件中的所有文本,粘贴一个新的 Prometheus 配置文件,如下所示。您可以根据需要调整时间间隔:" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" -"Now after you have edited the Prometheus configuration, do the same with the " -"Grafana configuration files. Open those using one of the following commands " -"as before:" -msgstr "" -"编辑完 Prometheus 配置后,请对 Grafana 配置文件执行同样的操作。与之前一样,使" -"用以下命令之一打开这些文件:" +"Now after you have edited the Prometheus configuration, do the same with " +"the Grafana configuration files. Open those using one of the following " +"commands as before:" +msgstr "编辑完 Prometheus 配置后,请对 Grafana 配置文件执行同样的操作。与之前一样,使用以下命令之一打开这些文件:" #: ../../source/how-to-monitor-simulation.rst:69 msgid "" @@ -5607,8 +5096,8 @@ msgstr "您的终端编辑器应该会打开,并允许您像之前一样应用 #: ../../source/how-to-monitor-simulation.rst:84 msgid "" -"Congratulations, you just downloaded all the necessary software needed for " -"metrics tracking. Now, let’s start it." +"Congratulations, you just downloaded all the necessary software needed " +"for metrics tracking. Now, let’s start it." msgstr "恭喜您,您刚刚下载了指标跟踪所需的所有软件。现在,让我们开始吧。" #: ../../source/how-to-monitor-simulation.rst:88 @@ -5623,8 +5112,8 @@ msgstr "在运行 Flower 模拟之前,您必须启动刚刚安装和配置的 #: ../../source/how-to-monitor-simulation.rst:97 msgid "" -"Please include the following argument in your Python code when starting a " -"simulation." +"Please include the following argument in your Python code when starting a" +" simulation." msgstr "开始模拟时,请在 Python 代码中加入以下参数。" #: ../../source/how-to-monitor-simulation.rst:108 @@ -5633,8 +5122,8 @@ msgstr "现在,您可以开始工作了。" #: ../../source/how-to-monitor-simulation.rst:110 msgid "" -"Shortly after the simulation starts, you should see the following logs in " -"your terminal:" +"Shortly after the simulation starts, you should see the following logs in" +" your terminal:" msgstr "模拟启动后不久,您就会在终端中看到以下日志:" #: ../../source/how-to-monitor-simulation.rst:117 @@ -5643,31 +5132,28 @@ msgstr "您可以在 ``_ 查看所有内容。" #: ../../source/how-to-monitor-simulation.rst:119 msgid "" -"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the " -"lowest option)." -msgstr "" -"这是一个 Ray Dashboard。您可以导航到 \"度量标准\"(左侧面板,最低选项)。" +"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" +" lowest option)." +msgstr "这是一个 Ray Dashboard。您可以导航到 \"度量标准\"(左侧面板,最低选项)。" #: ../../source/how-to-monitor-simulation.rst:121 msgid "" -"Or alternatively, you can just see them in Grafana by clicking on the right-" -"up corner, “View in Grafana”. Please note that the Ray dashboard is only " -"accessible during the simulation. After the simulation ends, you can only " -"use Grafana to explore the metrics. You can start Grafana by going to " -"``http://localhost:3000/``." +"Or alternatively, you can just see them in Grafana by clicking on the " +"right-up corner, “View in Grafana”. Please note that the Ray dashboard is" +" only accessible during the simulation. After the simulation ends, you " +"can only use Grafana to explore the metrics. You can start Grafana by " +"going to ``http://localhost:3000/``." msgstr "" -"或者,您也可以点击右上角的 \"在 Grafana 中查看\",在 Grafana 中查看它们。请注" -"意,Ray 仪表盘只能在模拟期间访问。模拟结束后,您只能使用 Grafana 浏览指标。您" -"可以访问 ``http://localhost:3000/``启动 Grafana。" +"或者,您也可以点击右上角的 \"在 Grafana 中查看\",在 Grafana 中查看它们。请注意,Ray " +"仪表盘只能在模拟期间访问。模拟结束后,您只能使用 Grafana 浏览指标。您可以访问 ``http://localhost:3000/``启动 " +"Grafana。" #: ../../source/how-to-monitor-simulation.rst:123 msgid "" "After you finish the visualization, stop Prometheus and Grafana. This is " "important as they will otherwise block, for example port :code:`3000` on " "your machine as long as they are running." -msgstr "" -"完成可视化后,请停止 Prometheus 和 Grafana。这一点很重要,否则只要它们在运" -"行,就会阻塞机器上的端口 :code:`3000`。" +msgstr "完成可视化后,请停止 Prometheus 和 Grafana。这一点很重要,否则只要它们在运行,就会阻塞机器上的端口 :code:`3000`。" #: ../../source/how-to-monitor-simulation.rst:132 msgid "Resource allocation" @@ -5675,24 +5161,21 @@ msgstr "资源分配" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" -"You must understand how the Ray library works to efficiently allocate system " -"resources to simulation clients on your own." -msgstr "" -"您必须了解 Ray 库是如何工作的,才能有效地为自己的仿真客户端分配系统资源。" +"You must understand how the Ray library works to efficiently allocate " +"system resources to simulation clients on your own." +msgstr "您必须了解 Ray 库是如何工作的,才能有效地为自己的仿真客户端分配系统资源。" #: ../../source/how-to-monitor-simulation.rst:136 msgid "" "Initially, the simulation (which Ray handles under the hood) starts by " "default with all the available resources on the system, which it shares " -"among the clients. It doesn't mean it divides it equally among all of them, " -"nor that the model training happens at all of them simultaneously. You will " -"learn more about that in the later part of this blog. You can check the " -"system resources by running the following:" +"among the clients. It doesn't mean it divides it equally among all of " +"them, nor that the model training happens at all of them simultaneously. " +"You will learn more about that in the later part of this blog. You can " +"check the system resources by running the following:" msgstr "" -"最初,模拟(由 Ray 在引擎下处理)默认使用系统上的所有可用资源启动,并在客户端" -"之间共享。但这并不意味着它会将资源平均分配给所有客户端,也不意味着模型训练会" -"在所有客户端同时进行。您将在本博客的后半部分了解到更多相关信息。您可以运行以" -"下命令检查系统资源:" +"最初,模拟(由 Ray " +"在引擎下处理)默认使用系统上的所有可用资源启动,并在客户端之间共享。但这并不意味着它会将资源平均分配给所有客户端,也不意味着模型训练会在所有客户端同时进行。您将在本博客的后半部分了解到更多相关信息。您可以运行以下命令检查系统资源:" #: ../../source/how-to-monitor-simulation.rst:143 msgid "In Google Colab, the result you see might be similar to this:" @@ -5700,8 +5183,8 @@ msgstr "在 Google Colab 中,您看到的结果可能与此类似:" #: ../../source/how-to-monitor-simulation.rst:155 msgid "" -"However, you can overwrite the defaults. When starting a simulation, do the " -"following (you don't need to overwrite all of them):" +"However, you can overwrite the defaults. When starting a simulation, do " +"the following (you don't need to overwrite all of them):" msgstr "不过,您可以覆盖默认值。开始模拟时,请执行以下操作(不必全部覆盖):" #: ../../source/how-to-monitor-simulation.rst:175 @@ -5710,26 +5193,23 @@ msgstr "我们还可以为单个客户指定资源。" #: ../../source/how-to-monitor-simulation.rst:205 msgid "" -"Now comes the crucial part. Ray will start a new client only when it has all " -"the required resources (such that they run in parallel) when the resources " -"allow." -msgstr "" -"现在到了关键部分。只有在资源允许的情况下,Ray 才会在拥有所有所需资源(如并行" -"运行)时启动新客户端。" +"Now comes the crucial part. Ray will start a new client only when it has " +"all the required resources (such that they run in parallel) when the " +"resources allow." +msgstr "现在到了关键部分。只有在资源允许的情况下,Ray 才会在拥有所有所需资源(如并行运行)时启动新客户端。" #: ../../source/how-to-monitor-simulation.rst:207 msgid "" -"In the example above, only one client will be run, so your clients won't run " -"concurrently. Setting :code:`client_num_gpus = 0.5` would allow running two " -"clients and therefore enable them to run concurrently. Be careful not to " -"require more resources than available. If you specified :code:" -"`client_num_gpus = 2`, the simulation wouldn't start (even if you had 2 GPUs " -"but decided to set 1 in :code:`ray_init_args`)." +"In the example above, only one client will be run, so your clients won't " +"run concurrently. Setting :code:`client_num_gpus = 0.5` would allow " +"running two clients and therefore enable them to run concurrently. Be " +"careful not to require more resources than available. If you specified " +":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " +"had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." msgstr "" -"在上面的示例中,将只运行一个客户端,因此您的客户端不会并发运行。设置 :code:" -"`client_num_gpus = 0.5` 将允许运行两个客户端,从而使它们能够并发运行。请注" -"意,所需的资源不要超过可用资源。如果您指定 :code:`client_num_gpus = 2`,模拟" -"将无法启动(即使您有 2 个 GPU,但决定在 :code:`ray_init_args` 中设置为 1)。" +"在上面的示例中,将只运行一个客户端,因此您的客户端不会并发运行。设置 :code:`client_num_gpus = 0.5` " +"将允许运行两个客户端,从而使它们能够并发运行。请注意,所需的资源不要超过可用资源。如果您指定 :code:`client_num_gpus = " +"2`,模拟将无法启动(即使您有 2 个 GPU,但决定在 :code:`ray_init_args` 中设置为 1)。" #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 msgid "FAQ" @@ -5741,25 +5221,22 @@ msgstr "问:我没有看到任何指标记录。" #: ../../source/how-to-monitor-simulation.rst:216 msgid "" -"A: The timeframe might not be properly set. The setting is in the top right " -"corner (\"Last 30 minutes\" by default). Please change the timeframe to " -"reflect the period when the simulation was running." -msgstr "" -"答:时间范围可能没有正确设置。设置在右上角(默认为 \"最后 30 分钟\")。请更改" -"时间框架,以反映模拟运行的时间段。" +"A: The timeframe might not be properly set. The setting is in the top " +"right corner (\"Last 30 minutes\" by default). Please change the " +"timeframe to reflect the period when the simulation was running." +msgstr "答:时间范围可能没有正确设置。设置在右上角(默认为 \"最后 30 分钟\")。请更改时间框架,以反映模拟运行的时间段。" #: ../../source/how-to-monitor-simulation.rst:218 msgid "" -"Q: I see “Grafana server not detected. Please make sure the Grafana server " -"is running and refresh this page” after going to the Metrics tab in Ray " -"Dashboard." -msgstr "" -"问:我看到 \"未检测到 Grafana 服务器。请确保 Grafana 服务器正在运行并刷新此页" -"面\"。" +"Q: I see “Grafana server not detected. Please make sure the Grafana " +"server is running and refresh this page” after going to the Metrics tab " +"in Ray Dashboard." +msgstr "问:我看到 \"未检测到 Grafana 服务器。请确保 Grafana 服务器正在运行并刷新此页面\"。" #: ../../source/how-to-monitor-simulation.rst:220 msgid "" -"A: You probably don't have Grafana running. Please check the running services" +"A: You probably don't have Grafana running. Please check the running " +"services" msgstr "答:您可能没有运行 Grafana。请检查正在运行的服务" #: ../../source/how-to-monitor-simulation.rst:226 @@ -5770,8 +5247,8 @@ msgstr "问:在访问 ``_时,我看到 \"无法访问 #: ../../source/how-to-monitor-simulation.rst:228 msgid "" -"A: Either the simulation has already finished, or you still need to start " -"Prometheus." +"A: Either the simulation has already finished, or you still need to start" +" Prometheus." msgstr "答:要么模拟已经完成,要么您还需要启动Prometheus。" #: ../../source/how-to-monitor-simulation.rst:232 @@ -5783,15 +5260,14 @@ msgstr "资源" msgid "" "Ray Dashboard: ``_" -msgstr "" -"Ray 仪表盘: ``_" +msgstr "Ray 仪表盘: ``_" #: ../../source/how-to-monitor-simulation.rst:236 #, fuzzy msgid "Ray Metrics: ``_" msgstr "" -"Ray 指标: ``_" +"Ray 指标: ``_" #: ../../source/how-to-run-flower-using-docker.rst:2 #, fuzzy @@ -5801,9 +5277,9 @@ msgstr "使用 Docker 运行 Flower" #: ../../source/how-to-run-flower-using-docker.rst:4 #, fuzzy msgid "" -"The simplest way to get started with Flower is by using the pre-made Docker " -"images, which you can find on `Docker Hub `_." +"The simplest way to get started with Flower is by using the pre-made " +"Docker images, which you can find on `Docker Hub " +"`__." msgstr "" "开始使用 Flower 的最简单方法是使用预制的 Docker 镜像,您可以在 `Docker Hub " "`_ 上找到这些镜像。" @@ -5816,221 +5292,540 @@ msgstr "开始之前,请确保 Docker 守护进程正在运行:" #: ../../source/how-to-run-flower-using-docker.rst:14 #, fuzzy msgid "" -"If you do not see the version of Docker but instead get an error saying that " -"the command was not found, you will need to install Docker first. You can " -"find installation instruction `here `_." +"If you do not see the version of Docker but instead get an error saying " +"that the command was not found, you will need to install Docker first. " +"You can find installation instruction `here `_." msgstr "" -"如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。你" -"可以在 `_ 找到安装说明。" +"如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。你可以在 " +"`_ 找到安装说明。" #: ../../source/how-to-run-flower-using-docker.rst:20 #, fuzzy msgid "" -"On Linux, Docker commands require ``sudo`` privilege. If you want to avoid " -"using ``sudo``, you can follow the `Post-installation steps `_ on the official Docker " -"website." +"On Linux, Docker commands require ``sudo`` privilege. If you want to " +"avoid using ``sudo``, you can follow the `Post-installation steps " +"`_ on the " +"official Docker website." +msgstr "" +"在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``,可以按照 Docker 官方网站上的 " +"`安装后步骤 `_进行操作。" + +#: ../../source/how-to-run-flower-using-docker.rst:26 +msgid "" +"To ensure optimal performance and compatibility, the SuperLink, SuperNode" +" and ServerApp image must have the same version when running together. " +"This guarantees seamless integration and avoids potential conflicts or " +"issues that may arise from using different versions." msgstr "" -"在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``,可以按" -"照 Docker 官方网站上的 `安装后步骤 `_进行操作。" -#: ../../source/how-to-run-flower-using-docker.rst:25 +#: ../../source/how-to-run-flower-using-docker.rst:31 #, fuzzy -msgid "Flower server" -msgstr "Flower 服务器" +msgid "Flower SuperLink" +msgstr "flower-superlink" -#: ../../source/how-to-run-flower-using-docker.rst:28 +#: ../../source/how-to-run-flower-using-docker.rst:34 #, fuzzy msgid "Quickstart" msgstr "快速入门 JAX" -#: ../../source/how-to-run-flower-using-docker.rst:30 +#: ../../source/how-to-run-flower-using-docker.rst:36 #, fuzzy msgid "If you're looking to try out Flower, you can use the following command:" msgstr "如果您想试用 Flower,可以使用以下命令:" -#: ../../source/how-to-run-flower-using-docker.rst:37 +#: ../../source/how-to-run-flower-using-docker.rst:42 #, fuzzy msgid "" -"The command will pull the Docker image with the tag ``1.7.0-py3.11-" -"ubuntu22.04`` from Docker Hub. The tag contains the information which " -"Flower, Python and Ubuntu is used. In this case, it uses Flower 1.7.0, " -"Python 3.11 and Ubuntu 22.04. The ``--rm`` flag tells Docker to remove the " -"container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker " +"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " +"The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -"该命令将从 Docker Hub 提取标签为``1.7.0-py3.11-ubuntu22.04``的 Docker 镜像。" -"标签包含使用 Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower " -"1.7.0、Python 3.11 和 Ubuntu 22.04。rm \"标记告诉 Docker 在退出后移除容器。" +"该命令将从 Docker Hub 提取标签为``1.7.0-py3.11-ubuntu22.04``的 Docker 镜像。标签包含使用 " +"Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower 1.7.0、Python 3.11 和 Ubuntu " +"22.04。rm \"标记告诉 Docker 在退出后移除容器。" -#: ../../source/how-to-run-flower-using-docker.rst:44 +#: ../../source/how-to-run-flower-using-docker.rst:48 #, fuzzy msgid "" -"By default, the Flower server keeps state in-memory. When using the Docker " -"flag ``--rm``, the state is not persisted between container starts. We will " -"show below how to save the state in a file on your host system." +"By default, the Flower SuperLink keeps state in-memory. When using the " +"Docker flag ``--rm``, the state is not persisted between container " +"starts. We will show below how to save the state in a file on your host " +"system." msgstr "" -"默认情况下,Flower 服务器会将状态保存在内存中。使用 Docker 标志 ``--rm`` 时," -"状态不会在容器启动之间持久化。下面我们将展示如何将状态保存到主机系统上的文件" -"中。" +"默认情况下,Flower 服务器会将状态保存在内存中。使用 Docker 标志 ``--rm`` " +"时,状态不会在容器启动之间持久化。下面我们将展示如何将状态保存到主机系统上的文件中。" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:52 #, fuzzy msgid "" -"The ``-p :`` flag tells Docker to map the ports ``9091``/" -"``9092`` of the host to ``9091``/``9092`` of the container, allowing you to " -"access the Driver API on ``http://localhost:9091`` and the Fleet API on " -"``http://localhost:9092``. Lastly, any flag that comes after the tag is " -"passed to the Flower server. Here, we are passing the flag ``--insecure``." +"The ``-p :`` flag tells Docker to map the ports " +"``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " +"allowing you to access the Driver API on ``http://localhost:9091`` and " +"the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " +"after the tag is passed to the Flower SuperLink. Here, we are passing the" +" flag ``--insecure``." msgstr "" -"``-p :`` 标记会告诉 Docker 将主机的端口 ``9091``/``9092`` 映" -"射到容器的端口 ``9091``/`9092``,这样你就可以在 ``http://localhost:9091`` 上" -"访问 Driver API,在 ``http://localhost:9092`` 上访问 Fleet API。最后,标签后" -"面的任何标志都会传递给 Flower 服务器。在这里,我们传递的标志是 ``--" -"insecure`` 。" +"``-p :`` 标记会告诉 Docker 将主机的端口 ``9091``/``9092`` 映射到容器的端口 " +"``9091``/`9092``,这样你就可以在 ``http://localhost:9091`` 上访问 Driver API,在 " +"``http://localhost:9092`` 上访问 Fleet API。最后,标签后面的任何标志都会传递给 Flower " +"服务器。在这里,我们传递的标志是 ``--insecure`` 。" -#: ../../source/how-to-run-flower-using-docker.rst:55 +#: ../../source/how-to-run-flower-using-docker.rst:59 +#: ../../source/how-to-run-flower-using-docker.rst:238 +#: ../../source/how-to-run-flower-using-docker.rst:354 #, fuzzy msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " -"HTTPS) and should only be used for testing purposes. We strongly recommend " -"enabling `SSL `_ when deploying to a " -"production environment." +"HTTPS) and should only be used for testing purposes. We strongly " +"recommend enabling `SSL `__ when " +"deploying to a production environment." msgstr "" -"不安全 \"标志启用不安全通信(使用 HTTP,而非 HTTPS),只能用于测试目的。我们" -"强烈建议在部署到生产环境时启用 `SSL `_。" +"不安全 \"标志启用不安全通信(使用 HTTP,而非 HTTPS),只能用于测试目的。我们强烈建议在部署到生产环境时启用 `SSL " +"`_。" -#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:64 #, fuzzy msgid "" -"You can use ``--help`` to view all available flags that the server supports:" +"You can use ``--help`` to view all available flags that the SuperLink " +"supports:" msgstr "您可以使用 ``--help`` 查看服务器支持的所有可用标记:" -#: ../../source/how-to-run-flower-using-docker.rst:67 +#: ../../source/how-to-run-flower-using-docker.rst:71 #, fuzzy msgid "Mounting a volume to store the state on the host system" msgstr "在主机系统上挂载卷以存储状态" -#: ../../source/how-to-run-flower-using-docker.rst:69 +#: ../../source/how-to-run-flower-using-docker.rst:73 #, fuzzy msgid "" -"If you want to persist the state of the server on your host system, all you " -"need to do is specify a path where you want to save the file on your host " -"system and a name for the database file. In the example below, we tell " -"Docker via the flag ``-v`` to mount the user's home directory (``~/`` on " -"your host) into the ``/app/`` directory of the container. Furthermore, we " -"use the flag ``--database`` to specify the name of the database file." +"If you want to persist the state of the SuperLink on your host system, " +"all you need to do is specify a path where you want to save the file on " +"your host system and a name for the database file. In the example below, " +"we tell Docker via the flag ``--volume`` to mount the user's home " +"directory (``~/`` on your host) into the ``/app/`` directory of the " +"container. Furthermore, we use the flag ``--database`` to specify the " +"name of the database file." msgstr "" -"如果想在主机系统上持久保存服务器的状态,只需在主机系统上指定保存文件的路径和" -"数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉 Docker 将用户" -"的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外,我们使用标志 " -"``--database`` 来指定数据库文件的名称。" +"如果想在主机系统上持久保存服务器的状态,只需在主机系统上指定保存文件的路径和数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉" +" Docker 将用户的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外,我们使用标志 ``--database``" +" 来指定数据库文件的名称。" -#: ../../source/how-to-run-flower-using-docker.rst:82 +#: ../../source/how-to-run-flower-using-docker.rst:86 #, fuzzy msgid "" -"As soon as the server starts, the file ``state.db`` is created in the user's " -"home directory on your host system. If the file already exists, the server " -"tries to restore the state from the file. To start the server with an empty " -"database, simply remove the ``state.db`` file." +"As soon as the SuperLink starts, the file ``state.db`` is created in the " +"user's home directory on your host system. If the file already exists, " +"the SuperLink tries to restore the state from the file. To start the " +"SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -"服务器一启动,就会在主机系统的用户主目录下创建文件 ``state.db``。如果该文件已" -"经存在,服务器会尝试从该文件恢复状态。要以空数据库启动服务器,只需删除 " -"``state.db`` 文件即可。" +"服务器一启动,就会在主机系统的用户主目录下创建文件 " +"``state.db``。如果该文件已经存在,服务器会尝试从该文件恢复状态。要以空数据库启动服务器,只需删除 ``state.db`` 文件即可。" -#: ../../source/how-to-run-flower-using-docker.rst:87 +#: ../../source/how-to-run-flower-using-docker.rst:91 +#: ../../source/how-to-run-flower-using-docker.rst:260 +#: ../../source/how-to-run-flower-using-docker.rst:375 #, fuzzy msgid "Enabling SSL for secure connections" msgstr "启用 SSL 连接" -#: ../../source/how-to-run-flower-using-docker.rst:89 +#: ../../source/how-to-run-flower-using-docker.rst:93 #, fuzzy msgid "" -"To enable SSL, you will need a CA certificate, a server certificate and a " -"server private key." +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" +"encoded private key and a PEM-encoded certificate chain." msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" -#: ../../source/how-to-run-flower-using-docker.rst:92 +#: ../../source/how-to-run-flower-using-docker.rst:97 +#, fuzzy +msgid "" +"For testing purposes, you can generate your own self-signed certificates." +" The `Enable SSL connections `__ page contains a section that" +" will guide you through the process." +msgstr "" +"出于测试目的,你可以生成自己的自签名证书。启用 SSL 连接 `_ 页面中有一个部分将指导你完成这一过程。" + +#: ../../source/how-to-run-flower-using-docker.rst:101 +#, fuzzy +msgid "" +"Assuming all files we need are in the local ``certificates`` directory, " +"we can use the flag ``--volume`` to mount the local directory into the " +"``/app/`` directory of the container. This allows the SuperLink to access" +" the files within the container. Finally, we pass the names of the " +"certificates to the SuperLink with the ``--certificates`` flag." +msgstr "" +"假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " +"``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" + +#: ../../source/how-to-run-flower-using-docker.rst:113 +#, fuzzy +msgid "Flower SuperNode" +msgstr "Flower 服务器" + +#: ../../source/how-to-run-flower-using-docker.rst:115 +msgid "" +"The SuperNode Docker image comes with a pre-installed version of Flower " +"and serves as a base for building your own SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:120 +msgid "" +"The SuperNode Docker image currently works only with the 1.9.0-nightly " +"release. A stable version will be available when Flower 1.9.0 (stable) " +"gets released (ETA: May). A SuperNode nightly image must be paired with " +"the corresponding SuperLink and ServerApp nightly images released on the " +"same day. To ensure the versions are in sync, using the concrete tag, " +"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:126 +msgid "" +"We will use the ``quickstart-pytorch`` example, which you can find in the" +" Flower repository, to illustrate how you can dockerize your ClientApp." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:134 +#, fuzzy +msgid "" +"Before we can start, we need to meet a few prerequisites in our local " +"development environment. You can skip the first part if you want to run " +"your ClientApp instead of the ``quickstart-pytorch`` example." +msgstr "在开始之前,我们需要在本地开发环境中满足一些先决条件。" + +#: ../../source/how-to-run-flower-using-docker.rst:138 +#, fuzzy +msgid "Clone the Flower repository." +msgstr "**叉花仓库**" + +#: ../../source/how-to-run-flower-using-docker.rst:152 +msgid "Creating a SuperNode Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:154 +#: ../../source/how-to-run-flower-using-docker.rst:289 +msgid "Let's assume the following project layout:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:163 +msgid "" +"First, we need to create a ``requirements.txt`` file in the directory " +"where the ``ClientApp`` code is located. In the file, we list all the " +"dependencies that the ClientApp requires." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:175 +msgid "" +"Note that `flwr `__ is already installed " +"in the ``flwr/supernode`` base image, so you only need to include other " +"package dependencies in your ``requirements.txt``, such as ``torch``, " +"``tensorflow``, etc." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:179 +msgid "" +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.supernode`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:182 +msgid "" +"The ``Dockerfile.supernode`` contains the instructions that assemble the " +"SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:196 +msgid "" +"In the first two lines, we instruct Docker to use the SuperNode image " +"tagged ``nightly`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. Next, we install the ClientApp dependencies by copying the " +"``requirements.txt`` file into the image and run ``pip install``. In the " +"last two lines, we copy the ``client.py`` module into the image and set " +"the entry point to ``flower-client-app`` with the argument " +"``client:app``. The argument is the object reference of the ClientApp " +"(``:``) that will be run inside the ClientApp." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:205 +#, fuzzy +msgid "Building the SuperNode Docker image" +msgstr "启动服务器" + +#: ../../source/how-to-run-flower-using-docker.rst:207 +msgid "" +"Next, we build the SuperNode Docker image by running the following " +"command in the directory where Dockerfile and ClientApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:214 +msgid "" +"We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:219 +#, fuzzy +msgid "Running the SuperNode Docker image" +msgstr "启动服务器" + +#: ../../source/how-to-run-flower-using-docker.rst:221 +msgid "Now that we have built the SuperNode image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:229 +#: ../../source/how-to-run-flower-using-docker.rst:345 +msgid "Let's break down each part of this command:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:231 +#: ../../source/how-to-run-flower-using-docker.rst:347 +msgid "``docker run``: This is the command to run a new Docker container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:232 +#: ../../source/how-to-run-flower-using-docker.rst:348 +msgid "" +"``--rm``: This option specifies that the container should be " +"automatically removed when it stops." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:233 +msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:234 +#: ../../source/how-to-run-flower-using-docker.rst:350 +msgid "``--insecure``: This option enables insecure communication." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "" +"``--server 192.168.1.100:9092``: This option specifies the address of the" +" SuperLinks Fleet" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "API to connect to. Remember to update it with your SuperLink IP." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:248 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your SuperNodes." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:252 +msgid "" +"Any argument that comes after the tag is passed to the Flower SuperNode " +"binary. To see all available flags that the SuperNode supports, run:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:262 +msgid "" +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your SuperNode container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:264 +#, fuzzy +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the SuperNode to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." +msgstr "" +"假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " +"``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" + +#: ../../source/how-to-run-flower-using-docker.rst:275 +#, fuzzy +msgid "Flower ServerApp" +msgstr "Flower 服务器。" + +#: ../../source/how-to-run-flower-using-docker.rst:277 +msgid "" +"The procedure for building and running a ServerApp image is almost " +"identical to the SuperNode image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:279 +msgid "" +"Similar to the SuperNode image, the ServerApp Docker image comes with a " +"pre-installed version of Flower and serves as a base for building your " +"own ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:282 +msgid "" +"We will use the same ``quickstart-pytorch`` example as we do in the " +"Flower SuperNode section. If you have not already done so, please follow " +"the `SuperNode Prerequisites`_ before proceeding." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:287 +msgid "Creating a ServerApp Dockerfile" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:298 +msgid "" +"First, we need to create a Dockerfile in the directory where the " +"``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.serverapp`` in ``examples" +"/quickstart-pytorch``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:302 +msgid "" +"The ``Dockerfile.serverapp`` contains the instructions that assemble the " +"ServerApp image." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:313 +msgid "" +"In the first two lines, we instruct Docker to use the ServerApp image " +"tagged ``1.8.0`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. In the last two lines, we copy the ``server.py`` module into " +"the image and set the entry point to ``flower-server-app`` with the " +"argument ``server:app``. The argument is the object reference of the " +"ServerApp (``:``) that will be run inside the " +"ServerApp container." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:321 +#, fuzzy +msgid "Building the ServerApp Docker image" +msgstr "启动服务器" + +#: ../../source/how-to-run-flower-using-docker.rst:323 +msgid "" +"Next, we build the ServerApp Docker image by running the following " +"command in the directory where Dockerfile and ServerApp code are located." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:330 +msgid "" +"We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " +"Remember that the here chosen values only serve as an example. You can " +"change them to your needs." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:335 #, fuzzy +msgid "Running the ServerApp Docker image" +msgstr "启动服务器" + +#: ../../source/how-to-run-flower-using-docker.rst:337 +msgid "Now that we have built the ServerApp image, we can finally run it." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:349 +msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst +msgid "" +"``--server 192.168.1.100:9091``: This option specifies the address of the" +" SuperLinks Driver" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:363 +msgid "" +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your ServerApps." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:367 msgid "" -"For testing purposes, you can generate your own self-signed certificates. " -"The `Enable SSL connections `_ page contains a section that will guide " -"you through the process." +"Any argument that comes after the tag is passed to the Flower ServerApp " +"binary. To see all available flags that the ServerApp supports, run:" msgstr "" -"出于测试目的,你可以生成自己的自签名证书。启用 SSL 连接 `_ 页面中有一" -"个部分将指导你完成这一过程。" -#: ../../source/how-to-run-flower-using-docker.rst:96 +#: ../../source/how-to-run-flower-using-docker.rst:377 #, fuzzy msgid "" -"Assuming all files we need are in the local ``certificates`` directory, we " -"can use the flag ``-v`` to mount the local directory into the ``/app/`` " -"directory of the container. This allows the server to access the files " -"within the container. Finally, we pass the names of the certificates to the " -"server with the ``--certificates`` flag." +"To enable SSL, we will need to mount a PEM-encoded root certificate into " +"your ServerApp container." +msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" + +#: ../../source/how-to-run-flower-using-docker.rst:379 +#, fuzzy +msgid "" +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the ServerApp to access the certificate " +"within the container. Use the ``--certificates`` flag when starting the " +"container." msgstr "" -"假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 " -"``-v`` 将本地目录挂载到容器的 ``/app/`` 目录中。这样,服务器就可以访问容器内" -"的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" +"假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " +"``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" -#: ../../source/how-to-run-flower-using-docker.rst:108 +#: ../../source/how-to-run-flower-using-docker.rst:390 #, fuzzy -msgid "Using a different Flower or Python version" +msgid "Advanced Docker options" +msgstr "高级安装选项" + +#: ../../source/how-to-run-flower-using-docker.rst:393 +#, fuzzy +msgid "Using a different Flower version" msgstr "使用不同的 Flower 或 Python 版本" -#: ../../source/how-to-run-flower-using-docker.rst:110 +#: ../../source/how-to-run-flower-using-docker.rst:395 #, fuzzy msgid "" -"If you want to use a different version of Flower or Python, you can do so by " -"changing the tag. All versions we provide are available on `Docker Hub " -"`_." +"If you want to use a different version of Flower, for example Flower " +"nightly, you can do so by changing the tag. All available versions are on" +" `Docker Hub `__." msgstr "" -"如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。我们提供的所" -"有版本都可以在 `Docker Hub `_ 上找" -"到。" +"如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。我们提供的所有版本都可以在 `Docker Hub " +"`_ 上找到。" -#: ../../source/how-to-run-flower-using-docker.rst:114 +#: ../../source/how-to-run-flower-using-docker.rst:400 #, fuzzy msgid "Pinning a Docker image to a specific version" msgstr "将 Docker 映像固定到特定版本" -#: ../../source/how-to-run-flower-using-docker.rst:116 +#: ../../source/how-to-run-flower-using-docker.rst:402 #, fuzzy msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that you " -"always use the same image, you can specify the hash of the image instead of " -"the tag." +"change the functionality of Flower. However, if you want to ensure that " +"you always use the same image, you can specify the hash of the image " +"instead of the tag." msgstr "" -"我们可能会更新标签后面的图像。此类更新通常包括系统依赖项的安全更新,不会改变 " -"Flower 的功能。不过,如果您想确保始终使用同一张图片,可以指定图片的哈希值而不" -"是标签。" +"我们可能会更新标签后面的图像。此类更新通常包括系统依赖项的安全更新,不会改变 Flower " +"的功能。不过,如果您想确保始终使用同一张图片,可以指定图片的哈希值而不是标签。" -#: ../../source/how-to-run-flower-using-docker.rst:121 +#: ../../source/how-to-run-flower-using-docker.rst:407 #, fuzzy msgid "" "The following command returns the current image hash referenced by the " -"``server:1.7.0-py3.11-ubuntu22.04`` tag:" -msgstr "" -"下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` 标记引用的当前图像哈希" -"值:" +"``superlink:1.8.0`` tag:" +msgstr "下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` 标记引用的当前图像哈希值:" -#: ../../source/how-to-run-flower-using-docker.rst:128 +#: ../../source/how-to-run-flower-using-docker.rst:414 #, fuzzy -msgid "Next, we can pin the hash when running a new server container:" +msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "接下来,我们可以在运行新服务器容器时将哈希值固定下来:" -#: ../../source/how-to-run-flower-using-docker.rst:137 +#: ../../source/how-to-run-flower-using-docker.rst:423 #, fuzzy msgid "Setting environment variables" msgstr "设置编码环境" -#: ../../source/how-to-run-flower-using-docker.rst:139 +#: ../../source/how-to-run-flower-using-docker.rst:425 #, fuzzy msgid "" "To set a variable inside a Docker container, you can use the ``-e " @@ -6044,85 +5839,81 @@ msgstr "运行模拟" #: ../../source/how-to-run-simulations.rst:8 msgid "" "Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients but " -"without having to source, configure and mange a large number of physical " -"devices; you might want to run your FL workloads as fast as possible on the " -"compute systems you have access to without having to go through a complex " -"setup process; you might want to validate your algorithm on different " -"scenarios at varying levels of data and system heterogeneity, client " -"availability, privacy budgets, etc. These are among some of the use-cases " -"where simulating FL workloads makes sense. Flower can accommodate these " -"scenarios by means of its `VirtualClientEngine `_ or VCE." -msgstr "" -"模拟联邦学习工作负载可用于多种案例:您可能希望在大量客户端上运行您的工作负" -"载,但无需采购、配置和管理大量物理设备;您可能希望在您可以访问的计算系统上尽" -"可能快地运行您的 FL 工作负载,而无需经过复杂的设置过程;您可能希望在不同数据" -"和系统异构性、客户端可用性、隐私预算等不同水平的场景中验证您的算法。这些都是" -"模拟 FL 工作负载的一些案例。Flower 可以通过其 \"虚拟客户端引擎" -"\"(VirtualClientEngine)_或 VCE 来匹配这些情况。" +"cases: you might want to run your workload on a large cohort of clients " +"but without having to source, configure and mange a large number of " +"physical devices; you might want to run your FL workloads as fast as " +"possible on the compute systems you have access to without having to go " +"through a complex setup process; you might want to validate your " +"algorithm on different scenarios at varying levels of data and system " +"heterogeneity, client availability, privacy budgets, etc. These are among" +" some of the use-cases where simulating FL workloads makes sense. Flower " +"can accommodate these scenarios by means of its `VirtualClientEngine " +"`_ or " +"VCE." +msgstr "" +"模拟联邦学习工作负载可用于多种案例:您可能希望在大量客户端上运行您的工作负载,但无需采购、配置和管理大量物理设备;您可能希望在您可以访问的计算系统上尽可能快地运行您的" +" FL 工作负载,而无需经过复杂的设置过程;您可能希望在不同数据和系统异构性、客户端可用性、隐私预算等不同水平的场景中验证您的算法。这些都是模拟 " +"FL 工作负载的一些案例。Flower 可以通过其 \"虚拟客户端引擎\"(VirtualClientEngine)_或 VCE 来匹配这些情况。" #: ../../source/how-to-run-simulations.rst:10 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " -"clients. These clients are identical to `non-virtual` clients (i.e. the ones " -"you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by creating a " -"class inheriting, for example, from `flwr.client.NumPyClient `_ and therefore behave in an identical way. In " -"addition to that, clients managed by the :code:`VirtualClientEngine` are:" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" +" clients. These clients are identical to `non-virtual` clients (i.e. the " +"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " +"creating a class inheriting, for example, from `flwr.client.NumPyClient " +"`_ and therefore behave in an " +"identical way. In addition to that, clients managed by the " +":code:`VirtualClientEngine` are:" msgstr "" -":code:`VirtualClientEngine`用来规划,启动和管理`虚拟`客户端。这些客户端跟`非" -"虚拟`客户端是一样的(即为您通过`flwr.client.start_client `_启动的客户端),因为它们可以通过创建一个继承自 `flwr." -"client.NumPyClient `_ 的类进行配" -"置,因此其行为方式相同。另外,由 `VirtualClientEngine` 管理的客户端有:" +":code:`VirtualClientEngine`用来规划,启动和管理`虚拟`客户端。这些客户端跟`非虚拟`客户端是一样的(即为您通过`flwr.client.start_client" +" `_启动的客户端),因为它们可以通过创建一个继承自 " +"`flwr.client.NumPyClient `_ " +"的类进行配置,因此其行为方式相同。另外,由 `VirtualClientEngine` 管理的客户端有:" #: ../../source/how-to-run-simulations.rst:12 msgid "" -"resource-aware: this means that each client gets assigned a portion of the " -"compute and memory on your system. You as a user can control this at the " -"beginning of the simulation and allows you to control the degree of " +"resource-aware: this means that each client gets assigned a portion of " +"the compute and memory on your system. You as a user can control this at " +"the beginning of the simulation and allows you to control the degree of " "parallelism of your Flower FL simulation. The fewer the resources per " "client, the more clients can run concurrently on the same hardware." msgstr "" -"资源感知:这意味着每个客户端都会分配到系统中的一部分计算和内存。作为用户,您" -"可以在模拟开始时对其进行控制,从而控制 Flower FL 模拟的并行程度。每个客户端的" -"资源越少,在同一硬件上并发运行的客户端就越多。" +"资源感知:这意味着每个客户端都会分配到系统中的一部分计算和内存。作为用户,您可以在模拟开始时对其进行控制,从而控制 Flower FL " +"模拟的并行程度。每个客户端的资源越少,在同一硬件上并发运行的客户端就越多。" #: ../../source/how-to-run-simulations.rst:13 msgid "" -"self-managed: this means that you as a user do not need to launch clients " -"manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"self-managed: this means that you as a user do not need to launch clients" +" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " "internals." -msgstr "" -"自管理:这意味着用户无需手动启动客户端,而是由 :code:`VirtualClientEngine` 负" -"责。" +msgstr "自管理:这意味着用户无需手动启动客户端,而是由 :code:`VirtualClientEngine` 负责。" #: ../../source/how-to-run-simulations.rst:14 msgid "" -"ephemeral: this means that a client is only materialized when it is required " -"in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards, releasing the resources it was " -"assigned and allowing in this way other clients to participate." +"ephemeral: this means that a client is only materialized when it is " +"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," +" releasing the resources it was assigned and allowing in this way other " +"clients to participate." msgstr "" -"即时性:这意味着客户端只有在 FL 进程中需要它时才会被实体化(例如执行 `fit() " -"`_ )。之后该对象将被销毁,释放分配" -"给它的资源,并允许其他客户端以这种方式参与。" +"即时性:这意味着客户端只有在 FL 进程中需要它时才会被实体化(例如执行 `fit() `_ " +")。之后该对象将被销毁,释放分配给它的资源,并允许其他客户端以这种方式参与。" #: ../../source/how-to-run-simulations.rst:16 msgid "" "The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " "`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use of " -"`Actors `_ to spawn " -"`virtual` clients and run their workload." +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " +"of `Actors `_ to " +"spawn `virtual` clients and run their workload." msgstr "" -":code:`VirtualClientEngine`使用`Ray `_来实现`虚拟`客户" -"端,这是一个用于可扩展 Python 工作负载的开源框架。特别地,Flower 的 :code:" -"`VirtualClientEngine` 使用 `Actors `_ 来生成 `virtual` 客户端并运行它们的工作负载。" +":code:`VirtualClientEngine`使用`Ray " +"`_来实现`虚拟`客户端,这是一个用于可扩展 Python 工作负载的开源框架。特别地,Flower 的" +" :code:`VirtualClientEngine` 使用 `Actors `_ 来生成 `virtual` 客户端并运行它们的工作负载。" #: ../../source/how-to-run-simulations.rst:20 msgid "Launch your Flower simulation" @@ -6130,16 +5921,16 @@ msgstr "启动 Flower 模拟" #: ../../source/how-to-run-simulations.rst:22 msgid "" -"Running Flower simulations still require you to define your client class, a " -"strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your simulation " -"is done with `start_simulation `_ and a minimal example looks as follows:" +"Running Flower simulations still require you to define your client class," +" a strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your " +"simulation is done with `start_simulation `_ and a minimal example looks" +" as follows:" msgstr "" -"运行 Flower 模拟器仍然需要定义客户端类、策略以及下载和加载(可能还需要分割)" -"数据集的实用程序。在完成这些工作后,就可以使用 \"start_simulation `_\" 来启动模拟了,一个最简单的示" -"例如下:" +"运行 Flower 模拟器仍然需要定义客户端类、策略以及下载和加载(可能还需要分割)数据集的实用程序。在完成这些工作后,就可以使用 " +"\"start_simulation `_\" 来启动模拟了,一个最简单的示例如下:" #: ../../source/how-to-run-simulations.rst:44 msgid "VirtualClientEngine resources" @@ -6147,24 +5938,23 @@ msgstr "虚拟客户端引擎资源" #: ../../source/how-to-run-simulations.rst:45 msgid "" -"By default the VCE has access to all system resources (i.e. all CPUs, all " -"GPUs, etc) since that is also the default behavior when starting Ray. " -"However, in some settings you might want to limit how many of your system " -"resources are used for simulation. You can do this via the :code:" -"`ray_init_args` input argument to :code:`start_simulation` which the VCE " -"internally passes to Ray's :code:`ray.init` command. For a complete list of " -"settings you can configure check the `ray.init `_ documentation. Do not set :" -"code:`ray_init_args` if you want the VCE to use all your system's CPUs and " -"GPUs." -msgstr "" -"默认情况下,VCE 可以访问所有系统资源(即所有 CPU、所有 GPU 等),因为这也是启" -"动 Ray 时的默认行为。不过,在某些设置中,您可能希望限制有多少系统资源用于模" -"拟。您可以通过 :code:`ray_init_args` 输入到 :code:`start_simulation` 的参数来" -"做到这一点,VCE 会在内部将该参数传递给 Ray 的 :code:`ray.init` 命令。有关您可" -"以配置的设置的完整列表,请查看 `ray.init `_ 文档。如果希望 VCE 使用系统中所有的 " -"CPU 和 GPU,请不要设置 :code:`ray_init_args`。" +"By default the VCE has access to all system resources (i.e. all CPUs, all" +" GPUs, etc) since that is also the default behavior when starting Ray. " +"However, in some settings you might want to limit how many of your system" +" resources are used for simulation. You can do this via the " +":code:`ray_init_args` input argument to :code:`start_simulation` which " +"the VCE internally passes to Ray's :code:`ray.init` command. For a " +"complete list of settings you can configure check the `ray.init " +"`_" +" documentation. Do not set :code:`ray_init_args` if you want the VCE to " +"use all your system's CPUs and GPUs." +msgstr "" +"默认情况下,VCE 可以访问所有系统资源(即所有 CPU、所有 GPU 等),因为这也是启动 Ray " +"时的默认行为。不过,在某些设置中,您可能希望限制有多少系统资源用于模拟。您可以通过 :code:`ray_init_args` 输入到 " +":code:`start_simulation` 的参数来做到这一点,VCE 会在内部将该参数传递给 Ray 的 :code:`ray.init`" +" 命令。有关您可以配置的设置的完整列表,请查看 `ray.init `_ 文档。如果希望 VCE 使用系统中所有的 CPU 和 " +"GPU,请不要设置 :code:`ray_init_args`。" #: ../../source/how-to-run-simulations.rst:62 msgid "Assigning client resources" @@ -6172,27 +5962,27 @@ msgstr "分配客户端资源" #: ../../source/how-to-run-simulations.rst:63 msgid "" -"By default the :code:`VirtualClientEngine` assigns a single CPU core (and " -"nothing else) to each virtual client. This means that if your system has 10 " -"cores, that many virtual clients can be concurrently running." +"By default the :code:`VirtualClientEngine` assigns a single CPU core (and" +" nothing else) to each virtual client. This means that if your system has" +" 10 cores, that many virtual clients can be concurrently running." msgstr "" -"默认情况下,:code:`VirtualClientEngine` 会为每个虚拟客户端分配一个 CPU 内核" -"(不分配其他任何内核)。这意味着,如果系统有 10 个内核,那么可以同时运行这么" -"多虚拟客户端。" +"默认情况下,:code:`VirtualClientEngine` 会为每个虚拟客户端分配一个 CPU " +"内核(不分配其他任何内核)。这意味着,如果系统有 10 个内核,那么可以同时运行这么多虚拟客户端。" #: ../../source/how-to-run-simulations.rst:65 msgid "" -"More often than not, you would probably like to adjust the resources your " -"clients get assigned based on the complexity (i.e. compute and memory " -"footprint) of your FL workload. You can do so when starting your simulation " -"by setting the argument `client_resources` to `start_simulation `_. Two keys are internally used " -"by Ray to schedule and spawn workloads (in our case Flower clients):" +"More often than not, you would probably like to adjust the resources your" +" clients get assigned based on the complexity (i.e. compute and memory " +"footprint) of your FL workload. You can do so when starting your " +"simulation by setting the argument `client_resources` to " +"`start_simulation `_." +" Two keys are internally used by Ray to schedule and spawn workloads (in " +"our case Flower clients):" msgstr "" -"通常情况下,您可能希望根据 FL 工作负载的复杂性(即计算和内存占用)来调整分配" -"给客户端的资源。您可以在启动模拟时将参数 `client_resources` 设置为 " -"`start_simulation `_ 。" -"Ray 内部使用两个键来调度和生成工作负载(在我们的例子中是 Flower 客户端):" +"通常情况下,您可能希望根据 FL 工作负载的复杂性(即计算和内存占用)来调整分配给客户端的资源。您可以在启动模拟时将参数 " +"`client_resources` 设置为 `start_simulation `_ 。Ray " +"内部使用两个键来调度和生成工作负载(在我们的例子中是 Flower 客户端):" #: ../../source/how-to-run-simulations.rst:67 msgid ":code:`num_cpus` indicates the number of CPU cores a client would get." @@ -6212,30 +6002,29 @@ msgstr "让我们来看几个例子:" msgid "" "While the :code:`client_resources` can be used to control the degree of " "concurrency in your FL simulation, this does not stop you from running " -"dozens, hundreds or even thousands of clients in the same round and having " -"orders of magnitude more `dormant` (i.e. not participating in a round) " -"clients. Let's say you want to have 100 clients per round but your system " -"can only accommodate 8 clients concurrently. The :code:`VirtualClientEngine` " -"will schedule 100 jobs to run (each simulating a client sampled by the " -"strategy) and then will execute them in a resource-aware manner in batches " -"of 8." -msgstr "" -"虽然 :code:`client_resources` 可用来控制 FL 模拟的并发程度,但这并不能阻止您" -"在同一轮模拟中运行几十、几百甚至上千个客户端,并拥有数量级更多的 \"休眠\"(即" -"不参与一轮模拟)客户端。比方说,您希望每轮有 100 个客户端,但您的系统只能同时" -"容纳 8 个客户端。:code:`VirtualClientEngine` 将安排运行 100 个工作(每个工作" -"模拟策略采样的一个客户端),然后以资源感知的方式分批执行。" +"dozens, hundreds or even thousands of clients in the same round and " +"having orders of magnitude more `dormant` (i.e. not participating in a " +"round) clients. Let's say you want to have 100 clients per round but your" +" system can only accommodate 8 clients concurrently. The " +":code:`VirtualClientEngine` will schedule 100 jobs to run (each " +"simulating a client sampled by the strategy) and then will execute them " +"in a resource-aware manner in batches of 8." +msgstr "" +"虽然 :code:`client_resources` 可用来控制 FL " +"模拟的并发程度,但这并不能阻止您在同一轮模拟中运行几十、几百甚至上千个客户端,并拥有数量级更多的 " +"\"休眠\"(即不参与一轮模拟)客户端。比方说,您希望每轮有 100 个客户端,但您的系统只能同时容纳 8 " +"个客户端。:code:`VirtualClientEngine` 将安排运行 100 " +"个工作(每个工作模拟策略采样的一个客户端),然后以资源感知的方式分批执行。" #: ../../source/how-to-run-simulations.rst:91 msgid "" "To understand all the intricate details on how resources are used to " -"schedule FL clients and how to define custom resources, please take a look " -"at the `Ray documentation `_." +"schedule FL clients and how to define custom resources, please take a " +"look at the `Ray documentation `_." msgstr "" -"要了解资源如何用于调度 FL 客户端以及如何定义自定义资源的所有复杂细节,请查看 " -"`Ray 文档 `_。" +"要了解资源如何用于调度 FL 客户端以及如何定义自定义资源的所有复杂细节,请查看 `Ray 文档 " +"`_。" #: ../../source/how-to-run-simulations.rst:94 msgid "Simulation examples" @@ -6243,27 +6032,26 @@ msgstr "模拟示例" #: ../../source/how-to-run-simulations.rst:96 msgid "" -"A few ready-to-run complete examples for Flower simulation in Tensorflow/" -"Keras and PyTorch are provided in the `Flower repository `_. You can run them on Google Colab too:" +"A few ready-to-run complete examples for Flower simulation in " +"Tensorflow/Keras and PyTorch are provided in the `Flower repository " +"`_. You can run them on Google Colab too:" msgstr "" -"在 Tensorflow/Keras 和 PyTorch 中进行 Flower 模拟的几个可随时运行的完整示例已" -"在 `Flower 库 `_ 中提供。您也可以在 Google " -"Colab 上运行它们:" +"在 Tensorflow/Keras 和 PyTorch 中进行 Flower 模拟的几个可随时运行的完整示例已在 `Flower 库 " +"`_ 中提供。您也可以在 Google Colab 上运行它们:" #: ../../source/how-to-run-simulations.rst:98 msgid "" -"`Tensorflow/Keras Simulation `_: 100 clients collaboratively train a MLP " -"model on MNIST." +"`Tensorflow/Keras Simulation " +"`_: 100 clients collaboratively train a MLP model on MNIST." msgstr "" -"Tensorflow/Keras模拟 `_:100个客户端在MNIST上协作训练一个MLP模型。" +"Tensorflow/Keras模拟 `_:100个客户端在MNIST上协作训练一个MLP模型。" #: ../../source/how-to-run-simulations.rst:99 msgid "" -"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " +"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " "MNIST." msgstr "" "PyTorch 模拟 `)" -msgstr "" -"在所有节点中都有一份数据集副本(更多相关信息请参阅 :ref:`模拟注意事项" -"`)" +"Have a copy of your dataset in all nodes (more about this in " +":ref:`simulation considerations `)" +msgstr "在所有节点中都有一份数据集副本(更多相关信息请参阅 :ref:`模拟注意事项`)" #: ../../source/how-to-run-simulations.rst:111 msgid "" -"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation `_ so the :code:" -"`VirtualClientEngine` attaches to a running Ray instance." +"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation " +"`_ so the " +":code:`VirtualClientEngine` attaches to a running Ray instance." msgstr "" "将 :code:`ray_init_args={\"address\"=\"auto\"}`传递给 `start_simulation `_ ,这样 :code:" -"`VirtualClientEngine`就会连接到正在运行的 Ray 实例。" +"api-flwr.html#flwr.simulation.start_simulation>`_ ,这样 " +":code:`VirtualClientEngine`就会连接到正在运行的 Ray 实例。" #: ../../source/how-to-run-simulations.rst:112 msgid "" -"Start Ray on you head node: on the terminal type :code:`ray start --head`. " -"This command will print a few lines, one of which indicates how to attach " -"other nodes to the head node." +"Start Ray on you head node: on the terminal type :code:`ray start " +"--head`. This command will print a few lines, one of which indicates how " +"to attach other nodes to the head node." msgstr "" -"在头部节点上启动 Ray:在终端上输入 :code:`raystart--head`。该命令将打印几行输" -"出,其中一行说明如何将其他节点连接到头部节点。" +"在头部节点上启动 Ray:在终端上输入 :code:`raystart--" +"head`。该命令将打印几行输出,其中一行说明如何将其他节点连接到头部节点。" #: ../../source/how-to-run-simulations.rst:113 msgid "" -"Attach other nodes to the head node: copy the command shown after starting " -"the head and execute it on terminal of a new node: for example :code:`ray " -"start --address='192.168.1.132:6379'`" +"Attach other nodes to the head node: copy the command shown after " +"starting the head and execute it on terminal of a new node: for example " +":code:`ray start --address='192.168.1.132:6379'`" msgstr "" -"将其他节点附加到头部节点:复制启动头部后显示的命令,并在新节点的终端上执行:" -"例如 :code:`ray start --address='192.168.1.132:6379'`" +"将其他节点附加到头部节点:复制启动头部后显示的命令,并在新节点的终端上执行:例如 :code:`ray start " +"--address='192.168.1.132:6379'`" #: ../../source/how-to-run-simulations.rst:115 msgid "" "With all the above done, you can run your code from the head node as you " "would if the simulation was running on a single node." -msgstr "" -"完成上述所有操作后,您就可以在头部节点上运行代码了,就像在单个节点上运行模拟" -"一样。" +msgstr "完成上述所有操作后,您就可以在头部节点上运行代码了,就像在单个节点上运行模拟一样。" #: ../../source/how-to-run-simulations.rst:117 msgid "" -"Once your simulation is finished, if you'd like to dismantle your cluster " -"you simply need to run the command :code:`ray stop` in each node's terminal " -"(including the head node)." -msgstr "" -"模拟结束后,如果要拆除集群,只需在每个节点(包括头部节点)的终端运行 :code:" -"`ray stop` 命令即可。" +"Once your simulation is finished, if you'd like to dismantle your cluster" +" you simply need to run the command :code:`ray stop` in each node's " +"terminal (including the head node)." +msgstr "模拟结束后,如果要拆除集群,只需在每个节点(包括头部节点)的终端运行 :code:`ray stop` 命令即可。" #: ../../source/how-to-run-simulations.rst:120 msgid "Multi-node simulation good-to-know" @@ -6355,27 +6135,28 @@ msgstr "在此,我们列举了运行多节点 FL 模拟时的一些有趣功 #: ../../source/how-to-run-simulations.rst:124 msgid "" -"User :code:`ray status` to check all nodes connected to your head node as " -"well as the total resources available to the :code:`VirtualClientEngine`." +"User :code:`ray status` to check all nodes connected to your head node as" +" well as the total resources available to the " +":code:`VirtualClientEngine`." msgstr "" -"使用 :code:`ray status` 查看连接到头部节点的所有节点,以及 :code:" -"`VirtualClientEngine` 可用的总资源。" +"使用 :code:`ray status` 查看连接到头部节点的所有节点,以及 :code:`VirtualClientEngine` " +"可用的总资源。" #: ../../source/how-to-run-simulations.rst:126 msgid "" -"When attaching a new node to the head, all its resources (i.e. all CPUs, all " -"GPUs) will be visible by the head node. This means that the :code:" -"`VirtualClientEngine` can schedule as many `virtual` clients as that node " -"can possible run. In some settings you might want to exclude certain " -"resources from the simulation. You can do this by appending `--num-" -"cpus=` and/or `--num-gpus=` in any :" -"code:`ray start` command (including when starting the head)" +"When attaching a new node to the head, all its resources (i.e. all CPUs, " +"all GPUs) will be visible by the head node. This means that the " +":code:`VirtualClientEngine` can schedule as many `virtual` clients as " +"that node can possible run. In some settings you might want to exclude " +"certain resources from the simulation. You can do this by appending " +"`--num-cpus=` and/or `--num-" +"gpus=` in any :code:`ray start` command (including " +"when starting the head)" msgstr "" -"将新节点附加到头部节点时,头部节点将可见其所有资源(即所有 CPU 和 GPU)。这意" -"味着 :code:`VirtualClientEngine` 可以调度尽可能多的 \"虚拟 \"客户端来运行该节" -"点。在某些设置中,您可能希望将某些资源排除在模拟之外。为此,您可以在任何 :" -"code:`ray start` 命令(包括启动头部时)中添加 `--num-" -"cpus=`和/或 `--num-gpus=`" +"将新节点附加到头部节点时,头部节点将可见其所有资源(即所有 CPU 和 GPU)。这意味着 :code:`VirtualClientEngine`" +" 可以调度尽可能多的 \"虚拟 \"客户端来运行该节点。在某些设置中,您可能希望将某些资源排除在模拟之外。为此,您可以在任何 :code:`ray" +" start` 命令(包括启动头部时)中添加 `--num-cpus=`和/或 `--num-" +"gpus=`" #: ../../source/how-to-run-simulations.rst:132 msgid "Considerations for simulations" @@ -6383,26 +6164,23 @@ msgstr "模拟的注意事项" #: ../../source/how-to-run-simulations.rst:135 msgid "" -"We are actively working on these fronts so to make it trivial to run any FL " -"workload with Flower simulation." -msgstr "" -"我们正在积极开展这些方面的工作,以便使 FL 工作负载与 Flower 模拟的运行变得轻" -"而易举。" +"We are actively working on these fronts so to make it trivial to run any " +"FL workload with Flower simulation." +msgstr "我们正在积极开展这些方面的工作,以便使 FL 工作负载与 Flower 模拟的运行变得轻而易举。" #: ../../source/how-to-run-simulations.rst:138 msgid "" -"The current VCE allows you to run Federated Learning workloads in simulation " -"mode whether you are prototyping simple scenarios on your personal laptop or " -"you want to train a complex FL pipeline across multiple high-performance GPU " -"nodes. While we add more capabilities to the VCE, the points below highlight " -"some of the considerations to keep in mind when designing your FL pipeline " -"with Flower. We also highlight a couple of current limitations in our " -"implementation." +"The current VCE allows you to run Federated Learning workloads in " +"simulation mode whether you are prototyping simple scenarios on your " +"personal laptop or you want to train a complex FL pipeline across " +"multiple high-performance GPU nodes. While we add more capabilities to " +"the VCE, the points below highlight some of the considerations to keep in" +" mind when designing your FL pipeline with Flower. We also highlight a " +"couple of current limitations in our implementation." msgstr "" -"当前的 VCE 允许您在模拟模式下运行联邦学习工作负载,无论您是在个人笔记本电脑上" -"建立简单的场景原型,还是要在多个高性能 GPU 节点上训练复杂的 FL情景。虽然我们" -"为 VCE 增加了更多的功能,但以下几点强调了在使用 Flower 设计 FL 时需要注意的一" -"些事项。我们还强调了我们的实现中目前存在的一些局限性。" +"当前的 VCE 允许您在模拟模式下运行联邦学习工作负载,无论您是在个人笔记本电脑上建立简单的场景原型,还是要在多个高性能 GPU 节点上训练复杂的" +" FL情景。虽然我们为 VCE 增加了更多的功能,但以下几点强调了在使用 Flower 设计 FL " +"时需要注意的一些事项。我们还强调了我们的实现中目前存在的一些局限性。" #: ../../source/how-to-run-simulations.rst:141 msgid "GPU resources" @@ -6410,29 +6188,28 @@ msgstr "GPU 资源" #: ../../source/how-to-run-simulations.rst:143 msgid "" -"The VCE assigns a share of GPU memory to a client that specifies the key :" -"code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " +"The VCE assigns a share of GPU memory to a client that specifies the key " +":code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " "internally by the VCE) is by default:" msgstr "" -"VCE 会为指定 :code:`client_resources` 中 :code:`num_gpus` 关键字的客户端分配 " -"GPU 内存份额。也就是说,Ray(VCE 内部使用)是默认的:" +"VCE 会为指定 :code:`client_resources` 中 :code:`num_gpus` 关键字的客户端分配 GPU " +"内存份额。也就是说,Ray(VCE 内部使用)是默认的:" #: ../../source/how-to-run-simulations.rst:146 msgid "" -"not aware of the total VRAM available on the GPUs. This means that if you " -"set :code:`num_gpus=0.5` and you have two GPUs in your system with different " -"(e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients concurrently." +"not aware of the total VRAM available on the GPUs. This means that if you" +" set :code:`num_gpus=0.5` and you have two GPUs in your system with " +"different (e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients" +" concurrently." msgstr "" -"不知道 GPU 上可用的总 VRAM。这意味着,如果您设置 :code:`num_gpus=0.5`,而系统" -"中有两个不同(如 32GB 和 8GB)VRAM 的 GPU,它们都将同时运行 2 个客户端。" +"不知道 GPU 上可用的总 VRAM。这意味着,如果您设置 :code:`num_gpus=0.5`,而系统中有两个不同(如 32GB 和 " +"8GB)VRAM 的 GPU,它们都将同时运行 2 个客户端。" #: ../../source/how-to-run-simulations.rst:147 msgid "" "not aware of other unrelated (i.e. not created by the VCE) workloads are " "running on the GPU. Two takeaways from this are:" -msgstr "" -"不知道 GPU 上正在运行其他无关(即不是由 VCE 创建)的工作负载。从中可以得到以" -"下两点启示:" +msgstr "不知道 GPU 上正在运行其他无关(即不是由 VCE 创建)的工作负载。从中可以得到以下两点启示:" #: ../../source/how-to-run-simulations.rst:149 msgid "" @@ -6440,27 +6217,28 @@ msgid "" "aggregation (by instance when making use of the `evaluate method `_)" msgstr "" -"您的 Flower 服务器可能需要 GPU 来评估聚合后的 \"全局模型\"(例如在使用 \"评估" -"方法\"`_时)" +"您的 Flower 服务器可能需要 GPU 来评估聚合后的 \"全局模型\"(例如在使用 \"评估方法\"`_时)" #: ../../source/how-to-run-simulations.rst:150 msgid "" "If you want to run several independent Flower simulations on the same " -"machine you need to mask-out your GPUs with :code:" -"`CUDA_VISIBLE_DEVICES=\"\"` when launching your experiment." +"machine you need to mask-out your GPUs with " +":code:`CUDA_VISIBLE_DEVICES=\"\"` when launching your " +"experiment." msgstr "" -"如果您想在同一台机器上运行多个独立的 Flower 模拟,则需要在启动实验时使用 :" -"code:`CUDA_VISIBLE_DEVICES=\"\"` 屏蔽 GPU。" +"如果您想在同一台机器上运行多个独立的 Flower 模拟,则需要在启动实验时使用 " +":code:`CUDA_VISIBLE_DEVICES=\"\"` 屏蔽 GPU。" #: ../../source/how-to-run-simulations.rst:153 msgid "" -"In addition, the GPU resource limits passed to :code:`client_resources` are " -"not `enforced` (i.e. they can be exceeded) which can result in the situation " -"of client using more VRAM than the ratio specified when starting the " -"simulation." +"In addition, the GPU resource limits passed to :code:`client_resources` " +"are not `enforced` (i.e. they can be exceeded) which can result in the " +"situation of client using more VRAM than the ratio specified when " +"starting the simulation." msgstr "" -"此外,传递给 :code:`client_resources` 的 GPU 资源限制并不是 \"强制 \"的(即可" -"以超出),这可能导致客户端使用的 VRAM 超过启动模拟时指定的比例。" +"此外,传递给 :code:`client_resources` 的 GPU 资源限制并不是 \"强制 \"的(即可以超出),这可能导致客户端使用的" +" VRAM 超过启动模拟时指定的比例。" #: ../../source/how-to-run-simulations.rst:156 msgid "TensorFlow with GPUs" @@ -6468,40 +6246,42 @@ msgstr "使用 GPU 的 TensorFlow" #: ../../source/how-to-run-simulations.rst:158 msgid "" -"When `using a GPU with TensorFlow `_ " -"nearly your entire GPU memory of all your GPUs visible to the process will " -"be mapped. This is done by TensorFlow for optimization purposes. However, in " -"settings such as FL simulations where we want to split the GPU into multiple " -"`virtual` clients, this is not a desirable mechanism. Luckily we can disable " -"this default behavior by `enabling memory growth `_." +"When `using a GPU with TensorFlow " +"`_ nearly your entire GPU memory of" +" all your GPUs visible to the process will be mapped. This is done by " +"TensorFlow for optimization purposes. However, in settings such as FL " +"simulations where we want to split the GPU into multiple `virtual` " +"clients, this is not a desirable mechanism. Luckily we can disable this " +"default behavior by `enabling memory growth " +"`_." msgstr "" -"在 TensorFlow `_ 中使用 GPU 时,几乎所" -"有进程可见的 GPU 内存都将被映射。TensorFlow 这样做是出于优化目的。然而,在 " -"FL 模拟等设置中,我们希望将 GPU 分割成多个 \"虚拟 \"客户端,这并不是一个理想" -"的机制。幸运的是,我们可以通过 `启用内存增长 `_来禁用这一默认行为。" +"在 TensorFlow `_ 中使用 GPU 时,几乎所有进程可见的" +" GPU 内存都将被映射。TensorFlow 这样做是出于优化目的。然而,在 FL 模拟等设置中,我们希望将 GPU 分割成多个 \"虚拟 " +"\"客户端,这并不是一个理想的机制。幸运的是,我们可以通过 `启用内存增长 " +"`_来禁用这一默认行为。" #: ../../source/how-to-run-simulations.rst:160 msgid "" -"This would need to be done in the main process (which is where the server " -"would run) and in each Actor created by the VCE. By means of :code:" -"`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` in order " -"to specify a function to be executed upon actor initialization. In this " -"case, to enable GPU growth for TF workloads. It would look as follows:" +"This would need to be done in the main process (which is where the server" +" would run) and in each Actor created by the VCE. By means of " +":code:`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` " +"in order to specify a function to be executed upon actor initialization. " +"In this case, to enable GPU growth for TF workloads. It would look as " +"follows:" msgstr "" -"这需要在主进程(也就是服务器运行的地方)和 VCE 创建的每个角色中完成。通过 :" -"code:`actor_kwargs`,我们可以传递保留关键字`\"on_actor_init_fn\"`,以指定在角" -"色初始化时执行的函数。在本例中,为了使 TF 工作负载的 GPU 增长,它看起来如下:" +"这需要在主进程(也就是服务器运行的地方)和 VCE 创建的每个角色中完成。通过 " +":code:`actor_kwargs`,我们可以传递保留关键字`\"on_actor_init_fn\"`,以指定在角色初始化时执行的函数。在本例中,为了使" +" TF 工作负载的 GPU 增长,它看起来如下:" #: ../../source/how-to-run-simulations.rst:179 msgid "" "This is precisely the mechanism used in `Tensorflow/Keras Simulation " -"`_ " -"example." +"`_ example." msgstr "" -"这正是 \"Tensorflow/Keras 模拟 `_\"示例中使用的机制。" +"这正是 \"Tensorflow/Keras 模拟 " +"`_\"示例中使用的机制。" #: ../../source/how-to-run-simulations.rst:183 msgid "Multi-node setups" @@ -6509,35 +6289,35 @@ msgstr "多节点设置" #: ../../source/how-to-run-simulations.rst:185 msgid "" -"The VCE does not currently offer a way to control on which node a particular " -"`virtual` client is executed. In other words, if more than a single node " -"have the resources needed by a client to run, then any of those nodes could " -"get the client workload scheduled onto. Later in the FL process (i.e. in a " -"different round) the same client could be executed by a different node. " -"Depending on how your clients access their datasets, this might require " -"either having a copy of all dataset partitions on all nodes or a dataset " -"serving mechanism (e.g. using nfs, a database) to circumvent data " -"duplication." -msgstr "" -"VCE 目前不提供控制特定 \"虚拟 \"客户端在哪个节点上执行的方法。换句话说,如果" -"不止一个节点拥有客户端运行所需的资源,那么这些节点中的任何一个都可能被调度到" -"客户端工作负载上。在 FL 进程的稍后阶段(即在另一轮中),同一客户端可以由不同" -"的节点执行。根据客户访问数据集的方式,这可能需要在所有节点上复制所有数据集分" -"区,或采用数据集服务机制(如使用 nfs 或数据库)来避免数据重复。" +"The VCE does not currently offer a way to control on which node a " +"particular `virtual` client is executed. In other words, if more than a " +"single node have the resources needed by a client to run, then any of " +"those nodes could get the client workload scheduled onto. Later in the FL" +" process (i.e. in a different round) the same client could be executed by" +" a different node. Depending on how your clients access their datasets, " +"this might require either having a copy of all dataset partitions on all " +"nodes or a dataset serving mechanism (e.g. using nfs, a database) to " +"circumvent data duplication." +msgstr "" +"VCE 目前不提供控制特定 \"虚拟 " +"\"客户端在哪个节点上执行的方法。换句话说,如果不止一个节点拥有客户端运行所需的资源,那么这些节点中的任何一个都可能被调度到客户端工作负载上。在 " +"FL " +"进程的稍后阶段(即在另一轮中),同一客户端可以由不同的节点执行。根据客户访问数据集的方式,这可能需要在所有节点上复制所有数据集分区,或采用数据集服务机制(如使用" +" nfs 或数据库)来避免数据重复。" #: ../../source/how-to-run-simulations.rst:187 msgid "" -"By definition virtual clients are `stateless` due to their ephemeral nature. " -"A client state can be implemented as part of the Flower client class but " -"users need to ensure this saved to persistent storage (e.g. a database, " -"disk) and that can be retrieve later by the same client regardless on which " -"node it is running from. This is related to the point above also since, in " -"some way, the client's dataset could be seen as a type of `state`." +"By definition virtual clients are `stateless` due to their ephemeral " +"nature. A client state can be implemented as part of the Flower client " +"class but users need to ensure this saved to persistent storage (e.g. a " +"database, disk) and that can be retrieve later by the same client " +"regardless on which node it is running from. This is related to the point" +" above also since, in some way, the client's dataset could be seen as a " +"type of `state`." msgstr "" -"根据定义,虚拟客户端是 \"无状态 \"的,因为它们具有即时性。客户机状态可以作为 " -"Flower 客户机类的一部分来实现,但用户需要确保将其保存到持久存储(如数据库、磁" -"盘)中,而且无论客户机在哪个节点上运行,都能在以后检索到。这也与上述观点有" -"关,因为在某种程度上,客户端的数据集可以被视为一种 \"状态\"。" +"根据定义,虚拟客户端是 \"无状态 \"的,因为它们具有即时性。客户机状态可以作为 Flower " +"客户机类的一部分来实现,但用户需要确保将其保存到持久存储(如数据库、磁盘)中,而且无论客户机在哪个节点上运行,都能在以后检索到。这也与上述观点有关,因为在某种程度上,客户端的数据集可以被视为一种" +" \"状态\"。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:2 msgid "Save and load model checkpoints" @@ -6545,12 +6325,10 @@ msgstr "保存和加载模型检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:4 msgid "" -"Flower does not automatically save model updates on the server-side. This " -"how-to guide describes the steps to save (and load) model checkpoints in " -"Flower." -msgstr "" -"Flower 不会在服务器端自动保存模型更新。本指南将介绍在 Flower 中保存(和加载)" -"模型检查点的步骤。" +"Flower does not automatically save model updates on the server-side. This" +" how-to guide describes the steps to save (and load) model checkpoints in" +" Flower." +msgstr "Flower 不会在服务器端自动保存模型更新。本指南将介绍在 Flower 中保存(和加载)模型检查点的步骤。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:8 msgid "Model checkpointing" @@ -6558,22 +6336,22 @@ msgstr "模型检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:10 msgid "" -"Model updates can be persisted on the server-side by customizing :code:" -"`Strategy` methods. Implementing custom strategies is always an option, but " -"for many cases it may be more convenient to simply customize an existing " -"strategy. The following code example defines a new :code:`SaveModelStrategy` " -"which customized the existing built-in :code:`FedAvg` strategy. In " -"particular, it customizes :code:`aggregate_fit` by calling :code:" -"`aggregate_fit` in the base class (:code:`FedAvg`). It then continues to " -"save returned (aggregated) weights before it returns those aggregated " -"weights to the caller (i.e., the server):" -msgstr "" -"模型更新可通过自定义 :code:`Strategy` 方法在服务器端持久化。实现自定义策略始" -"终是一种选择,但在许多情况下,简单地自定义现有策略可能更方便。下面的代码示例" -"定义了一个新的 :code:`SaveModelStrategy`,它自定义了现有的内置 :code:" -"`FedAvg` 策略。特别是,它通过调用基类(:code:`FedAvg`)中的 :code:" -"`aggregate_fit` 来定制 :code:`aggregate_fit`。然后继续保存返回的(聚合)参" -"数,然后再将这些聚合参数返回给调用者(即服务器):" +"Model updates can be persisted on the server-side by customizing " +":code:`Strategy` methods. Implementing custom strategies is always an " +"option, but for many cases it may be more convenient to simply customize " +"an existing strategy. The following code example defines a new " +":code:`SaveModelStrategy` which customized the existing built-in " +":code:`FedAvg` strategy. In particular, it customizes " +":code:`aggregate_fit` by calling :code:`aggregate_fit` in the base class " +"(:code:`FedAvg`). It then continues to save returned (aggregated) weights" +" before it returns those aggregated weights to the caller (i.e., the " +"server):" +msgstr "" +"模型更新可通过自定义 :code:`Strategy` " +"方法在服务器端持久化。实现自定义策略始终是一种选择,但在许多情况下,简单地自定义现有策略可能更方便。下面的代码示例定义了一个新的 " +":code:`SaveModelStrategy`,它自定义了现有的内置 :code:`FedAvg` " +"策略。特别是,它通过调用基类(:code:`FedAvg`)中的 :code:`aggregate_fit` 来定制 " +":code:`aggregate_fit`。然后继续保存返回的(聚合)参数,然后再将这些聚合参数返回给调用者(即服务器):" #: ../../source/how-to-save-and-load-model-checkpoints.rst:47 msgid "Save and load PyTorch checkpoints" @@ -6581,32 +6359,29 @@ msgstr "保存和加载 PyTorch 检查点" #: ../../source/how-to-save-and-load-model-checkpoints.rst:49 msgid "" -"Similar to the previous example but with a few extra steps, we'll show how " -"to store a PyTorch checkpoint we'll use the ``torch.save`` function. " -"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be " -"transformed into a list of NumPy ``ndarray``'s, then those are transformed " -"into the PyTorch ``state_dict`` following the ``OrderedDict`` class " -"structure." +"Similar to the previous example but with a few extra steps, we'll show " +"how to store a PyTorch checkpoint we'll use the ``torch.save`` function. " +"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be" +" transformed into a list of NumPy ``ndarray``'s, then those are " +"transformed into the PyTorch ``state_dict`` following the ``OrderedDict``" +" class structure." msgstr "" -"与前面的例子类似,但多了几个步骤,我们将展示如何存储一个 PyTorch 检查点,我们" -"将使用 ``torch.save`` 函数。首先,``aggregate_fit`` 返回一个 ``Parameters`` " -"对象,它必须被转换成一个 NumPy ``ndarray`` 的列表,然后这些对象按照 " -"``OrderedDict`` 类结构被转换成 PyTorch `state_dict` 对象。" +"与前面的例子类似,但多了几个步骤,我们将展示如何存储一个 PyTorch 检查点,我们将使用 ``torch.save`` " +"函数。首先,``aggregate_fit`` 返回一个 ``Parameters`` 对象,它必须被转换成一个 NumPy " +"``ndarray`` 的列表,然后这些对象按照 ``OrderedDict`` 类结构被转换成 PyTorch `state_dict` 对象。" #: ../../source/how-to-save-and-load-model-checkpoints.rst:85 msgid "" -"To load your progress, you simply append the following lines to your code. " -"Note that this will iterate over all saved checkpoints and load the latest " -"one:" -msgstr "" -"要加载进度,只需在代码中添加以下几行。请注意,这将遍历所有已保存的检查点,并" -"加载最新的检查点:" +"To load your progress, you simply append the following lines to your " +"code. Note that this will iterate over all saved checkpoints and load the" +" latest one:" +msgstr "要加载进度,只需在代码中添加以下几行。请注意,这将遍历所有已保存的检查点,并加载最新的检查点:" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 #, fuzzy msgid "" -"Return/use this object of type ``Parameters`` wherever necessary, such as in " -"the ``initial_parameters`` when defining a ``Strategy``." +"Return/use this object of type ``Parameters`` wherever necessary, such as" +" in the ``initial_parameters`` when defining a ``Strategy``." msgstr "" "在必要时返回/使用此 ``Parameters`` 类型的对象,例如在定义 ``Strategy` 时的 " "``initial_parameters` 中。" @@ -6617,23 +6392,23 @@ msgstr "升级至 Flower 1.0" #: ../../source/how-to-upgrade-to-flower-1.0.rst:4 msgid "" -"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable " -"foundation for future growth. Compared to Flower 0.19 (and other 0.x series " -"releases), there are a few breaking changes that make it necessary to change " -"the code of existing 0.x-series projects." +"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable" +" foundation for future growth. Compared to Flower 0.19 (and other 0.x " +"series releases), there are a few breaking changes that make it necessary" +" to change the code of existing 0.x-series projects." msgstr "" -"Flower 1.0 正式发布。除了新功能,Flower 1.0 还为未来的发展奠定了稳定的基础。" -"与 Flower 0.19(以及其他 0.x 系列版本)相比,有一些破坏性改动需要修改现有 0." -"x 系列项目的代码。" +"Flower 1.0 正式发布。除了新功能,Flower 1.0 还为未来的发展奠定了稳定的基础。与 Flower 0.19(以及其他 0.x " +"系列版本)相比,有一些破坏性改动需要修改现有 0.x 系列项目的代码。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 +#: ../../source/how-to-upgrade-to-flower-next.rst:43 msgid "Install update" msgstr "安装更新" #: ../../source/how-to-upgrade-to-flower-1.0.rst:10 msgid "" -"Here's how to update an existing installation to Flower 1.0 using either pip " -"or Poetry:" +"Here's how to update an existing installation to Flower 1.0 using either " +"pip or Poetry:" msgstr "下面介绍如何使用 pip 或 Poetry 将现有安装更新到 Flower 1.0:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:12 @@ -6644,15 +6419,13 @@ msgstr "pip: 安装时添加 ``-U``." msgid "" "``python -m pip install -U flwr`` (when using ``start_server`` and " "``start_client``)" -msgstr "" -"`python -m pip install -U flwr``(当使用`start_server`和`start_client`时)" +msgstr "`python -m pip install -U flwr``(当使用`start_server`和`start_client`时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:15 msgid "" "``python -m pip install -U flwr[simulation]`` (when using " "``start_simulation``)" -msgstr "" -"`python -m pip install -U flwr[simulation]``(当使用`start_simulation``时)" +msgstr "`python -m pip install -U flwr[simulation]``(当使用`start_simulation``时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:17 msgid "" @@ -6660,23 +6433,23 @@ msgid "" "reinstall (don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` " "before running ``poetry install``)." msgstr "" -"Poetry:更新 ``pyproject.toml`` 中的 ``flwr`` 依赖包,然后重新安装(运行 " -"``poetry install`` 前,别忘了通过 ``rm poetry.lock` 删除 ``poetry.lock`)。" +"Poetry:更新 ``pyproject.toml`` 中的 ``flwr`` 依赖包,然后重新安装(运行 ``poetry install``" +" 前,别忘了通过 ``rm poetry.lock` 删除 ``poetry.lock`)。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:19 -msgid "" -"``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" +msgid "``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" msgstr "``flwr = \"^1.0.0\"`` (当使用 ``start_server` 和 ``start_client` 时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:20 msgid "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when using " -"``start_simulation``)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when " +"using ``start_simulation``)" msgstr "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }``(当使用" -"``start_simulation``时)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] " +"}``(当使用``start_simulation``时)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 +#: ../../source/how-to-upgrade-to-flower-next.rst:100 msgid "Required changes" msgstr "所需变更" @@ -6698,17 +6471,22 @@ msgstr "将所有参数作为关键字参数传递(而不是位置参数)。 msgid "" "Flower 0.19 (positional arguments): ``start_client(\"127.0.0.1:8080\", " "FlowerClient())``" -msgstr "" -"Flower 0.19 (位置参数): ``start_client(\"127.0.0.1:8080\", FlowerClient())``" +msgstr "Flower 0.19 (位置参数): ``start_client(\"127.0.0.1:8080\", FlowerClient())``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:34 msgid "" "Flower 1.0 (keyword arguments): " -"``start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())``" +"``start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())``" msgstr "" "Flower 1.0(关键字参数): ``start_client(server_address=\"127.0.0.1:8080\", " "client=FlowerClient())``" +#: ../../source/how-to-upgrade-to-flower-1.0.rst:37 +#: ../../source/ref-api/flwr.client.Client.rst:2 +msgid "Client" +msgstr "客户端" + #: ../../source/how-to-upgrade-to-flower-1.0.rst:39 msgid "" "Subclasses of ``NumPyClient``: change ``def get_parameters(self):``` to " @@ -6722,8 +6500,8 @@ msgid "" "Subclasses of ``Client``: change ``def get_parameters(self):``` to ``def " "get_parameters(self, ins: GetParametersIns):``" msgstr "" -"客户端 \"的子类:将 \"get_parameters(self): \"改为 \"get_parameters(self, " -"ins: GetParametersIns):\"" +"客户端 \"的子类:将 \"get_parameters(self): \"改为 \"get_parameters(self, ins: " +"GetParametersIns):\"" #: ../../source/how-to-upgrade-to-flower-1.0.rst:43 msgid "Strategies / ``start_server`` / ``start_simulation``" @@ -6747,30 +6525,29 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:48 msgid "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" msgstr "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:50 msgid "" "Replace ``num_rounds=1`` in ``start_simulation`` with the new " "``config=ServerConfig(...)`` (see previous item)" -msgstr "" -"将`start_simulation``中的`num_rounds=1``替换为新的`config=ServerConfig(...)`" -"(参见前一项)" +msgstr "将`start_simulation``中的`num_rounds=1``替换为新的`config=ServerConfig(...)`(参见前一项)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:51 msgid "" "Remove ``force_final_distributed_eval`` parameter from calls to " -"``start_server``. Distributed evaluation on all clients can be enabled by " -"configuring the strategy to sample all clients for evaluation after the last " -"round of training." +"``start_server``. Distributed evaluation on all clients can be enabled by" +" configuring the strategy to sample all clients for evaluation after the " +"last round of training." msgstr "" -"删除调用 ``start_server`` 时的 ``force_final_distributed_eval` 参数。可以通过" -"配置策略,在最后一轮训练后对所有客户端进行抽样评估,从而启用对所有客户端的分" -"布式评估。" +"删除调用 ``start_server`` 时的 ``force_final_distributed_eval` " +"参数。可以通过配置策略,在最后一轮训练后对所有客户端进行抽样评估,从而启用对所有客户端的分布式评估。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:52 msgid "Rename parameter/ndarray conversion functions:" @@ -6786,18 +6563,17 @@ msgstr "``weights_to_parameters`` --> ``ndarrays_to_parameters``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:57 msgid "" -"Strategy initialization: if the strategy relies on the default values for " -"``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " +"Strategy initialization: if the strategy relies on the default values for" +" ``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " "``fraction_evaluate`` manually to ``0.1``. Projects that do not manually " "create a strategy (by calling ``start_server`` or ``start_simulation`` " -"without passing a strategy instance) should now manually initialize FedAvg " -"with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." +"without passing a strategy instance) should now manually initialize " +"FedAvg with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." msgstr "" -"策略初始化:如果策略依赖于 ``fraction_fit`` 和 ``fraction_evaluate`` 的默认" -"值,请手动将 ``fraction_fit`` 和 ``fraction_evaluate`` 设置为 ``0.1``。未手动" -"创建策略的项目(调用 ``start_server` 或 ``start_simulation` 时未传递策略实" -"例)现在应手动初始化 FedAvg,并将 `fraction_fit` 和 `fraction_evaluate` 设为 " -"`0.1``。" +"策略初始化:如果策略依赖于 ``fraction_fit`` 和 ``fraction_evaluate`` 的默认值,请手动将 " +"``fraction_fit`` 和 ``fraction_evaluate`` 设置为 ``0.1``。未手动创建策略的项目(调用 " +"``start_server` 或 ``start_simulation` 时未传递策略实例)现在应手动初始化 FedAvg,并将 " +"`fraction_fit` 和 `fraction_evaluate` 设为 `0.1``。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:58 msgid "Rename built-in strategy parameters (e.g., ``FedAvg``):" @@ -6822,8 +6598,8 @@ msgid "" "``configure_evaluate``, ``aggregate_evaluate``, and ``evaluate_fn``." msgstr "" "将 `rnd` 更名为 `server_round`。这会影响多个方法和函数,例如 " -"``configure_fit``、``aggregate_fit``、``configure_evaluate``、" -"`aggregate_evaluate`` 和 ``evaluate_fn``。" +"``configure_fit``、``aggregate_fit``、``configure_evaluate``、`aggregate_evaluate``" +" 和 ``evaluate_fn``。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:65 msgid "Add ``server_round`` and ``config`` to ``evaluate_fn``:" @@ -6831,19 +6607,21 @@ msgstr "在 ``evaluate_fn` 中添加 ``server_round` 和 ``config`:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:67 msgid "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " -"Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " +"Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " -"Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " +"Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:68 msgid "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " -"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " +"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " +"Scalar]]]:``" msgstr "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " -"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " +"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " +"Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:71 msgid "Custom strategies" @@ -6851,23 +6629,22 @@ msgstr "定制策略" #: ../../source/how-to-upgrade-to-flower-1.0.rst:73 msgid "" -"The type of parameter ``failures`` has changed from ``List[BaseException]`` " -"to ``List[Union[Tuple[ClientProxy, FitRes], BaseException]]`` (in " -"``aggregate_fit``) and ``List[Union[Tuple[ClientProxy, EvaluateRes], " -"BaseException]]`` (in ``aggregate_evaluate``)" +"The type of parameter ``failures`` has changed from " +"``List[BaseException]`` to ``List[Union[Tuple[ClientProxy, FitRes], " +"BaseException]]`` (in ``aggregate_fit``) and " +"``List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]]`` (in " +"``aggregate_evaluate``)" msgstr "" -"参数``failures``的类型已从``List[BaseException]``变为" -"``List[Union[Tuple[ClientProxy, FitRes], BaseException]]``(在" -"``agregate_fit``中)和``List[Union[Tuple[ClientProxy, EvaluateRes], " -"BaseException]]``(在``agregate_evaluate``中)" +"参数``failures``的类型已从``List[BaseException]``变为``List[Union[Tuple[ClientProxy," +" FitRes], " +"BaseException]]``(在``agregate_fit``中)和``List[Union[Tuple[ClientProxy, " +"EvaluateRes], BaseException]]``(在``agregate_evaluate``中)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:74 msgid "" "The ``Strategy`` method ``evaluate`` now receives the current round of " "federated learning/evaluation as the first parameter:" -msgstr "" -"``Strategy``方法 的``evaluate``现在会接收当前一轮联邦学习/评估作为第一个参" -"数:" +msgstr "``Strategy``方法 的``evaluate``现在会接收当前一轮联邦学习/评估作为第一个参数:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:76 msgid "" @@ -6879,11 +6656,11 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:77 msgid "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" -"> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " +"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" -"> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " +"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:80 msgid "Optional improvements" @@ -6898,11 +6675,12 @@ msgstr "除了上述必要的改动之外,还有一些潜在的改进措施: #: ../../source/how-to-upgrade-to-flower-1.0.rst:84 msgid "" "Remove \"placeholder\" methods from subclasses of ``Client`` or " -"``NumPyClient``. If you, for example, use server-side evaluation, then empty " -"placeholder implementations of ``evaluate`` are no longer necessary." +"``NumPyClient``. If you, for example, use server-side evaluation, then " +"empty placeholder implementations of ``evaluate`` are no longer " +"necessary." msgstr "" -"删除 ``Client`` 或 ``NumPyClient`` 子类中的 \"占位符 \"方法。例如,如果你使用" -"服务器端评估,那么就不再需要``evaluate``的 \"空占位符 \"实现。" +"删除 ``Client`` 或 ``NumPyClient`` 子类中的 \"占位符 " +"\"方法。例如,如果你使用服务器端评估,那么就不再需要``evaluate``的 \"空占位符 \"实现。" #: ../../source/how-to-upgrade-to-flower-1.0.rst:85 msgid "" @@ -6910,116 +6688,313 @@ msgid "" "``start_simulation(..., config=flwr.server.ServerConfig(num_rounds=3, " "round_timeout=600.0), ...)``" msgstr "" -"通过 ``start_simulation`` 配置循环超时: ``start_simulation(..., config=flwr." -"server.ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +"通过 ``start_simulation`` 配置循环超时: ``start_simulation(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 +#: ../../source/how-to-upgrade-to-flower-next.rst:317 msgid "Further help" msgstr "更多帮助" #: ../../source/how-to-upgrade-to-flower-1.0.rst:91 msgid "" -"Most official `Flower code examples `_ are already updated to Flower 1.0, they can serve as a " -"reference for using the Flower 1.0 API. If there are further questions, " -"`join the Flower Slack `_ and use the channel " -"``#questions``." +"Most official `Flower code examples " +"`_ are already updated" +" to Flower 1.0, they can serve as a reference for using the Flower 1.0 " +"API. If there are further questions, `join the Flower Slack " +"`_ and use the channel ``#questions``." msgstr "" -"大多数官方的 `Flower 代码示例 `_ 已经更新到 Flower 1.0,它们可以作为使用 Flower 1.0 API 的参考。如" -"果还有其他问题,请加入 Flower Slack `_ 并使用 " -"\"#questions``\"。" +"大多数官方的 `Flower 代码示例 `_" +" 已经更新到 Flower 1.0,它们可以作为使用 Flower 1.0 API 的参考。如果还有其他问题,请加入 Flower Slack " +"`_ 并使用 \"#questions``\"。" -#: ../../source/how-to-use-built-in-mods.rst:2 +#: ../../source/how-to-upgrade-to-flower-next.rst:2 #, fuzzy -msgid "Use Built-in Mods" -msgstr "使用内置调制器" +msgid "Upgrade to Flower Next" +msgstr "升级至 Flower 1.0" -#: ../../source/how-to-use-built-in-mods.rst:4 -#, fuzzy +#: ../../source/how-to-upgrade-to-flower-next.rst:4 msgid "" -"**Note: This tutorial covers experimental features. The functionality and " -"interfaces may change in future versions.**" -msgstr "**注:本教程涵盖实验性功能。功能和界面可能会在未来版本中发生变化。" +"Welcome to the migration guide for updating Flower to Flower Next! " +"Whether you're a seasoned user or just getting started, this guide will " +"help you smoothly transition your existing setup to take advantage of the" +" latest features and improvements in Flower Next, starting from version " +"1.8." +msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:6 -#, fuzzy +#: ../../source/how-to-upgrade-to-flower-next.rst:9 msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment the " -"behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) allow us " -"to perform operations before and after a task is processed in the " -"``ClientApp``." +"This guide shows how to reuse pre-``1.8`` Flower code with minimum code " +"changes by using the *compatibility layer* in Flower Next. In another " +"guide, we will show how to run Flower Next end-to-end with pure Flower " +"Next APIs." msgstr "" -"在本教程中,我们将学习如何利用内置模块来增强 ``ClientApp`` 的行为。修改器(有" -"时也称为修改器)允许我们在 ``ClientApp`` 处理任务之前和之后执行操作。" -#: ../../source/how-to-use-built-in-mods.rst:9 -#, fuzzy -msgid "What are Mods?" -msgstr "什么是 Mods?" +#: ../../source/how-to-upgrade-to-flower-next.rst:13 +msgid "Let's dive in!" +msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:11 +#: ../../source/how-to-upgrade-to-flower-next.rst:48 #, fuzzy msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate or " -"inspect the incoming ``Message`` and the resulting outgoing ``Message``. The " -"signature for a ``Mod`` is as follows:" -msgstr "" -"Mod 是包裹在 ``ClientApp`` 周围的可调用程序。它可以操作或检查传入的 " -"``Message`` 和由此产生的传出的 ``Message`` 。一个 ``Mod`` 的签名如下:" +"Here's how to update an existing installation of Flower to Flower Next " +"with ``pip``:" +msgstr "下面介绍如何使用 pip 或 Poetry 将现有安装更新到 Flower 1.0:" -#: ../../source/how-to-use-built-in-mods.rst:18 +#: ../../source/how-to-upgrade-to-flower-next.rst:54 #, fuzzy -msgid "A typical mod function might look something like this:" -msgstr "一个典型的修改函数可能是这样的:" +msgid "or if you need Flower Next with simulation:" +msgstr "启动 Flower 模拟" -#: ../../source/how-to-use-built-in-mods.rst:31 -#, fuzzy -msgid "Using Mods" -msgstr "使用修改器" +#: ../../source/how-to-upgrade-to-flower-next.rst:61 +msgid "" +"Ensure you set the following version constraint in your " +"``requirements.txt``" +msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:33 -#, fuzzy -msgid "To use mods in your ``ClientApp``, you can follow these steps:" -msgstr "要在您的 ``ClientApp`` 中使用 mod,可以按照以下步骤操作:" +#: ../../source/how-to-upgrade-to-flower-next.rst:71 +msgid "or ``pyproject.toml``:" +msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:36 +#: ../../source/how-to-upgrade-to-flower-next.rst:82 #, fuzzy -msgid "1. Import the required mods" -msgstr "1. 导入所需修改" +msgid "Using Poetry" +msgstr "使用 pip" -#: ../../source/how-to-use-built-in-mods.rst:38 +#: ../../source/how-to-upgrade-to-flower-next.rst:84 #, fuzzy -msgid "First, import the built-in mod you intend to use:" -msgstr "首先,导入您打算使用的内置模式:" +msgid "" +"Update the ``flwr`` dependency in ``pyproject.toml`` and then reinstall " +"(don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` before " +"running ``poetry install``)." +msgstr "" +"Poetry:更新 ``pyproject.toml`` 中的 ``flwr`` 依赖包,然后重新安装(运行 ``poetry install``" +" 前,别忘了通过 ``rm poetry.lock` 删除 ``poetry.lock`)。" -#: ../../source/how-to-use-built-in-mods.rst:46 +#: ../../source/how-to-upgrade-to-flower-next.rst:86 #, fuzzy -msgid "2. Define your client function" -msgstr "2. 定义客户功能" +msgid "" +"Ensure you set the following version constraint in your " +"``pyproject.toml``:" +msgstr "将 ``pyproject.toml`` 中的次要版本增加一个。" -#: ../../source/how-to-use-built-in-mods.rst:48 -#, fuzzy +#: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" -"Define your client function (``client_fn``) that will be wrapped by the " -"mod(s):" -msgstr "定义将被 mod 封装的客户端函数(``client_fn``):" +"In Flower Next, the *infrastructure* and *application layers* have been " +"decoupled. Instead of starting a client in code via ``start_client()``, " +"you create a |clientapp_link|_ and start it via the command line. Instead" +" of starting a server in code via ``start_server()``, you create a " +"|serverapp_link|_ and start it via the command line. The long-running " +"components of server and client are called SuperLink and SuperNode. The " +"following non-breaking changes that require manual updates and allow you " +"to run your project both in the traditional way and in the Flower Next " +"way:" +msgstr "" -#: ../../source/how-to-use-built-in-mods.rst:57 +#: ../../source/how-to-upgrade-to-flower-next.rst:109 #, fuzzy -msgid "3. Create the ``ClientApp`` with mods" -msgstr "3. 用模块创建 ``ClientApp``" +msgid "|clientapp_link|_" +msgstr "客户端" -#: ../../source/how-to-use-built-in-mods.rst:59 -#, fuzzy +#: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" -"Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " -"argument. The order in which you provide the mods matters:" +"Wrap your existing client with |clientapp_link|_ instead of launching it " +"via |startclient_link|_. Here's an example:" msgstr "" -"创建您的 ``ClientApp`` 并将 mods 作为列表传递给 ``mods`` 参数。提供 mod 的顺" -"序很重要:" -#: ../../source/how-to-use-built-in-mods.rst:72 +#: ../../source/how-to-upgrade-to-flower-next.rst:132 +#, fuzzy +msgid "|serverapp_link|_" +msgstr "服务器" + +#: ../../source/how-to-upgrade-to-flower-next.rst:133 +msgid "" +"Wrap your existing strategy with |serverapp_link|_ instead of starting " +"the server via |startserver_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:154 +msgid "Deployment" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:155 +msgid "" +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " +"in sequence, |flowernext_clientapp_link|_ (2x) and " +"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" +" `server.py` as Python scripts." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:158 +msgid "" +"Here's an example to start the server without HTTPS (only for " +"prototyping):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:174 +msgid "" +"Here's another example to start with HTTPS. Use the ``--certificates`` " +"command line argument to pass paths to (CA certificate, server " +"certificate, and server private key)." +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:201 +#, fuzzy +msgid "Simulation in CLI" +msgstr "运行模拟" + +#: ../../source/how-to-upgrade-to-flower-next.rst:202 +msgid "" +"Wrap your existing client and strategy with |clientapp_link|_ and " +"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" +" anymore. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:232 +msgid "" +"Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " +"``client_app`` object in the code instead of executing the Python script." +" Here's an example (assuming the ``server_app`` and ``client_app`` " +"objects are in a ``sim.py`` module):" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:249 +msgid "" +"Set default resources for each |clientapp_link|_ using the ``--backend-" +"config`` command line argument instead of setting the " +"``client_resources`` argument in |startsim_link|_. Here's an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:275 +msgid "Simulation in a Notebook" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:276 +msgid "" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " +"an example:" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:319 +#, fuzzy +msgid "" +"Some official `Flower code examples `_ " +"are already updated to Flower Next so they can serve as a reference for " +"using the Flower Next API. If there are further questions, `join the " +"Flower Slack `_ and use the channel " +"``#questions``. You can also `participate in Flower Discuss " +"`_ where you can find us answering questions," +" or share and learn from others about migrating to Flower Next." +msgstr "" +"大多数官方的 `Flower 代码示例 `_" +" 已经更新到 Flower 1.0,它们可以作为使用 Flower 1.0 API 的参考。如果还有其他问题,请加入 Flower Slack " +"`_ 并使用 \"#questions``\"。" + +#: ../../source/how-to-upgrade-to-flower-next.rst:325 +#, fuzzy +msgid "Important" +msgstr "重要变更:" + +#: ../../source/how-to-upgrade-to-flower-next.rst:328 +msgid "" +"As we continuously enhance Flower Next at a rapid pace, we'll be " +"periodically updating this guide. Please feel free to share any feedback " +"with us!" +msgstr "" + +#: ../../source/how-to-upgrade-to-flower-next.rst:334 +msgid "Happy migrating! 🚀" +msgstr "" + +#: ../../source/how-to-use-built-in-mods.rst:2 +#, fuzzy +msgid "Use Built-in Mods" +msgstr "使用内置调制器" + +#: ../../source/how-to-use-built-in-mods.rst:4 +#, fuzzy +msgid "" +"**Note: This tutorial covers experimental features. The functionality and" +" interfaces may change in future versions.**" +msgstr "**注:本教程涵盖实验性功能。功能和界面可能会在未来版本中发生变化。" + +#: ../../source/how-to-use-built-in-mods.rst:6 +#, fuzzy +msgid "" +"In this tutorial, we will learn how to utilize built-in mods to augment " +"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " +"allow us to perform operations before and after a task is processed in " +"the ``ClientApp``." +msgstr "" +"在本教程中,我们将学习如何利用内置模块来增强 ``ClientApp`` 的行为。修改器(有时也称为修改器)允许我们在 ``ClientApp``" +" 处理任务之前和之后执行操作。" + +#: ../../source/how-to-use-built-in-mods.rst:9 +#, fuzzy +msgid "What are Mods?" +msgstr "什么是 Mods?" + +#: ../../source/how-to-use-built-in-mods.rst:11 +#, fuzzy +msgid "" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " +"or inspect the incoming ``Message`` and the resulting outgoing " +"``Message``. The signature for a ``Mod`` is as follows:" +msgstr "" +"Mod 是包裹在 ``ClientApp`` 周围的可调用程序。它可以操作或检查传入的 ``Message`` 和由此产生的传出的 " +"``Message`` 。一个 ``Mod`` 的签名如下:" + +#: ../../source/how-to-use-built-in-mods.rst:18 +#, fuzzy +msgid "A typical mod function might look something like this:" +msgstr "一个典型的修改函数可能是这样的:" + +#: ../../source/how-to-use-built-in-mods.rst:31 +#, fuzzy +msgid "Using Mods" +msgstr "使用修改器" + +#: ../../source/how-to-use-built-in-mods.rst:33 +#, fuzzy +msgid "To use mods in your ``ClientApp``, you can follow these steps:" +msgstr "要在您的 ``ClientApp`` 中使用 mod,可以按照以下步骤操作:" + +#: ../../source/how-to-use-built-in-mods.rst:36 +#, fuzzy +msgid "1. Import the required mods" +msgstr "1. 导入所需修改" + +#: ../../source/how-to-use-built-in-mods.rst:38 +#, fuzzy +msgid "First, import the built-in mod you intend to use:" +msgstr "首先,导入您打算使用的内置模式:" + +#: ../../source/how-to-use-built-in-mods.rst:46 +#, fuzzy +msgid "2. Define your client function" +msgstr "2. 定义客户功能" + +#: ../../source/how-to-use-built-in-mods.rst:48 +#, fuzzy +msgid "" +"Define your client function (``client_fn``) that will be wrapped by the " +"mod(s):" +msgstr "定义将被 mod 封装的客户端函数(``client_fn``):" + +#: ../../source/how-to-use-built-in-mods.rst:57 +#, fuzzy +msgid "3. Create the ``ClientApp`` with mods" +msgstr "3. 用模块创建 ``ClientApp``" + +#: ../../source/how-to-use-built-in-mods.rst:59 +#, fuzzy +msgid "" +"Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " +"argument. The order in which you provide the mods matters:" +msgstr "创建您的 ``ClientApp`` 并将 mods 作为列表传递给 ``mods`` 参数。提供 mod 的顺序很重要:" + +#: ../../source/how-to-use-built-in-mods.rst:72 #, fuzzy msgid "Order of execution" msgstr "停用" @@ -7061,22 +7036,20 @@ msgstr "``example_mod_1`` (返回途中最外层的模式)" #: ../../source/how-to-use-built-in-mods.rst:82 #, fuzzy msgid "" -"Each mod has a chance to inspect and modify the incoming ``Message`` before " -"passing it to the next mod, and likewise with the outgoing ``Message`` " -"before returning it up the stack." -msgstr "" -"每个模块都有机会检查和修改传入的 \"信息\",然后再将其传递给下一个模块,同样," -"也有机会检查和修改传出的 \"信息\",然后再将其返回堆栈。" +"Each mod has a chance to inspect and modify the incoming ``Message`` " +"before passing it to the next mod, and likewise with the outgoing " +"``Message`` before returning it up the stack." +msgstr "每个模块都有机会检查和修改传入的 \"信息\",然后再将其传递给下一个模块,同样,也有机会检查和修改传出的 \"信息\",然后再将其返回堆栈。" #: ../../source/how-to-use-built-in-mods.rst:87 #, fuzzy msgid "" "By following this guide, you have learned how to effectively use mods to " -"enhance your ``ClientApp``'s functionality. Remember that the order of mods " -"is crucial and affects how the input and output are processed." +"enhance your ``ClientApp``'s functionality. Remember that the order of " +"mods is crucial and affects how the input and output are processed." msgstr "" -"通过本指南,您已学会如何有效地使用 mod 来增强您的 ``ClientApp`` 的功能。请记" -"住,mod 的顺序至关重要,它会影响输入和输出的处理方式。" +"通过本指南,您已学会如何有效地使用 mod 来增强您的 ``ClientApp`` 的功能。请记住,mod " +"的顺序至关重要,它会影响输入和输出的处理方式。" #: ../../source/how-to-use-built-in-mods.rst:89 #, fuzzy @@ -7091,34 +7064,32 @@ msgstr "差分隐私" #: ../../source/how-to-use-differential-privacy.rst:3 #, fuzzy msgid "" -"This guide explains how you can utilize differential privacy in the Flower " -"framework. If you are not yet familiar with differential privacy, you can " -"refer to :doc:`explanation-differential-privacy`." +"This guide explains how you can utilize differential privacy in the " +"Flower framework. If you are not yet familiar with differential privacy, " +"you can refer to :doc:`explanation-differential-privacy`." msgstr "" -"本指南解释了如何在 Flower 框架中使用差分隐私。如果您还不熟悉差分隐私,可以参" -"考 :doc:`explanation-differential-privacy` 。" +"本指南解释了如何在 Flower 框架中使用差分隐私。如果您还不熟悉差分隐私,可以参考 :doc:`explanation-" +"differential-privacy` 。" #: ../../source/how-to-use-differential-privacy.rst:7 #, fuzzy msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " -"these features in a production environment with sensitive data, feel free " -"contact us to discuss your requirements and to receive guidance on how to " -"best use these features." +"these features in a production environment with sensitive data, feel free" +" contact us to discuss your requirements and to receive guidance on how " +"to best use these features." msgstr "" -"Flower 中的差异隐私处于预览阶段。如果您计划在生产环境中使用这些敏感数据功能," -"请随时联系我们,讨论您的需求,并获得如何最好地使用这些功能的指导。" +"Flower " +"中的差异隐私处于预览阶段。如果您计划在生产环境中使用这些敏感数据功能,请随时联系我们,讨论您的需求,并获得如何最好地使用这些功能的指导。" #: ../../source/how-to-use-differential-privacy.rst:12 #, fuzzy msgid "" -"This approach consists of two seprate phases: clipping of the updates and " -"adding noise to the aggregated model. For the clipping phase, Flower " -"framework has made it possible to decide whether to perform clipping on the " -"server side or the client side." -msgstr "" -"这种方法包括两个独立的阶段:对更新进行剪切和在聚合模型中添加噪声。在剪切阶" -"段,Flower 框架可以决定是在服务器端还是在客户端执行剪切。" +"This approach consists of two seprate phases: clipping of the updates and" +" adding noise to the aggregated model. For the clipping phase, Flower " +"framework has made it possible to decide whether to perform clipping on " +"the server side or the client side." +msgstr "这种方法包括两个独立的阶段:对更新进行剪切和在聚合模型中添加噪声。在剪切阶段,Flower 框架可以决定是在服务器端还是在客户端执行剪切。" #: ../../source/how-to-use-differential-privacy.rst:15 #, fuzzy @@ -7126,23 +7097,20 @@ msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " "communication overhead for clipping values. However, it also has the " -"disadvantage of increasing the computational load on the server due to the " -"need to perform the clipping operation for all clients." +"disadvantage of increasing the computational load on the server due to " +"the need to perform the clipping operation for all clients." msgstr "" -"** 服务器端剪切**: 这种方法的优点是服务器可对所有客户端的更新执行统一的剪" -"切,并减少剪切值的通信开销。不过,这种方法也有缺点,那就是需要为所有客户端执" -"行剪切操作,从而增加了服务器的计算负荷。" +"** 服务器端剪切**: " +"这种方法的优点是服务器可对所有客户端的更新执行统一的剪切,并减少剪切值的通信开销。不过,这种方法也有缺点,那就是需要为所有客户端执行剪切操作,从而增加了服务器的计算负荷。" #: ../../source/how-to-use-differential-privacy.rst:16 #, fuzzy msgid "" -"**Client-side Clipping**: This approach has the advantage of reducing the " -"computational overhead on the server. However, it also has the disadvantage " -"of lacking centralized control, as the server has less control over the " -"clipping process." -msgstr "" -"**客户端剪切**: 这种方法的优点是可以减少服务器的计算开销。不过,它也有缺乏集" -"中控制的缺点,因为服务器对剪切过程的控制较少。" +"**Client-side Clipping**: This approach has the advantage of reducing the" +" computational overhead on the server. However, it also has the " +"disadvantage of lacking centralized control, as the server has less " +"control over the clipping process." +msgstr "**客户端剪切**: 这种方法的优点是可以减少服务器的计算开销。不过,它也有缺乏集中控制的缺点,因为服务器对剪切过程的控制较少。" #: ../../source/how-to-use-differential-privacy.rst:21 #, fuzzy @@ -7154,15 +7122,15 @@ msgstr "服务器端逻辑" msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " -"(for example, :code:`FedAvg`). The two wrapper classes are :code:" -"`DifferentialPrivacyServerSideFixedClipping` and :code:" -"`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and adaptive " -"clipping." +"(for example, :code:`FedAvg`). The two wrapper classes are " +":code:`DifferentialPrivacyServerSideFixedClipping` and " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " +"adaptive clipping." msgstr "" -"对于具有服务器端剪裁功能的中央 DP,有两个 :code:`Strategy` 类作为实际 :code:" -"`Strategy` 实例(例如 :code:`FedAvg`)的包装器。这两个封装类分别是 :code:" -"`DifferentialPrivacyServerSideFixedClipping` 和 :code:" -"`DifferentialPrivacyServerSideAdaptiveClipping` ,用于固定剪辑和自适应剪辑。" +"对于具有服务器端剪裁功能的中央 DP,有两个 :code:`Strategy` 类作为实际 :code:`Strategy` 实例(例如 " +":code:`FedAvg`)的包装器。这两个封装类分别是 " +":code:`DifferentialPrivacyServerSideFixedClipping` 和 " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` ,用于固定剪辑和自适应剪辑。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -7172,15 +7140,16 @@ msgstr "服务器端逻辑" #: ../../source/how-to-use-differential-privacy.rst:31 #, fuzzy msgid "" -"The code sample below enables the :code:`FedAvg` strategy to use server-side " -"fixed clipping using the :code:`DifferentialPrivacyServerSideFixedClipping` " -"wrapper class. The same approach can be used with :code:" -"`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " +"The code sample below enables the :code:`FedAvg` strategy to use server-" +"side fixed clipping using the " +":code:`DifferentialPrivacyServerSideFixedClipping` wrapper class. The " +"same approach can be used with " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" -"下面的代码示例使用 :code:`DifferentialPrivacyServerSideFixedClipping` 封装类" -"使 :code:`FedAvg` 策略使用服务器端固定剪辑。通过调整相应的输入参数,同样的方" -"法也可用于 :code:`DifferentialPrivacyServerSideAdaptiveClipping`。" +"下面的代码示例使用 :code:`DifferentialPrivacyServerSideFixedClipping` 封装类使 " +":code:`FedAvg` 策略使用服务器端固定剪辑。通过调整相应的输入参数,同样的方法也可用于 " +":code:`DifferentialPrivacyServerSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:52 #, fuzzy @@ -7191,18 +7160,18 @@ msgstr "客户端逻辑" #, fuzzy msgid "" "For central DP with client-side clipping, the server sends the clipping " -"value to selected clients on each round. Clients can use existing Flower :" -"code:`Mods` to perform the clipping. Two mods are available for fixed and " -"adaptive client-side clipping: :code:`fixedclipping_mod` and :code:" -"`adaptiveclipping_mod` with corresponding server-side wrappers :code:" -"`DifferentialPrivacyClientSideFixedClipping` and :code:" -"`DifferentialPrivacyClientSideAdaptiveClipping`." -msgstr "" -"对于带有客户端剪裁功能的中央 DP,服务器会在每一轮向选定的客户端发送剪裁值。客" -"户端可以使用现有的 Flower :code:`Mods`来执行剪裁。有两种模式可用于固定和自适" -"应客户端剪辑::code:`fixedclipping_mod` 和 :code:`adaptiveclipping_mod`,以及" -"相应的服务器端封装 :code:`DifferentialPrivacyClientSideFixedClipping` 和 :" -"code:`DifferentialPrivacyClientSideAdaptiveClipping`。" +"value to selected clients on each round. Clients can use existing Flower " +":code:`Mods` to perform the clipping. Two mods are available for fixed " +"and adaptive client-side clipping: :code:`fixedclipping_mod` and " +":code:`adaptiveclipping_mod` with corresponding server-side wrappers " +":code:`DifferentialPrivacyClientSideFixedClipping` and " +":code:`DifferentialPrivacyClientSideAdaptiveClipping`." +msgstr "" +"对于带有客户端剪裁功能的中央 DP,服务器会在每一轮向选定的客户端发送剪裁值。客户端可以使用现有的 Flower " +":code:`Mods`来执行剪裁。有两种模式可用于固定和自适应客户端剪辑::code:`fixedclipping_mod` 和 " +":code:`adaptiveclipping_mod`,以及相应的服务器端封装 " +":code:`DifferentialPrivacyClientSideFixedClipping` 和 " +":code:`DifferentialPrivacyClientSideAdaptiveClipping`。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -7213,35 +7182,33 @@ msgstr "客户端逻辑" #, fuzzy msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " -"differential privacy with client-side fixed clipping using both the :code:" -"`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on the " -"client, :code:`fixedclipping_mod`:" +"differential privacy with client-side fixed clipping using both the " +":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " +"the client, :code:`fixedclipping_mod`:" msgstr "" -"下面的代码示例使用 :code:`DifferentialPrivacyClientSideFixedClipping` 封装类" -"和客户端的 :code:`fixedclipping_mod` 使 :code:`FedAvg` 策略在客户端固定剪辑的" -"情况下使用差分隐私:" +"下面的代码示例使用 :code:`DifferentialPrivacyClientSideFixedClipping` 封装类和客户端的 " +":code:`fixedclipping_mod` 使 :code:`FedAvg` 策略在客户端固定剪辑的情况下使用差分隐私:" #: ../../source/how-to-use-differential-privacy.rst:80 #, fuzzy msgid "" -"In addition to the server-side strategy wrapper, the :code:`ClientApp` needs " -"to configure the matching :code:`fixedclipping_mod` to perform the client-" -"side clipping:" +"In addition to the server-side strategy wrapper, the :code:`ClientApp` " +"needs to configure the matching :code:`fixedclipping_mod` to perform the " +"client-side clipping:" msgstr "" -"除了服务器端策略包装器外,:code:`ClientApp` 还需要配置匹配的 :code:" -"`fixedclipping_mod` 以执行客户端剪切:" +"除了服务器端策略包装器外,:code:`ClientApp` 还需要配置匹配的 :code:`fixedclipping_mod` " +"以执行客户端剪切:" #: ../../source/how-to-use-differential-privacy.rst:97 #, fuzzy msgid "" -"To utilize local differential privacy (DP) and add noise to the client model " -"parameters before transmitting them to the server in Flower, you can use the " -"`LocalDpMod`. The following hyperparameters need to be set: clipping norm " -"value, sensitivity, epsilon, and delta." +"To utilize local differential privacy (DP) and add noise to the client " +"model parameters before transmitting them to the server in Flower, you " +"can use the `LocalDpMod`. The following hyperparameters need to be set: " +"clipping norm value, sensitivity, epsilon, and delta." msgstr "" -"要利用本地差分隐私(DP)并在将客户端模型参数传输到 Flower 服务器之前为其添加" -"噪声,可以使用 `LocalDpMod`。需要设置以下超参数:剪切规范值、灵敏度、ε 和 " -"delta。" +"要利用本地差分隐私(DP)并在将客户端模型参数传输到 Flower 服务器之前为其添加噪声,可以使用 " +"`LocalDpMod`。需要设置以下超参数:剪切规范值、灵敏度、ε 和 delta。" #: ../../source/how-to-use-differential-privacy.rst:-1 #, fuzzy @@ -7256,12 +7223,11 @@ msgstr "下面的代码示例展示了如何使用 :code:`LocalDpMod`:" #: ../../source/how-to-use-differential-privacy.rst:122 #, fuzzy msgid "" -"Please note that the order of mods, especially those that modify parameters, " -"is important when using multiple modifiers. Typically, differential privacy " -"(DP) modifiers should be the last to operate on parameters." -msgstr "" -"请注意,在使用多个修改器时,修改器(尤其是修改参数的修改器)的顺序非常重要。" -"通常情况下,差分隐私 (DP) 修改器应最后对参数进行操作。" +"Please note that the order of mods, especially those that modify " +"parameters, is important when using multiple modifiers. Typically, " +"differential privacy (DP) modifiers should be the last to operate on " +"parameters." +msgstr "请注意,在使用多个修改器时,修改器(尤其是修改参数的修改器)的顺序非常重要。通常情况下,差分隐私 (DP) 修改器应最后对参数进行操作。" #: ../../source/how-to-use-differential-privacy.rst:125 #, fuzzy @@ -7271,18 +7237,19 @@ msgstr "使用隐私引擎进行本地培训" #: ../../source/how-to-use-differential-privacy.rst:126 #, fuzzy msgid "" -"For ensuring data instance-level privacy during local model training on the " -"client side, consider leveraging privacy engines such as Opacus and " -"TensorFlow Privacy. For examples of using Flower with these engines, please " -"refer to the Flower examples directory (`Opacus `_, `Tensorflow Privacy `_)." +"For ensuring data instance-level privacy during local model training on " +"the client side, consider leveraging privacy engines such as Opacus and " +"TensorFlow Privacy. For examples of using Flower with these engines, " +"please refer to the Flower examples directory (`Opacus " +"`_, `Tensorflow" +" Privacy `_)." msgstr "" -"要在客户端本地模型训练期间确保数据实例级隐私,可考虑利用 Opacus 和 " -"TensorFlow Privacy 等隐私引擎。有关将 Flower 与这些引擎结合使用的示例,请参" -"阅 Flower 示例目录(`Opacus `_, `Tensorflow Privacy `_)。" +"要在客户端本地模型训练期间确保数据实例级隐私,可考虑利用 Opacus 和 TensorFlow Privacy 等隐私引擎。有关将 Flower" +" 与这些引擎结合使用的示例,请参阅 Flower 示例目录(`Opacus " +"`_, `Tensorflow" +" Privacy `_)。" #: ../../source/how-to-use-strategies.rst:2 msgid "Use strategies" @@ -7290,17 +7257,15 @@ msgstr "使用策略" #: ../../source/how-to-use-strategies.rst:4 msgid "" -"Flower allows full customization of the learning process through the :code:" -"`Strategy` abstraction. A number of built-in strategies are provided in the " -"core framework." -msgstr "" -"Flower 允许通过 :code:`Strategy` 抽象类对学习过程进行完全定制。核心框架中提供" -"了许多内置策略。" +"Flower allows full customization of the learning process through the " +":code:`Strategy` abstraction. A number of built-in strategies are " +"provided in the core framework." +msgstr "Flower 允许通过 :code:`Strategy` 抽象类对学习过程进行完全定制。核心框架中提供了许多内置策略。" #: ../../source/how-to-use-strategies.rst:6 msgid "" -"There are three ways to customize the way Flower orchestrates the learning " -"process on the server side:" +"There are three ways to customize the way Flower orchestrates the " +"learning process on the server side:" msgstr "有三种方法可以自定义 Flower 在服务器端协调学习过程的方式:" #: ../../source/how-to-use-strategies.rst:8 @@ -7323,27 +7288,23 @@ msgstr "使用现有策略" #: ../../source/how-to-use-strategies.rst:16 msgid "" -"Flower comes with a number of popular federated learning strategies built-" -"in. A built-in strategy can be instantiated as follows:" +"Flower comes with a number of popular federated learning strategies " +"built-in. A built-in strategy can be instantiated as follows:" msgstr "Flower 内置了许多流行的联邦学习策略。内置策略的实例化方法如下:" #: ../../source/how-to-use-strategies.rst:25 msgid "" -"This creates a strategy with all parameters left at their default values and " -"passes it to the :code:`start_server` function. It is usually recommended to " -"adjust a few parameters during instantiation:" -msgstr "" -"这会创建一个所有参数都保持默认值的策略,并将其传递给 :code:`start_server` 函" -"数。通常建议在实例化过程中调整一些参数:" +"This creates a strategy with all parameters left at their default values " +"and passes it to the :code:`start_server` function. It is usually " +"recommended to adjust a few parameters during instantiation:" +msgstr "这会创建一个所有参数都保持默认值的策略,并将其传递给 :code:`start_server` 函数。通常建议在实例化过程中调整一些参数:" #: ../../source/how-to-use-strategies.rst:42 msgid "" "Existing strategies provide several ways to customize their behaviour. " "Callback functions allow strategies to call user-provided code during " "execution." -msgstr "" -"现有的策略提供了多种自定义行为的方法。回调函数允许策略在执行过程中调用用户提" -"供的代码。" +msgstr "现有的策略提供了多种自定义行为的方法。回调函数允许策略在执行过程中调用用户提供的代码。" #: ../../source/how-to-use-strategies.rst:45 msgid "Configuring client fit and client evaluate" @@ -7352,37 +7313,36 @@ msgstr "配置客户匹配和客户评估" #: ../../source/how-to-use-strategies.rst:47 msgid "" "The server can pass new configuration values to the client each round by " -"providing a function to :code:`on_fit_config_fn`. The provided function will " -"be called by the strategy and must return a dictionary of configuration key " -"values pairs that will be sent to the client. It must return a dictionary of " -"arbitrary configuration values :code:`client.fit` and :code:`client." -"evaluate` functions during each round of federated learning." +"providing a function to :code:`on_fit_config_fn`. The provided function " +"will be called by the strategy and must return a dictionary of " +"configuration key values pairs that will be sent to the client. It must " +"return a dictionary of arbitrary configuration values :code:`client.fit`" +" and :code:`client.evaluate` functions during each round of federated " +"learning." msgstr "" -"服务器可以通过向 :code:`on_fit_config_fn` 提供一个函数,在每一轮向客户端传递" -"新的配置值。提供的函数将被策略调用,并且必须返回一个配置键值对的字典,该字典" -"将被发送到客户端。在每一轮联邦学习期间,它必须返回一个任意配置值 dictionary :" -"code:`client.fit`和 :code:`client.evaluate`函数。" +"服务器可以通过向 :code:`on_fit_config_fn` " +"提供一个函数,在每一轮向客户端传递新的配置值。提供的函数将被策略调用,并且必须返回一个配置键值对的字典,该字典将被发送到客户端。在每一轮联邦学习期间,它必须返回一个任意配置值" +" dictionary :code:`client.fit`和 :code:`client.evaluate`函数。" #: ../../source/how-to-use-strategies.rst:75 msgid "" "The :code:`on_fit_config_fn` can be used to pass arbitrary configuration " "values from server to client, and poetentially change these values each " -"round, for example, to adjust the learning rate. The client will receive the " -"dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client." -"fit()` function." +"round, for example, to adjust the learning rate. The client will receive " +"the dictionary returned by the :code:`on_fit_config_fn` in its own " +":code:`client.fit()` function." msgstr "" -":code:`on_fit_config_fn`可用于将任意配置值从服务器传递到客户端,并在每一轮改" -"变这些值,例如,调整学习率。客户端将在自己的 :code:`client.fit()` 函数中接" -"收 :code:`on_fit_config_fn` 返回的字典。" +":code:`on_fit_config_fn`可用于将任意配置值从服务器传递到客户端,并在每一轮改变这些值,例如,调整学习率。客户端将在自己的 " +":code:`client.fit()` 函数中接收 :code:`on_fit_config_fn` 返回的字典。" #: ../../source/how-to-use-strategies.rst:78 msgid "" -"Similar to :code:`on_fit_config_fn`, there is also :code:" -"`on_evaluate_config_fn` to customize the configuration sent to :code:`client." -"evaluate()`" +"Similar to :code:`on_fit_config_fn`, there is also " +":code:`on_evaluate_config_fn` to customize the configuration sent to " +":code:`client.evaluate()`" msgstr "" -"与 :code:`on_fit_config_fn` 类似,还有 :code:`on_evaluate_config_fn` 用于定制" -"发送到 :code:`client.evaluate()` 的配置" +"与 :code:`on_fit_config_fn` 类似,还有 :code:`on_evaluate_config_fn` 用于定制发送到 " +":code:`client.evaluate()` 的配置" #: ../../source/how-to-use-strategies.rst:81 msgid "Configuring server-side evaluation" @@ -7390,18 +7350,18 @@ msgstr "配置服务器端评估" #: ../../source/how-to-use-strategies.rst:83 msgid "" -"Server-side evaluation can be enabled by passing an evaluation function to :" -"code:`evaluate_fn`." +"Server-side evaluation can be enabled by passing an evaluation function " +"to :code:`evaluate_fn`." msgstr "服务器端评估可通过向 :code:`evaluate_fn` 传递评估函数来启用。" #: ../../source/how-to-use-strategies.rst:89 msgid "" -"Writing a fully custom strategy is a bit more involved, but it provides the " -"most flexibility. Read the `Implementing Strategies `_ guide to learn more." +"Writing a fully custom strategy is a bit more involved, but it provides " +"the most flexibility. Read the `Implementing Strategies `_ guide to learn more." msgstr "" -"编写完全自定义的策略涉及的内容较多,但灵活性最高。阅读 `实施策略 _ 指南,了解更多信息。" +"编写完全自定义的策略涉及的内容较多,但灵活性最高。阅读 `实施策略 _ " +"指南,了解更多信息。" #: ../../source/index.rst:34 msgid "Tutorial" @@ -7411,15 +7371,15 @@ msgstr "教程" msgid "Quickstart tutorials" msgstr "快速入门教程" -#: ../../source/index.rst:75 ../../source/index.rst:79 +#: ../../source/index.rst:74 ../../source/index.rst:78 msgid "How-to guides" msgstr "操作指南" -#: ../../source/index.rst:98 +#: ../../source/index.rst:99 msgid "Legacy example guides" msgstr "旧版指南范例" -#: ../../source/index.rst:109 ../../source/index.rst:113 +#: ../../source/index.rst:108 ../../source/index.rst:112 msgid "Explanations" msgstr "说明" @@ -7427,23 +7387,23 @@ msgstr "说明" msgid "API reference" msgstr "应用程序接口参考" -#: ../../source/index.rst:138 +#: ../../source/index.rst:137 msgid "Reference docs" msgstr "参考文档" -#: ../../source/index.rst:154 +#: ../../source/index.rst:153 msgid "Contributor tutorials" msgstr "贡献者教程" -#: ../../source/index.rst:161 +#: ../../source/index.rst:160 msgid "Contributor how-to guides" msgstr "投稿指南" -#: ../../source/index.rst:174 +#: ../../source/index.rst:173 msgid "Contributor explanations" msgstr "贡献者解释" -#: ../../source/index.rst:180 +#: ../../source/index.rst:179 msgid "Contributor references" msgstr "贡献者参考资料" @@ -7461,9 +7421,7 @@ msgstr "Flower 框架文档" msgid "" "Welcome to Flower's documentation. `Flower `_ is a " "friendly federated learning framework." -msgstr "" -"欢迎访问 Flower 文档。`Flower `_ 是一个友好的联邦学习框" -"架。" +msgstr "欢迎访问 Flower 文档。`Flower `_ 是一个友好的联邦学习框架。" #: ../../source/index.rst:11 msgid "Join the Flower Community" @@ -7474,9 +7432,7 @@ msgid "" "The Flower Community is growing quickly - we're a friendly group of " "researchers, engineers, students, professionals, academics, and other " "enthusiasts." -msgstr "" -"Flower 社区发展迅速--我们是一个由研究人员、工程师、学生、专业人士、学者和其他" -"爱好者组成的友好团体。" +msgstr "Flower 社区发展迅速--我们是一个由研究人员、工程师、学生、专业人士、学者和其他爱好者组成的友好团体。" #: ../../source/index.rst:15 msgid "Join us on Slack" @@ -7490,12 +7446,11 @@ msgstr "Flower 框架" msgid "" "The user guide is targeted at researchers and developers who want to use " "Flower to bring existing machine learning workloads into a federated " -"setting. One of Flower's design goals was to make this simple. Read on to " -"learn more." +"setting. One of Flower's design goals was to make this simple. Read on to" +" learn more." msgstr "" -"该用户指南面向希望使用 Flower 将现有机器学习工作负载引入联邦环境的研究人员和" -"开发人员。Flower 的设计目标之一就是让这一切变得简单。请继续阅读,了解更多信" -"息。" +"该用户指南面向希望使用 Flower 将现有机器学习工作负载引入联邦环境的研究人员和开发人员。Flower " +"的设计目标之一就是让这一切变得简单。请继续阅读,了解更多信息。" #: ../../source/index.rst:30 msgid "Tutorials" @@ -7503,80 +7458,79 @@ msgstr "教程" #: ../../source/index.rst:32 msgid "" -"A learning-oriented series of federated learning tutorials, the best place " -"to start." +"A learning-oriented series of federated learning tutorials, the best " +"place to start." msgstr "以学习为导向的联邦学习教程系列,最好的起点。" -#: ../../source/index.rst:62 -msgid "" -"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" -"`TensorFlow ` | :doc:`🤗 Transformers " -"` | :doc:`JAX ` | :" -"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc:`scikit-learn " -"` | :doc:`XGBoost ` | :doc:`Android ` | :doc:`iOS " -"`" -msgstr "" -"快速入门教程: :doc:`PyTorch ` | :doc:" -"`TensorFlow ` | :doc:`🤗 Transformers " -"` | :doc:`JAX ` | :" -"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc:`scikit-learn " -"` | :doc:`XGBoost ` | :doc:`Android ` | :doc:`iOS " -"`" - -#: ../../source/index.rst:64 +#: ../../source/index.rst:61 +#, fuzzy +msgid "" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | " +":doc:`TensorFlow ` | :doc:`🤗 Transformers" +" ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " +"` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " +":doc:`Android ` | :doc:`iOS `" +msgstr "" +"快速入门教程: :doc:`PyTorch ` | :doc:`TensorFlow " +"` | :doc:`🤗 Transformers ` | :doc:`JAX ` | " +":doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`MXNet ` | :doc" +":`scikit-learn ` | :doc:`XGBoost " +"` | :doc:`Android ` | :doc:`iOS `" + +#: ../../source/index.rst:63 msgid "We also made video tutorials for PyTorch:" msgstr "我们还为 PyTorch 制作了视频教程:" -#: ../../source/index.rst:69 +#: ../../source/index.rst:68 msgid "And TensorFlow:" msgstr "还有 TensorFlow:" -#: ../../source/index.rst:77 +#: ../../source/index.rst:76 msgid "" -"Problem-oriented how-to guides show step-by-step how to achieve a specific " -"goal." +"Problem-oriented how-to guides show step-by-step how to achieve a " +"specific goal." msgstr "以问题为导向的 \"如何做 \"指南逐步展示如何实现特定目标。" -#: ../../source/index.rst:111 +#: ../../source/index.rst:110 msgid "" "Understanding-oriented concept guides explain and discuss key topics and " "underlying ideas behind Flower and collaborative AI." -msgstr "" -"以理解为导向的概念指南解释并讨论了Flower和协作式人工智能背后的关键主题和基本" -"思想。" +msgstr "以理解为导向的概念指南解释并讨论了Flower和协作式人工智能背后的关键主题和基本思想。" -#: ../../source/index.rst:121 +#: ../../source/index.rst:120 msgid "References" msgstr "参考资料" -#: ../../source/index.rst:123 +#: ../../source/index.rst:122 msgid "Information-oriented API reference and other reference material." msgstr "以信息为导向的 API 参考资料和其他参考资料。" -#: ../../source/index.rst:132::1 +#: ../../source/index.rst:131::1 #, fuzzy msgid ":py:obj:`flwr `\\" msgstr ":py:obj:`flwr `\\" -#: ../../source/index.rst:132::1 flwr:1 of +#: ../../source/index.rst:131::1 flwr:1 of #, fuzzy msgid "Flower main package." msgstr "Flower 主包装。" -#: ../../source/index.rst:149 +#: ../../source/index.rst:148 msgid "Contributor docs" msgstr "贡献者文档" -#: ../../source/index.rst:151 +#: ../../source/index.rst:150 msgid "" -"The Flower community welcomes contributions. The following docs are intended " -"to help along the way." +"The Flower community welcomes contributions. The following docs are " +"intended to help along the way." msgstr "Flower 社区欢迎您的贡献。以下文档旨在为您提供帮助。" #: ../../source/ref-api-cli.rst:2 @@ -7584,23 +7538,20 @@ msgid "Flower CLI reference" msgstr "Flower CLI 参考" #: ../../source/ref-api-cli.rst:7 -msgid "flower-superlink" -msgstr "flower-superlink" +#, fuzzy +msgid "flower-simulation" +msgstr "运行模拟" #: ../../source/ref-api-cli.rst:17 -msgid "flower-driver-api" -msgstr "flower-driver-api" +msgid "flower-superlink" +msgstr "flower-superlink" #: ../../source/ref-api-cli.rst:27 -msgid "flower-fleet-api" -msgstr "flower-fleet-api" - -#: ../../source/ref-api-cli.rst:37 #, fuzzy msgid "flower-client-app" msgstr "Flower 客户端。" -#: ../../source/ref-api-cli.rst:47 +#: ../../source/ref-api-cli.rst:37 #, fuzzy msgid "flower-server-app" msgstr "flower-driver-api" @@ -7610,7 +7561,7 @@ msgstr "flower-driver-api" msgid "flwr" msgstr "Flower" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:52 +#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 #, fuzzy msgid "Modules" msgstr "模块" @@ -7639,7 +7590,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr ":py:obj:`flwr.server `\\" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:41::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." msgstr "Flower 服务器。" @@ -7666,18 +7617,29 @@ msgstr "客户端" msgid "Functions" msgstr "四种函数:" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #, fuzzy msgid ":py:obj:`run_client_app `\\ \\(\\)" msgstr ":py:obj:`run_client_app `\\ \\(\\)" -#: ../../source/ref-api/flwr.client.rst:24::1 -#: flwr.client.app.run_client_app:1 of +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_client_app:1 of #, fuzzy msgid "Run Flower client app." msgstr "Flower 客户端。" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 +#, fuzzy +msgid ":py:obj:`run_supernode `\\ \\(\\)" +msgstr ":py:obj:`run_superlink `\\ \\(\\)" + +#: ../../source/ref-api/flwr.client.rst:25::1 +#: flwr.client.supernode.app.run_supernode:1 of +#, fuzzy +msgid "Run Flower SuperNode." +msgstr "Flower 服务器。" + +#: ../../source/ref-api/flwr.client.rst:25::1 #, fuzzy msgid "" ":py:obj:`start_client `\\ \\(\\*\\, " @@ -7686,70 +7648,73 @@ msgstr "" ":py:obj:`start_client `\\ \\(\\*\\, " "server\\_address\\[\\, client\\_fn\\, ...\\]\\)" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_client:1 of msgid "Start a Flower client node which connects to a Flower server." msgstr "启动一个 Flower 客户节点,连接到 Flower 服务器。" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #, fuzzy msgid "" -":py:obj:`start_numpy_client `\\ \\(\\*\\, " -"server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\," +" server\\_address\\, client\\)" msgstr "" -":py:obj:`start_numpy_client `\\ \\(\\*\\, " -"server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\," +" server\\_address\\, client\\)" -#: ../../source/ref-api/flwr.client.rst:24::1 +#: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_numpy_client:1 of msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "启动 Flower NumPyClient,连接到 gRPC 服务器。" -#: ../../source/ref-api/flwr.client.rst:26 +#: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:29 +#: ../../source/ref-api/flwr.server.rst:28 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 #, fuzzy msgid "Classes" msgstr "类别" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #, fuzzy msgid ":py:obj:`Client `\\ \\(\\)" msgstr ":py:obj:`Client `\\ \\(\\)" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client.Client:1 of msgid "Abstract base class for Flower clients." msgstr "Flower 客户端的抽象基类。" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #, fuzzy msgid "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " +"mods\\]\\)" msgstr "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " +"mods\\]\\)" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client_app.ClientApp:1 of #, fuzzy msgid "Flower ClientApp." msgstr "Flower 客户端。" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #, fuzzy msgid ":py:obj:`NumPyClient `\\ \\(\\)" msgstr ":py:obj:`NumPyClient `\\ \\(\\)" -#: ../../source/ref-api/flwr.client.rst:33::1 +#: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.numpy_client.NumPyClient:1 of msgid "Abstract base class for Flower clients using NumPy." msgstr "使用 NumPy 的 Flower 客户端的抽象基类。" #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 -#: flwr.server.strategy.strategy.Strategy:1 of +#: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 +#: of #, fuzzy msgid "Bases: :py:class:`~abc.ABC`" msgstr "Bases: :py:class:`~abc.ABC`" @@ -7765,6 +7730,7 @@ msgstr "Bases: :py:class:`~abc.ABC`" #: ../../source/ref-api/flwr.common.Error.rst:15 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:15 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:15 +#: ../../source/ref-api/flwr.common.EventType.rst:15 #: ../../source/ref-api/flwr.common.FitIns.rst:15 #: ../../source/ref-api/flwr.common.FitRes.rst:15 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:15 @@ -7858,10 +7824,8 @@ msgstr "评估客户端的反应。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #, fuzzy -msgid "" -":py:obj:`get_parameters `\\ \\(ins\\)" -msgstr "" -":py:obj:`get_parameters `\\ \\(ins\\)" +msgid ":py:obj:`get_parameters `\\ \\(ins\\)" +msgstr ":py:obj:`get_parameters `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7872,10 +7836,8 @@ msgstr "返回当前本地模型参数。" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #, fuzzy -msgid "" -":py:obj:`get_properties `\\ \\(ins\\)" -msgstr "" -":py:obj:`get_properties `\\ \\(ins\\)" +msgid ":py:obj:`get_properties `\\ \\(ins\\)" +msgstr ":py:obj:`get_properties `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.get_properties:1 of @@ -7915,7 +7877,7 @@ msgstr "返回客户端(本身)。" #: ../../source/ref-api/flwr.common.Error.rst:25 #: ../../source/ref-api/flwr.common.EvaluateIns.rst:25 #: ../../source/ref-api/flwr.common.EvaluateRes.rst:25 -#: ../../source/ref-api/flwr.common.EventType.rst:19 +#: ../../source/ref-api/flwr.common.EventType.rst:165 #: ../../source/ref-api/flwr.common.FitIns.rst:25 #: ../../source/ref-api/flwr.common.FitRes.rst:25 #: ../../source/ref-api/flwr.common.GetParametersIns.rst:25 @@ -7960,7 +7922,6 @@ msgstr ":py:obj:`context `\\" #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.unregister #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver flwr.server.driver.driver.Driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -7994,12 +7955,10 @@ msgstr "参数" #: flwr.client.client.Client.evaluate:3 of msgid "" -"The evaluation instructions containing (global) model parameters received " -"from the server and a dictionary of configuration values used to customize " -"the local evaluation process." -msgstr "" -"评估指令包含从服务器接收的(全局)模型参数,以及用于定制本地评估流程的配置值" -"字典。" +"The evaluation instructions containing (global) model parameters received" +" from the server and a dictionary of configuration values used to " +"customize the local evaluation process." +msgstr "评估指令包含从服务器接收的(全局)模型参数,以及用于定制本地评估流程的配置值字典。" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -8014,7 +7973,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -8035,8 +7993,7 @@ msgstr "返回" msgid "" "The evaluation result containing the loss on the local dataset and other " "details such as the number of local data examples used for evaluation." -msgstr "" -"评估结果包含本地数据集上的损失值和其他详细信息,如用于评估的本地数据的数量。" +msgstr "评估结果包含本地数据集上的损失值和其他详细信息,如用于评估的本地数据的数量。" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -8049,7 +8006,6 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.num_available #: flwr.server.client_manager.SimpleClientManager.register #: flwr.server.client_manager.SimpleClientManager.wait_for -#: flwr.server.compat.app.start_driver #: flwr.server.driver.driver.Driver.create_message #: flwr.server.driver.driver.Driver.pull_messages #: flwr.server.driver.driver.Driver.push_messages @@ -8068,17 +8024,15 @@ msgstr "返回类型" #: flwr.client.client.Client.fit:3 of msgid "" -"The training instructions containing (global) model parameters received from " -"the server and a dictionary of configuration values used to customize the " -"local training process." -msgstr "" -"训练指令,包含从服务器接收的(全局)模型参数,以及用于定制本地训练过程的配置" -"值字典。" +"The training instructions containing (global) model parameters received " +"from the server and a dictionary of configuration values used to " +"customize the local training process." +msgstr "训练指令,包含从服务器接收的(全局)模型参数,以及用于定制本地训练过程的配置值字典。" #: flwr.client.client.Client.fit:8 of msgid "" -"The training result containing updated parameters and other details such as " -"the number of local training examples used for training." +"The training result containing updated parameters and other details such " +"as the number of local training examples used for training." msgstr "训练结果包含更新的参数和其他详细信息,如用于训练的本地训练示例的数量。" #: flwr.client.client.Client.get_parameters:3 of @@ -8117,9 +8071,9 @@ msgstr "客户端" #: flwr.common.typing.GetParametersRes:1 flwr.common.typing.GetPropertiesIns:1 #: flwr.common.typing.GetPropertiesRes:1 flwr.common.typing.Parameters:1 #: flwr.common.typing.ReconnectIns:1 flwr.common.typing.ServerMessage:1 -#: flwr.common.typing.Status:1 flwr.server.driver.driver.Driver:1 -#: flwr.server.history.History:1 flwr.server.server.Server:1 -#: flwr.server.server_app.ServerApp:1 flwr.server.server_config.ServerConfig:1 +#: flwr.common.typing.Status:1 flwr.server.history.History:1 +#: flwr.server.server.Server:1 flwr.server.server_app.ServerApp:1 +#: flwr.server.server_config.ServerConfig:1 #: flwr.server.workflow.default_workflows.DefaultWorkflow:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of @@ -8132,8 +8086,7 @@ msgstr "Bases: :py:class:`object`" #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 #: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 -#: flwr.server.compat.app.start_driver:32 flwr.server.server_app.ServerApp:4 -#: flwr.server.server_app.ServerApp.main:4 +#: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:21 @@ -8147,28 +8100,24 @@ msgstr "实例" msgid "" "Assuming a typical `Client` implementation named `FlowerClient`, you can " "wrap it in a `ClientApp` as follows:" -msgstr "" -"假定有一个名为 `FlowerClient` 的典型 `Client` 实现,可以将其封装在一个 " -"`ClientApp` 中,如下所示:" +msgstr "假定有一个名为 `FlowerClient` 的典型 `Client` 实现,可以将其封装在一个 `ClientApp` 中,如下所示:" #: flwr.client.client_app.ClientApp:16 of #, fuzzy msgid "" -"If the above code is in a Python module called `client`, it can be started " -"as follows:" -msgstr "" -"如果上述代码位于一个名为 \"客户端 \"的 Python 模块中,则可以按如下方式启动" -"它:" +"If the above code is in a Python module called `client`, it can be " +"started as follows:" +msgstr "如果上述代码位于一个名为 \"客户端 \"的 Python 模块中,则可以按如下方式启动它:" #: flwr.client.client_app.ClientApp:21 of #, fuzzy msgid "" -"In this `client:app` example, `client` refers to the Python module `client." -"py` in which the previous code lives in and `app` refers to the global " -"attribute `app` that points to an object of type `ClientApp`." +"In this `client:app` example, `client` refers to the Python module " +"`client.py` in which the previous code lives in and `app` refers to the " +"global attribute `app` that points to an object of type `ClientApp`." msgstr "" -"在这个 `client:app` 例子中,`client` 指的是前面代码所在的 Python 模块 " -"`client.py`,而 `app` 指的是指向 `ClientApp` 类型对象的全局属性 `app` 。" +"在这个 `client:app` 例子中,`client` 指的是前面代码所在的 Python 模块 `client.py`,而 `app` " +"指的是指向 `ClientApp` 类型对象的全局属性 `app` 。" #: flwr.client.client_app.ClientApp.evaluate:1::1 of #, fuzzy @@ -8218,10 +8167,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy -msgid "" -":py:obj:`fit `\\ \\(parameters\\, config\\)" -msgstr "" -":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgstr ":py:obj:`fit `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.fit:1 of @@ -8259,9 +8206,11 @@ msgstr "返回客户端的属性集。" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy msgid "" -":py:obj:`set_context `\\ \\(context\\)" +":py:obj:`set_context `\\ " +"\\(context\\)" msgstr "" -":py:obj:`set_context `\\ \\(context\\)" +":py:obj:`set_context `\\ " +"\\(context\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #, fuzzy @@ -8290,30 +8239,28 @@ msgstr "当前(全局)模型参数。" #: flwr.client.numpy_client.NumPyClient.evaluate:5 of msgid "" -"Configuration parameters which allow the server to influence evaluation on " -"the client. It can be used to communicate arbitrary values from the server " -"to the client, for example, to influence the number of examples used for " -"evaluation." -msgstr "" -"允许服务器影响客户端评估的配置参数。它可用于将任意值从服务器传送到客户端,例" -"如,影响用于评估的示例数量。" +"Configuration parameters which allow the server to influence evaluation " +"on the client. It can be used to communicate arbitrary values from the " +"server to the client, for example, to influence the number of examples " +"used for evaluation." +msgstr "允许服务器影响客户端评估的配置参数。它可用于将任意值从服务器传送到客户端,例如,影响用于评估的示例数量。" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" "* **loss** (*float*) -- The evaluation loss of the model on the local " "dataset. * **num_examples** (*int*) -- The number of examples used for " "evaluation. * **metrics** (*Dict[str, Scalar]*) -- A dictionary mapping " -"arbitrary string keys to values of type bool, bytes, float, int, or str. " -"It can be used to communicate arbitrary values back to the server." +"arbitrary string keys to values of type bool, bytes, float, int, or " +"str. It can be used to communicate arbitrary values back to the server." msgstr "" -"**loss** (*float*) -- 模型在本地数据集上的评估损失值。**num_examples** " -"(*int*) -- 用于评估的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字" -"符串键映射到 bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传" -"回服务器。" +"**loss** (*float*) -- 模型在本地数据集上的评估损失值。**num_examples** (*int*) -- " +"用于评估的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 " +"bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" -"**loss** (*float*) -- The evaluation loss of the model on the local dataset." +"**loss** (*float*) -- The evaluation loss of the model on the local " +"dataset." msgstr "**loss** (*float*) -- 模型在本地数据集上的评估损失值。" #: flwr.client.numpy_client.NumPyClient.evaluate:12 of @@ -8323,43 +8270,41 @@ msgstr "**num_examples** (*int*) -- 用于评估的示例数量。" #: flwr.client.numpy_client.NumPyClient.evaluate:13 #: flwr.client.numpy_client.NumPyClient.fit:13 of msgid "" -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " -"keys to values of type bool, bytes, float, int, or str. It can be used to " -"communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " +"string keys to values of type bool, bytes, float, int, or str. It can be " +"used to communicate arbitrary values back to the server." msgstr "" -"**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 bool、bytes、" -"float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" +"**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 bool、bytes、float、int 或 " +"str 类型值的字典。它可用于将任意值传回服务器。" #: flwr.client.numpy_client.NumPyClient.evaluate:19 of msgid "" -"The previous return type format (int, float, float) and the extended format " -"(int, float, float, Dict[str, Scalar]) have been deprecated and removed " -"since Flower 0.19." +"The previous return type format (int, float, float) and the extended " +"format (int, float, float, Dict[str, Scalar]) have been deprecated and " +"removed since Flower 0.19." msgstr "" -"自 Flower 0.19 起,之前的返回类型格式(int、float、float)和扩展格式(int、" -"float、float、Dict[str, Scalar])已被弃用和移除。" +"自 Flower 0.19 起,之前的返回类型格式(int、float、float)和扩展格式(int、float、float、Dict[str," +" Scalar])已被弃用和移除。" #: flwr.client.numpy_client.NumPyClient.fit:5 of msgid "" -"Configuration parameters which allow the server to influence training on the " -"client. It can be used to communicate arbitrary values from the server to " -"the client, for example, to set the number of (local) training epochs." -msgstr "" -"允许服务器影响客户端训练的配置参数。它可用于将任意值从服务器传送到客户端,例" -"如设置(本地)训练遍历数。" +"Configuration parameters which allow the server to influence training on " +"the client. It can be used to communicate arbitrary values from the " +"server to the client, for example, to set the number of (local) training " +"epochs." +msgstr "允许服务器影响客户端训练的配置参数。它可用于将任意值从服务器传送到客户端,例如设置(本地)训练遍历数。" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "" "* **parameters** (*NDArrays*) -- The locally updated model parameters. * " "**num_examples** (*int*) -- The number of examples used for training. * " -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " -"keys to values of type bool, bytes, float, int, or str. It can be used to " -"communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " +"string keys to values of type bool, bytes, float, int, or str. It can " +"be used to communicate arbitrary values back to the server." msgstr "" -"**parameters** (*NDArrays*) -- 本地更新的模型参数。**num_examples** (*int*) " -"-- 用于训练的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映" -"射到 bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务" -"器。" +"**parameters** (*NDArrays*) -- 本地更新的模型参数。**num_examples** (*int*) -- " +"用于训练的示例数量。**metrics** (*Dict[str, Scalar]*) -- 将任意字符串键映射到 " +"bool、bytes、float、int 或 str 类型值的字典。它可用于将任意值传回服务器。" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "**parameters** (*NDArrays*) -- The locally updated model parameters." @@ -8371,37 +8316,41 @@ msgstr "**num_examples** (*int*) -- 用于训练的数据数量。" #: flwr.client.numpy_client.NumPyClient.get_parameters:3 of msgid "" -"Configuration parameters requested by the server. This can be used to tell " -"the client which parameters are needed along with some Scalar attributes." -msgstr "" -"服务器请求的配置参数。这可以用来告诉客户端需要哪些参数以及一些标量属性。" +"Configuration parameters requested by the server. This can be used to " +"tell the client which parameters are needed along with some Scalar " +"attributes." +msgstr "服务器请求的配置参数。这可以用来告诉客户端需要哪些参数以及一些标量属性。" #: flwr.client.numpy_client.NumPyClient.get_parameters:8 of -msgid "" -"**parameters** -- The local model parameters as a list of NumPy ndarrays." +msgid "**parameters** -- The local model parameters as a list of NumPy ndarrays." msgstr "**parameters** -- NumPy ndarrays 的本地模型参数列表。" #: flwr.client.numpy_client.NumPyClient.get_properties:3 of msgid "" -"Configuration parameters requested by the server. This can be used to tell " -"the client which properties are needed along with some Scalar attributes." -msgstr "" -"服务器请求的配置参数。这可以用来告诉客户端需要哪些属性以及一些标量属性。" +"Configuration parameters requested by the server. This can be used to " +"tell the client which properties are needed along with some Scalar " +"attributes." +msgstr "服务器请求的配置参数。这可以用来告诉客户端需要哪些属性以及一些标量属性。" #: flwr.client.numpy_client.NumPyClient.get_properties:8 of msgid "" -"**properties** -- A dictionary mapping arbitrary string keys to values of " -"type bool, bytes, float, int, or str. It can be used to communicate " +"**properties** -- A dictionary mapping arbitrary string keys to values of" +" type bool, bytes, float, int, or str. It can be used to communicate " "arbitrary property values back to the server." msgstr "" -"**properties** -- 将任意字符串键映射到 bool、bytes、float、int 或 str 类型值" -"的字典。它可用于将任意属性值传回服务器。" +"**properties** -- 将任意字符串键映射到 bool、bytes、float、int 或 str " +"类型值的字典。它可用于将任意属性值传回服务器。" #: ../../source/ref-api/flwr.client.run_client_app.rst:2 #, fuzzy msgid "run\\_client\\_app" msgstr "run\\_client\\_app" +#: ../../source/ref-api/flwr.client.run_supernode.rst:2 +#, fuzzy +msgid "run\\_supernode" +msgstr "flower-superlink" + #: ../../source/ref-api/flwr.client.start_client.rst:2 #, fuzzy msgid "start\\_client" @@ -8410,7 +8359,8 @@ msgstr "启动客户端" #: flwr.client.app.start_client:3 flwr.client.app.start_numpy_client:9 of msgid "" "The IPv4 or IPv6 address of the server. If the Flower server runs on the " -"same machine on port 8080, then `server_address` would be `\"[::]:8080\"`." +"same machine on port 8080, then `server_address` would be " +"`\"[::]:8080\"`." msgstr "" "服务器的 IPv4 或 IPv6 地址:如果 Flower 服务器在同一台机器上运行,端口为 " "8080,则`server_address`应为`\"[::]:8080\"`。" @@ -8421,70 +8371,62 @@ msgstr "用于实例化客户端的可调用程序。(默认值:无)" #: flwr.client.app.start_client:9 of msgid "" -"An implementation of the abstract base class `flwr.client.Client` (default: " -"None)" +"An implementation of the abstract base class `flwr.client.Client` " +"(default: None)" msgstr "抽象基类 `flwr.client.Client` 的实现(默认值:无)" #: flwr.client.app.start_client:12 flwr.client.app.start_numpy_client:15 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower " -"server. The default should be sufficient for most models. Users who train " -"very large models might need to increase this value. Note that the Flower " -"server needs to be started with the same value (see `flwr.server." -"start_server`), otherwise it will not know about the increased limit and " -"block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower" +" server. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower server needs to be started with the same value (see " +"`flwr.server.start_server`), otherwise it will not know about the " +"increased limit and block larger messages." msgstr "" -"可与 Flower 服务器交换的 gRPC 信息的最大长度:默认值对大多数模型都足够了。训" -"练超大模型的用户可能需要增加该值。请注意,Flower 服务器需要以相同的值启动(请" -"参阅 `flwr.server.start_server`),否则它将不知道增加的限制并阻止更大的消息。" +"可与 Flower 服务器交换的 gRPC 信息的最大长度:默认值对大多数模型都足够了。训练超大模型的用户可能需要增加该值。请注意,Flower " +"服务器需要以相同的值启动(请参阅 `flwr.server.start_server`),否则它将不知道增加的限制并阻止更大的消息。" -#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 -#: flwr.server.compat.app.start_driver:21 of +#: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " -"provided, a secure connection using the certificates will be established to " -"an SSL-enabled Flower server." -msgstr "" -"字节字符串或路径字符串形式的 PEM 编码根证书。如果提供,将使用这些证书与启用 " -"SSL 的 Flower 服务器建立安全连接。" +"provided, a secure connection using the certificates will be established " +"to an SSL-enabled Flower server." +msgstr "字节字符串或路径字符串形式的 PEM 编码根证书。如果提供,将使用这些证书与启用 SSL 的 Flower 服务器建立安全连接。" #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of #, fuzzy msgid "" -"Starts an insecure gRPC connection when True. Enables HTTPS connection when " -"False, using system certificates if `root_certificates` is None." +"Starts an insecure gRPC connection when True. Enables HTTPS connection " +"when False, using system certificates if `root_certificates` is None." msgstr "" -"为 True 时启动不安全的 gRPC 连接。False 时启用 HTTPS 连接,如果 " -"`root_certificates` 为 None,则使用系统证书。" +"为 True 时启动不安全的 gRPC 连接。False 时启用 HTTPS 连接,如果 `root_certificates` 为 " +"None,则使用系统证书。" #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" "Configure the transport layer. Allowed values: - 'grpc-bidi': gRPC, " -"bidirectional streaming - 'grpc-rere': gRPC, request-response (experimental) " -"- 'rest': HTTP (experimental)" +"bidirectional streaming - 'grpc-rere': gRPC, request-response " +"(experimental) - 'rest': HTTP (experimental)" msgstr "" -"配置传输层:允许的值包括 - 'grpc-bidi': gRPC,双向流 - 'grpc-rere': gRPC,请" -"求-响应(实验性) - 'rest': HTTP(实验性)" +"配置传输层:允许的值包括 - 'grpc-bidi': gRPC,双向流 - 'grpc-rere': gRPC,请求-响应(实验性) - " +"'rest': HTTP(实验性)" #: flwr.client.app.start_client:31 of #, fuzzy msgid "" "The maximum number of times the client will try to connect to the server " -"before giving up in case of a connection error. If set to None, there is no " -"limit to the number of tries." -msgstr "" -"客户端在出现连接错误时放弃连接服务器的最大尝试次数。如果设置为 \"无\",则不限" -"制尝试次数。" +"before giving up in case of a connection error. If set to None, there is " +"no limit to the number of tries." +msgstr "客户端在出现连接错误时放弃连接服务器的最大尝试次数。如果设置为 \"无\",则不限制尝试次数。" #: flwr.client.app.start_client:35 of #, fuzzy msgid "" -"The maximum duration before the client stops trying to connect to the server " -"in case of connection error. If set to None, there is no limit to the total " -"time." -msgstr "" -"在出现连接错误时,客户端停止尝试连接服务器之前的最长持续时间。如果设置为 \"无" -"\",则总时间没有限制。" +"The maximum duration before the client stops trying to connect to the " +"server in case of connection error. If set to None, there is no limit to " +"the total time." +msgstr "在出现连接错误时,客户端停止尝试连接服务器之前的最长持续时间。如果设置为 \"无\",则总时间没有限制。" #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of msgid "Starting a gRPC client with an insecure server connection:" @@ -8508,13 +8450,13 @@ msgstr "start_numpy_client" #: flwr.client.app.start_numpy_client:5 of #, fuzzy msgid "" -"This function is deprecated since 1.7.0. Use :code:`flwr.client." -"start_client` instead and first convert your :code:`NumPyClient` to type :" -"code:`flwr.client.Client` by executing its :code:`to_client()` method." +"This function is deprecated since 1.7.0. Use " +":code:`flwr.client.start_client` instead and first convert your " +":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " +":code:`to_client()` method." msgstr "" -"自 1.7.0 起该函数已被弃用。请使用 :code:`flwr.client.start_client`,并首先通" -"过执行 :code:`to_client()`方法将 :code:`NumPyClient`转换为 :code:`flwr." -"client.Client`。" +"自 1.7.0 起该函数已被弃用。请使用 :code:`flwr.client.start_client`,并首先通过执行 " +":code:`to_client()`方法将 :code:`NumPyClient`转换为 :code:`flwr.client.Client`。" #: flwr.client.app.start_numpy_client:13 of msgid "An implementation of the abstract base class `flwr.client.NumPyClient`." @@ -8526,10 +8468,8 @@ msgstr "常见" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid "" -":py:obj:`array_from_numpy `\\ \\(ndarray\\)" -msgstr "" -":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgstr ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.record.conversion_utils.array_from_numpy:1 of @@ -8539,10 +8479,8 @@ msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" -msgstr "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgstr ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.bytes_to_ndarray:1 of @@ -8594,10 +8532,8 @@ msgstr "以整数严重性 \"级别 \"记录 \"msg % args\"。" #: ../../source/ref-api/flwr.common.rst:30::1 #, fuzzy -msgid "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" -msgstr "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgstr ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarray_to_bytes:1 of @@ -8648,9 +8584,11 @@ msgstr "将参数对象转换为 NumPy ndarrays。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " +"data\\)" msgstr "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " +"data\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.Array:1 of @@ -8688,8 +8626,9 @@ msgid "" ":py:obj:`ConfigsRecord `\\ " "\\(\\[configs\\_dict\\, keep\\_input\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.configsrecord.ConfigsRecord:1 of @@ -8721,9 +8660,11 @@ msgstr "客户端向服务器发送 DisconnectRes 信息。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, " +"config\\)" msgstr "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, " +"config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.EvaluateIns:1 of @@ -8791,10 +8732,8 @@ msgstr "数据类,用于存储所发生错误的相关信息。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy -msgid "" -":py:obj:`GetParametersIns `\\ \\(config\\)" -msgstr "" -":py:obj:`GetParametersIns `\\ \\(config\\)" +msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" +msgstr ":py:obj:`GetParametersIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetParametersIns:1 of @@ -8817,10 +8756,8 @@ msgstr "要求返回参数时的响应。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy -msgid "" -":py:obj:`GetPropertiesIns `\\ \\(config\\)" -msgstr "" -":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgstr ":py:obj:`GetPropertiesIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetPropertiesIns:1 of @@ -8881,11 +8818,11 @@ msgstr "传统信息类型。" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " -"src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, " +"message\\_id\\, src\\_node\\_id\\, ...\\)" msgstr "" -":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " -"src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, " +"message\\_id\\, src\\_node\\_id\\, ...\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Metadata:1 of @@ -8916,11 +8853,11 @@ msgstr ":py:obj:`NDArray `\\" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy msgid "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" -"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " +":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" -"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " +":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" #: ../../source/ref-api/flwr.common.rst:64::1 #, fuzzy @@ -9015,28 +8952,24 @@ msgstr "数据类,包含数组类或张量类对象的序列化数据以及相 #: flwr.common.record.parametersrecord.Array:6 of #, fuzzy msgid "" -"A string representing the data type of the serialised object (e.g. `np." -"float32`)" +"A string representing the data type of the serialised object (e.g. " +"`np.float32`)" msgstr "表示序列化对象数据类型的字符串(例如 `np.float32`)" #: flwr.common.record.parametersrecord.Array:8 of #, fuzzy msgid "" -"A list representing the shape of the unserialized array-like object. This is " -"used to deserialize the data (depending on the serialization method) or " -"simply as a metadata field." -msgstr "" -"代表未序列化数组对象形状的列表。它可用于反序列化数据(取决于序列化方法),或" -"仅作为元数据字段使用。" +"A list representing the shape of the unserialized array-like object. This" +" is used to deserialize the data (depending on the serialization method) " +"or simply as a metadata field." +msgstr "代表未序列化数组对象形状的列表。它可用于反序列化数据(取决于序列化方法),或仅作为元数据字段使用。" #: flwr.common.record.parametersrecord.Array:12 of #, fuzzy msgid "" -"A string indicating the type of serialisation mechanism used to generate the " -"bytes in `data` from an array-like or tensor-like object." -msgstr "" -"表示序列化机制类型的字符串,用于从类似数组或类似张量的对象中生成 `data` 中的" -"字节。" +"A string indicating the type of serialisation mechanism used to generate " +"the bytes in `data` from an array-like or tensor-like object." +msgstr "表示序列化机制类型的字符串,用于从类似数组或类似张量的对象中生成 `data` 中的字节。" #: flwr.common.record.parametersrecord.Array:15 of #, fuzzy @@ -9092,16 +9025,20 @@ msgstr ":py:obj:`fit_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_parameters_res `\\" +":py:obj:`get_parameters_res " +"`\\" msgstr "" -":py:obj:`get_parameters_res `\\" +":py:obj:`get_parameters_res " +"`\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`get_properties_res `\\" +":py:obj:`get_properties_res " +"`\\" msgstr "" -":py:obj:`get_properties_res `\\" +":py:obj:`get_properties_res " +"`\\" #: ../../source/ref-api/flwr.common.Code.rst:2 #, fuzzy @@ -9121,20 +9058,20 @@ msgstr ":py:obj:`OK `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " +"`\\" msgstr "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " +"`\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " +"`\\" msgstr "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " +"`\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy @@ -9144,11 +9081,11 @@ msgstr ":py:obj:`FIT_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 #, fuzzy msgid "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED " +"`\\" msgstr "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED " +"`\\" #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:2 #, fuzzy @@ -9158,19 +9095,20 @@ msgstr "配置日志记录" #: flwr.common.record.configsrecord.ConfigsRecord:1 of #, fuzzy msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" -"class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing.List`\\ " -"[:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], :py:class:" -"`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ [:py:class:" -"`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" +" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " +"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " +":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" +" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" -"class:`str`, :py:class:`bytes`, :py:class:`bool`, :py:class:`~typing.List`\\ " -"[:py:class:`int`], :py:class:`~typing.List`\\ [:py:class:`float`], :py:class:" -"`~typing.List`\\ [:py:class:`str`], :py:class:`~typing.List`\\ [:py:class:" -"`bytes`], :py:class:`~typing.List`\\ [:py:class:`bool`]]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " +":py:class:`float`, :py:class:`str`, :py:class:`bytes`, :py:class:`bool`, " +":py:class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ " +"[:py:class:`float`], :py:class:`~typing.List`\\ [:py:class:`str`], " +":py:class:`~typing.List`\\ [:py:class:`bytes`], " +":py:class:`~typing.List`\\ [:py:class:`bool`]]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy @@ -9225,8 +9163,7 @@ msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of #, fuzzy -msgid "" -"If key is not found, d is returned if given, otherwise KeyError is raised." +msgid "If key is not found, d is returned if given, otherwise KeyError is raised." msgstr "如果未找到 key,则返回 d(如果给定),否则引发 KeyError。" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9262,15 +9199,13 @@ msgstr "背景" #: flwr.common.context.Context:3 of #, fuzzy msgid "" -"Holds records added by the entity in a given run and that will stay local. " -"This means that the data it holds will never leave the system it's running " -"from. This can be used as an intermediate storage or scratchpad when " -"executing mods. It can also be used as a memory to access at different " -"points during the lifecycle of this entity (e.g. across multiple rounds)" -msgstr "" -"保存实体在给定运行中添加的记录,这些记录将保留在本地。这意味着它保存的数据永" -"远不会离开运行的系统。在执行模式时,它可用作中间存储或抓取板。它还可以作为存" -"储器,在实体生命周期的不同阶段(如多轮)进行访问。" +"Holds records added by the entity in a given run and that will stay " +"local. This means that the data it holds will never leave the system it's" +" running from. This can be used as an intermediate storage or scratchpad " +"when executing mods. It can also be used as a memory to access at " +"different points during the lifecycle of this entity (e.g. across " +"multiple rounds)" +msgstr "保存实体在给定运行中添加的记录,这些记录将保留在本地。这意味着它保存的数据永远不会离开运行的系统。在执行模式时,它可用作中间存储或抓取板。它还可以作为存储器,在实体生命周期的不同阶段(如多轮)进行访问。" #: ../../source/ref-api/flwr.common.Context.rst:28::1 #, fuzzy @@ -9372,2162 +9307,2941 @@ msgstr "返回类型" msgid "Bases: :py:class:`str`, :py:class:`~enum.Enum`" msgstr "Bases: :py:class:`str`, :py:class:`~enum.Enum`" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -#, fuzzy -msgid ":py:obj:`PING `\\" -msgstr ":py:obj:`PING `\\" - -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_CLIENT_ENTER `\\" +":py:obj:`encode `\\ \\(\\[encoding\\, " +"errors\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.encode:1 of +msgid "Encode the string using the codec registered for encoding." msgstr "" -":py:obj:`START_CLIENT_ENTER `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_CLIENT_LEAVE `\\" +":py:obj:`replace `\\ \\(old\\, new\\[\\, " +"count\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.replace:1 of +msgid "Return a copy with all occurrences of substring old replaced by new." msgstr "" -":py:obj:`START_CLIENT_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_SERVER_ENTER `\\" -msgstr "" -":py:obj:`START_SERVER_ENTER `\\" +":py:obj:`split `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -#, fuzzy +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -":py:obj:`START_SERVER_LEAVE `\\" +"Return a list of the substrings in the string, using sep as the separator" +" string." msgstr "" -":py:obj:`START_SERVER_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`RUN_DRIVER_API_ENTER `\\" +":py:obj:`rsplit `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" +msgstr ":py:obj:`PING `\\" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy +msgid ":py:obj:`join `\\ \\(iterable\\, \\/\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.join:1 of +msgid "Concatenate any number of strings." msgstr "" -":py:obj:`RUN_DRIVER_API_ENTER `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE `\\" +msgid ":py:obj:`capitalize `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.capitalize:1 of +msgid "Return a capitalized version of the string." msgstr "" -":py:obj:`RUN_DRIVER_API_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "" -":py:obj:`RUN_FLEET_API_ENTER `\\" +msgid ":py:obj:`casefold `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.casefold:1 of +msgid "Return a version of the string suitable for caseless comparisons." msgstr "" -":py:obj:`RUN_FLEET_API_ENTER `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "" -":py:obj:`RUN_FLEET_API_LEAVE `\\" +msgid ":py:obj:`title `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.title:1 of +msgid "Return a version of the string where each word is titlecased." msgstr "" -":py:obj:`RUN_FLEET_API_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`RUN_SUPERLINK_ENTER `\\" -msgstr "" -":py:obj:`RUN_SUPERLINK_ENTER `\\" +":py:obj:`center `\\ \\(width\\[\\, " +"fillchar\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.center:1 of +#, fuzzy +msgid "Return a centered string of length width." +msgstr "返回客户端的属性集。" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE `\\" +":py:obj:`count `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" +msgstr ":py:obj:`Context `\\ \\(state\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]." msgstr "" -":py:obj:`RUN_SUPERLINK_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_SIMULATION_ENTER `\\" +":py:obj:`expandtabs `\\ " +"\\(\\[tabsize\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.expandtabs:1 of +msgid "Return a copy where all tab characters are expanded using spaces." msgstr "" -":py:obj:`START_SIMULATION_ENTER `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_SIMULATION_LEAVE `\\" +":py:obj:`find `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" +msgstr ":py:obj:`PING `\\" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]." msgstr "" -":py:obj:`START_SIMULATION_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`DRIVER_CONNECT `\\" -msgstr ":py:obj:`DRIVER_CONNECT `\\" +msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" +msgstr ":py:obj:`partition_id `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -#, fuzzy -msgid ":py:obj:`DRIVER_DISCONNECT `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.partition:1 flwr.common.EventType.rpartition:1 of +msgid "Partition the string into three parts using the given separator." msgstr "" -":py:obj:`DRIVER_DISCONNECT `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_DRIVER_ENTER `\\" -msgstr "" -":py:obj:`START_DRIVER_ENTER `\\" +":py:obj:`index `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" +msgstr ":py:obj:`Context `\\ \\(state\\)" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`START_DRIVER_LEAVE `\\" +":py:obj:`ljust `\\ \\(width\\[\\, " +"fillchar\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.ljust:1 of +msgid "Return a left-justified string of length width." msgstr "" -":py:obj:`START_DRIVER_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER `\\" +msgid ":py:obj:`lower `\\ \\(\\)" +msgstr ":py:obj:`now `\\ \\(\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lower:1 of +msgid "Return a copy of the string converted to lowercase." msgstr "" -":py:obj:`RUN_CLIENT_APP_ENTER `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE `\\" +msgid ":py:obj:`lstrip `\\ \\(\\[chars\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.lstrip:1 of +msgid "Return a copy of the string with leading whitespace removed." msgstr "" -":py:obj:`RUN_CLIENT_APP_LEAVE `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -":py:obj:`RUN_SERVER_APP_ENTER `\\" -msgstr "" -":py:obj:`RUN_SERVER_APP_ENTER `\\" +":py:obj:`rfind `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.EventType.rst:42::1 -#, fuzzy +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE `\\" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]." msgstr "" -":py:obj:`RUN_SERVER_APP_LEAVE `\\" -#: ../../source/ref-api/flwr.common.FitIns.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "FitIns" -msgstr "FitIns" +msgid "" +":py:obj:`rindex `\\ \\(sub\\[\\, " +"start\\[\\, end\\]\\]\\)" +msgstr ":py:obj:`Context `\\ \\(state\\)" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`parameters `\\" -msgstr ":py:obj:`parameters `\\" +msgid "" +":py:obj:`rjust `\\ \\(width\\[\\, " +"fillchar\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 -#, fuzzy -msgid ":py:obj:`config `\\" -msgstr ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rjust:1 of +msgid "Return a right-justified string of length width." +msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "FitRes" -msgstr "FitRes" +msgid ":py:obj:`rstrip `\\ \\(\\[chars\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -#, fuzzy -msgid ":py:obj:`status `\\" -msgstr ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.rstrip:1 of +msgid "Return a copy of the string with trailing whitespace removed." +msgstr "" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`parameters `\\" -msgstr ":py:obj:`parameters `\\" +msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" +msgstr ":py:obj:`partition_id `\\" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`num_examples `\\" -msgstr ":py:obj:`num_examples `\\" +msgid "" +":py:obj:`splitlines `\\ " +"\\(\\[keepends\\]\\)" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 -#, fuzzy -msgid ":py:obj:`metrics `\\" -msgstr ":py:obj:`metrics `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.splitlines:1 of +msgid "Return a list of the lines in the string, breaking at line boundaries." +msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "GetParametersIns" -msgstr "参数" +msgid ":py:obj:`strip `\\ \\(\\[chars\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 -#, fuzzy -msgid ":py:obj:`config `\\" -msgstr ":py:obj:`config `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.strip:1 of +msgid "Return a copy of the string with leading and trailing whitespace removed." +msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "GetParametersRes" -msgstr "参数" +msgid ":py:obj:`swapcase `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 -#, fuzzy -msgid ":py:obj:`status `\\" -msgstr ":py:obj:`status `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.swapcase:1 of +msgid "" +"Convert uppercase characters to lowercase and lowercase characters to " +"uppercase." +msgstr "" -#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`parameters `\\" -msgstr ":py:obj:`parameters `\\" +msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 -#, fuzzy -msgid "GetPropertiesIns" -msgstr "GetPropertiesIns" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.translate:1 of +msgid "Replace each character in the string using the given translation table." +msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`config `\\" -msgstr ":py:obj:`config `\\" +msgid ":py:obj:`upper `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 -#, fuzzy -msgid "GetPropertiesRes" -msgstr "GetPropertiesRes" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.upper:1 of +msgid "Return a copy of the string converted to uppercase." +msgstr "" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`status `\\" -msgstr ":py:obj:`status `\\" +msgid "" +":py:obj:`startswith `\\ \\(prefix\\[\\," +" start\\[\\, end\\]\\]\\)" +msgstr ":py:obj:`Status `\\ \\(code\\, message\\)" -#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 -#, fuzzy -msgid ":py:obj:`properties `\\" -msgstr ":py:obj:`properties `\\" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S starts with the specified prefix, False otherwise." +msgstr "" -#: ../../source/ref-api/flwr.common.Message.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Message" -msgstr "服务器端" +msgid "" +":py:obj:`endswith `\\ \\(suffix\\[\\, " +"start\\[\\, end\\]\\]\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 -#: flwr.common.message.Message:3 of -#, fuzzy -msgid "A dataclass including information about the message to be executed." -msgstr "数据类型,包括要执行的信息的相关信息。" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return True if S ends with the specified suffix, False otherwise." +msgstr "" -#: flwr.common.message.Message:5 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side " -"logic to a client, or vice-versa) or that will be sent to it." +":py:obj:`removeprefix `\\ " +"\\(prefix\\, \\/\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removeprefix:1 of +msgid "Return a str with the given prefix string removed if present." msgstr "" -"保存由其他实体发送的记录(如由服务器端逻辑发送到客户端,反之亦然)或将发送到" -"该实体的记录。" -#: flwr.common.message.Message:8 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -"A dataclass that captures information about an error that took place when " -"processing another message." -msgstr "数据类,用于捕捉处理其他报文时发生的错误信息。" +":py:obj:`removesuffix `\\ " +"\\(suffix\\, \\/\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#, fuzzy -msgid "" -":py:obj:`create_error_reply `\\ " -"\\(error\\, ttl\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.removesuffix:1 of +msgid "Return a str with the given suffix string removed if present." msgstr "" -":py:obj:`create_error_reply `\\ " -"\\(error\\, ttl\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_error_reply:1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Construct a reply message indicating an error happened." -msgstr "构建一条回复信息,说明发生了错误。" +msgid ":py:obj:`isascii `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#, fuzzy -msgid "" -":py:obj:`create_reply `\\ \\(content\\, " -"ttl\\)" +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isascii:1 of +msgid "Return True if all characters in the string are ASCII, False otherwise." msgstr "" -":py:obj:`create_reply `\\ \\(content\\, " -"ttl\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.create_reply:1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Create a reply to this message with specified content and TTL." -msgstr "以指定的内容和 TTL 创建对该信息的回复。" +msgid ":py:obj:`islower `\\ \\(\\)" +msgstr ":py:obj:`now `\\ \\(\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.islower:1 of +msgid "Return True if the string is a lowercase string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`has_content `\\ \\(\\)" -msgstr ":py:obj:`has_content `\\ \\(\\)" +msgid ":py:obj:`isupper `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_content:1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isupper:1 of +msgid "Return True if the string is an uppercase string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Return True if message has content, else False." -msgstr "如果信息有内容,则返回 True,否则返回 False。" +msgid ":py:obj:`istitle `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.istitle:1 of +msgid "Return True if the string is a title-cased string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`has_error `\\ \\(\\)" -msgstr ":py:obj:`has_error `\\ \\(\\)" +msgid ":py:obj:`isspace `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: ../../source/ref-api/flwr.common.Message.rst:35::1 -#: flwr.common.message.Message.has_error:1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isspace:1 of +msgid "Return True if the string is a whitespace string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Return True if message has an error, else False." -msgstr "如果信息有错误,则返回 True,否则返回 False。" +msgid ":py:obj:`isdecimal `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Message.content:1::1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdecimal:1 of +msgid "Return True if the string is a decimal string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`content `\\" -msgstr ":py:obj:`content `\\" +msgid ":py:obj:`isdigit `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 -#: of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isdigit:1 of +msgid "Return True if the string is a digit string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "The content of this message." -msgstr "评估客户端的反应。" +msgid ":py:obj:`isnumeric `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Message.content:1::1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isnumeric:1 of +msgid "Return True if the string is a numeric string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`error `\\" -msgstr ":py:obj:`error `\\" +msgid ":py:obj:`isalpha `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalpha:1 of +msgid "Return True if the string is an alphabetic string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Error captured by this message." -msgstr "该信息捕捉到的错误。" +msgid ":py:obj:`isalnum `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Message.content:1::1 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isalnum:1 of +msgid "Return True if the string is an alpha-numeric string, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid ":py:obj:`metadata `\\" -msgstr ":py:obj:`metadata `\\" +msgid ":py:obj:`isidentifier `\\ \\(\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" -#: flwr.common.message.Message.create_error_reply:3 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isidentifier:1 of +msgid "Return True if the string is a valid Python identifier, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "The error that was encountered." -msgstr "遇到的错误。" +msgid ":py:obj:`isprintable `\\ \\(\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.ttl:1 flwr.common.message.Message.create_error_reply:5 -#: flwr.common.message.Message.create_reply:9 flwr.common.message.Metadata:16 -#: of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.isprintable:1 of +msgid "Return True if the string is printable, False otherwise." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "Time-to-live for this message." -msgstr "该信息的有效时间。" +msgid ":py:obj:`zfill `\\ \\(width\\, \\/\\)" +msgstr ":py:obj:`PING `\\" -#: flwr.common.message.Message.create_reply:3 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.zfill:1 of +msgid "" +"Pad a numeric string with zeros on the left, to fill a field of the given" +" width." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy msgid "" -"The method generates a new `Message` as a reply to this message. It inherits " -"'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from this message " -"and sets 'reply_to_message' to the ID of this message." +":py:obj:`format `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" msgstr "" -"该方法会生成一条新的 \"信息\",作为对该信息的回复。该方法继承了该消息的 " -"\"run_id\"、\"src_node_id\"、\"dst_node_id \"和 \"message_type\",并将 " -"\"reply_to_message \"设置为该消息的 ID。" +":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " +"\\*\\*kwargs\\)" -#: flwr.common.message.Message.create_reply:7 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from args and kwargs." +msgstr "" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "The content for the reply message." -msgstr "回复信息的内容。" +msgid ":py:obj:`format_map `\\ \\(mapping\\)" +msgstr ":py:obj:`EventType `\\ \\(value\\)" + +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +msgid "Return a formatted version of S, using substitutions from mapping." +msgstr "" -#: flwr.common.message.Message.create_reply:12 of +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy -msgid "A new `Message` instance representing the reply." -msgstr "代表回复的新的 `Message` 实例。" +msgid ":py:obj:`maketrans `\\" +msgstr ":py:obj:`TRAIN `\\" -#: ../../source/ref-api/flwr.common.MessageType.rst:2 +#: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#: flwr.common.EventType.maketrans:1 of +msgid "Return a translation table usable for str.translate()." +msgstr "" + +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "MessageType" -msgstr "返回类型" +msgid ":py:obj:`PING `\\" +msgstr ":py:obj:`PING `\\" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`EVALUATE `\\" -msgstr ":py:obj:`EVALUATE `\\" +msgid ":py:obj:`START_CLIENT_ENTER `\\" +msgstr ":py:obj:`START_CLIENT_ENTER `\\" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`QUERY `\\" -msgstr ":py:obj:`QUERY `\\" +msgid ":py:obj:`START_CLIENT_LEAVE `\\" +msgstr ":py:obj:`START_CLIENT_LEAVE `\\" -#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`TRAIN `\\" -msgstr ":py:obj:`TRAIN `\\" +msgid ":py:obj:`START_SERVER_ENTER `\\" +msgstr ":py:obj:`START_SERVER_ENTER `\\" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "MessageTypeLegacy" -msgstr "MessageTypeLegacy" +msgid ":py:obj:`START_SERVER_LEAVE `\\" +msgstr ":py:obj:`START_SERVER_LEAVE `\\" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy msgid "" -":py:obj:`GET_PARAMETERS `\\" +":py:obj:`RUN_DRIVER_API_ENTER " +"`\\" msgstr "" -":py:obj:`GET_PARAMETERS `\\" +":py:obj:`RUN_DRIVER_API_ENTER " +"`\\" -#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy msgid "" -":py:obj:`GET_PROPERTIES `\\" +":py:obj:`RUN_DRIVER_API_LEAVE " +"`\\" msgstr "" -":py:obj:`GET_PROPERTIES `\\" - -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of -#, fuzzy -msgid "An identifier for the current run." -msgstr "当前运行的标识符。" - -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of -#, fuzzy -msgid "An identifier for the current message." -msgstr "当前信息的标识符。" +":py:obj:`RUN_DRIVER_API_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "An identifier for the node sending this message." -msgstr "发送此信息的节点的标识符。" +msgid "" +":py:obj:`RUN_FLEET_API_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_FLEET_API_ENTER " +"`\\" -#: flwr.common.Metadata.dst_node_id:1 -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.message.Metadata:9 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "An identifier for the node receiving this message." -msgstr "接收此信息的节点的标识符。" +msgid "" +":py:obj:`RUN_FLEET_API_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_FLEET_API_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "An identifier for the message this message replies to." -msgstr "该信息回复的信息的标识符。" +msgid "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" -#: flwr.common.message.Metadata:13 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy msgid "" -"An identifier for grouping messages. In some settings, this is used as the " -"FL round." -msgstr "用于分组报文的标识符。在某些设置中,它被用作 FL 轮。" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "A string that encodes the action to be executed on the receiving end." -msgstr "编码接收端要执行的操作的字符串。" +msgid "" +":py:obj:`START_SIMULATION_ENTER " +"`\\" +msgstr "" +":py:obj:`START_SIMULATION_ENTER " +"`\\" -#: flwr.common.message.Metadata:21 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy msgid "" -"An identifier that can be used when loading a particular data partition for " -"a ClientApp. Making use of this identifier is more relevant when conducting " -"simulations." +":py:obj:`START_SIMULATION_LEAVE " +"`\\" msgstr "" -"为 ClientApp 加载特定数据分区时可使用的标识符。在进行模拟时,使用该标识符更有" -"意义。" +":py:obj:`START_SIMULATION_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`dst_node_id `\\" -msgstr ":py:obj:`dst_node_id `\\" +msgid ":py:obj:`DRIVER_CONNECT `\\" +msgstr ":py:obj:`DRIVER_CONNECT `\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`group_id `\\" -msgstr ":py:obj:`group_id `\\" +msgid ":py:obj:`DRIVER_DISCONNECT `\\" +msgstr ":py:obj:`DRIVER_DISCONNECT `\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.group_id:1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "An identifier for grouping messages." -msgstr "用于分组信息的标识符。" +msgid ":py:obj:`START_DRIVER_ENTER `\\" +msgstr ":py:obj:`START_DRIVER_ENTER `\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`message_id `\\" -msgstr ":py:obj:`message_id `\\" +msgid ":py:obj:`START_DRIVER_LEAVE `\\" +msgstr ":py:obj:`START_DRIVER_LEAVE `\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`message_type `\\" -msgstr ":py:obj:`message_type `\\" +msgid "" +":py:obj:`RUN_CLIENT_APP_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_CLIENT_APP_ENTER " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`partition_id `\\" -msgstr ":py:obj:`partition_id `\\" +msgid "" +":py:obj:`RUN_CLIENT_APP_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_CLIENT_APP_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 -#: flwr.common.Metadata.partition_id:1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid "An identifier telling which data partition a ClientApp should use." -msgstr "告诉 ClientApp 应使用哪个数据分区的标识符。" +msgid "" +":py:obj:`RUN_SERVER_APP_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_SERVER_APP_ENTER " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`reply_to_message `\\" -msgstr ":py:obj:`reply_to_message `\\" +msgid "" +":py:obj:`RUN_SERVER_APP_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_SERVER_APP_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`run_id `\\" -msgstr ":py:obj:`run_id `\\" +msgid "" +":py:obj:`RUN_SUPERNODE_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of +#: flwr.common.EventType.capitalize:1::1 of #, fuzzy -msgid ":py:obj:`src_node_id `\\" -msgstr ":py:obj:`src_node_id `\\" +msgid "" +":py:obj:`RUN_SUPERNODE_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" -#: flwr.common.Metadata.dst_node_id:1::1 of -#, fuzzy -msgid ":py:obj:`ttl `\\" -msgstr ":py:obj:`ttl `\\" +#: flwr.common.EventType.capitalize:3 of +msgid "" +"More specifically, make the first character have upper case and the rest " +"lower case." +msgstr "" -#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 -#, fuzzy -msgid "MetricsRecord" -msgstr "MetricsRecord" +#: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 +#: flwr.common.EventType.rjust:3 of +msgid "Padding is done using the specified fill character (default is a space)." +msgstr "" -#: flwr.common.record.metricsrecord.MetricsRecord:1 of -#, fuzzy +#: flwr.common.EventType.count:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" -"class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:" -"class:`float`]]]" +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]. Optional arguments start and end are interpreted as" +" in slice notation." msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, :py:class:`float`, :py:" -"class:`~typing.List`\\ [:py:class:`int`], :py:class:`~typing.List`\\ [:py:" -"class:`float`]]]" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`clear `\\ \\(\\)" -msgstr ":py:obj:`clear `\\ \\(\\)" +#: flwr.common.EventType.encode:3 of +msgid "encoding" +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`count_bytes `\\ \\(\\)" -msgstr ":py:obj:`count_bytes `\\ \\(\\)" +#: flwr.common.EventType.encode:4 of +msgid "The encoding in which to encode the string." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of +#: flwr.common.EventType.encode:9 of #, fuzzy -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +msgid "errors" +msgstr "错误" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`items `\\ \\(\\)" -msgstr ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.encode:6 of +msgid "" +"The error handling scheme to use for encoding errors. The default is " +"'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " +"as any other name registered with codecs.register_error that can handle " +"UnicodeEncodeErrors." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`keys `\\ \\(\\)" -msgstr ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.endswith:1 of +msgid "" +"Return True if S ends with the specified suffix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. suffix can also be a tuple of strings " +"to try." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.expandtabs:3 of +msgid "If tabsize is not given, a tab size of 8 characters is assumed." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy +#: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." msgstr "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`values `\\ \\(\\)" -msgstr ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of +msgid "Return -1 on failure." +msgstr "" -#: ../../source/ref-api/flwr.common.NDArray.rst:2 -#, fuzzy -msgid "NDArray" -msgstr "NDArray" +#: flwr.common.EventType.format:1 of +msgid "" +"Return a formatted version of S, using substitutions from args and " +"kwargs. The substitutions are identified by braces ('{' and '}')." +msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -#, fuzzy -msgid ":py:obj:`tensors `\\" -msgstr ":py:obj:`tensors `\\" +#: flwr.common.EventType.format_map:1 of +msgid "" +"Return a formatted version of S, using substitutions from mapping. The " +"substitutions are identified by braces ('{' and '}')." +msgstr "" -#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 -#, fuzzy -msgid ":py:obj:`tensor_type `\\" -msgstr ":py:obj:`tensor_type `\\" +#: flwr.common.EventType.index:5 flwr.common.EventType.rindex:5 of +msgid "Raises ValueError when the substring is not found." +msgstr "" -#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 -#, fuzzy -msgid "ParametersRecord" -msgstr "参数" +#: flwr.common.EventType.isalnum:3 of +msgid "" +"A string is alpha-numeric if all characters in the string are alpha-" +"numeric and there is at least one character in the string." +msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord:1 of -#, fuzzy +#: flwr.common.EventType.isalpha:3 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"A string is alphabetic if all characters in the string are alphabetic and" +" there is at least one character in the string." msgstr "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" -#: flwr.common.record.parametersrecord.ParametersRecord:3 of -#, fuzzy +#: flwr.common.EventType.isascii:3 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds entries " -"as an OrderedDict[str, Array]. ParametersRecord objects can be viewed as an " -"equivalent to PyTorch's state_dict, but holding serialised tensors instead." +"ASCII characters have code points in the range U+0000-U+007F. Empty " +"string is ASCII too." msgstr "" -"按顺序存储命名数组的数据类。这意味着它以 OrderedDict[str, Array] 的形式保存条" -"目。ParametersRecord 对象相当于 PyTorch 的 state_dict,但它保存的是序列化的张" -"量。" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`clear `\\ \\(\\)" -msgstr ":py:obj:`clear `\\ \\(\\)" +#: flwr.common.EventType.isdecimal:3 of +msgid "" +"A string is a decimal string if all characters in the string are decimal " +"and there is at least one character in the string." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy +#: flwr.common.EventType.isdigit:3 of msgid "" -":py:obj:`count_bytes `\\ \\(\\)" +"A string is a digit string if all characters in the string are digits and" +" there is at least one character in the string." msgstr "" -":py:obj:`count_bytes `\\ \\(\\)" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.isidentifier:3 of +msgid "" +"Call keyword.iskeyword(s) to test whether string s is a reserved " +"identifier, such as \"def\" or \"class\"." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`items `\\ \\(\\)" -msgstr ":py:obj:`items `\\ \\(\\)" +#: flwr.common.EventType.islower:3 of +msgid "" +"A string is lowercase if all cased characters in the string are lowercase" +" and there is at least one cased character in the string." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`keys `\\ \\(\\)" -msgstr ":py:obj:`keys `\\ \\(\\)" +#: flwr.common.EventType.isnumeric:3 of +msgid "" +"A string is numeric if all characters in the string are numeric and there" +" is at least one character in the string." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +#: flwr.common.EventType.isprintable:3 of +msgid "" +"A string is printable if all of its characters are considered printable " +"in repr() or if it is empty." +msgstr "" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy +#: flwr.common.EventType.isspace:3 of msgid "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" +"A string is whitespace if all characters in the string are whitespace and" +" there is at least one character in the string." msgstr "" -":py:obj:`update `\\ \\(\\[E\\, " -"\\]\\*\\*F\\)" -#: flwr.common.record.typeddict.TypedDict.clear:1::1 of -#, fuzzy -msgid ":py:obj:`values `\\ \\(\\)" -msgstr ":py:obj:`values `\\ \\(\\)" +#: flwr.common.EventType.istitle:3 of +msgid "" +"In a title-cased string, upper- and title-case characters may only follow" +" uncased characters and lowercase characters only cased ones." +msgstr "" -#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of -#, fuzzy +#: flwr.common.EventType.isupper:3 of msgid "" -"Note that a small amount of Bytes might also be included in this counting " -"that correspond to metadata of the serialized object (e.g. of NumPy array) " -"needed for deseralization." +"A string is uppercase if all cased characters in the string are uppercase" +" and there is at least one cased character in the string." msgstr "" -"请注意,该计数中还可能包含少量字节,这些字节与序列化对象(如 NumPy 数组)的元" -"数据相对应,需要进行去eralization。" -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 -#, fuzzy -msgid "ReconnectIns" -msgstr "启用 SSL 连接" +#: flwr.common.EventType.join:3 of +msgid "" +"The string whose method is called is inserted in between each given " +"string. The result is returned as a new string." +msgstr "" -#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 -#, fuzzy -msgid ":py:obj:`seconds `\\" -msgstr ":py:obj:`seconds `\\" +#: flwr.common.EventType.join:6 of +msgid "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" +msgstr "" -#: ../../source/ref-api/flwr.common.RecordSet.rst:2 -#, fuzzy -msgid "RecordSet" -msgstr "RecordSet" +#: flwr.common.EventType.lstrip:3 flwr.common.EventType.rstrip:3 +#: flwr.common.EventType.strip:3 of +msgid "If chars is given and not None, remove characters in chars instead." +msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -#, fuzzy -msgid ":py:obj:`configs_records `\\" -msgstr ":py:obj:`configs_records `\\" +#: flwr.common.EventType.maketrans:3 of +msgid "" +"If there is only one argument, it must be a dictionary mapping Unicode " +"ordinals (integers) or characters to Unicode ordinals, strings or None. " +"Character keys will be then converted to ordinals. If there are two " +"arguments, they must be strings of equal length, and in the resulting " +"dictionary, each character in x will be mapped to the character at the " +"same position in y. If there is a third argument, it must be a string, " +"whose characters will be mapped to None in the result." +msgstr "" -#: flwr.common.RecordSet.configs_records:1 -#: flwr.common.RecordSet.configs_records:1::1 of -#, fuzzy -msgid "Dictionary holding ConfigsRecord instances." -msgstr "包含 ConfigsRecord 实例的字典。" +#: flwr.common.EventType.partition:3 of +msgid "" +"This will search for the separator in the string. If the separator is " +"found, returns a 3-tuple containing the part before the separator, the " +"separator itself, and the part after it." +msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -#, fuzzy -msgid ":py:obj:`metrics_records `\\" -msgstr ":py:obj:`metrics_records `\\" +#: flwr.common.EventType.partition:7 of +msgid "" +"If the separator is not found, returns a 3-tuple containing the original " +"string and two empty strings." +msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.metrics_records:1 of -#, fuzzy -msgid "Dictionary holding MetricsRecord instances." -msgstr "保存 MetricsRecord 实例的字典。" +#: flwr.common.EventType.removeprefix:3 of +msgid "" +"If the string starts with the prefix string, return string[len(prefix):]." +" Otherwise, return a copy of the original string." +msgstr "" -#: flwr.common.RecordSet.configs_records:1::1 of -#, fuzzy +#: flwr.common.EventType.removesuffix:3 of msgid "" -":py:obj:`parameters_records `\\" +"If the string ends with the suffix string and that suffix is not empty, " +"return string[:-len(suffix)]. Otherwise, return a copy of the original " +"string." msgstr "" -":py:obj:`parameters_records `\\" -#: flwr.common.RecordSet.configs_records:1::1 -#: flwr.common.RecordSet.parameters_records:1 of +#: flwr.common.EventType.replace:5 of #, fuzzy -msgid "Dictionary holding ParametersRecord instances." -msgstr "存放 ParametersRecord 实例的字典。" +msgid "count" +msgstr "背景" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 -#, fuzzy -msgid "ServerMessage" -msgstr "服务器端" +#: flwr.common.EventType.replace:4 of +msgid "" +"Maximum number of occurrences to replace. -1 (the default value) means " +"replace all occurrences." +msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -#, fuzzy -msgid ":py:obj:`evaluate_ins `\\" -msgstr ":py:obj:`evaluate_ins `\\" +#: flwr.common.EventType.replace:7 of +msgid "" +"If the optional argument count is given, only the first count occurrences" +" are replaced." +msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -#, fuzzy -msgid ":py:obj:`fit_ins `\\" -msgstr ":py:obj:`fit_ins `\\" +#: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of +msgid "" +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]. Optional arguments start and end are " +"interpreted as in slice notation." +msgstr "" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -#, fuzzy +#: flwr.common.EventType.rpartition:3 of msgid "" -":py:obj:`get_parameters_ins `\\" +"This will search for the separator in the string, starting at the end. If" +" the separator is found, returns a 3-tuple containing the part before the" +" separator, the separator itself, and the part after it." msgstr "" -":py:obj:`get_parameters_ins `\\" -#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 -#, fuzzy +#: flwr.common.EventType.rpartition:7 of msgid "" -":py:obj:`get_properties_ins `\\" +"If the separator is not found, returns a 3-tuple containing two empty " +"strings and the original string." msgstr "" -":py:obj:`get_properties_ins `\\" -#: ../../source/ref-api/flwr.common.Status.rst:2 -#, fuzzy -msgid "Status" -msgstr "客户端状态。" +#: flwr.common.EventType.rsplit:7 flwr.common.EventType.split:7 of +msgid "sep" +msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -#, fuzzy -msgid ":py:obj:`code `\\" -msgstr ":py:obj:`code `\\" +#: flwr.common.EventType.rsplit:4 flwr.common.EventType.split:4 of +msgid "The separator used to split the string." +msgstr "" -#: ../../source/ref-api/flwr.common.Status.rst:29::1 -#, fuzzy -msgid ":py:obj:`message `\\" -msgstr ":py:obj:`message `\\" +#: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of +msgid "" +"When set to None (the default value), will split on any whitespace " +"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" +" empty strings from the result." +msgstr "" -#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 -#, fuzzy -msgid "array\\_from\\_numpy" -msgstr "array\\_from\\_numpy" +#: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of +msgid "maxsplit" +msgstr "" -#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 -#, fuzzy -msgid "bytes\\_to\\_ndarray" -msgstr "bytes\\_to\\_ndarray" - -#: ../../source/ref-api/flwr.common.configure.rst:2 -#, fuzzy -msgid "configure" -msgstr "配置日志记录" +#: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of +msgid "" +"Maximum number of splits (starting from the left). -1 (the default value)" +" means no limit." +msgstr "" -#: ../../source/ref-api/flwr.common.event.rst:2 -#, fuzzy -msgid "event" -msgstr "事件" +#: flwr.common.EventType.rsplit:13 of +msgid "Splitting starts at the end of the string and works to the front." +msgstr "" -#: ../../source/ref-api/flwr.common.log.rst:2 -#, fuzzy -msgid "log" -msgstr "登录" +#: flwr.common.EventType.split:13 of +msgid "" +"Note, str.split() is mainly useful for data that has been intentionally " +"delimited. With natural text that includes punctuation, consider using " +"the regular expression module." +msgstr "" -#: logging.Logger.log:3 of +#: flwr.common.EventType.splitlines:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a true " -"value, e.g." -msgstr "要传递异常信息,请使用带 true 值的关键字参数 exc_info,例如。" +"Line breaks are not included in the resulting list unless keepends is " +"given and true." +msgstr "" -#: logging.Logger.log:6 of -#, python-format -msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" +#: flwr.common.EventType.startswith:1 of +msgid "" +"Return True if S starts with the specified prefix, False otherwise. With " +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. prefix can also be a tuple of strings " +"to try." msgstr "" -"logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" -#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 -#, fuzzy -msgid "ndarray\\_to\\_bytes" -msgstr "ndarray\\_to\\_bytes" +#: flwr.common.EventType.title:3 of +msgid "" +"More specifically, words start with uppercased characters and all " +"remaining cased characters have lower case." +msgstr "" -#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 +#: flwr.common.EventType.translate:5 of #, fuzzy -msgid "ndarrays\\_to\\_parameters" -msgstr "ndarrays\\_to\\_parameters" +msgid "table" +msgstr "数据库" -#: ../../source/ref-api/flwr.common.now.rst:2 -#, fuzzy -msgid "now" -msgstr "现在" +#: flwr.common.EventType.translate:4 of +msgid "" +"Translation table, which must be a mapping of Unicode ordinals to Unicode" +" ordinals, strings, or None." +msgstr "" -#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 -#, fuzzy -msgid "parameters\\_to\\_ndarrays" -msgstr "parameters\\_to\\_ndarrays" +#: flwr.common.EventType.translate:7 of +msgid "" +"The table must implement lookup/indexing via __getitem__, for instance a " +"dictionary or list. If this operation raises LookupError, the character " +"is left untouched. Characters mapped to None are deleted." +msgstr "" -#: ../../source/ref-api/flwr.server.rst:2 -msgid "server" -msgstr "服务器" +#: flwr.common.EventType.zfill:3 of +msgid "The string is never truncated." +msgstr "" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.FitIns.rst:2 #, fuzzy -msgid ":py:obj:`run_driver_api `\\ \\(\\)" -msgstr ":py:obj:`run_driver_api `\\ \\(\\)" +msgid "FitIns" +msgstr "FitIns" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_driver_api:1 of +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 #, fuzzy -msgid "Run Flower server (Driver API)." -msgstr "flower-driver-api" +msgid ":py:obj:`parameters `\\" +msgstr ":py:obj:`parameters `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.FitIns.rst:29::1 #, fuzzy -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -msgstr ":py:obj:`run_fleet_api `\\ \\(\\)" +msgid ":py:obj:`config `\\" +msgstr ":py:obj:`config `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_fleet_api:1 of +#: ../../source/ref-api/flwr.common.FitRes.rst:2 #, fuzzy -msgid "Run Flower server (Fleet API)." -msgstr "Flower 服务器。" +msgid "FitRes" +msgstr "FitRes" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 #, fuzzy -msgid ":py:obj:`run_server_app `\\ \\(\\)" -msgstr ":py:obj:`run_server_app `\\ \\(\\)" +msgid ":py:obj:`status `\\" +msgstr ":py:obj:`status `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.run_serverapp.run_server_app:1 of +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 #, fuzzy -msgid "Run Flower server app." -msgstr "Flower 服务器。" +msgid ":py:obj:`parameters `\\" +msgstr ":py:obj:`parameters `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 #, fuzzy -msgid ":py:obj:`run_superlink `\\ \\(\\)" -msgstr ":py:obj:`run_superlink `\\ \\(\\)" +msgid ":py:obj:`num_examples `\\" +msgstr ":py:obj:`num_examples `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.run_superlink:1 of +#: ../../source/ref-api/flwr.common.FitRes.rst:31::1 #, fuzzy -msgid "Run Flower server (Driver API and Fleet API)." -msgstr "运行 Flower 服务器(Driver API 和 Fleet API)。" +msgid ":py:obj:`metrics `\\" +msgstr ":py:obj:`metrics `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 #, fuzzy -msgid "" -":py:obj:`start_driver `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" -msgstr "" -":py:obj:`start_driver `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" +msgid "GetParametersIns" +msgstr "参数" -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.compat.app.start_driver:1 of +#: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 #, fuzzy -msgid "Start a Flower Driver API server." -msgstr "启动基于 Ray 的Flower模拟服务器。" +msgid ":py:obj:`config `\\" +msgstr ":py:obj:`config `\\" -#: ../../source/ref-api/flwr.server.rst:27::1 +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 #, fuzzy -msgid "" -":py:obj:`start_server `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" -msgstr "" -":py:obj:`start_server `\\ \\(\\*\\[\\, " -"server\\_address\\, server\\, ...\\]\\)" - -#: ../../source/ref-api/flwr.server.rst:27::1 -#: flwr.server.app.start_server:1 of -msgid "Start a Flower server using the gRPC transport layer." -msgstr "使用 gRPC 传输层启动 Flower 服务器。" +msgid "GetParametersRes" +msgstr "参数" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 #, fuzzy -msgid ":py:obj:`ClientManager `\\ \\(\\)" -msgstr ":py:obj:`ClientManager `\\ \\(\\)" +msgid ":py:obj:`status `\\" +msgstr ":py:obj:`status `\\" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.ClientManager:1 of +#: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 #, fuzzy -msgid "Abstract base class for managing Flower clients." -msgstr "Flower 客户端的抽象基类。" +msgid ":py:obj:`parameters `\\" +msgstr ":py:obj:`parameters `\\" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 #, fuzzy -msgid "" -":py:obj:`Driver `\\ " -"\\(\\[driver\\_service\\_address\\, ...\\]\\)" -msgstr "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +msgid "GetPropertiesIns" +msgstr "GetPropertiesIns" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.driver.driver.Driver:1 of +#: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 #, fuzzy -msgid "`Driver` class provides an interface to the Driver API." -msgstr "`Driver` 类为驱动程序 API 提供了一个接口。" +msgid ":py:obj:`config `\\" +msgstr ":py:obj:`config `\\" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 #, fuzzy -msgid ":py:obj:`History `\\ \\(\\)" -msgstr ":py:obj:`History `\\ \\(\\)" +msgid "GetPropertiesRes" +msgstr "GetPropertiesRes" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.history.History:1 of +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 #, fuzzy -msgid "History class for training and/or evaluation metrics collection." -msgstr "**hist** -- 包含训练和评估指标的对象。" +msgid ":py:obj:`status `\\" +msgstr ":py:obj:`status `\\" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 #, fuzzy -msgid "" -":py:obj:`LegacyContext `\\ \\(state\\[\\, " -"config\\, strategy\\, ...\\]\\)" -msgstr "" -":py:obj:`LegacyContext `\\ \\(state\\[\\, " -"config\\, strategy\\, ...\\]\\)" +msgid ":py:obj:`properties `\\" +msgstr ":py:obj:`properties `\\" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.compat.legacy_context.LegacyContext:1 of +#: ../../source/ref-api/flwr.common.Message.rst:2 #, fuzzy -msgid "Legacy Context." -msgstr "传承背景。" +msgid "Message" +msgstr "服务器端" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 +#: flwr.common.message.Message:3 of #, fuzzy -msgid "" -":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " -"strategy\\]\\)" -msgstr "" -":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " -"strategy\\]\\)" +msgid "A dataclass including information about the message to be executed." +msgstr "数据类型,包括要执行的信息的相关信息。" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: flwr.common.message.Message:5 of #, fuzzy msgid "" -":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " -"strategy\\, ...\\]\\)" -msgstr "server.strategy.Strategy" +"Holds records either sent by another entity (e.g. sent by the server-side" +" logic to a client, or vice-versa) or that will be sent to it." +msgstr "保存由其他实体发送的记录(如由服务器端逻辑发送到客户端,反之亦然)或将发送到该实体的记录。" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_app.ServerApp:1 of +#: flwr.common.message.Message:8 of #, fuzzy -msgid "Flower ServerApp." -msgstr "Flower 服务器。" +msgid "" +"A dataclass that captures information about an error that took place when" +" processing another message." +msgstr "数据类,用于捕捉处理其他报文时发生的错误信息。" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.Message.rst:35::1 #, fuzzy msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\, " -"round\\_timeout\\]\\)" +":py:obj:`create_error_reply `\\ " +"\\(error\\[\\, ttl\\]\\)" msgstr "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +":py:obj:`create_error_reply `\\ " +"\\(error\\, ttl\\)" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.server_config.ServerConfig:1 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_error_reply:1 of #, fuzzy -msgid "Flower server config." -msgstr "Flower 服务器。" +msgid "Construct a reply message indicating an error happened." +msgstr "构建一条回复信息,说明发生了错误。" -#: ../../source/ref-api/flwr.server.rst:41::1 +#: ../../source/ref-api/flwr.common.Message.rst:35::1 #, fuzzy msgid "" -":py:obj:`SimpleClientManager `\\ \\(\\)" +":py:obj:`create_reply `\\ " +"\\(content\\[\\, ttl\\]\\)" msgstr "" -":py:obj:`SimpleClientManager `\\ \\(\\)" +":py:obj:`create_reply `\\ \\(content\\," +" ttl\\)" -#: ../../source/ref-api/flwr.server.rst:41::1 -#: flwr.server.client_manager.SimpleClientManager:1 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.create_reply:1 of #, fuzzy -msgid "Provides a pool of available clients." -msgstr "使用部分可用客户进行评估。" +msgid "Create a reply to this message with specified content and TTL." +msgstr "以指定的内容和 TTL 创建对该信息的回复。" -#: ../../source/ref-api/flwr.server.rst:60::1 +#: ../../source/ref-api/flwr.common.Message.rst:35::1 #, fuzzy -msgid ":py:obj:`flwr.server.strategy `\\" -msgstr "server.strategy.Strategy" - -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.strategy:1 of -msgid "Contains the strategy abstraction and different implementations." -msgstr "包含策略抽象和不同的实现方法。" +msgid ":py:obj:`has_content `\\ \\(\\)" +msgstr ":py:obj:`has_content `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:60::1 +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_content:1 of #, fuzzy -msgid ":py:obj:`flwr.server.workflow `\\" -msgstr "server.strategy.Strategy" +msgid "Return True if message has content, else False." +msgstr "如果信息有内容,则返回 True,否则返回 False。" -#: ../../source/ref-api/flwr.server.rst:60::1 -#: flwr.server.workflow:1 of +#: ../../source/ref-api/flwr.common.Message.rst:35::1 #, fuzzy -msgid "Workflows." -msgstr "工作流程" +msgid ":py:obj:`has_error `\\ \\(\\)" +msgstr ":py:obj:`has_error `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.ClientManager.rst:2 +#: ../../source/ref-api/flwr.common.Message.rst:35::1 +#: flwr.common.message.Message.has_error:1 of #, fuzzy -msgid "ClientManager" -msgstr "客户端" +msgid "Return True if message has an error, else False." +msgstr "如果信息有错误,则返回 True,否则返回 False。" -#: flwr.server.client_manager.ClientManager.all:1::1 of +#: flwr.common.Message.content:1::1 of #, fuzzy -msgid ":py:obj:`all `\\ \\(\\)" -msgstr ":py:obj:`all `\\ \\(\\)" +msgid ":py:obj:`content `\\" +msgstr ":py:obj:`content `\\" -#: flwr.server.client_manager.ClientManager.all:1 -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.all:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: flwr.common.Message.content:1 flwr.common.Message.content:1::1 +#: of #, fuzzy -msgid "Return all available clients." -msgstr "返回所有可用客户。" +msgid "The content of this message." +msgstr "评估客户端的反应。" -#: flwr.server.client_manager.ClientManager.all:1::1 of +#: flwr.common.Message.content:1::1 of #, fuzzy -msgid "" -":py:obj:`num_available `\\ \\(\\)" -msgstr "" -":py:obj:`num_available `\\ \\(\\)" +msgid ":py:obj:`error `\\" +msgstr ":py:obj:`error `\\" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.num_available:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.num_available:1 of +#: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of #, fuzzy -msgid "Return the number of available clients." -msgstr "返回样本大小和所需的可用客户数量。" +msgid "Error captured by this message." +msgstr "该信息捕捉到的错误。" -#: flwr.server.client_manager.ClientManager.all:1::1 of +#: flwr.common.Message.content:1::1 of #, fuzzy -msgid ":py:obj:`register `\\ \\(client\\)" -msgstr ":py:obj:`register `\\ \\(client\\)" +msgid ":py:obj:`metadata `\\" +msgstr ":py:obj:`metadata `\\" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.register:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.register:1 of +#: flwr.common.message.Message.create_error_reply:3 of #, fuzzy -msgid "Register Flower ClientProxy instance." -msgstr "注册 Flower ClientProxy 实例。" +msgid "The error that was encountered." +msgstr "遇到的错误。" -#: flwr.server.client_manager.ClientManager.all:1::1 of -#, fuzzy +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -":py:obj:`sample `\\ \\(num\\_clients\\[\\, " -"min\\_num\\_clients\\, criterion\\]\\)" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " +"msg.meta.created_at)" msgstr "" -":py:obj:`sample `\\ \\(num\\_clients\\[\\, " -"min\\_num\\_clients\\, criterion\\]\\)" - -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.sample:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.sample:1 of -#, fuzzy -msgid "Sample a number of Flower ClientProxy instances." -msgstr "取样若干 Flower ClientProxy 实例。" -#: flwr.server.client_manager.ClientManager.all:1::1 of -#, fuzzy +#: flwr.common.message.Message.create_error_reply:5 +#: flwr.common.message.Message.create_reply:9 of msgid "" -":py:obj:`unregister `\\ \\(client\\)" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation:" msgstr "" -":py:obj:`unregister `\\ \\(client\\)" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.unregister:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.unregister:1 of -#, fuzzy -msgid "Unregister Flower ClientProxy instance." -msgstr "取消注册 Flower ClientProxy 实例。" +#: flwr.common.message.Message.create_error_reply:9 +#: flwr.common.message.Message.create_reply:13 of +msgid "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" +msgstr "" -#: flwr.server.client_manager.ClientManager.all:1::1 of +#: flwr.common.message.Message.create_reply:3 of #, fuzzy msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\, timeout\\)" +"The method generates a new `Message` as a reply to this message. It " +"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " +"this message and sets 'reply_to_message' to the ID of this message." msgstr "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\, timeout\\)" +"该方法会生成一条新的 \"信息\",作为对该信息的回复。该方法继承了该消息的 " +"\"run_id\"、\"src_node_id\"、\"dst_node_id \"和 \"message_type\",并将 " +"\"reply_to_message \"设置为该消息的 ID。" -#: flwr.server.client_manager.ClientManager.all:1::1 -#: flwr.server.client_manager.ClientManager.wait_for:1 -#: flwr.server.client_manager.SimpleClientManager.all:1::1 -#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of +#: flwr.common.message.Message.create_reply:7 of #, fuzzy -msgid "Wait until at least `num_clients` are available." -msgstr "等待至少 `num_clients` 可用。" +msgid "The content for the reply message." +msgstr "回复信息的内容。" -#: flwr.server.client_manager.ClientManager.num_available:3 -#: flwr.server.client_manager.SimpleClientManager.num_available:3 of +#: flwr.common.message.Message.create_reply:16 of #, fuzzy -msgid "**num_available** -- The number of currently available clients." -msgstr "**num_available** -- 当前可用客户端的数量。" +msgid "A new `Message` instance representing the reply." +msgstr "代表回复的新的 `Message` 实例。" -#: flwr.server.client_manager.ClientManager.register:6 -#: flwr.server.client_manager.SimpleClientManager.register:6 of +#: ../../source/ref-api/flwr.common.MessageType.rst:2 #, fuzzy -msgid "" -"**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any reason." -msgstr "" -"**success** -- 表示注册是否成功。如果 ClientProxy 已注册或因故无法注册,则为 " -"False。" +msgid "MessageType" +msgstr "返回类型" -#: flwr.server.client_manager.ClientManager.unregister:3 -#: flwr.server.client_manager.SimpleClientManager.unregister:3 of +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 #, fuzzy -msgid "This method is idempotent." -msgstr "这种方法是幂等的。" +msgid ":py:obj:`EVALUATE `\\" +msgstr ":py:obj:`EVALUATE `\\" -#: ../../source/ref-api/flwr.server.Driver.rst:2 +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 #, fuzzy -msgid "Driver" -msgstr "服务器" +msgid ":py:obj:`QUERY `\\" +msgstr ":py:obj:`QUERY `\\" -#: flwr.server.driver.driver.Driver:3 of +#: ../../source/ref-api/flwr.common.MessageType.rst:30::1 #, fuzzy -msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:9091\"`." -msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" +msgid ":py:obj:`TRAIN `\\" +msgstr ":py:obj:`TRAIN `\\" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of -msgid "" -"Tuple containing root certificate, server certificate, and private key to " -"start a secure SSL-enabled server. The tuple is expected to have three bytes " -"elements in the following order: * CA certificate. * server " -"certificate. * server private key." -msgstr "" -"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以" -"下顺序包含三个字节元素: * CA 证书,* 服务器证书, * 服务器私钥。" +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 +#, fuzzy +msgid "MessageTypeLegacy" +msgstr "MessageTypeLegacy" -#: flwr.server.app.start_server:28 flwr.server.driver.driver.Driver:6 of -msgid "" -"Tuple containing root certificate, server certificate, and private key to " -"start a secure SSL-enabled server. The tuple is expected to have three bytes " -"elements in the following order:" -msgstr "" -"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以" -"下顺序包含三个字节元素:" +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#, fuzzy +msgid ":py:obj:`GET_PARAMETERS `\\" +msgstr ":py:obj:`GET_PARAMETERS `\\" -#: flwr.server.app.start_server:32 flwr.server.driver.driver.Driver:10 of -msgid "CA certificate." -msgstr "CA 证书。" +#: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 +#, fuzzy +msgid ":py:obj:`GET_PROPERTIES `\\" +msgstr ":py:obj:`GET_PROPERTIES `\\" -#: flwr.server.app.start_server:33 flwr.server.driver.driver.Driver:11 of -msgid "server certificate." -msgstr "服务器证书。" +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of +#, fuzzy +msgid "An identifier for the current run." +msgstr "当前运行的标识符。" -#: flwr.server.app.start_server:34 flwr.server.driver.driver.Driver:12 of -msgid "server private key." -msgstr "服务器私人密钥。" +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of +#, fuzzy +msgid "An identifier for the current message." +msgstr "当前信息的标识符。" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of #, fuzzy -msgid ":py:obj:`close `\\ \\(\\)" -msgstr "server.strategy.Strategy" +msgid "An identifier for the node sending this message." +msgstr "发送此信息的节点的标识符。" -#: flwr.server.driver.driver.Driver.close:1 -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.dst_node_id:1 flwr.common.message.Metadata:9 of #, fuzzy -msgid "Disconnect from the SuperLink if connected." -msgstr "如果已连接,请断开与超级链接的连接。" +msgid "An identifier for the node receiving this message." +msgstr "接收此信息的节点的标识符。" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of #, fuzzy -msgid "" -":py:obj:`create_message `\\ \\(content\\, " -"message\\_type\\, ...\\)" -msgstr "" -":py:obj:`create_message `\\ \\(content\\, " -"message\\_type\\, ...\\)" +msgid "An identifier for the message this message replies to." +msgstr "该信息回复的信息的标识符。" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.create_message:1 of +#: flwr.common.message.Metadata:13 of #, fuzzy -msgid "Create a new message with specified parameters." -msgstr "使用指定参数创建新信息。" +msgid "" +"An identifier for grouping messages. In some settings, this is used as " +"the FL round." +msgstr "用于分组报文的标识符。在某些设置中,它被用作 FL 轮。" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.message.Metadata:16 of #, fuzzy -msgid ":py:obj:`get_node_ids `\\ \\(\\)" -msgstr ":py:obj:`get_node_ids `\\ \\(\\)" +msgid "Time-to-live for this message in seconds." +msgstr "该信息的有效时间。" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.get_node_ids:1 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of #, fuzzy -msgid "Get node IDs." -msgstr "获取节点 ID。" +msgid "A string that encodes the action to be executed on the receiving end." +msgstr "编码接收端要执行的操作的字符串。" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.message.Metadata:21 of #, fuzzy msgid "" -":py:obj:`pull_messages `\\ " -"\\(message\\_ids\\)" -msgstr "" -":py:obj:`pull_messages `\\ " -"\\(message\\_ids\\)" +"An identifier that can be used when loading a particular data partition " +"for a ClientApp. Making use of this identifier is more relevant when " +"conducting simulations." +msgstr "为 ClientApp 加载特定数据分区时可使用的标识符。在进行模拟时,使用该标识符更有意义。" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.pull_messages:1 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "Pull messages based on message IDs." -msgstr "根据信息 ID 提取信息。" +msgid ":py:obj:`created_at `\\" +msgstr ":py:obj:`ttl `\\" -#: flwr.server.driver.driver.Driver.close:1::1 of -#, fuzzy -msgid "" -":py:obj:`push_messages `\\ \\(messages\\)" +#: flwr.common.Metadata.created_at:1 +#: flwr.common.Metadata.created_at:1::1 of +msgid "Unix timestamp when the message was created." msgstr "" -":py:obj:`push_messages `\\ \\(messages\\)" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.push_messages:1 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "Push messages to specified node IDs." -msgstr "向指定的节点 ID 推送信息。" +msgid ":py:obj:`dst_node_id `\\" +msgstr ":py:obj:`dst_node_id `\\" -#: flwr.server.driver.driver.Driver.close:1::1 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -":py:obj:`send_and_receive `\\ " -"\\(messages\\, \\*\\[\\, timeout\\]\\)" -msgstr "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +msgid ":py:obj:`group_id `\\" +msgstr ":py:obj:`group_id `\\" -#: flwr.server.driver.driver.Driver.close:1::1 -#: flwr.server.driver.driver.Driver.send_and_receive:1 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.group_id:1 of #, fuzzy -msgid "Push messages to specified node IDs and pull the reply messages." -msgstr "向指定的节点 ID 推送信息并提取回复信息。" +msgid "An identifier for grouping messages." +msgstr "用于分组信息的标识符。" -#: flwr.server.driver.driver.Driver.create_message:3 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"This method constructs a new `Message` with given content and metadata. The " -"`run_id` and `src_node_id` will be set automatically." -msgstr "" -"本方法使用给定的内容和元数据构建新的 `Message` 。run_id \"和 \"src_node_id " -"\"将自动设置。" +msgid ":py:obj:`message_id `\\" +msgstr ":py:obj:`message_id `\\" -#: flwr.server.driver.driver.Driver.create_message:6 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"The content for the new message. This holds records that are to be sent to " -"the destination node." -msgstr "新信息的内容。其中包含要发送到目的节点的记录。" +msgid ":py:obj:`message_type `\\" +msgstr ":py:obj:`message_type `\\" -#: flwr.server.driver.driver.Driver.create_message:9 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"The type of the message, defining the action to be executed on the receiving " -"end." -msgstr "信息类型,定义接收端要执行的操作。" +msgid ":py:obj:`partition_id `\\" +msgstr ":py:obj:`partition_id `\\" -#: flwr.server.driver.driver.Driver.create_message:12 of +#: flwr.common.Metadata.created_at:1::1 +#: flwr.common.Metadata.partition_id:1 of #, fuzzy -msgid "The ID of the destination node to which the message is being sent." -msgstr "信息发送目的地节点的 ID。" +msgid "An identifier telling which data partition a ClientApp should use." +msgstr "告诉 ClientApp 应使用哪个数据分区的标识符。" -#: flwr.server.driver.driver.Driver.create_message:14 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"The ID of the group to which this message is associated. In some settings, " -"this is used as the FL round." -msgstr "与该信息相关联的组的 ID。在某些设置中,它被用作 FL 轮。" +msgid ":py:obj:`reply_to_message `\\" +msgstr ":py:obj:`reply_to_message `\\" -#: flwr.server.driver.driver.Driver.create_message:17 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"Time-to-live for the round trip of this message, i.e., the time from sending " -"this message to receiving a reply. It specifies the duration for which the " -"message and its potential reply are considered valid." -msgstr "" -"此报文往返的有效时间,即从发送此报文到收到回复的时间。它规定了信息及其潜在回" -"复被视为有效的持续时间。" +msgid ":py:obj:`run_id `\\" +msgstr ":py:obj:`run_id `\\" -#: flwr.server.driver.driver.Driver.create_message:22 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"**message** -- A new `Message` instance with the specified content and " -"metadata." -msgstr "**message** -- 具有指定内容和元数据的新 \"信息 \"实例。" +msgid ":py:obj:`src_node_id `\\" +msgstr ":py:obj:`src_node_id `\\" -#: flwr.server.driver.driver.Driver.pull_messages:3 of +#: flwr.common.Metadata.created_at:1::1 of #, fuzzy -msgid "" -"This method is used to collect messages from the SuperLink that correspond " -"to a set of given message IDs." -msgstr "该方法用于从超级链接中收集与一组给定消息 ID 相对应的消息。" +msgid ":py:obj:`ttl `\\" +msgstr ":py:obj:`ttl `\\" -#: flwr.server.driver.driver.Driver.pull_messages:6 of +#: flwr.common.Metadata.created_at:1::1 flwr.common.Metadata.ttl:1 +#: of #, fuzzy -msgid "" -"An iterable of message IDs for which reply messages are to be retrieved." -msgstr "要检索回复信息的信息 ID 的可迭代项。" +msgid "Time-to-live for this message." +msgstr "该信息的有效时间。" -#: flwr.server.driver.driver.Driver.pull_messages:9 of +#: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 #, fuzzy -msgid "**messages** -- An iterable of messages received." -msgstr "**messages** -- 收到的信息迭代。" +msgid "MetricsRecord" +msgstr "MetricsRecord" -#: flwr.server.driver.driver.Driver.push_messages:3 of +#: flwr.common.record.metricsrecord.MetricsRecord:1 of #, fuzzy msgid "" -"This method takes an iterable of messages and sends each message to the node " -"specified in `dst_node_id`." +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " +":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" +" [:py:class:`float`]]" msgstr "" -"该方法接收一个可迭代的消息,并将每条消息发送到 `dst_node_id` 中指定的节点。" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:obj:`~typing.Union`\\ [:py:class:`int`, " +":py:class:`float`, :py:class:`~typing.List`\\ [:py:class:`int`], " +":py:class:`~typing.List`\\ [:py:class:`float`]]]" -#: flwr.server.driver.driver.Driver.push_messages:6 -#: flwr.server.driver.driver.Driver.send_and_receive:7 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "An iterable of messages to be sent." -msgstr "要发送的信息迭代。" +msgid ":py:obj:`clear `\\ \\(\\)" +msgstr ":py:obj:`clear `\\ \\(\\)" -#: flwr.server.driver.driver.Driver.push_messages:9 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, which " -"can be used to pull replies." -msgstr "**message_ids** -- 已发送信息的可迭代 ID,可用于提取回复信息。" +msgid ":py:obj:`count_bytes `\\ \\(\\)" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" -#: flwr.server.driver.driver.Driver.send_and_receive:3 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "" -"This method sends a list of messages to their destination node IDs and then " -"waits for the replies. It continues to pull replies until either all replies " -"are received or the specified timeout duration is exceeded." -msgstr "" -"该方法会向目标节点 ID 发送信息列表,然后等待回复。它会继续提取回复,直到收到" -"所有回复或超过指定的超时时间。" +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -#: flwr.server.driver.driver.Driver.send_and_receive:9 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "" -"The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the method " -"will wait until replies for all messages are received." -msgstr "" -"超时时间(秒)。如果指定,该方法将在此期限内等待回复。如果指定为 \"无\",则没" -"有时间限制,该方法将等待直到收到所有信息的回复。" +msgid ":py:obj:`items `\\ \\(\\)" +msgstr ":py:obj:`items `\\ \\(\\)" -#: flwr.server.driver.driver.Driver.send_and_receive:14 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "" -"**replies** -- An iterable of reply messages received from the SuperLink." -msgstr "**replies** -- 从超级链接收到的回复信息的迭代。" +msgid ":py:obj:`keys `\\ \\(\\)" +msgstr ":py:obj:`keys `\\ \\(\\)" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "Notes" -msgstr "无" +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -#: flwr.server.driver.driver.Driver.send_and_receive:19 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy msgid "" -"This method uses `push_messages` to send the messages and `pull_messages` to " -"collect the replies. If `timeout` is set, the method may not return replies " -"for all sent messages. A message remains valid until its TTL, which is not " -"affected by `timeout`." +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" msgstr "" -"该方法使用 `push_messages` 发送信息,并使用 `pull_messages` 收集回复。如果设" -"置了 `timeout`,该方法可能不会返回所有已发送消息的回复。消息在其 TTL 之前一直" -"有效,不受 `timeout` 影响。" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" -#: ../../source/ref-api/flwr.server.History.rst:2 +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "History" -msgstr "历史" +msgid ":py:obj:`values `\\ \\(\\)" +msgstr ":py:obj:`values `\\ \\(\\)" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: ../../source/ref-api/flwr.common.NDArray.rst:2 #, fuzzy -msgid "" -":py:obj:`add_loss_centralized `\\ " -"\\(server\\_round\\, loss\\)" -msgstr "" -":py:obj:`add_loss_centralized `\\ " -"\\(server\\_round\\, loss\\)" +msgid "NDArray" +msgstr "NDArray" -#: flwr.server.history.History.add_loss_centralized:1 -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 #, fuzzy -msgid "Add one loss entry (from centralized evaluation)." -msgstr "集中评估" +msgid ":py:obj:`tensors `\\" +msgstr ":py:obj:`tensors `\\" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: ../../source/ref-api/flwr.common.Parameters.rst:29::1 #, fuzzy -msgid "" -":py:obj:`add_loss_distributed `\\ " -"\\(server\\_round\\, loss\\)" -msgstr "" -":py:obj:`add_loss_distributed `\\ " -"\\(server\\_round\\, loss\\)" +msgid ":py:obj:`tensor_type `\\" +msgstr ":py:obj:`tensor_type `\\" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_loss_distributed:1 of +#: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 #, fuzzy -msgid "Add one loss entry (from distributed evaluation)." -msgstr "增加一个损失条目(来自分布式评估)。" +msgid "ParametersRecord" +msgstr "参数" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: flwr.common.record.parametersrecord.ParametersRecord:1 of #, fuzzy msgid "" -":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" -":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" - -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_centralized:1 of -#, fuzzy -msgid "Add metrics entries (from centralized evaluation)." -msgstr "集中评估" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: flwr.common.record.parametersrecord.ParametersRecord:3 of #, fuzzy msgid "" -":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" +"A dataclass storing named Arrays in order. This means that it holds " +"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " +"viewed as an equivalent to PyTorch's state_dict, but holding serialised " +"tensors instead." msgstr "" -":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" +"按顺序存储命名数组的数据类。这意味着它以 OrderedDict[str, Array] 的形式保存条目。ParametersRecord " +"对象相当于 PyTorch 的 state_dict,但它保存的是序列化的张量。" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed:1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "Add metrics entries (from distributed evaluation)." -msgstr "定制的集中/分布式评估" +msgid ":py:obj:`clear `\\ \\(\\)" +msgstr ":py:obj:`clear `\\ \\(\\)" -#: flwr.server.history.History.add_loss_centralized:1::1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "" -":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" -msgstr "" -":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" +msgid ":py:obj:`count_bytes `\\ \\(\\)" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" -#: flwr.server.history.History.add_loss_centralized:1::1 -#: flwr.server.history.History.add_metrics_distributed_fit:1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "Add metrics entries (from distributed fit)." -msgstr "添加度量条目(来自分布式拟合)。" +msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "LegacyContext" -msgstr "遗留上下文" +msgid ":py:obj:`items `\\ \\(\\)" +msgstr ":py:obj:`items `\\ \\(\\)" -#: flwr.server.compat.legacy_context.LegacyContext:1 of +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid "Bases: :py:class:`~flwr.common.context.Context`" -msgstr "Bases: :py:class:`~flwr.common.context.Context`" +msgid ":py:obj:`keys `\\ \\(\\)" +msgstr ":py:obj:`keys `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid ":py:obj:`config `\\" -msgstr "server.strategy.Strategy" +msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid ":py:obj:`strategy `\\" -msgstr "server.strategy.Strategy" +msgid "" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" +msgstr "" +":py:obj:`update `\\ \\(\\[E\\, " +"\\]\\*\\*F\\)" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: flwr.common.record.typeddict.TypedDict.clear:1::1 of #, fuzzy -msgid ":py:obj:`client_manager `\\" -msgstr ":py:obj:`client_manager `\\" +msgid ":py:obj:`values `\\ \\(\\)" +msgstr ":py:obj:`values `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of #, fuzzy -msgid ":py:obj:`history `\\" -msgstr "server.strategy.Strategy" +msgid "" +"Note that a small amount of Bytes might also be included in this counting" +" that correspond to metadata of the serialized object (e.g. of NumPy " +"array) needed for deseralization." +msgstr "请注意,该计数中还可能包含少量字节,这些字节与序列化对象(如 NumPy 数组)的元数据相对应,需要进行去eralization。" -#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 #, fuzzy -msgid ":py:obj:`state `\\" -msgstr "server.strategy.Strategy" +msgid "ReconnectIns" +msgstr "启用 SSL 连接" -#: flwr.server.server.Server.client_manager:1::1 of +#: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 #, fuzzy -msgid ":py:obj:`client_manager `\\ \\(\\)" -msgstr ":py:obj:`client_manager `\\ \\(\\)" +msgid ":py:obj:`seconds `\\" +msgstr ":py:obj:`seconds `\\" -#: flwr.server.server.Server.client_manager:1 -#: flwr.server.server.Server.client_manager:1::1 of +#: ../../source/ref-api/flwr.common.RecordSet.rst:2 #, fuzzy -msgid "Return ClientManager." -msgstr "返回客户端(本身)。" +msgid "RecordSet" +msgstr "RecordSet" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.RecordSet.configs_records:1::1 of #, fuzzy -msgid "" -":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" -msgstr "" -":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" +msgid ":py:obj:`configs_records `\\" +msgstr ":py:obj:`configs_records `\\" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.disconnect_all_clients:1 of +#: flwr.common.RecordSet.configs_records:1 +#: flwr.common.RecordSet.configs_records:1::1 of #, fuzzy -msgid "Send shutdown signal to all clients." -msgstr "向所有客户端发送关闭信号。" +msgid "Dictionary holding ConfigsRecord instances." +msgstr "包含 ConfigsRecord 实例的字典。" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.RecordSet.configs_records:1::1 of #, fuzzy -msgid "" -":py:obj:`evaluate_round `\\ " -"\\(server\\_round\\, timeout\\)" -msgstr "" -":py:obj:`evaluate_round `\\ " -"\\(server\\_round\\, timeout\\)" +msgid ":py:obj:`metrics_records `\\" +msgstr ":py:obj:`metrics_records `\\" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.evaluate_round:1 of +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.metrics_records:1 of #, fuzzy -msgid "Validate current global model on a number of clients." -msgstr "当前(全局)模型参数。" +msgid "Dictionary holding MetricsRecord instances." +msgstr "保存 MetricsRecord 实例的字典。" -#: flwr.server.server.Server.client_manager:1::1 of +#: flwr.common.RecordSet.configs_records:1::1 of #, fuzzy -msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" -msgstr ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" +msgid ":py:obj:`parameters_records `\\" +msgstr ":py:obj:`parameters_records `\\" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit:1 of +#: flwr.common.RecordSet.configs_records:1::1 +#: flwr.common.RecordSet.parameters_records:1 of #, fuzzy -msgid "Run federated averaging for a number of rounds." -msgstr "联邦平均动量策略。" +msgid "Dictionary holding ParametersRecord instances." +msgstr "存放 ParametersRecord 实例的字典。" -#: flwr.server.server.Server.client_manager:1::1 of +#: ../../source/ref-api/flwr.common.ServerMessage.rst:2 #, fuzzy -msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\, " -"timeout\\)" -msgstr "" -":py:obj:`fit_round `\\ \\(server\\_round\\, " -"timeout\\)" +msgid "ServerMessage" +msgstr "服务器端" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.fit_round:1 of +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy -msgid "Perform a single round of federated averaging." -msgstr "本轮联邦学习。" +msgid ":py:obj:`evaluate_ins `\\" +msgstr ":py:obj:`evaluate_ins `\\" -#: flwr.server.server.Server.client_manager:1::1 of +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy -msgid "" -":py:obj:`set_max_workers `\\ " -"\\(max\\_workers\\)" -msgstr "" -":py:obj:`set_max_workers `\\ " -"\\(max\\_workers\\)" +msgid ":py:obj:`fit_ins `\\" +msgstr ":py:obj:`fit_ins `\\" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_max_workers:1 of +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy -msgid "Set the max_workers used by ThreadPoolExecutor." -msgstr "设置 ThreadPoolExecutor 使用的最大工作器数。" +msgid "" +":py:obj:`get_parameters_ins " +"`\\" +msgstr "" +":py:obj:`get_parameters_ins " +"`\\" -#: flwr.server.server.Server.client_manager:1::1 of +#: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 #, fuzzy msgid "" -":py:obj:`set_strategy `\\ \\(strategy\\)" +":py:obj:`get_properties_ins " +"`\\" msgstr "" -":py:obj:`set_strategy `\\ \\(strategy\\)" +":py:obj:`get_properties_ins " +"`\\" -#: flwr.server.server.Server.client_manager:1::1 -#: flwr.server.server.Server.set_strategy:1 of +#: ../../source/ref-api/flwr.common.Status.rst:2 #, fuzzy -msgid "Replace server strategy." -msgstr "server.strategy" +msgid "Status" +msgstr "客户端状态。" -#: ../../source/ref-api/flwr.server.ServerApp.rst:2 +#: ../../source/ref-api/flwr.common.Status.rst:29::1 #, fuzzy -msgid "ServerApp" -msgstr "服务器" +msgid ":py:obj:`code `\\" +msgstr ":py:obj:`code `\\" -#: flwr.server.server_app.ServerApp:5 of +#: ../../source/ref-api/flwr.common.Status.rst:29::1 #, fuzzy -msgid "Use the `ServerApp` with an existing `Strategy`:" -msgstr "使用现有策略" +msgid ":py:obj:`message `\\" +msgstr ":py:obj:`message `\\" -#: flwr.server.server_app.ServerApp:15 of +#: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 #, fuzzy -msgid "Use the `ServerApp` with a custom main function:" -msgstr "使用带有自定义主函数的 `ServerApp`:" +msgid "array\\_from\\_numpy" +msgstr "array\\_from\\_numpy" -#: flwr.server.server_app.ServerApp.main:1::1 of +#: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 #, fuzzy -msgid ":py:obj:`main `\\ \\(\\)" -msgstr "server.strategy.Strategy" +msgid "bytes\\_to\\_ndarray" +msgstr "bytes\\_to\\_ndarray" -#: flwr.server.server_app.ServerApp.main:1 -#: flwr.server.server_app.ServerApp.main:1::1 of +#: ../../source/ref-api/flwr.common.configure.rst:2 #, fuzzy -msgid "Return a decorator that registers the main fn with the server app." -msgstr "返回向服务器应用程序注册 main fn 的装饰器。" +msgid "configure" +msgstr "配置日志记录" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 +#: ../../source/ref-api/flwr.common.event.rst:2 #, fuzzy -msgid "ServerConfig" -msgstr "服务器" +msgid "event" +msgstr "事件" -#: flwr.server.server_config.ServerConfig:3 of +#: ../../source/ref-api/flwr.common.log.rst:2 #, fuzzy +msgid "log" +msgstr "登录" + +#: logging.Logger.log:3 of msgid "" -"All attributes have default values which allows users to configure just the " -"ones they care about." -msgstr "所有属性都有默认值,用户只需配置自己关心的属性即可。" +"To pass exception information, use the keyword argument exc_info with a " +"true value, e.g." +msgstr "要传递异常信息,请使用带 true 值的关键字参数 exc_info,例如。" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 -#, fuzzy -msgid ":py:obj:`num_rounds `\\" -msgstr ":py:obj:`num_rounds `\\" +#: logging.Logger.log:6 of +#, python-format +msgid "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" +msgstr "logger.log(level, \"We have a %s\", \"mysterious problem\", exc_info=1)" -#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +#: ../../source/ref-api/flwr.common.ndarray_to_bytes.rst:2 #, fuzzy -msgid ":py:obj:`round_timeout `\\" -msgstr ":py:obj:`round_timeout `\\" +msgid "ndarray\\_to\\_bytes" +msgstr "ndarray\\_to\\_bytes" -#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 +#: ../../source/ref-api/flwr.common.ndarrays_to_parameters.rst:2 #, fuzzy -msgid "SimpleClientManager" -msgstr "SimpleClientManager" +msgid "ndarrays\\_to\\_parameters" +msgstr "ndarrays\\_to\\_parameters" -#: flwr.server.client_manager.SimpleClientManager:1 of +#: ../../source/ref-api/flwr.common.now.rst:2 #, fuzzy -msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" -msgstr "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" +msgid "now" +msgstr "现在" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.common.parameters_to_ndarrays.rst:2 #, fuzzy -msgid ":py:obj:`all `\\ \\(\\)" -msgstr ":py:obj:`all `\\ \\(\\)" +msgid "parameters\\_to\\_ndarrays" +msgstr "parameters\\_to\\_ndarrays" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.server.rst:2 +msgid "server" +msgstr "服务器" + +#: ../../source/ref-api/flwr.server.rst:26::1 #, fuzzy -msgid "" -":py:obj:`num_available `\\ " -"\\(\\)" -msgstr "" -":py:obj:`num_available `\\ " -"\\(\\)" +msgid ":py:obj:`run_driver_api `\\ \\(\\)" +msgstr ":py:obj:`run_driver_api `\\ \\(\\)" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_driver_api:1 of #, fuzzy -msgid "" -":py:obj:`register `\\ \\(client\\)" -msgstr "" -":py:obj:`register `\\ \\(client\\)" +msgid "Run Flower server (Driver API)." +msgstr "flower-driver-api" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.server.rst:26::1 #, fuzzy -msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" -msgstr "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +msgstr ":py:obj:`run_fleet_api `\\ \\(\\)" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_fleet_api:1 of #, fuzzy -msgid "" -":py:obj:`unregister `\\ " -"\\(client\\)" -msgstr "" -":py:obj:`unregister `\\ " -"\\(client\\)" +msgid "Run Flower server (Fleet API)." +msgstr "Flower 服务器。" -#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#: ../../source/ref-api/flwr.server.rst:26::1 #, fuzzy -msgid "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\[\\, timeout\\]\\)" -msgstr "" -":py:obj:`wait_for `\\ " -"\\(num\\_clients\\[\\, timeout\\]\\)" +msgid ":py:obj:`run_server_app `\\ \\(\\)" +msgstr ":py:obj:`run_server_app `\\ \\(\\)" -#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.run_serverapp.run_server_app:1 of #, fuzzy -msgid "" -"Blocks until the requested number of clients is available or until a timeout " -"is reached. Current timeout default: 1 day." -msgstr "阻塞,直到请求的客户端数量可用或达到超时为止。当前超时默认值:1 天。" +msgid "Run Flower server app." +msgstr "Flower 服务器。" -#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of +#: ../../source/ref-api/flwr.server.rst:26::1 #, fuzzy -msgid "The number of clients to wait for." -msgstr "需要等待的客户数量。" +msgid ":py:obj:`run_superlink `\\ \\(\\)" +msgstr ":py:obj:`run_superlink `\\ \\(\\)" -#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.run_superlink:1 of #, fuzzy -msgid "The time in seconds to wait for, defaults to 86400 (24h)." -msgstr "以秒为单位的等待时间,默认为 86400(24 小时)。" +msgid "Run Flower SuperLink (Driver API and Fleet API)." +msgstr "运行 Flower 服务器(Driver API 和 Fleet API)。" -#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of +#: ../../source/ref-api/flwr.server.rst:26::1 #, fuzzy -msgid "**success**" -msgstr "**success**" +msgid "" +":py:obj:`start_server `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" +msgstr "" +":py:obj:`start_server `\\ \\(\\*\\[\\, " +"server\\_address\\, server\\, ...\\]\\)" -#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 +#: ../../source/ref-api/flwr.server.rst:26::1 +#: flwr.server.app.start_server:1 of +msgid "Start a Flower server using the gRPC transport layer." +msgstr "使用 gRPC 传输层启动 Flower 服务器。" + +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy -msgid "run\\_driver\\_api" -msgstr "flower-driver-api" +msgid ":py:obj:`ClientManager `\\ \\(\\)" +msgstr ":py:obj:`ClientManager `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.ClientManager:1 of #, fuzzy -msgid "run\\_fleet\\_api" -msgstr "run\\_fleet\\_api" +msgid "Abstract base class for managing Flower clients." +msgstr "Flower 客户端的抽象基类。" -#: ../../source/ref-api/flwr.server.run_server_app.rst:2 +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy -msgid "run\\_server\\_app" -msgstr "run\\_server\\_app" +msgid ":py:obj:`Driver `\\ \\(\\)" +msgstr ":py:obj:`run_driver_api `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.run_superlink.rst:2 +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.driver.driver.Driver:1 of #, fuzzy -msgid "run\\_superlink" -msgstr "flower-superlink" +msgid "Abstract base Driver class for the Driver API." +msgstr "Flower 客户端的抽象基类。" -#: ../../source/ref-api/flwr.server.start_driver.rst:2 +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy -msgid "start\\_driver" -msgstr "启动客户端" +msgid ":py:obj:`History `\\ \\(\\)" +msgstr ":py:obj:`History `\\ \\(\\)" -#: flwr.server.compat.app.start_driver:3 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.history.History:1 of #, fuzzy -msgid "" -"The IPv4 or IPv6 address of the Driver API server. Defaults to " -"`\"[::]:8080\"`." -msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" +msgid "History class for training and/or evaluation metrics collection." +msgstr "**hist** -- 包含训练和评估指标的对象。" -#: flwr.server.compat.app.start_driver:6 of +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy msgid "" -"A server implementation, either `flwr.server.Server` or a subclass thereof. " -"If no instance is provided, then `start_driver` will create one." +":py:obj:`LegacyContext `\\ \\(state\\[\\, " +"config\\, strategy\\, ...\\]\\)" msgstr "" -"服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例," -"`start_server` 将创建一个。" +":py:obj:`LegacyContext `\\ \\(state\\[\\, " +"config\\, strategy\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.compat.legacy_context.LegacyContext:1 of +#, fuzzy +msgid "Legacy Context." +msgstr "传承背景。" -#: flwr.server.app.start_server:9 flwr.server.compat.app.start_driver:10 -#: flwr.simulation.app.start_simulation:28 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#, fuzzy msgid "" -"Currently supported values are `num_rounds` (int, default: 1) and " -"`round_timeout` in seconds (float, default: None)." +":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " +"strategy\\]\\)" msgstr "" -"目前支持的值有:`num_rounds`(int,默认值:1)和以秒为单位的`round_timeout`" -"(float,默认值:无)。" +":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " +"strategy\\]\\)" -#: flwr.server.app.start_server:12 flwr.server.compat.app.start_driver:13 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#, fuzzy msgid "" -"An implementation of the abstract base class `flwr.server.strategy." -"Strategy`. If no strategy is provided, then `start_server` will use `flwr." -"server.strategy.FedAvg`." -msgstr "" -"抽象基类 `flwr.server.strategy.Strategy` 的实现。如果没有提供策略," -"`start_server` 将使用 `flwr.server.strategy.FedAvg`。" +":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " +"strategy\\, ...\\]\\)" +msgstr "server.strategy.Strategy" + +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_app.ServerApp:1 of +#, fuzzy +msgid "Flower ServerApp." +msgstr "Flower 服务器。" -#: flwr.server.compat.app.start_driver:17 of +#: ../../source/ref-api/flwr.server.rst:40::1 #, fuzzy msgid "" -"An implementation of the class `flwr.server.ClientManager`. If no " -"implementation is provided, then `start_driver` will use `flwr.server." -"SimpleClientManager`." +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," +" round\\_timeout\\]\\)" msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," -"`start_server` 将使用 `flwr.server.client_manager.SimpleClientManager`。" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: flwr.server.compat.app.start_driver:25 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.server_config.ServerConfig:1 of #, fuzzy -msgid "The Driver object to use." -msgstr "要使用的驱动程序对象。" +msgid "Flower server config." +msgstr "Flower 服务器。" -#: flwr.server.app.start_server:37 flwr.server.compat.app.start_driver:28 of -msgid "**hist** -- Object containing training and evaluation metrics." -msgstr "**hist** -- 包含训练和评估指标的对象。" +#: ../../source/ref-api/flwr.server.rst:40::1 +#, fuzzy +msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +msgstr ":py:obj:`SimpleClientManager `\\ \\(\\)" -#: flwr.server.compat.app.start_driver:33 of +#: ../../source/ref-api/flwr.server.rst:40::1 +#: flwr.server.client_manager.SimpleClientManager:1 of #, fuzzy -msgid "Starting a driver that connects to an insecure server:" -msgstr "启动不安全的服务器:" +msgid "Provides a pool of available clients." +msgstr "使用部分可用客户进行评估。" -#: flwr.server.compat.app.start_driver:37 of +#: ../../source/ref-api/flwr.server.rst:59::1 #, fuzzy -msgid "Starting a driver that connects to an SSL-enabled server:" -msgstr "启动支持 SSL 的服务器:" +msgid ":py:obj:`flwr.server.strategy `\\" +msgstr "server.strategy.Strategy" -#: ../../source/ref-api/flwr.server.start_server.rst:2 +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.strategy:1 of +msgid "Contains the strategy abstraction and different implementations." +msgstr "包含策略抽象和不同的实现方法。" + +#: ../../source/ref-api/flwr.server.rst:59::1 #, fuzzy -msgid "start\\_server" -msgstr "server.start_server" +msgid ":py:obj:`flwr.server.workflow `\\" +msgstr "server.strategy.Strategy" -#: flwr.server.app.start_server:3 of -msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." -msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" +#: ../../source/ref-api/flwr.server.rst:59::1 +#: flwr.server.workflow:1 of +#, fuzzy +msgid "Workflows." +msgstr "工作流程" -#: flwr.server.app.start_server:5 of -msgid "" -"A server implementation, either `flwr.server.Server` or a subclass thereof. " -"If no instance is provided, then `start_server` will create one." -msgstr "" -"服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例," -"`start_server` 将创建一个。" +#: ../../source/ref-api/flwr.server.ClientManager.rst:2 +#, fuzzy +msgid "ClientManager" +msgstr "客户端" -#: flwr.server.app.start_server:16 of -msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`. If " -"no implementation is provided, then `start_server` will use `flwr.server." -"client_manager.SimpleClientManager`." -msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," -"`start_server` 将使用 `flwr.server.client_manager.SimpleClientManager`。" +#: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy +msgid ":py:obj:`all `\\ \\(\\)" +msgstr ":py:obj:`all `\\ \\(\\)" -#: flwr.server.app.start_server:21 of -msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower " -"clients. The default should be sufficient for most models. Users who train " -"very large models might need to increase this value. Note that the Flower " -"clients need to be started with the same value (see `flwr.client." -"start_client`), otherwise clients will not know about the increased limit " -"and block larger messages." -msgstr "" -"可与 Flower 客户端交换的 gRPC 消息的最大长度:默认值对大多数模型都足够了。训" -"练超大模型的用户可能需要增加该值。请注意,Flower 客户端需要以相同的值启动(请" -"参阅 `flwr.client.start_client`),否则客户端将不知道已增加的限制并阻止更大的" -"消息。" +#: flwr.server.client_manager.ClientManager.all:1 +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.all:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "Return all available clients." +msgstr "返回所有可用客户。" -#: flwr.server.app.start_server:42 of -msgid "Starting an insecure server:" -msgstr "启动不安全的服务器:" +#: flwr.server.client_manager.ClientManager.all:1::1 of +#, fuzzy +msgid ":py:obj:`num_available `\\ \\(\\)" +msgstr ":py:obj:`num_available `\\ \\(\\)" -#: flwr.server.app.start_server:46 of -msgid "Starting an SSL-enabled server:" -msgstr "启动支持 SSL 的服务器:" +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.num_available:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.num_available:1 of +#, fuzzy +msgid "Return the number of available clients." +msgstr "返回样本大小和所需的可用客户数量。" -#: ../../source/ref-api/flwr.server.strategy.rst:2 +#: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy -msgid "strategy" -msgstr "Krum 策略。" +msgid ":py:obj:`register `\\ \\(client\\)" +msgstr ":py:obj:`register `\\ \\(client\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.register:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.register:1 of +#, fuzzy +msgid "Register Flower ClientProxy instance." +msgstr "注册 Flower ClientProxy 实例。" + +#: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" -":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.bulyan.Bulyan:1 of -msgid "Bulyan strategy." -msgstr "Bulyan 策略。" +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.sample:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.sample:1 of +#, fuzzy +msgid "Sample a number of Flower ClientProxy instances." +msgstr "取样若干 Flower ClientProxy 实例。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy -msgid "" -":py:obj:`DPFedAvgAdaptive `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\)" -msgstr "" -":py:obj:`DPFedAvgAdaptive `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\)" +msgid ":py:obj:`unregister `\\ \\(client\\)" +msgstr ":py:obj:`unregister `\\ \\(client\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of -msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." -msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.unregister:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.unregister:1 of +#, fuzzy +msgid "Unregister Flower ClientProxy instance." +msgstr "取消注册 Flower ClientProxy 实例。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 of #, fuzzy msgid "" -":py:obj:`DPFedAvgFixed `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\, timeout\\)" msgstr "" -":py:obj:`DPFedAvgFixed `\\ " -"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of -msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." -msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\, timeout\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.all:1::1 +#: flwr.server.client_manager.ClientManager.wait_for:1 +#: flwr.server.client_manager.SimpleClientManager.all:1::1 +#: flwr.server.client_manager.SimpleClientManager.wait_for:1 of #, fuzzy -msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" -msgstr "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" +msgid "Wait until at least `num_clients` are available." +msgstr "等待至少 `num_clients` 可用。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 -#: of +#: flwr.server.client_manager.ClientManager.num_available:3 +#: flwr.server.client_manager.SimpleClientManager.num_available:3 of #, fuzzy -msgid "Strategy wrapper for central DP with client-side adaptive clipping." -msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" +msgid "**num_available** -- The number of currently available clients." +msgstr "**num_available** -- 当前可用客户端的数量。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.client_manager.ClientManager.register:6 +#: flwr.server.client_manager.SimpleClientManager.register:6 of #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" -msgstr "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" +"**success** -- Indicating if registration was successful. False if " +"ClientProxy is already registered or can not be registered for any " +"reason." +msgstr "**success** -- 表示注册是否成功。如果 ClientProxy 已注册或因故无法注册,则为 False。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 -#: of +#: flwr.server.client_manager.ClientManager.unregister:3 +#: flwr.server.client_manager.SimpleClientManager.unregister:3 of #, fuzzy -msgid "Strategy wrapper for central DP with server-side adaptive clipping." -msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" +msgid "This method is idempotent." +msgstr "这种方法是幂等的。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: ../../source/ref-api/flwr.server.Driver.rst:2 +#, fuzzy +msgid "Driver" +msgstr "服务器" + +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" +":py:obj:`create_message `\\ " +"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" +":py:obj:`create_message `\\ " +"\\(content\\, message\\_type\\, ...\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 -#: of +#: flwr.server.driver.driver.Driver.create_message:1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy -msgid "Strategy wrapper for central DP with client-side fixed clipping." -msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" +msgid "Create a new message with specified parameters." +msgstr "使用指定参数创建新信息。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy -msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" -msgstr "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" +msgid ":py:obj:`get_node_ids `\\ \\(\\)" +msgstr ":py:obj:`get_node_ids `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 -#: of +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.get_node_ids:1 of #, fuzzy -msgid "Strategy wrapper for central DP with server-side fixed clipping." -msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" +msgid "Get node IDs." +msgstr "获取节点 ID。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy msgid "" -":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`pull_messages `\\ " +"\\(message\\_ids\\)" msgstr "" -":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`pull_messages `\\ " +"\\(message\\_ids\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of -msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." -msgstr "FedAdagrad 策略 - 使用 Adagrad 进行自适应联合优化。" +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.pull_messages:1 of +#, fuzzy +msgid "Pull messages based on message IDs." +msgstr "根据信息 ID 提取信息。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy msgid "" -":py:obj:`FedAdam `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`push_messages `\\ " +"\\(messages\\)" msgstr "" -":py:obj:`FedAdam `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`push_messages `\\ " +"\\(messages\\)" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedadam.FedAdam:1 of -msgid "FedAdam - Adaptive Federated Optimization using Adam." -msgstr "FedAdam - 使用 Adam 进行自适应联合优化。" +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.push_messages:1 of +#, fuzzy +msgid "Push messages to specified node IDs." +msgstr "向指定的节点 ID 推送信息。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:1::1 of #, fuzzy msgid "" -":py:obj:`FedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`send_and_receive `\\ " +"\\(messages\\, \\*\\[\\, timeout\\]\\)" msgstr "" -":py:obj:`FedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavg.FedAvg:1 -#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of -msgid "Federated Averaging strategy." -msgstr "联邦平均策略。" +#: flwr.server.driver.driver.Driver.create_message:1::1 +#: flwr.server.driver.driver.Driver.send_and_receive:1 of +#, fuzzy +msgid "Push messages to specified node IDs and pull the reply messages." +msgstr "向指定的节点 ID 推送信息并提取回复信息。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:3 of #, fuzzy msgid "" -":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" -msgstr "" -":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +"This method constructs a new `Message` with given content and metadata. " +"The `run_id` and `src_node_id` will be set automatically." +msgstr "本方法使用给定的内容和元数据构建新的 `Message` 。run_id \"和 \"src_node_id \"将自动设置。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:6 of #, fuzzy msgid "" -":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" -msgstr "" -":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedavgm.FedAvgM:1 of -msgid "Federated Averaging with Momentum strategy." -msgstr "联邦平均动量策略。" +"The content for the new message. This holds records that are to be sent " +"to the destination node." +msgstr "新信息的内容。其中包含要发送到目的节点的记录。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:9 of #, fuzzy msgid "" -":py:obj:`FedMedian `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" -msgstr "" -":py:obj:`FedMedian `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +"The type of the message, defining the action to be executed on the " +"receiving end." +msgstr "信息类型,定义接收端要执行的操作。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedmedian.FedMedian:1 of +#: flwr.server.driver.driver.Driver.create_message:12 of #, fuzzy -msgid "Configurable FedMedian strategy implementation." -msgstr "可配置的 FedAvg 策略实施。" +msgid "The ID of the destination node to which the message is being sent." +msgstr "信息发送目的地节点的 ID。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:14 of #, fuzzy msgid "" -":py:obj:`FedOpt `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" -msgstr "" -":py:obj:`FedOpt `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +"The ID of the group to which this message is associated. In some " +"settings, this is used as the FL round." +msgstr "与该信息相关联的组的 ID。在某些设置中,它被用作 FL 轮。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedopt.FedOpt:1 of +#: flwr.server.driver.driver.Driver.create_message:17 of #, fuzzy -msgid "Federated Optim strategy." -msgstr "联邦优化策略。" +msgid "" +"Time-to-live for the round trip of this message, i.e., the time from " +"sending this message to receiving a reply. It specifies in seconds the " +"duration for which the message and its potential reply are considered " +"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " +"used." +msgstr "此报文往返的有效时间,即从发送此报文到收到回复的时间。它规定了信息及其潜在回复被视为有效的持续时间。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.create_message:23 of #, fuzzy msgid "" -":py:obj:`FedProx `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" -msgstr "" -":py:obj:`FedProx `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedprox.FedProx:1 of -msgid "Federated Optimization strategy." -msgstr "联邦优化策略。" +"**message** -- A new `Message` instance with the specified content and " +"metadata." +msgstr "**message** -- 具有指定内容和元数据的新 \"信息 \"实例。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.pull_messages:3 of #, fuzzy msgid "" -":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" -msgstr "" -":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" - -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of -msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." -msgstr "带修剪均值的联邦平均法[Dong Yin 等,2021]。" +"This method is used to collect messages from the SuperLink that " +"correspond to a set of given message IDs." +msgstr "该方法用于从超级链接中收集与一组给定消息 ID 相对应的消息。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.pull_messages:6 of #, fuzzy -msgid "" -":py:obj:`FedXgbBagging `\\ " -"\\(\\[evaluate\\_function\\]\\)" -msgstr "" -":py:obj:`FedXgbBagging `\\ " -"\\(\\[evaluate\\_function\\]\\)" +msgid "An iterable of message IDs for which reply messages are to be retrieved." +msgstr "要检索回复信息的信息 ID 的可迭代项。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of +#: flwr.server.driver.driver.Driver.pull_messages:9 of #, fuzzy -msgid "Configurable FedXgbBagging strategy implementation." -msgstr "可配置的 FedXgbNAvg 策略实施。" +msgid "**messages** -- An iterable of messages received." +msgstr "**messages** -- 收到的信息迭代。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.push_messages:3 of #, fuzzy msgid "" -":py:obj:`FedXgbCyclic `\\ " -"\\(\\*\\*kwargs\\)" -msgstr "" -":py:obj:`FedXgbCyclic `\\ " -"\\(\\*\\*kwargs\\)" +"This method takes an iterable of messages and sends each message to the " +"node specified in `dst_node_id`." +msgstr "该方法接收一个可迭代的消息,并将每条消息发送到 `dst_node_id` 中指定的节点。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 -#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of +#: flwr.server.driver.driver.Driver.push_messages:6 +#: flwr.server.driver.driver.Driver.send_and_receive:7 of #, fuzzy -msgid "Configurable FedXgbCyclic strategy implementation." -msgstr "可配置的 FedAvg 策略实施。" +msgid "An iterable of messages to be sent." +msgstr "要发送的信息迭代。" -#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.driver.driver.Driver.push_messages:9 of #, fuzzy msgid "" -":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " -"\\*\\*kwargs\\)" -msgstr "" +"**message_ids** -- An iterable of IDs for the messages that were sent, " +"which can be used to pull replies." +msgstr "**message_ids** -- 已发送信息的可迭代 ID,可用于提取回复信息。" + +#: flwr.server.driver.driver.Driver.send_and_receive:3 of +#, fuzzy +msgid "" +"This method sends a list of messages to their destination node IDs and " +"then waits for the replies. It continues to pull replies until either all" +" replies are received or the specified timeout duration is exceeded." +msgstr "该方法会向目标节点 ID 发送信息列表,然后等待回复。它会继续提取回复,直到收到所有回复或超过指定的超时时间。" + +#: flwr.server.driver.driver.Driver.send_and_receive:9 of +#, fuzzy +msgid "" +"The timeout duration in seconds. If specified, the method will wait for " +"replies for this duration. If `None`, there is no time limit and the " +"method will wait until replies for all messages are received." +msgstr "超时时间(秒)。如果指定,该方法将在此期限内等待回复。如果指定为 \"无\",则没有时间限制,该方法将等待直到收到所有信息的回复。" + +#: flwr.server.driver.driver.Driver.send_and_receive:14 of +#, fuzzy +msgid "**replies** -- An iterable of reply messages received from the SuperLink." +msgstr "**replies** -- 从超级链接收到的回复信息的迭代。" + +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +#, fuzzy +msgid "Notes" +msgstr "无" + +#: flwr.server.driver.driver.Driver.send_and_receive:19 of +#, fuzzy +msgid "" +"This method uses `push_messages` to send the messages and `pull_messages`" +" to collect the replies. If `timeout` is set, the method may not return " +"replies for all sent messages. A message remains valid until its TTL, " +"which is not affected by `timeout`." +msgstr "" +"该方法使用 `push_messages` 发送信息,并使用 `pull_messages` 收集回复。如果设置了 " +"`timeout`,该方法可能不会返回所有已发送消息的回复。消息在其 TTL 之前一直有效,不受 `timeout` 影响。" + +#: ../../source/ref-api/flwr.server.History.rst:2 +#, fuzzy +msgid "History" +msgstr "历史" + +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "" +":py:obj:`add_loss_centralized " +"`\\ \\(server\\_round\\, " +"loss\\)" +msgstr "" +":py:obj:`add_loss_centralized " +"`\\ \\(server\\_round\\, " +"loss\\)" + +#: flwr.server.history.History.add_loss_centralized:1 +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "Add one loss entry (from centralized evaluation)." +msgstr "集中评估" + +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "" +":py:obj:`add_loss_distributed " +"`\\ \\(server\\_round\\, " +"loss\\)" +msgstr "" +":py:obj:`add_loss_distributed " +"`\\ \\(server\\_round\\, " +"loss\\)" + +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_loss_distributed:1 of +#, fuzzy +msgid "Add one loss entry (from distributed evaluation)." +msgstr "增加一个损失条目(来自分布式评估)。" + +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "" +":py:obj:`add_metrics_centralized " +"`\\ \\(server\\_round\\, " +"metrics\\)" +msgstr "" +":py:obj:`add_metrics_centralized " +"`\\ \\(server\\_round\\, " +"metrics\\)" + +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_centralized:1 of +#, fuzzy +msgid "Add metrics entries (from centralized evaluation)." +msgstr "集中评估" + +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "" +":py:obj:`add_metrics_distributed " +"`\\ \\(server\\_round\\, " +"metrics\\)" +msgstr "" +":py:obj:`add_metrics_distributed " +"`\\ \\(server\\_round\\, " +"metrics\\)" + +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed:1 of +#, fuzzy +msgid "Add metrics entries (from distributed evaluation)." +msgstr "定制的集中/分布式评估" + +#: flwr.server.history.History.add_loss_centralized:1::1 of +#, fuzzy +msgid "" +":py:obj:`add_metrics_distributed_fit " +"`\\ \\(server\\_round\\," +" ...\\)" +msgstr "" +":py:obj:`add_metrics_distributed_fit " +"`\\ \\(server\\_round\\," +" ...\\)" + +#: flwr.server.history.History.add_loss_centralized:1::1 +#: flwr.server.history.History.add_metrics_distributed_fit:1 of +#, fuzzy +msgid "Add metrics entries (from distributed fit)." +msgstr "添加度量条目(来自分布式拟合)。" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:2 +#, fuzzy +msgid "LegacyContext" +msgstr "遗留上下文" + +#: flwr.server.compat.legacy_context.LegacyContext:1 of +#, fuzzy +msgid "Bases: :py:class:`~flwr.common.context.Context`" +msgstr "Bases: :py:class:`~flwr.common.context.Context`" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`config `\\" +msgstr "server.strategy.Strategy" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`strategy `\\" +msgstr "server.strategy.Strategy" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`client_manager `\\" +msgstr ":py:obj:`client_manager `\\" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`history `\\" +msgstr "server.strategy.Strategy" + +#: ../../source/ref-api/flwr.server.LegacyContext.rst:32::1 +#, fuzzy +msgid ":py:obj:`state `\\" +msgstr "server.strategy.Strategy" + +#: ../../source/ref-api/flwr.server.Server.rst:2 +msgid "Server" +msgstr "服务器" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid ":py:obj:`client_manager `\\ \\(\\)" +msgstr ":py:obj:`client_manager `\\ \\(\\)" + +#: flwr.server.server.Server.client_manager:1 +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid "Return ClientManager." +msgstr "返回客户端(本身)。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid "" +":py:obj:`disconnect_all_clients " +"`\\ \\(timeout\\)" +msgstr "" +":py:obj:`disconnect_all_clients " +"`\\ \\(timeout\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.disconnect_all_clients:1 of +#, fuzzy +msgid "Send shutdown signal to all clients." +msgstr "向所有客户端发送关闭信号。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid "" +":py:obj:`evaluate_round `\\ " +"\\(server\\_round\\, timeout\\)" +msgstr "" +":py:obj:`evaluate_round `\\ " +"\\(server\\_round\\, timeout\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.evaluate_round:1 of +#, fuzzy +msgid "Validate current global model on a number of clients." +msgstr "当前(全局)模型参数。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" +msgstr ":py:obj:`fit `\\ \\(num\\_rounds\\, timeout\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit:1 of +#, fuzzy +msgid "Run federated averaging for a number of rounds." +msgstr "联邦平均动量策略。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid "" +":py:obj:`fit_round `\\ \\(server\\_round\\," +" timeout\\)" +msgstr "" +":py:obj:`fit_round `\\ \\(server\\_round\\," +" timeout\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.fit_round:1 of +#, fuzzy +msgid "Perform a single round of federated averaging." +msgstr "本轮联邦学习。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid "" +":py:obj:`set_max_workers `\\ " +"\\(max\\_workers\\)" +msgstr "" +":py:obj:`set_max_workers `\\ " +"\\(max\\_workers\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_max_workers:1 of +#, fuzzy +msgid "Set the max_workers used by ThreadPoolExecutor." +msgstr "设置 ThreadPoolExecutor 使用的最大工作器数。" + +#: flwr.server.server.Server.client_manager:1::1 of +#, fuzzy +msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +msgstr ":py:obj:`set_strategy `\\ \\(strategy\\)" + +#: flwr.server.server.Server.client_manager:1::1 +#: flwr.server.server.Server.set_strategy:1 of +#, fuzzy +msgid "Replace server strategy." +msgstr "server.strategy" + +#: ../../source/ref-api/flwr.server.ServerApp.rst:2 +#, fuzzy +msgid "ServerApp" +msgstr "服务器" + +#: flwr.server.server_app.ServerApp:5 of +#, fuzzy +msgid "Use the `ServerApp` with an existing `Strategy`:" +msgstr "使用现有策略" + +#: flwr.server.server_app.ServerApp:15 of +#, fuzzy +msgid "Use the `ServerApp` with a custom main function:" +msgstr "使用带有自定义主函数的 `ServerApp`:" + +#: flwr.server.server_app.ServerApp.main:1::1 of +#, fuzzy +msgid ":py:obj:`main `\\ \\(\\)" +msgstr "server.strategy.Strategy" + +#: flwr.server.server_app.ServerApp.main:1 +#: flwr.server.server_app.ServerApp.main:1::1 of +#, fuzzy +msgid "Return a decorator that registers the main fn with the server app." +msgstr "返回向服务器应用程序注册 main fn 的装饰器。" + +#: ../../source/ref-api/flwr.server.ServerConfig.rst:2 +#, fuzzy +msgid "ServerConfig" +msgstr "服务器" + +#: flwr.server.server_config.ServerConfig:3 of +#, fuzzy +msgid "" +"All attributes have default values which allows users to configure just " +"the ones they care about." +msgstr "所有属性都有默认值,用户只需配置自己关心的属性即可。" + +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +#, fuzzy +msgid ":py:obj:`num_rounds `\\" +msgstr ":py:obj:`num_rounds `\\" + +#: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 +#, fuzzy +msgid ":py:obj:`round_timeout `\\" +msgstr ":py:obj:`round_timeout `\\" + +#: ../../source/ref-api/flwr.server.SimpleClientManager.rst:2 +#, fuzzy +msgid "SimpleClientManager" +msgstr "SimpleClientManager" + +#: flwr.server.client_manager.SimpleClientManager:1 of +#, fuzzy +msgid "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" +msgstr "Bases: :py:class:`~flwr.server.client_manager.ClientManager`" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid ":py:obj:`all `\\ \\(\\)" +msgstr ":py:obj:`all `\\ \\(\\)" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "" +":py:obj:`num_available `\\" +" \\(\\)" +msgstr "" +":py:obj:`num_available `\\" +" \\(\\)" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "" +":py:obj:`register `\\ " +"\\(client\\)" +msgstr "" +":py:obj:`register `\\ " +"\\(client\\)" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +msgstr "" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "" +":py:obj:`unregister `\\ " +"\\(client\\)" +msgstr "" +":py:obj:`unregister `\\ " +"\\(client\\)" + +#: flwr.server.client_manager.SimpleClientManager.all:1::1 of +#, fuzzy +msgid "" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\[\\, timeout\\]\\)" +msgstr "" +":py:obj:`wait_for `\\ " +"\\(num\\_clients\\[\\, timeout\\]\\)" + +#: flwr.server.client_manager.SimpleClientManager.wait_for:3 of +#, fuzzy +msgid "" +"Blocks until the requested number of clients is available or until a " +"timeout is reached. Current timeout default: 1 day." +msgstr "阻塞,直到请求的客户端数量可用或达到超时为止。当前超时默认值:1 天。" + +#: flwr.server.client_manager.SimpleClientManager.wait_for:6 of +#, fuzzy +msgid "The number of clients to wait for." +msgstr "需要等待的客户数量。" + +#: flwr.server.client_manager.SimpleClientManager.wait_for:8 of +#, fuzzy +msgid "The time in seconds to wait for, defaults to 86400 (24h)." +msgstr "以秒为单位的等待时间,默认为 86400(24 小时)。" + +#: flwr.server.client_manager.SimpleClientManager.wait_for:11 of +#, fuzzy +msgid "**success**" +msgstr "**success**" + +#: ../../source/ref-api/flwr.server.run_driver_api.rst:2 +#, fuzzy +msgid "run\\_driver\\_api" +msgstr "flower-driver-api" + +#: ../../source/ref-api/flwr.server.run_fleet_api.rst:2 +#, fuzzy +msgid "run\\_fleet\\_api" +msgstr "run\\_fleet\\_api" + +#: ../../source/ref-api/flwr.server.run_server_app.rst:2 +#, fuzzy +msgid "run\\_server\\_app" +msgstr "run\\_server\\_app" + +#: ../../source/ref-api/flwr.server.run_superlink.rst:2 +#, fuzzy +msgid "run\\_superlink" +msgstr "flower-superlink" + +#: ../../source/ref-api/flwr.server.start_server.rst:2 +#, fuzzy +msgid "start\\_server" +msgstr "server.start_server" + +#: flwr.server.app.start_server:3 of +msgid "The IPv4 or IPv6 address of the server. Defaults to `\"[::]:8080\"`." +msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" + +#: flwr.server.app.start_server:5 of +msgid "" +"A server implementation, either `flwr.server.Server` or a subclass " +"thereof. If no instance is provided, then `start_server` will create one." +msgstr "服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例,`start_server` 将创建一个。" + +#: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of +msgid "" +"Currently supported values are `num_rounds` (int, default: 1) and " +"`round_timeout` in seconds (float, default: None)." +msgstr "目前支持的值有:`num_rounds`(int,默认值:1)和以秒为单位的`round_timeout`(float,默认值:无)。" + +#: flwr.server.app.start_server:12 of +msgid "" +"An implementation of the abstract base class " +"`flwr.server.strategy.Strategy`. If no strategy is provided, then " +"`start_server` will use `flwr.server.strategy.FedAvg`." +msgstr "" +"抽象基类 `flwr.server.strategy.Strategy` 的实现。如果没有提供策略,`start_server` 将使用 " +"`flwr.server.strategy.FedAvg`。" + +#: flwr.server.app.start_server:16 of +msgid "" +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_server` will use " +"`flwr.server.client_manager.SimpleClientManager`." +msgstr "" +"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现,`start_server` 将使用 " +"`flwr.server.client_manager.SimpleClientManager`。" + +#: flwr.server.app.start_server:21 of +msgid "" +"The maximum length of gRPC messages that can be exchanged with the Flower" +" clients. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower clients need to be started with the same value (see " +"`flwr.client.start_client`), otherwise clients will not know about the " +"increased limit and block larger messages." +msgstr "" +"可与 Flower 客户端交换的 gRPC 消息的最大长度:默认值对大多数模型都足够了。训练超大模型的用户可能需要增加该值。请注意,Flower " +"客户端需要以相同的值启动(请参阅 `flwr.client.start_client`),否则客户端将不知道已增加的限制并阻止更大的消息。" + +#: flwr.server.app.start_server:28 of +msgid "" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order: * CA certificate. * " +"server certificate. * server private key." +msgstr "" +"包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以下顺序包含三个字节元素: * CA 证书,* 服务器证书, * " +"服务器私钥。" + +#: flwr.server.app.start_server:28 of +msgid "" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order:" +msgstr "包含根证书、服务器证书和私钥的元组,用于启动启用 SSL 的安全服务器。元组应按以下顺序包含三个字节元素:" + +#: flwr.server.app.start_server:32 of +msgid "CA certificate." +msgstr "CA 证书。" + +#: flwr.server.app.start_server:33 of +msgid "server certificate." +msgstr "服务器证书。" + +#: flwr.server.app.start_server:34 of +msgid "server private key." +msgstr "服务器私人密钥。" + +#: flwr.server.app.start_server:37 of +msgid "**hist** -- Object containing training and evaluation metrics." +msgstr "**hist** -- 包含训练和评估指标的对象。" + +#: flwr.server.app.start_server:42 of +msgid "Starting an insecure server:" +msgstr "启动不安全的服务器:" + +#: flwr.server.app.start_server:46 of +msgid "Starting an SSL-enabled server:" +msgstr "启动支持 SSL 的服务器:" + +#: ../../source/ref-api/flwr.server.strategy.rst:2 +#, fuzzy +msgid "strategy" +msgstr "Krum 策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`Bulyan `\\ \\(\\*\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +msgstr "" +":py:obj:`Bulyan `\\ \\(\\*\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.bulyan.Bulyan:1 of +msgid "Bulyan strategy." +msgstr "Bulyan 策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DPFedAvgAdaptive `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\)" +msgstr "" +":py:obj:`DPFedAvgAdaptive `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive:1 of +msgid "Wrapper for configuring a Strategy for DP with Adaptive Clipping." +msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DPFedAvgFixed `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" +msgstr "" +":py:obj:`DPFedAvgFixed `\\ " +"\\(strategy\\, num\\_sampled\\_clients\\, ...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed:1 of +msgid "Wrapper for configuring a Strategy for DP with Fixed Clipping." +msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " +"`\\ " +"\\(...\\)" +msgstr "" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " +"`\\ " +"\\(...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:1 +#: of +#, fuzzy +msgid "Strategy wrapper for central DP with client-side adaptive clipping." +msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " +"`\\ " +"\\(...\\)" +msgstr "" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " +"`\\ " +"\\(...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:1 +#: of +#, fuzzy +msgid "Strategy wrapper for central DP with server-side adaptive clipping." +msgstr "用于配置具有自适应剪切功能的 DP 策略的包装器。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DifferentialPrivacyClientSideFixedClipping " +"`\\ " +"\\(...\\)" +msgstr "" +":py:obj:`DifferentialPrivacyClientSideFixedClipping " +"`\\ " +"\\(...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:1 +#: of +#, fuzzy +msgid "Strategy wrapper for central DP with client-side fixed clipping." +msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`DifferentialPrivacyServerSideFixedClipping " +"`\\ " +"\\(...\\)" +msgstr "" +":py:obj:`DifferentialPrivacyServerSideFixedClipping " +"`\\ " +"\\(...\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:1 +#: of +#, fuzzy +msgid "Strategy wrapper for central DP with server-side fixed clipping." +msgstr "封装器,用于为具有固定剪切功能的 DP 配置策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedAdagrad `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadagrad.FedAdagrad:1 of +msgid "FedAdagrad strategy - Adaptive Federated Optimization using Adagrad." +msgstr "FedAdagrad 策略 - 使用 Adagrad 进行自适应联合优化。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedAdam `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedAdam `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedadam.FedAdam:1 of +msgid "FedAdam - Adaptive Federated Optimization using Adam." +msgstr "FedAdam - 使用 Adam 进行自适应联合优化。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +msgstr "" +":py:obj:`FedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavg.FedAvg:1 +#: flwr.server.strategy.fedavg_android.FedAvgAndroid:1 of +msgid "Federated Averaging strategy." +msgstr "联邦平均策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedAvgAndroid `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedAvgAndroid `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedAvgM `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedavgm.FedAvgM:1 of +msgid "Federated Averaging with Momentum strategy." +msgstr "联邦平均动量策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedMedian `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedMedian `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedmedian.FedMedian:1 of +#, fuzzy +msgid "Configurable FedMedian strategy implementation." +msgstr "可配置的 FedAvg 策略实施。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +msgstr "" +":py:obj:`FedOpt `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedopt.FedOpt:1 of +#, fuzzy +msgid "Federated Optim strategy." +msgstr "联邦优化策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedProx `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedProx `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedprox.FedProx:1 of +msgid "Federated Optimization strategy." +msgstr "联邦优化策略。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedTrimmedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +msgstr "" +":py:obj:`FedTrimmedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedtrimmedavg.FedTrimmedAvg:1 of +msgid "Federated Averaging with Trimmed Mean [Dong Yin, et al., 2021]." +msgstr "带修剪均值的联邦平均法[Dong Yin 等,2021]。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedXgbBagging `\\ " +"\\(\\[evaluate\\_function\\]\\)" +msgstr "" +":py:obj:`FedXgbBagging `\\ " +"\\(\\[evaluate\\_function\\]\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_bagging.FedXgbBagging:1 of +#, fuzzy +msgid "Configurable FedXgbBagging strategy implementation." +msgstr "可配置的 FedXgbNAvg 策略实施。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedXgbCyclic `\\ " +"\\(\\*\\*kwargs\\)" +msgstr "" +":py:obj:`FedXgbCyclic `\\ " +"\\(\\*\\*kwargs\\)" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic:1 of +#, fuzzy +msgid "Configurable FedXgbCyclic strategy implementation." +msgstr "可配置的 FedAvg 策略实施。" + +#: ../../source/ref-api/flwr.server.strategy.rst:45::1 +#, fuzzy +msgid "" +":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " +"\\*\\*kwargs\\)" +msgstr "" ":py:obj:`FedXgbNnAvg `\\ \\(\\*args\\, " "\\*\\*kwargs\\)" @@ -11553,11 +12267,13 @@ msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`FaultTolerantFedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg " +"`\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" -":py:obj:`FaultTolerantFedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg " +"`\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg:1 of @@ -11567,11 +12283,11 @@ msgstr "可配置的容错 FedAvg 策略实施。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" -":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.krum.Krum:1 of @@ -11582,11 +12298,11 @@ msgstr "FedYogi [Reddi 等人,2020] 策略。" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #, fuzzy msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " -"qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " +"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " -"qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " +"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 #: flwr.server.strategy.qfedavg.QFedAvg:1 of @@ -11756,8 +12472,8 @@ msgstr "初始全局模型参数。" #: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of the " -"Bulyan (e.g., Krum)" +"Byzantine resilient aggregation rule that is used as the first step of " +"the Bulyan (e.g., Krum)" msgstr "Byzantine弹性聚合规则,用作 Bulyan 的第一步(如 Krum)" #: flwr.server.strategy.bulyan.Bulyan:29 of @@ -11767,11 +12483,13 @@ msgstr "第一聚类规则的参数" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11801,11 +12519,13 @@ msgstr "使用 Bulyan 技术汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.configure_evaluate:1 @@ -11890,11 +12610,13 @@ msgstr "使用评估函数评估模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -11911,11 +12633,13 @@ msgstr "初始化全局模型参数。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -11932,11 +12656,11 @@ msgstr "使用部分可用客户进行评估。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -11969,11 +12693,13 @@ msgstr "该类已被弃用,将在以后的版本中删除。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -11993,11 +12719,13 @@ msgstr "使用给定的策略汇总评估损失。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12009,11 +12737,13 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_evaluate:1 of @@ -12024,11 +12754,13 @@ msgstr "使用指定策略配置下一轮评估。" #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of @@ -12050,19 +12782,20 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "" -"Evaluate model parameters using an evaluation function from the strategy." +msgid "Evaluate model parameters using an evaluation function from the strategy." msgstr "使用策略中的评估函数评估模型参数。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.initialize_parameters:1 @@ -12100,14 +12833,13 @@ msgstr "客户端管理器,用于管理当前连接的所有客户端。" msgid "" "**evaluate_configuration** -- A list of tuples. Each tuple in the list " "identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this list, " -"it means that this `ClientProxy` will not participate in the next round of " -"federated evaluation." +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated evaluation." msgstr "" -"**evaluate_configuration** -- 一个元组列表。列表中的每个元组都标识了一个" -"`ClientProxy`和该特定`ClientProxy`的`EvaluateIns`。如果某个特定的 " -"`ClientProxy` 未包含在此列表中,则表示该 `ClientProxy` 将不参与下一轮联合评" -"估。" +"**evaluate_configuration** -- " +"一个元组列表。列表中的每个元组都标识了一个`ClientProxy`和该特定`ClientProxy`的`EvaluateIns`。如果某个特定的" +" `ClientProxy` 未包含在此列表中,则表示该 `ClientProxy` 将不参与下一轮联合评估。" #: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 msgid "DPFedAvgFixed" @@ -12128,20 +12860,24 @@ msgstr "Bases: :py:class:`~flwr.server.strategy.strategy.Strategy`" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12153,26 +12889,31 @@ msgstr "使用非加权汇总法汇总训练结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -"Configure the next round of training incorporating Differential Privacy (DP)." +"Configure the next round of training incorporating Differential Privacy " +"(DP)." msgstr "配置包含差分隐私 (DP) 的下一轮训练。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12189,29 +12930,31 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -"Configuration of the next training round includes information related to DP, " -"such as clip norm and noise stddev." +"Configuration of the next training round includes information related to " +"DP, such as clip norm and noise stddev." msgstr "下一轮训练的配置包括与 DP 相关的信息,如片段规范和噪声 stddev。" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 #: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list identifies " -"a `ClientProxy` and the `FitIns` for this particular `ClientProxy`. If a " -"particular `ClientProxy` is not included in this list, it means that this " -"`ClientProxy` will not participate in the next round of federated learning." +"**fit_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `FitIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated learning." msgstr "" -"**fit_configuration** -- 一个元组列表。列表中的每个元组都标识了一个" -"`ClientProxy`和该特定`ClientProxy`的`FitIns'。如果某个特定的`ClientProxy`不在" -"此列表中,则表示该`ClientProxy`将不参加下一轮联合学习。" +"**fit_configuration** -- " +"一个元组列表。列表中的每个元组都标识了一个`ClientProxy`和该特定`ClientProxy`的`FitIns'。如果某个特定的`ClientProxy`不在此列表中,则表示该`ClientProxy`将不参加下一轮联合学习。" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 #, fuzzy @@ -12230,12 +12973,13 @@ msgstr "在客户端使用 \"adaptiveclipping_mod \"修改器。" msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `adaptiveclipping_mod`." +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " +"happen on the client-side, usually by using the built-in " +"`adaptiveclipping_mod`." msgstr "" -"与在服务器端执行剪切的 `DifferentialPrivacyServerSideAdaptiveClipping` 相比," -"`DifferentialPrivacyClientSideAdaptiveClipping` 希望在客户端进行剪切,通常使" -"用内置的 `adaptiveclipping_mod`。" +"与在服务器端执行剪切的 `DifferentialPrivacyServerSideAdaptiveClipping` " +"相比,`DifferentialPrivacyClientSideAdaptiveClipping` 希望在客户端进行剪切,通常使用内置的 " +"`adaptiveclipping_mod`。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:3 @@ -12275,8 +13019,7 @@ msgstr "剪切规范的初始值。默认为 0.1。安德鲁等人建议设置 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of #, fuzzy -msgid "" -"The desired quantile of updates which should be clipped. Defaults to 0.5." +msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "需要剪切的更新量化值。默认为 0.5。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 @@ -12284,19 +13027,17 @@ msgstr "需要剪切的更新量化值。默认为 0.5。" #: of #, fuzzy msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. Andrew " -"et al. recommends to set to 0.2." +"The learning rate for the clipping norm adaptation. Defaults to 0.2. " +"Andrew et al. recommends to set to 0.2." msgstr "剪切规范适应的学习率。默认为 0.2。安德鲁等人建议设置为 0.2。" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of #, fuzzy msgid "" -"The stddev of the noise added to the count of updates currently below the " -"estimate. Andrew et al. recommends to set to `expected_num_records/20`" -msgstr "" -"添加到当前低于估计值的更新计数中的噪声的 stddev。安德鲁等人建议设置为 " -"\"expected_num_records/20" +"The stddev of the noise added to the count of updates currently below the" +" estimate. Andrew et al. recommends to set to `expected_num_records/20`" +msgstr "添加到当前低于估计值的更新计数中的噪声的 stddev。安德鲁等人建议设置为 \"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:23 @@ -12311,10 +13052,9 @@ msgstr "server.strategy" #: of #, fuzzy msgid "" -"Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` " -"wrapper:" -msgstr "" -"用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" +"Wrap the strategy with the " +"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" +msgstr "用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 #: of @@ -12326,25 +13066,25 @@ msgstr "在客户端,将 \"adaptiveclipping_mod \"添加到客户端模块中 #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_fit:1 @@ -12359,49 +13099,49 @@ msgstr "汇总 DPFedAvgFixed 中的训练结果并更新片段标准。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 #, fuzzy @@ -12420,22 +13160,21 @@ msgstr "在客户端使用 `fixedclipping_mod` 修改器。" msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen on " -"the client-side, usually by using the built-in `fixedclipping_mod`." +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" -"与在服务器端执行剪切的 \"DifferentialPrivacyServerSideFixedClipping \"相" -"比,\"DifferentialPrivacyClientSideFixedClipping \"希望在客户端进行剪切,通常" -"是使用内置的 \"fixedclipping_mod\"。" +"与在服务器端执行剪切的 \"DifferentialPrivacyServerSideFixedClipping " +"\"相比,\"DifferentialPrivacyClientSideFixedClipping \"希望在客户端进行剪切,通常是使用内置的 " +"\"fixedclipping_mod\"。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of #, fuzzy msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A value " -"of 1.0 or higher is recommended for strong privacy." -msgstr "" -"模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" +"The noise multiplier for the Gaussian mechanism for model updates. A " +"value of 1.0 or higher is recommended for strong privacy." +msgstr "模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 @@ -12462,25 +13201,25 @@ msgstr "在客户端,将 \"fixedclipping_mod \"添加到客户端模块中:" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_fit:1 @@ -12493,49 +13232,49 @@ msgstr "然后将汇总结果序列化:" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 #, fuzzy @@ -12546,11 +13285,10 @@ msgstr "DifferentialPrivacyServerSideAdaptiveClipping" #: of #, fuzzy msgid "" -"The standard deviation of the noise added to the count of updates below the " -"estimate. Andrew et al. recommends to set to `expected_num_records/20`" -msgstr "" -"添加到低于估计值的更新计数中的噪声标准偏差。安德鲁等人建议设置为 " -"\"expected_num_records/20" +"The standard deviation of the noise added to the count of updates below " +"the estimate. Andrew et al. recommends to set to " +"`expected_num_records/20`" +msgstr "添加到低于估计值的更新计数中的噪声标准偏差。安德鲁等人建议设置为 \"expected_num_records/20" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 #: of @@ -12564,73 +13302,73 @@ msgstr "用 DifferentialPrivacyServerSideAdaptiveClipping 封装器封装策略" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 #, fuzzy @@ -12641,32 +13379,33 @@ msgstr "差分隐私" #: of #, fuzzy msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " +"wrapper" msgstr "用 DifferentialPrivacyServerSideFixedClipping 封装器封装策略" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:1 @@ -12679,49 +13418,49 @@ msgstr "计算更新、剪辑并将其传递给聚合。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 #: of @@ -12738,21 +13477,25 @@ msgstr "server.strategy.FaultTolerantFedAvg" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_fit:1 @@ -12774,21 +13517,25 @@ msgstr "使用加权平均法汇总拟合结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of @@ -12804,34 +13551,40 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:839 +#: ../../source/ref-changelog.md:905 msgid "FedAdagrad" msgstr "FedAdagrad" @@ -12882,38 +13635,42 @@ msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\" +" \\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\" +" \\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12927,29 +13684,35 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 #, fuzzy @@ -12969,11 +13732,13 @@ msgstr "第二动量参数。默认为 0.99。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -12987,11 +13752,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13014,28 +13781,34 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvg.rst:2 @@ -13052,8 +13825,8 @@ msgstr "实施基于 https://arxiv.org/abs/1602.05629" #: of msgid "" "Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will still " -"be sampled. Defaults to 1.0." +"larger than `fraction_fit * available_clients`, `min_fit_clients` will " +"still be sampled. Defaults to 1.0." msgstr "" "训练过程中使用的客户端比例。如果 `min_fit_clients` 大于 `fraction_fit * " "available_clients`,则仍会对 `min_fit_clients` 进行采样。默认为 1.0。" @@ -13061,13 +13834,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -"Fraction of clients used during validation. In case `min_evaluate_clients` " -"is larger than `fraction_evaluate * available_clients`, " -"`min_evaluate_clients` will still be sampled. Defaults to 1.0." +"Fraction of clients used during validation. In case " +"`min_evaluate_clients` is larger than `fraction_evaluate * " +"available_clients`, `min_evaluate_clients` will still be sampled. " +"Defaults to 1.0." msgstr "" -"验证过程中使用的客户端的比例。如果 `min_evaluate_clients` 大于 " -"`fraction_evaluate * available_clients`,则仍会对 `min_evaluate_clients` 进行" -"采样。默认为 1.0。" +"验证过程中使用的客户端的比例。如果 `min_evaluate_clients` 大于 `fraction_evaluate * " +"available_clients`,则仍会对 `min_evaluate_clients` 进行采样。默认为 1.0。" #: flwr.server.strategy.fedavg.FedAvg:33 of #, fuzzy @@ -13077,11 +13850,13 @@ msgstr "启用(真)或禁用(假)模型更新的就地聚合。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13095,11 +13870,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13122,29 +13899,33 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 #, fuzzy @@ -13155,31 +13936,35 @@ msgstr "DPFedAvgAdaptive" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray " +"`\\ \\(tensor\\)" msgstr "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray " +"`\\ \\(tensor\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.bytes_to_ndarray:1 of @@ -13191,20 +13976,24 @@ msgstr "从字节反序列化 NumPy ndarray。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -13221,21 +14010,23 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes " +"`\\ \\(ndarray\\)" msgstr "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes " +"`\\ \\(ndarray\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarray_to_bytes:1 of @@ -13247,41 +14038,49 @@ msgstr "将 NumPy ndarray 序列化为字节。" #: of #, fuzzy msgid "" -":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters " +"`\\ " +"\\(ndarrays\\)" msgstr "" -":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters " +"`\\ " +"\\(ndarrays\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" +":py:obj:`parameters_to_ndarrays " +"`\\ " +"\\(parameters\\)" msgstr "" -":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" +":py:obj:`parameters_to_ndarrays " +"`\\ " +"\\(parameters\\)" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: flwr.server.strategy.fedavg_android.FedAvgAndroid.parameters_to_ndarrays:1 @@ -13302,7 +14101,8 @@ msgstr "实施基于 https://arxiv.org/pdf/1909.06335.pdf" #: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to 1.0." +"Server-side learning rate used in server-side optimization. Defaults to " +"1.0." msgstr "服务器端优化中使用的服务器端学习率。默认为 1.0。" #: flwr.server.strategy.fedavgm.FedAvgM:28 of @@ -13312,11 +14112,13 @@ msgstr "用于 FedAvgM 的服务器端动量因子。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13330,11 +14132,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13357,28 +14161,34 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedMedian.rst:2 @@ -13389,11 +14199,13 @@ msgstr "联邦医保" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13412,11 +14224,13 @@ msgstr "使用中位数汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13439,28 +14253,34 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedOpt.rst:2 @@ -13479,11 +14299,13 @@ msgstr "第二动量参数。默认为 0.0。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13497,11 +14319,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13524,29 +14348,33 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 #, fuzzy @@ -13559,12 +14387,10 @@ msgstr "实施基于 https://arxiv.org/abs/1812.06127" #: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"The strategy in itself will not be different than FedAvg, the client needs " -"to be adjusted. A proximal term needs to be added to the loss function " -"during the training:" -msgstr "" -"策略本身与 FedAvg 并无不同,客户端需要进行调整。在训练过程中,需要在损失函数" -"中添加一个近端项:" +"The strategy in itself will not be different than FedAvg, the client " +"needs to be adjusted. A proximal term needs to be added to the loss " +"function during the training:" +msgstr "策略本身与 FedAvg 并无不同,客户端需要进行调整。在训练过程中,需要在损失函数中添加一个近端项:" #: flwr.server.strategy.fedprox.FedProx:9 of msgid "" @@ -13598,20 +14424,22 @@ msgstr "其中,\"global_params \"是训练前的参数副本。" msgid "" "The weight of the proximal term used in the optimization. 0.0 makes this " "strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to be " -"closer to the server parameters during training)." +"regularization will be used (that is, the client parameters will need to " +"be closer to the server parameters during training)." msgstr "" -"优化中使用的近端项权重。0.0 使该策略等同于 FedAvg,系数越大,使用的正则化就越" -"多(也就是说,在训练过程中,客户端参数需要更接近服务器参数)。" +"优化中使用的近端项权重。0.0 使该策略等同于 " +"FedAvg,系数越大,使用的正则化就越多(也就是说,在训练过程中,客户端参数需要更接近服务器参数)。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13625,11 +14453,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -13652,28 +14482,34 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedprox.FedProx.configure_fit:3 of @@ -13697,19 +14533,23 @@ msgstr "截取分布两个尾部的分数。默认为 0.2。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 @@ -13720,19 +14560,23 @@ msgstr "使用修剪平均值汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13747,29 +14591,35 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 #, fuzzy @@ -13780,11 +14630,13 @@ msgstr "FedXgbBagging" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 @@ -13799,10 +14651,12 @@ msgstr "采用加权平均法计算评估损失总额。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 @@ -13817,20 +14671,24 @@ msgstr "使用 Bulyan 技术汇总拟合结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 @@ -13847,31 +14705,37 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 #, fuzzy @@ -13882,41 +14746,49 @@ msgstr "FedXgbCyclic" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\," +" results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\," +" results\\, failures\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of @@ -13932,31 +14804,37 @@ msgstr "" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 #, fuzzy @@ -13967,46 +14845,55 @@ msgstr "DP-FedAvg" #, fuzzy msgid "" "This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +"Baselines: " +"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" -"该策略已被弃用,但在 Flower Baselines: https://github.com/adap/flower/tree/" -"main/baselines/hfedxgboost 中有其副本。" +"该策略已被弃用,但在 Flower Baselines: " +"https://github.com/adap/flower/tree/main/baselines/hfedxgboost 中有其副本。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\, " +"results\\, failures\\)" msgstr "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\, " +"results\\, failures\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14020,29 +14907,35 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 #, fuzzy @@ -14067,11 +14960,13 @@ msgstr "控制算法的适应度。默认为 1e-9。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14085,11 +14980,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14112,28 +15009,34 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Krum.rst:2 @@ -14148,20 +15051,20 @@ msgstr "实施基于 https://arxiv.org/abs/2304.07537。" #: flwr.server.strategy.krum.Krum:17 of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in " -"that case classical Krum is applied." -msgstr "" -"求平均值前保留的客户端数量(MultiKrum)。默认值为 0,在这种情况下会应用经典 " -"Krum。" +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" +" that case classical Krum is applied." +msgstr "求平均值前保留的客户端数量(MultiKrum)。默认值为 0,在这种情况下会应用经典 Krum。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14180,11 +15083,13 @@ msgstr "使用 Krum 汇总拟合结果。" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14207,20 +15112,24 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14239,11 +15148,13 @@ msgstr "DP-FedAvg" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14257,11 +15168,13 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy @@ -14284,28 +15197,34 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of #, fuzzy msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.Strategy.rst:2 @@ -14317,11 +15236,13 @@ msgstr "Krum 策略。" #: of #, fuzzy msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -14348,11 +15269,13 @@ msgstr "汇总训练结果。" #: of #, fuzzy msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of @@ -14383,11 +15306,13 @@ msgstr "评估当前的模型参数。" #: of #, fuzzy msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: flwr.server.strategy.strategy.Strategy.initialize_parameters:1 of @@ -14396,22 +15321,19 @@ msgstr "初始化(全局)模型参数。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Successful updates from the previously selected and configured clients. Each " -"pair of `(ClientProxy, FitRes` constitutes a successful update from one of " -"the previously selected clients. Not that not all previously selected " -"clients are necessarily included in this list: a client might drop out and " -"not submit a result. For each client that did not submit an update, there " -"should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " +"one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -"从先前选定和配置的客户端进行的成功更新。每一对`(ClientProxy, FitRes)`都是来自" -"先前选定客户端的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表" -"中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,`failures`中" -"都应该有一个`Exception`。" +"从先前选定和配置的客户端进行的成功更新。每一对`(ClientProxy, " +"FitRes)`都是来自先前选定客户端的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,`failures`中都应该有一个`Exception`。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "" -"Exceptions that occurred while the server was waiting for client updates." +msgid "Exceptions that occurred while the server was waiting for client updates." msgstr "服务器等待客户端更新时发生的异常。" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of @@ -14422,31 +15344,29 @@ msgstr "**aggregation_result** -- 汇总的评估结果。聚合通常使用某 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Successful updates from the previously selected and configured clients. Each " -"pair of `(ClientProxy, FitRes)` constitutes a successful update from one of " -"the previously selected clients. Not that not all previously selected " -"clients are necessarily included in this list: a client might drop out and " -"not submit a result. For each client that did not submit an update, there " -"should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" +" one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" -"来自先前选定和配置的客户端的成功更新。每一对`(ClientProxy, FitRes)`都构成先前" -"选定的客户端之一的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表" -"中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,\"失败 \"中都" -"应该有一个 \"异常\"。" +"来自先前选定和配置的客户端的成功更新。每一对`(ClientProxy, " +"FitRes)`都构成先前选定的客户端之一的一次成功更新。但并非所有先前选定的客户机都一定包含在此列表中:客户机可能会退出,不提交结果。对于每个没有提交更新的客户端,\"失败" +" \"中都应该有一个 \"异常\"。" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the previous " -"parameters with the ones returned from this method). If `None` is returned " -"(e.g., because there were only failures and no viable results) then the " -"server will no update the previous model parameters, the updates received in " -"this round are discarded, and the global model parameters remain the same." +"these as the new global model parameters (i.e., it will replace the " +"previous parameters with the ones returned from this method). If `None` " +"is returned (e.g., because there were only failures and no viable " +"results) then the server will no update the previous model parameters, " +"the updates received in this round are discarded, and the global model " +"parameters remain the same." msgstr "" -"**parameters** -- 如果返回参数,那么服务器将把这些参数作为新的全局模型参数" -"(即用本方法返回的参数替换之前的参数)。如果返回 \"无\"(例如,因为只有失败而" -"没有可行的结果),那么服务器将不再更新之前的模型参数,本轮收到的更新将被丢" -"弃,全局模型参数保持不变。" +"**parameters** -- 如果返回参数,那么服务器将把这些参数作为新的全局模型参数(即用本方法返回的参数替换之前的参数)。如果返回 " +"\"无\"(例如,因为只有失败而没有可行的结果),那么服务器将不再更新之前的模型参数,本轮收到的更新将被丢弃,全局模型参数保持不变。" #: flwr.server.strategy.strategy.Strategy.evaluate:3 of msgid "" @@ -14456,18 +15376,16 @@ msgstr "该函数可用于对模型参数进行集中(即服务器端)评估 #: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple containing " -"loss and a dictionary containing task-specific metrics (e.g., accuracy)." -msgstr "" -"**evaluation_result** -- 评估结果,通常是一个元组,包含损失值和一个字典,字典" -"中包含特定任务的指标(如准确率)。" +"**evaluation_result** -- The evaluation result, usually a Tuple " +"containing loss and a dictionary containing task-specific metrics (e.g., " +"accuracy)." +msgstr "**evaluation_result** -- 评估结果,通常是一个元组,包含损失值和一个字典,字典中包含特定任务的指标(如准确率)。" #: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " "these as the initial global model parameters." -msgstr "" -"**parameters** -- 如果返回参数,服务器将把这些参数视为初始全局模型参数。" +msgstr "**parameters** -- 如果返回参数,服务器将把这些参数视为初始全局模型参数。" #: ../../source/ref-api/flwr.server.workflow.rst:2 #, fuzzy @@ -14534,25 +15452,22 @@ msgstr "工作流程" #: of #, fuzzy msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors owned " -"by multiple parties, without accessing any individual integer vector. This " -"workflow allows the server to compute the weighted average of model " -"parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and a " -"weighted version of the locally updated parameters, both of which are masked " -"for privacy. Specifically, each client uploads \"[w, w * params]\" with " -"masks, where weighting factor 'w' is the number of examples ('num_examples') " -"and 'params' represents the model parameters ('parameters') from the " -"client's `FitRes`. The server then aggregates these contributions to compute " -"the weighted average of model parameters." -msgstr "" -"SecAgg+ 协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向" -"量。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持" -"私密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保" -"护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * " -"params]\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客" -"户端 \"FitRes \"中的模型参数(\"parameters\")。然后,服务器会汇总这些贡献," -"计算模型参数的加权平均值。" +"The SecAgg+ protocol ensures the secure summation of integer vectors " +"owned by multiple parties, without accessing any individual integer " +"vector. This workflow allows the server to compute the weighted average " +"of model parameters across all clients, ensuring individual contributions" +" remain private. This is achieved by clients sending both, a weighting " +"factor and a weighted version of the locally updated parameters, both of " +"which are masked for privacy. Specifically, each client uploads \"[w, w *" +" params]\" with masks, where weighting factor 'w' is the number of " +"examples ('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." +msgstr "" +"SecAgg+ " +"协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向量。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持私密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w," +" w * params]\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " +"\"FitRes \"中的模型参数(\"parameters\")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 #: of @@ -14561,9 +15476,7 @@ msgid "" "The protocol involves four main stages: - 'setup': Send SecAgg+ " "configuration to clients and collect their public keys. - 'share keys': " "Broadcast public keys among clients and collect encrypted secret" -msgstr "" -"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg+ 配置并收集其公钥。- 共" -"享密钥\": 在客户端之间广播公钥,并收集加密密钥。" +msgstr "协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg+ 配置并收集其公钥。- 共享密钥\": 在客户端之间广播公钥,并收集加密密钥。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:17 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:17 @@ -14595,53 +15508,45 @@ msgstr "解密\": 收集密钥共享,解密并汇总模型参数。" #: of #, fuzzy msgid "" -"Only the aggregated model parameters are exposed and passed to `Strategy." -"aggregate_fit`, ensuring individual data privacy." -msgstr "" -"只有聚合模型参数才会公开并传递给 `Strategy.aggregate_fit`,从而确保个人数据隐" -"私。" +"Only the aggregated model parameters are exposed and passed to " +"`Strategy.aggregate_fit`, ensuring individual data privacy." +msgstr "只有聚合模型参数才会公开并传递给 `Strategy.aggregate_fit`,从而确保个人数据隐私。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of #, fuzzy msgid "" -"The number of shares into which each client's private key is split under the " -"SecAgg+ protocol. If specified as a float, it represents the proportion of " -"all selected clients, and the number of shares will be set dynamically in " -"the run time. A private key can be reconstructed from these shares, allowing " -"for the secure aggregation of model updates. Each client sends one share to " -"each of its neighbors while retaining one." +"The number of shares into which each client's private key is split under " +"the SecAgg+ protocol. If specified as a float, it represents the " +"proportion of all selected clients, and the number of shares will be set " +"dynamically in the run time. A private key can be reconstructed from " +"these shares, allowing for the secure aggregation of model updates. Each " +"client sends one share to each of its neighbors while retaining one." msgstr "" -"在 SecAgg+ 协议下,每个客户的私钥被分成的份数。如果指定为浮点数,则代表所有选" -"定客户的比例,份额数将在运行时动态设置。私钥可以从这些份额中重建,从而实现模" -"型更新的安全聚合。每个客户端向其每个邻居发送一份,同时保留一份。" +"在 SecAgg+ " +"协议下,每个客户的私钥被分成的份数。如果指定为浮点数,则代表所有选定客户的比例,份额数将在运行时动态设置。私钥可以从这些份额中重建,从而实现模型更新的安全聚合。每个客户端向其每个邻居发送一份,同时保留一份。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 #: of #, fuzzy msgid "" -"The minimum number of shares required to reconstruct a client's private key, " -"or, if specified as a float, it represents the proportion of the total " -"number of shares needed for reconstruction. This threshold ensures privacy " -"by allowing for the recovery of contributions from dropped clients during " -"aggregation, without compromising individual client data." -msgstr "" -"重建客户私钥所需的最小份数,如果指定为浮动,则表示重建所需的份数占总份数的比" -"例。这个阈值允许在聚合过程中恢复掉线客户的贡献,从而确保隐私,而不会泄露单个" -"客户的数据。" +"The minimum number of shares required to reconstruct a client's private " +"key, or, if specified as a float, it represents the proportion of the " +"total number of shares needed for reconstruction. This threshold ensures " +"privacy by allowing for the recovery of contributions from dropped " +"clients during aggregation, without compromising individual client data." +msgstr "重建客户私钥所需的最小份数,如果指定为浮动,则表示重建所需的份数占总份数的比例。这个阈值允许在聚合过程中恢复掉线客户的贡献,从而确保隐私,而不会泄露单个客户的数据。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 #: of #, fuzzy msgid "" -"The maximum value of the weight that can be assigned to any single client's " -"update during the weighted average calculation on the server side, e.g., in " -"the FedAvg algorithm." -msgstr "" -"在服务器端进行加权平均计算(如 FedAvg 算法)时,可分配给任何单个客户端更新的" -"权重的最大值。" +"The maximum value of the weight that can be assigned to any single " +"client's update during the weighted average calculation on the server " +"side, e.g., in the FedAvg algorithm." +msgstr "在服务器端进行加权平均计算(如 FedAvg 算法)时,可分配给任何单个客户端更新的权重的最大值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:42 @@ -14649,11 +15554,9 @@ msgstr "" #, fuzzy msgid "" "The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within [-" -"clipping_range, clipping_range], facilitating quantization." -msgstr "" -"量化前模型参数的裁剪范围。该参数可确保每个模型参数都在 [-clipping_range, " -"clipping_range] 范围内,便于量化。" +"This parameter ensures each model parameter is bounded within " +"[-clipping_range, clipping_range], facilitating quantization." +msgstr "量化前模型参数的裁剪范围。该参数可确保每个模型参数都在 [-clipping_range, clipping_range] 范围内,便于量化。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:46 @@ -14664,9 +15567,7 @@ msgid "" "quantized, mapping each parameter to an integer in [0, " "quantization_range-1]. This facilitates cryptographic operations on the " "model updates." -msgstr "" -"浮点模型参数量化范围的大小,将每个参数映射为 [0, quantization_range-1] 中的整" -"数。这有助于对模型更新进行加密操作。" +msgstr "浮点模型参数量化范围的大小,将每个参数映射为 [0, quantization_range-1] 中的整数。这有助于对模型更新进行加密操作。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:43 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:50 @@ -14674,42 +15575,36 @@ msgstr "" #, fuzzy msgid "" "The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. Please " -"use 2**n values for `modulus_range` to prevent overflow issues." +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " +"Please use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" -"对随机掩码条目进行均匀采样的数值范围([0, modulus_range-1])。modulus_range " -"\"必须小于 4294967296。为防止出现溢出问题,请为 `modulus_range` 使用 2**n 的" -"值。" +"对随机掩码条目进行均匀采样的数值范围([0, modulus_range-1])。modulus_range \"必须小于 " +"4294967296。为防止出现溢出问题,请为 `modulus_range` 使用 2**n 的值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of #, fuzzy msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for " -"replies for this duration each time. If `None`, there is no time limit and " -"the workflow will wait until replies for all messages are received." -msgstr "" -"超时时间(秒)。如果指定,工作流将在每次等待回复的时间内等待回复。如果指定为 " -"\"无\",则没有时间限制,工作流程将一直等待到收到所有信息的回复。" +"The timeout duration in seconds. If specified, the workflow will wait for" +" replies for this duration each time. If `None`, there is no time limit " +"and the workflow will wait until replies for all messages are received." +msgstr "超时时间(秒)。如果指定,工作流将在每次等待回复的时间内等待回复。如果指定为 \"无\",则没有时间限制,工作流程将一直等待到收到所有信息的回复。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 #: of #, fuzzy msgid "" "Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` means " -"better privacy guarantees but less tolerance to dropouts." -msgstr "" -"一般来说,\"份额数 \"越高,意味着对丢弃的鲁棒性越强,同时计算成本也会增加;" -"\"重构阈值 \"越高,意味着隐私保证越好,但对丢弃的容忍度越低。" +"increasing the computational costs; higher `reconstruction_threshold` " +"means better privacy guarantees but less tolerance to dropouts." +msgstr "一般来说,\"份额数 \"越高,意味着对丢弃的鲁棒性越强,同时计算成本也会增加;\"重构阈值 \"越高,意味着隐私保证越好,但对丢弃的容忍度越低。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of #, fuzzy -msgid "" -"Too large `max_weight` may compromise the precision of the quantization." +msgid "Too large `max_weight` may compromise the precision of the quantization." msgstr "过大的 `max_weight` 可能会影响量化的精度。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 @@ -14724,46 +15619,46 @@ msgstr "modulus_range \"必须为 2**n,且大于 \"quantization_range\"。" #, fuzzy msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in the " -"runtime. This allows for dynamic adjustment based on the total number of " -"participating clients." -msgstr "" -"当 `num_shares` 为浮点数时,它被解释为所有选定客户端的比例,因此份额数将在运" -"行时确定。这样就可以根据参与客户端的总数进行动态调整。" +"selected clients, and hence the number of shares will be determined in " +"the runtime. This allows for dynamic adjustment based on the total number" +" of participating clients." +msgstr "当 `num_shares` 为浮点数时,它被解释为所有选定客户端的比例,因此份额数将在运行时确定。这样就可以根据参与客户端的总数进行动态调整。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 #: of #, fuzzy msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted as " -"the proportion of the number of shares needed for the reconstruction of a " -"private key. This feature enables flexibility in setting the security " -"threshold relative to the number of distributed shares." +"Similarly, when `reconstruction_threshold` is a float, it is interpreted " +"as the proportion of the number of shares needed for the reconstruction " +"of a private key. This feature enables flexibility in setting the " +"security threshold relative to the number of distributed shares." msgstr "" -"同样,当 `reconstruction_threshold` 为浮点数时,它被解释为重建私钥所需的份额" -"数比例。这一功能使我们可以根据分发的份额数灵活设置安全阈值。" +"同样,当 `reconstruction_threshold` " +"为浮点数时,它被解释为重建私钥所需的份额数比例。这一功能使我们可以根据分发的份额数灵活设置安全阈值。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 #: of #, fuzzy msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters " -"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+ " -"protocol." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters" +" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+" +" protocol." msgstr "" -"份额数\"、\"重建阈值 \"和量化参数(\"裁剪范围\"、\"量化范围\"、\"模数范围\")" -"在平衡 SecAgg+ 协议的隐私性、稳健性和效率方面发挥着关键作用。" +"份额数\"、\"重建阈值 \"和量化参数(\"裁剪范围\"、\"量化范围\"、\"模数范围\")在平衡 SecAgg+ " +"协议的隐私性、稳健性和效率方面发挥着关键作用。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of #, fuzzy msgid "" -":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\" +" \\(driver\\, ...\\)" msgstr "" -":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\" +" \\(driver\\, ...\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -14776,11 +15671,13 @@ msgstr "执行 \"收集屏蔽向量 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.setup_stage:1 @@ -14793,11 +15690,13 @@ msgstr "执行 \"设置 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage " +"`\\ " +"\\(driver\\, context\\, state\\)" msgstr "" -":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage " +"`\\ " +"\\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.share_keys_stage:1 @@ -14810,11 +15709,13 @@ msgstr "执行 \"共享密钥 \"阶段。" #: of #, fuzzy msgid "" -":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" -":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 @@ -14829,50 +15730,51 @@ msgstr "工作流程" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"Bases: :py:class:`~flwr.server.workflow.secure_aggregation." -"secaggplus_workflow.SecAggPlusWorkflow`" +"Bases: " +":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned by " -"multiple parties, without accessing any individual integer vector. This " -"workflow allows the server to compute the weighted average of model " +"The SecAgg protocol ensures the secure summation of integer vectors owned" +" by multiple parties, without accessing any individual integer vector. " +"This workflow allows the server to compute the weighted average of model " "parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and a " -"weighted version of the locally updated parameters, both of which are masked " -"for privacy. Specifically, each client uploads \"[w, w * params]\" with " -"masks, where weighting factor 'w' is the number of examples ('num_examples') " -"and 'params' represents the model parameters ('parameters') from the " -"client's `FitRes`. The server then aggregates these contributions to compute " -"the weighted average of model parameters." +"private. This is achieved by clients sending both, a weighting factor and" +" a weighted version of the locally updated parameters, both of which are " +"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" +" with masks, where weighting factor 'w' is the number of examples " +"('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg configuration " -"to clients and collect their public keys. - 'share keys': Broadcast public " -"keys among clients and collect encrypted secret" +"The protocol involves four main stages: - 'setup': Send SecAgg " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"Each client's private key is split into N shares under the SecAgg protocol, " -"where N is the number of selected clients." +"Each client's private key is split into N shares under the SecAgg " +"protocol, where N is the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"Generally, higher `reconstruction_threshold` means better privacy guarantees " -"but less tolerance to dropouts." +"Generally, higher `reconstruction_threshold` means better privacy " +"guarantees but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in setting " -"the security threshold relative to the number of selected clients." +"reconstruction of a private key. This feature enables flexibility in " +"setting the security threshold relative to the number of selected " +"clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of @@ -14886,29 +15788,32 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\ " +"\\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\" +" \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage `\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:2 @@ -14916,35 +15821,24 @@ msgstr "" msgid "simulation" msgstr "运行模拟" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\, " -"client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\," +" client\\_fn\\[\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.app.start_simulation:1 of msgid "Start a Ray-based Flower simulation server." msgstr "启动基于 Ray 的Flower模拟服务器。" -#: ../../source/ref-api/flwr.simulation.rst:19::1 -msgid "" -":py:obj:`run_simulation_from_cli `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.simulation.rst:19::1 -#: flwr.simulation.run_simulation.run_simulation_from_cli:1 of -msgid "Run Simulation Engine from the CLI." -msgstr "" - -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" ":py:obj:`run_simulation `\\ " "\\(server\\_app\\, client\\_app\\, ...\\)" msgstr "" -#: ../../source/ref-api/flwr.simulation.rst:19::1 +#: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.run_simulation.run_simulation:1 of msgid "Run a Flower App using the Simulation Engine." msgstr "" @@ -14962,14 +15856,15 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive " -"messages sent by the `ServerApp`." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive" +" messages sent by the `ServerApp`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in the " -"ServerApp and receive a Message describing what the ClientApp should perform." +"Number of nodes that run a ClientApp. They can be sampled by a Driver in " +"the ServerApp and receive a Message describing what the ClientApp should " +"perform." msgstr "" #: flwr.simulation.run_simulation.run_simulation:13 of @@ -14978,33 +15873,28 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to configure a " -"backend. Values supported in are those included by `flwr.common." -"typing.ConfigsRecordValues`." +"'A dictionary, e.g {\"\": , \"\": } to " +"configure a backend. Values supported in are those included by " +"`flwr.common.typing.ConfigsRecordValues`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. This " -"is desirable if you make use of a TensorFlow model on your `ServerApp` while " -"having your `ClientApp` running on the same GPU. Without enabling this, you " -"might encounter an out-of-memory error because TensorFlow, by default, " -"allocates all GPU memory. Read more about how `tf.config.experimental." -"set_memory_growth()` works in the TensorFlow documentation: https://www." -"tensorflow.org/api/stable." +"A boolean to indicate whether to enable GPU growth on the main thread. " +"This is desirable if you make use of a TensorFlow model on your " +"`ServerApp` while having your `ClientApp` running on the same GPU. " +"Without enabling this, you might encounter an out-of-memory error because" +" TensorFlow, by default, allocates all GPU memory. Read more about how " +"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " +"documentation: https://www.tensorflow.org/api/stable." msgstr "" #: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If " -"enabled, DEBUG-level logs will be displayed." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" +" enabled, DEBUG-level logs will be displayed." msgstr "" -#: ../../source/ref-api/flwr.simulation.run_simulation_from_cli.rst:2 -#, fuzzy -msgid "run\\_simulation\\_from\\_cli" -msgstr "运行模拟" - #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 #, fuzzy msgid "start\\_simulation" @@ -15012,76 +15902,68 @@ msgstr "start_simulation" #: flwr.simulation.app.start_simulation:3 of msgid "" -"A function creating client instances. The function must take a single `str` " -"argument called `cid`. It should return a single client instance of type " -"Client. Note that the created client instances are ephemeral and will often " -"be destroyed after a single method invocation. Since client instances are " -"not long-lived, they should not attempt to carry state over method " -"invocations. Any state required by the instance (model, dataset, " +"A function creating client instances. The function must take a single " +"`str` argument called `cid`. It should return a single client instance of" +" type Client. Note that the created client instances are ephemeral and " +"will often be destroyed after a single method invocation. Since client " +"instances are not long-lived, they should not attempt to carry state over" +" method invocations. Any state required by the instance (model, dataset, " "hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load evaluation " -"data in the `evaluate` method itself)." +"`client_fn` or the call to any of the client methods (e.g., load " +"evaluation data in the `evaluate` method itself)." msgstr "" -"创建客户端实例的函数。该函数必须接受一个名为 `cid` 的 `str` 参数。它应返回一" -"个 Client 类型的客户端实例。请注意,创建的客户端实例是短暂的,通常在调用一个" -"方法后就会被销毁。由于客户机实例不是长期存在的,它们不应试图在方法调用时携带" -"状态数据。实例所需的任何状态数据(模型、数据集、超参数......)都应在调用 " -"`client_fn` 或任何客户端方法(例如,在 `evaluate` 方法中加载评估数据)时(重" -"新)创建。" +"创建客户端实例的函数。该函数必须接受一个名为 `cid` 的 `str` 参数。它应返回一个 Client " +"类型的客户端实例。请注意,创建的客户端实例是短暂的,通常在调用一个方法后就会被销毁。由于客户机实例不是长期存在的,它们不应试图在方法调用时携带状态数据。实例所需的任何状态数据(模型、数据集、超参数......)都应在调用" +" `client_fn` 或任何客户端方法(例如,在 `evaluate` 方法中加载评估数据)时(重新)创建。" #: flwr.simulation.app.start_simulation:13 of msgid "" "The total number of clients in this simulation. This must be set if " "`clients_ids` is not set and vice-versa." -msgstr "" -"本次模拟的客户总数。如果未设置 `clients_ids`,则必须设置该参数,反之亦然。" +msgstr "本次模拟的客户总数。如果未设置 `clients_ids`,则必须设置该参数,反之亦然。" #: flwr.simulation.app.start_simulation:16 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients` is " -"not set. Setting both `num_clients` and `clients_ids` with " +"List `client_id`s for each client. This is only required if `num_clients`" +" is not set. Setting both `num_clients` and `clients_ids` with " "`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" -"列出每个客户的 `client_id`。只有在未设置 `num_clients` 时才需要这样做。同时设" -"置`num_clients`和`clients_ids`,且`len(clients_ids)`不等于`num_clients`,会产" -"生错误。" +"列出每个客户的 `client_id`。只有在未设置 `num_clients` " +"时才需要这样做。同时设置`num_clients`和`clients_ids`,且`len(clients_ids)`不等于`num_clients`,会产生错误。" #: flwr.simulation.app.start_simulation:20 of #, fuzzy msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` and " -"`num_gpus`. To understand the GPU utilization caused by `num_gpus`, as well " -"as using custom resources, please consult the Ray documentation." +"CPU and GPU resources for a single client. Supported keys are `num_cpus` " +"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " +"as well as using custom resources, please consult the Ray documentation." msgstr "" -"\"num_gpus\": 0.0` 单个客户端的 CPU 和 GPU 资源。支持的键值为 `num_cpus` 和 " -"`num_gpus`。要了解 `num_gpus` 所导致的 GPU 利用率,以及使用自定义资源的情况," -"请查阅 Ray 文档。" +"\"num_gpus\": 0.0` 单个客户端的 CPU 和 GPU 资源。支持的键值为 `num_cpus` 和 `num_gpus`。要了解" +" `num_gpus` 所导致的 GPU 利用率,以及使用自定义资源的情况,请查阅 Ray 文档。" #: flwr.simulation.app.start_simulation:25 of msgid "" "An implementation of the abstract base class `flwr.server.Server`. If no " "instance is provided, then `start_server` will create one." -msgstr "" -"抽象基类 `flwr.server.Server`的实现。如果没有提供实例,`start_server` 将创建" -"一个。" +msgstr "抽象基类 `flwr.server.Server`的实现。如果没有提供实例,`start_server` 将创建一个。" #: flwr.simulation.app.start_simulation:31 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If no " -"strategy is provided, then `start_server` will use `flwr.server.strategy." -"FedAvg`." +"An implementation of the abstract base class `flwr.server.Strategy`. If " +"no strategy is provided, then `start_server` will use " +"`flwr.server.strategy.FedAvg`." msgstr "" -"抽象基类 `flwr.server.strategy` 的实现。如果没有提供策略,`start_server` 将使" -"用 `flwr.server.strategy.FedAvg`。" +"抽象基类 `flwr.server.strategy` 的实现。如果没有提供策略,`start_server` 将使用 " +"`flwr.server.strategy.FedAvg`。" #: flwr.simulation.app.start_simulation:35 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`. If " -"no implementation is provided, then `start_simulation` will use `flwr.server." -"client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_simulation` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" -"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现," -"`start_simulation` 将使用 `flwr.server.client_manager.SimpleClientManager`。" +"抽象基类 `flwr.server.ClientManager` 的实现。如果没有提供实现,`start_simulation` 将使用 " +"`flwr.server.client_manager.SimpleClientManager`。" #: flwr.simulation.app.start_simulation:39 of msgid "" @@ -15089,21 +15971,19 @@ msgid "" "ray_init_args is None (the default), Ray will be initialized with the " "following default args: { \"ignore_reinit_error\": True, " "\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to ray.init." +"(ray_init_args={}) to prevent any arguments from being passed to " +"ray.init." msgstr "" -"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认" -"值),则将使用以下默认参数初始化 Ray: { \"ignore_reinit_error\": True, " -"\"include_dashboard\": False } 可以使用空字典(ray_init_args={})来防止向 " -"ray.init 传递任何参数。" +"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认值),则将使用以下默认参数初始化 Ray:" +" { \"ignore_reinit_error\": True, \"include_dashboard\": False } " +"可以使用空字典(ray_init_args={})来防止向 ray.init 传递任何参数。" #: flwr.simulation.app.start_simulation:39 of msgid "" "Optional dictionary containing arguments for the call to `ray.init`. If " "ray_init_args is None (the default), Ray will be initialized with the " "following default args:" -msgstr "" -"可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认" -"值),则将使用以下默认参数初始化 Ray:" +msgstr "可选字典,包含调用 `ray.init` 时的参数。如果 ray_init_args 为 None(默认值),则将使用以下默认参数初始化 Ray:" #: flwr.simulation.app.start_simulation:43 of msgid "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" @@ -15111,15 +15991,15 @@ msgstr "{ \"ignore_reinit_error\": True, \"include_dashboard\": False }" #: flwr.simulation.app.start_simulation:45 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any arguments " -"from being passed to ray.init." +"An empty dictionary can be used (ray_init_args={}) to prevent any " +"arguments from being passed to ray.init." msgstr "可以使用空字典 (ray_init_args={}) 来防止向 ray.init 传递任何参数。" #: flwr.simulation.app.start_simulation:48 of msgid "" -"Set to True to prevent `ray.shutdown()` in case `ray.is_initialized()=True`." -msgstr "" -"设为 True 可在 `ray.is_initialized()=True` 情况下阻止 `ray.shutdown()` 。" +"Set to True to prevent `ray.shutdown()` in case " +"`ray.is_initialized()=True`." +msgstr "设为 True 可在 `ray.is_initialized()=True` 情况下阻止 `ray.shutdown()` 。" #: flwr.simulation.app.start_simulation:50 of #, fuzzy @@ -15127,33 +16007,28 @@ msgid "" "Optionally specify the type of actor to use. The actor object, which " "persists throughout the simulation, will be the process in charge of " "executing a ClientApp wrapping input argument `client_fn`." -msgstr "" -"可选择指定要使用的actor类型。actor对象将在整个模拟过程中持续存在,它将是负责" -"运行客户端作业(即其 `fit()`方法)的进程。" +msgstr "可选择指定要使用的actor类型。actor对象将在整个模拟过程中持续存在,它将是负责运行客户端作业(即其 `fit()`方法)的进程。" #: flwr.simulation.app.start_simulation:54 of msgid "" -"If you want to create your own Actor classes, you might need to pass some " -"input argument. You can use this dictionary for such purpose." -msgstr "" -"如果您想创建自己的 Actor 类,可能需要传递一些输入参数。为此,您可以使用本字" -"典。" +"If you want to create your own Actor classes, you might need to pass some" +" input argument. You can use this dictionary for such purpose." +msgstr "如果您想创建自己的 Actor 类,可能需要传递一些输入参数。为此,您可以使用本字典。" #: flwr.simulation.app.start_simulation:57 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for the " -"VCE to choose in which node the actor is placed. If you are an advanced user " -"needed more control you can use lower-level scheduling strategies to pin " -"actors to specific compute nodes (e.g. via NodeAffinitySchedulingStrategy). " -"Please note this is an advanced feature. For all details, please refer to " -"the Ray documentation: https://docs.ray.io/en/latest/ray-core/scheduling/" -"index.html" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " +"the VCE to choose in which node the actor is placed. If you are an " +"advanced user needed more control you can use lower-level scheduling " +"strategies to pin actors to specific compute nodes (e.g. via " +"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." +" For all details, please refer to the Ray documentation: " +"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" msgstr "" -"(默认:\"DEFAULT\")可选字符串(\"DEFAULT \"或 \"SPREAD\"),供 VCE 选择将行" -"为体放置在哪个节点上。如果你是需要更多控制权的高级用户,可以使用低级调度策略" -"将actor固定到特定计算节点(例如,通过 NodeAffinitySchedulingStrategy)。请注" -"意,这是一项高级功能。有关详细信息,请参阅 Ray 文档:https://docs.ray.io/en/" -"latest/ray-core/scheduling/index.html" +"(默认:\"DEFAULT\")可选字符串(\"DEFAULT \"或 \"SPREAD\"),供 VCE " +"选择将行为体放置在哪个节点上。如果你是需要更多控制权的高级用户,可以使用低级调度策略将actor固定到特定计算节点(例如,通过 " +"NodeAffinitySchedulingStrategy)。请注意,这是一项高级功能。有关详细信息,请参阅 Ray " +"文档:https://docs.ray.io/en/latest/ray-core/scheduling/index.html" #: flwr.simulation.app.start_simulation:66 of msgid "**hist** -- Object containing metrics from training." @@ -15167,58 +16042,65 @@ msgstr "更新日志" msgid "Unreleased" msgstr "尚未发布" -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:17 -#: ../../source/ref-changelog.md:110 ../../source/ref-changelog.md:210 -#: ../../source/ref-changelog.md:294 ../../source/ref-changelog.md:358 -#: ../../source/ref-changelog.md:416 ../../source/ref-changelog.md:485 -#: ../../source/ref-changelog.md:614 ../../source/ref-changelog.md:656 -#: ../../source/ref-changelog.md:723 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:834 ../../source/ref-changelog.md:873 -#: ../../source/ref-changelog.md:906 ../../source/ref-changelog.md:956 +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 +#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 +#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 +#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 +#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 +#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 +#: ../../source/ref-changelog.md:1022 msgid "What's new?" msgstr "有什么新内容?" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:80 -#: ../../source/ref-changelog.md:192 ../../source/ref-changelog.md:282 -#: ../../source/ref-changelog.md:346 ../../source/ref-changelog.md:404 -#: ../../source/ref-changelog.md:473 ../../source/ref-changelog.md:535 -#: ../../source/ref-changelog.md:554 ../../source/ref-changelog.md:710 -#: ../../source/ref-changelog.md:781 ../../source/ref-changelog.md:818 -#: ../../source/ref-changelog.md:861 +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 +#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 +#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 +#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 +#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 msgid "Incompatible changes" msgstr "不兼容的更改" -#: ../../source/ref-changelog.md:9 +#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 +#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 +#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 +#: ../../source/ref-changelog.md:603 +msgid "None" +msgstr "无" + +#: ../../source/ref-changelog.md:11 #, fuzzy -msgid "v1.7.0 (2024-02-05)" +msgid "v1.8.0 (2024-04-03)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:104 -#: ../../source/ref-changelog.md:204 ../../source/ref-changelog.md:288 -#: ../../source/ref-changelog.md:352 ../../source/ref-changelog.md:410 -#: ../../source/ref-changelog.md:479 ../../source/ref-changelog.md:548 +#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 +#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 +#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 +#: ../../source/ref-changelog.md:614 msgid "Thanks to our contributors" msgstr "感谢我们的贡献者" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:106 -#: ../../source/ref-changelog.md:206 ../../source/ref-changelog.md:290 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:412 +#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 +#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 +#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 +#: ../../source/ref-changelog.md:478 msgid "" -"We would like to give our special thanks to all the contributors who made " -"the new version of Flower possible (in `git shortlog` order):" -msgstr "" -"在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` " -"顺序排列):" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" +msgstr "在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` 顺序排列):" -#: ../../source/ref-changelog.md:15 +#: ../../source/ref-changelog.md:17 #, fuzzy msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles Beauville`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S Chaitanya Kumar`, `Mohammad " -"Naseri`, `Nikos Vlachakis`, `Pritam Neog`, `Robert Kuska`, `Robert Steiner`, " -"`Taner Topal`, `Yahia Salaheldin Shaaban`, `Yan Gao`, `Yasar Abbas` " +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " msgstr "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -15226,820 +16108,1336 @@ msgstr "" "Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " -#: ../../source/ref-changelog.md:19 -#, fuzzy -msgid "" -"**Introduce stateful clients (experimental)** ([#2770](https://github.com/" -"adap/flower/pull/2770), [#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), [#2643](https://github." -"com/adap/flower/pull/2643), [#2769](https://github.com/adap/flower/" -"pull/2769))" -msgstr "" -"** baselines的普通更新** ([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), [#2307](https://github." -"com/adap/flower/pull/2307), [#2327](https://github.com/adap/flower/" -"pull/2327), [#2435](https://github.com/adap/flower/pull/2435))" - #: ../../source/ref-changelog.md:21 msgid "" -"Subclasses of `Client` and `NumPyClient` can now store local state that " -"remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via `start_simulation`) " -"and networked clients (via `start_client`). It's also the first preview of " -"new abstractions like `Context` and `RecordSet`. Clients can access state of " -"type `RecordSet` via `state: RecordSet = self.context.state`. Changes to " -"this `RecordSet` are preserved across different rounds of execution to " -"enable stateful computations in a unified way across simulation and " -"deployment." +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" msgstr "" #: ../../source/ref-changelog.md:23 -#, fuzzy msgid "" -"**Improve performance** ([#2293](https://github.com/adap/flower/pull/2293))" -msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " +"this multi-run) and execute the same project in either simulation " +"environments or deployment environments without having to change a single" +" line of code. The best part? It's fully compatible with existing Flower " +"projects that use `Strategy`, `NumPyClient` & co." +msgstr "" #: ../../source/ref-changelog.md:25 +#, fuzzy msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-place " -"aggregation to reduce memory consumption. The Flower client serialization/" -"deserialization has been rewritten from the ground up, which results in " -"significant speedups, especially when the client-side training time is short." +"**Introduce Flower Next low-level API (preview)** " +"([#3062](https://github.com/adap/flower/pull/3062), " +"[#3034](https://github.com/adap/flower/pull/3034), " +"[#3069](https://github.com/adap/flower/pull/3069))" msgstr "" +"** 统一客户端应用程序接口** ([#2303](https://github.com/adap/flower/pull/2303), " +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" #: ../../source/ref-changelog.md:27 -#, fuzzy msgid "" -"**Support Federated Learning with Apple MLX and Flower** ([#2693](https://" -"github.com/adap/flower/pull/2693))" +"In addition to the Flower Next *high-level* API that uses `Strategy`, " +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " +"new Flower Next *low-level* API. The low-level API allows for granular " +"control of every aspect of the learning process by sending/receiving " +"individual messages to/from client nodes. The new `ServerApp` supports " +"registering a custom `main` function that allows writing custom training " +"loops for methods like async FL, cyclic training, or federated analytics." +" The new `ClientApp` supports registering `train`, `evaluate` and `query`" +" functions that can access the raw message received from the `ServerApp`." +" New abstractions like `RecordSet`, `Message` and `Context` further " +"enable sending multiple models, multiple sets of config values and " +"metrics, stateful computations on the client node and implementations of " +"custom SMPC protocols, to name just a few." msgstr "" -"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** ([#1598](https://github." -"com/adap/flower/pull/1598))" #: ../../source/ref-changelog.md:29 +#, fuzzy msgid "" -"Flower has official support for federated learning using [Apple MLX](https://" -"ml-explore.github.io/mlx) via the new `quickstart-mlx` code example." +"**Introduce Flower Mods (preview)** " +"([#3054](https://github.com/adap/flower/pull/3054), " +"[#2911](https://github.com/adap/flower/pull/2911), " +"[#3083](https://github.com/adap/flower/pull/3083))" msgstr "" +"**引入新的模拟引擎** ([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" #: ../../source/ref-changelog.md:31 -#, fuzzy msgid "" -"**Introduce new XGBoost cyclic strategy** ([#2666](https://github.com/adap/" -"flower/pull/2666), [#2668](https://github.com/adap/flower/pull/2668))" +"Flower Modifiers (we call them Mods) can intercept messages and analyze, " +"edit or handle them directly. Mods can be used to develop pluggable " +"modules that work across different projects. Flower 1.8 already includes " +"mods to log the size of a message, the number of parameters sent over the" +" network, differential privacy with fixed clipping and adaptive clipping," +" local differential privacy and secure aggregation protocols SecAgg and " +"SecAgg+. The Flower Mods API is released as a preview, but researchers " +"can already use it to experiment with arbirtrary SMPC protocols." msgstr "" -"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/" -"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" #: ../../source/ref-changelog.md:33 +#, fuzzy msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of " -"training (often called cyclic). The `xgboost-comprehensive` code example " -"shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower offers " -"best-in-class XGBoost support." +"**Fine-tune LLMs with LLM FlowerTune** " +"([#3029](https://github.com/adap/flower/pull/3029), " +"[#3089](https://github.com/adap/flower/pull/3089), " +"[#3092](https://github.com/adap/flower/pull/3092), " +"[#3100](https://github.com/adap/flower/pull/3100), " +"[#3114](https://github.com/adap/flower/pull/3114), " +"[#3162](https://github.com/adap/flower/pull/3162), " +"[#3172](https://github.com/adap/flower/pull/3172))" msgstr "" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475)))" #: ../../source/ref-changelog.md:35 -#, fuzzy msgid "" -"**Support Python 3.11** ([#2394](https://github.com/adap/flower/pull/2394))" +"We are introducing LLM FlowerTune, an introductory example that " +"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " +"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" +" different models and/or datasets. Read our blog post [LLM FlowerTune: " +"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" +"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -"** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" #: ../../source/ref-changelog.md:37 +#, fuzzy msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will ensure " -"better support for users using more recent Python versions." -msgstr "" +"**Introduce built-in Differential Privacy (preview)** " +"([#2798](https://github.com/adap/flower/pull/2798), " +"[#2959](https://github.com/adap/flower/pull/2959), " +"[#3038](https://github.com/adap/flower/pull/3038), " +"[#3147](https://github.com/adap/flower/pull/3147), " +"[#2909](https://github.com/adap/flower/pull/2909), " +"[#2893](https://github.com/adap/flower/pull/2893), " +"[#2892](https://github.com/adap/flower/pull/2892), " +"[#3039](https://github.com/adap/flower/pull/3039), " +"[#3074](https://github.com/adap/flower/pull/3074))" +msgstr "" +"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:39 -#, fuzzy msgid "" -"**Update gRPC and ProtoBuf dependencies** ([#2814](https://github.com/adap/" -"flower/pull/2814))" +"Built-in Differential Privacy is here! Flower supports both central and " +"local differential privacy (DP). Central DP can be configured with either" +" fixed or adaptive clipping. The clipping can happen either on the " +"server-side or the client-side. Local DP does both clipping and noising " +"on the client-side. A new documentation page [explains Differential " +"Privacy approaches](https://flower.ai/docs/framework/explanation-" +"differential-privacy.html) and a new how-to guide describes [how to use " +"the new Differential Privacy components](https://flower.ai/docs/framework" +"/how-to-use-differential-privacy.html) in Flower." msgstr "" -"**更新 REST API 以支持创建和删除节点** ([#2283](https://github.com/adap/" -"flower/pull/2283))" #: ../../source/ref-changelog.md:41 +#, fuzzy msgid "" -"The `grpcio` and `protobuf` dependencies were updated to their latest " -"versions for improved security and performance." +"**Introduce built-in Secure Aggregation (preview)** " +"([#3120](https://github.com/adap/flower/pull/3120), " +"[#3110](https://github.com/adap/flower/pull/3110), " +"[#3108](https://github.com/adap/flower/pull/3108))" msgstr "" +"**引入新的模拟引擎** ([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" #: ../../source/ref-changelog.md:43 -#, fuzzy msgid "" -"**Introduce Docker image for Flower server** ([#2700](https://github.com/" -"adap/flower/pull/2700), [#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), [#2695](https://github." -"com/adap/flower/pull/2695), [#2747](https://github.com/adap/flower/" -"pull/2747), [#2746](https://github.com/adap/flower/pull/2746), [#2680]" -"(https://github.com/adap/flower/pull/2680), [#2682](https://github.com/adap/" -"flower/pull/2682), [#2701](https://github.com/adap/flower/pull/2701))" +"Built-in Secure Aggregation is here! Flower now supports different secure" +" aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In " +"this initial release, we inlcude support for SecAgg and SecAgg+, but more" +" protocols will be implemented shortly. We'll also add detailed docs that" +" explain secure aggregation and how to use it in Flower. You can already " +"check out the new code example that shows how to use Flower to easily " +"combine Federated Learning, Differential Privacy and Secure Aggregation " +"in the same project." msgstr "" -"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/" -"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" -"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" -"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" -"github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:45 +#, fuzzy msgid "" -"The Flower server can now be run using an official Docker image. A new how-" -"to guide explains [how to run Flower using Docker](https://flower.ai/docs/" -"framework/how-to-run-flower-using-docker.html). An official Flower client " -"Docker image will follow." -msgstr "" +"**Introduce** `flwr` **CLI (preview)** " +"([#2942](https://github.com/adap/flower/pull/2942), " +"[#3055](https://github.com/adap/flower/pull/3055), " +"[#3111](https://github.com/adap/flower/pull/3111), " +"[#3130](https://github.com/adap/flower/pull/3130), " +"[#3136](https://github.com/adap/flower/pull/3136), " +"[#3094](https://github.com/adap/flower/pull/3094), " +"[#3059](https://github.com/adap/flower/pull/3059), " +"[#3049](https://github.com/adap/flower/pull/3049), " +"[#3142](https://github.com/adap/flower/pull/3142))" +msgstr "" +"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" #: ../../source/ref-changelog.md:47 -#, fuzzy msgid "" -"**Introduce** `flower-via-docker-compose` **example** ([#2626](https://" -"github.com/adap/flower/pull/2626))" +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" +" and then running them using the Simulation Engine (`flwr run`)." msgstr "" -"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" -"pull/2131))" #: ../../source/ref-changelog.md:49 #, fuzzy msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** ([#2719](https://" -"github.com/adap/flower/pull/2719))" -msgstr "" -"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce Flower Next Simulation Engine** " +"([#3024](https://github.com/adap/flower/pull/3024), " +"[#3061](https://github.com/adap/flower/pull/3061), " +"[#2997](https://github.com/adap/flower/pull/2997), " +"[#2783](https://github.com/adap/flower/pull/2783), " +"[#3184](https://github.com/adap/flower/pull/3184), " +"[#3075](https://github.com/adap/flower/pull/3075), " +"[#3047](https://github.com/adap/flower/pull/3047), " +"[#2998](https://github.com/adap/flower/pull/2998), " +"[#3009](https://github.com/adap/flower/pull/3009), " +"[#3008](https://github.com/adap/flower/pull/3008))" +msgstr "" +"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" #: ../../source/ref-changelog.md:51 -#, fuzzy msgid "" -"**Introduce** `custom-metrics` **example** ([#1958](https://github.com/adap/" -"flower/pull/1958))" +"The Flower Simulation Engine can now run Flower Next projects. For " +"notebook environments, there's also a new `run_simulation` function that " +"can run `ServerApp` and `ClientApp`." msgstr "" -"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" #: ../../source/ref-changelog.md:53 #, fuzzy msgid "" -"**Update code examples to use Flower Datasets** ([#2450](https://github.com/" -"adap/flower/pull/2450), [#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), [#2712](https://github." -"com/adap/flower/pull/2712))" -msgstr "" -"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), [#1276]" -"(https://github.com/adap/flower/pull/1276), [#1301](https://github.com/adap/" -"flower/pull/1301), [#1310](https://github.com/adap/flower/pull/1310)" +"**Handle SuperNode connection errors** " +"([#2969](https://github.com/adap/flower/pull/2969))" +msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" #: ../../source/ref-changelog.md:55 msgid "" -"Several code examples were updated to use [Flower Datasets](https://flower." -"ai/docs/datasets/)." +"A SuperNode will now try to reconnect indefinitely to the SuperLink in " +"case of connection errors. The arguments `--max-retries` and `--max-wait-" +"time` can now be passed to the `flower-client-app` command. `--max-" +"retries` will define the number of tentatives the client should make " +"before it gives up trying to reconnect to the SuperLink, and, `--max-" +"wait-time` defines the time before the SuperNode gives up trying to " +"reconnect to the SuperLink." msgstr "" #: ../../source/ref-changelog.md:57 #, fuzzy msgid "" -"**General updates to Flower Examples** ([#2381](https://github.com/adap/" -"flower/pull/2381), [#2805](https://github.com/adap/flower/pull/2805), [#2782]" -"(https://github.com/adap/flower/pull/2782), [#2806](https://github.com/adap/" -"flower/pull/2806), [#2829](https://github.com/adap/flower/pull/2829), [#2825]" -"(https://github.com/adap/flower/pull/2825), [#2816](https://github.com/adap/" -"flower/pull/2816), [#2726](https://github.com/adap/flower/pull/2726), [#2659]" -"(https://github.com/adap/flower/pull/2659), [#2655](https://github.com/adap/" -"flower/pull/2655))" +"**General updates to Flower Baselines** " +"([#2904](https://github.com/adap/flower/pull/2904), " +"[#2482](https://github.com/adap/flower/pull/2482), " +"[#2985](https://github.com/adap/flower/pull/2985), " +"[#2968](https://github.com/adap/flower/pull/2968))" msgstr "" -"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/" -"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" -"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" -"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" -"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" -"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" -"(https://github.com/adap/flower/pull/1794))" +"**引入新的 Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679)" #: ../../source/ref-changelog.md:59 +msgid "" +"There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " +"baseline. Several other baselined have been updated as well." +msgstr "" + +#: ../../source/ref-changelog.md:61 +msgid "" +"**Improve documentation and translations** " +"([#3050](https://github.com/adap/flower/pull/3050), " +"[#3044](https://github.com/adap/flower/pull/3044), " +"[#3043](https://github.com/adap/flower/pull/3043), " +"[#2986](https://github.com/adap/flower/pull/2986), " +"[#3041](https://github.com/adap/flower/pull/3041), " +"[#3046](https://github.com/adap/flower/pull/3046), " +"[#3042](https://github.com/adap/flower/pull/3042), " +"[#2978](https://github.com/adap/flower/pull/2978), " +"[#2952](https://github.com/adap/flower/pull/2952), " +"[#3167](https://github.com/adap/flower/pull/3167), " +"[#2953](https://github.com/adap/flower/pull/2953), " +"[#3045](https://github.com/adap/flower/pull/3045), " +"[#2654](https://github.com/adap/flower/pull/2654), " +"[#3082](https://github.com/adap/flower/pull/3082), " +"[#2990](https://github.com/adap/flower/pull/2990), " +"[#2989](https://github.com/adap/flower/pull/2989))" +msgstr "" + +#: ../../source/ref-changelog.md:63 +msgid "" +"As usual, we merged many smaller and larger improvements to the " +"documentation. A special thank you goes to [Sebastian van der " +"Voort](https://github.com/svdvoort) for landing a big documentation PR!" +msgstr "" + +#: ../../source/ref-changelog.md:65 +#, fuzzy +msgid "" +"**General updates to Flower Examples** " +"([3134](https://github.com/adap/flower/pull/3134), " +"[2996](https://github.com/adap/flower/pull/2996), " +"[2930](https://github.com/adap/flower/pull/2930), " +"[2967](https://github.com/adap/flower/pull/2967), " +"[2467](https://github.com/adap/flower/pull/2467), " +"[2910](https://github.com/adap/flower/pull/2910), " +"[#2918](https://github.com/adap/flower/pull/2918), " +"[#2773](https://github.com/adap/flower/pull/2773), " +"[#3063](https://github.com/adap/flower/pull/3063), " +"[#3116](https://github.com/adap/flower/pull/3116), " +"[#3117](https://github.com/adap/flower/pull/3117))" +msgstr "" +"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" + +#: ../../source/ref-changelog.md:67 +msgid "" +"Two new examples show federated training of a Vision Transformer (ViT) " +"and federated learning in a medical context using the popular MONAI " +"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" +" new Flower Next `ServerApp` and `ClientApp`. Many other examples " +"received considerable updates as well." +msgstr "" + +#: ../../source/ref-changelog.md:69 +msgid "" +"**General improvements** " +"([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), " +"[3003](https://github.com/adap/flower/pull/3003), " +"[3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), " +"[3085](https://github.com/adap/flower/pull/3085), " +"[3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), " +"[2991](https://github.com/adap/flower/pull/2991), " +"[2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), " +"[3086](https://github.com/adap/flower/pull/3086), " +"[2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), " +"[2941](https://github.com/adap/flower/pull/2941), " +"[2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), " +"[2973](https://github.com/adap/flower/pull/2973), " +"[2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), " +"[3040](https://github.com/adap/flower/pull/3040), " +"[3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), " +"[2902](https://github.com/adap/flower/pull/2902), " +"[2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), " +"[3132](https://github.com/adap/flower/pull/3132), " +"[3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), " +"[3064](https://github.com/adap/flower/pull/3064), " +"[3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), " +"[3178](https://github.com/adap/flower/pull/3178), " +"[2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), " +"[3091](https://github.com/adap/flower/pull/3091), " +"[3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), " +"[3013](https://github.com/adap/flower/pull/3013), " +"[3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), " +"[3068](https://github.com/adap/flower/pull/3068), " +"[2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), " +"[2984](https://github.com/adap/flower/pull/2984), " +"[2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), " +"[3143](https://github.com/adap/flower/pull/3143), " +"[2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), " +"[2927](https://github.com/adap/flower/pull/2927), " +"[2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), " +"[2912](https://github.com/adap/flower/pull/2912), " +"[3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), " +"[2922](https://github.com/adap/flower/pull/2922), " +"[2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), " +"[3179](https://github.com/adap/flower/pull/3179), " +"[3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), " +"[3187](https://github.com/adap/flower/pull/3187), " +"[2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), " +"[3144](https://github.com/adap/flower/pull/3144), " +"[3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), " +"[#2836](https://github.com/adap/flower/pull/2836), " +"[#2929](https://github.com/adap/flower/pull/2929), " +"[#2943](https://github.com/adap/flower/pull/2943), " +"[#2955](https://github.com/adap/flower/pull/2955), " +"[#2954](https://github.com/adap/flower/pull/2954))" +msgstr "" + +#: ../../source/ref-changelog.md:75 +#, fuzzy +msgid "v1.7.0 (2024-02-05)" +msgstr "v1.3.0 (2023-02-06)" + +#: ../../source/ref-changelog.md:81 +#, fuzzy +msgid "" +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " +"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " +"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " +"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " +"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " +"Shaaban`, `Yan Gao`, `Yasar Abbas` " +msgstr "" +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " + +#: ../../source/ref-changelog.md:85 +#, fuzzy +msgid "" +"**Introduce stateful clients (experimental)** " +"([#2770](https://github.com/adap/flower/pull/2770), " +"[#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), " +"[#2643](https://github.com/adap/flower/pull/2643), " +"[#2769](https://github.com/adap/flower/pull/2769))" +msgstr "" +"** baselines的普通更新** ([#2301](https://github.com/adap/flower/pull/2301), " +"[#2305](https://github.com/adap/flower/pull/2305), " +"[#2307](https://github.com/adap/flower/pull/2307), " +"[#2327](https://github.com/adap/flower/pull/2327), " +"[#2435](https://github.com/adap/flower/pull/2435))" + +#: ../../source/ref-changelog.md:87 +msgid "" +"Subclasses of `Client` and `NumPyClient` can now store local state that " +"remains on the client. Let's start with the highlight first: this new " +"feature is compatible with both simulated clients (via " +"`start_simulation`) and networked clients (via `start_client`). It's also" +" the first preview of new abstractions like `Context` and `RecordSet`. " +"Clients can access state of type `RecordSet` via `state: RecordSet = " +"self.context.state`. Changes to this `RecordSet` are preserved across " +"different rounds of execution to enable stateful computations in a " +"unified way across simulation and deployment." +msgstr "" + +#: ../../source/ref-changelog.md:89 +#, fuzzy +msgid "" +"**Improve performance** " +"([#2293](https://github.com/adap/flower/pull/2293))" +msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" + +#: ../../source/ref-changelog.md:91 +msgid "" +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" +"place aggregation to reduce memory consumption. The Flower client " +"serialization/deserialization has been rewritten from the ground up, " +"which results in significant speedups, especially when the client-side " +"training time is short." +msgstr "" + +#: ../../source/ref-changelog.md:93 +#, fuzzy +msgid "" +"**Support Federated Learning with Apple MLX and Flower** " +"([#2693](https://github.com/adap/flower/pull/2693))" +msgstr "" +"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " +"([#1598](https://github.com/adap/flower/pull/1598))" + +#: ../../source/ref-changelog.md:95 +msgid "" +"Flower has official support for federated learning using [Apple " +"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " +"example." +msgstr "" + +#: ../../source/ref-changelog.md:97 +#, fuzzy +msgid "" +"**Introduce new XGBoost cyclic strategy** " +"([#2666](https://github.com/adap/flower/pull/2666), " +"[#2668](https://github.com/adap/flower/pull/2668))" +msgstr "" +"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" + +#: ../../source/ref-changelog.md:99 +msgid "" +"A new strategy called `FedXgbCyclic` supports a client-by-client style of" +" training (often called cyclic). The `xgboost-comprehensive` code example" +" shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower " +"offers best-in-class XGBoost support." +msgstr "" + +#: ../../source/ref-changelog.md:101 +#, fuzzy +msgid "" +"**Support Python 3.11** " +"([#2394](https://github.com/adap/flower/pull/2394))" +msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" + +#: ../../source/ref-changelog.md:103 +msgid "" +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " +"ensure better support for users using more recent Python versions." +msgstr "" + +#: ../../source/ref-changelog.md:105 +#, fuzzy +msgid "" +"**Update gRPC and ProtoBuf dependencies** " +"([#2814](https://github.com/adap/flower/pull/2814))" +msgstr "" +"**更新 REST API 以支持创建和删除节点** " +"([#2283](https://github.com/adap/flower/pull/2283))" + +#: ../../source/ref-changelog.md:107 +msgid "" +"The `grpcio` and `protobuf` dependencies were updated to their latest " +"versions for improved security and performance." +msgstr "" + +#: ../../source/ref-changelog.md:109 +#, fuzzy +msgid "" +"**Introduce Docker image for Flower server** " +"([#2700](https://github.com/adap/flower/pull/2700), " +"[#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), " +"[#2695](https://github.com/adap/flower/pull/2695), " +"[#2747](https://github.com/adap/flower/pull/2747), " +"[#2746](https://github.com/adap/flower/pull/2746), " +"[#2680](https://github.com/adap/flower/pull/2680), " +"[#2682](https://github.com/adap/flower/pull/2682), " +"[#2701](https://github.com/adap/flower/pull/2701))" +msgstr "" +"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" + +#: ../../source/ref-changelog.md:111 +msgid "" +"The Flower server can now be run using an official Docker image. A new " +"how-to guide explains [how to run Flower using " +"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html). An official Flower client Docker image will follow." +msgstr "" + +#: ../../source/ref-changelog.md:113 +#, fuzzy +msgid "" +"**Introduce** `flower-via-docker-compose` **example** " +"([#2626](https://github.com/adap/flower/pull/2626))" +msgstr "" +"**介绍Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" + +#: ../../source/ref-changelog.md:115 +#, fuzzy +msgid "" +"**Introduce** `quickstart-sklearn-tabular` **example** " +"([#2719](https://github.com/adap/flower/pull/2719))" +msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" + +#: ../../source/ref-changelog.md:117 +#, fuzzy +msgid "" +"**Introduce** `custom-metrics` **example** " +"([#1958](https://github.com/adap/flower/pull/1958))" +msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" + +#: ../../source/ref-changelog.md:119 +#, fuzzy +msgid "" +"**Update code examples to use Flower Datasets** " +"([#2450](https://github.com/adap/flower/pull/2450), " +"[#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), " +"[#2712](https://github.com/adap/flower/pull/2712))" +msgstr "" +"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310)" + +#: ../../source/ref-changelog.md:121 +msgid "" +"Several code examples were updated to use [Flower " +"Datasets](https://flower.ai/docs/datasets/)." +msgstr "" + +#: ../../source/ref-changelog.md:123 +#, fuzzy +msgid "" +"**General updates to Flower Examples** " +"([#2381](https://github.com/adap/flower/pull/2381), " +"[#2805](https://github.com/adap/flower/pull/2805), " +"[#2782](https://github.com/adap/flower/pull/2782), " +"[#2806](https://github.com/adap/flower/pull/2806), " +"[#2829](https://github.com/adap/flower/pull/2829), " +"[#2825](https://github.com/adap/flower/pull/2825), " +"[#2816](https://github.com/adap/flower/pull/2816), " +"[#2726](https://github.com/adap/flower/pull/2726), " +"[#2659](https://github.com/adap/flower/pull/2659), " +"[#2655](https://github.com/adap/flower/pull/2655))" +msgstr "" +"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/flower/pull/1663)," +" [#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" + +#: ../../source/ref-changelog.md:125 msgid "Many Flower code examples received substantial updates." msgstr "" -#: ../../source/ref-changelog.md:61 ../../source/ref-changelog.md:154 +#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 msgid "**Update Flower Baselines**" msgstr "**更新 Flower Baselines**" -#: ../../source/ref-changelog.md:63 +#: ../../source/ref-changelog.md:129 #, fuzzy msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), [#2771]" -"(https://github.com/adap/flower/pull/2771))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " +"[#2771](https://github.com/adap/flower/pull/2771))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" -"github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:64 +#: ../../source/ref-changelog.md:130 #, fuzzy msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:65 +#: ../../source/ref-changelog.md:131 #, fuzzy msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:66 +#: ../../source/ref-changelog.md:132 #, fuzzy msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" msgstr "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" -#: ../../source/ref-changelog.md:67 +#: ../../source/ref-changelog.md:133 #, fuzzy msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:68 +#: ../../source/ref-changelog.md:134 #, fuzzy msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:70 -#, fuzzy -msgid "" -"**Improve documentation** ([#2674](https://github.com/adap/flower/" -"pull/2674), [#2480](https://github.com/adap/flower/pull/2480), [#2826]" -"(https://github.com/adap/flower/pull/2826), [#2727](https://github.com/adap/" -"flower/pull/2727), [#2761](https://github.com/adap/flower/pull/2761), [#2900]" -"(https://github.com/adap/flower/pull/2900))" -msgstr "" -"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), [#1628]" -"(https://github.com/adap/flower/pull/1628), [#1620](https://github.com/adap/" -"flower/pull/1620), [#1618](https://github.com/adap/flower/pull/1618), [#1617]" -"(https://github.com/adap/flower/pull/1617), [#1613](https://github.com/adap/" -"flower/pull/1613), [#1614](https://github.com/adap/flower/pull/1614)))" - -#: ../../source/ref-changelog.md:72 -msgid "" -"**Improved testing and development infrastructure** ([#2797](https://github." -"com/adap/flower/pull/2797), [#2676](https://github.com/adap/flower/" -"pull/2676), [#2644](https://github.com/adap/flower/pull/2644), [#2656]" -"(https://github.com/adap/flower/pull/2656), [#2848](https://github.com/adap/" -"flower/pull/2848), [#2675](https://github.com/adap/flower/pull/2675), [#2735]" -"(https://github.com/adap/flower/pull/2735), [#2767](https://github.com/adap/" -"flower/pull/2767), [#2732](https://github.com/adap/flower/pull/2732), [#2744]" -"(https://github.com/adap/flower/pull/2744), [#2681](https://github.com/adap/" -"flower/pull/2681), [#2699](https://github.com/adap/flower/pull/2699), [#2745]" -"(https://github.com/adap/flower/pull/2745), [#2734](https://github.com/adap/" -"flower/pull/2734), [#2731](https://github.com/adap/flower/pull/2731), [#2652]" -"(https://github.com/adap/flower/pull/2652), [#2720](https://github.com/adap/" -"flower/pull/2720), [#2721](https://github.com/adap/flower/pull/2721), [#2717]" -"(https://github.com/adap/flower/pull/2717), [#2864](https://github.com/adap/" -"flower/pull/2864), [#2694](https://github.com/adap/flower/pull/2694), [#2709]" -"(https://github.com/adap/flower/pull/2709), [#2658](https://github.com/adap/" -"flower/pull/2658), [#2796](https://github.com/adap/flower/pull/2796), [#2692]" -"(https://github.com/adap/flower/pull/2692), [#2657](https://github.com/adap/" -"flower/pull/2657), [#2813](https://github.com/adap/flower/pull/2813), [#2661]" -"(https://github.com/adap/flower/pull/2661), [#2398](https://github.com/adap/" -"flower/pull/2398))" -msgstr "" - -#: ../../source/ref-changelog.md:74 -msgid "" -"The Flower testing and development infrastructure has received substantial " -"updates. This makes Flower 1.7 the most tested release ever." -msgstr "" - -#: ../../source/ref-changelog.md:76 -#, fuzzy -msgid "" -"**Update dependencies** ([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), [#2739](https://github." -"com/adap/flower/pull/2739), [#2837](https://github.com/adap/flower/" -"pull/2837), [#2788](https://github.com/adap/flower/pull/2788), [#2811]" -"(https://github.com/adap/flower/pull/2811), [#2774](https://github.com/adap/" -"flower/pull/2774), [#2790](https://github.com/adap/flower/pull/2790), [#2751]" -"(https://github.com/adap/flower/pull/2751), [#2850](https://github.com/adap/" -"flower/pull/2850), [#2812](https://github.com/adap/flower/pull/2812), [#2872]" -"(https://github.com/adap/flower/pull/2872), [#2736](https://github.com/adap/" -"flower/pull/2736), [#2756](https://github.com/adap/flower/pull/2756), [#2857]" -"(https://github.com/adap/flower/pull/2857), [#2757](https://github.com/adap/" -"flower/pull/2757), [#2810](https://github.com/adap/flower/pull/2810), [#2740]" -"(https://github.com/adap/flower/pull/2740), [#2789](https://github.com/adap/" -"flower/pull/2789))" -msgstr "" -"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), [#1873]" -"(https://github.com/adap/flower/pull/1873), [#1981](https://github.com/adap/" -"flower/pull/1981), [#1988](https://github.com/adap/flower/pull/1988), [#1984]" -"(https://github.com/adap/flower/pull/1984), [#1982](https://github.com/adap/" -"flower/pull/1982), [#2112](https://github.com/adap/flower/pull/2112), [#2144]" -"(https://github.com/adap/flower/pull/2144), [#2174](https://github.com/adap/" -"flower/pull/2174), [#2225](https://github.com/adap/flower/pull/2225), [#2183]" -"(https://github.com/adap/flower/pull/2183))" - -#: ../../source/ref-changelog.md:78 -msgid "" -"**General improvements** ([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." -"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/" -"pull/2690), [#2889](https://github.com/adap/flower/pull/2889), [#2874]" -"(https://github.com/adap/flower/pull/2874), [#2819](https://github.com/adap/" -"flower/pull/2819), [#2689](https://github.com/adap/flower/pull/2689), [#2457]" -"(https://github.com/adap/flower/pull/2457), [#2870](https://github.com/adap/" -"flower/pull/2870), [#2669](https://github.com/adap/flower/pull/2669), [#2876]" -"(https://github.com/adap/flower/pull/2876), [#2885](https://github.com/adap/" -"flower/pull/2885), [#2858](https://github.com/adap/flower/pull/2858), [#2867]" -"(https://github.com/adap/flower/pull/2867), [#2351](https://github.com/adap/" -"flower/pull/2351), [#2886](https://github.com/adap/flower/pull/2886), [#2860]" -"(https://github.com/adap/flower/pull/2860), [#2828](https://github.com/adap/" -"flower/pull/2828), [#2869](https://github.com/adap/flower/pull/2869), [#2875]" -"(https://github.com/adap/flower/pull/2875), [#2733](https://github.com/adap/" -"flower/pull/2733), [#2488](https://github.com/adap/flower/pull/2488), [#2646]" -"(https://github.com/adap/flower/pull/2646), [#2879](https://github.com/adap/" -"flower/pull/2879), [#2821](https://github.com/adap/flower/pull/2821), [#2855]" -"(https://github.com/adap/flower/pull/2855), [#2800](https://github.com/adap/" -"flower/pull/2800), [#2807](https://github.com/adap/flower/pull/2807), [#2801]" -"(https://github.com/adap/flower/pull/2801), [#2804](https://github.com/adap/" -"flower/pull/2804), [#2851](https://github.com/adap/flower/pull/2851), [#2787]" -"(https://github.com/adap/flower/pull/2787), [#2852](https://github.com/adap/" -"flower/pull/2852), [#2672](https://github.com/adap/flower/pull/2672), [#2759]" -"(https://github.com/adap/flower/pull/2759))" -msgstr "" - -#: ../../source/ref-changelog.md:82 -#, fuzzy -msgid "" -"**Deprecate** `start_numpy_client` ([#2563](https://github.com/adap/flower/" -"pull/2563), [#2718](https://github.com/adap/flower/pull/2718))" -msgstr "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" -"github.com/adap/flower/pull/2508))" - -#: ../../source/ref-changelog.md:84 +#: ../../source/ref-changelog.md:136 +#, fuzzy +msgid "" +"**Improve documentation** " +"([#2674](https://github.com/adap/flower/pull/2674), " +"[#2480](https://github.com/adap/flower/pull/2480), " +"[#2826](https://github.com/adap/flower/pull/2826), " +"[#2727](https://github.com/adap/flower/pull/2727), " +"[#2761](https://github.com/adap/flower/pull/2761), " +"[#2900](https://github.com/adap/flower/pull/2900))" +msgstr "" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614)))" + +#: ../../source/ref-changelog.md:138 msgid "" -"Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we have " -"introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need to " -"first call the `.to_client()` method and then pass returned `Client` object " -"to `start_client`. The examples and the documentation have been updated " -"accordingly." +"**Improved testing and development infrastructure** " +"([#2797](https://github.com/adap/flower/pull/2797), " +"[#2676](https://github.com/adap/flower/pull/2676), " +"[#2644](https://github.com/adap/flower/pull/2644), " +"[#2656](https://github.com/adap/flower/pull/2656), " +"[#2848](https://github.com/adap/flower/pull/2848), " +"[#2675](https://github.com/adap/flower/pull/2675), " +"[#2735](https://github.com/adap/flower/pull/2735), " +"[#2767](https://github.com/adap/flower/pull/2767), " +"[#2732](https://github.com/adap/flower/pull/2732), " +"[#2744](https://github.com/adap/flower/pull/2744), " +"[#2681](https://github.com/adap/flower/pull/2681), " +"[#2699](https://github.com/adap/flower/pull/2699), " +"[#2745](https://github.com/adap/flower/pull/2745), " +"[#2734](https://github.com/adap/flower/pull/2734), " +"[#2731](https://github.com/adap/flower/pull/2731), " +"[#2652](https://github.com/adap/flower/pull/2652), " +"[#2720](https://github.com/adap/flower/pull/2720), " +"[#2721](https://github.com/adap/flower/pull/2721), " +"[#2717](https://github.com/adap/flower/pull/2717), " +"[#2864](https://github.com/adap/flower/pull/2864), " +"[#2694](https://github.com/adap/flower/pull/2694), " +"[#2709](https://github.com/adap/flower/pull/2709), " +"[#2658](https://github.com/adap/flower/pull/2658), " +"[#2796](https://github.com/adap/flower/pull/2796), " +"[#2692](https://github.com/adap/flower/pull/2692), " +"[#2657](https://github.com/adap/flower/pull/2657), " +"[#2813](https://github.com/adap/flower/pull/2813), " +"[#2661](https://github.com/adap/flower/pull/2661), " +"[#2398](https://github.com/adap/flower/pull/2398))" +msgstr "" + +#: ../../source/ref-changelog.md:140 +msgid "" +"The Flower testing and development infrastructure has received " +"substantial updates. This makes Flower 1.7 the most tested release ever." +msgstr "" + +#: ../../source/ref-changelog.md:142 +#, fuzzy +msgid "" +"**Update dependencies** " +"([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), " +"[#2739](https://github.com/adap/flower/pull/2739), " +"[#2837](https://github.com/adap/flower/pull/2837), " +"[#2788](https://github.com/adap/flower/pull/2788), " +"[#2811](https://github.com/adap/flower/pull/2811), " +"[#2774](https://github.com/adap/flower/pull/2774), " +"[#2790](https://github.com/adap/flower/pull/2790), " +"[#2751](https://github.com/adap/flower/pull/2751), " +"[#2850](https://github.com/adap/flower/pull/2850), " +"[#2812](https://github.com/adap/flower/pull/2812), " +"[#2872](https://github.com/adap/flower/pull/2872), " +"[#2736](https://github.com/adap/flower/pull/2736), " +"[#2756](https://github.com/adap/flower/pull/2756), " +"[#2857](https://github.com/adap/flower/pull/2857), " +"[#2757](https://github.com/adap/flower/pull/2757), " +"[#2810](https://github.com/adap/flower/pull/2810), " +"[#2740](https://github.com/adap/flower/pull/2740), " +"[#2789](https://github.com/adap/flower/pull/2789))" +msgstr "" +"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), " +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" + +#: ../../source/ref-changelog.md:144 +msgid "" +"**General improvements** " +"([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), " +"[#2877](https://github.com/adap/flower/pull/2877), " +"[#2690](https://github.com/adap/flower/pull/2690), " +"[#2889](https://github.com/adap/flower/pull/2889), " +"[#2874](https://github.com/adap/flower/pull/2874), " +"[#2819](https://github.com/adap/flower/pull/2819), " +"[#2689](https://github.com/adap/flower/pull/2689), " +"[#2457](https://github.com/adap/flower/pull/2457), " +"[#2870](https://github.com/adap/flower/pull/2870), " +"[#2669](https://github.com/adap/flower/pull/2669), " +"[#2876](https://github.com/adap/flower/pull/2876), " +"[#2885](https://github.com/adap/flower/pull/2885), " +"[#2858](https://github.com/adap/flower/pull/2858), " +"[#2867](https://github.com/adap/flower/pull/2867), " +"[#2351](https://github.com/adap/flower/pull/2351), " +"[#2886](https://github.com/adap/flower/pull/2886), " +"[#2860](https://github.com/adap/flower/pull/2860), " +"[#2828](https://github.com/adap/flower/pull/2828), " +"[#2869](https://github.com/adap/flower/pull/2869), " +"[#2875](https://github.com/adap/flower/pull/2875), " +"[#2733](https://github.com/adap/flower/pull/2733), " +"[#2488](https://github.com/adap/flower/pull/2488), " +"[#2646](https://github.com/adap/flower/pull/2646), " +"[#2879](https://github.com/adap/flower/pull/2879), " +"[#2821](https://github.com/adap/flower/pull/2821), " +"[#2855](https://github.com/adap/flower/pull/2855), " +"[#2800](https://github.com/adap/flower/pull/2800), " +"[#2807](https://github.com/adap/flower/pull/2807), " +"[#2801](https://github.com/adap/flower/pull/2801), " +"[#2804](https://github.com/adap/flower/pull/2804), " +"[#2851](https://github.com/adap/flower/pull/2851), " +"[#2787](https://github.com/adap/flower/pull/2787), " +"[#2852](https://github.com/adap/flower/pull/2852), " +"[#2672](https://github.com/adap/flower/pull/2672), " +"[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" -#: ../../source/ref-changelog.md:86 +#: ../../source/ref-changelog.md:148 #, fuzzy msgid "" -"**Deprecate legacy DP wrappers** ([#2749](https://github.com/adap/flower/" -"pull/2749))" +"**Deprecate** `start_numpy_client` " +"([#2563](https://github.com/adap/flower/pull/2563), " +"[#2718](https://github.com/adap/flower/pull/2718))" +msgstr "" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" + +#: ../../source/ref-changelog.md:150 +msgid "" +"Until now, clients of type `NumPyClient` needed to be started via " +"`start_numpy_client`. In our efforts to consolidate framework APIs, we " +"have introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need " +"to first call the `.to_client()` method and then pass returned `Client` " +"object to `start_client`. The examples and the documentation have been " +"updated accordingly." msgstr "" -"**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:88 +#: ../../source/ref-changelog.md:152 +#, fuzzy +msgid "" +"**Deprecate legacy DP wrappers** " +"([#2749](https://github.com/adap/flower/pull/2749))" +msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" + +#: ../../source/ref-changelog.md:154 msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is in " -"preparation for an all-new pluggable version of differential privacy support " -"in Flower." +"Legacy DP wrapper classes are deprecated, but still functional. This is " +"in preparation for an all-new pluggable version of differential privacy " +"support in Flower." msgstr "" -#: ../../source/ref-changelog.md:90 +#: ../../source/ref-changelog.md:156 #, fuzzy msgid "" "**Make optional arg** `--callable` **in** `flower-client` **a required " "positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" -"**从** `start_client` 中移除** `rest` **实验参数 ([#2324](https://github.com/" -"adap/flower/pull/2324))" +"**从** `start_client` 中移除** `rest` **实验参数 " +"([#2324](https://github.com/adap/flower/pull/2324))" -#: ../../source/ref-changelog.md:92 +#: ../../source/ref-changelog.md:158 #, fuzzy msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` ([#2890]" -"(https://github.com/adap/flower/pull/2890))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " +"([#2890](https://github.com/adap/flower/pull/2890))" msgstr "" -"**重新命名** `rnd` ** to** `server_round` ([#1321](https://github.com/adap/" -"flower/pull/1321))" +"**重新命名** `rnd` ** to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:94 +#: ../../source/ref-changelog.md:160 #, fuzzy msgid "" -"**Drop experimental** `Task` **fields** ([#2866](https://github.com/adap/" -"flower/pull/2866), [#2865](https://github.com/adap/flower/pull/2865))" +"**Drop experimental** `Task` **fields** " +"([#2866](https://github.com/adap/flower/pull/2866), " +"[#2865](https://github.com/adap/flower/pull/2865))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" -"github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:96 +#: ../../source/ref-changelog.md:162 msgid "" "Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed fields " -"are superseded by the new `RecordSet` abstraction." +"`legacy_client_message` were removed from `Task` message. The removed " +"fields are superseded by the new `RecordSet` abstraction." msgstr "" -#: ../../source/ref-changelog.md:98 +#: ../../source/ref-changelog.md:164 #, fuzzy msgid "" -"**Retire MXNet examples** ([#2724](https://github.com/adap/flower/pull/2724))" -msgstr "" -"**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/" -"pull/748))" +"**Retire MXNet examples** " +"([#2724](https://github.com/adap/flower/pull/2724))" +msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:100 +#: ../../source/ref-changelog.md:166 msgid "" "The development of the MXNet fremework has ended and the project is now " "[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " "examples won't receive updates." msgstr "" -#: ../../source/ref-changelog.md:102 +#: ../../source/ref-changelog.md:168 #, fuzzy msgid "v1.6.0 (2023-11-28)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:108 +#: ../../source/ref-changelog.md:174 msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, " -"`Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " -"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " -"`k3nfalt` " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," +" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " +"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " +"`cnxdeveloper`, `k3nfalt` " msgstr "" -#: ../../source/ref-changelog.md:112 +#: ../../source/ref-changelog.md:178 msgid "" -"**Add experimental support for Python 3.12** ([#2565](https://github.com/" -"adap/flower/pull/2565))" +"**Add experimental support for Python 3.12** " +"([#2565](https://github.com/adap/flower/pull/2565))" msgstr "" -"** 增加对 Python 3.12 的实验支持** ([#2565](https://github.com/adap/flower/" -"pull/2565))" +"** 增加对 Python 3.12 的实验支持** " +"([#2565](https://github.com/adap/flower/pull/2565))" -#: ../../source/ref-changelog.md:114 +#: ../../source/ref-changelog.md:180 #, fuzzy msgid "" -"**Add new XGBoost examples** ([#2612](https://github.com/adap/flower/" -"pull/2612), [#2554](https://github.com/adap/flower/pull/2554), [#2617]" -"(https://github.com/adap/flower/pull/2617), [#2618](https://github.com/adap/" -"flower/pull/2618), [#2619](https://github.com/adap/flower/pull/2619), [#2567]" -"(https://github.com/adap/flower/pull/2567))" +"**Add new XGBoost examples** " +"([#2612](https://github.com/adap/flower/pull/2612), " +"[#2554](https://github.com/adap/flower/pull/2554), " +"[#2617](https://github.com/adap/flower/pull/2617), " +"[#2618](https://github.com/adap/flower/pull/2618), " +"[#2619](https://github.com/adap/flower/pull/2619), " +"[#2567](https://github.com/adap/flower/pull/2567))" msgstr "" -"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/" -"pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" -"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" -"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" -"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" -"flower/pull/1567))" +"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/pull/1520)," +" [#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:116 +#: ../../source/ref-changelog.md:182 msgid "" -"We have added a new `xgboost-quickstart` example alongside a new `xgboost-" -"comprehensive` example that goes more in-depth." +"We have added a new `xgboost-quickstart` example alongside a new " +"`xgboost-comprehensive` example that goes more in-depth." msgstr "" -#: ../../source/ref-changelog.md:118 +#: ../../source/ref-changelog.md:184 #, fuzzy msgid "" -"**Add Vertical FL example** ([#2598](https://github.com/adap/flower/" -"pull/2598))" -msgstr "" -"**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/" -"pull/1289))" +"**Add Vertical FL example** " +"([#2598](https://github.com/adap/flower/pull/2598))" +msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:120 +#: ../../source/ref-changelog.md:186 msgid "" -"We had many questions about Vertical Federated Learning using Flower, so we " -"decided to add an simple example for it on the [Titanic dataset](https://www." -"kaggle.com/competitions/titanic/data) alongside a tutorial (in the README)." +"We had many questions about Vertical Federated Learning using Flower, so " +"we decided to add an simple example for it on the [Titanic " +"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " +"tutorial (in the README)." msgstr "" -#: ../../source/ref-changelog.md:122 +#: ../../source/ref-changelog.md:188 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` ([#2292](https://" -"github.com/adap/flower/pull/2292))" -msgstr "" -"**在***`start_driver()`中支持自定义***`ClientManager([#2292](https://github." -"com/adap/flower/pull/2292))" +"**Support custom** `ClientManager` **in** `start_driver()` " +"([#2292](https://github.com/adap/flower/pull/2292))" +msgstr "**在***`start_driver()`中支持自定义***`ClientManager([#2292](https://github.com/adap/flower/pull/2292))" -#: ../../source/ref-changelog.md:124 +#: ../../source/ref-changelog.md:190 msgid "" -"**Update REST API to support create and delete nodes** ([#2283](https://" -"github.com/adap/flower/pull/2283))" +"**Update REST API to support create and delete nodes** " +"([#2283](https://github.com/adap/flower/pull/2283))" msgstr "" -"**更新 REST API 以支持创建和删除节点** ([#2283](https://github.com/adap/" -"flower/pull/2283))" +"**更新 REST API 以支持创建和删除节点** " +"([#2283](https://github.com/adap/flower/pull/2283))" -#: ../../source/ref-changelog.md:126 +#: ../../source/ref-changelog.md:192 #, fuzzy msgid "" -"**Update the Android SDK** ([#2187](https://github.com/adap/flower/" -"pull/2187))" +"**Update the Android SDK** " +"([#2187](https://github.com/adap/flower/pull/2187))" msgstr "" -"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" -"pull/2131))" +"**介绍Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" -#: ../../source/ref-changelog.md:128 +#: ../../source/ref-changelog.md:194 #, fuzzy msgid "Add gRPC request-response capability to the Android SDK." msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" -#: ../../source/ref-changelog.md:130 +#: ../../source/ref-changelog.md:196 #, fuzzy msgid "" -"**Update the C++ SDK** ([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), [#2523](https://github." -"com/adap/flower/pull/2523), [#2522](https://github.com/adap/flower/" -"pull/2522))" +"**Update the C++ SDK** " +"([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" msgstr "" -"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), [#2528]" -"(https://github/com/adap/flower/pull/2528), [#2523](https://github.com/adap/" -"flower/pull/2523), [#2522](https://github.com/adap/flower/pull/2522))" +"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), " +"[#2528](https://github/com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" -#: ../../source/ref-changelog.md:132 +#: ../../source/ref-changelog.md:198 msgid "Add gRPC request-response capability to the C++ SDK." msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" -#: ../../source/ref-changelog.md:134 +#: ../../source/ref-changelog.md:200 #, fuzzy msgid "" -"**Make HTTPS the new default** ([#2591](https://github.com/adap/flower/" -"pull/2591), [#2636](https://github.com/adap/flower/pull/2636))" +"**Make HTTPS the new default** " +"([#2591](https://github.com/adap/flower/pull/2591), " +"[#2636](https://github.com/adap/flower/pull/2636))" msgstr "" -"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), [#2400]" -"(https://github.com/adap/flower/pull/2400)" +"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400)" -#: ../../source/ref-changelog.md:136 +#: ../../source/ref-changelog.md:202 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP for " -"prototyping. The same applies to `flower-client`, which can either use user-" -"provided credentials or gRPC-bundled certificates to connect to an HTTPS-" -"enabled server or requires opt-out via passing `--insecure` to enable " -"insecure HTTP connections." +"passing `--certificates`, but users can enable `--insecure` to use HTTP " +"for prototyping. The same applies to `flower-client`, which can either " +"use user-provided credentials or gRPC-bundled certificates to connect to " +"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " +"enable insecure HTTP connections." msgstr "" -#: ../../source/ref-changelog.md:138 +#: ../../source/ref-changelog.md:204 msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` will " -"still start in insecure mode by default. In a future release, insecure " -"connections will require user opt-in by passing `insecure=True`." +"For backward compatibility, `start_client()` and `start_numpy_client()` " +"will still start in insecure mode by default. In a future release, " +"insecure connections will require user opt-in by passing `insecure=True`." msgstr "" -#: ../../source/ref-changelog.md:140 +#: ../../source/ref-changelog.md:206 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), [#2493](https://github." -"com/adap/flower/pull/2493))" +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" msgstr "" -"** 统一客户端应用程序接口** ([#2303](https://github.com/adap/flower/" -"pull/2303), [#2390](https://github.com/adap/flower/pull/2390), [#2493]" -"(https://github.com/adap/flower/pull/2493))" +"** 统一客户端应用程序接口** ([#2303](https://github.com/adap/flower/pull/2303), " +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" -#: ../../source/ref-changelog.md:142 +#: ../../source/ref-changelog.md:208 #, fuzzy msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as standalone " -"processes (i.e. via `start_client`) or in simulation (i.e. via " -"`start_simulation`) without requiring changes to how the client class is " -"defined and instantiated. The `to_client()` function is introduced to " +"Using the `client_fn`, Flower clients can interchangeably run as " +"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" +" `start_simulation`) without requiring changes to how the client class is" +" defined and instantiated. The `to_client()` function is introduced to " "convert a `NumPyClient` to a `Client`." msgstr "" -"使用 `client_fn`,Flower 客户端可以作为独立进程(即通过 `start_client`)或在" -"模拟中(即通过 `start_simulation`)交替运行,而无需更改客户端类的定义和实例化" -"方式。调用 `start_numpy_client` 现已过时。" +"使用 `client_fn`,Flower 客户端可以作为独立进程(即通过 `start_client`)或在模拟中(即通过 " +"`start_simulation`)交替运行,而无需更改客户端类的定义和实例化方式。调用 `start_numpy_client` 现已过时。" -#: ../../source/ref-changelog.md:144 +#: ../../source/ref-changelog.md:210 msgid "" -"**Add new** `Bulyan` **strategy** ([#1817](https://github.com/adap/flower/" -"pull/1817), [#1891](https://github.com/adap/flower/pull/1891))" +"**Add new** `Bulyan` **strategy** " +"([#1817](https://github.com/adap/flower/pull/1817), " +"[#1891](https://github.com/adap/flower/pull/1891))" msgstr "" -"**添加新**\"Bulyan \"**策略**([#1817](https://github.com/adap/flower/" -"pull/1817), [#1891](https://github.com/adap/flower/pull/1891)" +"**添加新**\"Bulyan " +"\"**策略**([#1817](https://github.com/adap/flower/pull/1817), " +"[#1891](https://github.com/adap/flower/pull/1891)" -#: ../../source/ref-changelog.md:146 +#: ../../source/ref-changelog.md:212 msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., 2018]" -"(https://arxiv.org/abs/1802.07927)" -msgstr "" -"新的 \"Bulyan\"策略通过[El Mhamdi 等人,2018](https://arxiv.org/" -"abs/1802.07927)实现" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " +"2018](https://arxiv.org/abs/1802.07927)" +msgstr "新的 \"Bulyan\"策略通过[El Mhamdi 等人,2018](https://arxiv.org/abs/1802.07927)实现" -#: ../../source/ref-changelog.md:148 +#: ../../source/ref-changelog.md:214 #, fuzzy msgid "" -"**Add new** `XGB Bagging` **strategy** ([#2611](https://github.com/adap/" -"flower/pull/2611))" -msgstr "" -"**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/" -"pull/1619))" +"**Add new** `XGB Bagging` **strategy** " +"([#2611](https://github.com/adap/flower/pull/2611))" +msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:150 ../../source/ref-changelog.md:152 +#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 #, fuzzy msgid "" -"**Introduce `WorkloadState`** ([#2564](https://github.com/adap/flower/" -"pull/2564), [#2632](https://github.com/adap/flower/pull/2632))" +"**Introduce `WorkloadState`** " +"([#2564](https://github.com/adap/flower/pull/2564), " +"[#2632](https://github.com/adap/flower/pull/2632))" msgstr "" -"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) [#822]" -"(https://github.com/adap/flower/pull/822)" +"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822)" -#: ../../source/ref-changelog.md:156 +#: ../../source/ref-changelog.md:222 msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" -"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" -"pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " +"[#2286](https://github.com/adap/flower/pull/2286), " +"[#2509](https://github.com/adap/flower/pull/2509))" msgstr "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" -"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" -"pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " +"[#2286](https://github.com/adap/flower/pull/2286), " +"[#2509](https://github.com/adap/flower/pull/2509))" -#: ../../source/ref-changelog.md:158 +#: ../../source/ref-changelog.md:224 msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), [#2400]" -"(https://github.com/adap/flower/pull/2400))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400))" msgstr "" -"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), [#2400]" -"(https://github.com/adap/flower/pull/2400)" +"Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400)" -#: ../../source/ref-changelog.md:160 +#: ../../source/ref-changelog.md:226 msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" -"github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " +"[#2507](https://github.com/adap/flower/pull/2507))" msgstr "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" -"github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " +"[#2507](https://github.com/adap/flower/pull/2507))" -#: ../../source/ref-changelog.md:162 +#: ../../source/ref-changelog.md:228 msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" -"github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" msgstr "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" -"github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" -#: ../../source/ref-changelog.md:164 +#: ../../source/ref-changelog.md:230 msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" -#: ../../source/ref-changelog.md:166 +#: ../../source/ref-changelog.md:232 msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:168 +#: ../../source/ref-changelog.md:234 msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "MOON [#2421](https://github.com/adap/flower/pull/2421)" -#: ../../source/ref-changelog.md:170 +#: ../../source/ref-changelog.md:236 msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" -#: ../../source/ref-changelog.md:172 +#: ../../source/ref-changelog.md:238 msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:174 +#: ../../source/ref-changelog.md:240 msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" -#: ../../source/ref-changelog.md:176 +#: ../../source/ref-changelog.md:242 msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:244 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" -"github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" msgstr "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" -"github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:180 +#: ../../source/ref-changelog.md:246 #, fuzzy msgid "" -"**General updates to Flower Examples** ([#2384](https://github.com/adap/" -"flower/pull/2384), [#2425](https://github.com/adap/flower/pull/2425), [#2526]" -"(https://github.com/adap/flower/pull/2526), [#2302](https://github.com/adap/" -"flower/pull/2302), [#2545](https://github.com/adap/flower/pull/2545))" +"**General updates to Flower Examples** " +"([#2384](https://github.com/adap/flower/pull/2384), " +"[#2425](https://github.com/adap/flower/pull/2425), " +"[#2526](https://github.com/adap/flower/pull/2526), " +"[#2302](https://github.com/adap/flower/pull/2302), " +"[#2545](https://github.com/adap/flower/pull/2545))" msgstr "" -"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), [#2528]" -"(https://github/com/adap/flower/pull/2528), [#2523](https://github.com/adap/" -"flower/pull/2523), [#2522](https://github.com/adap/flower/pull/2522))" +"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), " +"[#2528](https://github/com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:248 #, fuzzy msgid "" -"**General updates to Flower Baselines** ([#2301](https://github.com/adap/" -"flower/pull/2301), [#2305](https://github.com/adap/flower/pull/2305), [#2307]" -"(https://github.com/adap/flower/pull/2307), [#2327](https://github.com/adap/" -"flower/pull/2327), [#2435](https://github.com/adap/flower/pull/2435), [#2462]" -"(https://github.com/adap/flower/pull/2462), [#2463](https://github.com/adap/" -"flower/pull/2463), [#2461](https://github.com/adap/flower/pull/2461), [#2469]" -"(https://github.com/adap/flower/pull/2469), [#2466](https://github.com/adap/" -"flower/pull/2466), [#2471](https://github.com/adap/flower/pull/2471), [#2472]" -"(https://github.com/adap/flower/pull/2472), [#2470](https://github.com/adap/" -"flower/pull/2470))" -msgstr "" -"**普通改进**([#2309](https://github.com/adap/flower/pull/2309), [#2310]" -"(https://github.com/adap/flower/pull/2310), [2313](https://github.com/adap/" -"flower/pull/2313), [#2316](https://github.com/adap/flower/pull/2316), [2317]" -"(https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/" -"flower/pull/2349), [#2360](https://github.com/adap/flower/pull/2360), [#2402]" -"(https://github.com/adap/flower/pull/2402), [#2446](https://github.com/adap/" -"flower/pull/2446) [#2561](https://github.com/adap/flower/pull/2561))" +"**General updates to Flower Baselines** " +"([#2301](https://github.com/adap/flower/pull/2301), " +"[#2305](https://github.com/adap/flower/pull/2305), " +"[#2307](https://github.com/adap/flower/pull/2307), " +"[#2327](https://github.com/adap/flower/pull/2327), " +"[#2435](https://github.com/adap/flower/pull/2435), " +"[#2462](https://github.com/adap/flower/pull/2462), " +"[#2463](https://github.com/adap/flower/pull/2463), " +"[#2461](https://github.com/adap/flower/pull/2461), " +"[#2469](https://github.com/adap/flower/pull/2469), " +"[#2466](https://github.com/adap/flower/pull/2466), " +"[#2471](https://github.com/adap/flower/pull/2471), " +"[#2472](https://github.com/adap/flower/pull/2472), " +"[#2470](https://github.com/adap/flower/pull/2470))" +msgstr "" +"**普通改进**([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), " +"[2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[2317](https://github.com/adap/flower/pull/2317),[#2349](https://github.com/adap/flower/pull/2349)," +" [#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446) " +"[#2561](https://github.com/adap/flower/pull/2561))" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:250 #, fuzzy msgid "" -"**General updates to the simulation engine** ([#2331](https://github.com/" -"adap/flower/pull/2331), [#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), [#2294](https://github." -"com/adap/flower/pull/2294))" +"**General updates to the simulation engine** " +"([#2331](https://github.com/adap/flower/pull/2331), " +"[#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), " +"[#2294](https://github.com/adap/flower/pull/2294))" msgstr "" "**模拟引擎的普通更新** ([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), [#2448](https://github." -"com/adap/flower/pull/2448))" +"[#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448))" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:252 #, fuzzy msgid "" -"**General updates to Flower SDKs** ([#2288](https://github.com/adap/flower/" -"pull/2288), [#2429](https://github.com/adap/flower/pull/2429), [#2555]" -"(https://github.com/adap/flower/pull/2555), [#2543](https://github.com/adap/" -"flower/pull/2543), [#2544](https://github.com/adap/flower/pull/2544), [#2597]" -"(https://github.com/adap/flower/pull/2597), [#2623](https://github.com/adap/" -"flower/pull/2623))" +"**General updates to Flower SDKs** " +"([#2288](https://github.com/adap/flower/pull/2288), " +"[#2429](https://github.com/adap/flower/pull/2429), " +"[#2555](https://github.com/adap/flower/pull/2555), " +"[#2543](https://github.com/adap/flower/pull/2543), " +"[#2544](https://github.com/adap/flower/pull/2544), " +"[#2597](https://github.com/adap/flower/pull/2597), " +"[#2623](https://github.com/adap/flower/pull/2623))" msgstr "" -"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), [#1470]" -"(https://github.com/adap/flower/pull/1470), [#1472](https://github.com/adap/" -"flower/pull/1472), [#1473](https://github.com/adap/flower/pull/1473), [#1474]" -"(https://github.com/adap/flower/pull/1474), [#1475](https://github.com/adap/" -"flower/pull/1475)))" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475)))" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:254 msgid "" -"**General improvements** ([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." -"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/" -"pull/2316), [#2317](https://github.com/adap/flower/pull/2317), [#2349]" -"(https://github.com/adap/flower/pull/2349), [#2360](https://github.com/adap/" -"flower/pull/2360), [#2402](https://github.com/adap/flower/pull/2402), [#2446]" -"(https://github.com/adap/flower/pull/2446), [#2561](https://github.com/adap/" -"flower/pull/2561), [#2273](https://github.com/adap/flower/pull/2273), [#2267]" -"(https://github.com/adap/flower/pull/2267), [#2274](https://github.com/adap/" -"flower/pull/2274), [#2275](https://github.com/adap/flower/pull/2275), [#2432]" -"(https://github.com/adap/flower/pull/2432), [#2251](https://github.com/adap/" -"flower/pull/2251), [#2321](https://github.com/adap/flower/pull/2321), [#1936]" -"(https://github.com/adap/flower/pull/1936), [#2408](https://github.com/adap/" -"flower/pull/2408), [#2413](https://github.com/adap/flower/pull/2413), [#2401]" -"(https://github.com/adap/flower/pull/2401), [#2531](https://github.com/adap/" -"flower/pull/2531), [#2534](https://github.com/adap/flower/pull/2534), [#2535]" -"(https://github.com/adap/flower/pull/2535), [#2521](https://github.com/adap/" -"flower/pull/2521), [#2553](https://github.com/adap/flower/pull/2553), [#2596]" -"(https://github.com/adap/flower/pull/2596))" -msgstr "" - -#: ../../source/ref-changelog.md:190 ../../source/ref-changelog.md:280 -#: ../../source/ref-changelog.md:344 ../../source/ref-changelog.md:398 -#: ../../source/ref-changelog.md:465 -msgid "" -"Flower received many improvements under the hood, too many to list here." +"**General improvements** " +"([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), " +"[#2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[#2317](https://github.com/adap/flower/pull/2317), " +"[#2349](https://github.com/adap/flower/pull/2349), " +"[#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446), " +"[#2561](https://github.com/adap/flower/pull/2561), " +"[#2273](https://github.com/adap/flower/pull/2273), " +"[#2267](https://github.com/adap/flower/pull/2267), " +"[#2274](https://github.com/adap/flower/pull/2274), " +"[#2275](https://github.com/adap/flower/pull/2275), " +"[#2432](https://github.com/adap/flower/pull/2432), " +"[#2251](https://github.com/adap/flower/pull/2251), " +"[#2321](https://github.com/adap/flower/pull/2321), " +"[#1936](https://github.com/adap/flower/pull/1936), " +"[#2408](https://github.com/adap/flower/pull/2408), " +"[#2413](https://github.com/adap/flower/pull/2413), " +"[#2401](https://github.com/adap/flower/pull/2401), " +"[#2531](https://github.com/adap/flower/pull/2531), " +"[#2534](https://github.com/adap/flower/pull/2534), " +"[#2535](https://github.com/adap/flower/pull/2535), " +"[#2521](https://github.com/adap/flower/pull/2521), " +"[#2553](https://github.com/adap/flower/pull/2553), " +"[#2596](https://github.com/adap/flower/pull/2596))" +msgstr "" + +#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 +#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 +#: ../../source/ref-changelog.md:531 +msgid "Flower received many improvements under the hood, too many to list here." msgstr "Flower 进行了许多改进,这里就不一一列举了。" -#: ../../source/ref-changelog.md:194 +#: ../../source/ref-changelog.md:260 msgid "" -"**Remove support for Python 3.7** ([#2280](https://github.com/adap/flower/" -"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" -"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" -"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" -"(https://github.com/adap/flower/pull/2356))" -msgstr "" -"**移除对 Python 3.7 的支持** ([#2280](https://github.com/adap/flower/" -"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" -"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" -"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" -"(https://github.com/adap/flower/pull/2356))" +"**Remove support for Python 3.7** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" +msgstr "" +"**移除对 Python 3.7 的支持** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:262 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes " -"support. Flower now requires Python 3.8." -msgstr "" -"在 Flower 1.5 中,Python 3.7 支持已被弃用,本版本将删除该支持。Flower 现在需" -"要 Python 3.8。" +"Python 3.7 support was deprecated in Flower 1.5, and this release removes" +" support. Flower now requires Python 3.8." +msgstr "在 Flower 1.5 中,Python 3.7 支持已被弃用,本版本将删除该支持。Flower 现在需要 Python 3.8。" -#: ../../source/ref-changelog.md:198 +#: ../../source/ref-changelog.md:264 msgid "" -"**Remove experimental argument** `rest` **from** `start_client` ([#2324]" -"(https://github.com/adap/flower/pull/2324))" +"**Remove experimental argument** `rest` **from** `start_client` " +"([#2324](https://github.com/adap/flower/pull/2324))" msgstr "" -"**从** `start_client` 中移除** `rest` **实验参数 ([#2324](https://github.com/" -"adap/flower/pull/2324))" +"**从** `start_client` 中移除** `rest` **实验参数 " +"([#2324](https://github.com/adap/flower/pull/2324))" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:266 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` and " -"`start_numpy_client`. Use `transport=\"rest\"` to opt into the experimental " -"REST API instead." +"The (still experimental) argument `rest` was removed from `start_client` " +"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " +"experimental REST API instead." msgstr "" -"删除了 `start_client` 和 `start_numpy_client` 中的参数 `rest`(仍属试验性" -"质)。请使用 `transport=\"rest\"` 来选择使用试验性 REST API。" +"删除了 `start_client` 和 `start_numpy_client` 中的参数 `rest`(仍属试验性质)。请使用 " +"`transport=\"rest\"` 来选择使用试验性 REST API。" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:268 msgid "v1.5.0 (2023-08-31)" msgstr "v1.5.0 (2023-08-31)" -#: ../../source/ref-changelog.md:208 +#: ../../source/ref-changelog.md:274 msgid "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -16053,766 +17451,831 @@ msgstr "" "Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " -#: ../../source/ref-changelog.md:212 +#: ../../source/ref-changelog.md:278 msgid "" -"**Introduce new simulation engine** ([#1969](https://github.com/adap/flower/" -"pull/1969), [#2221](https://github.com/adap/flower/pull/2221), [#2248]" -"(https://github.com/adap/flower/pull/2248))" +"**Introduce new simulation engine** " +"([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" msgstr "" "**引入新的模拟引擎** ([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), [#2248](https://github." -"com/adap/flower/pull/2248))" +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:280 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and " -"memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-only, " -"CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"remains fully backwards compatible. It offers much improved stability and" +" memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-" +"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -"新的模拟引擎从头开始重新编写,但仍完全向后兼容。它的稳定性和内存处理能力大大" -"提高,尤其是在使用 GPU 时。仿真可透明地适应不同的设置,以在仅 CPU、CPU+GPU、" -"多 GPU 或多节点多 GPU 环境中扩展模拟。" +"新的模拟引擎从头开始重新编写,但仍完全向后兼容。它的稳定性和内存处理能力大大提高,尤其是在使用 GPU 时。仿真可透明地适应不同的设置,以在仅 " +"CPU、CPU+GPU、多 GPU 或多节点多 GPU 环境中扩展模拟。" -#: ../../source/ref-changelog.md:216 +#: ../../source/ref-changelog.md:282 msgid "" -"Comprehensive documentation includes a new [how-to run simulations](https://" -"flower.ai/docs/framework/how-to-run-simulations.html) guide, new [simulation-" +"Comprehensive documentation includes a new [how-to run " +"simulations](https://flower.ai/docs/framework/how-to-run-" +"simulations.html) guide, new [simulation-" +"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " +"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" +"tensorflow.html) notebooks, and a new [YouTube tutorial " +"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +msgstr "" +"综合文档包括新的[how-to run simulations](https://flower.ai/docs/framework/how-to-" +"run-simulations.html) guide, new [simulation-" "pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " "[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial series](https://www." -"youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." -msgstr "" -"综合文档包括新的[how-to run simulations](https://flower.ai/docs/framework/" -"how-to-run-simulations.html) guide, new [simulation-pytorch](https://flower." -"ai/docs/examples/simulation-pytorch.html) and [simulation-tensorflow]" -"(https://flower.ai/docs/examples/simulation-tensorflow.html) notebooks, and " -"a new [YouTube tutorial series](https://www.youtube.com/watch?" -"v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)。" - -#: ../../source/ref-changelog.md:218 -msgid "" -"**Restructure Flower Docs** ([#1824](https://github.com/adap/flower/" -"pull/1824), [#1865](https://github.com/adap/flower/pull/1865), [#1884]" -"(https://github.com/adap/flower/pull/1884), [#1887](https://github.com/adap/" -"flower/pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" -"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" -"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" -"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" -"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" -"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" -"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" -"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" -"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" -"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" -"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" -"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" -"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" -"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" -"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" -"(https://github.com/adap/flower/pull/2227))" +"tensorflow.html) notebooks, and a new [YouTube tutorial " +"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)。" + +#: ../../source/ref-changelog.md:284 +msgid "" +"**Restructure Flower Docs** " +"([#1824](https://github.com/adap/flower/pull/1824), " +"[#1865](https://github.com/adap/flower/pull/1865), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1887](https://github.com/adap/flower/pull/1887), " +"[#1919](https://github.com/adap/flower/pull/1919), " +"[#1922](https://github.com/adap/flower/pull/1922), " +"[#1920](https://github.com/adap/flower/pull/1920), " +"[#1923](https://github.com/adap/flower/pull/1923), " +"[#1924](https://github.com/adap/flower/pull/1924), " +"[#1962](https://github.com/adap/flower/pull/1962), " +"[#2006](https://github.com/adap/flower/pull/2006), " +"[#2133](https://github.com/adap/flower/pull/2133), " +"[#2203](https://github.com/adap/flower/pull/2203), " +"[#2215](https://github.com/adap/flower/pull/2215), " +"[#2122](https://github.com/adap/flower/pull/2122), " +"[#2223](https://github.com/adap/flower/pull/2223), " +"[#2219](https://github.com/adap/flower/pull/2219), " +"[#2232](https://github.com/adap/flower/pull/2232), " +"[#2233](https://github.com/adap/flower/pull/2233), " +"[#2234](https://github.com/adap/flower/pull/2234), " +"[#2235](https://github.com/adap/flower/pull/2235), " +"[#2237](https://github.com/adap/flower/pull/2237), " +"[#2238](https://github.com/adap/flower/pull/2238), " +"[#2242](https://github.com/adap/flower/pull/2242), " +"[#2231](https://github.com/adap/flower/pull/2231), " +"[#2243](https://github.com/adap/flower/pull/2243), " +"[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" "**重构 Flower 文档** ([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), [#1884](https://github." -"com/adap/flower/pull/1884), [#1887](https://github.com/adap/flower/" -"pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" -"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" -"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" -"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" -"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" -"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" -"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" -"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" -"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" -"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" -"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" -"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" -"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" -"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" -"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" -"(https://github.com/adap/flower/pull/2227))" - -#: ../../source/ref-changelog.md:220 -#, fuzzy -msgid "" -"Much effort went into a completely restructured Flower docs experience. The " -"documentation on [flower.ai/docs](https://flower.ai/docs) is now divided " -"into Flower Framework, Flower Baselines, Flower Android SDK, Flower iOS SDK, " -"and code example projects." -msgstr "" -"Flower 文档体验的全面重构耗费了大量精力。现在,[flower.ai/docs](flower.ai/" -"docs)上的文档分为 Flower Framework、Flower Baselines、Flower Android SDK、" -"Flower iOS SDK 和代码示例项目。" +"[#1865](https://github.com/adap/flower/pull/1865), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1887](https://github.com/adap/flower/pull/1887), " +"[#1919](https://github.com/adap/flower/pull/1919), " +"[#1922](https://github.com/adap/flower/pull/1922), " +"[#1920](https://github.com/adap/flower/pull/1920), " +"[#1923](https://github.com/adap/flower/pull/1923), " +"[#1924](https://github.com/adap/flower/pull/1924), " +"[#1962](https://github.com/adap/flower/pull/1962), " +"[#2006](https://github.com/adap/flower/pull/2006), " +"[#2133](https://github.com/adap/flower/pull/2133), " +"[#2203](https://github.com/adap/flower/pull/2203), " +"[#2215](https://github.com/adap/flower/pull/2215), " +"[#2122](https://github.com/adap/flower/pull/2122), " +"[#2223](https://github.com/adap/flower/pull/2223), " +"[#2219](https://github.com/adap/flower/pull/2219), " +"[#2232](https://github.com/adap/flower/pull/2232), " +"[#2233](https://github.com/adap/flower/pull/2233), " +"[#2234](https://github.com/adap/flower/pull/2234), " +"[#2235](https://github.com/adap/flower/pull/2235), " +"[#2237](https://github.com/adap/flower/pull/2237), " +"[#2238](https://github.com/adap/flower/pull/2238), " +"[#2242](https://github.com/adap/flower/pull/2242), " +"[#2231](https://github.com/adap/flower/pull/2231), " +"[#2243](https://github.com/adap/flower/pull/2243), " +"[#2227](https://github.com/adap/flower/pull/2227))" -#: ../../source/ref-changelog.md:222 +#: ../../source/ref-changelog.md:286 +#, fuzzy msgid "" -"**Introduce Flower Swift SDK** ([#1858](https://github.com/adap/flower/" -"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" +"Much effort went into a completely restructured Flower docs experience. " +"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " +"divided into Flower Framework, Flower Baselines, Flower Android SDK, " +"Flower iOS SDK, and code example projects." msgstr "" -"**介绍 Flower Swift SDK** ([#1858](https://github.com/adap/flower/" -"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" +"Flower 文档体验的全面重构耗费了大量精力。现在,[flower.ai/docs](flower.ai/docs)上的文档分为 Flower " +"Framework、Flower Baselines、Flower Android SDK、Flower iOS SDK 和代码示例项目。" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-changelog.md:288 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support on " -"iOS is improving, and alongside the Swift SDK and code example, there is now " -"also an iOS quickstart tutorial." +"**Introduce Flower Swift SDK** " +"([#1858](https://github.com/adap/flower/pull/1858), " +"[#1897](https://github.com/adap/flower/pull/1897))" msgstr "" -"这是 Flower Swift SDK 的首个预览版。Flower 对 iOS 的支持正在不断改进,除了 " -"Swift SDK 和代码示例外,现在还有 iOS 快速入门教程。" +"**介绍 Flower Swift SDK** " +"([#1858](https://github.com/adap/flower/pull/1858), " +"[#1897](https://github.com/adap/flower/pull/1897))" -#: ../../source/ref-changelog.md:226 +#: ../../source/ref-changelog.md:290 msgid "" -"**Introduce Flower Android SDK** ([#2131](https://github.com/adap/flower/" -"pull/2131))" +"This is the first preview release of the Flower Swift SDK. Flower support" +" on iOS is improving, and alongside the Swift SDK and code example, there" +" is now also an iOS quickstart tutorial." msgstr "" -"**介绍Flower Android SDK** ([#2131](https://github.com/adap/flower/" -"pull/2131))" +"这是 Flower Swift SDK 的首个预览版。Flower 对 iOS 的支持正在不断改进,除了 Swift SDK " +"和代码示例外,现在还有 iOS 快速入门教程。" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-changelog.md:292 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower support " -"on Android is improving, and alongside the Kotlin SDK and code example, " -"there is now also an Android quickstart tutorial." +"**Introduce Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" msgstr "" -"这是 Flower Kotlin SDK 的首个预览版。Flower 对 Android 的支持正在不断改进,除" -"了 Kotlin SDK 和代码示例,现在还有 Android 快速入门教程。" +"**介绍Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" -#: ../../source/ref-changelog.md:230 +#: ../../source/ref-changelog.md:294 +msgid "" +"This is the first preview release of the Flower Kotlin SDK. Flower " +"support on Android is improving, and alongside the Kotlin SDK and code " +"example, there is now also an Android quickstart tutorial." +msgstr "" +"这是 Flower Kotlin SDK 的首个预览版。Flower 对 Android 的支持正在不断改进,除了 Kotlin SDK " +"和代码示例,现在还有 Android 快速入门教程。" + +#: ../../source/ref-changelog.md:296 msgid "" -"**Introduce new end-to-end testing infrastructure** ([#1842](https://github." -"com/adap/flower/pull/1842), [#2071](https://github.com/adap/flower/" -"pull/2071), [#2072](https://github.com/adap/flower/pull/2072), [#2068]" -"(https://github.com/adap/flower/pull/2068), [#2067](https://github.com/adap/" -"flower/pull/2067), [#2069](https://github.com/adap/flower/pull/2069), [#2073]" -"(https://github.com/adap/flower/pull/2073), [#2070](https://github.com/adap/" -"flower/pull/2070), [#2074](https://github.com/adap/flower/pull/2074), [#2082]" -"(https://github.com/adap/flower/pull/2082), [#2084](https://github.com/adap/" -"flower/pull/2084), [#2093](https://github.com/adap/flower/pull/2093), [#2109]" -"(https://github.com/adap/flower/pull/2109), [#2095](https://github.com/adap/" -"flower/pull/2095), [#2140](https://github.com/adap/flower/pull/2140), [#2137]" -"(https://github.com/adap/flower/pull/2137), [#2165](https://github.com/adap/" -"flower/pull/2165))" +"**Introduce new end-to-end testing infrastructure** " +"([#1842](https://github.com/adap/flower/pull/1842), " +"[#2071](https://github.com/adap/flower/pull/2071), " +"[#2072](https://github.com/adap/flower/pull/2072), " +"[#2068](https://github.com/adap/flower/pull/2068), " +"[#2067](https://github.com/adap/flower/pull/2067), " +"[#2069](https://github.com/adap/flower/pull/2069), " +"[#2073](https://github.com/adap/flower/pull/2073), " +"[#2070](https://github.com/adap/flower/pull/2070), " +"[#2074](https://github.com/adap/flower/pull/2074), " +"[#2082](https://github.com/adap/flower/pull/2082), " +"[#2084](https://github.com/adap/flower/pull/2084), " +"[#2093](https://github.com/adap/flower/pull/2093), " +"[#2109](https://github.com/adap/flower/pull/2109), " +"[#2095](https://github.com/adap/flower/pull/2095), " +"[#2140](https://github.com/adap/flower/pull/2140), " +"[#2137](https://github.com/adap/flower/pull/2137), " +"[#2165](https://github.com/adap/flower/pull/2165))" msgstr "" "*介绍新的端到端测试** ([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), [#2072](https://github." -"com/adap/flower/pull/2072), [#2068](https://github.com/adap/flower/" -"pull/2068), [#2067](https://github.com/adap/flower/pull/2067), [#2069]" -"(https://github.com/adap/flower/pull/2069), [#2073](https://github.com/adap/" -"flower/pull/2073), [#2070](https://github.com/adap/flower/pull/2070), [#2074]" -"(https://github.com/adap/flower/pull/2074), [#2082](https://github.com/adap/" -"flower/pull/2082), [#2084](https://github.com/adap/flower/pull/2084), [#2093]" -"(https://github.com/adap/flower/pull/2093), [#2109](https://github.com/adap/" -"flower/pull/2109), [#2095](https://github.com/adap/flower/pull/2095), [#2140]" -"(https://github.com/adap/flower/pull/2140), [#2137](https://github.com/adap/" -"flower/pull/2137), [#2165](https://github.com/adap/flower/pull/2165))" +"[#2071](https://github.com/adap/flower/pull/2071), " +"[#2072](https://github.com/adap/flower/pull/2072), " +"[#2068](https://github.com/adap/flower/pull/2068), " +"[#2067](https://github.com/adap/flower/pull/2067), " +"[#2069](https://github.com/adap/flower/pull/2069), " +"[#2073](https://github.com/adap/flower/pull/2073), " +"[#2070](https://github.com/adap/flower/pull/2070), " +"[#2074](https://github.com/adap/flower/pull/2074), " +"[#2082](https://github.com/adap/flower/pull/2082), " +"[#2084](https://github.com/adap/flower/pull/2084), " +"[#2093](https://github.com/adap/flower/pull/2093), " +"[#2109](https://github.com/adap/flower/pull/2109), " +"[#2095](https://github.com/adap/flower/pull/2095), " +"[#2140](https://github.com/adap/flower/pull/2140), " +"[#2137](https://github.com/adap/flower/pull/2137), " +"[#2165](https://github.com/adap/flower/pull/2165))" -#: ../../source/ref-changelog.md:232 +#: ../../source/ref-changelog.md:298 msgid "" -"A new testing infrastructure ensures that new changes stay compatible with " -"existing framework integrations or strategies." +"A new testing infrastructure ensures that new changes stay compatible " +"with existing framework integrations or strategies." msgstr "新的测试设施可确保新的变更与现有的框架集成或策略保持兼容。" -#: ../../source/ref-changelog.md:234 +#: ../../source/ref-changelog.md:300 msgid "**Deprecate Python 3.7**" msgstr "** 过时的 Python 3.7**" -#: ../../source/ref-changelog.md:236 +#: ../../source/ref-changelog.md:302 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for " -"Python 3.7 is now deprecated and will be removed in an upcoming release." -msgstr "" -"由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并" -"将在即将发布的版本中移除。" +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" +" Python 3.7 is now deprecated and will be removed in an upcoming release." +msgstr "由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并将在即将发布的版本中移除。" -#: ../../source/ref-changelog.md:238 +#: ../../source/ref-changelog.md:304 msgid "" -"**Add new** `FedTrimmedAvg` **strategy** ([#1769](https://github.com/adap/" -"flower/pull/1769), [#1853](https://github.com/adap/flower/pull/1853))" +"**Add new** `FedTrimmedAvg` **strategy** " +"([#1769](https://github.com/adap/flower/pull/1769), " +"[#1853](https://github.com/adap/flower/pull/1853))" msgstr "" -"**添加新的**`FedTrimmedAvg`**策略**([#1769](https://github.com/adap/flower/" -"pull/1769), [#1853](https://github.com/adap/flower/pull/1853)" +"**添加新的**`FedTrimmedAvg`**策略**([#1769](https://github.com/adap/flower/pull/1769)," +" [#1853](https://github.com/adap/flower/pull/1853)" -#: ../../source/ref-changelog.md:240 +#: ../../source/ref-changelog.md:306 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, 2018]" -"(https://arxiv.org/abs/1803.01498)." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " +"2018](https://arxiv.org/abs/1803.01498)." msgstr "" -"新的 \"FedTrimmedAvg \"策略实现了[Dong Yin, 2018](https://arxiv.org/" -"abs/1803.01498)的 \"Trimmed Mean\"。" +"新的 \"FedTrimmedAvg \"策略实现了[Dong Yin, " +"2018](https://arxiv.org/abs/1803.01498)的 \"Trimmed Mean\"。" -#: ../../source/ref-changelog.md:242 +#: ../../source/ref-changelog.md:308 msgid "" -"**Introduce start_driver** ([#1697](https://github.com/adap/flower/" -"pull/1697))" -msgstr "" -"**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce start_driver** " +"([#1697](https://github.com/adap/flower/pull/1697))" +msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" -#: ../../source/ref-changelog.md:244 +#: ../../source/ref-changelog.md:310 msgid "" -"In addition to `start_server` and using the raw Driver API, there is a new " -"`start_driver` function that allows for running `start_server` scripts as a " -"Flower driver with only a single-line code change. Check out the `mt-" -"pytorch` code example to see a working example using `start_driver`." +"In addition to `start_server` and using the raw Driver API, there is a " +"new `start_driver` function that allows for running `start_server` " +"scripts as a Flower driver with only a single-line code change. Check out" +" the `mt-pytorch` code example to see a working example using " +"`start_driver`." msgstr "" -"除了 `start_server` 和使用原始驱动 API 之外,还有一个新的 `start_driver` 函" -"数,只需修改一行代码,就能将 `start_server` 脚本作为 Flower 驱动程序运行。请" -"查看 `mt-pytorch` 代码示例,了解使用 `start_driver` 的工作示例。" +"除了 `start_server` 和使用原始驱动 API 之外,还有一个新的 `start_driver` 函数,只需修改一行代码,就能将 " +"`start_server` 脚本作为 Flower 驱动程序运行。请查看 `mt-pytorch` 代码示例,了解使用 " +"`start_driver` 的工作示例。" -#: ../../source/ref-changelog.md:246 +#: ../../source/ref-changelog.md:312 msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** ([#1785]" -"(https://github.com/adap/flower/pull/1785))" +"**Add parameter aggregation to** `mt-pytorch` **code example** " +"([#1785](https://github.com/adap/flower/pull/1785))" msgstr "" -"为 `mt-pytorch` **代码示例**添加参数聚合 ([#1785](https://github.com/adap/" -"flower/pull/1785))" +"为 `mt-pytorch` **代码示例**添加参数聚合 " +"([#1785](https://github.com/adap/flower/pull/1785))" -#: ../../source/ref-changelog.md:248 +#: ../../source/ref-changelog.md:314 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a " -"driver script. The included `driver.py` and `server.py` have been aligned to " -"demonstrate both the low-level way and the high-level way of building server-" -"side logic." +"The `mt-pytorch` example shows how to aggregate parameters when writing a" +" driver script. The included `driver.py` and `server.py` have been " +"aligned to demonstrate both the low-level way and the high-level way of " +"building server-side logic." msgstr "" -"`mt-pytorch`示例展示了如何在编写驱动程序脚本时聚合参数。附带的 `driver.py` " -"和 `server.py` 已经进行了调整,以演示构建服务器端逻辑的低级方法和高级方法。" +"`mt-pytorch`示例展示了如何在编写驱动程序脚本时聚合参数。附带的 `driver.py` 和 `server.py` " +"已经进行了调整,以演示构建服务器端逻辑的低级方法和高级方法。" -#: ../../source/ref-changelog.md:250 +#: ../../source/ref-changelog.md:316 msgid "" -"**Migrate experimental REST API to Starlette** ([2171](https://github.com/" -"adap/flower/pull/2171))" +"**Migrate experimental REST API to Starlette** " +"([2171](https://github.com/adap/flower/pull/2171))" msgstr "" -"**将实验性 REST API 移植到 Starlette** ([2171](https://github.com/adap/" -"flower/pull/2171))" +"**将实验性 REST API 移植到 Starlette** " +"([2171](https://github.com/adap/flower/pull/2171))" -#: ../../source/ref-changelog.md:252 +#: ../../source/ref-changelog.md:318 msgid "" -"The (experimental) REST API used to be implemented in [FastAPI](https://" -"fastapi.tiangolo.com/), but it has now been migrated to use [Starlette]" -"(https://www.starlette.io/) directly." +"The (experimental) REST API used to be implemented in " +"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" +" use [Starlette](https://www.starlette.io/) directly." msgstr "" -"REST API(试验性)曾在 [FastAPI](https://fastapi.tiangolo.com/) 中实现,但现" -"在已迁移到直接使用 [Starlette](https://www.starlette.io/) 。" +"REST API(试验性)曾在 [FastAPI](https://fastapi.tiangolo.com/) 中实现,但现在已迁移到直接使用 " +"[Starlette](https://www.starlette.io/) 。" -#: ../../source/ref-changelog.md:254 +#: ../../source/ref-changelog.md:320 msgid "" -"Please note: The REST request-response API is still experimental and will " -"likely change significantly over time." -msgstr "" -"请注意:REST 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" +"Please note: The REST request-response API is still experimental and will" +" likely change significantly over time." +msgstr "请注意:REST 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:256 +#: ../../source/ref-changelog.md:322 msgid "" -"**Introduce experimental gRPC request-response API** ([#1867](https://github." -"com/adap/flower/pull/1867), [#1901](https://github.com/adap/flower/" -"pull/1901))" +"**Introduce experimental gRPC request-response API** " +"([#1867](https://github.com/adap/flower/pull/1867), " +"[#1901](https://github.com/adap/flower/pull/1901))" msgstr "" -"**引入实验性 gRPC 请求-响应 API** ([#1867](https://github.com/adap/flower/" -"pull/1867), [#1901](https://github.com/adap/flower/pull/1901)" +"**引入实验性 gRPC 请求-响应 API** " +"([#1867](https://github.com/adap/flower/pull/1867), " +"[#1901](https://github.com/adap/flower/pull/1901)" -#: ../../source/ref-changelog.md:258 +#: ../../source/ref-changelog.md:324 msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) and " -"the experimental REST API, there is now a new gRPC API that uses a request-" -"response model to communicate with client nodes." +"In addition to the existing gRPC API (based on bidirectional streaming) " +"and the experimental REST API, there is now a new gRPC API that uses a " +"request-response model to communicate with client nodes." msgstr "" -"除了现有的 gRPC 应用程序接口(基于双向流)和试验性 REST 应用程序接口外,现在" -"还有一个新的 gRPC 应用程序接口,它使用请求-响应模型与客户端节点通信。" +"除了现有的 gRPC 应用程序接口(基于双向流)和试验性 REST 应用程序接口外,现在还有一个新的 gRPC " +"应用程序接口,它使用请求-响应模型与客户端节点通信。" -#: ../../source/ref-changelog.md:260 +#: ../../source/ref-changelog.md:326 msgid "" -"Please note: The gRPC request-response API is still experimental and will " -"likely change significantly over time." -msgstr "" -"请注意:gRPC 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" +"Please note: The gRPC request-response API is still experimental and will" +" likely change significantly over time." +msgstr "请注意:gRPC 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:328 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` ([#1880](https://github.com/adap/flower/" -"pull/1880))" +"`start_client(transport=\"rest\")` " +"([#1880](https://github.com/adap/flower/pull/1880))" msgstr "" "**用新的** `start_client(transport=\"rest\")` 替换实验性** " -"`start_client(rest=True)` ([#1880](https://github.com/adap/flower/pull/1880))" +"`start_client(rest=True)` " +"([#1880](https://github.com/adap/flower/pull/1880))" -#: ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:330 msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in favour " -"of a new argument `transport`. `start_client(transport=\"rest\")` will yield " -"the same behaviour as `start_client(rest=True)` did before. All code should " -"migrate to the new argument `transport`. The deprecated argument `rest` will " -"be removed in a future release." +"The (experimental) `start_client` argument `rest` was deprecated in " +"favour of a new argument `transport`. `start_client(transport=\"rest\")` " +"will yield the same behaviour as `start_client(rest=True)` did before. " +"All code should migrate to the new argument `transport`. The deprecated " +"argument `rest` will be removed in a future release." msgstr "" -"已废弃(试验性的)`start_client`参数`rest`,改用新参数`transport`。" -"`start_client(transport=\"rest\")`将产生与以前的`start_client(rest=True)`相同" -"的行为。所有代码都应迁移到新参数 `transport`。过时的参数 `rest` 将在今后的版" -"本中删除。" +"已废弃(试验性的)`start_client`参数`rest`,改用新参数`transport`。`start_client(transport=\"rest\")`将产生与以前的`start_client(rest=True)`相同的行为。所有代码都应迁移到新参数" +" `transport`。过时的参数 `rest` 将在今后的版本中删除。" -#: ../../source/ref-changelog.md:266 +#: ../../source/ref-changelog.md:332 msgid "" -"**Add a new gRPC option** ([#2197](https://github.com/adap/flower/pull/2197))" -msgstr "" -"** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/" -"pull/2197))" +"**Add a new gRPC option** " +"([#2197](https://github.com/adap/flower/pull/2197))" +msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" -#: ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:334 msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls` " -"option set to 0 by default. This prevents the clients from sending keepalive " -"pings when there is no outstanding stream." +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" +" option set to 0 by default. This prevents the clients from sending " +"keepalive pings when there is no outstanding stream." msgstr "" -"现在我们启动一个 gRPC 服务器,并将 `grpc.keepalive_permit_without_calls` 选项" -"默认设置为 0。这将防止客户端在没有未处理数据流时发送 keepalive pings。" +"现在我们启动一个 gRPC 服务器,并将 `grpc.keepalive_permit_without_calls` 选项默认设置为 " +"0。这将防止客户端在没有未处理数据流时发送 keepalive pings。" -#: ../../source/ref-changelog.md:270 +#: ../../source/ref-changelog.md:336 msgid "" -"**Improve example notebooks** ([#2005](https://github.com/adap/flower/" -"pull/2005))" +"**Improve example notebooks** " +"([#2005](https://github.com/adap/flower/pull/2005))" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" -#: ../../source/ref-changelog.md:272 +#: ../../source/ref-changelog.md:338 msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "有一个新的 30 分钟的联邦学习 PyTorch 教程!" -#: ../../source/ref-changelog.md:274 +#: ../../source/ref-changelog.md:340 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), [#1981](https://github." -"com/adap/flower/pull/1981), [#1988](https://github.com/adap/flower/" -"pull/1988), [#1984](https://github.com/adap/flower/pull/1984), [#1982]" -"(https://github.com/adap/flower/pull/1982), [#2112](https://github.com/adap/" -"flower/pull/2112), [#2144](https://github.com/adap/flower/pull/2144), [#2174]" -"(https://github.com/adap/flower/pull/2174), [#2225](https://github.com/adap/" -"flower/pull/2225), [#2183](https://github.com/adap/flower/pull/2183))" -msgstr "" -"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), [#1873]" -"(https://github.com/adap/flower/pull/1873), [#1981](https://github.com/adap/" -"flower/pull/1981), [#1988](https://github.com/adap/flower/pull/1988), [#1984]" -"(https://github.com/adap/flower/pull/1984), [#1982](https://github.com/adap/" -"flower/pull/1982), [#2112](https://github.com/adap/flower/pull/2112), [#2144]" -"(https://github.com/adap/flower/pull/2144), [#2174](https://github.com/adap/" -"flower/pull/2174), [#2225](https://github.com/adap/flower/pull/2225), [#2183]" -"(https://github.com/adap/flower/pull/2183))" - -#: ../../source/ref-changelog.md:276 +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" +msgstr "" +"**更新Example** ([#1772](https://github.com/adap/flower/pull/1772), " +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" + +#: ../../source/ref-changelog.md:342 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A " -"major upgrade is that all code examples now have a `requirements.txt` (in " -"addition to `pyproject.toml`)." -msgstr "" -"许多示例都进行了重大更新,包括简化了 advanced-tensorflow 和 advanced-pytorch " -"示例,改进了 TensorFlow 示例的 macOS 兼容性,以及模拟代码示例。一项重大升级是" -"所有代码示例现在都有了 \"requirements.txt\"(除 \"pyproject.toml \"外)。" - -#: ../../source/ref-changelog.md:278 -msgid "" -"**General improvements** ([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), [#1884](https://github." -"com/adap/flower/pull/1884), [#1837](https://github.com/adap/flower/" -"pull/1837), [#1477](https://github.com/adap/flower/pull/1477), [#2171]" -"(https://github.com/adap/flower/pull/2171))" -msgstr "" -"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), [#1866]" -"(https://github.com/adap/flower/pull/1866), [#1884](https://github.com/adap/" -"flower/pull/1884), [#1837](https://github.com/adap/flower/pull/1837), [#1477]" -"(https://github.com/adap/flower/pull/1477), [#2171](https://github.com/adap/" -"flower/pull/2171))" - -#: ../../source/ref-changelog.md:284 ../../source/ref-changelog.md:348 -#: ../../source/ref-changelog.md:406 ../../source/ref-changelog.md:475 -#: ../../source/ref-changelog.md:537 -msgid "None" -msgstr "无" - -#: ../../source/ref-changelog.md:286 +"compatibility of TensorFlow examples, and code examples for simulation. A" +" major upgrade is that all code examples now have a `requirements.txt` " +"(in addition to `pyproject.toml`)." +msgstr "" +"许多示例都进行了重大更新,包括简化了 advanced-tensorflow 和 advanced-pytorch 示例,改进了 " +"TensorFlow 示例的 macOS 兼容性,以及模拟代码示例。一项重大升级是所有代码示例现在都有了 " +"\"requirements.txt\"(除 \"pyproject.toml \"外)。" + +#: ../../source/ref-changelog.md:344 +msgid "" +"**General improvements** " +"([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" +msgstr "" +"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" + +#: ../../source/ref-changelog.md:352 msgid "v1.4.0 (2023-04-21)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:358 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" -"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " -"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " -"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " -"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" -"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " -"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " -"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " -"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:362 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and example)** " -"([#1694](https://github.com/adap/flower/pull/1694), [#1709](https://github." -"com/adap/flower/pull/1709), [#1715](https://github.com/adap/flower/" -"pull/1715), [#1717](https://github.com/adap/flower/pull/1717), [#1763]" -"(https://github.com/adap/flower/pull/1763), [#1795](https://github.com/adap/" -"flower/pull/1795))" -msgstr "" -"**引入对XGBoost的支持(**`FedXgbNnAvg` **策略和示例)** ([#1694](https://" -"github.com/adap/flower/pull/1694), [#1709](https://github.com/adap/flower/" -"pull/1709), [#1715](https://github.com/adap/flower/pull/1715), [#1717]" -"(https://github.com/adap/flower/pull/1717), [#1763](https://github.com/adap/" -"flower/pull/1763), [#1795](https://github.com/adap/flower/pull/1795))" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " +"example)** ([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" +msgstr "" +"**引入对XGBoost的支持(**`FedXgbNnAvg` **策略和示例)** " +"([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:364 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg` " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/" -"strategy/fedxgb_nn_avg.py), and a [code example](https://github.com/adap/" -"flower/tree/main/examples/xgboost-quickstart) that demonstrates the usage of " -"this new strategy in an XGBoost project." -msgstr "" -"XGBoost 是一种基于树的集合机器学习算法,它使用梯度提升来提高模型的准确性。我" -"们添加了一个新的 \"FedXgbNnAvg\"[策略](https://github.com/adap/flower/tree/" -"main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)和一个[代码示例](https://" -"github.com/adap/flower/tree/main/examples/xgboost-quickstart),演示如何在 " -"XGBoost 项目中使用这个新策略。" +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" +" " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," +" and a [code example](https://github.com/adap/flower/tree/main/examples" +"/xgboost-quickstart) that demonstrates the usage of this new strategy in " +"an XGBoost project." +msgstr "" +"XGBoost 是一种基于树的集合机器学习算法,它使用梯度提升来提高模型的准确性。我们添加了一个新的 " +"\"FedXgbNnAvg\"[策略](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)和一个[代码示例](https://github.com/adap/flower/tree/main/examples" +"/xgboost-quickstart),演示如何在 XGBoost 项目中使用这个新策略。" -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:366 msgid "" -"**Introduce iOS SDK (preview)** ([#1621](https://github.com/adap/flower/" -"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" +"**Introduce iOS SDK (preview)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" msgstr "" -"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/" -"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" +"**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:368 msgid "" -"This is a major update for anyone wanting to implement Federated Learning on " -"iOS mobile devices. We now have a swift iOS SDK present under [src/swift/" -"flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) that will " -"facilitate greatly the app creating process. To showcase its use, the [iOS " +"This is a major update for anyone wanting to implement Federated Learning" +" on iOS mobile devices. We now have a swift iOS SDK present under " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" that will facilitate greatly the app creating process. To showcase its " +"use, the [iOS " "example](https://github.com/adap/flower/tree/main/examples/ios) has also " "been updated!" msgstr "" -"对于想要在 iOS 移动设备上实施联邦学习的人来说,这是一次重大更新。现在,我们" -"在 [src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) " -"下提供了一个迅捷的 iOS SDK,这将大大方便应用程序的创建过程。为了展示其使用情" -"况,我们还更新了 [iOS 示例](https://github.com/adap/flower/tree/main/" -"examples/ios)!" +"对于想要在 iOS 移动设备上实施联邦学习的人来说,这是一次重大更新。现在,我们在 " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" 下提供了一个迅捷的 iOS SDK,这将大大方便应用程序的创建过程。为了展示其使用情况,我们还更新了 [iOS " +"示例](https://github.com/adap/flower/tree/main/examples/ios)!" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:370 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** ([#1657](https://" -"github.com/adap/flower/pull/1657), [#1721](https://github.com/adap/flower/" -"pull/1721))" +"**Introduce new \"What is Federated Learning?\" tutorial** " +"([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721))" msgstr "" -"**引入新的 \"什么是联邦学习?\"教程**([#1657](https://github.com/adap/" -"flower/pull/1657), [#1721](https://github.com/adap/flower/pull/1721)" +"**引入新的 " +"\"什么是联邦学习?\"教程**([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721)" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:372 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-what-" -"is-federated-learning.html) in our documentation explains the basics of " -"Fedetated Learning. It enables anyone who's unfamiliar with Federated " -"Learning to start their journey with Flower. Forward it to anyone who's " +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" +"what-is-federated-learning.html) in our documentation explains the basics" +" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" +" Learning to start their journey with Flower. Forward it to anyone who's " "interested in Federated Learning!" msgstr "" -"我们的文档中新增了一个[入门级教程](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html),解释了联邦学习的基础知识。它让任何不熟悉联" -"邦学习的人都能开始 Flower 之旅。请转发给对联邦学习感兴趣的人!" +"我们的文档中新增了一个[入门级教程](https://flower.ai/docs/framework/tutorial-what-is-" +"federated-learning.html),解释了联邦学习的基础知识。它让任何不熟悉联邦学习的人都能开始 Flower " +"之旅。请转发给对联邦学习感兴趣的人!" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:374 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" -"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." -"com/adap/flower/pull/1679))" +"**Introduce new Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" msgstr "" -"**引入新的 Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" -"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." -"com/adap/flower/pull/1679)" +"**引入新的 Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679)" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:376 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated " -"Optimization in Heterogeneous Networks (Li et al., 2018)](https://arxiv.org/" -"abs/1812.06127). It uses the `FedProx` strategy, which aims at making " -"convergence more robust in heterogeneous settings." +"This new baseline replicates the MNIST+CNN task from the paper [Federated" +" Optimization in Heterogeneous Networks (Li et al., " +"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," +" which aims at making convergence more robust in heterogeneous settings." msgstr "" -"这条新Baseline复现了论文[Federated Optimization in Heterogeneous Networks " -"(Li et al., 2018)](https://arxiv.org/abs/1812.06127)中的 MNIST+CNN 任务。它使" -"用 \"FedProx \"策略,旨在使收敛在异构环境中更加稳健。" +"这条新Baseline复现了论文[Federated Optimization in Heterogeneous Networks (Li et " +"al., 2018)](https://arxiv.org/abs/1812.06127)中的 MNIST+CNN 任务。它使用 " +"\"FedProx \"策略,旨在使收敛在异构环境中更加稳健。" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:378 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** ([#1655](https://github." -"com/adap/flower/pull/1655))" +"**Introduce new Flower Baseline: FedAvg FEMNIST** " +"([#1655](https://github.com/adap/flower/pull/1655))" msgstr "" -"**引入新的 Flower Baseline: FedAvg FEMNIST** ([#1655](https://github.com/" -"adap/flower/pull/1655))" +"**引入新的 Flower Baseline: FedAvg FEMNIST** " +"([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:380 msgid "" -"This new baseline replicates an experiment evaluating the performance of the " -"FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A Benchmark " -"for Federated Settings (Caldas et al., 2018)](https://arxiv.org/" -"abs/1812.01097)." +"This new baseline replicates an experiment evaluating the performance of " +"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " +"Benchmark for Federated Settings (Caldas et al., " +"2018)](https://arxiv.org/abs/1812.01097)." msgstr "" -"这一新Baseline复现了论文[LEAF: A Benchmark for Federated Settings(Caldas 等" -"人,2018 年)](https://arxiv.org/abs/1812.01097)中评估 FedAvg 算法在 FEMNIST " -"数据集上性能的实验。" +"这一新Baseline复现了论文[LEAF: A Benchmark for Federated Settings(Caldas 等人,2018 " +"年)](https://arxiv.org/abs/1812.01097)中评估 FedAvg 算法在 FEMNIST 数据集上性能的实验。" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:382 msgid "" -"**Introduce (experimental) REST API** ([#1594](https://github.com/adap/" -"flower/pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" -"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" -"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" -"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" -"flower/pull/1733))" -msgstr "" -"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/" -"pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" -"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" -"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" -"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" -"flower/pull/1733))" +"**Introduce (experimental) REST API** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" +msgstr "" +"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:384 msgid "" "A new REST API has been introduced as an alternative to the gRPC-based " "communication stack. In this initial version, the REST API only supports " "anonymous clients." -msgstr "" -"作为基于 gRPC 的通信栈的替代方案,我们引入了新的 REST API。在初始版本中," -"REST API 仅支持匿名客户端。" +msgstr "作为基于 gRPC 的通信栈的替代方案,我们引入了新的 REST API。在初始版本中,REST API 仅支持匿名客户端。" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:386 msgid "" "Please note: The REST API is still experimental and will likely change " "significantly over time." msgstr "请注意:REST API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:388 msgid "" -"**Improve the (experimental) Driver API** ([#1663](https://github.com/adap/" -"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" -"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" -"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" -"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" -"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" -"(https://github.com/adap/flower/pull/1794))" -msgstr "" -"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/" -"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" -"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" -"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" -"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" -"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" -"(https://github.com/adap/flower/pull/1794))" +"**Improve the (experimental) Driver API** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" +msgstr "" +"**改进(试验性)驱动程序应用程序接口** ([#1663](https://github.com/adap/flower/pull/1663)," +" [#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:390 msgid "" -"The Driver API is still an experimental feature, but this release introduces " -"some major upgrades. One of the main improvements is the introduction of an " -"SQLite database to store server state on disk (instead of in-memory). " -"Another improvement is that tasks (instructions or results) that have been " -"delivered will now be deleted. This greatly improves the memory efficiency " -"of a long-running Flower server." +"The Driver API is still an experimental feature, but this release " +"introduces some major upgrades. One of the main improvements is the " +"introduction of an SQLite database to store server state on disk (instead" +" of in-memory). Another improvement is that tasks (instructions or " +"results) that have been delivered will now be deleted. This greatly " +"improves the memory efficiency of a long-running Flower server." msgstr "" -"驱动程序应用程序接口(Driver API)仍是一项试验性功能,但这一版本引入了一些重" -"大升级。主要改进之一是引入了 SQLite 数据库,将服务器状态存储在磁盘上(而不是" -"内存中)。另一项改进是,已交付的任务(指令或结果)现在将被删除。这大大提高了" -"长期运行的 Flower 服务器的内存效率。" +"驱动程序应用程序接口(Driver API)仍是一项试验性功能,但这一版本引入了一些重大升级。主要改进之一是引入了 SQLite " +"数据库,将服务器状态存储在磁盘上(而不是内存中)。另一项改进是,已交付的任务(指令或结果)现在将被删除。这大大提高了长期运行的 Flower " +"服务器的内存效率。" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:392 msgid "" -"**Fix spilling issues related to Ray during simulations** ([#1698](https://" -"github.com/adap/flower/pull/1698))" -msgstr "" -"**修复模拟过程中与Ray有关的溢出问题** ([#1698](https://github.com/adap/" -"flower/pull/1698))" +"**Fix spilling issues related to Ray during simulations** " +"([#1698](https://github.com/adap/flower/pull/1698))" +msgstr "**修复模拟过程中与Ray有关的溢出问题** ([#1698](https://github.com/adap/flower/pull/1698))" -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:394 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts of " -"data that would make the training unable to continue. This is now fixed! 🎉" -msgstr "" -"在运行长时间模拟时,`ray` 有时会溢出大量数据,导致训练无法继续。现在这个问题" -"已经解决!🎉" +"While running long simulations, `ray` was sometimes spilling huge amounts" +" of data that would make the training unable to continue. This is now " +"fixed! 🎉" +msgstr "在运行长时间模拟时,`ray` 有时会溢出大量数据,导致训练无法继续。现在这个问题已经解决!🎉" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:396 msgid "" -"**Add new example using** `TabNet` **and Flower** ([#1725](https://github." -"com/adap/flower/pull/1725))" +"**Add new example using** `TabNet` **and Flower** " +"([#1725](https://github.com/adap/flower/pull/1725))" msgstr "" -"** 添加使用** `TabNet` ** 的新示例** ([#1725](https://github.com/adap/flower/" -"pull/1725))" +"** 添加使用** `TabNet` ** 的新示例** " +"([#1725](https://github.com/adap/flower/pull/1725))" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:398 msgid "" -"TabNet is a powerful and flexible framework for training machine learning " -"models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples/" -"quickstart-tabnet)." +"TabNet is a powerful and flexible framework for training machine learning" +" models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" +"/quickstart-tabnet)." msgstr "" -"TabNet 是一个强大而灵活的框架,用于在表格数据上训练机器学习模型。我们现在有一" -"个使用 Flower 的联邦示例:[quickstart-tabnet](https://github.com/adap/flower/" -"tree/main/examples/quickstart-tabnet)。" +"TabNet 是一个强大而灵活的框架,用于在表格数据上训练机器学习模型。我们现在有一个使用 Flower 的联邦示例:[quickstart-" +"tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" +"tabnet)。" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:400 msgid "" -"**Add new how-to guide for monitoring simulations** ([#1649](https://github." -"com/adap/flower/pull/1649))" -msgstr "" -"** 添加新的模拟监控指南** ([#1649](https://github.com/adap/flower/pull/1649))" +"**Add new how-to guide for monitoring simulations** " +"([#1649](https://github.com/adap/flower/pull/1649))" +msgstr "** 添加新的模拟监控指南** ([#1649](https://github.com/adap/flower/pull/1649))" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:402 msgid "" -"We now have a documentation guide to help users monitor their performance " -"during simulations." +"We now have a documentation guide to help users monitor their performance" +" during simulations." msgstr "我们现在有一份文档指南,可帮助用户在模拟过程中监控其性能。" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:404 msgid "" -"**Add training metrics to** `History` **object during simulations** ([#1696]" -"(https://github.com/adap/flower/pull/1696))" +"**Add training metrics to** `History` **object during simulations** " +"([#1696](https://github.com/adap/flower/pull/1696))" msgstr "" -"**在模拟过程中为***`历史`***对象添加训练指标*** ([#1696](https://github.com/" -"adap/flower/pull/1696))" +"**在模拟过程中为***`历史`***对象添加训练指标*** " +"([#1696](https://github.com/adap/flower/pull/1696))" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:406 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training metrics, " -"but previous releases did not save the results in the `History` object. This " -"is now the case!" +"The `fit_metrics_aggregation_fn` can be used to aggregate training " +"metrics, but previous releases did not save the results in the `History` " +"object. This is now the case!" msgstr "" -"`fit_metrics_aggregation_fn`可用于汇总训练指标,但以前的版本不会将结果保存在 " -"\"History \"对象中。现在可以了!" +"`fit_metrics_aggregation_fn`可用于汇总训练指标,但以前的版本不会将结果保存在 \"History " +"\"对象中。现在可以了!" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:408 msgid "" -"**General improvements** ([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), [#1647](https://github." -"com/adap/flower/pull/1647), [#1471](https://github.com/adap/flower/" -"pull/1471), [#1648](https://github.com/adap/flower/pull/1648), [#1651]" -"(https://github.com/adap/flower/pull/1651), [#1652](https://github.com/adap/" -"flower/pull/1652), [#1653](https://github.com/adap/flower/pull/1653), [#1659]" -"(https://github.com/adap/flower/pull/1659), [#1665](https://github.com/adap/" -"flower/pull/1665), [#1670](https://github.com/adap/flower/pull/1670), [#1672]" -"(https://github.com/adap/flower/pull/1672), [#1677](https://github.com/adap/" -"flower/pull/1677), [#1684](https://github.com/adap/flower/pull/1684), [#1683]" -"(https://github.com/adap/flower/pull/1683), [#1686](https://github.com/adap/" -"flower/pull/1686), [#1682](https://github.com/adap/flower/pull/1682), [#1685]" -"(https://github.com/adap/flower/pull/1685), [#1692](https://github.com/adap/" -"flower/pull/1692), [#1705](https://github.com/adap/flower/pull/1705), [#1708]" -"(https://github.com/adap/flower/pull/1708), [#1711](https://github.com/adap/" -"flower/pull/1711), [#1713](https://github.com/adap/flower/pull/1713), [#1714]" -"(https://github.com/adap/flower/pull/1714), [#1718](https://github.com/adap/" -"flower/pull/1718), [#1716](https://github.com/adap/flower/pull/1716), [#1723]" -"(https://github.com/adap/flower/pull/1723), [#1735](https://github.com/adap/" -"flower/pull/1735), [#1678](https://github.com/adap/flower/pull/1678), [#1750]" -"(https://github.com/adap/flower/pull/1750), [#1753](https://github.com/adap/" -"flower/pull/1753), [#1736](https://github.com/adap/flower/pull/1736), [#1766]" -"(https://github.com/adap/flower/pull/1766), [#1760](https://github.com/adap/" -"flower/pull/1760), [#1775](https://github.com/adap/flower/pull/1775), [#1776]" -"(https://github.com/adap/flower/pull/1776), [#1777](https://github.com/adap/" -"flower/pull/1777), [#1779](https://github.com/adap/flower/pull/1779), [#1784]" -"(https://github.com/adap/flower/pull/1784), [#1773](https://github.com/adap/" -"flower/pull/1773), [#1755](https://github.com/adap/flower/pull/1755), [#1789]" -"(https://github.com/adap/flower/pull/1789), [#1788](https://github.com/adap/" -"flower/pull/1788), [#1798](https://github.com/adap/flower/pull/1798), [#1799]" -"(https://github.com/adap/flower/pull/1799), [#1739](https://github.com/adap/" -"flower/pull/1739), [#1800](https://github.com/adap/flower/pull/1800), [#1804]" -"(https://github.com/adap/flower/pull/1804), [#1805](https://github.com/adap/" -"flower/pull/1805))" -msgstr "" -"**普通改进** ([#1659](https://github.com/adap/flower/pull/1659), [#1646]" -"(https://github.com/adap/flower/pull/1646), [#1647](https://github.com/adap/" -"flower/pull/1647), [#1471](https://github.com/adap/flower/pull/1471), [#1648]" -"(https://github.com/adap/flower/pull/1648), [#1651](https://github.com/adap/" -"flower/pull/1651), [#1652](https://github.com/adap/flower/pull/1652), [#1653]" -"(https://github.com/adap/flower/pull/1653), [#1659](https://github.com/adap/" -"flower/pull/1659), [#1665](https://github.com/adap/flower/pull/1665), [#1670]" -"(https://github.com/adap/flower/pull/1670), [#1672](https://github.com/adap/" -"flower/pull/1672), [#1677](https://github.com/adap/flower/pull/1677), [#1684]" -"(https://github.com/adap/flower/pull/1684), [#1683](https://github.com/adap/" -"flower/pull/1683), [#1686](https://github.com/adap/flower/pull/1686), [#1682]" -"(https://github.com/adap/flower/pull/1682), [#1685](https://github.com/adap/" -"flower/pull/1685), [#1692](https://github.com/adap/flower/pull/1692), [#1705]" -"(https://github.com/adap/flower/pull/1705), [#1708](https://github.com/adap/" -"flower/pull/1708), [#1711](https://github.com/adap/flower/pull/1711), [#1713]" -"(https://github.com/adap/flower/pull/1713), [#1714](https://github.com/adap/" -"flower/pull/1714), [#1718](https://github.com/adap/flower/pull/1718), [#1716]" -"(https://github.com/adap/flower/pull/1716), [#1723](https://github.com/adap/" -"flower/pull/1723), [#1735](https://github.com/adap/flower/pull/1735), [#1678]" -"(https://github.com/adap/flower/pull/1678), [#1750](https://github.com/adap/" -"flower/pull/1750), [#1753](https://github.com/adap/flower/pull/1753), [#1736]" -"(https://github.com/adap/flower/pull/1736), [#1766](https://github.com/adap/" -"flower/pull/1766), [#1760](https://github.com/adap/flower/pull/1760), [#1775]" -"(https://github.com/adap/flower/pull/1775), [#1776](https://github.com/adap/" -"flower/pull/1776), [#1777](https://github.com/adap/flower/pull/1777), [#1779]" -"(https://github.com/adap/flower/pull/1779), [#1784](https://github.com/adap/" -"flower/pull/1784), [#1773](https://github.com/adap/flower/pull/1773), [#1755]" -"(https://github.com/adap/flower/pull/1755), [#1789](https://github.com/adap/" -"flower/pull/1789), [#1788](https://github.com/adap/flower/pull/1788), [#1798]" -"(https://github.com/adap/flower/pull/1798), [#1799](https://github.com/adap/" -"flower/pull/1799), [#1739](https://github.com/adap/flower/pull/1739), [#1800]" -"(https://github.com/adap/flower/pull/1800), [#1804](https://github.com/adap/" -"flower/pull/1804), [#1805](https://github.com/adap/flower/pull/1805))" - -#: ../../source/ref-changelog.md:350 +"**General improvements** " +"([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/adap/flower/pull/1705), " +"[#1708](https://github.com/adap/flower/pull/1708), " +"[#1711](https://github.com/adap/flower/pull/1711), " +"[#1713](https://github.com/adap/flower/pull/1713), " +"[#1714](https://github.com/adap/flower/pull/1714), " +"[#1718](https://github.com/adap/flower/pull/1718), " +"[#1716](https://github.com/adap/flower/pull/1716), " +"[#1723](https://github.com/adap/flower/pull/1723), " +"[#1735](https://github.com/adap/flower/pull/1735), " +"[#1678](https://github.com/adap/flower/pull/1678), " +"[#1750](https://github.com/adap/flower/pull/1750), " +"[#1753](https://github.com/adap/flower/pull/1753), " +"[#1736](https://github.com/adap/flower/pull/1736), " +"[#1766](https://github.com/adap/flower/pull/1766), " +"[#1760](https://github.com/adap/flower/pull/1760), " +"[#1775](https://github.com/adap/flower/pull/1775), " +"[#1776](https://github.com/adap/flower/pull/1776), " +"[#1777](https://github.com/adap/flower/pull/1777), " +"[#1779](https://github.com/adap/flower/pull/1779), " +"[#1784](https://github.com/adap/flower/pull/1784), " +"[#1773](https://github.com/adap/flower/pull/1773), " +"[#1755](https://github.com/adap/flower/pull/1755), " +"[#1789](https://github.com/adap/flower/pull/1789), " +"[#1788](https://github.com/adap/flower/pull/1788), " +"[#1798](https://github.com/adap/flower/pull/1798), " +"[#1799](https://github.com/adap/flower/pull/1799), " +"[#1739](https://github.com/adap/flower/pull/1739), " +"[#1800](https://github.com/adap/flower/pull/1800), " +"[#1804](https://github.com/adap/flower/pull/1804), " +"[#1805](https://github.com/adap/flower/pull/1805))" +msgstr "" +"**普通改进** ([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/adap/flower/pull/1705), " +"[#1708](https://github.com/adap/flower/pull/1708), " +"[#1711](https://github.com/adap/flower/pull/1711), " +"[#1713](https://github.com/adap/flower/pull/1713), " +"[#1714](https://github.com/adap/flower/pull/1714), " +"[#1718](https://github.com/adap/flower/pull/1718), " +"[#1716](https://github.com/adap/flower/pull/1716), " +"[#1723](https://github.com/adap/flower/pull/1723), " +"[#1735](https://github.com/adap/flower/pull/1735), " +"[#1678](https://github.com/adap/flower/pull/1678), " +"[#1750](https://github.com/adap/flower/pull/1750), " +"[#1753](https://github.com/adap/flower/pull/1753), " +"[#1736](https://github.com/adap/flower/pull/1736), " +"[#1766](https://github.com/adap/flower/pull/1766), " +"[#1760](https://github.com/adap/flower/pull/1760), " +"[#1775](https://github.com/adap/flower/pull/1775), " +"[#1776](https://github.com/adap/flower/pull/1776), " +"[#1777](https://github.com/adap/flower/pull/1777), " +"[#1779](https://github.com/adap/flower/pull/1779), " +"[#1784](https://github.com/adap/flower/pull/1784), " +"[#1773](https://github.com/adap/flower/pull/1773), " +"[#1755](https://github.com/adap/flower/pull/1755), " +"[#1789](https://github.com/adap/flower/pull/1789), " +"[#1788](https://github.com/adap/flower/pull/1788), " +"[#1798](https://github.com/adap/flower/pull/1798), " +"[#1799](https://github.com/adap/flower/pull/1799), " +"[#1739](https://github.com/adap/flower/pull/1739), " +"[#1800](https://github.com/adap/flower/pull/1800), " +"[#1804](https://github.com/adap/flower/pull/1804), " +"[#1805](https://github.com/adap/flower/pull/1805))" + +#: ../../source/ref-changelog.md:416 msgid "v1.3.0 (2023-02-06)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:356 +#: ../../source/ref-changelog.md:422 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " -"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " -"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" -#: ../../source/ref-changelog.md:360 +#: ../../source/ref-changelog.md:426 msgid "" "**Add support for** `workload_id` **and** `group_id` **in Driver API** " "([#1595](https://github.com/adap/flower/pull/1595))" msgstr "" -"**在驱动程序应用程序接口中添加对** `workload_id` **和** `group_id` **的支持" -"** ([#1595](https://github.com/adap/flower/pull/1595))" +"**在驱动程序应用程序接口中添加对** `workload_id` **和** `group_id` **的支持** " +"([#1595](https://github.com/adap/flower/pull/1595))" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:428 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be used " -"to identify which workload a task belongs to. It also supports a new " -"`group_id` that can be used, for example, to indicate the current training " -"round. Both the `workload_id` and `group_id` enable client nodes to decide " -"whether they want to handle a task or not." +"The (experimental) Driver API now supports a `workload_id` that can be " +"used to identify which workload a task belongs to. It also supports a new" +" `group_id` that can be used, for example, to indicate the current " +"training round. Both the `workload_id` and `group_id` enable client nodes" +" to decide whether they want to handle a task or not." msgstr "" -"驱动程序 API(试验性)现在支持 `workload_id`,可用于识别任务所属的工作量。它" -"还支持新的 `group_id`,例如,可用于指示当前的训练轮次。通过 `workload_id` 和 " -"`group_id` 客户端节点可以决定是否要处理某个任务。" +"驱动程序 API(试验性)现在支持 `workload_id`,可用于识别任务所属的工作量。它还支持新的 " +"`group_id`,例如,可用于指示当前的训练轮次。通过 `workload_id` 和 `group_id` " +"客户端节点可以决定是否要处理某个任务。" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:430 msgid "" -"**Make Driver API and Fleet API address configurable** ([#1637](https://" -"github.com/adap/flower/pull/1637))" +"**Make Driver API and Fleet API address configurable** " +"([#1637](https://github.com/adap/flower/pull/1637))" msgstr "" -"**使Driver API 和Fleet API地址可配置**([#1637](https://github.com/adap/" -"flower/pull/1637))" +"**使Driver API 和Fleet " +"API地址可配置**([#1637](https://github.com/adap/flower/pull/1637))" -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:432 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) can " -"now configure the server address of both Driver API (via `--driver-api-" -"address`) and Fleet API (via `--fleet-api-address`) when starting:" +"The (experimental) long-running Flower server (Driver API and Fleet API) " +"can now configure the server address of both Driver API (via `--driver-" +"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" -"长期运行的 Flower 服务器(Driver API 和 Fleet API)现在可以在启动时配置 " -"Driver API(通过 `--driver-api-address`)和 Fleet API(通过 `-fleet-api-" -"address`)的服务器地址:" +"长期运行的 Flower 服务器(Driver API 和 Fleet API)现在可以在启动时配置 Driver API(通过 " +"`--driver-api-address`)和 Fleet API(通过 `-fleet-api-address`)的服务器地址:" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:434 #, fuzzy msgid "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " @@ -16821,931 +18284,977 @@ msgstr "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " "\"0.0.0.0:8086\"`" -#: ../../source/ref-changelog.md:370 +#: ../../source/ref-changelog.md:436 msgid "Both IPv4 and IPv6 addresses are supported." msgstr "支持 IPv4 和 IPv6 地址。" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:438 msgid "" -"**Add new example of Federated Learning using fastai and Flower** ([#1598]" -"(https://github.com/adap/flower/pull/1598))" +"**Add new example of Federated Learning using fastai and Flower** " +"([#1598](https://github.com/adap/flower/pull/1598))" msgstr "" -"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** ([#1598](https://github." -"com/adap/flower/pull/1598))" +"** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " +"([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:440 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples/" -"quickstart-fastai)." -msgstr "" -"一个新的代码示例(`quickstart-fastai`)演示了使用 [fastai](https://www.fast." -"ai/) 和 Flower 的联邦学习。您可以在这里找到它: [quickstart-fastai](https://" -"github.com/adap/flower/tree/main/examples/quickstart-fastai)。" - -#: ../../source/ref-changelog.md:376 -msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest " -"versions of Android** ([#1603](https://github.com/adap/flower/pull/1603))" -msgstr "" -"**使安卓示例兼容** `flwr >= 1.0.0` **和最新版本的安卓** ([#1603](https://" -"github.com/adap/flower/pull/1603))" - -#: ../../source/ref-changelog.md:378 -msgid "" -"The Android code example has received a substantial update: the project is " -"compatible with Flower 1.0 (and later), the UI received a full refresh, and " -"the project is updated to be compatible with newer Android tooling." -msgstr "" -"Android 代码示例已进行了大幅更新:项目兼容 Flower 1.0(及更高版本),用户界面" -"已全面刷新,项目已更新为兼容较新的 Android 工具。" - -#: ../../source/ref-changelog.md:380 -msgid "" -"**Add new `FedProx` strategy** ([#1619](https://github.com/adap/flower/" -"pull/1619))" -msgstr "" -"**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/" -"pull/1619))" - -#: ../../source/ref-changelog.md:382 -msgid "" -"This [strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/" -"strategy/fedprox.py) is almost identical to [`FedAvg`](https://github.com/" -"adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py), but helps " -"users replicate what is described in this [paper](https://arxiv.org/" -"abs/1812.06127). It essentially adds a parameter called `proximal_mu` to " -"regularize the local models with respect to the global models." -msgstr "" -"该[策略](https://github.com/adap/flower/blob/main/src/py/flwr/server/" -"strategy/fedprox.py)与[`FedAvg`](https://github.com/adap/flower/blob/main/" -"src/py/flwr/server/strategy/fedavg.py)几乎相同,但可以帮助用户复现本[论文]" -"(https://arxiv.org/abs/1812.06127)中的描述。它的本质是添加一个名为 " -"`proximal_mu`的参数,使局部模型与全局模型正则化。" - -#: ../../source/ref-changelog.md:384 -msgid "" -"**Add new metrics to telemetry events** ([#1640](https://github.com/adap/" -"flower/pull/1640))" +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" +"/quickstart-fastai)." msgstr "" -"**为遥测事件添加新指标**([#1640](https://github.com/adap/flower/pull/1640))" - -#: ../../source/ref-changelog.md:386 -msgid "" -"An updated event structure allows, for example, the clustering of events " -"within the same workload." -msgstr "例如,更新后的事件结构可以将同一工作负载中的事件集中在一起。" +"一个新的代码示例(`quickstart-fastai`)演示了使用 [fastai](https://www.fast.ai/) 和 " +"Flower 的联邦学习。您可以在这里找到它: [quickstart-" +"fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" +"fastai)。" -#: ../../source/ref-changelog.md:388 +#: ../../source/ref-changelog.md:442 msgid "" -"**Add new custom strategy tutorial section** [#1623](https://github.com/adap/" -"flower/pull/1623)" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" +" versions of Android** " +"([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -"**添加新的自定义策略教程部分** [#1623](https://github.com/adap/flower/" -"pull/1623)" +"**使安卓示例兼容** `flwr >= 1.0.0` **和最新版本的安卓** " +"([#1603](https://github.com/adap/flower/pull/1603))" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:444 msgid "" -"The Flower tutorial now has a new section that covers implementing a custom " -"strategy from scratch: [Open in Colab](https://colab.research.google.com/" -"github/adap/flower/blob/main/doc/source/tutorial-build-a-strategy-from-" -"scratch-pytorch.ipynb)" +"The Android code example has received a substantial update: the project " +"is compatible with Flower 1.0 (and later), the UI received a full " +"refresh, and the project is updated to be compatible with newer Android " +"tooling." msgstr "" -"Flower 教程新增了一个章节,介绍如何从零开始实施自定义策略: [在 Colab 中打开]" -"(https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" -"tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"Android 代码示例已进行了大幅更新:项目兼容 Flower 1.0(及更高版本),用户界面已全面刷新,项目已更新为兼容较新的 Android" +" 工具。" -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:446 msgid "" -"**Add new custom serialization tutorial section** ([#1622](https://github." -"com/adap/flower/pull/1622))" -msgstr "" -"** 添加新的自定义序列化教程部分** ([#1622](https://github.com/adap/flower/" -"pull/1622))" +"**Add new `FedProx` strategy** " +"([#1619](https://github.com/adap/flower/pull/1619))" +msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:448 msgid "" -"The Flower tutorial now has a new section that covers custom serialization: " -"[Open in Colab](https://colab.research.google.com/github/adap/flower/blob/" -"main/doc/source/tutorial-customize-the-client-pytorch.ipynb)" +"This " +"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" +" is almost identical to " +"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," +" but helps users replicate what is described in this " +"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " +"parameter called `proximal_mu` to regularize the local models with " +"respect to the global models." msgstr "" -"Flower 教程现在新增了一个章节,介绍自定义序列化: [在 Colab 中打开](https://" -"colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial-" -"customize-the-client-pytorch.ipynb)" - -#: ../../source/ref-changelog.md:396 -msgid "" -"**General improvements** ([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), [#1636](https://github." -"com/adap/flower/pull/1636), [#1635](https://github.com/adap/flower/" -"pull/1635), [#1633](https://github.com/adap/flower/pull/1633), [#1632]" -"(https://github.com/adap/flower/pull/1632), [#1631](https://github.com/adap/" -"flower/pull/1631), [#1630](https://github.com/adap/flower/pull/1630), [#1627]" -"(https://github.com/adap/flower/pull/1627), [#1593](https://github.com/adap/" -"flower/pull/1593), [#1616](https://github.com/adap/flower/pull/1616), [#1615]" -"(https://github.com/adap/flower/pull/1615), [#1607](https://github.com/adap/" -"flower/pull/1607), [#1609](https://github.com/adap/flower/pull/1609), [#1608]" -"(https://github.com/adap/flower/pull/1608), [#1603](https://github.com/adap/" -"flower/pull/1603), [#1590](https://github.com/adap/flower/pull/1590), [#1580]" -"(https://github.com/adap/flower/pull/1580), [#1599](https://github.com/adap/" -"flower/pull/1599), [#1600](https://github.com/adap/flower/pull/1600), [#1601]" -"(https://github.com/adap/flower/pull/1601), [#1597](https://github.com/adap/" -"flower/pull/1597), [#1595](https://github.com/adap/flower/pull/1595), [#1591]" -"(https://github.com/adap/flower/pull/1591), [#1588](https://github.com/adap/" -"flower/pull/1588), [#1589](https://github.com/adap/flower/pull/1589), [#1587]" -"(https://github.com/adap/flower/pull/1587), [#1573](https://github.com/adap/" -"flower/pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" -"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" -"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" -"(https://github.com/adap/flower/pull/1586))" -msgstr "" -"**普通改进** ([#1638](https://github.com/adap/flower/pull/1638), [#1634]" -"(https://github.com/adap/flower/pull/1634), [#1636](https://github.com/adap/" -"flower/pull/1636), [#1635](https://github.com/adap/flower/pull/1635), [#1633]" -"(https://github.com/adap/flower/pull/1633), [#1632](https://github.com/adap/" -"flower/pull/1632), [#1631](https://github.com/adap/flower/pull/1631), [#1630]" -"(https://github.com/adap/flower/pull/1630), [#1627](https://github. com/adap/" -"flower/pull/1627), [#1593](https://github.com/adap/flower/pull/1593), [#1616]" -"(https://github.com/adap/flower/pull/1616), [#1615](https://github.com/adap/" -"flower/pull/1615), [#1607](https://github.com/adap/flower/pull/1607), [#1609]" -"(https://github.com/adap/flower/pull/1609), [#1608](https://github.com/adap/" -"flower/pull/1608), [#1603](https://github.com/adap/flower/pull/1603), [#1590]" -"(https://github. com/adap/flower/pull/1590), [#1580](https://github.com/adap/" -"flower/pull/1580), [#1599](https://github.com/adap/flower/pull/1599), [#1600]" -"(https://github.com/adap/flower/pull/1600), [#1601](https://github.com/adap/" -"flower/pull/1601), [#1597](https://github.com/adap/flower/pull/1597), [#1595]" -"(https://github.com/adap/flower/pull/1595), [#1591](https://github.com/adap/" -"flower/pull/1591), [#1588](https://github. com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), [#1587](https://github." -"com/adap/flower/pull/1587), [#1573](https://github.com/adap/flower/" -"pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" -"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" -"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" -"(https://github.com/adap/flower/pull/1586))" +"该[策略](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)与[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)几乎相同,但可以帮助用户复现本[论文](https://arxiv.org/abs/1812.06127)中的描述。它的本质是添加一个名为" +" `proximal_mu`的参数,使局部模型与全局模型正则化。" -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:450 msgid "" -"**Updated documentation** ([#1629](https://github.com/adap/flower/" -"pull/1629), [#1628](https://github.com/adap/flower/pull/1628), [#1620]" -"(https://github.com/adap/flower/pull/1620), [#1618](https://github.com/adap/" -"flower/pull/1618), [#1617](https://github.com/adap/flower/pull/1617), [#1613]" -"(https://github.com/adap/flower/pull/1613), [#1614](https://github.com/adap/" -"flower/pull/1614))" -msgstr "" -"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), [#1628]" -"(https://github.com/adap/flower/pull/1628), [#1620](https://github.com/adap/" -"flower/pull/1620), [#1618](https://github.com/adap/flower/pull/1618), [#1617]" -"(https://github.com/adap/flower/pull/1617), [#1613](https://github.com/adap/" -"flower/pull/1613), [#1614](https://github.com/adap/flower/pull/1614)))" +"**Add new metrics to telemetry events** " +"([#1640](https://github.com/adap/flower/pull/1640))" +msgstr "**为遥测事件添加新指标**([#1640](https://github.com/adap/flower/pull/1640))" -#: ../../source/ref-changelog.md:402 ../../source/ref-changelog.md:469 +#: ../../source/ref-changelog.md:452 msgid "" -"As usual, the documentation has improved quite a bit. It is another step in " -"our effort to make the Flower documentation the best documentation of any " -"project. Stay tuned and as always, feel free to provide feedback!" -msgstr "" -"和往常一样,我们的文档有了很大的改进。这是我们努力使 Flower 文档成为所有项目" -"中最好文档的又一步骤。请继续关注,并随时提供反馈意见!" +"An updated event structure allows, for example, the clustering of events " +"within the same workload." +msgstr "例如,更新后的事件结构可以将同一工作负载中的事件集中在一起。" -#: ../../source/ref-changelog.md:408 +#: ../../source/ref-changelog.md:454 +msgid "" +"**Add new custom strategy tutorial section** " +"[#1623](https://github.com/adap/flower/pull/1623)" +msgstr "**添加新的自定义策略教程部分** [#1623](https://github.com/adap/flower/pull/1623)" + +#: ../../source/ref-changelog.md:456 +msgid "" +"The Flower tutorial now has a new section that covers implementing a " +"custom strategy from scratch: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +msgstr "" +"Flower 教程新增了一个章节,介绍如何从零开始实施自定义策略: [在 Colab " +"中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" + +#: ../../source/ref-changelog.md:458 +msgid "" +"**Add new custom serialization tutorial section** " +"([#1622](https://github.com/adap/flower/pull/1622))" +msgstr "** 添加新的自定义序列化教程部分** ([#1622](https://github.com/adap/flower/pull/1622))" + +#: ../../source/ref-changelog.md:460 +msgid "" +"The Flower tutorial now has a new section that covers custom " +"serialization: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-customize-the-client-pytorch.ipynb)" +msgstr "" +"Flower 教程现在新增了一个章节,介绍自定义序列化: [在 Colab " +"中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-customize-the-client-pytorch.ipynb)" + +#: ../../source/ref-changelog.md:462 +msgid "" +"**General improvements** " +"([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github.com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github.com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/adap/flower/pull/1600), " +"[#1601](https://github.com/adap/flower/pull/1601), " +"[#1597](https://github.com/adap/flower/pull/1597), " +"[#1595](https://github.com/adap/flower/pull/1595), " +"[#1591](https://github.com/adap/flower/pull/1591), " +"[#1588](https://github.com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), " +"[#1587](https://github.com/adap/flower/pull/1587), " +"[#1573](https://github.com/adap/flower/pull/1573), " +"[#1581](https://github.com/adap/flower/pull/1581), " +"[#1578](https://github.com/adap/flower/pull/1578), " +"[#1574](https://github.com/adap/flower/pull/1574), " +"[#1572](https://github.com/adap/flower/pull/1572), " +"[#1586](https://github.com/adap/flower/pull/1586))" +msgstr "" +"**普通改进** ([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github. com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github. com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/adap/flower/pull/1600), " +"[#1601](https://github.com/adap/flower/pull/1601), " +"[#1597](https://github.com/adap/flower/pull/1597), " +"[#1595](https://github.com/adap/flower/pull/1595), " +"[#1591](https://github.com/adap/flower/pull/1591), " +"[#1588](https://github. com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), " +"[#1587](https://github.com/adap/flower/pull/1587), " +"[#1573](https://github.com/adap/flower/pull/1573), " +"[#1581](https://github.com/adap/flower/pull/1581), " +"[#1578](https://github.com/adap/flower/pull/1578), " +"[#1574](https://github.com/adap/flower/pull/1574), " +"[#1572](https://github.com/adap/flower/pull/1572), " +"[#1586](https://github.com/adap/flower/pull/1586))" + +#: ../../source/ref-changelog.md:466 +msgid "" +"**Updated documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" +msgstr "" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614)))" + +#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 +msgid "" +"As usual, the documentation has improved quite a bit. It is another step " +"in our effort to make the Flower documentation the best documentation of " +"any project. Stay tuned and as always, feel free to provide feedback!" +msgstr "和往常一样,我们的文档有了很大的改进。这是我们努力使 Flower 文档成为所有项目中最好文档的又一步骤。请继续关注,并随时提供反馈意见!" + +#: ../../source/ref-changelog.md:474 msgid "v1.2.0 (2023-01-13)" msgstr "v1.2.0 (2023-01-13)" -#: ../../source/ref-changelog.md:414 +#: ../../source/ref-changelog.md:480 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " -"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." +" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " -"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." +" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" -#: ../../source/ref-changelog.md:418 +#: ../../source/ref-changelog.md:484 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/" -"adap/flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" +"**Introduce new Flower Baseline: FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -"**引入新的 Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/adap/" -"flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" +"**引入新的 Flower Baseline: FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" -#: ../../source/ref-changelog.md:420 +#: ../../source/ref-changelog.md:486 msgid "" "Over the coming weeks, we will be releasing a number of new reference " "implementations useful especially to FL newcomers. They will typically " "revisit well known papers from the literature, and be suitable for " "integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in this " -"series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-pack-" -"fedavg-mnist-cnn/)" +"deepen your knowledge of FL in general. Today's release is the first in " +"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" +"pack-fedavg-mnist-cnn/)" msgstr "" -"在未来几周内,我们将发布一些新的参考,特别是对 FL 新手有用的方法。它们通常会" -"重温文献中的知名论文,适合集成到您自己的应用程序中或用于实验,以加深您对 FL " -"的总体了解。今天发布的是该系列中的第一篇。[阅读全文](https://flower.ai/" -"blog/2023-01-12-fl-starter-pack-fedavg-mnist-cnn/)" +"在未来几周内,我们将发布一些新的参考,特别是对 FL " +"新手有用的方法。它们通常会重温文献中的知名论文,适合集成到您自己的应用程序中或用于实验,以加深您对 FL " +"的总体了解。今天发布的是该系列中的第一篇。[阅读全文](https://flower.ai/blog/2023-01-12-fl-starter-" +"pack-fedavg-mnist-cnn/)" -#: ../../source/ref-changelog.md:422 +#: ../../source/ref-changelog.md:488 msgid "" -"**Improve GPU support in simulations** ([#1555](https://github.com/adap/" -"flower/pull/1555))" -msgstr "" -"**改进模拟中的 GPU 支持**([#1555](https://github.com/adap/flower/" -"pull/1555))" +"**Improve GPU support in simulations** " +"([#1555](https://github.com/adap/flower/pull/1555))" +msgstr "**改进模拟中的 GPU 支持**([#1555](https://github.com/adap/flower/pull/1555))" -#: ../../source/ref-changelog.md:424 +#: ../../source/ref-changelog.md:490 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated to " -"improve GPU support. The update includes some of the hard-earned lessons " -"from scaling simulations in GPU cluster environments. New defaults make " -"running GPU-based simulations substantially more robust." +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" +" to improve GPU support. The update includes some of the hard-earned " +"lessons from scaling simulations in GPU cluster environments. New " +"defaults make running GPU-based simulations substantially more robust." msgstr "" -"基于 Ray 的虚拟客户端引擎 (`start_simulation`)已更新,以改进对 GPU 的支持。此" -"次更新包含了在 GPU 集群环境中扩展模拟的一些经验教训。新的默认设置使基于 GPU " -"的模拟运行更加稳健。" +"基于 Ray 的虚拟客户端引擎 (`start_simulation`)已更新,以改进对 GPU 的支持。此次更新包含了在 GPU " +"集群环境中扩展模拟的一些经验教训。新的默认设置使基于 GPU 的模拟运行更加稳健。" -#: ../../source/ref-changelog.md:426 +#: ../../source/ref-changelog.md:492 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** ([#1527](https://" -"github.com/adap/flower/pull/1527), [#1558](https://github.com/adap/flower/" -"pull/1558))" +"**Improve GPU support in Jupyter Notebook tutorials** " +"([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" msgstr "" -"**改进 Jupyter Notebook 教程中的 GPU 支持** ([#1527](https://github.com/adap/" -"flower/pull/1527), [#1558](https://github.com/adap/flower/pull/1558))" +"**改进 Jupyter Notebook 教程中的 GPU 支持** " +"([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" -#: ../../source/ref-changelog.md:428 +#: ../../source/ref-changelog.md:494 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to use " -"on GPU instances. We listened and made improvements to all of our Jupyter " -"notebooks! Check out the updated notebooks here:" +"Some users reported that Jupyter Notebooks have not always been easy to " +"use on GPU instances. We listened and made improvements to all of our " +"Jupyter notebooks! Check out the updated notebooks here:" msgstr "" -"一些用户报告说,在 GPU 实例上使用 Jupyter 笔记本并不是很方便。我们听取了他们" -"的意见,并对所有 Jupyter 笔记本进行了改进!点击这里查看更新后的笔记本:" +"一些用户报告说,在 GPU 实例上使用 Jupyter 笔记本并不是很方便。我们听取了他们的意见,并对所有 Jupyter " +"笔记本进行了改进!点击这里查看更新后的笔记本:" -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:496 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework/" -"tutorial-get-started-with-flower-pytorch.html)" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework" +"/tutorial-get-started-with-flower-pytorch.html)" msgstr "" "[联邦学习简介](https://flower.ai/docs/framework/tutorial-get-started-with-" "flower-pytorch.html)" -#: ../../source/ref-changelog.md:431 +#: ../../source/ref-changelog.md:497 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework/tutorial-" -"use-a-federated-learning-strategy-pytorch.html)" +"[Strategies in Federated Learning](https://flower.ai/docs/framework" +"/tutorial-use-a-federated-learning-strategy-pytorch.html)" msgstr "" "[联邦学习策略](https://flower.ai/docs/framework/tutorial-use-a-federated-" "learning-strategy-pytorch.html)" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:498 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a-" -"strategy-from-scratch-pytorch.html)" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" +"-strategy-from-scratch-pytorch.html)" msgstr "" "[制定策略](https://flower.ai/docs/framework/tutorial-build-a-strategy-from-" "scratch-pytorch.html)" -#: ../../source/ref-changelog.md:433 +#: ../../source/ref-changelog.md:499 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" -"the-client-pytorch.html)" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" +"customize-the-client-pytorch.html)" msgstr "" "[客户端和 NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" "the-client-pytorch.html)" -#: ../../source/ref-changelog.md:435 +#: ../../source/ref-changelog.md:501 msgid "" -"**Introduce optional telemetry** ([#1533](https://github.com/adap/flower/" -"pull/1533), [#1544](https://github.com/adap/flower/pull/1544), [#1584]" -"(https://github.com/adap/flower/pull/1584))" +"**Introduce optional telemetry** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" msgstr "" -"**引入可选遥测**([#1533](https://github.com/adap/flower/pull/1533), [#1544]" -"(https://github.com/adap/flower/pull/1544), [#1584](https://github.com/adap/" -"flower/pull/1584)" +"**引入可选遥测**([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584)" -#: ../../source/ref-changelog.md:437 +#: ../../source/ref-changelog.md:503 msgid "" -"After a [request for feedback](https://github.com/adap/flower/issues/1534) " -"from the community, the Flower open-source project introduces optional " -"collection of *anonymous* usage metrics to make well-informed decisions to " -"improve Flower. Doing this enables the Flower team to understand how Flower " -"is used and what challenges users might face." +"After a [request for " +"feedback](https://github.com/adap/flower/issues/1534) from the community," +" the Flower open-source project introduces optional collection of " +"*anonymous* usage metrics to make well-informed decisions to improve " +"Flower. Doing this enables the Flower team to understand how Flower is " +"used and what challenges users might face." msgstr "" "在社区发出[反馈请求](https://github.com/adap/flower/issues/1534)之后,Flower " -"开放源码项目引入了可选的*匿名*使用指标收集,以便在充分知情的情况下做出改进 " -"Flower 的决定。这样做能让 Flower 团队了解 Flower 的使用情况以及用户可能面临的" -"挑战。" +"开放源码项目引入了可选的*匿名*使用指标收集,以便在充分知情的情况下做出改进 Flower 的决定。这样做能让 Flower 团队了解 " +"Flower 的使用情况以及用户可能面临的挑战。" -#: ../../source/ref-changelog.md:439 +#: ../../source/ref-changelog.md:505 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.** " -"Staying true to this statement, Flower makes it easy to disable telemetry " -"for users who do not want to share anonymous usage metrics. [Read more.]" -"(https://flower.ai/docs/telemetry.html)." +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users who do not want to share anonymous usage metrics. " +"[Read more.](https://flower.ai/docs/telemetry.html)." msgstr "" -"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声" -"明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。[阅读全文](https://" -"flower.ai/docs/telemetry.html)。" +"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower " +"遵循这一声明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。[阅读全文](https://flower.ai/docs/telemetry.html)。" -#: ../../source/ref-changelog.md:441 +#: ../../source/ref-changelog.md:507 msgid "" -"**Introduce (experimental) Driver API** ([#1520](https://github.com/adap/" -"flower/pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" -"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" -"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" -"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" -"flower/pull/1567))" -msgstr "" -"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/" -"pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" -"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" -"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" -"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" -"flower/pull/1567))" +"**Introduce (experimental) Driver API** " +"([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" +msgstr "" +"**引入(试验性)Driver API** ([#1520](https://github.com/adap/flower/pull/1520)," +" [#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:443 +#: ../../source/ref-changelog.md:509 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API " -"will be the abstraction that many upcoming features will be built on - and " -"you can start building those things now, too." +"Analytics applications. Phew, that's a lot! Going forward, the Driver API" +" will be the abstraction that many upcoming features will be built on - " +"and you can start building those things now, too." msgstr "" -"Flower 现在有了一个新的(试验性的)驱动程序应用程序接口(Driver API),它将支" -"持完全可编程、异步和多租户的联邦学习(Federated Learning)和联邦分析" -"(Federated Analytics)应用程序。展望未来,Driver API 将成为许多即将推出的功" -"能的抽象基础,您现在就可以开始构建这些功能。" +"Flower 现在有了一个新的(试验性的)驱动程序应用程序接口(Driver " +"API),它将支持完全可编程、异步和多租户的联邦学习(Federated Learning)和联邦分析(Federated " +"Analytics)应用程序。展望未来,Driver API 将成为许多即将推出的功能的抽象基础,您现在就可以开始构建这些功能。" -#: ../../source/ref-changelog.md:445 +#: ../../source/ref-changelog.md:511 msgid "" -"The Driver API also enables a new execution mode in which the server runs " -"indefinitely. Multiple individual workloads can run concurrently and start " -"and stop their execution independent of the server. This is especially " -"useful for users who want to deploy Flower in production." +"The Driver API also enables a new execution mode in which the server runs" +" indefinitely. Multiple individual workloads can run concurrently and " +"start and stop their execution independent of the server. This is " +"especially useful for users who want to deploy Flower in production." msgstr "" -"驱动程序应用程序接口还支持一种新的执行模式,在这种模式下,服务器可无限期运" -"行。多个单独的工作负载可以同时运行,并独立于服务器启动和停止执行。这对于希望" -"在生产中部署 Flower 的用户来说尤其有用。" +"驱动程序应用程序接口还支持一种新的执行模式,在这种模式下,服务器可无限期运行。多个单独的工作负载可以同时运行,并独立于服务器启动和停止执行。这对于希望在生产中部署" +" Flower 的用户来说尤其有用。" -#: ../../source/ref-changelog.md:447 +#: ../../source/ref-changelog.md:513 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward to " -"you feedback!" +"To learn more, check out the `mt-pytorch` code example. We look forward " +"to you feedback!" msgstr "要了解更多信息,请查看 `mt-pytorch` 代码示例。我们期待您的反馈!" -#: ../../source/ref-changelog.md:449 +#: ../../source/ref-changelog.md:515 msgid "" -"Please note: *The Driver API is still experimental and will likely change " -"significantly over time.*" +"Please note: *The Driver API is still experimental and will likely change" +" significantly over time.*" msgstr "请注意:Driver API仍处于试验阶段,随着时间的推移可能会发生重大变化。*" -#: ../../source/ref-changelog.md:451 +#: ../../source/ref-changelog.md:517 msgid "" -"**Add new Federated Analytics with Pandas example** ([#1469](https://github." -"com/adap/flower/pull/1469), [#1535](https://github.com/adap/flower/" -"pull/1535))" +"**Add new Federated Analytics with Pandas example** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" msgstr "" -"** 添加新的使用 Pandas 的联邦分析示例**([#1469](https://github.com/adap/" -"flower/pull/1469), [#1535](https://github.com/adap/flower/pull/1535)" +"** 添加新的使用 Pandas " +"的联邦分析示例**([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535)" -#: ../../source/ref-changelog.md:453 +#: ../../source/ref-changelog.md:519 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics " -"with Pandas and Flower. You can find it here: [quickstart-pandas](https://" -"github.com/adap/flower/tree/main/examples/quickstart-pandas)." +"A new code example (`quickstart-pandas`) demonstrates federated analytics" +" with Pandas and Flower. You can find it here: [quickstart-" +"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" +"pandas)." msgstr "" -"新代码示例(`quickstart-pandas`)演示了使用 Pandas 和 Flower 进行联邦分析。您" -"可以在此处找到它: [quickstart-pandas](https://github.com/adap/flower/tree/" -"main/examples/quickstart-pandas)。" +"新代码示例(`quickstart-pandas`)演示了使用 Pandas 和 Flower 进行联邦分析。您可以在此处找到它: " +"[quickstart-pandas](https://github.com/adap/flower/tree/main/examples" +"/quickstart-pandas)。" -#: ../../source/ref-changelog.md:455 +#: ../../source/ref-changelog.md:521 msgid "" -"**Add new strategies: Krum and MultiKrum** ([#1481](https://github.com/adap/" -"flower/pull/1481))" +"**Add new strategies: Krum and MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" msgstr "" -"**添加新策略: Krum 和 MultiKrum** ([#1481](https://github.com/adap/flower/" -"pull/1481))" +"**添加新策略: Krum 和 MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" -#: ../../source/ref-changelog.md:457 +#: ../../source/ref-changelog.md:523 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum and " -"MultiKrum in their workloads." +"contributed a new `Krum` strategy that enables users to easily use Krum " +"and MultiKrum in their workloads." msgstr "" -"罗马萨皮恩扎大学(Sapienza University)计算机科学专业的学生埃多尔多" -"(Edoardo)提出了一种新的 \"Krum \"策略,使用户能够在其工作负载中轻松使用 " -"Krum 和 MultiKrum。" +"罗马萨皮恩扎大学(Sapienza University)计算机科学专业的学生埃多尔多(Edoardo)提出了一种新的 \"Krum " +"\"策略,使用户能够在其工作负载中轻松使用 Krum 和 MultiKrum。" -#: ../../source/ref-changelog.md:459 +#: ../../source/ref-changelog.md:525 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** ([#1495](https://" -"github.com/adap/flower/pull/1495))" +"**Update C++ example to be compatible with Flower v1.2.0** " +"([#1495](https://github.com/adap/flower/pull/1495))" msgstr "" -"** 更新 C++ 示例,与 Flower v1.2.0 兼容** ([#1495](https://github.com/adap/" -"flower/pull/1495))" +"** 更新 C++ 示例,与 Flower v1.2.0 兼容** " +"([#1495](https://github.com/adap/flower/pull/1495))" -#: ../../source/ref-changelog.md:461 +#: ../../source/ref-changelog.md:527 msgid "" -"The C++ code example has received a substantial update to make it compatible " -"with the latest version of Flower." +"The C++ code example has received a substantial update to make it " +"compatible with the latest version of Flower." msgstr "为了与最新版本的 Flower 兼容,C++ 示例代码进行了大幅更新。" -#: ../../source/ref-changelog.md:463 -msgid "" -"**General improvements** ([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), [#1506](https://github." -"com/adap/flower/pull/1506), [#1514](https://github.com/adap/flower/" -"pull/1514), [#1522](https://github.com/adap/flower/pull/1522), [#1523]" -"(https://github.com/adap/flower/pull/1523), [#1526](https://github.com/adap/" -"flower/pull/1526), [#1528](https://github.com/adap/flower/pull/1528), [#1547]" -"(https://github.com/adap/flower/pull/1547), [#1549](https://github.com/adap/" -"flower/pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" -"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" -"flower/pull/1566))" -msgstr "" -"**普通改进** ([#1491](https://github.com/adap/flower/pull/1491), [#1504]" -"(https://github.com/adap/flower/pull/1504), [#1506](https://github.com/adap/" -"flower/pull/1506), [#1514](https://github.com/adap/flower/pull/1514), [#1522]" -"(https://github.com/adap/flower/pull/1522), [#1523](https://github.com/adap/" -"flower/pull/1523), [#1526](https://github. com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), [#1547](https://github." -"com/adap/flower/pull/1547), [#1549](https://github.com/adap/flower/" -"pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" -"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" -"flower/pull/1566))" - -#: ../../source/ref-changelog.md:467 -msgid "" -"**Updated documentation** ([#1494](https://github.com/adap/flower/" -"pull/1494), [#1496](https://github.com/adap/flower/pull/1496), [#1500]" -"(https://github.com/adap/flower/pull/1500), [#1503](https://github.com/adap/" -"flower/pull/1503), [#1505](https://github.com/adap/flower/pull/1505), [#1524]" -"(https://github.com/adap/flower/pull/1524), [#1518](https://github.com/adap/" -"flower/pull/1518), [#1519](https://github.com/adap/flower/pull/1519), [#1515]" -"(https://github.com/adap/flower/pull/1515))" -msgstr "" -"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), [#1496]" -"(https://github.com/adap/flower/pull/1496), [#1500](https://github.com/adap/" -"flower/pull/1500), [#1503](https://github.com/adap/flower/pull/1503), [#1505]" -"(https://github.com/adap/flower/pull/1505), [#1524](https://github.com/adap/" -"flower/pull/1524), [#1518](https://github.com/adap/flower/pull/1518), [#1519]" -"(https://github.com/adap/flower/pull/1519), [#1515](https://github.com/adap/" -"flower/pull/1515))" - -#: ../../source/ref-changelog.md:471 -msgid "" -"One highlight is the new [first time contributor guide](https://flower.ai/" -"docs/first-time-contributors.html): if you've never contributed on GitHub " -"before, this is the perfect place to start!" +#: ../../source/ref-changelog.md:529 +msgid "" +"**General improvements** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" +msgstr "" +"**普通改进** ([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github. com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" + +#: ../../source/ref-changelog.md:533 +msgid "" +"**Updated documentation** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" +msgstr "" +"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" + +#: ../../source/ref-changelog.md:537 +msgid "" +"One highlight is the new [first time contributor " +"guide](https://flower.ai/docs/first-time-contributors.html): if you've " +"never contributed on GitHub before, this is the perfect place to start!" msgstr "" "其中一个亮点是新的[首次贡献者指南](https://flower.ai/docs/first-time-" -"contributors.html):如果你以前从未在 GitHub 上做过贡献,这将是一个完美的开" -"始!" +"contributors.html):如果你以前从未在 GitHub 上做过贡献,这将是一个完美的开始!" -#: ../../source/ref-changelog.md:477 +#: ../../source/ref-changelog.md:543 msgid "v1.1.0 (2022-10-31)" msgstr "v1.1.0 (2022-10-31)" -#: ../../source/ref-changelog.md:481 +#: ../../source/ref-changelog.md:547 msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" -msgstr "" -"在此,我们向所有促成 Flower 新版本的贡献者致以**特别的谢意(按 \"git " -"shortlog \"顺序排列):" +msgstr "在此,我们向所有促成 Flower 新版本的贡献者致以**特别的谢意(按 \"git shortlog \"顺序排列):" -#: ../../source/ref-changelog.md:483 +#: ../../source/ref-changelog.md:549 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " -"`edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" msgstr "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " -"`edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" -#: ../../source/ref-changelog.md:487 +#: ../../source/ref-changelog.md:553 msgid "" -"**Introduce Differential Privacy wrappers (preview)** ([#1357](https://" -"github.com/adap/flower/pull/1357), [#1460](https://github.com/adap/flower/" -"pull/1460))" +"**Introduce Differential Privacy wrappers (preview)** " +"([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" msgstr "" -"**引入差分隐私包装器(预览)** ([#1357](https://github.com/adap/flower/" -"pull/1357), [#1460](https://github.com/adap/flower/pull/1460))" +"**引入差分隐私包装器(预览)** ([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:489 +#: ../../source/ref-changelog.md:555 msgid "" -"The first (experimental) preview of pluggable Differential Privacy wrappers " -"enables easy configuration and usage of differential privacy (DP). The " -"pluggable DP wrappers enable framework-agnostic **and** strategy-agnostic " -"usage of both client-side DP and server-side DP. Head over to the Flower " -"docs, a new explainer goes into more detail." +"The first (experimental) preview of pluggable Differential Privacy " +"wrappers enables easy configuration and usage of differential privacy " +"(DP). The pluggable DP wrappers enable framework-agnostic **and** " +"strategy-agnostic usage of both client-side DP and server-side DP. Head " +"over to the Flower docs, a new explainer goes into more detail." msgstr "" -"可插拔差分隐私封装器的首个(实验性)预览版可轻松配置和使用差分隐私(DP)。可" -"插拔的差分隐私封装器可实现客户端差分隐私和服务器端差分隐私的框架无关**以及**" -"策略无关的使用。请访问 Flower 文档,新的解释器会提供更多细节。" +"可插拔差分隐私封装器的首个(实验性)预览版可轻松配置和使用差分隐私(DP)。可插拔的差分隐私封装器可实现客户端差分隐私和服务器端差分隐私的框架无关**以及**策略无关的使用。请访问" +" Flower 文档,新的解释器会提供更多细节。" -#: ../../source/ref-changelog.md:491 +#: ../../source/ref-changelog.md:557 msgid "" -"**New iOS CoreML code example** ([#1289](https://github.com/adap/flower/" -"pull/1289))" -msgstr "" -"**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/" -"pull/1289))" +"**New iOS CoreML code example** " +"([#1289](https://github.com/adap/flower/pull/1289))" +msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:493 +#: ../../source/ref-changelog.md:559 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can be " -"built for iOS. The code example contains both Flower iOS SDK components that " -"can be used for many tasks, and one task example running on CoreML." +"Flower goes iOS! A massive new code example shows how Flower clients can " +"be built for iOS. The code example contains both Flower iOS SDK " +"components that can be used for many tasks, and one task example running " +"on CoreML." msgstr "" -"Flower 进入 iOS!大量新代码示例展示了如何为 iOS 构建 Flower 客户端。该代码示" -"例包含可用于多种任务的 Flower iOS SDK 组件,以及在 CoreML 上运行的一个任务示" -"例。" +"Flower 进入 iOS!大量新代码示例展示了如何为 iOS 构建 Flower 客户端。该代码示例包含可用于多种任务的 Flower iOS " +"SDK 组件,以及在 CoreML 上运行的一个任务示例。" -#: ../../source/ref-changelog.md:495 +#: ../../source/ref-changelog.md:561 msgid "" -"**New FedMedian strategy** ([#1461](https://github.com/adap/flower/" -"pull/1461))" -msgstr "" -"**新的联邦医疗策略** ([#1461](https://github.com/adap/flower/pull/1461))" +"**New FedMedian strategy** " +"([#1461](https://github.com/adap/flower/pull/1461))" +msgstr "**新的联邦医疗策略** ([#1461](https://github.com/adap/flower/pull/1461))" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:563 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by [Yin " -"et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"The new `FedMedian` strategy implements Federated Median (FedMedian) by " +"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -"新的 \"FedMedian \"战略实现了[Yin 等人,2018]的联邦中值(FedMedian)(https://" -"arxiv.org/pdf/1803.01498v1.pdf)。" +"新的 \"FedMedian \"战略实现了[Yin " +"等人,2018]的联邦中值(FedMedian)(https://arxiv.org/pdf/1803.01498v1.pdf)。" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:565 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** ([#1493](https://" -"github.com/adap/flower/pull/1493))" -msgstr "" -"**虚拟客户端引擎中的**日志**`客户端`**异常([#1493](https://github.com/adap/" -"flower/pull/1493))" +"**Log** `Client` **exceptions in Virtual Client Engine** " +"([#1493](https://github.com/adap/flower/pull/1493))" +msgstr "**虚拟客户端引擎中的**日志**`客户端`**异常([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:567 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default and " -"not just exposed to the configured `Strategy` (via the `failures` argument)." -msgstr "" -"VCE 中发生的所有 \"客户端 \"异常现在都会被默认记录下来,而不只是暴露给配置的 " -"`Strategy`(通过 `failures`参数)。" +"All `Client` exceptions happening in the VCE are now logged by default " +"and not just exposed to the configured `Strategy` (via the `failures` " +"argument)." +msgstr "VCE 中发生的所有 \"客户端 \"异常现在都会被默认记录下来,而不只是暴露给配置的 `Strategy`(通过 `failures`参数)。" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:569 msgid "" -"**Improve Virtual Client Engine internals** ([#1401](https://github.com/adap/" -"flower/pull/1401), [#1453](https://github.com/adap/flower/pull/1453))" -msgstr "" -"**改进虚拟客户端引擎内部**([#1401](https://github.com/adap/flower/" -"pull/1401)、[#1453](https://github.com/adap/flower/pull/1453))" +"**Improve Virtual Client Engine internals** " +"([#1401](https://github.com/adap/flower/pull/1401), " +"[#1453](https://github.com/adap/flower/pull/1453))" +msgstr "**改进虚拟客户端引擎内部**([#1401](https://github.com/adap/flower/pull/1401)、[#1453](https://github.com/adap/flower/pull/1453))" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:571 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE now " -"uses Ray 2.0 under the hood, the value type of the `client_resources` " -"dictionary changed to `float` to allow fractions of resources to be " +"Some internals of the Virtual Client Engine have been revamped. The VCE " +"now uses Ray 2.0 under the hood, the value type of the `client_resources`" +" dictionary changed to `float` to allow fractions of resources to be " "allocated." msgstr "" -"虚拟客户端引擎的部分内部结构已进行了修改。VCE 现在使用 Ray " -"2.0,\"client_resources \"字典的值类型改为 \"float\",以允许分配分数资源。" +"虚拟客户端引擎的部分内部结构已进行了修改。VCE 现在使用 Ray 2.0,\"client_resources \"字典的值类型改为 " +"\"float\",以允许分配分数资源。" -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:573 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual Client " -"Engine**" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " +"Client Engine**" msgstr "**支持虚拟客户端引擎中的可选** `Client`**/**`NumPyClient` **方法**" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:575 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and " -"`NumPyClient`) methods." +"The Virtual Client Engine now has full support for optional `Client` (and" +" `NumPyClient`) methods." msgstr "虚拟客户端引擎现在完全支持可选的 `Client`(和 `NumPyClient`)方法。" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:577 msgid "" -"**Provide type information to packages using** `flwr` ([#1377](https://" -"github.com/adap/flower/pull/1377))" +"**Provide type information to packages using** `flwr` " +"([#1377](https://github.com/adap/flower/pull/1377))" msgstr "" -"**使用** `flwr`向软件包提供类型信息 ([#1377](https://github.com/adap/flower/" -"pull/1377))" +"**使用** `flwr`向软件包提供类型信息 " +"([#1377](https://github.com/adap/flower/pull/1377))" -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:579 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that the " -"package is typed. This enables typing support for projects or packages that " -"use `flwr` by enabling them to improve their code using static type checkers " -"like `mypy`." +"The package `flwr` is now bundled with a `py.typed` file indicating that " +"the package is typed. This enables typing support for projects or " +"packages that use `flwr` by enabling them to improve their code using " +"static type checkers like `mypy`." msgstr "" -"软件包 `flwr` 现在捆绑了一个 `py.typed` 文件,表明该软件包是类型化的。这样," -"使用 `flwr` 的项目或软件包就可以使用 `mypy` 等静态类型检查器改进代码,从而获" -"得类型支持。" +"软件包 `flwr` 现在捆绑了一个 `py.typed` 文件,表明该软件包是类型化的。这样,使用 `flwr` 的项目或软件包就可以使用 " +"`mypy` 等静态类型检查器改进代码,从而获得类型支持。" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:581 msgid "" -"**Updated code example** ([#1344](https://github.com/adap/flower/pull/1344), " +"**Updated code example** " +"([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -"** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), [#1347]" -"(https://github.com/adap/flower/pull/1347))" +"** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:583 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." -msgstr "" -"涵盖 scikit-learn 和 PyTorch Lightning 的代码示例已更新,以便与最新版本的 " -"Flower 配合使用。" - -#: ../../source/ref-changelog.md:519 -msgid "" -"**Updated documentation** ([#1355](https://github.com/adap/flower/" -"pull/1355), [#1558](https://github.com/adap/flower/pull/1558), [#1379]" -"(https://github.com/adap/flower/pull/1379), [#1380](https://github.com/adap/" -"flower/pull/1380), [#1381](https://github.com/adap/flower/pull/1381), [#1332]" -"(https://github.com/adap/flower/pull/1332), [#1391](https://github.com/adap/" -"flower/pull/1391), [#1403](https://github.com/adap/flower/pull/1403), [#1364]" -"(https://github.com/adap/flower/pull/1364), [#1409](https://github.com/adap/" -"flower/pull/1409), [#1419](https://github.com/adap/flower/pull/1419), [#1444]" -"(https://github.com/adap/flower/pull/1444), [#1448](https://github.com/adap/" -"flower/pull/1448), [#1417](https://github.com/adap/flower/pull/1417), [#1449]" -"(https://github.com/adap/flower/pull/1449), [#1465](https://github.com/adap/" -"flower/pull/1465), [#1467](https://github.com/adap/flower/pull/1467))" -msgstr "" -"**更新文档** ([#1355](https://github.com/adap/flower/pull/1355), [#1558]" -"(https://github.com/adap/flower/pull/1558), [#1379](https://github.com/adap/" -"flower/pull/1379), [#1380](https://github.com/adap/flower/pull/1380), [#1381]" -"(https://github.com/adap/flower/pull/1381), [#1332](https://github.com/adap/" -"flower/pull/1332), [#1391](https://github.com/adap/flower/pull/1391), [#1403]" -"(https://github.com/adap/flower/pull/1403), [#1364](https://github. com/adap/" -"flower/pull/1364), [#1409](https://github.com/adap/flower/pull/1409), [#1419]" -"(https://github.com/adap/flower/pull/1419), [#1444](https://github.com/adap/" -"flower/pull/1444), [#1448](https://github.com/adap/flower/pull/1448), [#1417]" -"(https://github.com/adap/flower/pull/1417), [#1449](https://github.com/adap/" -"flower/pull/1449), [#1465](https://github.com/adap/flower/pull/1465), [#1467]" -"(https://github.com/adap/flower/pull/1467))" - -#: ../../source/ref-changelog.md:521 +msgstr "涵盖 scikit-learn 和 PyTorch Lightning 的代码示例已更新,以便与最新版本的 Flower 配合使用。" + +#: ../../source/ref-changelog.md:585 +msgid "" +"**Updated documentation** " +"([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github.com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" +msgstr "" +"**更新文档** ([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github. com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" + +#: ../../source/ref-changelog.md:587 msgid "" "There have been so many documentation updates that it doesn't even make " "sense to list them individually." msgstr "文档更新的数量之多,甚至没有必要逐一列出。" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:589 msgid "" -"**Restructured documentation** ([#1387](https://github.com/adap/flower/" -"pull/1387))" +"**Restructured documentation** " +"([#1387](https://github.com/adap/flower/pull/1387))" msgstr "**重构文档**([#1387](https://github.com/adap/flower/pull/1387))" -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:591 msgid "" -"The documentation has been restructured to make it easier to navigate. This " -"is just the first step in a larger effort to make the Flower documentation " -"the best documentation of any project ever. Stay tuned!" -msgstr "" -"我们对文档进行了重组,使其更易于浏览。这只是让 Flower 文档成为所有项目中最好" -"文档的第一步。敬请期待!" +"The documentation has been restructured to make it easier to navigate. " +"This is just the first step in a larger effort to make the Flower " +"documentation the best documentation of any project ever. Stay tuned!" +msgstr "我们对文档进行了重组,使其更易于浏览。这只是让 Flower 文档成为所有项目中最好文档的第一步。敬请期待!" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:593 msgid "" -"**Open in Colab button** ([#1389](https://github.com/adap/flower/pull/1389))" -msgstr "" -"**在 Colab 中打开按钮** ([#1389](https://github.com/adap/flower/pull/1389))" +"**Open in Colab button** " +"([#1389](https://github.com/adap/flower/pull/1389))" +msgstr "**在 Colab 中打开按钮** ([#1389](https://github.com/adap/flower/pull/1389))" -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:595 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a new " -"`Open in Colab` button. No need to install anything on your local machine, " -"you can now use and learn about Flower in your browser, it's only a single " -"click away." +"The four parts of the Flower Federated Learning Tutorial now come with a " +"new `Open in Colab` button. No need to install anything on your local " +"machine, you can now use and learn about Flower in your browser, it's " +"only a single click away." msgstr "" -"Flower 联邦学习教程的四个部分现在都带有一个新的 \"在 Colab 中打开 \"按钮。现" -"在,您无需在本地计算机上安装任何软件,只需点击一下,就可以在浏览器中使用和学" -"习 Flower。" +"Flower 联邦学习教程的四个部分现在都带有一个新的 \"在 Colab 中打开 " +"\"按钮。现在,您无需在本地计算机上安装任何软件,只需点击一下,就可以在浏览器中使用和学习 Flower。" -#: ../../source/ref-changelog.md:531 +#: ../../source/ref-changelog.md:597 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468), " -"[#1470](https://github.com/adap/flower/pull/1470), [#1472](https://github." -"com/adap/flower/pull/1472), [#1473](https://github.com/adap/flower/" -"pull/1473), [#1474](https://github.com/adap/flower/pull/1474), [#1475]" -"(https://github.com/adap/flower/pull/1475))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" msgstr "" -"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), [#1470]" -"(https://github.com/adap/flower/pull/1470), [#1472](https://github.com/adap/" -"flower/pull/1472), [#1473](https://github.com/adap/flower/pull/1473), [#1474]" -"(https://github.com/adap/flower/pull/1474), [#1475](https://github.com/adap/" -"flower/pull/1475)))" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475)))" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:599 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved (many " -"small changes and fixes)." +"`NumPyClient`. The existing parts one and two have also been improved " +"(many small changes and fixes)." msgstr "" -"Flower 联邦学习教程有两个全新的部分,涉及自定义策略(仍处于 WIP 阶段)和 " -"`Client` 与 `NumPyClient` 之间的区别。现有的第一和第二部分也得到了改进(许多" -"小改动和修正)。" +"Flower 联邦学习教程有两个全新的部分,涉及自定义策略(仍处于 WIP 阶段)和 `Client` 与 `NumPyClient` " +"之间的区别。现有的第一和第二部分也得到了改进(许多小改动和修正)。" -#: ../../source/ref-changelog.md:539 +#: ../../source/ref-changelog.md:605 msgid "v1.0.0 (2022-07-28)" msgstr "v1.0.0 (2022-07-28)" -#: ../../source/ref-changelog.md:541 +#: ../../source/ref-changelog.md:607 msgid "Highlights" msgstr "亮点" -#: ../../source/ref-changelog.md:543 +#: ../../source/ref-changelog.md:609 msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "稳定的**虚拟客户端引擎**(可通过`start_simulation`访问)" -#: ../../source/ref-changelog.md:544 +#: ../../source/ref-changelog.md:610 msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "所有 `Client`/`NumPyClient` 方法现在都是可选的了" -#: ../../source/ref-changelog.md:545 +#: ../../source/ref-changelog.md:611 msgid "Configurable `get_parameters`" msgstr "可配置的`get_parameters`" -#: ../../source/ref-changelog.md:546 +#: ../../source/ref-changelog.md:612 msgid "" -"Tons of small API cleanups resulting in a more coherent developer experience" +"Tons of small API cleanups resulting in a more coherent developer " +"experience" msgstr "对大量小型应用程序接口进行了清理,使开发人员的体验更加一致" -#: ../../source/ref-changelog.md:550 +#: ../../source/ref-changelog.md:616 msgid "" "We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub Contributors](https://github." -"com/adap/flower/graphs/contributors) order):" -msgstr "" -"在此,我们谨向所有促成 Flower 1.0 的贡献者致以**特别的谢意(按[GitHub 贡献者]" -"(https://github.com/adap/flower/graphs/contributors) 倒序排列):" - -#: ../../source/ref-changelog.md:552 -msgid "" -"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" -"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" -"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" -"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." -"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" -"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." -"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." -"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" -"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" -"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" -"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" -"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" -"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." -"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" -"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" -"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" -"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" -"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" -"tanertopal), [@danieljanes](https://github.com/danieljanes)." -msgstr "" -"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" -"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" -"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" -"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." -"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" -"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." -"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." -"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" -"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" -"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" -"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" -"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" -"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." -"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" -"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" -"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" -"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" -"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" -"tanertopal), [@danieljanes](https://github.com/danieljanes)." - -#: ../../source/ref-changelog.md:556 -msgid "" -"**All arguments must be passed as keyword arguments** ([#1338](https://" -"github.com/adap/flower/pull/1338))" -msgstr "" -"** 所有参数必须作为关键字参数传递** ([#1338](https://github.com/adap/flower/" -"pull/1338))" - -#: ../../source/ref-changelog.md:558 -msgid "" -"Pass all arguments as keyword arguments, positional arguments are not longer " -"supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword for " -"each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())`)." -msgstr "" -"以关键字参数传递所有参数,不再支持位置参数。使用位置参数的代码(例如," -"`start_client(\"127.0.0.1:8080\", FlowerClient())`)必须为每个位置参数添加关" -"键字(例如,`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)。" - -#: ../../source/ref-changelog.md:560 +"made Flower 1.0 possible (in reverse [GitHub " +"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +msgstr "" +"在此,我们谨向所有促成 Flower 1.0 的贡献者致以**特别的谢意(按[GitHub " +"贡献者](https://github.com/adap/flower/graphs/contributors) 倒序排列):" + +#: ../../source/ref-changelog.md:618 +msgid "" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), " +"[@mrinaald](https://github.com/mrinaald), " +"[@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), " +"[@sancarlim](https://github.com/sancarlim), " +"[@gubertoli](https://github.com/gubertoli), " +"[@Vingt100](https://github.com/Vingt100), " +"[@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), " +"[@jafermarq](https://github.com/jafermarq), " +"[@sisco0](https://github.com/sisco0), " +"[@akhilmathurs](https://github.com/akhilmathurs), " +"[@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), " +"[@pedropgusmao](https://github.com/pedropgusmao), " +"[@tanertopal](https://github.com/tanertopal), " +"[@danieljanes](https://github.com/danieljanes)." +msgstr "" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), " +"[@mrinaald](https://github.com/mrinaald), " +"[@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), " +"[@sancarlim](https://github.com/sancarlim), " +"[@gubertoli](https://github.com/gubertoli), " +"[@Vingt100](https://github.com/Vingt100), " +"[@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), " +"[@jafermarq](https://github.com/jafermarq), " +"[@sisco0](https://github.com/sisco0), " +"[@akhilmathurs](https://github.com/akhilmathurs), " +"[@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), " +"[@pedropgusmao](https://github.com/pedropgusmao), " +"[@tanertopal](https://github.com/tanertopal), " +"[@danieljanes](https://github.com/danieljanes)." + +#: ../../source/ref-changelog.md:622 +msgid "" +"**All arguments must be passed as keyword arguments** " +"([#1338](https://github.com/adap/flower/pull/1338))" +msgstr "** 所有参数必须作为关键字参数传递** ([#1338](https://github.com/adap/flower/pull/1338))" + +#: ../../source/ref-changelog.md:624 +msgid "" +"Pass all arguments as keyword arguments, positional arguments are not " +"longer supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " +"for each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)." +msgstr "" +"以关键字参数传递所有参数,不再支持位置参数。使用位置参数的代码(例如,`start_client(\"127.0.0.1:8080\", " +"FlowerClient())`)必须为每个位置参数添加关键字(例如,`start_client(server_address=\"127.0.0.1:8080\"," +" client=FlowerClient())`)。" + +#: ../../source/ref-changelog.md:626 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` ([#1317](https://github.com/adap/flower/" -"pull/1317))" +"**and** `start_simulation` " +"([#1317](https://github.com/adap/flower/pull/1317))" msgstr "" "**在*** `start_server` ***和*** `start_simulation` 中引入配置对象*** " "`ServerConfig` ([#1317](https://github.com/adap/flower/pull/1317))" -#: ../../source/ref-changelog.md:562 +#: ../../source/ref-changelog.md:628 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": 600.0}" -"`, `start_server` and `start_simulation` now expect a configuration object " -"of type `flwr.server.ServerConfig`. `ServerConfig` takes the same arguments " -"that as the previous config dict, but it makes writing type-safe code easier " -"and the default parameters values more transparent." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " +"600.0}`, `start_server` and `start_simulation` now expect a configuration" +" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" +" arguments that as the previous config dict, but it makes writing type-" +"safe code easier and the default parameters values more transparent." msgstr "" -"并非配置字典`{\"num_rounds\": 3, \"round_timeout\": 600.0}`, `start_server`" -"和 `start_simulation`现在用一个类型为 `flwr.server.ServerConfig`的配置对象。" -"`ServerConfig`接收的参数与之前的 config dict 相同,但它使编写类型安全代码变得" -"更容易,默认参数值也更加透明。" +"并非配置字典`{\"num_rounds\": 3, \"round_timeout\": 600.0}`, `start_server`和 " +"`start_simulation`现在用一个类型为 " +"`flwr.server.ServerConfig`的配置对象。`ServerConfig`接收的参数与之前的 config dict " +"相同,但它使编写类型安全代码变得更容易,默认参数值也更加透明。" -#: ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:630 msgid "" -"**Rename built-in strategy parameters for clarity** ([#1334](https://github." -"com/adap/flower/pull/1334))" -msgstr "" -"**重新命名内置策略参数,使其更加清晰** ([#1334](https://github.com/adap/" -"flower/pull/1334))" +"**Rename built-in strategy parameters for clarity** " +"([#1334](https://github.com/adap/flower/pull/1334))" +msgstr "**重新命名内置策略参数,使其更加清晰** ([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:566 +#: ../../source/ref-changelog.md:632 msgid "" "The following built-in strategy parameters were renamed to improve " "readability and consistency with other API's:" msgstr "以下内置策略参数已重新命名,以提高可读性并与其他 API 保持一致:" -#: ../../source/ref-changelog.md:568 +#: ../../source/ref-changelog.md:634 msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "`fraction_eval` --> `fraction_evaluate`" -#: ../../source/ref-changelog.md:569 +#: ../../source/ref-changelog.md:635 msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "`min_eval_clients` --> `min_evaluate_clients`" -#: ../../source/ref-changelog.md:570 +#: ../../source/ref-changelog.md:636 msgid "`eval_fn` --> `evaluate_fn`" msgstr "`eval_fn` --> `evaluate_fn`" -#: ../../source/ref-changelog.md:572 +#: ../../source/ref-changelog.md:638 msgid "" -"**Update default arguments of built-in strategies** ([#1278](https://github." -"com/adap/flower/pull/1278))" -msgstr "" -"**更新内置策略的默认参数** ([#1278](https://github.com/adap/flower/" -"pull/1278))" +"**Update default arguments of built-in strategies** " +"([#1278](https://github.com/adap/flower/pull/1278))" +msgstr "**更新内置策略的默认参数** ([#1278](https://github.com/adap/flower/pull/1278))" -#: ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:640 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently available " -"clients for training and evaluation. Projects that relied on the previous " -"default values can get the previous behaviour by initializing the strategy " -"in the following way:" +"`fraction_evaluate=1.0`, which means they select *all* currently " +"available clients for training and evaluation. Projects that relied on " +"the previous default values can get the previous behaviour by " +"initializing the strategy in the following way:" msgstr "" -"所有内置策略现在都使用 \"fraction_fit=1.0 \"和 \"fraction_evaluate=1.0\",这" -"意味着它们会选择*所有*当前可用的客户端进行训练和评估。依赖以前默认值的项目可" -"以通过以下方式初始化策略,获得以前的行为:" +"所有内置策略现在都使用 \"fraction_fit=1.0 \"和 " +"\"fraction_evaluate=1.0\",这意味着它们会选择*所有*当前可用的客户端进行训练和评估。依赖以前默认值的项目可以通过以下方式初始化策略,获得以前的行为:" -#: ../../source/ref-changelog.md:576 +#: ../../source/ref-changelog.md:642 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" -#: ../../source/ref-changelog.md:578 +#: ../../source/ref-changelog.md:644 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` ([#1334](https://github." -"com/adap/flower/pull/1334))" +"**Add** `server_round` **to** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -"**添加*** `server_round` ***到*** `Strategy.evaluate` ([#1334](https://" -"github.com/adap/flower/pull/1334))" +"**添加*** `server_round` ***到*** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:580 +#: ../../source/ref-changelog.md:646 msgid "" -"The `Strategy` method `evaluate` now receives the current round of federated " -"learning/evaluation as the first parameter." -msgstr "" -"`Strategy`的`evaluate` 方法现在会接收当前一轮联邦学习/评估作为第一个参数。" +"The `Strategy` method `evaluate` now receives the current round of " +"federated learning/evaluation as the first parameter." +msgstr "`Strategy`的`evaluate` 方法现在会接收当前一轮联邦学习/评估作为第一个参数。" -#: ../../source/ref-changelog.md:582 +#: ../../source/ref-changelog.md:648 msgid "" "**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -17753,106 +19262,103 @@ msgstr "" "**将*** `server_round` **和*** `config` **参数添加到*** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:584 +#: ../../source/ref-changelog.md:650 msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), and " -"(3) a config dictionary (`config`)." +"(`server_round`), (2) the model parameters to evaluate (`parameters`), " +"and (3) a config dictionary (`config`)." msgstr "" -"传递给内置策略(如 `FedAvg`)的 `evaluate_fn` 现在需要三个参数:(1) 当前一轮" -"联邦学习/评估 (`server_round`),(2) 要评估的模型参数 (`parameters`),(3) 配置" -"字典 (`config`)。" +"传递给内置策略(如 `FedAvg`)的 `evaluate_fn` 现在需要三个参数:(1) 当前一轮联邦学习/评估 " +"(`server_round`),(2) 要评估的模型参数 (`parameters`),(3) 配置字典 (`config`)。" -#: ../../source/ref-changelog.md:586 +#: ../../source/ref-changelog.md:652 msgid "" -"**Rename** `rnd` **to** `server_round` ([#1321](https://github.com/adap/" -"flower/pull/1321))" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" msgstr "" -"**重新命名** `rnd` ** to** `server_round` ([#1321](https://github.com/adap/" -"flower/pull/1321))" +"**重新命名** `rnd` ** to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:588 +#: ../../source/ref-changelog.md:654 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. To " -"improve reaability and avoid confusion with *random*, this parameter has " -"been renamed from `rnd` to `server_round`." +"current round of federated learning/evaluation as their first parameter. " +"To improve reaability and avoid confusion with *random*, this parameter " +"has been renamed from `rnd` to `server_round`." msgstr "" -"几个 Flower 方法和函数(`evaluate_fn`、`configure_fit`、`aggregate_fit`、" -"`configure_evaluate`、`aggregate_evaluate`)的第一个参数是当前一轮的联邦学习/" -"评估。为提高可重复性并避免与 *random* 混淆,该参数已从 `rnd` 更名为 " -"`server_round`。" +"几个 Flower " +"方法和函数(`evaluate_fn`、`configure_fit`、`aggregate_fit`、`configure_evaluate`、`aggregate_evaluate`)的第一个参数是当前一轮的联邦学习/评估。为提高可重复性并避免与" +" *random* 混淆,该参数已从 `rnd` 更名为 `server_round`。" -#: ../../source/ref-changelog.md:590 +#: ../../source/ref-changelog.md:656 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` ([#1273](https://github.com/" -"adap/flower/pull/1273))" +"**Move** `flwr.dataset` **to** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" msgstr "" -"**移动*** `flwr.dataset` **到*** `flwr_baselines` ([#1273](https://github." -"com/adap/flower/pull/1273))" +"**移动*** `flwr.dataset` **到*** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" -#: ../../source/ref-changelog.md:592 -msgid "" -"The experimental package `flwr.dataset` was migrated to Flower Baselines." +#: ../../source/ref-changelog.md:658 +msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "实验软件包 `flwr.dataset` 已迁移至 Flower Baselines。" -#: ../../source/ref-changelog.md:594 +#: ../../source/ref-changelog.md:660 msgid "" -"**Remove experimental strategies** ([#1280](https://github.com/adap/flower/" -"pull/1280))" +"**Remove experimental strategies** " +"([#1280](https://github.com/adap/flower/pull/1280))" msgstr "**删除实验策略** ([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:596 +#: ../../source/ref-changelog.md:662 msgid "" "Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " "`FedFSv1`)." msgstr "移除未维护的试验性策略(`FastAndSlow`、`FedFSv0`、`FedFSv1`)。" -#: ../../source/ref-changelog.md:598 +#: ../../source/ref-changelog.md:664 msgid "" -"**Rename** `Weights` **to** `NDArrays` ([#1258](https://github.com/adap/" -"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"**重新命名** `Weights` **到** `NDArrays` ([#1258](https://github.com/adap/" -"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" +"**重新命名** `Weights` **到** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:600 +#: ../../source/ref-changelog.md:666 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." -msgstr "" -"flwr.common.Weights \"更名为 \"flwr.common.NDArrays\",以更好地反映该类型的含" -"义。" +msgstr "flwr.common.Weights \"更名为 \"flwr.common.NDArrays\",以更好地反映该类型的含义。" -#: ../../source/ref-changelog.md:602 +#: ../../source/ref-changelog.md:668 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** `start_server` " -"([#1258](https://github.com/adap/flower/pull/1258), [#1259](https://github." -"com/adap/flower/pull/1259))" +"**Remove antiquated** `force_final_distributed_eval` **from** " +"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"**从** `start_server` 中移除过时的** `force_final_distributed_eval` ([#1258]" -"(https://github.com/adap/flower/pull/1258), [#1259](https://github.com/adap/" -"flower/pull/1259))" +"**从** `start_server` 中移除过时的** `force_final_distributed_eval` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:604 +#: ../../source/ref-changelog.md:670 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been a " -"historic artefact, in this release it is finally gone for good." +"The `start_server` parameter `force_final_distributed_eval` has long been" +" a historic artefact, in this release it is finally gone for good." msgstr "" -"start_server \"参数 \"force_final_distributed_eval \"长期以来一直是个历史遗留" -"问题,在此版本中终于永远消失了。" +"start_server \"参数 \"force_final_distributed_eval " +"\"长期以来一直是个历史遗留问题,在此版本中终于永远消失了。" -#: ../../source/ref-changelog.md:606 +#: ../../source/ref-changelog.md:672 msgid "" -"**Make** `get_parameters` **configurable** ([#1242](https://github.com/adap/" -"flower/pull/1242))" +"**Make** `get_parameters` **configurable** " +"([#1242](https://github.com/adap/flower/pull/1242))" msgstr "" -"**使** `get_parameters` **可配置** ([#1242](https://github.com/adap/flower/" -"pull/1242))" +"**使** `get_parameters` **可配置** " +"([#1242](https://github.com/adap/flower/pull/1242))" -#: ../../source/ref-changelog.md:608 +#: ../../source/ref-changelog.md:674 msgid "" "The `get_parameters` method now accepts a configuration dictionary, just " "like `get_properties`, `fit`, and `evaluate`." @@ -17860,7 +19366,7 @@ msgstr "" "现在,\"get_parameters \"方法与 \"get_properties\"、\"fit \"和 \"evaluate " "\"一样,都接受配置字典。" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:676 msgid "" "**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " "**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" @@ -17868,119 +19374,115 @@ msgstr "" "**用新的** `config` 参数** 替换** `num_rounds` ** in** `start_simulation` ** " "([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:678 msgid "" "The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the consistency " -"between `start_simulation` and `start_server` and makes transitioning " -"between the two easier." +"`config` instead of the `num_rounds` integer. This improves the " +"consistency between `start_simulation` and `start_server` and makes " +"transitioning between the two easier." msgstr "" -"现在,`start_simulation`(开始模拟)` 函数接受配置字典 `config` 而不是 " -"`num_rounds` 整数。这改进了 `start_simulation` 和 `start_server` 之间的一致" -"性,并使两者之间的转换更容易。" +"现在,`start_simulation`(开始模拟)` 函数接受配置字典 `config` 而不是 `num_rounds` 整数。这改进了 " +"`start_simulation` 和 `start_server` 之间的一致性,并使两者之间的转换更容易。" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:682 msgid "" -"**Support Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" -msgstr "" -"** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" +msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:618 +#: ../../source/ref-changelog.md:684 msgid "" -"The previous Flower release introduced experimental support for Python 3.10, " -"this release declares Python 3.10 support as stable." -msgstr "" -"上一个 Flower 版本引入了对 Python 3.10 的实验支持,而本版本则宣布对 Python " -"3.10 的支持为稳定支持。" +"The previous Flower release introduced experimental support for Python " +"3.10, this release declares Python 3.10 support as stable." +msgstr "上一个 Flower 版本引入了对 Python 3.10 的实验支持,而本版本则宣布对 Python 3.10 的支持为稳定支持。" -#: ../../source/ref-changelog.md:620 +#: ../../source/ref-changelog.md:686 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** ([#1260]" -"(https://github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/" -"flower/pull/1277))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** " +"([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" msgstr "" -"**使所有** `Client` **和** `NumPyClient` **方法成为可选** ([#1260](https://" -"github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/flower/" -"pull/1277))" +"**使所有** `Client` **和** `NumPyClient` **方法成为可选** " +"([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:688 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that " -"implement, for example, only `fit`, but no other method. No need to " +"`fit`, and `evaluate` are all optional. This enables writing clients that" +" implement, for example, only `fit`, but no other method. No need to " "implement `evaluate` when using centralized evaluation!" msgstr "" "`Client`/`NumPyClient`的 \"get_properties\"、\"get_parameters\"、\"fit \"和 " -"\"evaluate \"方法都是可选的。这样就可以编写只实现 `fit` 而不实现其他方法的客" -"户端。使用集中评估时,无需实现 `evaluate`!" +"\"evaluate \"方法都是可选的。这样就可以编写只实现 `fit` 而不实现其他方法的客户端。使用集中评估时,无需实现 " +"`evaluate`!" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:690 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` ([#1281]" -"(https://github.com/adap/flower/pull/1281))" +"**Enable passing a** `Server` **instance to** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -"**启用向** `start_simulation` 传递** `Server` 实例 ([#1281](https://github." -"com/adap/flower/pull/1281))" +"**启用向** `start_simulation` 传递** `Server` 实例 " +"([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:692 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server` " -"instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the " -"Virtual Client Engine." +"Similar to `start_server`, `start_simulation` now accepts a full `Server`" +" instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the" +" Virtual Client Engine." msgstr "" -"与 `start_server` 类似,`start_simulation` 现在也接受一个完整的 `Server` 实" -"例。这使得用户可以对实验的执行进行大量自定义,并为使用虚拟客户端引擎运行异步 " -"FL 等打开了大门。" +"与 `start_server` 类似,`start_simulation` 现在也接受一个完整的 `Server` " +"实例。这使得用户可以对实验的执行进行大量自定义,并为使用虚拟客户端引擎运行异步 FL 等打开了大门。" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:694 msgid "" -"**Update code examples** ([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), [#1282](https://github." -"com/adap/flower/pull/1282))" +"**Update code examples** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" msgstr "" -"**更新代码示例** ([#1291](https://github.com/adap/flower/pull/1291), [#1286]" -"(https://github.com/adap/flower/pull/1286), [#1282](https://github.com/adap/" -"flower/pull/1282))" +"**更新代码示例** ([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:696 msgid "" -"Many code examples received small or even large maintenance updates, among " -"them are" +"Many code examples received small or even large maintenance updates, " +"among them are" msgstr "许多代码示例都进行了小规模甚至大规模的维护更新,其中包括" -#: ../../source/ref-changelog.md:632 +#: ../../source/ref-changelog.md:698 msgid "`scikit-learn`" msgstr "`scikit-learn`" -#: ../../source/ref-changelog.md:633 +#: ../../source/ref-changelog.md:699 msgid "`simulation_pytorch`" msgstr "`simulation_pytorch`" -#: ../../source/ref-changelog.md:634 +#: ../../source/ref-changelog.md:700 msgid "`quickstart_pytorch`" msgstr "`quickstart_pytorch`" -#: ../../source/ref-changelog.md:635 +#: ../../source/ref-changelog.md:701 msgid "`quickstart_simulation`" msgstr "`quickstart_simulation`" -#: ../../source/ref-changelog.md:636 +#: ../../source/ref-changelog.md:702 msgid "`quickstart_tensorflow`" msgstr "`quickstart_tensorflow`" -#: ../../source/ref-changelog.md:637 +#: ../../source/ref-changelog.md:703 msgid "`advanced_tensorflow`" msgstr "`advanced_tensorflow`" -#: ../../source/ref-changelog.md:639 +#: ../../source/ref-changelog.md:705 msgid "" -"**Remove the obsolete simulation example** ([#1328](https://github.com/adap/" -"flower/pull/1328))" -msgstr "" -"**删除过时的模拟示例** ([#1328](https://github.com/adap/flower/pull/1328))" +"**Remove the obsolete simulation example** " +"([#1328](https://github.com/adap/flower/pull/1328))" +msgstr "**删除过时的模拟示例** ([#1328](https://github.com/adap/flower/pull/1328))" -#: ../../source/ref-changelog.md:641 +#: ../../source/ref-changelog.md:707 msgid "" "Removes the obsolete `simulation` example and renames " "`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " @@ -17989,589 +19491,579 @@ msgstr "" "删除过时的 \"simulation \"示例,并将 \"quickstart_simulation \"重命名为 " "\"simulation_tensorflow\",使其与 \"simulation_pytorch \"的命名一致" -#: ../../source/ref-changelog.md:643 -msgid "" -"**Update documentation** ([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), [#1251](https://github." -"com/adap/flower/pull/1251), [#1257](https://github.com/adap/flower/" -"pull/1257), [#1267](https://github.com/adap/flower/pull/1267), [#1268]" -"(https://github.com/adap/flower/pull/1268), [#1300](https://github.com/adap/" -"flower/pull/1300), [#1304](https://github.com/adap/flower/pull/1304), [#1305]" -"(https://github.com/adap/flower/pull/1305), [#1307](https://github.com/adap/" -"flower/pull/1307))" -msgstr "" -"**更新文档** ([#1223](https://github.com/adap/flower/pull/1223), [#1209]" -"(https://github.com/adap/flower/pull/1209), [#1251](https://github.com/adap/" -"flower/pull/1251), [#1257](https://github.com/adap/flower/pull/1257), [#1267]" -"(https://github.com/adap/flower/pull/1267), [#1268](https://github.com/adap/" -"flower/pull/1268), [#1300](https://github.com/adap/flower/pull/1300), [#1304]" -"(https://github.com/adap/flower/pull/1304), [#1305](https://github.com/adap/" -"flower/pull/1305), [#1307](https://github.com/adap/flower/pull/1307))" - -#: ../../source/ref-changelog.md:645 +#: ../../source/ref-changelog.md:709 +msgid "" +"**Update documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" +msgstr "" +"**更新文档** ([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" + +#: ../../source/ref-changelog.md:711 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the `flwr." -"common` module in the API reference, includes support for markdown-based " -"documentation, migrates the changelog from `.rst` to `.md`, and fixes a " -"number of smaller details!" -msgstr "" -"其中一个实质性的文档更新修复了多个较小的渲染问题,使标题更加简洁以改善导航," -"删除了一个已废弃的库,更新了文档依赖关系,在 API 参考中包含了 `flwr.common` " -"模块,包含了对基于 markdown 的文档的支持,将更新日志从 `.rst` 移植到了 `." -"md`,并修复了一些较小的细节!" - -#: ../../source/ref-changelog.md:647 ../../source/ref-changelog.md:702 -#: ../../source/ref-changelog.md:771 ../../source/ref-changelog.md:810 +"deprecated library, updates documentation dependencies, includes the " +"`flwr.common` module in the API reference, includes support for markdown-" +"based documentation, migrates the changelog from `.rst` to `.md`, and " +"fixes a number of smaller details!" +msgstr "" +"其中一个实质性的文档更新修复了多个较小的渲染问题,使标题更加简洁以改善导航,删除了一个已废弃的库,更新了文档依赖关系,在 API 参考中包含了 " +"`flwr.common` 模块,包含了对基于 markdown 的文档的支持,将更新日志从 `.rst` 移植到了 " +"`.md`,并修复了一些较小的细节!" + +#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 +#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 msgid "**Minor updates**" msgstr "**小规模更新**" -#: ../../source/ref-changelog.md:649 +#: ../../source/ref-changelog.md:715 msgid "" -"Add round number to fit and evaluate log messages ([#1266](https://github." -"com/adap/flower/pull/1266))" -msgstr "" -"添加四舍五入数字,以适应和评估日志信息([#1266](https://github.com/adap/" -"flower/pull/1266))" +"Add round number to fit and evaluate log messages " +"([#1266](https://github.com/adap/flower/pull/1266))" +msgstr "添加四舍五入数字,以适应和评估日志信息([#1266](https://github.com/adap/flower/pull/1266))" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:716 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example ([#847]" -"(https://github.com/adap/flower/pull/847))" +"Add secure gRPC connection to the `advanced_tensorflow` code example " +"([#847](https://github.com/adap/flower/pull/847))" msgstr "" -"为 `advanced_tensorflow` 代码示例添加安全 gRPC 连接 ([#847](https://github." -"com/adap/flower/pull/847))" +"为 `advanced_tensorflow` 代码示例添加安全 gRPC 连接 " +"([#847](https://github.com/adap/flower/pull/847))" -#: ../../source/ref-changelog.md:651 +#: ../../source/ref-changelog.md:717 msgid "" -"Update developer tooling ([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), [#1301](https://github." -"com/adap/flower/pull/1301), [#1310](https://github.com/adap/flower/" -"pull/1310))" +"Update developer tooling " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" msgstr "" -"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), [#1276]" -"(https://github.com/adap/flower/pull/1276), [#1301](https://github.com/adap/" -"flower/pull/1301), [#1310](https://github.com/adap/flower/pull/1310)" +"更新开发人员工具([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310)" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:718 msgid "" -"Rename ProtoBuf messages to improve consistency ([#1214](https://github.com/" -"adap/flower/pull/1214), [#1258](https://github.com/adap/flower/pull/1258), " +"Rename ProtoBuf messages to improve consistency " +"([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -"重命名 ProtoBuf 消息以提高一致性([#1214](https://github.com/adap/flower/" -"pull/1214), [#1258](https://github.com/adap/flower/pull/1258), [#1259]" -"(https://github.com/adap/flower/pull/1259)" +"重命名 ProtoBuf 消息以提高一致性([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259)" -#: ../../source/ref-changelog.md:654 +#: ../../source/ref-changelog.md:720 msgid "v0.19.0 (2022-05-18)" msgstr "v0.19.0 (2022-05-18)" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:724 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** ([#919](https://" -"github.com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" -"pull/1127), [#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" msgstr "" -"**Flower Baselines(预览): FedOpt、FedBN、FedAvgM** ([#919](https://github." -"com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" -"pull/1127), [#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines(预览): FedOpt、FedBN、FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:726 #, fuzzy msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how to " -"use [Flower Baselines](https://flower.ai/docs/using-baselines.html). With " -"this first preview release we're also inviting the community to [contribute " -"their own baselines](https://flower.ai/docs/baselines/how-to-contribute-" -"baselines.html)." -msgstr "" -"Flower Baselines 的第一个预览版已经发布!我们通过实现 FedOpt(FedYogi、" -"FedAdam、FedAdagrad)、FedBN 和 FedAvgM 来启动 Flower Baselines。请查阅文档了" -"解如何使用 [Flower Baselines](https://flower.ai/docs/using-baselines.html)。" -"在首次发布预览版时,我们还邀请社区成员[贡献自己的Baselines](https://flower." -"ai/docs/contributing-baselines.html)。" +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " +"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " +"With this first preview release we're also inviting the community to " +"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" +"contribute-baselines.html)." +msgstr "" +"Flower Baselines 的第一个预览版已经发布!我们通过实现 " +"FedOpt(FedYogi、FedAdam、FedAdagrad)、FedBN 和 FedAvgM 来启动 Flower " +"Baselines。请查阅文档了解如何使用 [Flower Baselines](https://flower.ai/docs/using-" +"baselines.html)。在首次发布预览版时,我们还邀请社区成员[贡献自己的Baselines](https://flower.ai/docs" +"/contributing-baselines.html)。" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:728 msgid "" -"**C++ client SDK (preview) and code example** ([#1111](https://github.com/" -"adap/flower/pull/1111))" -msgstr "" -"**C++客户端SDK(预览版)和代码示例**([#1111](https://github.com/adap/flower/" -"pull/1111))" +"**C++ client SDK (preview) and code example** " +"([#1111](https://github.com/adap/flower/pull/1111))" +msgstr "**C++客户端SDK(预览版)和代码示例**([#1111](https://github.com/adap/flower/pull/1111))" -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:730 msgid "" -"Preview support for Flower clients written in C++. The C++ preview includes " -"a Flower client SDK and a quickstart code example that demonstrates a simple " -"C++ client using the SDK." +"Preview support for Flower clients written in C++. The C++ preview " +"includes a Flower client SDK and a quickstart code example that " +"demonstrates a simple C++ client using the SDK." msgstr "" -"预览版支持用 C++ 编写的 Flower 客户端。C++ 预览版包括一个 Flower 客户端 SDK " -"和一个快速入门代码示例,使用 SDK 演示了一个简单的 C++ 客户端。" +"预览版支持用 C++ 编写的 Flower 客户端。C++ 预览版包括一个 Flower 客户端 SDK 和一个快速入门代码示例,使用 SDK " +"演示了一个简单的 C++ 客户端。" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:732 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** ([#1135]" -"(https://github.com/adap/flower/pull/1135))" +"**Add experimental support for Python 3.10 and Python 3.11** " +"([#1135](https://github.com/adap/flower/pull/1135))" msgstr "" -"** 增加对 Python 3.10 和 Python 3.11 的实验支持** ([#1135](https://github." -"com/adap/flower/pull/1135))" +"** 增加对 Python 3.10 和 Python 3.11 的实验支持** " +"([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:734 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due to " -"be released in October. This Flower release adds experimental support for " -"both Python versions." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due" +" to be released in October. This Flower release adds experimental support" +" for both Python versions." msgstr "" -"Python 3.10 是 Python 的最新稳定版本,Python 3.11 将于 10 月份发布。Flower 版" -"本增加了对这两个 Python 版本的实验支持。" +"Python 3.10 是 Python 的最新稳定版本,Python 3.11 将于 10 月份发布。Flower 版本增加了对这两个 " +"Python 版本的实验支持。" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:736 msgid "" -"**Aggregate custom metrics through user-provided functions** ([#1144]" -"(https://github.com/adap/flower/pull/1144))" -msgstr "" -"**通过用户提供的函数聚合自定义指标**([#1144](https://github.com/adap/flower/" -"pull/1144))" +"**Aggregate custom metrics through user-provided functions** " +"([#1144](https://github.com/adap/flower/pull/1144))" +msgstr "**通过用户提供的函数聚合自定义指标**([#1144](https://github.com/adap/flower/pull/1144))" -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:738 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to " -"customize the strategy. Built-in strategies support two new arguments, " +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" +" customize the strategy. Built-in strategies support two new arguments, " "`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " "allow passing custom metric aggregation functions." msgstr "" -"现在无需定制策略即可聚合自定义度量(如`准确度`)。内置策略支持两个新参数:" -"`fit_metrics_aggregation_fn` 和`evaluate_metrics_aggregation_fn`,允许传递自" -"定义度量聚合函数。" +"现在无需定制策略即可聚合自定义度量(如`准确度`)。内置策略支持两个新参数:`fit_metrics_aggregation_fn` " +"和`evaluate_metrics_aggregation_fn`,允许传递自定义度量聚合函数。" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:740 msgid "" -"**User-configurable round timeout** ([#1162](https://github.com/adap/flower/" -"pull/1162))" -msgstr "" -"**用户可配置的回合超时**([#1162](https://github.com/adap/flower/pull/1162))" +"**User-configurable round timeout** " +"([#1162](https://github.com/adap/flower/pull/1162))" +msgstr "**用户可配置的回合超时**([#1162](https://github.com/adap/flower/pull/1162))" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:742 msgid "" "A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary contains a " -"`round_timeout` key (with a `float` value in seconds), the server will wait " -"*at least* `round_timeout` seconds before it closes the connection." +"`start_server` and `start_simulation`. If the `config` dictionary " +"contains a `round_timeout` key (with a `float` value in seconds), the " +"server will wait *at least* `round_timeout` seconds before it closes the " +"connection." msgstr "" -"新的配置值允许为 `start_server` 和 `start_simulation` 设置回合超时。如果 " -"`config` 字典中包含一个 `round_timeout` 键(以秒为单位的 `float`值),服务器" -"将至少等待 ** `round_timeout` 秒后才关闭连接。" +"新的配置值允许为 `start_server` 和 `start_simulation` 设置回合超时。如果 `config` 字典中包含一个 " +"`round_timeout` 键(以秒为单位的 `float`值),服务器将至少等待 ** `round_timeout` 秒后才关闭连接。" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:744 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used at " -"the same time in all built-in strategies** ([#1091](https://github.com/adap/" -"flower/pull/1091))" +"**Enable both federated evaluation and centralized evaluation to be used " +"at the same time in all built-in strategies** " +"([#1091](https://github.com/adap/flower/pull/1091))" msgstr "" -"**允许在所有内置策略中同时使用联邦评价和集中评估** ([#1091](https://github." -"com/adap/flower/pull/1091))" +"**允许在所有内置策略中同时使用联邦评价和集中评估** " +"([#1091](https://github.com/adap/flower/pull/1091))" -#: ../../source/ref-changelog.md:680 +#: ../../source/ref-changelog.md:746 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., client-" -"side) and centralized evaluation (i.e., server-side) in the same round. " -"Federated evaluation can be disabled by setting `fraction_eval` to `0.0`." +"Built-in strategies can now perform both federated evaluation (i.e., " +"client-side) and centralized evaluation (i.e., server-side) in the same " +"round. Federated evaluation can be disabled by setting `fraction_eval` to" +" `0.0`." msgstr "" -"内置策略现在可以在同一轮中同时执行联邦评估(即客户端)和集中评估(即服务器" -"端)。可以通过将 `fraction_eval` 设置为 `0.0`来禁用联邦评估。" +"内置策略现在可以在同一轮中同时执行联邦评估(即客户端)和集中评估(即服务器端)。可以通过将 `fraction_eval` 设置为 " +"`0.0`来禁用联邦评估。" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:748 msgid "" -"**Two new Jupyter Notebook tutorials** ([#1141](https://github.com/adap/" -"flower/pull/1141))" +"**Two new Jupyter Notebook tutorials** " +"([#1141](https://github.com/adap/flower/pull/1141))" msgstr "" -"**两本新的 Jupyter Notebook 教程** ([#1141](https://github.com/adap/flower/" -"pull/1141))" +"**两本新的 Jupyter Notebook 教程** " +"([#1141](https://github.com/adap/flower/pull/1141))" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:750 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain basic " -"and intermediate Flower features:" -msgstr "" -"两本 Jupyter Notebook 教程(与 Google Colab 兼容)介绍了 Flower 的基本和中级" -"功能:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " +"basic and intermediate Flower features:" +msgstr "两本 Jupyter Notebook 教程(与 Google Colab 兼容)介绍了 Flower 的基本和中级功能:" -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:752 msgid "" -"*An Introduction to Federated Learning*: [Open in Colab](https://colab." -"research.google.com/github/adap/flower/blob/main/tutorials/Flower-1-Intro-to-" -"FL-PyTorch.ipynb)" +"*An Introduction to Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" msgstr "" -"*联邦学习简介*: [在 Colab 中打开](https://colab.research.google.com/github/" -"adap/flower/blob/main/tutorials/Flower-1-Intro-to-FL-PyTorch.ipynb)" +"*联邦学习简介*: [在 Colab " +"中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:754 msgid "" -"*Using Strategies in Federated Learning*: [Open in Colab](https://colab." -"research.google.com/github/adap/flower/blob/main/tutorials/Flower-2-" -"Strategies-in-FL-PyTorch.ipynb)" +"*Using Strategies in Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" msgstr "" -"*在联邦学习中使用策略*: [在 Colab 中打开](https://colab.research.google.com/" -"github/adap/flower/blob/main/tutorials/Flower-2-Strategies-in-FL-PyTorch." -"ipynb)" +"*在联邦学习中使用策略*: [在 Colab " +"中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:756 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** ([#1076]" -"(https://github.com/adap/flower/pull/1076))" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " +"([#1076](https://github.com/adap/flower/pull/1076))" msgstr "" -"**新的 FedAvgM 策略(带服务器动量的联邦平均)** ([#1076](https://github.com/" -"adap/flower/pull/1076))" +"**新的 FedAvgM 策略(带服务器动量的联邦平均)** " +"([#1076](https://github.com/adap/flower/pull/1076))" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:758 msgid "" "The new `FedAvgM` strategy implements Federated Averaging with Server " "Momentum \\[Hsu et al., 2019\\]." msgstr "新的 \"FedAvgM \"策略实现了带服务器动量的联邦平均[Hsu et al., 2019\\]." -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:760 msgid "" -"**New advanced PyTorch code example** ([#1007](https://github.com/adap/" -"flower/pull/1007))" -msgstr "" -"**新的 PyTorch 高级代码示例** ([#1007](https://github.com/adap/flower/" -"pull/1007))" +"**New advanced PyTorch code example** " +"([#1007](https://github.com/adap/flower/pull/1007))" +msgstr "**新的 PyTorch 高级代码示例** ([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:762 msgid "" "A new code example (`advanced_pytorch`) demonstrates advanced Flower " "concepts with PyTorch." msgstr "新代码示例 (`advanced_pytorch`) 演示了 PyTorch 的高级 Flower 概念。" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:764 msgid "" -"**New JAX code example** ([#906](https://github.com/adap/flower/pull/906), " +"**New JAX code example** " +"([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" "**新的 JAX 代码示例**([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143)" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:766 msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." -msgstr "" -"新代码示例(`jax_from_centralized_to_federated`)展示了使用 JAX 和 Flower 的" -"联邦学习。" +msgstr "新代码示例(`jax_from_centralized_to_federated`)展示了使用 JAX 和 Flower 的联邦学习。" -#: ../../source/ref-changelog.md:704 +#: ../../source/ref-changelog.md:770 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -"新增选项,用于在 \"start_simulation\"(开始模拟)中已初始化 Ray 的情况下保持 " -"Ray 运行([#1177](https://github.com/adap/flower/pull/1177))" +"新增选项,用于在 \"start_simulation\"(开始模拟)中已初始化 Ray 的情况下保持 Ray " +"运行([#1177](https://github.com/adap/flower/pull/1177))" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:771 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -"添加对自定义 \"客户端管理器 \"作为 \"start_simulation \"参数的支持([#1171]" -"(https://github.com/adap/flower/pull/1171))" +"添加对自定义 \"客户端管理器 \"作为 \"start_simulation " +"\"参数的支持([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:706 +#: ../../source/ref-changelog.md:772 msgid "" -"New documentation for [implementing strategies](https://flower.ai/docs/" -"framework/how-to-implement-strategies.html) ([#1097](https://github.com/adap/" -"flower/pull/1097), [#1175](https://github.com/adap/flower/pull/1175))" +"New documentation for [implementing " +"strategies](https://flower.ai/docs/framework/how-to-implement-" +"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -"[实施战略](https://flower.ai/docs/framework/how-to-implement-strategies." -"html) 的新文件([#1097](https://github.com/adap/flower/pull/1097), [#1175]" -"(https://github.com/adap/flower/pull/1175)" +"[实施战略](https://flower.ai/docs/framework/how-to-implement-strategies.html)" +" 的新文件([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175)" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:773 msgid "" -"New mobile-friendly documentation theme ([#1174](https://github.com/adap/" -"flower/pull/1174))" -msgstr "" -"新的移动友好型文档主题 ([#1174](https://github.com/adap/flower/pull/1174))" +"New mobile-friendly documentation theme " +"([#1174](https://github.com/adap/flower/pull/1174))" +msgstr "新的移动友好型文档主题 ([#1174](https://github.com/adap/flower/pull/1174))" -#: ../../source/ref-changelog.md:708 +#: ../../source/ref-changelog.md:774 msgid "" "Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) ([#1205](https://github.com/adap/" -"flower/pull/1205))" +"compatible releases (`>=1.9.2,<1.12.0`) " +"([#1205](https://github.com/adap/flower/pull/1205))" msgstr "" "限制(可选)`ray`依赖的版本范围,使其仅包含兼容版本(`>=1.9.2,<1.12.0`) " "([#1205](https://github.com/adap/flower/pull/1205))" -#: ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:778 msgid "" -"**Remove deprecated support for Python 3.6** ([#871](https://github.com/adap/" -"flower/pull/871))" -msgstr "" -"**删除对 Python 3.6 的过时支持** ([#871](https://github.com/adap/flower/" -"pull/871))" +"**Remove deprecated support for Python 3.6** " +"([#871](https://github.com/adap/flower/pull/871))" +msgstr "**删除对 Python 3.6 的过时支持** ([#871](https://github.com/adap/flower/pull/871))" -#: ../../source/ref-changelog.md:713 +#: ../../source/ref-changelog.md:779 msgid "" -"**Remove deprecated KerasClient** ([#857](https://github.com/adap/flower/" -"pull/857))" -msgstr "" -"**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" +"**Remove deprecated KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" +msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:714 +#: ../../source/ref-changelog.md:780 msgid "" -"**Remove deprecated no-op extra installs** ([#973](https://github.com/adap/" -"flower/pull/973))" -msgstr "" -"**移除过时的不操作额外安装** ([#973](https://github.com/adap/flower/" -"pull/973))" +"**Remove deprecated no-op extra installs** " +"([#973](https://github.com/adap/flower/pull/973))" +msgstr "**移除过时的不操作额外安装** ([#973](https://github.com/adap/flower/pull/973))" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:781 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" msgstr "" -"**从** `FitRes` **和** `EvaluateRes` 中移除已废弃的 proto 字段 ([#869]" -"(https://github.com/adap/flower/pull/869))" +"**从** `FitRes` **和** `EvaluateRes` 中移除已废弃的 proto 字段 " +"([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:782 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** ([#1107]" -"(https://github.com/adap/flower/pull/1107))" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " +"([#1107](https://github.com/adap/flower/pull/1107))" msgstr "" -"**移除过时的 QffedAvg 策略(由 QFedAvg 取代)** ([#1107](https://github.com/" -"adap/flower/pull/1107))" +"**移除过时的 QffedAvg 策略(由 QFedAvg 取代)** " +"([#1107](https://github.com/adap/flower/pull/1107))" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:783 msgid "" -"**Remove deprecated DefaultStrategy strategy** ([#1142](https://github.com/" -"adap/flower/pull/1142))" +"**Remove deprecated DefaultStrategy strategy** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"**删除过时的 DefaultStrategy 策略** ([#1142](https://github.com/adap/flower/" -"pull/1142))" +"**删除过时的 DefaultStrategy 策略** " +"([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:784 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** ([#1142]" -"(https://github.com/adap/flower/pull/1142))" +"**Remove deprecated support for eval_fn accuracy return value** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"**删除已过时的对 eval_fn 返回值准确性的支持** ([#1142](https://github.com/" -"adap/flower/pull/1142))" +"**删除已过时的对 eval_fn 返回值准确性的支持** " +"([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:719 +#: ../../source/ref-changelog.md:785 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -"**移除对以 NumPy ndarrays 传递初始参数的过时支持** ([#1142](https://github." -"com/adap/flower/pull/1142))" +"**移除对以 NumPy ndarrays 传递初始参数的过时支持** " +"([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:721 +#: ../../source/ref-changelog.md:787 msgid "v0.18.0 (2022-02-28)" msgstr "v0.18.0 (2022-02-28)" -#: ../../source/ref-changelog.md:725 +#: ../../source/ref-changelog.md:791 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), [#872]" -"(https://github.com/adap/flower/pull/872), [#833](https://github.com/adap/" -"flower/pull/833), [#1036](https://github.com/adap/flower/pull/1036))" +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -"**改进了虚拟客户端引擎与 Jupyter Notebook / Google Colab 的兼容性** ([#866]" -"(https://github.com/adap/flower/pull/866), [#872](https://github.com/adap/" -"flower/pull/872), [#833](https://github.com/adap/flower/pull/833), [#1036]" -"(https://github.com/adap/flower/pull/1036))" +"**改进了虚拟客户端引擎与 Jupyter Notebook / Google Colab 的兼容性** " +"([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" -#: ../../source/ref-changelog.md:727 +#: ../../source/ref-changelog.md:793 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) now " -"work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"Simulations (using the Virtual Client Engine through `start_simulation`) " +"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " "installing Flower with the `simulation` extra (`pip install " "flwr[simulation]`)." msgstr "" -"通过 `start_simulation` 在 Jupyter 笔记本(包括 Google Colab)上安装 Flower " -"并附加 `simulation` (`pip install flwr[simulation]`)后,模拟(通过 " -"`start_simulation` 使用虚拟客户端引擎)现在可以更流畅地运行。" +"通过 `start_simulation` 在 Jupyter 笔记本(包括 Google Colab)上安装 Flower 并附加 " +"`simulation` (`pip install flwr[simulation]`)后,模拟(通过 `start_simulation` " +"使用虚拟客户端引擎)现在可以更流畅地运行。" -#: ../../source/ref-changelog.md:729 +#: ../../source/ref-changelog.md:795 msgid "" -"**New Jupyter Notebook code example** ([#833](https://github.com/adap/flower/" -"pull/833))" +"**New Jupyter Notebook code example** " +"([#833](https://github.com/adap/flower/pull/833))" msgstr "" -"**新的 Jupyter Notebook 代码示例** ([#833](https://github.com/adap/flower/" -"pull/833))" +"**新的 Jupyter Notebook 代码示例** " +"([#833](https://github.com/adap/flower/pull/833))" -#: ../../source/ref-changelog.md:731 +#: ../../source/ref-changelog.md:797 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower simulations " -"using the Virtual Client Engine through Jupyter Notebook (incl. Google " -"Colab)." +"A new code example (`quickstart_simulation`) demonstrates Flower " +"simulations using the Virtual Client Engine through Jupyter Notebook " +"(incl. Google Colab)." msgstr "" "新代码示例(`quickstart_simulation`)通过 Jupyter Notebook(包括 Google " "Colab)演示了使用虚拟客户端引擎进行 Flower 模拟。" -#: ../../source/ref-changelog.md:733 +#: ../../source/ref-changelog.md:799 msgid "" -"**Client properties (feature preview)** ([#795](https://github.com/adap/" -"flower/pull/795))" -msgstr "" -"**客户端属性(功能预览)** ([#795](https://github.com/adap/flower/pull/795))" +"**Client properties (feature preview)** " +"([#795](https://github.com/adap/flower/pull/795))" +msgstr "**客户端属性(功能预览)** ([#795](https://github.com/adap/flower/pull/795))" -#: ../../source/ref-changelog.md:735 +#: ../../source/ref-changelog.md:801 msgid "" -"Clients can implement a new method `get_properties` to enable server-side " -"strategies to query client properties." -msgstr "" -"客户端可以实现一个新方法 `get_properties`,以启用服务器端策略来查询客户端属" -"性。" +"Clients can implement a new method `get_properties` to enable server-side" +" strategies to query client properties." +msgstr "客户端可以实现一个新方法 `get_properties`,以启用服务器端策略来查询客户端属性。" -#: ../../source/ref-changelog.md:737 +#: ../../source/ref-changelog.md:803 msgid "" -"**Experimental Android support with TFLite** ([#865](https://github.com/adap/" -"flower/pull/865))" -msgstr "" -"** 使用 TFLite 实验性支持安卓系统** ([#865](https://github.com/adap/flower/" -"pull/865))" +"**Experimental Android support with TFLite** " +"([#865](https://github.com/adap/flower/pull/865))" +msgstr "** 使用 TFLite 实验性支持安卓系统** ([#865](https://github.com/adap/flower/pull/865))" -#: ../../source/ref-changelog.md:739 +#: ../../source/ref-changelog.md:805 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has become a " -"lot easier." +"client platforms and with this release, using Flower on Android has " +"become a lot easier." msgstr "" -"`main`终于支持 Android 了!Flower 的设计与客户端和框架无关。我们可以集成任意" -"客户端平台,有了这个版本,在安卓系统上使用 Flower 就变得更容易了。" +"`main`终于支持 Android 了!Flower 的设计与客户端和框架无关。我们可以集成任意客户端平台,有了这个版本,在安卓系统上使用 " +"Flower 就变得更容易了。" -#: ../../source/ref-changelog.md:741 +#: ../../source/ref-changelog.md:807 msgid "" -"The example uses TFLite on the client side, along with a new `FedAvgAndroid` " -"strategy. The Android client and `FedAvgAndroid` are still experimental, but " -"they are a first step towards a fully-fledged Android SDK and a unified " -"`FedAvg` implementation that integrated the new functionality from " -"`FedAvgAndroid`." +"The example uses TFLite on the client side, along with a new " +"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " +"still experimental, but they are a first step towards a fully-fledged " +"Android SDK and a unified `FedAvg` implementation that integrated the new" +" functionality from `FedAvgAndroid`." msgstr "" "该示例在客户端使用了 TFLite 以及新的 `FedAvgAndroid`策略。Android 客户端和 " -"`FedAvgAndroid`仍处于试验阶段,但这是向成熟的 Android SDK 和集成了 " -"`FedAvgAndroid`新功能的统一 `FedAvg`实现迈出的第一步。" +"`FedAvgAndroid`仍处于试验阶段,但这是向成熟的 Android SDK 和集成了 `FedAvgAndroid`新功能的统一 " +"`FedAvg`实现迈出的第一步。" -#: ../../source/ref-changelog.md:743 +#: ../../source/ref-changelog.md:809 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default keepalive " -"time** ([#1069](https://github.com/adap/flower/pull/1069))" +"**Make gRPC keepalive time user-configurable and decrease default " +"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -"**使 gRPC 保持连接时间可由用户配置,并缩短默认保持连接时间** ([#1069]" -"(https://github.com/adap/flower/pull/1069))" +"**使 gRPC 保持连接时间可由用户配置,并缩短默认保持连接时间** " +"([#1069](https://github.com/adap/flower/pull/1069))" -#: ../../source/ref-changelog.md:745 +#: ../../source/ref-changelog.md:811 msgid "" "The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, Microsoft " -"Azure). Users can configure the keepalive time to customize the gRPC stack " -"based on specific requirements." +"compatibility of Flower with more cloud environments (for example, " +"Microsoft Azure). Users can configure the keepalive time to customize the" +" gRPC stack based on specific requirements." msgstr "" -"为提高 Flower 与更多云环境(如 Microsoft Azure)的兼容性,缩短了默认 gRPC 保" -"持时间。用户可以根据具体要求配置 keepalive 时间,自定义 gRPC 堆栈。" +"为提高 Flower 与更多云环境(如 Microsoft Azure)的兼容性,缩短了默认 gRPC 保持时间。用户可以根据具体要求配置 " +"keepalive 时间,自定义 gRPC 堆栈。" -#: ../../source/ref-changelog.md:747 +#: ../../source/ref-changelog.md:813 msgid "" -"**New differential privacy example using Opacus and PyTorch** ([#805]" -"(https://github.com/adap/flower/pull/805))" +"**New differential privacy example using Opacus and PyTorch** " +"([#805](https://github.com/adap/flower/pull/805))" msgstr "" -"**使用 Opacus 和 PyTorch 的新差分隐私示例** ([#805](https://github.com/adap/" -"flower/pull/805))" +"**使用 Opacus 和 PyTorch 的新差分隐私示例** " +"([#805](https://github.com/adap/flower/pull/805))" -#: ../../source/ref-changelog.md:749 +#: ../../source/ref-changelog.md:815 msgid "" -"A new code example (`opacus`) demonstrates differentially-private federated " -"learning with Opacus, PyTorch, and Flower." -msgstr "" -"一个新的代码示例(\"opacus\")演示了使用 Opacus、PyTorch 和 Flower 进行差分隐" -"私的联邦学习。" +"A new code example (`opacus`) demonstrates differentially-private " +"federated learning with Opacus, PyTorch, and Flower." +msgstr "一个新的代码示例(\"opacus\")演示了使用 Opacus、PyTorch 和 Flower 进行差分隐私的联邦学习。" -#: ../../source/ref-changelog.md:751 +#: ../../source/ref-changelog.md:817 msgid "" -"**New Hugging Face Transformers code example** ([#863](https://github.com/" -"adap/flower/pull/863))" +"**New Hugging Face Transformers code example** " +"([#863](https://github.com/adap/flower/pull/863))" msgstr "" -"**新的Hugging Face Transformers代码示例** ([#863](https://github.com/adap/" -"flower/pull/863))" +"**新的Hugging Face Transformers代码示例** " +"([#863](https://github.com/adap/flower/pull/863))" -#: ../../source/ref-changelog.md:753 +#: ../../source/ref-changelog.md:819 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of Hugging " -"Face Transformers with Flower." -msgstr "" -"新的代码示例(`quickstart_huggingface`)证明了结合Flower和Hugging Face " -"Transformers的实用性。" +"A new code example (`quickstart_huggingface`) demonstrates usage of " +"Hugging Face Transformers with Flower." +msgstr "新的代码示例(`quickstart_huggingface`)证明了结合Flower和Hugging Face Transformers的实用性。" -#: ../../source/ref-changelog.md:755 +#: ../../source/ref-changelog.md:821 msgid "" -"**New MLCube code example** ([#779](https://github.com/adap/flower/" -"pull/779), [#1034](https://github.com/adap/flower/pull/1034), [#1065]" -"(https://github.com/adap/flower/pull/1065), [#1090](https://github.com/adap/" -"flower/pull/1090))" +"**New MLCube code example** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" msgstr "" "**新的 MLCube 代码示例** ([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), [#1065](https://github." -"com/adap/flower/pull/1065), [#1090](https://github.com/adap/flower/" -"pull/1090))" +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-changelog.md:757 +#: ../../source/ref-changelog.md:823 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube with " -"Flower." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " +"with Flower." msgstr "新代码示例(\"quickstart_mlcube\")演示了 MLCube 与 Flower 的用法。" -#: ../../source/ref-changelog.md:759 +#: ../../source/ref-changelog.md:825 msgid "" -"**SSL-enabled server and client** ([#842](https://github.com/adap/flower/" -"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" -"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" -"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" -"github.com/adap/flower/pull/994))" +"**SSL-enabled server and client** " +"([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" msgstr "" -"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/" -"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" -"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" -"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" -"github.com/adap/flower/pull/994))" +"** 支持 SSL 的服务器和客户端** ([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:761 +#: ../../source/ref-changelog.md:827 msgid "" -"SSL enables secure encrypted connections between clients and servers. This " -"release open-sources the Flower secure gRPC implementation to make encrypted " -"communication channels accessible to all Flower users." -msgstr "" -"SSL 可实现客户端与服务器之间的安全加密连接。该版本开源了 Flower 安全 gRPC 实" -"现,使所有 Flower 用户都能访问加密通信通道。" +"SSL enables secure encrypted connections between clients and servers. " +"This release open-sources the Flower secure gRPC implementation to make " +"encrypted communication channels accessible to all Flower users." +msgstr "SSL 可实现客户端与服务器之间的安全加密连接。该版本开源了 Flower 安全 gRPC 实现,使所有 Flower 用户都能访问加密通信通道。" -#: ../../source/ref-changelog.md:763 +#: ../../source/ref-changelog.md:829 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** ([#885](https://" -"github.com/adap/flower/pull/885), [#895](https://github.com/adap/flower/" -"pull/895))" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" msgstr "" -"**更新**`FedAdam`**和**`FedYogi`**战略** ([#885](https://github.com/adap/" -"flower/pull/885), [#895](https://github.com/adap/flower/pull/895))" +"**更新**`FedAdam`**和**`FedYogi`**战略** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" -#: ../../source/ref-changelog.md:765 +#: ../../source/ref-changelog.md:831 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive Federated " -"Optimization paper." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive " +"Federated Optimization paper." msgstr "FedAdam \"和 \"FedAdam \"与最新版本的 \"自适应联邦优化 \"论文相匹配。" -#: ../../source/ref-changelog.md:767 +#: ../../source/ref-changelog.md:833 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** ([#860]" -"(https://github.com/adap/flower/pull/860))" +"**Initialize** `start_simulation` **with a list of client IDs** " +"([#860](https://github.com/adap/flower/pull/860))" msgstr "" -"**初始化** `start_simulation` **使用客户端 ID 列表** ([#860](https://github." -"com/adap/flower/pull/860))" +"**初始化** `start_simulation` **使用客户端 ID 列表** " +"([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-changelog.md:769 +#: ../../source/ref-changelog.md:835 msgid "" "`start_simulation` can now be called with a list of client IDs " "(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " @@ -18580,297 +20072,270 @@ msgid "" "identifiers." msgstr "" "现在可以使用客户端 ID 列表(`clients_ids`,类型:`List[str]`)调用 " -"`start_simulation`。每当需要初始化客户端时,这些 ID 就会被传递到 `client_fn` " -"中,这样就能更轻松地加载无法通过 `int` 标识符访问的数据分区。" +"`start_simulation`。每当需要初始化客户端时,这些 ID 就会被传递到 `client_fn` 中,这样就能更轻松地加载无法通过 " +"`int` 标识符访问的数据分区。" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:839 msgid "" -"Update `num_examples` calculation in PyTorch code examples in ([#909]" -"(https://github.com/adap/flower/pull/909))" +"Update `num_examples` calculation in PyTorch code examples in " +"([#909](https://github.com/adap/flower/pull/909))" msgstr "" -"更新 PyTorch 代码示例中的 \"num_examples \"计算 ([#909](https://github.com/" -"adap/flower/pull/909))" +"更新 PyTorch 代码示例中的 \"num_examples \"计算 " +"([#909](https://github.com/adap/flower/pull/909))" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:840 msgid "" -"Expose Flower version through `flwr.__version__` ([#952](https://github.com/" -"adap/flower/pull/952))" +"Expose Flower version through `flwr.__version__` " +"([#952](https://github.com/adap/flower/pull/952))" msgstr "" -"通过 `flwr.__version__` 公开 Flower 版本 ([#952](https://github.com/adap/" -"flower/pull/952))" +"通过 `flwr.__version__` 公开 Flower 版本 " +"([#952](https://github.com/adap/flower/pull/952))" -#: ../../source/ref-changelog.md:775 +#: ../../source/ref-changelog.md:841 msgid "" -"`start_server` in `app.py` now returns a `History` object containing metrics " -"from training ([#974](https://github.com/adap/flower/pull/974))" +"`start_server` in `app.py` now returns a `History` object containing " +"metrics from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -"`app.py`中的 `start_server`现在会返回一个 `History` 对象,其中包含训练中的指" -"标([#974](https://github.com/adap/flower/pull/974))" +"`app.py`中的 `start_server`现在会返回一个 `History` " +"对象,其中包含训练中的指标([#974](https://github.com/adap/flower/pull/974))" -#: ../../source/ref-changelog.md:776 +#: ../../source/ref-changelog.md:842 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable ([#978]" -"(https://github.com/adap/flower/pull/978))" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " +"([#978](https://github.com/adap/flower/pull/978))" msgstr "" -"使 `max_workers`(由 `ThreadPoolExecutor`使用)可配置([#978](https://github." -"com/adap/flower/pull/978))" +"使 `max_workers`(由 " +"`ThreadPoolExecutor`使用)可配置([#978](https://github.com/adap/flower/pull/978))" -#: ../../source/ref-changelog.md:777 +#: ../../source/ref-changelog.md:843 msgid "" -"Increase sleep time after server start to three seconds in all code examples " -"([#1086](https://github.com/adap/flower/pull/1086))" -msgstr "" -"在所有代码示例中,将服务器启动后的休眠时间延长至三秒([#1086](https://github." -"com/adap/flower/pull/1086))" +"Increase sleep time after server start to three seconds in all code " +"examples ([#1086](https://github.com/adap/flower/pull/1086))" +msgstr "在所有代码示例中,将服务器启动后的休眠时间延长至三秒([#1086](https://github.com/adap/flower/pull/1086))" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:844 msgid "" -"Added a new FAQ section to the documentation ([#948](https://github.com/adap/" -"flower/pull/948))" -msgstr "" -"在文档中添加了新的常见问题部分 ([#948](https://github.com/adap/flower/" -"pull/948))" +"Added a new FAQ section to the documentation " +"([#948](https://github.com/adap/flower/pull/948))" +msgstr "在文档中添加了新的常见问题部分 ([#948](https://github.com/adap/flower/pull/948))" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:845 msgid "" "And many more under-the-hood changes, library updates, documentation " "changes, and tooling improvements!" msgstr "还有更多底层更改、库更新、文档更改和工具改进!" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:849 msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" -"**从发布版中删除**`flwr_example`**和**`flwr_experimental`** ([#869](https://" -"github.com/adap/flower/pull/869))" +"**从发布版中删除**`flwr_example`**和**`flwr_experimental`** " +"([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:851 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " "builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in an " -"upcoming release." +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " +"an upcoming release." msgstr "" -"自 Flower 0.12.0 起,软件包 `flwr_example` 和 `flwr_experimental` 已被弃用," -"它们不再包含在 Flower 的发布版本中。相关的额外包(`baseline`, `examples-" -"pytorch`, `examples-tensorflow`, `http-logger`, `ops`)现在已不再使用,并将在" -"即将发布的版本中移除。" +"自 Flower 0.12.0 起,软件包 `flwr_example` 和 `flwr_experimental` 已被弃用,它们不再包含在 " +"Flower 的发布版本中。相关的额外包(`baseline`, `examples-pytorch`, `examples-" +"tensorflow`, `http-logger`, `ops`)现在已不再使用,并将在即将发布的版本中移除。" -#: ../../source/ref-changelog.md:787 +#: ../../source/ref-changelog.md:853 msgid "v0.17.0 (2021-09-24)" msgstr "v0.17.0 (2021-09-24)" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:857 msgid "" -"**Experimental virtual client engine** ([#781](https://github.com/adap/" -"flower/pull/781) [#790](https://github.com/adap/flower/pull/790) [#791]" -"(https://github.com/adap/flower/pull/791))" +"**Experimental virtual client engine** " +"([#781](https://github.com/adap/flower/pull/781) " +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" msgstr "" "**实验性虚拟客户端引擎** ([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) [#791](https://github.com/" -"adap/flower/pull/791))" +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:859 msgid "" -"One of Flower's goals is to enable research at scale. This release enables a " -"first (experimental) peek at a major new feature, codenamed the virtual " -"client engine. Virtual clients enable simulations that scale to a (very) " -"large number of clients on a single machine or compute cluster. The easiest " -"way to test the new functionality is to look at the two new code examples " -"called `quickstart_simulation` and `simulation_pytorch`." +"One of Flower's goals is to enable research at scale. This release " +"enables a first (experimental) peek at a major new feature, codenamed the" +" virtual client engine. Virtual clients enable simulations that scale to " +"a (very) large number of clients on a single machine or compute cluster. " +"The easiest way to test the new functionality is to look at the two new " +"code examples called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -"Flower 的目标之一是实现大规模研究。这一版本首次(试验性地)展示了代号为 \"虚" -"拟客户端引擎 \"的重要新功能。虚拟客户端可以在单台机器或计算集群上对大量客户端" -"进行模拟。测试新功能的最简单方法是查看名为 \"quickstart_simulation \"和 " -"\"simulation_pytorch \"的两个新代码示例。" +"Flower 的目标之一是实现大规模研究。这一版本首次(试验性地)展示了代号为 \"虚拟客户端引擎 " +"\"的重要新功能。虚拟客户端可以在单台机器或计算集群上对大量客户端进行模拟。测试新功能的最简单方法是查看名为 " +"\"quickstart_simulation \"和 \"simulation_pytorch \"的两个新代码示例。" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:861 msgid "" -"The feature is still experimental, so there's no stability guarantee for the " -"API. It's also not quite ready for prime time and comes with a few known " -"caveats. However, those who are curious are encouraged to try it out and " -"share their thoughts." +"The feature is still experimental, so there's no stability guarantee for " +"the API. It's also not quite ready for prime time and comes with a few " +"known caveats. However, those who are curious are encouraged to try it " +"out and share their thoughts." msgstr "" -"该功能仍处于试验阶段,因此无法保证 API 的稳定性。此外,它还没有完全准备好进入" -"黄金时间,并有一些已知的注意事项。不过,我们鼓励好奇的用户尝试使用并分享他们" -"的想法。" +"该功能仍处于试验阶段,因此无法保证 API " +"的稳定性。此外,它还没有完全准备好进入黄金时间,并有一些已知的注意事项。不过,我们鼓励好奇的用户尝试使用并分享他们的想法。" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:863 msgid "" -"**New built-in strategies** ([#828](https://github.com/adap/flower/pull/828) " +"**New built-in strategies** " +"([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" -"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) [#822]" -"(https://github.com/adap/flower/pull/822)" +"**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " +"[#822](https://github.com/adap/flower/pull/822)" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:865 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" -msgstr "" -"FedYogi - 在服务器端使用 Yogi 的联邦学习策略。基于 https://arxiv.org/" -"abs/2003.00295 实现" +msgstr "FedYogi - 在服务器端使用 Yogi 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" -#: ../../source/ref-changelog.md:800 +#: ../../source/ref-changelog.md:866 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" -msgstr "" -"FedAdam - 在服务器端使用 Adam 的联邦学习策略。基于 https://arxiv.org/" -"abs/2003.00295 实现" +msgstr "FedAdam - 在服务器端使用 Adam 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" -#: ../../source/ref-changelog.md:802 +#: ../../source/ref-changelog.md:868 msgid "" -"**New PyTorch Lightning code example** ([#617](https://github.com/adap/" -"flower/pull/617))" +"**New PyTorch Lightning code example** " +"([#617](https://github.com/adap/flower/pull/617))" msgstr "" -"**新的 PyTorch Lightning 代码示例** ([#617](https://github.com/adap/flower/" -"pull/617))" +"**新的 PyTorch Lightning 代码示例** " +"([#617](https://github.com/adap/flower/pull/617))" -#: ../../source/ref-changelog.md:804 +#: ../../source/ref-changelog.md:870 msgid "" -"**New Variational Auto-Encoder code example** ([#752](https://github.com/" -"adap/flower/pull/752))" -msgstr "" -"**新的变分自动编码器代码示例** ([#752](https://github.com/adap/flower/" -"pull/752))" +"**New Variational Auto-Encoder code example** " +"([#752](https://github.com/adap/flower/pull/752))" +msgstr "**新的变分自动编码器代码示例** ([#752](https://github.com/adap/flower/pull/752))" -#: ../../source/ref-changelog.md:806 +#: ../../source/ref-changelog.md:872 msgid "" -"**New scikit-learn code example** ([#748](https://github.com/adap/flower/" -"pull/748))" -msgstr "" -"**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/" -"pull/748))" +"**New scikit-learn code example** " +"([#748](https://github.com/adap/flower/pull/748))" +msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:808 +#: ../../source/ref-changelog.md:874 msgid "" -"**New experimental TensorBoard strategy** ([#789](https://github.com/adap/" -"flower/pull/789))" -msgstr "" -"**新的实验性 TensorBoard 策略**([#789](https://github.com/adap/flower/" -"pull/789))" +"**New experimental TensorBoard strategy** " +"([#789](https://github.com/adap/flower/pull/789))" +msgstr "**新的实验性 TensorBoard 策略**([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:812 +#: ../../source/ref-changelog.md:878 msgid "" -"Improved advanced TensorFlow code example ([#769](https://github.com/adap/" -"flower/pull/769))" -msgstr "" -"改进的高级 TensorFlow 代码示例([#769](https://github.com/adap/flower/" -"pull/769)" +"Improved advanced TensorFlow code example " +"([#769](https://github.com/adap/flower/pull/769))" +msgstr "改进的高级 TensorFlow 代码示例([#769](https://github.com/adap/flower/pull/769)" -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:879 msgid "" -"Warning when `min_available_clients` is misconfigured ([#830](https://github." -"com/adap/flower/pull/830))" +"Warning when `min_available_clients` is misconfigured " +"([#830](https://github.com/adap/flower/pull/830))" msgstr "" -"当 `min_available_clients` 配置错误时发出警告 ([#830](https://github.com/" -"adap/flower/pull/830))" +"当 `min_available_clients` 配置错误时发出警告 " +"([#830](https://github.com/adap/flower/pull/830))" -#: ../../source/ref-changelog.md:814 +#: ../../source/ref-changelog.md:880 msgid "" -"Improved gRPC server docs ([#841](https://github.com/adap/flower/pull/841))" -msgstr "" -"改进了 gRPC 服务器文档([#841](https://github.com/adap/flower/pull/841))" +"Improved gRPC server docs " +"([#841](https://github.com/adap/flower/pull/841))" +msgstr "改进了 gRPC 服务器文档([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:881 msgid "" -"Improved error message in `NumPyClient` ([#851](https://github.com/adap/" -"flower/pull/851))" -msgstr "" -"改进了 `NumPyClient` 中的错误信息 ([#851](https://github.com/adap/flower/" -"pull/851))" +"Improved error message in `NumPyClient` " +"([#851](https://github.com/adap/flower/pull/851))" +msgstr "改进了 `NumPyClient` 中的错误信息 ([#851](https://github.com/adap/flower/pull/851))" -#: ../../source/ref-changelog.md:816 +#: ../../source/ref-changelog.md:882 msgid "" -"Improved PyTorch quickstart code example ([#852](https://github.com/adap/" -"flower/pull/852))" -msgstr "" -"改进的 PyTorch 快速启动代码示例 ([#852](https://github.com/adap/flower/" -"pull/852))" +"Improved PyTorch quickstart code example " +"([#852](https://github.com/adap/flower/pull/852))" +msgstr "改进的 PyTorch 快速启动代码示例 ([#852](https://github.com/adap/flower/pull/852))" -#: ../../source/ref-changelog.md:820 +#: ../../source/ref-changelog.md:886 msgid "" -"**Disabled final distributed evaluation** ([#800](https://github.com/adap/" -"flower/pull/800))" -msgstr "" -"**禁用最终分布式评价** ([#800](https://github.com/adap/flower/pull/800))" +"**Disabled final distributed evaluation** " +"([#800](https://github.com/adap/flower/pull/800))" +msgstr "**禁用最终分布式评价** ([#800](https://github.com/adap/flower/pull/800))" -#: ../../source/ref-changelog.md:822 +#: ../../source/ref-changelog.md:888 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on " -"all connected clients, which is often not required (e.g., when using server-" -"side evaluation). The prior behaviour can be enabled by passing " +"Prior behaviour was to perform a final round of distributed evaluation on" +" all connected clients, which is often not required (e.g., when using " +"server-side evaluation). The prior behaviour can be enabled by passing " "`force_final_distributed_eval=True` to `start_server`." msgstr "" -"之前的行为是在所有连接的客户端上执行最后一轮分布式评估,而这通常是不需要的" -"(例如,在使用服务器端评估时)。可以通过向 `start_server` 传递 " -"`force_final_distributed_eval=True` 来启用之前的行为。" +"之前的行为是在所有连接的客户端上执行最后一轮分布式评估,而这通常是不需要的(例如,在使用服务器端评估时)。可以通过向 `start_server`" +" 传递 `force_final_distributed_eval=True` 来启用之前的行为。" -#: ../../source/ref-changelog.md:824 +#: ../../source/ref-changelog.md:890 msgid "" -"**Renamed q-FedAvg strategy** ([#802](https://github.com/adap/flower/" -"pull/802))" -msgstr "" -"**更名为 q-FedAvg 策略** ([#802](https://github.com/adap/flower/pull/802))" +"**Renamed q-FedAvg strategy** " +"([#802](https://github.com/adap/flower/pull/802))" +msgstr "**更名为 q-FedAvg 策略** ([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-changelog.md:826 +#: ../../source/ref-changelog.md:892 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect the " -"notation given in the original paper (q-FFL is the optimization objective, q-" -"FedAvg is the proposed solver). Note the original (now deprecated) " -"`QffedAvg` class is still available for compatibility reasons (it will be " -"removed in a future release)." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " +"the notation given in the original paper (q-FFL is the optimization " +"objective, q-FedAvg is the proposed solver). Note the original (now " +"deprecated) `QffedAvg` class is still available for compatibility reasons" +" (it will be removed in a future release)." msgstr "" -"名为 `QffedAvg` 的策略已更名为 `QFedAvg`,以更好地反映原始论文中给出的符号" -"(q-FFL 是优化目标,q-FedAvg 是建议的求解器)。请注意,出于兼容性原因,原始" -"(现已废弃)的 `QffedAvg` 类仍然可用(它将在未来的版本中移除)。" +"名为 `QffedAvg` 的策略已更名为 `QFedAvg`,以更好地反映原始论文中给出的符号(q-FFL 是优化目标,q-FedAvg " +"是建议的求解器)。请注意,出于兼容性原因,原始(现已废弃)的 `QffedAvg` 类仍然可用(它将在未来的版本中移除)。" -#: ../../source/ref-changelog.md:828 +#: ../../source/ref-changelog.md:894 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/pull/791))" +"`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" msgstr "" -"**删除并重命名代码示例**`simulation_pytorch`**为" -"**`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/" -"pull/791))" +"**删除并重命名代码示例**`simulation_pytorch`**为**`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:830 +#: ../../source/ref-changelog.md:896 msgid "" -"This example has been replaced by a new example. The new example is based on " -"the experimental virtual client engine, which will become the new default " -"way of doing most types of large-scale simulations in Flower. The existing " -"example was kept for reference purposes, but it might be removed in the " -"future." +"This example has been replaced by a new example. The new example is based" +" on the experimental virtual client engine, which will become the new " +"default way of doing most types of large-scale simulations in Flower. The" +" existing example was kept for reference purposes, but it might be " +"removed in the future." msgstr "" -"该示例已被新示例取代。新示例基于试验性虚拟客户端引擎,它将成为在 Flower 中进" -"行大多数类型大规模模拟的新的默认方式。现有示例将作为参考保留,但将来可能会删" -"除。" +"该示例已被新示例取代。新示例基于试验性虚拟客户端引擎,它将成为在 Flower " +"中进行大多数类型大规模模拟的新的默认方式。现有示例将作为参考保留,但将来可能会删除。" -#: ../../source/ref-changelog.md:832 +#: ../../source/ref-changelog.md:898 msgid "v0.16.0 (2021-05-11)" msgstr "v0.16.0 (2021-05-11)" -#: ../../source/ref-changelog.md:836 +#: ../../source/ref-changelog.md:902 msgid "" -"**New built-in strategies** ([#549](https://github.com/adap/flower/pull/549))" +"**New built-in strategies** " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "**新的内置策略** ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:838 +#: ../../source/ref-changelog.md:904 msgid "(abstract) FedOpt" msgstr "(摘要) FedOpt" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:907 msgid "" -"**Custom metrics for server and strategies** ([#717](https://github.com/adap/" -"flower/pull/717))" -msgstr "" -"**服务器和策略的自定义指标** ([#717](https://github.com/adap/flower/" -"pull/717))" +"**Custom metrics for server and strategies** " +"([#717](https://github.com/adap/flower/pull/717))" +msgstr "**服务器和策略的自定义指标** ([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:909 msgid "" "The Flower server is now fully task-agnostic, all remaining instances of " "task-specific metrics (such as `accuracy`) have been replaced by custom " @@ -18878,429 +20343,421 @@ msgid "" "dictionary containing custom metrics from client to server. As of this " "release, custom metrics replace task-specific metrics on the server." msgstr "" -"Flower 服务器现在完全与任务无关,所有剩余的任务特定度量(如 \"准确度\")都已" -"被自定义度量字典取代。Flower 0.15 引入了从客户端向服务器传递包含自定义指标的" -"字典的功能。从本版本开始,自定义指标将取代服务器上的特定任务指标。" +"Flower 服务器现在完全与任务无关,所有剩余的任务特定度量(如 \"准确度\")都已被自定义度量字典取代。Flower 0.15 " +"引入了从客户端向服务器传递包含自定义指标的字典的功能。从本版本开始,自定义指标将取代服务器上的特定任务指标。" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:911 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are " -"returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and they " -"enable evaluation functions passed to built-in strategies (via `eval_fn`) to " -"return more than two evaluation metrics. Strategies can even return " -"*aggregated* metrics dictionaries for the server to keep track of." +"Custom metric dictionaries are now used in two user-facing APIs: they are" +" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " +"they enable evaluation functions passed to built-in strategies (via " +"`eval_fn`) to return more than two evaluation metrics. Strategies can " +"even return *aggregated* metrics dictionaries for the server to keep " +"track of." msgstr "" -"自定义度量字典现在可在两个面向用户的 API 中使用:它们可从策略方法 " -"`aggregate_fit`/`aggregate_evaluate` 返回,还可使传递给内置策略(通过 " -"`eval_fn`)的评估函数返回两个以上的评估度量。策略甚至可以返回 *aggregated* 指" -"标字典,以便服务器跟踪。" +"自定义度量字典现在可在两个面向用户的 API 中使用:它们可从策略方法 `aggregate_fit`/`aggregate_evaluate` " +"返回,还可使传递给内置策略(通过 `eval_fn`)的评估函数返回两个以上的评估度量。策略甚至可以返回 *aggregated* " +"指标字典,以便服务器跟踪。" -#: ../../source/ref-changelog.md:847 +#: ../../source/ref-changelog.md:913 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate " -"from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"returning an empty `{}`), server-side evaluation functions should migrate" +" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -"Strategy 实现应将其 `aggregate_fit` 和 `aggregate_evaluate` 方法迁移到新的返" -"回类型(例如,只需返回空的 `{}`),服务器端评估函数应从 `return loss, " -"accuracy` 迁移到 `return loss, {\"accuracy\": accuracy}`。" +"Strategy 实现应将其 `aggregate_fit` 和 `aggregate_evaluate` " +"方法迁移到新的返回类型(例如,只需返回空的 `{}`),服务器端评估函数应从 `return loss, accuracy` 迁移到 " +"`return loss, {\"accuracy\": accuracy}`。" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:915 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." -msgstr "" -"Flower 0.15 风格的返回类型已被弃用(但仍受支持),兼容性将在未来的版本中移" -"除。" +msgstr "Flower 0.15 风格的返回类型已被弃用(但仍受支持),兼容性将在未来的版本中移除。" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:917 msgid "" -"**Migration warnings for deprecated functionality** ([#690](https://github." -"com/adap/flower/pull/690))" -msgstr "" -"** 过时功能的迁移警告** ([#690](https://github.com/adap/flower/pull/690))" +"**Migration warnings for deprecated functionality** " +"([#690](https://github.com/adap/flower/pull/690))" +msgstr "** 过时功能的迁移警告** ([#690](https://github.com/adap/flower/pull/690))" -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:919 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces detailed " -"warning messages if usage of deprecated APIs is detected. The new warning " -"messages often provide details on how to migrate to more recent APIs, thus " -"easing the transition from one release to another." +"maintaining compatibility with legacy APIs. This release introduces " +"detailed warning messages if usage of deprecated APIs is detected. The " +"new warning messages often provide details on how to migrate to more " +"recent APIs, thus easing the transition from one release to another." msgstr "" -"Flower 早期版本通常会迁移到新的应用程序接口,同时保持与旧版应用程序接口的兼" -"容。如果检测到使用了过时的 API,本版本将引入详细的警告信息。新的警告信息通常" -"会详细说明如何迁移到更新的 API,从而简化从一个版本到另一个版本的过渡。" +"Flower 早期版本通常会迁移到新的应用程序接口,同时保持与旧版应用程序接口的兼容。如果检测到使用了过时的 " +"API,本版本将引入详细的警告信息。新的警告信息通常会详细说明如何迁移到更新的 API,从而简化从一个版本到另一个版本的过渡。" -#: ../../source/ref-changelog.md:855 +#: ../../source/ref-changelog.md:921 msgid "" -"Improved docs and docstrings ([#691](https://github.com/adap/flower/" -"pull/691) [#692](https://github.com/adap/flower/pull/692) [#713](https://" -"github.com/adap/flower/pull/713))" +"Improved docs and docstrings " +"([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" msgstr "" -"改进了文档和文档说明 ([#691](https://github.com/adap/flower/pull/691) [#692]" -"(https://github.com/adap/flower/pull/692) [#713](https://github.com/adap/" -"flower/pull/713))" +"改进了文档和文档说明 ([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" -#: ../../source/ref-changelog.md:857 +#: ../../source/ref-changelog.md:923 msgid "MXNet example and documentation" msgstr "MXNet 示例和文档" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:925 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) [#702](https://github.com/" -"adap/flower/pull/702) [#705](https://github.com/adap/flower/pull/705))" +"([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" msgstr "" -"PyTorch 示例中的 FedBN 实现: 从集中到联邦 ([#696](https://github.com/adap/" -"flower/pull/696) [#702](https://github.com/adap/flower/pull/702) [#705]" -"(https://github.com/adap/flower/pull/705))" +"PyTorch 示例中的 FedBN 实现: 从集中到联邦 " +"([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:929 msgid "" -"**Serialization-agnostic server** ([#721](https://github.com/adap/flower/" -"pull/721))" +"**Serialization-agnostic server** " +"([#721](https://github.com/adap/flower/pull/721))" msgstr "**序列化无关服务器** ([#721](https://github.com/adap/flower/pull/721))" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:931 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of class " -"`Weights` (which represents parameters as deserialized NumPy ndarrays) was " -"replaced by class `Parameters` (e.g., in `Strategy`). `Parameters` objects " -"are fully serialization-agnostic and represents parameters as byte arrays, " -"the `tensor_type` attributes indicates how these byte arrays should be " -"interpreted (e.g., for serialization/deserialization)." +"The Flower server is now fully serialization-agnostic. Prior usage of " +"class `Weights` (which represents parameters as deserialized NumPy " +"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " +"`Parameters` objects are fully serialization-agnostic and represents " +"parameters as byte arrays, the `tensor_type` attributes indicates how " +"these byte arrays should be interpreted (e.g., for " +"serialization/deserialization)." msgstr "" -"Flower 服务器现在完全不依赖序列化。之前使用的 `Weights` 类(以反序列化的 " -"NumPy ndarrays 表示参数)已被 `Parameters` 类取代(例如在 `Strategy`中)。参" -"数 \"对象与序列化完全无关,它以字节数组的形式表示参数,\"tensor_type \"属性表" -"示如何解释这些字节数组(例如,用于序列化/反序列化)。" +"Flower 服务器现在完全不依赖序列化。之前使用的 `Weights` 类(以反序列化的 NumPy ndarrays 表示参数)已被 " +"`Parameters` 类取代(例如在 `Strategy`中)。参数 " +"\"对象与序列化完全无关,它以字节数组的形式表示参数,\"tensor_type \"属性表示如何解释这些字节数组(例如,用于序列化/反序列化)。" -#: ../../source/ref-changelog.md:867 +#: ../../source/ref-changelog.md:933 msgid "" -"Built-in strategies implement this approach by handling serialization and " -"deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"Built-in strategies implement this approach by handling serialization and" +" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " "implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR [#721](https://github.com/adap/" -"flower/pull/721) to see how strategies can easily migrate to the new format." +"definitions. Strategy authors can consult PR " +"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" +" easily migrate to the new format." msgstr "" -"内置策略通过在内部处理序列化和反序列化到/从`Weights`来实现这种方法。自定义/第" -"三方策略实现应更新为稍有改动的策略方法定义。策略作者可查阅 PR [#721](https://" -"github.com/adap/flower/pull/721) 以了解如何将策略轻松迁移到新格式。" +"内置策略通过在内部处理序列化和反序列化到/从`Weights`来实现这种方法。自定义/第三方策略实现应更新为稍有改动的策略方法定义。策略作者可查阅" +" PR [#721](https://github.com/adap/flower/pull/721) 以了解如何将策略轻松迁移到新格式。" -#: ../../source/ref-changelog.md:869 +#: ../../source/ref-changelog.md:935 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use `flwr.server.Server." -"evaluate_round` instead ([#717](https://github.com/adap/flower/pull/717))" +"Deprecated `flwr.server.Server.evaluate`, use " +"`flwr.server.Server.evaluate_round` instead " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -"已弃用 `flwr.server.Server.evaluate`,改用 `flwr.server.Server." -"evaluate_round`([#717](https://github.com/adap/flower/pull/717)" +"已弃用 `flwr.server.Server.evaluate`,改用 " +"`flwr.server.Server.evaluate_round`([#717](https://github.com/adap/flower/pull/717)" -#: ../../source/ref-changelog.md:871 +#: ../../source/ref-changelog.md:937 msgid "v0.15.0 (2021-03-12)" msgstr "v0.15.0 (2021-03-12)" -#: ../../source/ref-changelog.md:875 +#: ../../source/ref-changelog.md:941 msgid "" -"**Server-side parameter initialization** ([#658](https://github.com/adap/" -"flower/pull/658))" -msgstr "" -"**服务器端参数初始化** ([#658](https://github.com/adap/flower/pull/658))" +"**Server-side parameter initialization** " +"([#658](https://github.com/adap/flower/pull/658))" +msgstr "**服务器端参数初始化** ([#658](https://github.com/adap/flower/pull/658))" -#: ../../source/ref-changelog.md:877 +#: ../../source/ref-changelog.md:943 msgid "" "Model parameters can now be initialized on the server-side. Server-side " "parameter initialization works via a new `Strategy` method called " "`initialize_parameters`." msgstr "" -"现在可以在服务器端初始化模型参数。服务器端参数初始化通过名为 " -"\"initialize_parameters \"的新 \"Strategy \"方法进行。" +"现在可以在服务器端初始化模型参数。服务器端参数初始化通过名为 \"initialize_parameters \"的新 \"Strategy " +"\"方法进行。" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:945 msgid "" "Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies will " -"provide these initial parameters to the server on startup and then delete " -"them to free the memory afterwards." +"`initial_parameters` to set the initial parameters. Built-in strategies " +"will provide these initial parameters to the server on startup and then " +"delete them to free the memory afterwards." msgstr "" -"内置策略支持名为 \"initial_parameters \"的新构造函数参数,用于设置初始参数。" -"内置策略会在启动时向服务器提供这些初始参数,然后删除它们以释放内存。" +"内置策略支持名为 \"initial_parameters " +"\"的新构造函数参数,用于设置初始参数。内置策略会在启动时向服务器提供这些初始参数,然后删除它们以释放内存。" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:964 msgid "" "If no initial parameters are provided to the strategy, the server will " "continue to use the current behaviour (namely, it will ask one of the " "connected clients for its parameters and use these as the initial global " "parameters)." -msgstr "" -"如果没有向策略提供初始参数,服务器将继续使用当前行为(即向其中一个已连接的客" -"户端询问参数,并将这些参数用作初始全局参数)。" +msgstr "如果没有向策略提供初始参数,服务器将继续使用当前行为(即向其中一个已连接的客户端询问参数,并将这些参数用作初始全局参数)。" -#: ../../source/ref-changelog.md:900 +#: ../../source/ref-changelog.md:966 msgid "Deprecations" msgstr "停用" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:968 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to `flwr.server." -"strategy.FedAvg`, which is equivalent)" +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " +"`flwr.server.strategy.FedAvg`, which is equivalent)" msgstr "" -"停用 `flwr.server.strategy.DefaultStrategy`(迁移到等价的 `flwr.server." -"strategy.FedAvg`)" +"停用 `flwr.server.strategy.DefaultStrategy`(迁移到等价的 " +"`flwr.server.strategy.FedAvg`)" -#: ../../source/ref-changelog.md:904 +#: ../../source/ref-changelog.md:970 msgid "v0.14.0 (2021-02-18)" msgstr "v0.14.0 (2021-02-18)" -#: ../../source/ref-changelog.md:908 +#: ../../source/ref-changelog.md:974 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) [#572](https://github.com/" -"adap/flower/pull/572) [#633](https://github.com/adap/flower/pull/633))" +"([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" msgstr "" -"**通用** `Client.fit` **和** `Client.evaluate` **返回值** ([#610](https://" -"github.com/adap/flower/pull/610) [#572](https://github.com/adap/flower/" -"pull/572) [#633](https://github.com/adap/flower/pull/633))" +"**通用** `Client.fit` **和** `Client.evaluate` **返回值** " +"([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" -#: ../../source/ref-changelog.md:910 +#: ../../source/ref-changelog.md:976 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to values " -"of the following types: `bool`, `bytes`, `float`, `int`, `str`. This means " -"one can return almost arbitrary values from `fit`/`evaluate` and make use of " -"them on the server side!" +"Clients can now return an additional dictionary mapping `str` keys to " +"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " +"This means one can return almost arbitrary values from `fit`/`evaluate` " +"and make use of them on the server side!" msgstr "" -"客户端现在可以返回一个额外的字典,将 `str` 键映射为以下类型的值: bool`、" -"`bytes`、`float`、`int`、`str`。这意味着我们可以从 `fit`/`evaluate` 返回几乎" -"任意的值,并在服务器端使用它们!" +"客户端现在可以返回一个额外的字典,将 `str` 键映射为以下类型的值: " +"bool`、`bytes`、`float`、`int`、`str`。这意味着我们可以从 `fit`/`evaluate` " +"返回几乎任意的值,并在服务器端使用它们!" -#: ../../source/ref-changelog.md:912 +#: ../../source/ref-changelog.md:978 msgid "" -"This improvement also allowed for more consistent return types between `fit` " -"and `evaluate`: `evaluate` should now return a tuple `(float, int, dict)` " -"representing the loss, number of examples, and a dictionary holding " -"arbitrary problem-specific values like accuracy." +"This improvement also allowed for more consistent return types between " +"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " +"dict)` representing the loss, number of examples, and a dictionary " +"holding arbitrary problem-specific values like accuracy." msgstr "" -"这一改进还使 `fit` 和 `evaluate` 之间的返回类型更加一致:`evaluate` 现在应返" -"回一个元组`(float, int, dict)`,代表损失、示例数和一个包含特定问题任意值(如" -"准确度)的字典。" +"这一改进还使 `fit` 和 `evaluate` 之间的返回类型更加一致:`evaluate` 现在应返回一个元组`(float, int, " +"dict)`,代表损失、示例数和一个包含特定问题任意值(如准确度)的字典。" -#: ../../source/ref-changelog.md:914 +#: ../../source/ref-changelog.md:980 msgid "" -"In case you wondered: this feature is compatible with existing projects, the " -"additional dictionary return value is optional. New code should however " -"migrate to the new return types to be compatible with upcoming Flower " -"releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, `evaluate`: " -"`float, int, Dict[str, Scalar]`). See the example below for details." +"In case you wondered: this feature is compatible with existing projects, " +"the additional dictionary return value is optional. New code should " +"however migrate to the new return types to be compatible with upcoming " +"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " +"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " +"details." msgstr "" -"如果你想知道:此功能与现有项目兼容,额外的字典返回值是可选的。不过,新代码应" -"迁移到新的返回类型,以便与即将发布的 Flower 版本兼容(`fit`: `List[np." -"ndarray], int, Dict[str, Scalar]`,`evaluate`: `float, int, Dict[str, " -"Scalar]`)。详见下面的示例。" +"如果你想知道:此功能与现有项目兼容,额外的字典返回值是可选的。不过,新代码应迁移到新的返回类型,以便与即将发布的 Flower " +"版本兼容(`fit`: `List[np.ndarray], int, Dict[str, Scalar]`,`evaluate`: " +"`float, int, Dict[str, Scalar]`)。详见下面的示例。" -#: ../../source/ref-changelog.md:916 +#: ../../source/ref-changelog.md:982 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" -msgstr "" -"*代码示例:* 注意 `FlwrClient.fit` 和 `FlwrClient.evaluate` 中的附加字典返回" -"值:" +msgstr "*代码示例:* 注意 `FlwrClient.fit` 和 `FlwrClient.evaluate` 中的附加字典返回值:" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:997 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** `Client." -"evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Generalized** `config` **argument in** `Client.fit` **and** " +"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -"**在**`Client.fit` **和**`Client.evaluate`中泛化**`config`参数([#595]" -"(https://github.com/adap/flower/pull/595))" +"**在**`Client.fit` " +"**和**`Client.evaluate`中泛化**`config`参数([#595](https://github.com/adap/flower/pull/595))" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:999 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means that " -"dictionary values were expected to be strings. The new release generalizes " -"this to enable values of the following types: `bool`, `bytes`, `float`, " -"`int`, `str`." +"The `config` argument used to be of type `Dict[str, str]`, which means " +"that dictionary values were expected to be strings. The new release " +"generalizes this to enable values of the following types: `bool`, " +"`bytes`, `float`, `int`, `str`." msgstr "" -"`config`参数曾是 \"字典[str, str]\"类型,这意味着字典值应是字符串。新版本将其" -"扩展为以下类型的值: bool`、`bytes`、`float`、`int`、`str`。" +"`config`参数曾是 \"字典[str, str]\"类型,这意味着字典值应是字符串。新版本将其扩展为以下类型的值: " +"bool`、`bytes`、`float`、`int`、`str`。" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:1001 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-side " -"and `int(config[\"epochs\"])` on the client side!" +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" +"side and `int(config[\"epochs\"])` on the client side!" msgstr "" -"这意味着现在可以使用 `config` 字典向 `fit`/`evaluate` 传递几乎任意的值。耶," -"服务器端不再需要 `str(epochs)`,客户端不再需要 `int(config[\"epochs\"])`!" +"这意味着现在可以使用 `config` 字典向 `fit`/`evaluate` 传递几乎任意的值。耶,服务器端不再需要 " +"`str(epochs)`,客户端不再需要 `int(config[\"epochs\"])`!" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:1003 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" -msgstr "" -"*代码示例:* 注意 `config` 字典现在在 `Client.fit` 和 `Client.evaluate` 中都" -"包含非 `str` 值:" +msgstr "*代码示例:* 注意 `config` 字典现在在 `Client.fit` 和 `Client.evaluate` 中都包含非 `str` 值:" -#: ../../source/ref-changelog.md:954 +#: ../../source/ref-changelog.md:1020 msgid "v0.13.0 (2021-01-08)" msgstr "v0.13.0 (2021-01-08)" -#: ../../source/ref-changelog.md:958 +#: ../../source/ref-changelog.md:1024 msgid "" -"New example: PyTorch From Centralized To Federated ([#549](https://github." -"com/adap/flower/pull/549))" -msgstr "" -"新示例: PyTorch 从集中到联邦 ([#549](https://github.com/adap/flower/" -"pull/549))" +"New example: PyTorch From Centralized To Federated " +"([#549](https://github.com/adap/flower/pull/549))" +msgstr "新示例: PyTorch 从集中到联邦 ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:959 +#: ../../source/ref-changelog.md:1025 msgid "Improved documentation" msgstr "改进文档" -#: ../../source/ref-changelog.md:960 -msgid "" -"New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +#: ../../source/ref-changelog.md:1026 +msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "新文档主题 ([#551](https://github.com/adap/flower/pull/551))" -#: ../../source/ref-changelog.md:961 +#: ../../source/ref-changelog.md:1027 msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "新的 API 参考 ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:962 +#: ../../source/ref-changelog.md:1028 msgid "" -"Updated examples documentation ([#549](https://github.com/adap/flower/" -"pull/549))" +"Updated examples documentation " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "更新了示例文档 ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:963 +#: ../../source/ref-changelog.md:1029 msgid "" -"Removed obsolete documentation ([#548](https://github.com/adap/flower/" -"pull/548))" +"Removed obsolete documentation " +"([#548](https://github.com/adap/flower/pull/548))" msgstr "删除了过时的文档 ([#548](https://github.com/adap/flower/pull/548))" -#: ../../source/ref-changelog.md:965 +#: ../../source/ref-changelog.md:1031 msgid "Bugfix:" msgstr "错误修正:" -#: ../../source/ref-changelog.md:967 +#: ../../source/ref-changelog.md:1033 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the " -"clients is now handled in `flwr.server.start_server` ([#553](https://github." -"com/adap/flower/pull/553) [#540](https://github.com/adap/flower/issues/540))." +"`Server.fit` does not disconnect clients when finished, disconnecting the" +" clients is now handled in `flwr.server.start_server` " +"([#553](https://github.com/adap/flower/pull/553) " +"[#540](https://github.com/adap/flower/issues/540))." msgstr "" -"Server.fit \"完成后不会断开客户端连接,现在断开客户端连接是在 \"flwr.server." -"start_server \"中处理的([#553](https://github.com/adap/flower/pull/553) " +"Server.fit \"完成后不会断开客户端连接,现在断开客户端连接是在 \"flwr.server.start_server " +"\"中处理的([#553](https://github.com/adap/flower/pull/553) " "[#540](https://github.com/adap/flower/issues/540))。" -#: ../../source/ref-changelog.md:969 +#: ../../source/ref-changelog.md:1035 msgid "v0.12.0 (2020-12-07)" msgstr "v0.12.0 (2020-12-07)" -#: ../../source/ref-changelog.md:971 ../../source/ref-changelog.md:987 +#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 msgid "Important changes:" msgstr "重要变更:" -#: ../../source/ref-changelog.md:973 +#: ../../source/ref-changelog.md:1039 msgid "" -"Added an example for embedded devices ([#507](https://github.com/adap/flower/" -"pull/507))" +"Added an example for embedded devices " +"([#507](https://github.com/adap/flower/pull/507))" msgstr "添加了嵌入式设备示例 ([#507](https://github.com/adap/flower/pull/507))" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:1040 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) ([#504]" -"(https://github.com/adap/flower/pull/504) [#508](https://github.com/adap/" -"flower/pull/508))" +"Added a new NumPyClient (in addition to the existing KerasClient) " +"([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508))" msgstr "" -"添加了一个新的 NumPyClient(除现有的 KerasClient 之外)([#504](https://" -"github.com/adap/flower/pull/504) [#508](https://github.com/adap/flower/" -"pull/508)" +"添加了一个新的 NumPyClient(除现有的 KerasClient " +"之外)([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508)" -#: ../../source/ref-changelog.md:975 +#: ../../source/ref-changelog.md:1041 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into the " -"top-level `examples` directory ([#494](https://github.com/adap/flower/" -"pull/494) [#512](https://github.com/adap/flower/pull/512))" +"Deprecated `flwr_example` package and started to migrate examples into " +"the top-level `examples` directory " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" msgstr "" -"弃用 `flwr_example` 软件包,并开始将示例迁移到顶层的 `examples` 目录 ([#494]" -"(https://github.com/adap/flower/pull/494) [#512](https://github.com/adap/" -"flower/pull/512))" +"弃用 `flwr_example` 软件包,并开始将示例迁移到顶层的 `examples` 目录 " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" -#: ../../source/ref-changelog.md:977 +#: ../../source/ref-changelog.md:1043 msgid "v0.11.0 (2020-11-30)" msgstr "v0.11.0 (2020-11-30)" -#: ../../source/ref-changelog.md:979 +#: ../../source/ref-changelog.md:1045 msgid "Incompatible changes:" msgstr "不兼容的更改:" -#: ../../source/ref-changelog.md:981 +#: ../../source/ref-changelog.md:1047 msgid "" -"Renamed strategy methods ([#486](https://github.com/adap/flower/pull/486)) " -"to unify the naming of Flower's public APIs. Other public methods/functions " -"(e.g., every method in `Client`, but also `Strategy.evaluate`) do not use " -"the `on_` prefix, which is why we're removing it from the four methods in " -"Strategy. To migrate rename the following `Strategy` methods accordingly:" +"Renamed strategy methods " +"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " +"Flower's public APIs. Other public methods/functions (e.g., every method " +"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " +"which is why we're removing it from the four methods in Strategy. To " +"migrate rename the following `Strategy` methods accordingly:" msgstr "" -"重命名了策略方法([#486](https://github.com/adap/flower/pull/486)),以统一 " -"Flower公共 API 的命名。其他公共方法/函数(例如 `Client` 中的每个方法,以及 " -"`Strategy.evaluate`)不使用 `on_` 前缀,这就是我们从 Strategy 中的四个方法中" -"移除它的原因。迁移时,请相应地重命名以下 `Strategy` 方法:" +"重命名了策略方法([#486](https://github.com/adap/flower/pull/486)),以统一 Flower公共 " +"API 的命名。其他公共方法/函数(例如 `Client` 中的每个方法,以及 `Strategy.evaluate`)不使用 `on_` " +"前缀,这就是我们从 Strategy 中的四个方法中移除它的原因。迁移时,请相应地重命名以下 `Strategy` 方法:" -#: ../../source/ref-changelog.md:982 +#: ../../source/ref-changelog.md:1048 msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "`on_configure_evaluate` => `configure_evaluate`" -#: ../../source/ref-changelog.md:983 +#: ../../source/ref-changelog.md:1049 msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "`on_aggregate_evaluate` => `aggregate_evaluate`" -#: ../../source/ref-changelog.md:984 +#: ../../source/ref-changelog.md:1050 msgid "`on_configure_fit` => `configure_fit`" msgstr "`on_configure_fit` => `configure_fit`" -#: ../../source/ref-changelog.md:985 +#: ../../source/ref-changelog.md:1051 msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "`on_aggregate_fit` => `aggregate_fit`" -#: ../../source/ref-changelog.md:989 +#: ../../source/ref-changelog.md:1055 msgid "" -"Deprecated `DefaultStrategy` ([#479](https://github.com/adap/flower/" -"pull/479)). To migrate use `FedAvg` instead." +"Deprecated `DefaultStrategy` " +"([#479](https://github.com/adap/flower/pull/479)). To migrate use " +"`FedAvg` instead." msgstr "" -"已废弃的 `DefaultStrategy` ([#479](https://github.com/adap/flower/" -"pull/479)) 。迁移时请使用 `FedAvg`。" +"已废弃的 `DefaultStrategy` ([#479](https://github.com/adap/flower/pull/479)) " +"。迁移时请使用 `FedAvg`。" -#: ../../source/ref-changelog.md:990 +#: ../../source/ref-changelog.md:1056 msgid "" -"Simplified examples and baselines ([#484](https://github.com/adap/flower/" -"pull/484))." -msgstr "" -"简化示例和baselines([#484](https://github.com/adap/flower/pull/484))。" +"Simplified examples and baselines " +"([#484](https://github.com/adap/flower/pull/484))." +msgstr "简化示例和baselines([#484](https://github.com/adap/flower/pull/484))。" -#: ../../source/ref-changelog.md:991 +#: ../../source/ref-changelog.md:1057 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface ([#483]" -"(https://github.com/adap/flower/pull/483))." +"Removed presently unused `on_conclude_round` from strategy interface " +"([#483](https://github.com/adap/flower/pull/483))." msgstr "" -"删除了策略界面中目前未使用的 \"on_conclude_round\"([#483](https://github." -"com/adap/flower/pull/483))。" +"删除了策略界面中目前未使用的 " +"\"on_conclude_round\"([#483](https://github.com/adap/flower/pull/483))。" -#: ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:1058 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 ([#471](https://github." -"com/adap/flower/pull/471))." +"Set minimal Python version to 3.6.1 instead of 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." msgstr "" -"将最小 Python 版本设为 3.6.1,而不是 3.6.9 ([#471](https://github.com/adap/" -"flower/pull/471))." +"将最小 Python 版本设为 3.6.1,而不是 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." -#: ../../source/ref-changelog.md:993 +#: ../../source/ref-changelog.md:1059 msgid "" -"Improved `Strategy` docstrings ([#470](https://github.com/adap/flower/" -"pull/470))." +"Improved `Strategy` docstrings " +"([#470](https://github.com/adap/flower/pull/470))." msgstr "" -"改进了 `Strategy` docstrings([#470](https://github.com/adap/flower/" -"pull/470))。" +"改进了 `Strategy` " +"docstrings([#470](https://github.com/adap/flower/pull/470))。" #: ../../source/ref-example-projects.rst:2 msgid "Example projects" @@ -19308,15 +20765,15 @@ msgstr "项目实例" #: ../../source/ref-example-projects.rst:4 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate how " -"Flower can be used to federate different kinds of existing machine learning " -"pipelines, usually leveraging popular machine learning frameworks such as " -"`PyTorch `_ or `TensorFlow `_." +"Flower comes with a number of usage examples. The examples demonstrate " +"how Flower can be used to federate different kinds of existing machine " +"learning pipelines, usually leveraging popular machine learning " +"frameworks such as `PyTorch `_ or `TensorFlow " +"`_." msgstr "" -"Flower 附带了许多使用示例。这些示例演示了如何使用 Flower 联邦不同类型的现有机" -"器学习形式,通常是利用流行的机器学习框架,如 `PyTorch `_ 或 `TensorFlow `_。" +"Flower 附带了许多使用示例。这些示例演示了如何使用 Flower 联邦不同类型的现有机器学习形式,通常是利用流行的机器学习框架,如 " +"`PyTorch `_ 或 `TensorFlow " +"`_。" #: ../../source/ref-example-projects.rst:10 #, fuzzy @@ -19327,32 +20784,30 @@ msgstr "以下示例可作为独立项目使用。" #: ../../source/ref-example-projects.rst:14 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image classification " -"with MobileNetV2:" -msgstr "" -"TensorFlow/Keras 快速入门示例展示了使用 MobileNetV2 进行的 CIFAR-10 图像分" -"类:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image " +"classification with MobileNetV2:" +msgstr "TensorFlow/Keras 快速入门示例展示了使用 MobileNetV2 进行的 CIFAR-10 图像分类:" #: ../../source/ref-example-projects.rst:17 msgid "" -"`Quickstart TensorFlow (Code) `_" +"`Quickstart TensorFlow (Code) " +"`_" msgstr "" -"`TensorFlow快速入门 (代码) `_" +"`TensorFlow快速入门 (代码) `_" #: ../../source/ref-example-projects.rst:18 #, fuzzy -msgid "" -":doc:`Quickstart TensorFlow (Tutorial) `" +msgid ":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" "`TensorFlow快速入门 (教程) `_" #: ../../source/ref-example-projects.rst:19 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" "`TensorFlow快速入门 (博客) `_" @@ -19364,25 +20819,24 @@ msgstr "PyTorch快速入门" #: ../../source/ref-example-projects.rst:25 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a " -"simple Convolutional Neural Network:" -msgstr "" -"PyTorch 快速入门范例展示了使用简单卷积神经网络进行 CIFAR-10 图像分类的情况:" +"The PyTorch quickstart example shows CIFAR-10 image classification with a" +" simple Convolutional Neural Network:" +msgstr "PyTorch 快速入门范例展示了使用简单卷积神经网络进行 CIFAR-10 图像分类的情况:" #: ../../source/ref-example-projects.rst:28 msgid "" -"`Quickstart PyTorch (Code) `_" +"`Quickstart PyTorch (Code) " +"`_" msgstr "" -"`PyTorch快速入门 (代码) `_" +"`PyTorch快速入门 (代码) `_" #: ../../source/ref-example-projects.rst:29 #, fuzzy msgid ":doc:`Quickstart PyTorch (Tutorial) `" msgstr "" -"`PyTorch快速入门 (教程) `_" +"`PyTorch快速入门 (教程) `_" #: ../../source/ref-example-projects.rst:33 msgid "PyTorch: From Centralized To Federated" @@ -19396,11 +20850,12 @@ msgstr "本例展示了如何使用 Flower 联邦化一个普通的 PyTorch 项 #: ../../source/ref-example-projects.rst:37 msgid "" -"`PyTorch: From Centralized To Federated (Code) `_" +"`PyTorch: From Centralized To Federated (Code) " +"`_" msgstr "" -"PyTorch: 从集中式到联邦式(代码) `_" +"PyTorch: 从集中式到联邦式(代码) `_" #: ../../source/ref-example-projects.rst:38 #, fuzzy @@ -19408,8 +20863,8 @@ msgid "" ":doc:`PyTorch: From Centralized To Federated (Tutorial) `" msgstr "" -"PyTorch: 从集中式到联邦式(教程) `_" +"PyTorch: 从集中式到联邦式(教程) `_" #: ../../source/ref-example-projects.rst:42 msgid "Federated Learning on Raspberry Pi and Nvidia Jetson" @@ -19419,27 +20874,23 @@ msgstr "树莓派和 Nvidia Jetson 上的联邦学习" msgid "" "This example shows how Flower can be used to build a federated learning " "system that run across Raspberry Pi and Nvidia Jetson:" -msgstr "" -"本示例展示了如何利用 Flower 建立一个跨 Raspberry Pi 和 Nvidia Jetson 运行的联" -"邦学习系统:" +msgstr "本示例展示了如何利用 Flower 建立一个跨 Raspberry Pi 和 Nvidia Jetson 运行的联邦学习系统:" #: ../../source/ref-example-projects.rst:46 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) `_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " +"`_" msgstr "" -"Raspberry Pi 和 Nvidia Jetson 上的联邦学习(代码) `_" +"Raspberry Pi 和 Nvidia Jetson 上的联邦学习(代码) " +"`_" #: ../../source/ref-example-projects.rst:47 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) `_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " +"`_" msgstr "" -"Raspberry Pi和 Nvidia Jetson 上的联邦学习(博客) `_" +"Raspberry Pi和 Nvidia Jetson 上的联邦学习(博客) " +"`_" #: ../../source/ref-faq.rst:4 msgid "" @@ -19450,32 +20901,33 @@ msgstr "本页收集了有关 \"Flower 联邦学习 \"常见问题的答案。" #: ../../source/ref-faq.rst #, fuzzy msgid ":fa:`eye,mr-1` Can Flower run on Jupyter Notebooks / Google Colab?" -msgstr "" -":fa:`eye,mr-1` Flower 可以在 Juptyter Notebooks / Google Colab 上运行吗?" +msgstr ":fa:`eye,mr-1` Flower 可以在 Juptyter Notebooks / Google Colab 上运行吗?" #: ../../source/ref-faq.rst:8 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to " -"make it work even better on Colab. Here's a quickstart example:" -msgstr "" -"是的,它可以!Flower 甚至还进行了一些底层优化,使其在 Colab 上运行得更好。下" -"面是一个快速启动示例:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to" +" make it work even better on Colab. Here's a quickstart example:" +msgstr "是的,它可以!Flower 甚至还进行了一些底层优化,使其在 Colab 上运行得更好。下面是一个快速启动示例:" #: ../../source/ref-faq.rst:10 msgid "" -"`Flower simulation PyTorch `_" +"`Flower simulation PyTorch " +"`_" msgstr "" -"`Flower 模拟 PyTorch `_" +"`Flower 模拟 PyTorch " +"`_" #: ../../source/ref-faq.rst:11 msgid "" -"`Flower simulation TensorFlow/Keras `_" +"`Flower simulation TensorFlow/Keras " +"`_" msgstr "" -"`Flower模拟TensorFlow/Keras `_" +"`Flower模拟TensorFlow/Keras " +"`_" #: ../../source/ref-faq.rst msgid ":fa:`eye,mr-1` How can I run Federated Learning on a Raspberry Pi?" @@ -19484,37 +20936,33 @@ msgstr ":fa:`eye,mr-1` 如何在 Raspberry Pi 上运行联邦学习?" #: ../../source/ref-faq.rst:15 msgid "" "Find the `blog post about federated learning on embedded device here " -"`_ " -"and the corresponding `GitHub code example `_." +"`_" +" and the corresponding `GitHub code example " +"`_." msgstr "" -"请点击此处查看有关嵌入式设备联邦学习的 \"博文\"`_和" -"相应的 \"GitHub 代码示例\"`_。" +"请点击此处查看有关嵌入式设备联邦学习的 " +"\"博文\"`_和相应的" +" \"GitHub 代码示例\"`_。" #: ../../source/ref-faq.rst -msgid "" -":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr ":fa:`eye,mr-1` Flower 是否支持安卓设备上的联邦学习?" #: ../../source/ref-faq.rst:19 msgid "" -"Yes, it does. Please take a look at our `blog post `_ or " -"check out the code examples:" +"Yes, it does. Please take a look at our `blog post " +"`_ or check out the code examples:" msgstr "" -"是的,确实如此。请查看我们的 \"博客文章 `_\" 或查看代码示例:" +"是的,确实如此。请查看我们的 \"博客文章 `_\" 或查看代码示例:" #: ../../source/ref-faq.rst:21 msgid "" -"`Android Kotlin example `_" -msgstr "" -"`Android Kotlin 示例 `_" +"`Android Kotlin example `_" +msgstr "`Android Kotlin 示例 `_" #: ../../source/ref-faq.rst:22 msgid "`Android Java example `_" @@ -19532,46 +20980,46 @@ msgstr "当然可以。有关在区块链环境中使用 Flower 的可用示例 #: ../../source/ref-faq.rst:28 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." #: ../../source/ref-faq.rst:29 msgid "" -"`Flower meets Nevermined YouTube video `_." +"`Flower meets Nevermined YouTube video " +"`_." msgstr "" -"`Flower meets Nevermined YouTube 视频 `_." +"`Flower meets Nevermined YouTube 视频 " +"`_." #: ../../source/ref-faq.rst:30 #, fuzzy msgid "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." msgstr "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." #: ../../source/ref-faq.rst:31 msgid "" "`Flower meets Talan blog post `_ ." +"learning-same-mask-different-faces-imen-" +"ayari/?trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ ." msgstr "" "`Flower meets Talan博文 `_ 。" +"same-mask-different-faces-imen-" +"ayari/?trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ 。" #: ../../source/ref-faq.rst:32 msgid "" -"`Flower meets Talan GitHub Repository `_ ." +"`Flower meets Talan GitHub Repository " +"`_ ." msgstr "" -"`Flower meets Talan GitHub Repository `_ ." +"`Flower meets Talan GitHub Repository " +"`_ ." #: ../../source/ref-telemetry.md:1 msgid "Telemetry" @@ -19579,64 +21027,60 @@ msgstr "遥测功能" #: ../../source/ref-telemetry.md:3 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to make " -"well-informed decisions to improve Flower. Doing this enables the Flower " -"team to understand how Flower is used and what challenges users might face." +"The Flower open-source project collects **anonymous** usage metrics to " +"make well-informed decisions to improve Flower. Doing this enables the " +"Flower team to understand how Flower is used and what challenges users " +"might face." msgstr "" -"Flower 开源项目收集**匿名**使用指标,以便在充分知情的情况下做出改进 Flower 的" -"决定。这样做能让 Flower 团队了解 Flower 的使用情况以及用户可能面临的挑战。" +"Flower 开源项目收集**匿名**使用指标,以便在充分知情的情况下做出改进 Flower 的决定。这样做能让 Flower 团队了解 " +"Flower 的使用情况以及用户可能面临的挑战。" #: ../../source/ref-telemetry.md:5 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.** " -"Staying true to this statement, Flower makes it easy to disable telemetry " -"for users that do not want to share anonymous usage metrics." -msgstr "" -"**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声" -"明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。" +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users that do not want to share anonymous usage metrics." +msgstr "**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower 遵循这一声明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。" #: ../../source/ref-telemetry.md:7 msgid "Principles" msgstr "原则" #: ../../source/ref-telemetry.md:9 -msgid "" -"We follow strong principles guarding anonymous usage metrics collection:" +msgid "We follow strong principles guarding anonymous usage metrics collection:" msgstr "我们遵循严格的匿名使用指标收集原则:" #: ../../source/ref-telemetry.md:11 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to learn " -"“[How to opt-out](#how-to-opt-out)”." -msgstr "" -"**可选:** 您始终可以禁用遥测功能;请继续阅读\"[如何退出](#how-to-opt-" -"out)\"。" +"**Optional:** You will always be able to disable telemetry; read on to " +"learn “[How to opt-out](#how-to-opt-out)”." +msgstr "**可选:** 您始终可以禁用遥测功能;请继续阅读\"[如何退出](#how-to-opt-out)\"。" #: ../../source/ref-telemetry.md:12 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not contain " -"any personally identifiable information (PII). See “[Collected metrics]" -"(#collected-metrics)” to understand what metrics are being reported." +"**Anonymous:** The reported usage metrics are anonymous and do not " +"contain any personally identifiable information (PII). See “[Collected " +"metrics](#collected-metrics)” to understand what metrics are being " +"reported." msgstr "" -"**匿名:** 报告的使用指标是匿名的,不包含任何个人身份信息 (PII)。请参阅\"[收" -"集的指标](#collected-metrics) \"了解报告的指标。" +"**匿名:** 报告的使用指标是匿名的,不包含任何个人身份信息 (PII)。请参阅\"[收集的指标](#collected-metrics) " +"\"了解报告的指标。" #: ../../source/ref-telemetry.md:13 msgid "" "**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-to-" -"inspect-what-is-being-reported)”" +"reported; see the section “[How to inspect what is being reported](#how-" +"to-inspect-what-is-being-reported)”" msgstr "" -"**透明:** 您可以轻松查看正在报告的匿名指标;请参阅\"[如何查看正在报告的指标]" -"(#how-to-inspect-what-is-being-reported)\"部分" +"**透明:** 您可以轻松查看正在报告的匿名指标;请参阅\"[如何查看正在报告的指标](#how-to-inspect-what-is-" +"being-reported)\"部分" #: ../../source/ref-telemetry.md:14 msgid "" -"**Open for feedback:** You can always reach out to us if you have feedback; " -"see the section “[How to contact us](#how-to-contact-us)” for details." -msgstr "" -"**欢迎反馈:** 如果您有反馈意见,可以随时联系我们;详情请参见\"[如何联系我们]" -"(#how-to-contact-us) \"部分。" +"**Open for feedback:** You can always reach out to us if you have " +"feedback; see the section “[How to contact us](#how-to-contact-us)” for " +"details." +msgstr "**欢迎反馈:** 如果您有反馈意见,可以随时联系我们;详情请参见\"[如何联系我们](#how-to-contact-us) \"部分。" #: ../../source/ref-telemetry.md:16 msgid "How to opt-out" @@ -19650,17 +21094,17 @@ msgid "" "client, simply do so by prepending your command as in:" msgstr "" "Flower 启动时,会检查环境变量 `FLWR_TELEMETRY_ENABLED` 是否存在。通过设置 " -"`FLWR_TELEMETRY_ENABLED=0` 可以轻松禁用遥测功能。假设你启动的是 Flower 服务器" -"或客户端,只需在命令前添加以下内容即可:" +"`FLWR_TELEMETRY_ENABLED=0` 可以轻松禁用遥测功能。假设你启动的是 Flower " +"服务器或客户端,只需在命令前添加以下内容即可:" #: ../../source/ref-telemetry.md:24 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `." -"bashrc` (or whatever configuration file applies to your environment) to " -"disable Flower telemetry permanently." +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," +" `.bashrc` (or whatever configuration file applies to your environment) " +"to disable Flower telemetry permanently." msgstr "" -"或者,你也可以在 `.bashrc`(或任何适用于你的环境的配置文件)中导出 " -"`FLWR_TELEMETRY_ENABLED=0` 来永久禁用 Flower telemetry。" +"或者,你也可以在 `.bashrc`(或任何适用于你的环境的配置文件)中导出 `FLWR_TELEMETRY_ENABLED=0` 来永久禁用 " +"Flower telemetry。" #: ../../source/ref-telemetry.md:26 msgid "Collected metrics" @@ -19672,21 +21116,17 @@ msgstr "Flower 遥测技术收集以下指标:" #: ../../source/ref-telemetry.md:30 msgid "" -"**Flower version.** Understand which versions of Flower are currently being " -"used. This helps us to decide whether we should invest effort into releasing " -"a patch version for an older version of Flower or instead use the bandwidth " -"to build new features." -msgstr "" -"**了解目前使用的 Flower 版本。这有助于我们决定是否应该投入精力为旧版本的 " -"Flower 发布补丁版本,还是利用带宽来构建新功能。" +"**Flower version.** Understand which versions of Flower are currently " +"being used. This helps us to decide whether we should invest effort into " +"releasing a patch version for an older version of Flower or instead use " +"the bandwidth to build new features." +msgstr "**了解目前使用的 Flower 版本。这有助于我们决定是否应该投入精力为旧版本的 Flower 发布补丁版本,还是利用带宽来构建新功能。" #: ../../source/ref-telemetry.md:32 msgid "" "**Operating system.** Enables us to answer questions such as: *Should we " "create more guides for Linux, macOS, or Windows?*" -msgstr "" -"**操作系统**使我们能够回答以下问题: *我们应该为 Linux、macOS 还是 Windows 创" -"建更多指南?*" +msgstr "**操作系统**使我们能够回答以下问题: *我们应该为 Linux、macOS 还是 Windows 创建更多指南?*" #: ../../source/ref-telemetry.md:34 msgid "" @@ -19694,82 +21134,73 @@ msgid "" "decide whether we should invest effort into supporting old versions of " "Python or stop supporting them and start taking advantage of new Python " "features." -msgstr "" -"**例如,了解 Python 版本有助于我们决定是否应该投入精力支持旧版本的 Python,还" -"是停止支持这些版本并开始利用新的 Python 功能。" +msgstr "**例如,了解 Python 版本有助于我们决定是否应该投入精力支持旧版本的 Python,还是停止支持这些版本并开始利用新的 Python 功能。" #: ../../source/ref-telemetry.md:36 msgid "" -"**Hardware properties.** Understanding the hardware environment that Flower " -"is being used in helps to decide whether we should, for example, put more " -"effort into supporting low-resource environments." -msgstr "" -"**硬件属性** 了解 Flower 的硬件使用环境,有助于决定我们是否应在支持低资源环境" -"等方面投入更多精力。" +"**Hardware properties.** Understanding the hardware environment that " +"Flower is being used in helps to decide whether we should, for example, " +"put more effort into supporting low-resource environments." +msgstr "**硬件属性** 了解 Flower 的硬件使用环境,有助于决定我们是否应在支持低资源环境等方面投入更多精力。" #: ../../source/ref-telemetry.md:38 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables us " -"to understand how heavily certain features are being used and better " +"**Execution mode.** Knowing what execution mode Flower starts in enables " +"us to understand how heavily certain features are being used and better " "prioritize based on that." -msgstr "" -"** 执行模式** 了解 Flower 的启动执行模式,能让我们了解某些功能的使用率,并据" -"此更好地确定优先级。" +msgstr "** 执行模式** 了解 Flower 的启动执行模式,能让我们了解某些功能的使用率,并据此更好地确定优先级。" #: ../../source/ref-telemetry.md:40 msgid "" "**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " "time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete them." +"types not only start Flower workloads but also successfully complete " +"them." msgstr "" -"**每次 Flower 工作负载启动时,Flower 遥测都会随机分配一个内存集群 ID。这样," -"我们就能了解哪些设备类型不仅启动了 Flower 工作负载,而且还成功完成了它们。" +"**每次 Flower 工作负载启动时,Flower 遥测都会随机分配一个内存集群 ID。这样,我们就能了解哪些设备类型不仅启动了 Flower " +"工作负载,而且还成功完成了它们。" #: ../../source/ref-telemetry.md:42 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/" -"source` the first time a telemetry event is generated. The source ID is " -"important to identify whether an issue is recurring or whether an issue is " -"triggered by multiple clusters running concurrently (which often happens in " -"simulation). For example, if a device runs multiple workloads at the same " -"time, and this results in an issue, then, in order to reproduce the issue, " -"multiple workloads must be started at the same time." +"**Source.** Flower telemetry tries to store a random source ID in " +"`~/.flwr/source` the first time a telemetry event is generated. The " +"source ID is important to identify whether an issue is recurring or " +"whether an issue is triggered by multiple clusters running concurrently " +"(which often happens in simulation). For example, if a device runs " +"multiple workloads at the same time, and this results in an issue, then, " +"in order to reproduce the issue, multiple workloads must be started at " +"the same time." msgstr "" -"**Source.** Flower 遥测会在第一次生成遥测事件时,尝试在 `~/.flwr/source` 中存" -"储一个随机源 ID。源 ID 对于识别问题是否反复出现或问题是否由多个集群同时运行触" -"发(这在模拟中经常发生)非常重要。例如,如果设备同时运行多个工作负载并导致问" -"题,那么为了重现问题,必须同时启动多个工作负载。" +"**Source.** Flower 遥测会在第一次生成遥测事件时,尝试在 `~/.flwr/source` 中存储一个随机源 ID。源 ID " +"对于识别问题是否反复出现或问题是否由多个集群同时运行触发(这在模拟中经常发生)非常重要。例如,如果设备同时运行多个工作负载并导致问题,那么为了重现问题,必须同时启动多个工作负载。" #: ../../source/ref-telemetry.md:44 msgid "" -"You may delete the source ID at any time. If you wish for all events logged " -"under a specific source ID to be deleted, you can send a deletion request " -"mentioning the source ID to `telemetry@flower.ai`. All events related to " -"that source ID will then be permanently deleted." +"You may delete the source ID at any time. If you wish for all events " +"logged under a specific source ID to be deleted, you can send a deletion " +"request mentioning the source ID to `telemetry@flower.ai`. All events " +"related to that source ID will then be permanently deleted." msgstr "" -"您可以随时删除源 ID。如果您希望删除特定源 ID 下记录的所有事件,可以向 " -"`telemetry@flower.ai` 发送删除请求,并提及该源 ID。届时,与该源 ID 相关的所有" -"事件都将被永久删除。" +"您可以随时删除源 ID。如果您希望删除特定源 ID 下记录的所有事件,可以向 `telemetry@flower.ai` 发送删除请求,并提及该源" +" ID。届时,与该源 ID 相关的所有事件都将被永久删除。" #: ../../source/ref-telemetry.md:46 msgid "" -"We will not collect any personally identifiable information. If you think " -"any of the metrics collected could be misused in any way, please [get in " -"touch with us](#how-to-contact-us). We will update this page to reflect any " -"changes to the metrics collected and publish changes in the changelog." +"We will not collect any personally identifiable information. If you think" +" any of the metrics collected could be misused in any way, please [get in" +" touch with us](#how-to-contact-us). We will update this page to reflect " +"any changes to the metrics collected and publish changes in the " +"changelog." msgstr "" -"我们不会收集任何个人身份信息。如果您认为所收集的任何指标可能以任何方式被滥" -"用,请[与我们联系](#how-to-contact-us)。我们将更新本页面,以反映对所收集指" -"标的任何更改,并在更新日志中公布更改内容。" +"我们不会收集任何个人身份信息。如果您认为所收集的任何指标可能以任何方式被滥用,请[与我们联系](#how-to-contact-" +"us)。我们将更新本页面,以反映对所收集指标的任何更改,并在更新日志中公布更改内容。" #: ../../source/ref-telemetry.md:48 msgid "" "If you think other metrics would be helpful for us to better guide our " "decisions, please let us know! We will carefully review them; if we are " "confident that they do not compromise user privacy, we may add them." -msgstr "" -"如果您认为其他指标有助于我们更好地指导决策,请告诉我们!我们将仔细审查这些指" -"标;如果我们确信它们不会损害用户隐私,我们可能会添加这些指标。" +msgstr "如果您认为其他指标有助于我们更好地指导决策,请告诉我们!我们将仔细审查这些指标;如果我们确信它们不会损害用户隐私,我们可能会添加这些指标。" #: ../../source/ref-telemetry.md:50 msgid "How to inspect what is being reported" @@ -19778,23 +21209,21 @@ msgstr "如何检查报告中的内容" #: ../../source/ref-telemetry.md:52 msgid "" "We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information by " -"setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is " -"disabled by default. You may use logging independently from " +"metrics are reported. You can view all the reported telemetry information" +" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " +"is disabled by default. You may use logging independently from " "`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " "without sending any metrics." msgstr "" -"我们希望能让您轻松查看所报告的匿名使用指标。通过设置环境变量 " -"`FLWR_TELEMETRY_LOGGING=1` 可以查看所有报告的遥测信息。日志记录默认为禁用。您" -"可以不使用 `FLWR_TELEMETRY_ENABLED` 而单独使用日志记录,这样就可以在不发送任" -"何指标的情况下检查遥测功能。" +"我们希望能让您轻松查看所报告的匿名使用指标。通过设置环境变量 `FLWR_TELEMETRY_LOGGING=1` " +"可以查看所有报告的遥测信息。日志记录默认为禁用。您可以不使用 `FLWR_TELEMETRY_ENABLED` " +"而单独使用日志记录,这样就可以在不发送任何指标的情况下检查遥测功能。" #: ../../source/ref-telemetry.md:58 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics, " -"use both environment variables:" -msgstr "" -"在不发送任何匿名使用指标的情况下检查 Flower 遥测,可使用这两个环境变量:" +"The inspect Flower telemetry without sending any anonymous usage metrics," +" use both environment variables:" +msgstr "在不发送任何匿名使用指标的情况下检查 Flower 遥测,可使用这两个环境变量:" #: ../../source/ref-telemetry.md:64 msgid "How to contact us" @@ -19807,16 +21236,14 @@ msgid "" "[Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email " "(`telemetry@flower.ai`)." msgstr "" -"我们希望听到您的意见。如果您对如何改进我们处理匿名使用指标的方式有任何反馈或" -"想法,请通过 [Slack](https://flower.ai/join-slack/) (频道 `#telemetry`)或电" -"子邮件 (`telemetry@flower.ai`)与我们联系。" +"我们希望听到您的意见。如果您对如何改进我们处理匿名使用指标的方式有任何反馈或想法,请通过 [Slack](https://flower.ai" +"/join-slack/) (频道 `#telemetry`)或电子邮件 (`telemetry@flower.ai`)与我们联系。" #: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android app " -"using Flower." -msgstr "" -"阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 Android 应用程序。" +"Read this Federated Learning quickstart tutorial for creating an Android " +"app using Flower." +msgstr "阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 Android 应用程序。" #: ../../source/tutorial-quickstart-android.rst:5 msgid "Quickstart Android" @@ -19824,24 +21251,24 @@ msgstr "快速入门 Android" #: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"Let's build a federated learning system using TFLite and Flower on Android!" +"Let's build a federated learning system using TFLite and Flower on " +"Android!" msgstr "让我们在 Android 上使用 TFLite 和 Flower 构建一个联邦学习系统!" #: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ to learn " +"more." msgstr "" -"请参阅`完整代码示例 `_了解更多信息。" +"请参阅`完整代码示例 " +"`_了解更多信息。" #: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"FastAI to train a vision model on CIFAR-10." -msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 FastAI 在 CIFAR-10 上训练" -"视觉模型。" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with FastAI to train a vision model on CIFAR-10." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 FastAI 在 CIFAR-10 上训练视觉模型。" #: ../../source/tutorial-quickstart-fastai.rst:5 msgid "Quickstart fastai" @@ -19853,19 +21280,18 @@ msgstr "让我们用 fastai 和 Flower 建立一个联邦学习系统!" #: ../../source/tutorial-quickstart-fastai.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" -"请参阅 `完整代码示例 `_了解更多信息。" +"请参阅 `完整代码示例 `_了解更多信息。" #: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower with " -"HuggingFace Transformers in order to fine-tune an LLM." -msgstr "" -"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 HuggingFace Transformers " -"来微调 LLM。" +"Check out this Federating Learning quickstart tutorial for using Flower " +"with HuggingFace Transformers in order to fine-tune an LLM." +msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 HuggingFace Transformers 来微调 LLM。" #: ../../source/tutorial-quickstart-huggingface.rst:5 msgid "Quickstart 🤗 Transformers" @@ -19873,21 +21299,20 @@ msgstr "🤗 Transformers快速入门" #: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Let's build a federated learning system using Hugging Face Transformers and " -"Flower!" +"Let's build a federated learning system using Hugging Face Transformers " +"and Flower!" msgstr "让我们用Hugging Face Transformers和Flower来构建一个联邦学习系统!" #: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"We will leverage Hugging Face to federate the training of language models " -"over multiple clients using Flower. More specifically, we will fine-tune a " -"pre-trained Transformer model (distilBERT) for sequence classification over " -"a dataset of IMDB ratings. The end goal is to detect if a movie rating is " -"positive or negative." +"We will leverage Hugging Face to federate the training of language models" +" over multiple clients using Flower. More specifically, we will fine-tune" +" a pre-trained Transformer model (distilBERT) for sequence classification" +" over a dataset of IMDB ratings. The end goal is to detect if a movie " +"rating is positive or negative." msgstr "" -"我们将利用Hugging Face技术,使用 Flower 在多个客户端上联邦训练语言模型。更具" -"体地说,我们将对预先训练好的 Transformer 模型(distilBERT)进行微调,以便在 " -"IMDB 评分数据集上进行序列分类。最终目标是检测电影评分是正面还是负面。" +"我们将利用Hugging Face技术,使用 Flower 在多个客户端上联邦训练语言模型。更具体地说,我们将对预先训练好的 " +"Transformer 模型(distilBERT)进行微调,以便在 IMDB 评分数据集上进行序列分类。最终目标是检测电影评分是正面还是负面。" #: ../../source/tutorial-quickstart-huggingface.rst:18 msgid "Dependencies" @@ -19896,12 +21321,12 @@ msgstr "依赖关系" #: ../../source/tutorial-quickstart-huggingface.rst:20 msgid "" "To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, " -"and :code:`transformers`. This can be done using :code:`pip`:" +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " +":code:`torch`, and :code:`transformers`. This can be done using " +":code:`pip`:" msgstr "" -"要学习本教程,您需要安装以下软件包: :code:`datasets`、 :code:`evaluate`、 :" -"code:`flwr`、 :code:`torch`和 :code:`transformers`。这可以通过 :code:`pip` 来" -"完成:" +"要学习本教程,您需要安装以下软件包: :code:`datasets`、 :code:`evaluate`、 :code:`flwr`、 " +":code:`torch`和 :code:`transformers`。这可以通过 :code:`pip` 来完成:" #: ../../source/tutorial-quickstart-huggingface.rst:30 msgid "Standard Hugging Face workflow" @@ -19917,9 +21342,8 @@ msgid "" "library. We then need to tokenize the data and create :code:`PyTorch` " "dataloaders, this is all done in the :code:`load_data` function:" msgstr "" -"为了获取 IMDB 数据集,我们将使用 Hugging Face 的 :code:`datasets` 库。然后," -"我们需要对数据进行标记化,并创建 :code:`PyTorch` 数据加载器,这些都将在 :" -"code:`load_data` 函数中完成:" +"为了获取 IMDB 数据集,我们将使用 Hugging Face 的 :code:`datasets` 库。然后,我们需要对数据进行标记化,并创建" +" :code:`PyTorch` 数据加载器,这些都将在 :code:`load_data` 函数中完成:" #: ../../source/tutorial-quickstart-huggingface.rst:81 msgid "Training and testing the model" @@ -19927,12 +21351,12 @@ msgstr "训练和测试模型" #: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"Once we have a way of creating our trainloader and testloader, we can take " -"care of the training and testing. This is very similar to any :code:" -"`PyTorch` training or testing loop:" +"Once we have a way of creating our trainloader and testloader, we can " +"take care of the training and testing. This is very similar to any " +":code:`PyTorch` training or testing loop:" msgstr "" -"有了创建 trainloader 和 testloader 的方法后,我们就可以进行训练和测试了。这与" -"任何 :code:`PyTorch` 训练或测试循环都非常相似:" +"有了创建 trainloader 和 testloader 的方法后,我们就可以进行训练和测试了。这与任何 :code:`PyTorch` " +"训练或测试循环都非常相似:" #: ../../source/tutorial-quickstart-huggingface.rst:121 msgid "Creating the model itself" @@ -19940,11 +21364,11 @@ msgstr "创建模型本身" #: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT " -"model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"To create the model itself, we will just load the pre-trained distillBERT" +" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" -"要创建模型本身,我们只需使用 Hugging Face 的 :code:" -"`AutoModelForSequenceClassification` 加载预训练的 distillBERT 模型:" +"要创建模型本身,我们只需使用 Hugging Face 的 :code:`AutoModelForSequenceClassification` " +"加载预训练的 distillBERT 模型:" #: ../../source/tutorial-quickstart-huggingface.rst:136 msgid "Federating the example" @@ -19957,24 +21381,23 @@ msgstr "创建 IMDBClient" #: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" "To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). This " -"is very easy, as our model is a standard :code:`PyTorch` model:" +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " +"This is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" -"要将我们的示例联邦到多个客户端,我们首先需要编写 Flower 客户端类(继承自 :" -"code:`flwr.client.NumPyClient`)。这很容易,因为我们的模型是一个标准的 :code:" -"`PyTorch` 模型:" +"要将我们的示例联邦到多个客户端,我们首先需要编写 Flower 客户端类(继承自 " +":code:`flwr.client.NumPyClient`)。这很容易,因为我们的模型是一个标准的 :code:`PyTorch` 模型:" #: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" "The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the server " -"to send its parameters to the client. Finally, the :code:`fit` function " -"trains the model locally for the client, and the :code:`evaluate` function " -"tests the model locally and returns the relevant metrics." +"parameters. Inversely, the :code:`set_parameters` function allows the " +"server to send its parameters to the client. Finally, the :code:`fit` " +"function trains the model locally for the client, and the " +":code:`evaluate` function tests the model locally and returns the " +"relevant metrics." msgstr "" -":code:`get_parameters` 函数允许服务器获取客户端的参数。相反,:code:" -"`set_parameters`函数允许服务器将其参数发送给客户端。最后,:code:`fit`函数在本" -"地为客户端训练模型,:code:`evaluate`函数在本地测试模型并返回相关指标。" +":code:`get_parameters` " +"函数允许服务器获取客户端的参数。相反,:code:`set_parameters`函数允许服务器将其参数发送给客户端。最后,:code:`fit`函数在本地为客户端训练模型,:code:`evaluate`函数在本地测试模型并返回相关指标。" #: ../../source/tutorial-quickstart-huggingface.rst:175 msgid "Starting the server" @@ -19982,26 +21405,25 @@ msgstr "启动服务器" #: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Now that we have a way to instantiate clients, we need to create our server " -"in order to aggregate the results. Using Flower, this can be done very " -"easily by first choosing a strategy (here, we are using :code:`FedAvg`, " -"which will define the global weights as the average of all the clients' " -"weights at each round) and then using the :code:`flwr.server.start_server` " -"function:" +"Now that we have a way to instantiate clients, we need to create our " +"server in order to aggregate the results. Using Flower, this can be done " +"very easily by first choosing a strategy (here, we are using " +":code:`FedAvg`, which will define the global weights as the average of " +"all the clients' weights at each round) and then using the " +":code:`flwr.server.start_server` function:" msgstr "" -"现在我们有了实例化客户端的方法,我们需要创建服务器,以便汇总结果。使用 " -"Flower,首先选择一个策略(这里我们使用 :code:`FedAvg`,它将把全局模型参数定义" -"为每轮所有客户端模型参数的平均值),然后使用 :code:`flwr.server.start_server`" -"函数,就可以非常轻松地完成这项工作:" +"现在我们有了实例化客户端的方法,我们需要创建服务器,以便汇总结果。使用 Flower,首先选择一个策略(这里我们使用 " +":code:`FedAvg`,它将把全局模型参数定义为每轮所有客户端模型参数的平均值),然后使用 " +":code:`flwr.server.start_server`函数,就可以非常轻松地完成这项工作:" #: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"The :code:`weighted_average` function is there to provide a way to aggregate " -"the metrics distributed amongst the clients (basically this allows us to " -"display a nice average accuracy and loss for every round)." +"The :code:`weighted_average` function is there to provide a way to " +"aggregate the metrics distributed amongst the clients (basically this " +"allows us to display a nice average accuracy and loss for every round)." msgstr "" -"使用 :code:`weighted_average` 函数是为了提供一种方法来汇总分布在客户端的指标" -"(基本上,这可以让我们显示每一轮的平均精度和损失值)。" +"使用 :code:`weighted_average` " +"函数是为了提供一种方法来汇总分布在客户端的指标(基本上,这可以让我们显示每一轮的平均精度和损失值)。" #: ../../source/tutorial-quickstart-huggingface.rst:209 msgid "Putting everything together" @@ -20020,38 +21442,33 @@ msgstr "他们就能连接到服务器,开始联邦训练。" #: ../../source/tutorial-quickstart-huggingface.rst:223 #, fuzzy msgid "" -"If you want to check out everything put together, you should check out the " -"`full code example `_ ." +"If you want to check out everything put together, you should check out " +"the `full code example `_ ." msgstr "" -"如果您想查看所有内容,请查看完整的代码示例: [https://github.com/adap/flower/" -"tree/main/examples/quickstart-huggingface](https://github.com/adap/flower/" -"tree/main/examples/quickstart-huggingface)." +"如果您想查看所有内容,请查看完整的代码示例: [https://github.com/adap/flower/tree/main/examples" +"/quickstart-" +"huggingface](https://github.com/adap/flower/tree/main/examples" +"/quickstart-huggingface)." #: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Of course, this is a very basic example, and a lot can be added or modified, " -"it was just to showcase how simply we could federate a Hugging Face workflow " -"using Flower." -msgstr "" -"当然,这只是一个非常基本的示例,还可以添加或修改很多内容,只是为了展示我们可" -"以如何简单地使用 Flower 联合Hugging Face的工作流程。" +"Of course, this is a very basic example, and a lot can be added or " +"modified, it was just to showcase how simply we could federate a Hugging " +"Face workflow using Flower." +msgstr "当然,这只是一个非常基本的示例,还可以添加或修改很多内容,只是为了展示我们可以如何简单地使用 Flower 联合Hugging Face的工作流程。" #: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very " -"well used :code:`TensorFlow`." -msgstr "" -"请注意,在本例中我们使用了 :code:`PyTorch`,但也完全可以使用 :code:" -"`TensorFlow`。" +"Note that in this example we used :code:`PyTorch`, but we could have very" +" well used :code:`TensorFlow`." +msgstr "请注意,在本例中我们使用了 :code:`PyTorch`,但也完全可以使用 :code:`TensorFlow`。" #: ../../source/tutorial-quickstart-ios.rst:-1 msgid "" "Read this Federated Learning quickstart tutorial for creating an iOS app " "using Flower to train a neural network on MNIST." -msgstr "" -"阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 iOS 应用程序,并在 " -"MNIST 上训练神经网络。" +msgstr "阅读本联邦学习快速入门教程,了解如何使用 Flower 创建 iOS 应用程序,并在 MNIST 上训练神经网络。" #: ../../source/tutorial-quickstart-ios.rst:5 msgid "Quickstart iOS" @@ -20059,59 +21476,49 @@ msgstr "快速入门 iOS" #: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST using " -"Flower and CoreML on iOS devices." -msgstr "" -"在本教程中,我们将学习如何在 iOS 设备上使用 Flower 和 CoreML 在 MNIST 上训练" -"神经网络。" +"In this tutorial we will learn how to train a Neural Network on MNIST " +"using Flower and CoreML on iOS devices." +msgstr "在本教程中,我们将学习如何在 iOS 设备上使用 Flower 和 CoreML 在 MNIST 上训练神经网络。" #: ../../source/tutorial-quickstart-ios.rst:12 #, fuzzy msgid "" "First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv " -"`. For the Flower client " +"create a virtual environment and run everything within a :doc:`virtualenv" +" `. For the Flower client " "implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" "首先,为了运行 Flower Python 服务器,建议创建一个虚拟环境,并在 `virtualenv " -"`_ 中运行一切。对于在 iOS " -"中实现 Flower 客户端,建议使用 Xcode 作为我们的集成开发环境。" +"`_ 中运行一切。对于在 iOS 中实现 " +"Flower 客户端,建议使用 Xcode 作为我们的集成开发环境。" #: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that " -"all have the same model." -msgstr "" -"我们的示例包括一个 Python *服务器*和两个 iPhone *客户端*,它们都具有相同的模" -"型。" +"Our example consists of one Python *server* and two iPhone *clients* that" +" all have the same model." +msgstr "我们的示例包括一个 Python *服务器*和两个 iPhone *客户端*,它们都具有相同的模型。" #: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"*Clients* are responsible for generating individual weight updates for the " -"model based on their local datasets. These updates are then sent to the " -"*server* which will aggregate them to produce a better model. Finally, the " -"*server* sends this improved version of the model back to each *client*. A " -"complete cycle of weight updates is called a *round*." -msgstr "" -"*客户端*负责根据其本地数据集为模型生成独立的模型参数。然后,这些参数更新会被" -"发送到*服务器*,由*服务器*汇总后生成一个更好的模型。最后,*服务器*将改进后的" -"模型发送回每个*客户端*。一个完整的参数更新周期称为一*轮*。" +"*Clients* are responsible for generating individual weight updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." +msgstr "*客户端*负责根据其本地数据集为模型生成独立的模型参数。然后,这些参数更新会被发送到*服务器*,由*服务器*汇总后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客户端*。一个完整的参数更新周期称为一*轮*。" #: ../../source/tutorial-quickstart-ios.rst:21 msgid "" "Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You " -"can do this by using pip:" -msgstr "" -"现在我们已经有了一个大致的概念,让我们开始设置 Flower 服务器环境吧。首先,我" -"们需要安装 Flower。你可以使用 pip 来安装:" +"setup our Flower server environment. We first need to install Flower. You" +" can do this by using pip:" +msgstr "现在我们已经有了一个大致的概念,让我们开始设置 Flower 服务器环境吧。首先,我们需要安装 Flower。你可以使用 pip 来安装:" #: ../../source/tutorial-quickstart-ios.rst:27 msgid "Or Poetry:" msgstr "或者Poetry:" #: ../../source/tutorial-quickstart-ios.rst:34 -#: ../../source/tutorial-quickstart-mxnet.rst:36 #: ../../source/tutorial-quickstart-pytorch.rst:37 #: ../../source/tutorial-quickstart-scikitlearn.rst:40 #: ../../source/tutorial-quickstart-tensorflow.rst:29 @@ -20122,29 +21529,29 @@ msgstr "Flower 客户端" #: ../../source/tutorial-quickstart-ios.rst:36 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and MNIST " -"as our dataset. For simplicity reasons we will use the complete Flower " -"client with CoreML, that has been implemented and stored inside the Swift " -"SDK. The client implementation can be seen below:" +"distributed training using CoreML as our local training pipeline and " +"MNIST as our dataset. For simplicity reasons we will use the complete " +"Flower client with CoreML, that has been implemented and stored inside " +"the Swift SDK. The client implementation can be seen below:" msgstr "" -"现在我们已经安装了所有依赖项,让我们使用 CoreML 作为本地训练框架和 MNIST 作为" -"数据集,运行一个简单的分布式训练。为了简单起见,我们将使用 CoreML 的完整 " -"Flower 客户端,该客户端已在 Swift SDK 中实现并存储。客户端实现如下:" +"现在我们已经安装了所有依赖项,让我们使用 CoreML 作为本地训练框架和 MNIST " +"作为数据集,运行一个简单的分布式训练。为了简单起见,我们将使用 CoreML 的完整 Flower 客户端,该客户端已在 Swift SDK " +"中实现并存储。客户端实现如下:" #: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a " -"dependency in your project. For our application, we will store the logic of " -"our app in :code:`FLiOSModel.swift` and the UI elements in :code:" -"`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift` in this " -"quickstart. Please refer to the `full code example `_ to learn more about the app." +"Let's create a new application project in Xcode and add :code:`flwr` as a" +" dependency in your project. For our application, we will store the logic" +" of our app in :code:`FLiOSModel.swift` and the UI elements in " +":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" +" in this quickstart. Please refer to the `full code example " +"`_ to learn more " +"about the app." msgstr "" -"让我们在 Xcode 中创建一个新的应用程序项目,并在项目中添加 :code:`flwr` 作为依" -"赖关系。对于我们的应用程序,我们将在 :code:`FLiOSModel.swift` 中存储应用程序" -"的逻辑,在 :code:`ContentView.swift` 中存储 UI 元素。在本快速入门中,我们将更" -"多地关注 :code:`FLiOSModel.swift`。请参阅 `完整代码示例 `_ 以了解更多有关应用程序的信息。" +"让我们在 Xcode 中创建一个新的应用程序项目,并在项目中添加 :code:`flwr` 作为依赖关系。对于我们的应用程序,我们将在 " +":code:`FLiOSModel.swift` 中存储应用程序的逻辑,在 :code:`ContentView.swift` 中存储 UI " +"元素。在本快速入门中,我们将更多地关注 :code:`FLiOSModel.swift`。请参阅 `完整代码示例 " +"`_ 以了解更多有关应用程序的信息。" #: ../../source/tutorial-quickstart-ios.rst:75 msgid "Import Flower and CoreML related packages in :code:`FLiOSModel.swift`:" @@ -20153,30 +21560,30 @@ msgstr "在 :code:`FLiOSModel.swift` 中导入 Flower 和 CoreML 相关软件包 #: ../../source/tutorial-quickstart-ios.rst:83 msgid "" "Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS device. " -"We need to pass the url to access mlmodel and run CoreML machine learning " -"processes, it can be retrieved by calling the function :code:`Bundle.main." -"url`. For the MNIST dataset, we need to preprocess it into :code:" -"`MLBatchProvider` object. The preprocessing is done inside :code:`DataLoader." -"swift`." -msgstr "" -"然后通过拖放将 mlmodel 添加到项目中,在部署到 iOS 设备时,mlmodel 将被捆绑到" -"应用程序中。我们需要传递 url 以访问 mlmodel 并运行 CoreML 机器学习进程,可通" -"过调用函数 :code:`Bundle.main.url` 获取。对于 MNIST 数据集,我们需要将其预处" -"理为 :code:`MLBatchProvider` 对象。预处理在 :code:`DataLoader.swift` 中完成。" +"will be bundled inside the application during deployment to your iOS " +"device. We need to pass the url to access mlmodel and run CoreML machine " +"learning processes, it can be retrieved by calling the function " +":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " +"into :code:`MLBatchProvider` object. The preprocessing is done inside " +":code:`DataLoader.swift`." +msgstr "" +"然后通过拖放将 mlmodel 添加到项目中,在部署到 iOS 设备时,mlmodel 将被捆绑到应用程序中。我们需要传递 url 以访问 " +"mlmodel 并运行 CoreML 机器学习进程,可通过调用函数 :code:`Bundle.main.url` 获取。对于 MNIST " +"数据集,我们需要将其预处理为 :code:`MLBatchProvider` 对象。预处理在 :code:`DataLoader.swift` " +"中完成。" #: ../../source/tutorial-quickstart-ios.rst:99 #, fuzzy msgid "" -"Since CoreML does not allow the model parameters to be seen before training, " -"and accessing the model parameters during or after the training can only be " -"done by specifying the layer name, we need to know this information " -"beforehand, through looking at the model specification, which are written as " -"proto files. The implementation can be seen in :code:`MLModelInspect`." +"Since CoreML does not allow the model parameters to be seen before " +"training, and accessing the model parameters during or after the training" +" can only be done by specifying the layer name, we need to know this " +"information beforehand, through looking at the model specification, which" +" are written as proto files. The implementation can be seen in " +":code:`MLModelInspect`." msgstr "" -"由于 CoreML 不允许在训练前查看模型参数,而在训练过程中或训练后访问模型参数只" -"能通过指定层名来完成,因此我们需要事先通过查看模型规范(写成 proto 文件)来了" -"解这些信息。具体实现可参见 :code:`MLModelInspect`。" +"由于 CoreML 不允许在训练前查看模型参数,而在训练过程中或训练后访问模型参数只能通过指定层名来完成,因此我们需要事先通过查看模型规范(写成 " +"proto 文件)来了解这些信息。具体实现可参见 :code:`MLModelInspect`。" #: ../../source/tutorial-quickstart-ios.rst:102 #, fuzzy @@ -20185,4709 +21592,5337 @@ msgid "" "client." msgstr "获得所有必要信息后,让我们创建 Flower 客户端。" -#: ../../source/tutorial-quickstart-ios.rst:117 +#: ../../source/tutorial-quickstart-ios.rst:117 +msgid "" +"Then start the Flower gRPC client and start communicating to the server " +"by passing our Flower client to the function :code:`startFlwrGRPC`." +msgstr "然后启动 Flower gRPC 客户端,并通过将 Flower 客户端传递给函数 :code:`startFlwrGRPC` 来开始与服务器通信。" + +#: ../../source/tutorial-quickstart-ios.rst:124 +msgid "" +"That's it for the client. We only have to implement :code:`Client` or " +"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " +"The attribute :code:`hostname` and :code:`port` tells the client which " +"server to connect to. This can be done by entering the hostname and port " +"in the application before clicking the start button to start the " +"federated learning process." +msgstr "" +"这就是客户端。我们只需实现 :code:`Client` 或调用提供的 :code:`MLFlwrClient` 并调用 " +":code:`startFlwrGRPC()`。属性 :code:`hostname` 和 :code:`port` " +"会告诉客户端要连接到哪个服务器。这可以通过在应用程序中输入主机名和端口来实现,然后再点击开始按钮启动联邦学习进程。" + +#: ../../source/tutorial-quickstart-ios.rst:129 +#: ../../source/tutorial-quickstart-pytorch.rst:203 +#: ../../source/tutorial-quickstart-scikitlearn.rst:167 +#: ../../source/tutorial-quickstart-tensorflow.rst:98 +#: ../../source/tutorial-quickstart-xgboost.rst:309 +msgid "Flower Server" +msgstr "Flower 服务器" + +#: ../../source/tutorial-quickstart-ios.rst:131 +#: ../../source/tutorial-quickstart-pytorch.rst:205 +#: ../../source/tutorial-quickstart-tensorflow.rst:100 +msgid "" +"For simple workloads we can start a Flower server and leave all the " +"configuration possibilities at their default values. In a file named " +":code:`server.py`, import Flower and start the server:" +msgstr "" +"对于简单的工作负载,我们可以启动 Flower 服务器,并将所有配置选项保留为默认值。在名为 :code:`server.py` 的文件中,导入 " +"Flower 并启动服务器:" + +#: ../../source/tutorial-quickstart-ios.rst:142 +#: ../../source/tutorial-quickstart-pytorch.rst:216 +#: ../../source/tutorial-quickstart-scikitlearn.rst:230 +#: ../../source/tutorial-quickstart-tensorflow.rst:112 +msgid "Train the model, federated!" +msgstr "联邦训练模型!" + +#: ../../source/tutorial-quickstart-ios.rst:144 +#: ../../source/tutorial-quickstart-pytorch.rst:218 +#: ../../source/tutorial-quickstart-tensorflow.rst:114 +#: ../../source/tutorial-quickstart-xgboost.rst:525 +msgid "" +"With both client and server ready, we can now run everything and see " +"federated learning in action. FL systems usually have a server and " +"multiple clients. We therefore have to start the server first:" +msgstr "客户端和服务器都已准备就绪,我们现在可以运行一切,看看联邦学习的实际效果。FL 系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" + +#: ../../source/tutorial-quickstart-ios.rst:152 +msgid "" +"Once the server is running we can start the clients in different " +"terminals. Build and run the client through your Xcode, one through Xcode" +" Simulator and the other by deploying it to your iPhone. To see more " +"about how to deploy your app to iPhone or Simulator visit `here " +"`_." +msgstr "" +"服务器运行后,我们就可以在不同的终端启动客户端。通过 Xcode 构建并运行客户端,一个通过 Xcode 模拟器,另一个通过部署到 " +"iPhone。要了解更多有关如何将应用程序部署到 iPhone 或模拟器的信息,请访问 `此处 " +"`_。" + +#: ../../source/tutorial-quickstart-ios.rst:156 +msgid "" +"Congratulations! You've successfully built and run your first federated " +"learning system in your ios device. The full `source code " +"`_ for this " +"example can be found in :code:`examples/ios`." +msgstr "" +"恭喜您! 您已经成功地在 ios 设备中构建并运行了第一个联邦学习系统。本示例的`完整源代码 " +"`_ 可在 " +":code:`examples/ios` 中找到。" + +#: ../../source/tutorial-quickstart-jax.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Jax to train a linear regression model on a scikit-learn dataset." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 Jax 在 scikit-learn 数据集上训练线性回归模型。" + +#: ../../source/tutorial-quickstart-jax.rst:5 +msgid "Quickstart JAX" +msgstr "快速入门 JAX" + +#: ../../source/tutorial-quickstart-pandas.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Pandas to perform Federated Analytics." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 Pandas 执行联邦分析。" + +#: ../../source/tutorial-quickstart-pandas.rst:5 +msgid "Quickstart Pandas" +msgstr "快速入门Pandas" + +#: ../../source/tutorial-quickstart-pandas.rst:10 +msgid "Let's build a federated analytics system using Pandas and Flower!" +msgstr "让我们使用 Pandas 和 Flower 建立一个联邦分析系统!" + +#: ../../source/tutorial-quickstart-pandas.rst:12 +msgid "" +"Please refer to the `full code example " +"`_ " +"to learn more." +msgstr "" +"请参阅 `完整代码示例 `_\" 了解更多信息。" + +#: ../../source/tutorial-quickstart-pytorch.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch to train a CNN model on MNIST." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch 在 MNIST 上训练 CNN 模型。" + +#: ../../source/tutorial-quickstart-pytorch.rst:13 +msgid "" +"In this tutorial we will learn how to train a Convolutional Neural " +"Network on CIFAR10 using Flower and PyTorch." +msgstr "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 CIFAR10 上训练卷积神经网络。" + +#: ../../source/tutorial-quickstart-pytorch.rst:15 +#: ../../source/tutorial-quickstart-xgboost.rst:39 +#, fuzzy +msgid "" +"First of all, it is recommended to create a virtual environment and run " +"everything within a :doc:`virtualenv `." +msgstr "" +"首先,建议创建一个虚拟环境,并在 `virtualenv `_ 中运行一切。" + +#: ../../source/tutorial-quickstart-pytorch.rst:17 +#: ../../source/tutorial-quickstart-scikitlearn.rst:14 +msgid "" +"Our example consists of one *server* and two *clients* all having the " +"same model." +msgstr "我们的例子包括一个*服务器*和两个*客户端*,它们都有相同的模型。" + +#: ../../source/tutorial-quickstart-pytorch.rst:19 +msgid "" +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." +msgstr "*客户端*负责在其本地数据集上更新模型参数。然后,这些参数会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客户端*。一个完整的模型参数更新周期称为一*轮*。" + +#: ../../source/tutorial-quickstart-pytorch.rst:23 +msgid "" +"Now that we have a rough idea of what is going on, let's get started. We " +"first need to install Flower. You can do this by running :" +msgstr "现在,我们已经有了一个大致的概念了,那就让我们开始吧。首先,我们需要安装 Flower。可以通过运行 :" + +#: ../../source/tutorial-quickstart-pytorch.rst:29 +msgid "" +"Since we want to use PyTorch to solve a computer vision task, let's go " +"ahead and install PyTorch and the **torchvision** library:" +msgstr "既然我们想用 PyTorch 解决计算机视觉任务,那就继续安装 PyTorch 和 **torchvision** 库吧:" + +#: ../../source/tutorial-quickstart-pytorch.rst:39 +msgid "" +"Now that we have all our dependencies installed, let's run a simple " +"distributed training with two clients and one server. Our training " +"procedure and network architecture are based on PyTorch's `Deep Learning " +"with PyTorch " +"`_." +msgstr "" +"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练过程和网络架构基于 PyTorch " +"的《Deep Learning with PyTorch " +"`_》。" + +#: ../../source/tutorial-quickstart-pytorch.rst:41 +msgid "" +"In a file called :code:`client.py`, import Flower and PyTorch related " +"packages:" +msgstr "在名为 :code:`client.py` 的文件中,导入 Flower 和 PyTorch 相关软件包:" + +#: ../../source/tutorial-quickstart-pytorch.rst:56 +msgid "In addition, we define the device allocation in PyTorch with:" +msgstr "此外,我们还在 PyTorch 中定义了设备分配:" + +#: ../../source/tutorial-quickstart-pytorch.rst:62 +msgid "" +"We use PyTorch to load CIFAR10, a popular colored image classification " +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " +"the training and test data that are then normalized." +msgstr "" +"我们使用 PyTorch 来加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据集。PyTorch " +":code:`DataLoader()`下载训练数据和测试数据,然后进行归一化处理。" + +#: ../../source/tutorial-quickstart-pytorch.rst:78 +msgid "" +"Define the loss and optimizer with PyTorch. The training of the dataset " +"is done by looping over the dataset, measure the corresponding loss and " +"optimize it." +msgstr "使用 PyTorch 定义损失和优化器。数据集的训练是通过循环数据集、测量相应的损失值并对其进行优化来完成的。" + +#: ../../source/tutorial-quickstart-pytorch.rst:94 +msgid "" +"Define then the validation of the machine learning network. We loop over" +" the test set and measure the loss and accuracy of the test set." +msgstr "然后定义机器学习网络的验证。我们在测试集上循环,计算测试集的损失值和准确率。" + +#: ../../source/tutorial-quickstart-pytorch.rst:113 +msgid "" +"After defining the training and testing of a PyTorch machine learning " +"model, we use the functions for the Flower clients." +msgstr "在定义了 PyTorch 机器学习模型的训练和测试之后,我们将这些功能用于 Flower 客户端。" + +#: ../../source/tutorial-quickstart-pytorch.rst:115 +msgid "" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " +"Minute Blitz':" +msgstr "Flower 客户端将使用一个简单的从“PyTorch: 60 分钟突击\"改编的CNN:" + +#: ../../source/tutorial-quickstart-pytorch.rst:142 +msgid "" +"After loading the data set with :code:`load_data()` we define the Flower " +"interface." +msgstr "使用 :code:`load_data()` 加载数据集后,我们定义了 Flower 接口。" + +#: ../../source/tutorial-quickstart-pytorch.rst:144 +#: ../../source/tutorial-quickstart-tensorflow.rst:54 +msgid "" +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to train the neural network we defined earlier)." +msgstr "" +"Flower 服务器通过一个名为 :code:`Client` " +"的接口与客户端交互。当服务器选择一个特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会调用 :code:`Client`" +" 方法之一来运行您的代码(即训练我们之前定义的神经网络)。" + +#: ../../source/tutorial-quickstart-pytorch.rst:150 +msgid "" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " +"defining the following methods (:code:`set_parameters` is optional " +"though):" +msgstr "" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 PyTorch 时,它使 " +":code:`Client` 接口的实现变得更容易。实现 :code:`NumPyClient` " +"通常意味着定义以下方法(:code:`set_parameters` 是可选的):" + +#: ../../source/tutorial-quickstart-pytorch.rst:156 +#: ../../source/tutorial-quickstart-scikitlearn.rst:119 +msgid "return the model weight as a list of NumPy ndarrays" +msgstr "以 NumPy ndarrays 列表形式返回模型参数" + +#: ../../source/tutorial-quickstart-pytorch.rst:157 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 +msgid ":code:`set_parameters` (optional)" +msgstr ":code:`set_parameters` (可选)" + +#: ../../source/tutorial-quickstart-pytorch.rst:158 +#: ../../source/tutorial-quickstart-scikitlearn.rst:121 +msgid "" +"update the local model weights with the parameters received from the " +"server" +msgstr "用从服务器接收到的参数更新本地模型参数" + +#: ../../source/tutorial-quickstart-pytorch.rst:160 +#: ../../source/tutorial-quickstart-scikitlearn.rst:124 +msgid "set the local model weights" +msgstr "设置本地模型参数" + +#: ../../source/tutorial-quickstart-pytorch.rst:161 +#: ../../source/tutorial-quickstart-scikitlearn.rst:125 +msgid "train the local model" +msgstr "训练本地模型" + +#: ../../source/tutorial-quickstart-pytorch.rst:162 +#: ../../source/tutorial-quickstart-scikitlearn.rst:126 +msgid "receive the updated local model weights" +msgstr "接收更新的本地模型参数" + +#: ../../source/tutorial-quickstart-pytorch.rst:164 +#: ../../source/tutorial-quickstart-scikitlearn.rst:128 +msgid "test the local model" +msgstr "测试本地模型" + +#: ../../source/tutorial-quickstart-pytorch.rst:166 +msgid "which can be implemented in the following way:" +msgstr "可以通过以下方式实现:" + +#: ../../source/tutorial-quickstart-pytorch.rst:189 +#: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"Then start the Flower gRPC client and start communicating to the server by " -"passing our Flower client to the function :code:`startFlwrGRPC`." -msgstr "" -"然后启动 Flower gRPC 客户端,并通过将 Flower 客户端传递给函数 :code:" -"`startFlwrGRPC` 来开始与服务器通信。" +"We can now create an instance of our class :code:`CifarClient` and add " +"one line to actually run this client:" +msgstr "现在我们可以创建一个 :code:`CifarClient` 类的实例,并添加一行来实际运行该客户端:" -#: ../../source/tutorial-quickstart-ios.rst:124 +#: ../../source/tutorial-quickstart-pytorch.rst:196 +#: ../../source/tutorial-quickstart-tensorflow.rst:90 +#, fuzzy msgid "" -"That's it for the client. We only have to implement :code:`Client` or call " -"the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. The " -"attribute :code:`hostname` and :code:`port` tells the client which server to " -"connect to. This can be done by entering the hostname and port in the " -"application before clicking the start button to start the federated learning " -"process." +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " +"the client which server to connect to. In our case we can run the server " +"and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或调用提供的 :code:`MLFlwrClient` " -"并调用 :code:`startFlwrGRPC()`。属性 :code:`hostname` 和 :code:`port` 会告诉" -"客户端要连接到哪个服务器。这可以通过在应用程序中输入主机名和端口来实现,然后" -"再点击开始按钮启动联邦学习进程。" - -#: ../../source/tutorial-quickstart-ios.rst:129 -#: ../../source/tutorial-quickstart-mxnet.rst:226 -#: ../../source/tutorial-quickstart-pytorch.rst:203 -#: ../../source/tutorial-quickstart-scikitlearn.rst:157 -#: ../../source/tutorial-quickstart-tensorflow.rst:98 -#: ../../source/tutorial-quickstart-xgboost.rst:309 -msgid "Flower Server" -msgstr "Flower 服务器" +"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 " +":code:`fl.client.start_client()` 或 " +":code:`fl.client.start_numpy_client()`。字符串 " +":code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此使用 " +":code:`\"[::]:8080\"。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户端指向的 " +":code:`server_address`。" -#: ../../source/tutorial-quickstart-ios.rst:131 -#: ../../source/tutorial-quickstart-mxnet.rst:228 -#: ../../source/tutorial-quickstart-pytorch.rst:205 -#: ../../source/tutorial-quickstart-tensorflow.rst:100 +#: ../../source/tutorial-quickstart-pytorch.rst:226 +#: ../../source/tutorial-quickstart-scikitlearn.rst:239 +#: ../../source/tutorial-quickstart-tensorflow.rst:122 +#: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named :code:" -"`server.py`, import Flower and start the server:" -msgstr "" -"对于简单的工作负载,我们可以启动 Flower 服务器,并将所有配置选项保留为默认" -"值。在名为 :code:`server.py` 的文件中,导入 Flower 并启动服务器:" - -#: ../../source/tutorial-quickstart-ios.rst:142 -#: ../../source/tutorial-quickstart-mxnet.rst:239 -#: ../../source/tutorial-quickstart-pytorch.rst:216 -#: ../../source/tutorial-quickstart-scikitlearn.rst:215 -#: ../../source/tutorial-quickstart-tensorflow.rst:112 -msgid "Train the model, federated!" -msgstr "联邦训练模型!" +"Once the server is running we can start the clients in different " +"terminals. Open a new terminal and start the first client:" +msgstr "服务器运行后,我们就可以在不同终端启动客户端了。打开一个新终端,启动第一个客户端:" -#: ../../source/tutorial-quickstart-ios.rst:144 -#: ../../source/tutorial-quickstart-pytorch.rst:218 -#: ../../source/tutorial-quickstart-tensorflow.rst:114 -#: ../../source/tutorial-quickstart-xgboost.rst:525 -msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and multiple " -"clients. We therefore have to start the server first:" -msgstr "" -"客户端和服务器都已准备就绪,我们现在可以运行一切,看看联邦学习的实际效果。FL " -"系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +#: ../../source/tutorial-quickstart-pytorch.rst:233 +#: ../../source/tutorial-quickstart-scikitlearn.rst:246 +#: ../../source/tutorial-quickstart-tensorflow.rst:129 +#: ../../source/tutorial-quickstart-xgboost.rst:540 +msgid "Open another terminal and start the second client:" +msgstr "打开另一台终端,启动第二个客户端:" -#: ../../source/tutorial-quickstart-ios.rst:152 +#: ../../source/tutorial-quickstart-pytorch.rst:239 +#: ../../source/tutorial-quickstart-scikitlearn.rst:252 +#: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Once the server is running we can start the clients in different terminals. " -"Build and run the client through your Xcode, one through Xcode Simulator and " -"the other by deploying it to your iPhone. To see more about how to deploy " -"your app to iPhone or Simulator visit `here `_." -msgstr "" -"服务器运行后,我们就可以在不同的终端启动客户端。通过 Xcode 构建并运行客户端," -"一个通过 Xcode 模拟器,另一个通过部署到 iPhone。要了解更多有关如何将应用程序" -"部署到 iPhone 或模拟器的信息,请访问 `此处 `_。" +"Each client will have its own dataset. You should now see how the " +"training does in the very first terminal (the one that started the " +"server):" +msgstr "每个客户端都有自己的数据集。现在你应该看到第一个终端(启动服务器的终端)的训练效果了:" -#: ../../source/tutorial-quickstart-ios.rst:156 +#: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code `_ for this example can be found in :" -"code:`examples/ios`." +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples" +"/quickstart-pytorch`." msgstr "" -"恭喜您! 您已经成功地在 ios 设备中构建并运行了第一个联邦学习系统。本示例的`完" -"整源代码 `_ 可在 :" -"code:`examples/ios` 中找到。" +"恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " +"`_ 可以在 :code:`examples/quickstart-pytorch` 中找到。" -#: ../../source/tutorial-quickstart-jax.rst:-1 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"Jax to train a linear regression model on a scikit-learn dataset." -msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 Jax 在 scikit-learn 数据集" -"上训练线性回归模型。" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch Lightning to train an Auto Encoder model on MNIST." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch Lightning 在 MNIST 上训练自动编码器模型。" -#: ../../source/tutorial-quickstart-jax.rst:5 -msgid "Quickstart JAX" -msgstr "快速入门 JAX" +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 +msgid "Quickstart PyTorch Lightning" +msgstr "快速入门 PyTorch Lightning" -#: ../../source/tutorial-quickstart-mxnet.rst:-1 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"MXNet to train a Sequential model on MNIST." -msgstr "" -"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 MXNet 在 MNIST 上训练序列" -"模型。" - -#: ../../source/tutorial-quickstart-mxnet.rst:5 -msgid "Quickstart MXNet" -msgstr "快速入门 MXNet" +"Let's build a horizontal federated learning system using PyTorch " +"Lightning and Flower!" +msgstr "让我们使用 PyTorch Lightning 和 Flower 构建一个水平联邦学习系统!" -#: ../../source/tutorial-quickstart-mxnet.rst:7 +#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"MXNet is no longer maintained and has been moved into `Attic `_. As a result, we would encourage you to " -"use other ML frameworks alongside Flower, for example, PyTorch. This " -"tutorial might be removed in future versions of Flower." +"Please refer to the `full code example " +"`_ to learn more." msgstr "" +"请参阅 `完整代码示例 `_ 了解更多信息。" -#: ../../source/tutorial-quickstart-mxnet.rst:12 +#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with scikit-learn to train a linear regression model." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 scikit-learn 训练线性回归模型。" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:5 +msgid "Quickstart scikit-learn" +msgstr "scikit-learn快速入门" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"In this tutorial, we will learn how to train a :code:`Sequential` model on " -"MNIST using Flower and MXNet." +"In this tutorial, we will learn how to train a :code:`Logistic " +"Regression` model on MNIST using Flower and scikit-learn." msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 MXNet 在 MNIST 上训练 :code:" -"`Sequential` 模型。" +"在本教程中,我们将学习如何使用 Flower 和 scikit-learn 在 MNIST 上训练一个 :code:`Logistic " +"Regression` 模型。" -#: ../../source/tutorial-quickstart-mxnet.rst:14 #: ../../source/tutorial-quickstart-scikitlearn.rst:12 #, fuzzy msgid "" -"It is recommended to create a virtual environment and run everything within " -"this :doc:`virtualenv `." +"It is recommended to create a virtual environment and run everything " +"within this :doc:`virtualenv `." msgstr "" -"建议创建一个虚拟环境,并在此 `virtualenv `_ 中运行所有内容。" +"建议创建一个虚拟环境,并在此 `virtualenv `_ 中运行所有内容。" -#: ../../source/tutorial-quickstart-mxnet.rst:16 -#: ../../source/tutorial-quickstart-pytorch.rst:17 -#: ../../source/tutorial-quickstart-scikitlearn.rst:14 -msgid "" -"Our example consists of one *server* and two *clients* all having the same " -"model." -msgstr "我们的例子包括一个*服务器*和两个*客户端*,它们都有相同的模型。" - -#: ../../source/tutorial-quickstart-mxnet.rst:18 #: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"*Clients* are responsible for generating individual model parameter updates " -"for the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce an updated global model. " -"Finally, the *server* sends this improved version of the model back to each " -"*client*. A complete cycle of parameters updates is called a *round*." -msgstr "" -"*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。然后,这些参数更新" -"将被发送到*服务器*,由*服务器*汇总后生成一个更新的全局模型。最后,*服务器*将" -"这一改进版模型发回给每个*客户端*。一个完整的参数更新周期称为一*轮*。" +"*Clients* are responsible for generating individual model parameter " +"updates for the model based on their local datasets. These updates are " +"then sent to the *server* which will aggregate them to produce an updated" +" global model. Finally, the *server* sends this improved version of the " +"model back to each *client*. A complete cycle of parameters updates is " +"called a *round*." +msgstr "*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。然后,这些参数更新将被发送到*服务器*,由*服务器*汇总后生成一个更新的全局模型。最后,*服务器*将这一改进版模型发回给每个*客户端*。一个完整的参数更新周期称为一*轮*。" -#: ../../source/tutorial-quickstart-mxnet.rst:22 #: ../../source/tutorial-quickstart-scikitlearn.rst:20 msgid "" "Now that we have a rough idea of what is going on, let's get started. We " "first need to install Flower. You can do this by running:" -msgstr "" -"现在,我们已经有了一个大致的概念,让我们开始吧。首先,我们需要安装 Flower。运" -"行:" +msgstr "现在,我们已经有了一个大致的概念,让我们开始吧。首先,我们需要安装 Flower。运行:" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:26 +#, fuzzy +msgid "Since we want to use scikit-learn, let's go ahead and install it:" +msgstr "既然我们要使用 scikt-learn,那就继续安装吧:" -#: ../../source/tutorial-quickstart-mxnet.rst:28 -msgid "Since we want to use MXNet, let's go ahead and install it:" -msgstr "既然我们要使用 MXNet,那就继续安装吧:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:32 +msgid "Or simply install all dependencies using Poetry:" +msgstr "或者直接使用 Poetry 安装所有依赖项:" -#: ../../source/tutorial-quickstart-mxnet.rst:38 +#: ../../source/tutorial-quickstart-scikitlearn.rst:42 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training procedure " -"and network architecture are based on MXNet´s `Hand-written Digit " -"Recognition tutorial `_." +"distributed training with two clients and one server. However, before " +"setting up the client and server, we will define all functionalities that" +" we need for our federated learning setup within :code:`utils.py`. The " +":code:`utils.py` contains different functions defining all the machine " +"learning basics:" msgstr "" -"现在,我们已经安装了所有依赖项,让我们用两个客户端和一个服务器来运行一个简单" -"的分布式训练。我们的训练程序和网络架构基于 MXNet 的 `手写数字识别教程 " -"`_\"。" +"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。不过,在设置客户端和服务器之前,我们将在 " +":code:`utils.py` 中定义联邦学习设置所需的所有功能。:code:`utils.py`包含定义所有机器学习基础知识的不同函数:" -#: ../../source/tutorial-quickstart-mxnet.rst:40 -msgid "" -"In a file called :code:`client.py`, import Flower and MXNet related packages:" -msgstr "在名为 :code:`client.py` 的文件中,导入 Flower 和 MXNet 相关软件包:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:45 +msgid ":code:`get_model_parameters()`" +msgstr ":code:`get_model_parameters()`" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:46 +msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" +msgstr "返回 :code:`sklearn` LogisticRegression 模型的参数" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:47 +msgid ":code:`set_model_params()`" +msgstr ":code:`set_model_params()`" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:48 +#, fuzzy +msgid "Sets the parameters of a :code:`sklearn` LogisticRegression model" +msgstr "设置:code:`sklean`的LogisticRegression模型的参数" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid ":code:`set_initial_params()`" +msgstr ":code:`set_initial_params()`" -#: ../../source/tutorial-quickstart-mxnet.rst:55 -msgid "In addition, define the device allocation in MXNet with:" -msgstr "此外,还可以在 MXNet 中定义设备分配:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:50 +msgid "Initializes the model parameters that the Flower server will ask for" +msgstr "初始化 Flower 服务器将要求的模型参数" -#: ../../source/tutorial-quickstart-mxnet.rst:61 +#: ../../source/tutorial-quickstart-scikitlearn.rst:52 msgid "" -"We use MXNet to load MNIST, a popular image classification dataset of " -"handwritten digits for machine learning. The MXNet utility :code:`mx." -"test_utils.get_mnist()` downloads the training and test data." +"Please check out :code:`utils.py` `here " +"`_ for more details. The pre-defined functions are used in" +" the :code:`client.py` and imported. The :code:`client.py` also requires " +"to import several packages such as Flower and scikit-learn:" msgstr "" -"我们使用 MXNet 加载 MNIST,这是一个用于机器学习的流行手写数字图像分类数据集。" -"MXNet 工具 :code:`mx.test_utils.get_mnist()` 会下载训练和测试数据。" +"更多详情请查看 :code:`utils.py`` 这里 " +"`_。在 :code:`client.py` 中使用并导入了预定义函数。:code:`client.py` " +"还需要导入几个软件包,如 Flower 和 scikit-learn:" -#: ../../source/tutorial-quickstart-mxnet.rst:75 +#: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"Define the training and loss with MXNet. We train the model by looping over " -"the dataset, measure the corresponding loss, and optimize it." +"Prior to local training, we need to load the MNIST dataset, a popular " +"image classification dataset of handwritten digits for machine learning, " +"and partition the dataset for FL. This can be conveniently achieved using" +" `Flower Datasets `_. The " +":code:`FederatedDataset.load_partition()` method loads the partitioned " +"training set for each partition ID defined in the :code:`--partition-id` " +"argument." msgstr "" -"用 MXNet 定义训练和损失值。我们在数据集上循环训练模型,测量相应的损失值,并对" -"其进行优化。" -#: ../../source/tutorial-quickstart-mxnet.rst:113 +#: ../../source/tutorial-quickstart-scikitlearn.rst:95 +msgid "" +"Next, the logistic regression model is defined and initialized with " +":code:`utils.set_initial_params()`." +msgstr "接下来,使用 :code:`utils.set_initial_params()` 对逻辑回归模型进行定义和初始化。" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"Next, we define the validation of our machine learning model. We loop over " -"the test set and measure both loss and accuracy on the test set." +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to fit the logistic regression we defined earlier)." msgstr "" -"接下来,我们定义机器学习模型的验证。我们在测试集上循环,测量测试集上的损失值" -"和准确率。" +"Flower 服务器通过一个名为 :code:`Client` " +"的接口与客户端交互。当服务器选择一个特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会调用 :code:`Client`" +" 方法之一来运行您的代码(即拟合我们之前定义的逻辑回归)。" -#: ../../source/tutorial-quickstart-mxnet.rst:137 +#: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"After defining the training and testing of a MXNet machine learning model, " -"we use these functions to implement a Flower client." +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " +"means defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" -"在定义了 MXNet 机器学习模型的训练和测试后,我们使用这些函数实现了 Flower 客户" -"端。" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当你的工作负载使用 scikit-learn " +"时,它可以让你更容易地实现 :code:`Client` 接口。实现 :code:`NumPyClient` " +"通常意味着定义以下方法(:code:`set_parameters` 是可选的):" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:122 +msgid "is directly imported with :code:`utils.set_model_params()`" +msgstr "直接导入 :code:`utils.set_model_params()`" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:130 +msgid "The methods can be implemented in the following way:" +msgstr "这些方法可以通过以下方式实现:" -#: ../../source/tutorial-quickstart-mxnet.rst:139 -msgid "Our Flower clients will use a simple :code:`Sequential` model:" -msgstr "我们的 Flower 客户端将使用简单的 :code:`Sequential` 模型:" +#: ../../source/tutorial-quickstart-scikitlearn.rst:153 +msgid "" +"We can now create an instance of our class :code:`MnistClient` and add " +"one line to actually run this client:" +msgstr "现在我们可以创建一个 :code:`MnistClient` 类的实例,并添加一行来实际运行该客户端:" -#: ../../source/tutorial-quickstart-mxnet.rst:158 +#: ../../source/tutorial-quickstart-scikitlearn.rst:160 +#, fuzzy msgid "" -"After loading the dataset with :code:`load_data()` we perform one forward " -"propagation to initialize the model and model parameters with :code:" -"`model(init)`. Next, we implement a Flower client." +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" +" the client which server to connect to. In our case we can run the server" +" and the client on the same machine, therefore we use " +":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we pass to the client." msgstr "" -"使用 :code:`load_data()` 加载数据集后,我们会执行一次前向传播,使用 :code:" -"`model(init)` 初始化模型和模型参数。接下来,我们实现一个 Flower 客户端。" +"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 " +":code:`fl.client.start_client()` 或 " +":code:`fl.client.start_numpy_client()`。字符串 " +":code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " +":code:`\"0.0.0.0:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是传递给客户端的" +" :code:`server_address`。" -#: ../../source/tutorial-quickstart-mxnet.rst:160 -#: ../../source/tutorial-quickstart-pytorch.rst:144 -#: ../../source/tutorial-quickstart-tensorflow.rst:54 +#: ../../source/tutorial-quickstart-scikitlearn.rst:169 +msgid "" +"The following Flower server is a little bit more advanced and returns an " +"evaluation function for the server-side evaluation. First, we import " +"again all required libraries such as Flower and scikit-learn." +msgstr "" +"下面的 Flower 服务器更先进一些,会返回一个用于服务器端评估的评估函数。首先,我们再次导入所有需要的库,如 Flower 和 scikit-" +"learn。" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:172 +msgid ":code:`server.py`, import Flower and start the server:" +msgstr ":code:`server.py`, 导入 Flower 并启动服务器:" + +#: ../../source/tutorial-quickstart-scikitlearn.rst:185 +#, fuzzy msgid "" -"The Flower server interacts with clients through an interface called :code:" -"`Client`. When the server selects a particular client for training, it sends " -"training instructions over the network. The client receives those " -"instructions and calls one of the :code:`Client` methods to run your code (i." -"e., to train the neural network we defined earlier)." +"The number of federated learning rounds is set in :code:`fit_round()` and" +" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"function is called after each federated learning round and gives you " +"information about loss and accuracy. Note that we also make use of Flower" +" Datasets here to load the test split of the MNIST dataset for server-" +"side evaluation." msgstr "" -"Flower 服务器通过一个名为 :code:`Client` 的接口与客户端交互。当服务器选择一个" -"特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会" -"调用 :code:`Client` 方法之一来运行您的代码(即训练我们之前定义的神经网络)。" +"联邦学习轮数在 :code:`fit_round()` 中设置,评估在 :code:`get_evaluate_fn()` " +"中定义。每轮联邦学习后都会调用评估函数,并提供有关损失值和准确率的信息。" -#: ../../source/tutorial-quickstart-mxnet.rst:166 +#: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"MXNet. Implementing :code:`NumPyClient` usually means defining the following " -"methods (:code:`set_parameters` is optional though):" +"The :code:`main` contains the server-side parameter initialization " +":code:`utils.set_initial_params()` as well as the aggregation strategy " +":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " +"federated averaging (or FedAvg), with two clients and evaluation after " +"each federated learning round. The server can be started with the command" +" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 MXNet " -"时,它可以让您更轻松地实现 :code:`Client` 接口。实现 :code:`NumPyClient` 通常" -"意味着定义以下方法(:code:`set_parameters` 是可选的):" +":code:`main`包含服务器端参数初始化:code:`utils.set_initial_params()`以及聚合策略 " +":code:`fl.server.strategy:FedAvg()`。该策略是默认的联邦平均(或 " +"FedAvg)策略,有两个客户端,在每轮联邦学习后进行评估。可以使用 " +":code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))` 命令启动服务器。" -#: ../../source/tutorial-quickstart-mxnet.rst:172 -#: ../../source/tutorial-quickstart-pytorch.rst:156 -#: ../../source/tutorial-quickstart-scikitlearn.rst:109 -msgid "return the model weight as a list of NumPy ndarrays" -msgstr "以 NumPy ndarrays 列表形式返回模型参数" +#: ../../source/tutorial-quickstart-scikitlearn.rst:232 +msgid "" +"With both client and server ready, we can now run everything and see " +"federated learning in action. Federated learning systems usually have a " +"server and multiple clients. We, therefore, have to start the server " +"first:" +msgstr "客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" -#: ../../source/tutorial-quickstart-mxnet.rst:173 -#: ../../source/tutorial-quickstart-pytorch.rst:157 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 -msgid ":code:`set_parameters` (optional)" -msgstr ":code:`set_parameters` (可选)" +#: ../../source/tutorial-quickstart-scikitlearn.rst:286 +msgid "" +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples/sklearn-logreg-" +"mnist`." +msgstr "" +"恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " +"`_ 可以在 :code:`examples/sklearn-logreg-mnist` 中找到。" -#: ../../source/tutorial-quickstart-mxnet.rst:174 -#: ../../source/tutorial-quickstart-pytorch.rst:158 -#: ../../source/tutorial-quickstart-scikitlearn.rst:111 +#: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"update the local model weights with the parameters received from the server" -msgstr "用从服务器接收到的参数更新本地模型参数" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with TensorFlow to train a MobilNetV2 model on CIFAR-10." +msgstr "查看此联邦学习快速入门教程,了解如何使用 Flower 和 TensorFlow 在 CIFAR-10 上训练 MobilNetV2 模型。" -#: ../../source/tutorial-quickstart-mxnet.rst:176 -#: ../../source/tutorial-quickstart-pytorch.rst:160 -#: ../../source/tutorial-quickstart-scikitlearn.rst:114 -msgid "set the local model weights" -msgstr "设置本地模型参数" +#: ../../source/tutorial-quickstart-tensorflow.rst:5 +msgid "Quickstart TensorFlow" +msgstr "快速入门 TensorFlow" -#: ../../source/tutorial-quickstart-mxnet.rst:177 -#: ../../source/tutorial-quickstart-pytorch.rst:161 -#: ../../source/tutorial-quickstart-scikitlearn.rst:115 -msgid "train the local model" -msgstr "训练本地模型" +#: ../../source/tutorial-quickstart-tensorflow.rst:13 +msgid "Let's build a federated learning system in less than 20 lines of code!" +msgstr "让我们用不到 20 行代码构建一个联邦学习系统!" -#: ../../source/tutorial-quickstart-mxnet.rst:178 -#: ../../source/tutorial-quickstart-pytorch.rst:162 -#: ../../source/tutorial-quickstart-scikitlearn.rst:116 -msgid "receive the updated local model weights" -msgstr "接收更新的本地模型参数" +#: ../../source/tutorial-quickstart-tensorflow.rst:15 +msgid "Before Flower can be imported we have to install it:" +msgstr "在导入 Flower 之前,我们必须先安装它:" -#: ../../source/tutorial-quickstart-mxnet.rst:180 -#: ../../source/tutorial-quickstart-pytorch.rst:164 -#: ../../source/tutorial-quickstart-scikitlearn.rst:118 -msgid "test the local model" -msgstr "测试本地模型" +#: ../../source/tutorial-quickstart-tensorflow.rst:21 +msgid "" +"Since we want to use the Keras API of TensorFlow (TF), we have to install" +" TF as well:" +msgstr "由于我们要使用 TensorFlow (TF) 的 Keras API,因此还必须安装 TF:" -#: ../../source/tutorial-quickstart-mxnet.rst:182 -msgid "They can be implemented in the following way:" -msgstr "它们可以通过以下方式实现:" +#: ../../source/tutorial-quickstart-tensorflow.rst:31 +msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" +msgstr "接下来,在名为 :code:`client.py` 的文件中导入 Flower 和 TensorFlow:" -#: ../../source/tutorial-quickstart-mxnet.rst:212 +#: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"We can now create an instance of our class :code:`MNISTClient` and add one " -"line to actually run this client:" +"We use the Keras utilities of TF to load CIFAR10, a popular colored image" +" classification dataset for machine learning. The call to " +":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " +"it locally, and then returns the entire training and test set as NumPy " +"ndarrays." msgstr "" -"现在我们可以创建一个 :code:`MNISTClient` 类的实例,并添加一行来实际运行该客户" -"端:" +"我们使用 TF 的 Keras 实用程序加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据集。调用 " +":code:`tf.keras.datasets.cifar10.load_data()` 会下载 CIFAR10,将其缓存到本地,然后以 " +"NumPy ndarrays 的形式返回整个训练集和测试集。" -#: ../../source/tutorial-quickstart-mxnet.rst:219 +#: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"That's it for the client. We only have to implement :code:`Client` or :code:" -"`NumPyClient` and call :code:`fl.client.start_client()` or :code:`fl.client." -"start_numpy_client()`. The string :code:`\"0.0.0.0:8080\"` tells the client " -"which server to connect to. In our case we can run the server and the client " -"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " -"truly federated workload with the server and clients running on different " -"machines, all that needs to change is the :code:`server_address` we pass to " -"the client." -msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" -"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" -"符串 :code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在" -"同一台机器上运行服务器和客户端,因此我们使用 :code:`\"0.0.0.0:8080\"`。如果我" -"们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变" -"的只是传递给客户端的 :code:`server_address`。" +"Next, we need a model. For the purpose of this tutorial, we use " +"MobilNetV2 with 10 output classes:" +msgstr "接下来,我们需要一个模型。在本教程中,我们使用带有 10 个输出类的 MobilNetV2:" -#: ../../source/tutorial-quickstart-mxnet.rst:241 +#: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We therefore have to start the server first:" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses Keras. The :code:`NumPyClient` interface defines three " +"methods which can be implemented in the following way:" msgstr "" -"客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。" -"联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 Keras 时,该类可以更轻松地实现 " +":code:`Client` 接口。:code:`NumPyClient` 接口定义了三个方法,可以通过以下方式实现:" -#: ../../source/tutorial-quickstart-mxnet.rst:249 -#: ../../source/tutorial-quickstart-pytorch.rst:226 -#: ../../source/tutorial-quickstart-scikitlearn.rst:224 -#: ../../source/tutorial-quickstart-tensorflow.rst:122 -#: ../../source/tutorial-quickstart-xgboost.rst:533 +#: ../../source/tutorial-quickstart-tensorflow.rst:135 +msgid "Each client will have its own dataset." +msgstr "每个客户都有自己的数据集。" + +#: ../../source/tutorial-quickstart-tensorflow.rst:137 +msgid "" +"You should now see how the training does in the very first terminal (the " +"one that started the server):" +msgstr "现在你应该能在第一个终端(启动服务器的终端)看到训练的效果了:" + +#: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" -"Once the server is running we can start the clients in different terminals. " -"Open a new terminal and start the first client:" +"Congratulations! You've successfully built and run your first federated " +"learning system. The full `source code " +"`_ for this can be found in :code:`examples" +"/quickstart-tensorflow/client.py`." msgstr "" -"服务器运行后,我们就可以在不同终端启动客户端了。打开一个新终端,启动第一个客" -"户端:" +"恭喜您!您已经成功构建并运行了第一个联邦学习系统。`完整的源代码 " +"`_ 可以在 :code:`examples/quickstart-" +"tensorflow/client.py` 中找到。" -#: ../../source/tutorial-quickstart-mxnet.rst:256 -#: ../../source/tutorial-quickstart-pytorch.rst:233 -#: ../../source/tutorial-quickstart-scikitlearn.rst:231 -#: ../../source/tutorial-quickstart-tensorflow.rst:129 -#: ../../source/tutorial-quickstart-xgboost.rst:540 -msgid "Open another terminal and start the second client:" -msgstr "打开另一台终端,启动第二个客户端:" +#: ../../source/tutorial-quickstart-xgboost.rst:-1 +msgid "" +"Check out this Federated Learning quickstart tutorial for using Flower " +"with XGBoost to train classification models on trees." +msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 XGBoost 上训练分类模型。" -#: ../../source/tutorial-quickstart-mxnet.rst:262 -#: ../../source/tutorial-quickstart-pytorch.rst:239 -#: ../../source/tutorial-quickstart-scikitlearn.rst:237 -#: ../../source/tutorial-quickstart-xgboost.rst:546 +#: ../../source/tutorial-quickstart-xgboost.rst:5 +msgid "Quickstart XGBoost" +msgstr "XGBoost快速入门" + +#: ../../source/tutorial-quickstart-xgboost.rst:14 +msgid "Federated XGBoost" +msgstr "联邦化 XGBoost" + +#: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" -"Each client will have its own dataset. You should now see how the training " -"does in the very first terminal (the one that started the server):" +"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " +"implementation of gradient-boosted decision tree (**GBDT**), that " +"maximises the computational boundaries for boosted tree methods. It's " +"primarily designed to enhance both the performance and computational " +"speed of machine learning models. In XGBoost, trees are constructed " +"concurrently, unlike the sequential approach taken by GBDT." msgstr "" -"每个客户端都有自己的数据集。现在你应该看到第一个终端(启动服务器的终端)的训" -"练效果了:" +"EXtreme Gradient " +"Boosting(**XGBoost**)是梯度提升决策树(**GBDT**)的一种稳健而高效的实现方法,能最大限度地提高提升树方法的计算边界。它主要用于提高机器学习模型的性能和计算速度。在" +" XGBoost 中,决策树是并发构建的,与 GBDT 采用的顺序方法不同。" -#: ../../source/tutorial-quickstart-mxnet.rst:294 +#: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this example can be found " -"in :code:`examples/quickstart-mxnet`." -msgstr "" -"恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可在 :code:`examples/quickstart-mxnet` 中找到。" +"Often, for tabular data on medium-sized datasets with fewer than 10k " +"training examples, XGBoost surpasses the results of deep learning " +"techniques." +msgstr "对于训练示例少于 10k 的中型数据集上的表格数据,XGBoost 的结果往往超过深度学习技术。" -#: ../../source/tutorial-quickstart-pandas.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:23 +msgid "Why federated XGBoost?" +msgstr "为什么选择联邦 XGBoost?" + +#: ../../source/tutorial-quickstart-xgboost.rst:25 +msgid "" +"Indeed, as the demand for data privacy and decentralized learning grows, " +"there's an increasing requirement to implement federated XGBoost systems " +"for specialised applications, like survival analysis and financial fraud " +"detection." +msgstr "事实上,随着对数据隐私和分散学习的需求不断增长,越来越多的专业应用(如生存分析和金融欺诈检测)需要实施联邦 XGBoost 系统。" + +#: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"Pandas to perform Federated Analytics." +"Federated learning ensures that raw data remains on the local device, " +"making it an attractive approach for sensitive domains where data " +"security and privacy are paramount. Given the robustness and efficiency " +"of XGBoost, combining it with federated learning offers a promising " +"solution for these specific challenges." msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 Pandas 执行联邦分析。" +"联邦学习可确保原始数据保留在本地设备上,因此对于数据安全和隐私至关重要的敏感领域来说,这是一种极具吸引力的方法。鉴于 XGBoost " +"的稳健性和高效性,将其与联邦学习相结合为应对这些特定挑战提供了一种前景广阔的解决方案。" -#: ../../source/tutorial-quickstart-pandas.rst:5 -msgid "Quickstart Pandas" -msgstr "快速入门Pandas" +#: ../../source/tutorial-quickstart-xgboost.rst:30 +msgid "" +"In this tutorial we will learn how to train a federated XGBoost model on " +"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " +"example (`full code xgboost-quickstart " +"`_)" +" with two *clients* and one *server* to demonstrate how federated XGBoost" +" works, and then we dive into a more complex example (`full code xgboost-" +"comprehensive `_) to run various experiments." +msgstr "" +"在本教程中,我们将学习如何使用 Flower 和 :code:`xgboost` 软件包在 HIGGS 数据集上训练联邦 XGBoost " +"模型。我们将使用一个包含两个 * 客户端* 和一个 * 服务器* 的简单示例 (`完整代码 xgboost-quickstart " +"`_)来演示联邦 XGBoost 如何工作,然后我们将深入到一个更复杂的示例 (`完整代码 xgboost-" +"comprehensive `_),以运行各种实验。" -#: ../../source/tutorial-quickstart-pandas.rst:10 -msgid "Let's build a federated analytics system using Pandas and Flower!" -msgstr "让我们使用 Pandas 和 Flower 建立一个联邦分析系统!" +#: ../../source/tutorial-quickstart-xgboost.rst:37 +msgid "Environment Setup" +msgstr "环境设定" + +#: ../../source/tutorial-quickstart-xgboost.rst:41 +msgid "" +"We first need to install Flower and Flower Datasets. You can do this by " +"running :" +msgstr "我们首先需要安装 Flower 和 Flower Datasets。您可以通过运行 :" + +#: ../../source/tutorial-quickstart-xgboost.rst:47 +msgid "" +"Since we want to use :code:`xgboost` package to build up XGBoost trees, " +"let's go ahead and install :code:`xgboost`:" +msgstr "既然我们要使用 :code:`xgboost` 软件包来构建 XGBoost 树,那就继续安装 :code:`xgboost`:" -#: ../../source/tutorial-quickstart-pandas.rst:12 +#: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"Please refer to the `full code example `_ to learn more." -msgstr "" -"请参阅 `完整代码示例 `_\" 了解更多信息。" +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. Now that we have all our " +"dependencies installed, let's run a simple distributed training with two " +"clients and one server." +msgstr "*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。" -#: ../../source/tutorial-quickstart-pytorch.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:60 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"PyTorch to train a CNN model on MNIST." -msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch 在 MNIST 上训练 " -"CNN 模型。" +"In a file called :code:`client.py`, import xgboost, Flower, Flower " +"Datasets and other related functions:" +msgstr "在名为 :code:`client.py` 的文件中,导入 xgboost、Flower、Flower Datasets 和其他相关函数:" -#: ../../source/tutorial-quickstart-pytorch.rst:13 +#: ../../source/tutorial-quickstart-xgboost.rst:87 +msgid "Dataset partition and hyper-parameter selection" +msgstr "数据集划分和超参数选择" + +#: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural Network " -"on CIFAR10 using Flower and PyTorch." -msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 CIFAR10 上训练卷积神经网" -"络。" +"Prior to local training, we require loading the HIGGS dataset from Flower" +" Datasets and conduct data partitioning for FL:" +msgstr "在本地训练之前,我们需要从 Flower Datasets 加载 HIGGS 数据集,并对 FL 进行数据分区:" -#: ../../source/tutorial-quickstart-pytorch.rst:15 -#: ../../source/tutorial-quickstart-xgboost.rst:39 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" -"First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"In this example, we split the dataset into two partitions with uniform " +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " +"the partition for the given client based on :code:`node_id`:" msgstr "" -"首先,建议创建一个虚拟环境,并在 `virtualenv `_ 中运行一切。" +"在此示例中,我们将数据集分割成两个均匀分布的分区(:code:`IidPartitioner(num_partitions=2)`)。然后,我们根据" +" :code:`node_id` 为给定客户端加载分区:" -#: ../../source/tutorial-quickstart-pytorch.rst:19 +#: ../../source/tutorial-quickstart-xgboost.rst:121 msgid "" -"*Clients* are responsible for generating individual weight-updates for the " -"model based on their local datasets. These updates are then sent to the " -"*server* which will aggregate them to produce a better model. Finally, the " -"*server* sends this improved version of the model back to each *client*. A " -"complete cycle of weight updates is called a *round*." -msgstr "" -"*客户端*负责在其本地数据集上更新模型参数。然后,这些参数会被发送到*服务器*," -"由*服务器*聚合后生成一个更好的模型。最后,*服务器*将改进后的模型发送回每个*客" -"户端*。一个完整的模型参数更新周期称为一*轮*。" +"After that, we do train/test splitting on the given partition (client's " +"local data), and transform data format for :code:`xgboost` package." +msgstr "然后,我们在给定的分区(客户端的本地数据)上进行训练/测试分割,并为 :code:`xgboost` 软件包转换数据格式。" -#: ../../source/tutorial-quickstart-pytorch.rst:23 +#: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"Now that we have a rough idea of what is going on, let's get started. We " -"first need to install Flower. You can do this by running :" -msgstr "" -"现在,我们已经有了一个大致的概念了,那就让我们开始吧。首先,我们需要安装 " -"Flower。可以通过运行 :" +"The functions of :code:`train_test_split` and " +":code:`transform_dataset_to_dmatrix` are defined as below:" +msgstr ":code:`train_test_split` 和 :code:`transform_dataset_too_dmatrix` 的函数定义如下:" -#: ../../source/tutorial-quickstart-pytorch.rst:29 +#: ../../source/tutorial-quickstart-xgboost.rst:158 +msgid "Finally, we define the hyper-parameters used for XGBoost training." +msgstr "最后,我们定义了用于 XGBoost 训练的超参数。" + +#: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go ahead " -"and install PyTorch and the **torchvision** library:" +"The :code:`num_local_round` represents the number of iterations for local" +" tree boost. We use CPU for the training in default. One can shift it to " +"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " +"evaluation metric." msgstr "" -"既然我们想用 PyTorch 解决计算机视觉任务,那就继续安装 PyTorch 和 " -"**torchvision** 库吧:" +"代码:`num_local_round`表示本地树的迭代次数。我们默认使用 CPU 进行训练。可以通过将 :code:`tree_method` " +"设置为 :code:`gpu_hist`,将其转换为 GPU。我们使用 AUC 作为评估指标。" -#: ../../source/tutorial-quickstart-pytorch.rst:39 +#: ../../source/tutorial-quickstart-xgboost.rst:181 +msgid "Flower client definition for XGBoost" +msgstr "用于 XGBoost 的 Flower 客户端定义" + +#: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training procedure " -"and network architecture are based on PyTorch's `Deep Learning with PyTorch " -"`_." +"After loading the dataset we define the Flower client. We follow the " +"general rule to define :code:`XgbClient` class inherited from " +":code:`fl.client.Client`." msgstr "" -"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单" -"的分布式训练。我们的训练过程和网络架构基于 PyTorch 的《Deep Learning with " -"PyTorch `_》。" +"加载数据集后,我们定义 Flower 客户端。我们按照一般规则定义从 :code:`fl.client.Client` 继承而来的 " +":code:`XgbClient` 类。" -#: ../../source/tutorial-quickstart-pytorch.rst:41 +#: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" -"In a file called :code:`client.py`, import Flower and PyTorch related " -"packages:" -msgstr "在名为 :code:`client.py` 的文件中,导入 Flower 和 PyTorch 相关软件包:" - -#: ../../source/tutorial-quickstart-pytorch.rst:56 -msgid "In addition, we define the device allocation in PyTorch with:" -msgstr "此外,我们还在 PyTorch 中定义了设备分配:" +"The :code:`self.bst` is used to keep the Booster objects that remain " +"consistent across rounds, allowing them to store predictions from trees " +"integrated in earlier rounds and maintain other essential data structures" +" for training." +msgstr "" +"代码:`self.bst`用于保存在各轮中保持一致的 Booster " +"对象,使其能够存储在前几轮中集成的树的预测结果,并维护其他用于训练的重要数据结构。" -#: ../../source/tutorial-quickstart-pytorch.rst:62 +#: ../../source/tutorial-quickstart-xgboost.rst:196 msgid "" -"We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads the " -"training and test data that are then normalized." +"Then, we override :code:`get_parameters`, :code:`fit` and " +":code:`evaluate` methods insides :code:`XgbClient` class as follows." msgstr "" -"我们使用 PyTorch 来加载 CIFAR10,这是一个用于机器学习的流行彩色图像分类数据" -"集。PyTorch :code:`DataLoader()`下载训练数据和测试数据,然后进行归一化处理。" +"然后,我们在 :code:`XgbClient` 类中重写 :code:`get_parameters`、:code:`fit` 和 " +":code:`evaluate` 方法如下。" -#: ../../source/tutorial-quickstart-pytorch.rst:78 +#: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset is " -"done by looping over the dataset, measure the corresponding loss and " -"optimize it." +"Unlike neural network training, XGBoost trees are not started from a " +"specified random weights. In this case, we do not use " +":code:`get_parameters` and :code:`set_parameters` to initialise model " +"parameters for XGBoost. As a result, let's return an empty tensor in " +":code:`get_parameters` when it is called by the server at the first " +"round." msgstr "" -"使用 PyTorch 定义损失和优化器。数据集的训练是通过循环数据集、测量相应的损失值" -"并对其进行优化来完成的。" +"与神经网络训练不同,XGBoost 树不是从指定的随机参数开始的。在这种情况下,我们不使用 :code:`get_parameters` 和 " +":code:`set_parameters` 来初始化 XGBoost 的模型参数。因此,当服务器在第一轮调用 " +":code:`get_parameters` 时,让我们在 :code:`get_parameters` 中返回一个空张量。" -#: ../../source/tutorial-quickstart-pytorch.rst:94 +#: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"Define then the validation of the machine learning network. We loop over " -"the test set and measure the loss and accuracy of the test set." +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " +"up the first set of trees. the returned Booster object and config are " +"stored in :code:`self.bst` and :code:`self.config`, respectively. From " +"the second round, we load the global model sent from server to " +":code:`self.bst`, and then update model weights on local training data " +"with function :code:`local_boost` as follows:" msgstr "" -"然后定义机器学习网络的验证。我们在测试集上循环,计算测试集的损失值和准确率。" +"在 :code:`fit`中,第一轮我们调用 :code:`xgb.train()`来建立第一组树,返回的 Booster 对象和 config " +"分别存储在 :code:`self.bst` 和 :code:`self.config` 中。从第二轮开始,我们将服务器发送的全局模型加载到 " +":code:`self.bst`,然后使用函数 :code:`local_boost`更新本地训练数据的模型权重,如下所示:" -#: ../../source/tutorial-quickstart-pytorch.rst:113 +#: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"After defining the training and testing of a PyTorch machine learning model, " -"we use the functions for the Flower clients." +"Given :code:`num_local_round`, we update trees by calling " +":code:`self.bst.update` method. After training, the last " +":code:`N=num_local_round` trees will be extracted to send to the server." msgstr "" -"在定义了 PyTorch 机器学习模型的训练和测试之后,我们将这些功能用于 Flower 客户" -"端。" +"给定 :code:`num_local_round`,我们通过调用 " +":code:`self.bst.update`方法更新树。训练结束后,我们将提取最后一个 :code:`N=num_local_round` " +"树并发送给服务器。" -#: ../../source/tutorial-quickstart-pytorch.rst:115 +#: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 Minute " -"Blitz':" -msgstr "Flower 客户端将使用一个简单的从“PyTorch: 60 分钟突击\"改编的CNN:" +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " +"conduct evaluation on valid set. The AUC value will be returned." +msgstr "在 :code:`evaluate`中,我们调用 :code:`self.bst.eval_set`函数对有效集合进行评估。将返回 AUC 值。" -#: ../../source/tutorial-quickstart-pytorch.rst:142 +#: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"After loading the data set with :code:`load_data()` we define the Flower " -"interface." -msgstr "使用 :code:`load_data()` 加载数据集后,我们定义了 Flower 接口。" +"Now, we can create an instance of our class :code:`XgbClient` and add one" +" line to actually run this client:" +msgstr "现在,我们可以创建一个 :code:`XgbClient` 类的实例,并添加一行来实际运行该客户端:" -#: ../../source/tutorial-quickstart-pytorch.rst:150 +#: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"PyTorch. Implementing :code:`NumPyClient` usually means defining the " -"following methods (:code:`set_parameters` is optional though):" +"That's it for the client. We only have to implement :code:`Client`and " +"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " +"tells the client which server to connect to. In our case we can run the " +"server and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 " -"PyTorch 时,它使 :code:`Client` 接口的实现变得更容易。实现 :code:" -"`NumPyClient` 通常意味着定义以下方法(:code:`set_parameters` 是可选的):" - -#: ../../source/tutorial-quickstart-pytorch.rst:166 -msgid "which can be implemented in the following way:" -msgstr "可以通过以下方式实现:" +"这就是客户端。我们只需实现 :code:`客户端`并调用 :code:`fl.client.start_client()`。字符串 " +":code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " +":code:`\"[::]:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户端指向的 " +":code:`server_address`。" -#: ../../source/tutorial-quickstart-pytorch.rst:189 -#: ../../source/tutorial-quickstart-tensorflow.rst:82 +#: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add one " -"line to actually run this client:" +"These updates are then sent to the *server* which will aggregate them to " +"produce a better model. Finally, the *server* sends this improved version" +" of the model back to each *client* to finish a complete FL round." msgstr "" -"现在我们可以创建一个 :code:`CifarClient` 类的实例,并添加一行来实际运行该客户" -"端:" +"然后,这些更新会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*服务器*将这个改进版的模型发回给每个*客户端*,以完成一轮完整的" +" FL。" -#: ../../source/tutorial-quickstart-pytorch.rst:196 -#: ../../source/tutorial-quickstart-tensorflow.rst:90 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"That's it for the client. We only have to implement :code:`Client` or :code:" -"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " -"client of type :code:`NumPyClient` you'll need to first call its :code:" -"`to_client()` method. The string :code:`\"[::]:8080\"` tells the client " -"which server to connect to. In our case we can run the server and the client " -"on the same machine, therefore we use :code:`\"[::]:8080\"`. If we run a " -"truly federated workload with the server and clients running on different " -"machines, all that needs to change is the :code:`server_address` we point " -"the client at." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from " +":code:`flwr.server.strategy`." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" -"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" -"符串 :code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同" -"一台机器上运行服务器和客户端,因此使用 :code:`\"[::]:8080\"。如果我们运行的是" -"真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是客户" -"端指向的 :code:`server_address`。" +"在名为 :code:`server.py` 的文件中,从 :code:`flwr.server.strategy` 导入 Flower 和 " +"FedXgbBagging。" -#: ../../source/tutorial-quickstart-pytorch.rst:271 -msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this example can be found " -"in :code:`examples/quickstart-pytorch`." -msgstr "" -"恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可以在 :code:`examples/quickstart-pytorch` 中找到。" +#: ../../source/tutorial-quickstart-xgboost.rst:316 +msgid "We first define a strategy for XGBoost bagging aggregation." +msgstr "我们首先定义了 XGBoost bagging聚合策略。" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"PyTorch Lightning to train an Auto Encoder model on MNIST." +"We use two clients for this example. An " +":code:`evaluate_metrics_aggregation` function is defined to collect and " +"wighted average the AUC values from clients." msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 PyTorch Lightning 在 " -"MNIST 上训练自动编码器模型。" +"本示例使用两个客户端。我们定义了一个 :code:`evaluate_metrics_aggregation` 函数,用于收集客户机的 AUC " +"值并求取平均值。" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 -msgid "Quickstart PyTorch Lightning" -msgstr "快速入门 PyTorch Lightning" +#: ../../source/tutorial-quickstart-xgboost.rst:342 +msgid "Then, we start the server:" +msgstr "然后,我们启动服务器:" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 +#: ../../source/tutorial-quickstart-xgboost.rst:354 +msgid "Tree-based bagging aggregation" +msgstr "基于树的bagging聚合" + +#: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"Let's build a horizontal federated learning system using PyTorch Lightning " -"and Flower!" -msgstr "让我们使用 PyTorch Lightning 和 Flower 构建一个水平联邦学习系统!" +"You must be curious about how bagging aggregation works. Let's look into " +"the details." +msgstr "您一定很好奇bagging聚合是如何工作的。让我们来详细了解一下。" -#: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 +#: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"Please refer to the `full code example `_ to learn more." +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " +":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." +" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " +"and :code:`evaluate` methods as follows:" msgstr "" -"请参阅 `完整代码示例 `_ 了解更多信息。" +"在文件 :code:`flwr.server.strategy.fedxgb_bagging.py`中,我们定义了从 " +":code:`flwr.server.strategy.FedAvg`继承的 :code:`FedXgbBagging`。然后,我们覆盖 " +":code:`aggregate_fit`、:code:`aggregate_evaluate` 和 :code:`evaluate` 方法如下:" -#: ../../source/tutorial-quickstart-scikitlearn.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:454 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"scikit-learn to train a linear regression model." +"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " +"trees by calling :code:`aggregate()` function:" msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 scikit-learn 训练线性回归" -"模型。" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:5 -msgid "Quickstart scikit-learn" -msgstr "scikit-learn快速入门" +"在 :code:`aggregate_fit` 中,我们通过调用 :code:`aggregate()` 函数,按顺序聚合客户端的 XGBoost" +" 树:" -#: ../../source/tutorial-quickstart-scikitlearn.rst:10 +#: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic Regression` " -"model on MNIST using Flower and scikit-learn." +"In this function, we first fetch the number of trees and the number of " +"parallel trees for the current and previous model by calling " +":code:`_get_tree_nums`. Then, the fetched information will be aggregated." +" After that, the trees (containing model weights) are aggregated to " +"generate a new tree model." msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 scikit-learn 在 MNIST 上训练一个 :" -"code:`Logistic Regression` 模型。" +"在该函数中,我们首先通过调用 :code:`_get_tree_nums` " +"获取当前模型和上一个模型的树数和并行树数。然后,对获取的信息进行聚合。然后,聚合树(包含模型参数)生成新的树模型。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:26 -#, fuzzy -msgid "Since we want to use scikit-learn, let's go ahead and install it:" -msgstr "既然我们要使用 scikt-learn,那就继续安装吧:" +#: ../../source/tutorial-quickstart-xgboost.rst:518 +msgid "" +"After traversal of all clients' models, a new global model is generated, " +"followed by the serialisation, and sending back to each client." +msgstr "在遍历所有客户端的模型后,会生成一个新的全局模型,然后进行序列化,并发回给每个客户端。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:32 -msgid "Or simply install all dependencies using Poetry:" -msgstr "或者直接使用 Poetry 安装所有依赖项:" +#: ../../source/tutorial-quickstart-xgboost.rst:523 +msgid "Launch Federated XGBoost!" +msgstr "启动联邦 XGBoost!" -#: ../../source/tutorial-quickstart-scikitlearn.rst:42 +#: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" -"Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that we " -"need for our federated learning setup within :code:`utils.py`. The :code:" -"`utils.py` contains different functions defining all the machine learning " -"basics:" +"Congratulations! You've successfully built and run your first federated " +"XGBoost system. The AUC values can be checked in " +":code:`metrics_distributed`. One can see that the average AUC increases " +"over FL rounds." msgstr "" -"现在我们已经安装了所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单" -"的分布式训练。不过,在设置客户端和服务器之前,我们将在 :code:`utils.py` 中定" -"义联邦学习设置所需的所有功能。:code:`utils.py`包含定义所有机器学习基础知识的" -"不同函数:" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:45 -msgid ":code:`get_model_parameters()`" -msgstr ":code:`get_model_parameters()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:46 -msgid "Returns the parameters of a :code:`sklearn` LogisticRegression model" -msgstr "返回 :code:`sklearn` LogisticRegression 模型的参数" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:47 -msgid ":code:`set_model_params()`" -msgstr ":code:`set_model_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:48 -msgid "Sets the parameters of a :code:`sklean` LogisticRegression model" -msgstr "设置:code:`sklean`的LogisticRegression模型的参数" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:49 -msgid ":code:`set_initial_params()`" -msgstr ":code:`set_initial_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:50 -msgid "Initializes the model parameters that the Flower server will ask for" -msgstr "初始化 Flower 服务器将要求的模型参数" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:51 -msgid ":code:`load_mnist()`" -msgstr ":code:`load_mnist()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:52 -msgid "Loads the MNIST dataset using OpenML" -msgstr "使用 OpenML 加载 MNIST 数据集" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:53 -msgid ":code:`shuffle()`" -msgstr ":code:`shuffle()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:54 -msgid "Shuffles data and its label" -msgstr "对数据及其标签进行洗牌" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid ":code:`partition()`" -msgstr ":code:`partition()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:56 -msgid "Splits datasets into a number of partitions" -msgstr "将数据集分割成多个分区" +"恭喜您!您已成功构建并运行了第一个联邦 XGBoost 系统。可以在 :code:`metrics_distributed` 中查看 AUC " +"值。我们可以看到,平均 AUC 随 FL 轮数的增加而增加。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:58 +#: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"Please check out :code:`utils.py` `here `_ for more details. The pre-" -"defined functions are used in the :code:`client.py` and imported. The :code:" -"`client.py` also requires to import several packages such as Flower and " -"scikit-learn:" +"The full `source code `_ for this example can be found in :code:`examples" +"/xgboost-quickstart`." msgstr "" -"更多详情请查看 :code:`utils.py`` 这里 `_。在 :code:`client.py` 中使用并" -"导入了预定义函数。:code:`client.py` 还需要导入几个软件包,如 Flower 和 " -"scikit-learn:" +"此示例的`完整源代码 `_ 可在 :code:`examples/xgboost-quickstart` 中找到。" + +#: ../../source/tutorial-quickstart-xgboost.rst:594 +msgid "Comprehensive Federated XGBoost" +msgstr "综合的联邦 XGBoost" -#: ../../source/tutorial-quickstart-scikitlearn.rst:73 +#: ../../source/tutorial-quickstart-xgboost.rst:596 #, fuzzy msgid "" -"We load the MNIST dataset from `OpenML `_, a popular image classification dataset of " -"handwritten digits for machine learning. The utility :code:`utils." -"load_mnist()` downloads the training and test data. The training set is " -"split afterwards into 10 partitions with :code:`utils.partition()`." +"Now that you have known how federated XGBoost work with Flower, it's time" +" to run some more comprehensive experiments by customising the " +"experimental settings. In the xgboost-comprehensive example (`full code " +"`_), we provide more options to define various experimental" +" setups, including aggregation strategies, data partitioning and " +"centralised/distributed evaluation. We also support :doc:`Flower " +"simulation ` making it easy to simulate large " +"client cohorts in a resource-aware manner. Let's take a look!" msgstr "" -"我们从 `OpenML `_ 中加载 MNIST 数据集,这是一个" -"用于机器学习的流行手写数字图像分类数据集。实用程序 :code:`utils." -"load_mnist()` 下载训练和测试数据。然后使用 :code:`utils.partition()`将训练集" -"分割成 10 个分区。" +"既然您已经知道联合 XGBoost 如何与 Flower 协同工作,那么现在就该通过自定义实验设置来运行一些更综合的实验了。在 xgboost-" +"comprehensive 示例 (`完整代码 " +"`_)中,我们提供了更多选项来定义各种实验设置,包括数据分区和集中/分布式评估。让我们一起来看看!" -#: ../../source/tutorial-quickstart-scikitlearn.rst:85 -msgid "" -"Next, the logistic regression model is defined and initialized with :code:" -"`utils.set_initial_params()`." -msgstr "" -"接下来,使用 :code:`utils.set_initial_params()` 对逻辑回归模型进行定义和初始" -"化。" +#: ../../source/tutorial-quickstart-xgboost.rst:603 +#, fuzzy +msgid "Cyclic training" +msgstr "集中式训练" -#: ../../source/tutorial-quickstart-scikitlearn.rst:97 +#: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"The Flower server interacts with clients through an interface called :code:" -"`Client`. When the server selects a particular client for training, it sends " -"training instructions over the network. The client receives those " -"instructions and calls one of the :code:`Client` methods to run your code (i." -"e., to fit the logistic regression we defined earlier)." +"In addition to bagging aggregation, we offer a cyclic training scheme, " +"which performs FL in a client-by-client fashion. Instead of aggregating " +"multiple clients, there is only one single client participating in the " +"training per round in the cyclic training scenario. The trained local " +"XGBoost trees will be passed to the next client as an initialised model " +"for next round's boosting." msgstr "" -"Flower 服务器通过一个名为 :code:`Client` 的接口与客户端交互。当服务器选择一个" -"特定的客户端进行训练时,它会通过网络发送训练指令。客户端接收到这些指令后,会" -"调用 :code:`Client` 方法之一来运行您的代码(即拟合我们之前定义的逻辑回归)。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:103 +#: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"scikit-learn. Implementing :code:`NumPyClient` usually means defining the " -"following methods (:code:`set_parameters` is optional though):" +"To do this, we first customise a :code:`ClientManager` in " +":code:`server_utils.py`:" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当你的工作负载使用 " -"scikit-learn 时,它可以让你更容易地实现 :code:`Client` 接口。实现 :code:" -"`NumPyClient` 通常意味着定义以下方法(:code:`set_parameters` 是可选的):" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:112 -msgid "is directly imported with :code:`utils.set_model_params()`" -msgstr "直接导入 :code:`utils.set_model_params()`" - -#: ../../source/tutorial-quickstart-scikitlearn.rst:120 -msgid "The methods can be implemented in the following way:" -msgstr "这些方法可以通过以下方式实现:" -#: ../../source/tutorial-quickstart-scikitlearn.rst:143 +#: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add one " -"line to actually run this client:" +"The customised :code:`ClientManager` samples all available clients in " +"each FL round based on the order of connection to the server. Then, we " +"define a new strategy :code:`FedXgbCyclic` in " +":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " +"select only one client in given round and pass the received model to next" +" client." msgstr "" -"现在我们可以创建一个 :code:`MnistClient` 类的实例,并添加一行来实际运行该客户" -"端:" -#: ../../source/tutorial-quickstart-scikitlearn.rst:150 -#, fuzzy +#: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" -"That's it for the client. We only have to implement :code:`Client` or :code:" -"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " -"client of type :code:`NumPyClient` you'll need to first call its :code:" -"`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells the client " -"which server to connect to. In our case we can run the server and the client " -"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " -"truly federated workload with the server and clients running on different " -"machines, all that needs to change is the :code:`server_address` we pass to " -"the client." +"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " +"Instead, we just make a copy of the received client model as global model" +" by overriding :code:`aggregate_fit`." msgstr "" -"这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient` 并调用 :" -"code:`fl.client.start_client()` 或 :code:`fl.client.start_numpy_client()`。字" -"符串 :code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在" -"同一台机器上运行服务器和客户端,因此我们使用 :code:`\"0.0.0.0:8080\"`。如果我" -"们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变" -"的只是传递给客户端的 :code:`server_address`。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:159 +#: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import again " -"all required libraries such as Flower and scikit-learn." +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" +" methods ensure the clients to be sequentially selected given FL round:" msgstr "" -"下面的 Flower 服务器更先进一些,会返回一个用于服务器端评估的评估函数。首先," -"我们再次导入所有需要的库,如 Flower 和 scikit-learn。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:162 -msgid ":code:`server.py`, import Flower and start the server:" -msgstr ":code:`server.py`, 导入 Flower 并启动服务器:" +#: ../../source/tutorial-quickstart-xgboost.rst:757 +msgid "Customised data partitioning" +msgstr "定制数据分区" -#: ../../source/tutorial-quickstart-scikitlearn.rst:173 +#: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and " -"the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " -"function is called after each federated learning round and gives you " -"information about loss and accuracy." +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" +" to instantiate the data partitioner based on the given " +":code:`num_partitions` and :code:`partitioner_type`. Currently, we " +"provide four supported partitioner type to simulate the uniformity/non-" +"uniformity in data quantity (uniform, linear, square, exponential)." msgstr "" -"联邦学习轮数在 :code:`fit_round()` 中设置,评估在 :code:`get_evaluate_fn()` " -"中定义。每轮联邦学习后都会调用评估函数,并提供有关损失值和准确率的信息。" +"在 :code:`dataset.py` 中,我们有一个函数 :code:`instantiate_partitioner` 来根据给定的 " +":code:`num_partitions` 和 :code:`partitioner_type` " +"来实例化数据分区器。目前,我们提供四种支持的分区器类型(均匀、线性、正方形、指数)来模拟数据量的均匀性/非均匀性。" -#: ../../source/tutorial-quickstart-scikitlearn.rst:198 -msgid "" -"The :code:`main` contains the server-side parameter initialization :code:" -"`utils.set_initial_params()` as well as the aggregation strategy :code:`fl." -"server.strategy:FedAvg()`. The strategy is the default one, federated " -"averaging (or FedAvg), with two clients and evaluation after each federated " -"learning round. The server can be started with the command :code:`fl.server." -"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." -"server.ServerConfig(num_rounds=3))`." -msgstr "" -":code:`main`包含服务器端参数初始化:code:`utils.set_initial_params()`以及聚合" -"策略 :code:`fl.server.strategy:FedAvg()`。该策略是默认的联邦平均(或 FedAvg)" -"策略,有两个客户端,在每轮联邦学习后进行评估。可以使用 :code:`fl.server." -"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." -"server.ServerConfig(num_rounds=3))` 命令启动服务器。" +#: ../../source/tutorial-quickstart-xgboost.rst:790 +msgid "Customised centralised/distributed evaluation" +msgstr "定制的集中/分布式评估" -#: ../../source/tutorial-quickstart-scikitlearn.rst:217 +#: ../../source/tutorial-quickstart-xgboost.rst:792 +#, fuzzy msgid "" -"With both client and server ready, we can now run everything and see " -"federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server first:" -msgstr "" -"客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。" -"联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" +"To facilitate centralised evaluation, we define a function in " +":code:`server_utils.py`:" +msgstr "为便于集中评估,我们在 :code:`server.py` 中定义了一个函数:" -#: ../../source/tutorial-quickstart-scikitlearn.rst:271 +#: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this example can be found in :code:" -"`examples/sklearn-logreg-mnist`." +"This function returns a evaluation function which instantiates a " +":code:`Booster` object and loads the global model weights to it. The " +"evaluation is conducted by calling :code:`eval_set()` method, and the " +"tested AUC value is reported." msgstr "" -"恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " -"`_ 可" -"以在 :code:`examples/sklearn-logreg-mnist` 中找到。" +"此函数返回一个评估函数,该函数实例化一个 :code:`Booster` 对象,并向其加载全局模型参数。评估通过调用 " +":code:`eval_set()` 方法进行,并报告测试的 AUC 值。" -#: ../../source/tutorial-quickstart-tensorflow.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:827 +#, fuzzy msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"TensorFlow to train a MobilNetV2 model on CIFAR-10." +"As for distributed evaluation on the clients, it's same as the quick-" +"start example by overriding the :code:`evaluate()` method insides the " +":code:`XgbClient` class in :code:`client_utils.py`." msgstr "" -"查看此联邦学习快速入门教程,了解如何使用 Flower 和 TensorFlow 在 CIFAR-10 上" -"训练 MobilNetV2 模型。" - -#: ../../source/tutorial-quickstart-tensorflow.rst:5 -msgid "Quickstart TensorFlow" -msgstr "快速入门 TensorFlow" +"至于客户端上的分布式评估,与快速启动示例相同,通过覆盖 :code:`client.py` 中 :code:`XgbClient` 类内部的 " +":code:`evaluate()` 方法。" -#: ../../source/tutorial-quickstart-tensorflow.rst:13 -msgid "Let's build a federated learning system in less than 20 lines of code!" -msgstr "让我们用不到 20 行代码构建一个联邦学习系统!" - -#: ../../source/tutorial-quickstart-tensorflow.rst:15 -msgid "Before Flower can be imported we have to install it:" -msgstr "在导入 Flower 之前,我们必须先安装它:" +#: ../../source/tutorial-quickstart-xgboost.rst:831 +#, fuzzy +msgid "Flower simulation" +msgstr "运行模拟" -#: ../../source/tutorial-quickstart-tensorflow.rst:21 +#: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install TF " -"as well:" -msgstr "由于我们要使用 TensorFlow (TF) 的 Keras API,因此还必须安装 TF:" +"We also provide an example code (:code:`sim.py`) to use the simulation " +"capabilities of Flower to simulate federated XGBoost training on either a" +" single machine or a cluster of machines." +msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:31 -msgid "Next, in a file called :code:`client.py`, import Flower and TensorFlow:" -msgstr "接下来,在名为 :code:`client.py` 的文件中导入 Flower 和 TensorFlow:" +#: ../../source/tutorial-quickstart-xgboost.rst:866 +msgid "" +"After importing all required packages, we define a :code:`main()` " +"function to perform the simulation process:" +msgstr "" -#: ../../source/tutorial-quickstart-tensorflow.rst:38 +#: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image " -"classification dataset for machine learning. The call to :code:`tf.keras." -"datasets.cifar10.load_data()` downloads CIFAR10, caches it locally, and then " -"returns the entire training and test set as NumPy ndarrays." +"We first load the dataset and perform data partitioning, and the pre-" +"processed data is stored in a :code:`list`. After the simulation begins, " +"the clients won't need to pre-process their partitions again." msgstr "" -"我们使用 TF 的 Keras 实用程序加载 CIFAR10,这是一个用于机器学习的流行彩色图像" -"分类数据集。调用 :code:`tf.keras.datasets.cifar10.load_data()` 会下载 " -"CIFAR10,将其缓存到本地,然后以 NumPy ndarrays 的形式返回整个训练集和测试集。" -#: ../../source/tutorial-quickstart-tensorflow.rst:47 +#: ../../source/tutorial-quickstart-xgboost.rst:924 +msgid "Then, we define the strategies and other hyper-parameters:" +msgstr "" + +#: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use MobilNetV2 " -"with 10 output classes:" +"After that, we start the simulation by calling " +":code:`fl.simulation.start_simulation`:" msgstr "" -"接下来,我们需要一个模型。在本教程中,我们使用带有 10 个输出类的 MobilNetV2:" -#: ../../source/tutorial-quickstart-tensorflow.rst:60 +#: ../../source/tutorial-quickstart-xgboost.rst:995 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"Keras. The :code:`NumPyClient` interface defines three methods which can be " -"implemented in the following way:" +"One of key parameters for :code:`start_simulation` is :code:`client_fn` " +"which returns a function to construct a client. We define it as follows:" msgstr "" -"Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用 Keras " -"时,该类可以更轻松地实现 :code:`Client` 接口。:code:`NumPyClient` 接口定义了" -"三个方法,可以通过以下方式实现:" -#: ../../source/tutorial-quickstart-tensorflow.rst:135 -msgid "Each client will have its own dataset." -msgstr "每个客户都有自己的数据集。" +#: ../../source/tutorial-quickstart-xgboost.rst:1038 +msgid "Arguments parser" +msgstr "参数解析器" -#: ../../source/tutorial-quickstart-tensorflow.rst:137 +#: ../../source/tutorial-quickstart-xgboost.rst:1040 +#, fuzzy msgid "" -"You should now see how the training does in the very first terminal (the one " -"that started the server):" -msgstr "现在你应该能在第一个终端(启动服务器的终端)看到训练的效果了:" +"In :code:`utils.py`, we define the arguments parsers for clients, server " +"and simulation, allowing users to specify different experimental " +"settings. Let's first see the sever side:" +msgstr "在 :code:`utils.py` 中,我们定义了客户端和服务器端的参数解析器,允许用户指定不同的实验设置。让我们先看看服务器端:" -#: ../../source/tutorial-quickstart-tensorflow.rst:169 +#: ../../source/tutorial-quickstart-xgboost.rst:1086 +#, fuzzy msgid "" -"Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this can be found in :" -"code:`examples/quickstart-tensorflow/client.py`." +"This allows user to specify training strategies / the number of total " +"clients / FL rounds / participating clients / clients for evaluation, and" +" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" +" will do centralised evaluation and all functionalities for client " +"evaluation will be disabled." msgstr "" -"恭喜您!您已经成功构建并运行了第一个联邦学习系统。`完整的源代码 `_ " -"可以在 :code:`examples/quickstart-tensorflow/client.py` 中找到。" +"这允许用户指定总客户数/FL 轮数/参与客户数/评估客户数以及评估方式。请注意,如果使用 :code:`--centralised-" +"eval`,服务器将进行集中评估,客户端评估的所有功能将被禁用。" -#: ../../source/tutorial-quickstart-xgboost.rst:-1 +#: ../../source/tutorial-quickstart-xgboost.rst:1090 +msgid "Then, the argument parser on client side:" +msgstr "然后是客户端的参数解析器:" + +#: ../../source/tutorial-quickstart-xgboost.rst:1144 +#, fuzzy msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"XGBoost to train classification models on trees." +"This defines various options for client data partitioning. Besides, " +"clients also have an option to conduct evaluation on centralised test set" +" by setting :code:`--centralised-eval`, as well as an option to perform " +"scaled learning rate based on the number of clients by setting :code" +":`--scaled-lr`." +msgstr "这定义了客户端数据分区的各种选项。此外,通过设置 :code:`-centralised-eval`,客户端还可以选择在集中测试集上进行评估。" + +#: ../../source/tutorial-quickstart-xgboost.rst:1148 +msgid "We also have an argument parser for simulation:" msgstr "" -"查看此联邦学习 快速入门教程,了解如何使用 Flower 和 XGBoost 上训练分类模型。" -#: ../../source/tutorial-quickstart-xgboost.rst:5 -msgid "Quickstart XGBoost" -msgstr "XGBoost快速入门" +#: ../../source/tutorial-quickstart-xgboost.rst:1226 +msgid "This integrates all arguments for both client and server sides." +msgstr "" -#: ../../source/tutorial-quickstart-xgboost.rst:14 -msgid "Federated XGBoost" -msgstr "联邦化 XGBoost" +#: ../../source/tutorial-quickstart-xgboost.rst:1229 +msgid "Example commands" +msgstr "命令示例" -#: ../../source/tutorial-quickstart-xgboost.rst:16 +#: ../../source/tutorial-quickstart-xgboost.rst:1231 +#, fuzzy msgid "" -"EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that maximises " -"the computational boundaries for boosted tree methods. It's primarily " -"designed to enhance both the performance and computational speed of machine " -"learning models. In XGBoost, trees are constructed concurrently, unlike the " -"sequential approach taken by GBDT." +"To run a centralised evaluated experiment with bagging strategy on 5 " +"clients with exponential distribution for 50 rounds, we first start the " +"server as below:" +msgstr "为了在 5 个客户端上进行 50 轮指数分布的集中评估实验,我们首先启动服务器,如下所示:" + +#: ../../source/tutorial-quickstart-xgboost.rst:1238 +msgid "Then, on each client terminal, we start the clients:" +msgstr "然后,我们在每个客户终端上启动客户机:" + +#: ../../source/tutorial-quickstart-xgboost.rst:1244 +msgid "To run the same experiment with Flower simulation:" msgstr "" -"EXtreme Gradient Boosting(**XGBoost**)是梯度提升决策树(**GBDT**)的一种稳" -"健而高效的实现方法,能最大限度地提高提升树方法的计算边界。它主要用于提高机器" -"学习模型的性能和计算速度。在 XGBoost 中,决策树是并发构建的,与 GBDT 采用的顺" -"序方法不同。" -#: ../../source/tutorial-quickstart-xgboost.rst:20 +#: ../../source/tutorial-quickstart-xgboost.rst:1250 +#, fuzzy msgid "" -"Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning techniques." +"The full `code `_ for this comprehensive example can be found in" +" :code:`examples/xgboost-comprehensive`." msgstr "" -"对于训练示例少于 10k 的中型数据集上的表格数据,XGBoost 的结果往往超过深度学习" -"技术。" +"此综合示例的全部`源代码 `_ 可在 :code:`examples/xgboost-comprehensive` 中找到。" -#: ../../source/tutorial-quickstart-xgboost.rst:23 -msgid "Why federated XGBoost?" -msgstr "为什么选择联邦 XGBoost?" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 +msgid "Build a strategy from scratch" +msgstr "从零开始制定策略" -#: ../../source/tutorial-quickstart-xgboost.rst:25 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 msgid "" -"Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems for " -"specialised applications, like survival analysis and financial fraud " -"detection." -msgstr "" -"事实上,随着对数据隐私和分散学习的需求不断增长,越来越多的专业应用(如生存分" -"析和金融欺诈检测)需要实施联邦 XGBoost 系统。" +"Welcome to the third part of the Flower federated learning tutorial. In " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__) and we learned how strategies " +"can be used to customize the execution on both the server and the clients" +" (`part 2 `__)." +msgstr "" +"欢迎来到 Flower 联邦学习教程的第三部分。在本教程的前几部分,我们介绍了 PyTorch 和 Flower 的联邦学习(`part 1 " +"`__),并学习了如何使用策略来定制服务器和客户端的执行(`part 2 " +"`__)。" -#: ../../source/tutorial-quickstart-xgboost.rst:27 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"Federated learning ensures that raw data remains on the local device, making " -"it an attractive approach for sensitive domains where data security and " -"privacy are paramount. Given the robustness and efficiency of XGBoost, " -"combining it with federated learning offers a promising solution for these " -"specific challenges." +"In this notebook, we'll continue to customize the federated learning " +"system we built previously by creating a custom version of FedAvg (again," +" using `Flower `__ and `PyTorch " +"`__)." msgstr "" -"联邦学习可确保原始数据保留在本地设备上,因此对于数据安全和隐私至关重要的敏感" -"领域来说,这是一种极具吸引力的方法。鉴于 XGBoost 的稳健性和高效性,将其与联邦" -"学习相结合为应对这些特定挑战提供了一种前景广阔的解决方案。" +"在本笔记中,我们将通过创建 FedAvg 的自定义版本(再次使用 `Flower `__ 和 " +"`PyTorch `__),继续定制我们之前构建的联邦学习系统。" -#: ../../source/tutorial-quickstart-xgboost.rst:30 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"In this tutorial we will learn how to train a federated XGBoost model on " -"HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart `_) with two *clients* and one *server* to " -"demonstrate how federated XGBoost works, and then we dive into a more " -"complex example (`full code xgboost-comprehensive `_) to run various " -"experiments." -msgstr "" -"在本教程中,我们将学习如何使用 Flower 和 :code:`xgboost` 软件包在 HIGGS 数据" -"集上训练联邦 XGBoost 模型。我们将使用一个包含两个 * 客户端* 和一个 * 服务器* " -"的简单示例 (`完整代码 xgboost-quickstart `_)来演示联邦 XGBoost 如何工作,然后我" -"们将深入到一个更复杂的示例 (`完整代码 xgboost-comprehensive `_),以运行各种实" -"验。" +"`Star Flower on GitHub `__ ⭐️ and join " +"the Flower community on Slack to connect, ask questions, and get help: " +"`Join Slack `__ 🌼 We'd love to hear from " +"you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." +msgstr "" +"`Star Flower on GitHub `__ ⭐️ 并加入 Slack " +"上的 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 " +"我们希望在 ``#introductions`` 频道听到您的声音!如果有任何不清楚的地方,请访问 ``#questions`` 频道。" -#: ../../source/tutorial-quickstart-xgboost.rst:37 -msgid "Environment Setup" -msgstr "环境设定" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 +msgid "Let's build a new ``Strategy`` from scratch!" +msgstr "让我们从头开始构建一个新的``Strategy``!" -#: ../../source/tutorial-quickstart-xgboost.rst:41 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 +msgid "Preparation" +msgstr "准备工作" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 msgid "" -"We first need to install Flower and Flower Datasets. You can do this by " -"running :" -msgstr "我们首先需要安装 Flower 和 Flower Datasets。您可以通过运行 :" +"Before we begin with the actual code, let's make sure that we have " +"everything we need." +msgstr "在开始实际代码之前,让我们先确保我们已经准备好了所需的一切。" -#: ../../source/tutorial-quickstart-xgboost.rst:47 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 +msgid "Installing dependencies" +msgstr "安装依赖项" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 +msgid "First, we install the necessary packages:" +msgstr "首先,我们安装必要的软件包:" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 msgid "" -"Since we want to use :code:`xgboost` package to build up XGBoost trees, " -"let's go ahead and install :code:`xgboost`:" -msgstr "" -"既然我们要使用 :code:`xgboost` 软件包来构建 XGBoost 树,那就继续安装 :code:" -"`xgboost`:" +"Now that we have all dependencies installed, we can import everything we " +"need for this tutorial:" +msgstr "现在我们已经安装了所有依赖项,可以导入本教程所需的所有内容:" -#: ../../source/tutorial-quickstart-xgboost.rst:57 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"*Clients* are responsible for generating individual weight-updates for the " -"model based on their local datasets. Now that we have all our dependencies " -"installed, let's run a simple distributed training with two clients and one " -"server." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " +"GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" -"*客户端*负责根据其本地数据集为模型生成单独的模型参数更新。现在我们已经安装了" -"所有的依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。" +"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类型 > 硬件加速: GPU > " +"保存``)。但请注意,Google Colab 并非总能提供 GPU 加速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 " +"``DEVICE = torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU " +"加速,你应该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" -#: ../../source/tutorial-quickstart-xgboost.rst:60 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 +msgid "Data loading" +msgstr "数据加载" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower Datasets " -"and other related functions:" +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``. We introduce a new parameter" +" ``num_clients`` which allows us to call ``load_datasets`` with different" +" numbers of clients." msgstr "" -"在名为 :code:`client.py` 的文件中,导入 xgboost、Flower、Flower Datasets 和其" -"他相关函数:" +"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 " +"个较小的数据集(每个数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` 中。我们引入了一个新参数 " +"``num_clients``,它允许我们使用不同数量的客户端调用 ``load_datasets``。" -#: ../../source/tutorial-quickstart-xgboost.rst:87 -msgid "Dataset partition and hyper-parameter selection" -msgstr "数据集划分和超参数选择" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 +msgid "Model training/evaluation" +msgstr "模型培训/评估" -#: ../../source/tutorial-quickstart-xgboost.rst:89 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower " -"Datasets and conduct data partitioning for FL:" -msgstr "" -"在本地训练之前,我们需要从 Flower Datasets 加载 HIGGS 数据集,并对 FL 进行数" -"据分区:" +"Let's continue with the usual model definition (including " +"``set_parameters`` and ``get_parameters``), training and test functions:" +msgstr "让我们继续使用常见的模型定义(包括 `set_parameters` 和 `get_parameters`)、训练和测试函数:" -#: ../../source/tutorial-quickstart-xgboost.rst:102 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 +msgid "Flower client" +msgstr "Flower 客户端" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load the " -"partition for the given client based on :code:`node_id`:" +"To implement the Flower client, we (again) create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " +"``cid`` to the client and use it log additional details:" msgstr "" -"在此示例中,我们将数据集分割成两个均匀分布的分区(:code:" -"`IidPartitioner(num_partitions=2)`)。然后,我们根据 :code:`node_id` 为给定客" -"户端加载分区:" +"为了实现 Flower 客户端,我们(再次)创建了 ``flwr.client.NumPyClient`` 的子类,并实现了 " +"``get_parameters``、``fit`` 和 ``evaluate``三个方法。在这里,我们还将 ``cid`` " +"传递给客户端,并使用它记录其他详细信息:" -#: ../../source/tutorial-quickstart-xgboost.rst:121 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 +msgid "Let's test what we have so far before we continue:" +msgstr "在继续之前,让我们先测试一下我们目前掌握的情况:" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 +msgid "Build a Strategy from scratch" +msgstr "从零开始构建策略" + +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"After that, we do train/test splitting on the given partition (client's " -"local data), and transform data format for :code:`xgboost` package." +"Let’s overwrite the ``configure_fit`` method such that it passes a higher" +" learning rate (potentially also other hyperparameters) to the optimizer " +"of a fraction of the clients. We will keep the sampling of the clients as" +" it is in ``FedAvg`` and then change the configuration dictionary (one of" +" the ``FitIns`` attributes)." msgstr "" -"然后,我们在给定的分区(客户端的本地数据)上进行训练/测试分割,并为 :code:" -"`xgboost` 软件包转换数据格式。" +"让我们重写 ``configure_fit`` 方法,使其向一部分客户的优化器传递更高的学习率(可能还有其他超参数)。我们将保持 " +"``FedAvg`` 中的客户端采样,然后更改配置字典(``FitIns`` 属性之一)。" -#: ../../source/tutorial-quickstart-xgboost.rst:134 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 msgid "" -"The functions of :code:`train_test_split` and :code:" -"`transform_dataset_to_dmatrix` are defined as below:" -msgstr "" -":code:`train_test_split` 和 :code:`transform_dataset_too_dmatrix` 的函数定义" -"如下:" +"The only thing left is to use the newly created custom Strategy " +"``FedCustom`` when starting the experiment:" +msgstr "剩下的唯一工作就是在启动实验时使用新创建的自定义策略 ``FedCustom`` :" -#: ../../source/tutorial-quickstart-xgboost.rst:158 -msgid "Finally, we define the hyper-parameters used for XGBoost training." -msgstr "最后,我们定义了用于 XGBoost 训练的超参数。" +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 +msgid "Recap" +msgstr "回顾" -#: ../../source/tutorial-quickstart-xgboost.rst:174 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"The :code:`num_local_round` represents the number of iterations for local " -"tree boost. We use CPU for the training in default. One can shift it to GPU " -"by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as evaluation " -"metric." +"In this notebook, we’ve seen how to implement a custom strategy. A custom" +" strategy enables granular control over client node configuration, result" +" aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``." +" To make custom strategies even more powerful, you can pass custom " +"functions to the constructor of your new class (``__init__``) and then " +"call these functions whenever needed." msgstr "" -"代码:`num_local_round`表示本地树的迭代次数。我们默认使用 CPU 进行训练。可以通" -"过将 :code:`tree_method` 设置为 :code:`gpu_hist`,将其转换为 GPU。我们使用 " -"AUC 作为评估指标。" - -#: ../../source/tutorial-quickstart-xgboost.rst:181 -msgid "Flower client definition for XGBoost" -msgstr "用于 XGBoost 的 Flower 客户端定义" +"在本笔记中,我们了解了如何实施自定义策略。自定义策略可以对客户端节点配置、结果聚合等进行细粒度控制。要定义自定义策略,只需覆盖(抽象)基类 " +"``Strategy`` " +"的抽象方法即可。为使自定义策略更加强大,您可以将自定义函数传递给新类的构造函数(`__init__``),然后在需要时调用这些函数。" -#: ../../source/tutorial-quickstart-xgboost.rst:183 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"After loading the dataset we define the Flower client. We follow the general " -"rule to define :code:`XgbClient` class inherited from :code:`fl.client." -"Client`." +"Before you continue, make sure to join the Flower community on Slack: " +"`Join Slack `__" msgstr "" -"加载数据集后,我们定义 Flower 客户端。我们按照一般规则定义从 :code:`fl." -"client.Client` 继承而来的 :code:`XgbClient` 类。" +"在继续之前,请务必加入 Slack 上的 Flower 社区:`Join Slack `__" -#: ../../source/tutorial-quickstart-xgboost.rst:193 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"The :code:`self.bst` is used to keep the Booster objects that remain " -"consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures " -"for training." -msgstr "" -"代码:`self.bst`用于保存在各轮中保持一致的 Booster 对象,使其能够存储在前几轮" -"中集成的树的预测结果,并维护其他用于训练的重要数据结构。" +"There's a dedicated ``#questions`` channel if you need help, but we'd " +"also love to hear who you are in ``#introductions``!" +msgstr "如果您需要帮助,我们有专门的 ``#questions`` 频道,但我们也很乐意在 ``#introductions`` 中了解您是谁!" -#: ../../source/tutorial-quickstart-xgboost.rst:196 +#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and :code:`evaluate` " -"methods insides :code:`XgbClient` class as follows." +"The `Flower Federated Learning Tutorial - Part 4 " +"`__ introduces ``Client``, the flexible API underlying " +"``NumPyClient``." msgstr "" -"然后,我们在 :code:`XgbClient` 类中重写 :code:`get_parameters`、:code:`fit` " -"和 :code:`evaluate` 方法如下。" +"Flower联邦学习教程 - 第4部分 `__ 介绍了``Client``,它是``NumPyClient``底层的灵活应用程序接口。" -#: ../../source/tutorial-quickstart-xgboost.rst:210 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 +msgid "Customize the client" +msgstr "自定义客户端" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use :code:`get_parameters` " -"and :code:`set_parameters` to initialise model parameters for XGBoost. As a " -"result, let's return an empty tensor in :code:`get_parameters` when it is " -"called by the server at the first round." -msgstr "" -"与神经网络训练不同,XGBoost 树不是从指定的随机参数开始的。在这种情况下,我们" -"不使用 :code:`get_parameters` 和 :code:`set_parameters` 来初始化 XGBoost 的模" -"型参数。因此,当服务器在第一轮调用 :code:`get_parameters` 时,让我们在 :code:" -"`get_parameters` 中返回一个空张量。" +"Welcome to the fourth part of the Flower federated learning tutorial. In " +"the previous parts of this tutorial, we introduced federated learning " +"with PyTorch and Flower (`part 1 `__), we learned how " +"strategies can be used to customize the execution on both the server and " +"the clients (`part 2 `__), and we built our own " +"custom strategy from scratch (`part 3 `__)." +msgstr "" +"欢迎来到 Flower 联邦学习教程的第四部分。在本教程的前几部分中,我们介绍了 PyTorch 和 Flower 的联邦学习(`part 1 " +"`__),了解了如何使用策略来定制服务器和客户端的执行(`part 2 " +"`__),并从头开始构建了我们自己的定制策略(`part 3 " +"`__)。" -#: ../../source/tutorial-quickstart-xgboost.rst:251 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build up " -"the first set of trees. the returned Booster object and config are stored " -"in :code:`self.bst` and :code:`self.config`, respectively. From the second " -"round, we load the global model sent from server to :code:`self.bst`, and " -"then update model weights on local training data with function :code:" -"`local_boost` as follows:" +"In this notebook, we revisit ``NumPyClient`` and introduce a new " +"baseclass for building clients, simply named ``Client``. In previous " +"parts of this tutorial, we've based our client on ``NumPyClient``, a " +"convenience class which makes it easy to work with machine learning " +"libraries that have good NumPy interoperability. With ``Client``, we gain" +" a lot of flexibility that we didn't have before, but we'll also have to " +"do a few things the we didn't have to do before." msgstr "" -"在 :code:`fit`中,第一轮我们调用 :code:`xgb.train()`来建立第一组树,返回的 " -"Booster 对象和 config 分别存储在 :code:`self.bst` 和 :code:`self.config` 中。" -"从第二轮开始,我们将服务器发送的全局模型加载到 :code:`self.bst`,然后使用函" -"数 :code:`local_boost`更新本地训练数据的模型权重,如下所示:" +"在本笔记中,我们将重温 ``NumPyClient`` 并引入一个用于构建客户端的新基类,简单命名为 " +"``Client``。在本教程的前几部分中,我们的客户端基于``NumPyClient``,这是一个便捷类,可以让我们轻松地与具有良好 NumPy" +" 互操作性的机器学习库协同工作。有了 ``Client``,我们获得了很多以前没有的灵活性,但我们也必须做一些以前不需要做的事情。" -#: ../../source/tutorial-quickstart-xgboost.rst:269 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 msgid "" -"Given :code:`num_local_round`, we update trees by calling :code:`self.bst." -"update` method. After training, the last :code:`N=num_local_round` trees " -"will be extracted to send to the server." -msgstr "" -"给定 :code:`num_local_round`,我们通过调用 :code:`self.bst.update`方法更新" -"树。训练结束后,我们将提取最后一个 :code:`N=num_local_round` 树并发送给服务" -"器。" +"Let's go deeper and see what it takes to move from ``NumPyClient`` to " +"``Client``!" +msgstr "让我们深入了解一下从 ``NumPyClient`` 到 ``Client`` 的过程!" -#: ../../source/tutorial-quickstart-xgboost.rst:291 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 +msgid "Step 0: Preparation" +msgstr "步骤 0:准备工作" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to conduct " -"evaluation on valid set. The AUC value will be returned." +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``." msgstr "" -"在 :code:`evaluate`中,我们调用 :code:`self.bst.eval_set`函数对有效集合进行评" -"估。将返回 AUC 值。" +"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成十个较小的数据集(每个数据集又分为训练集和验证集),并将所有数据都封装在各自的 " +"``DataLoader`` 中。" -#: ../../source/tutorial-quickstart-xgboost.rst:294 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 +msgid "Step 1: Revisiting NumPyClient" +msgstr "步骤 1:重温 NumPyClient" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one " -"line to actually run this client:" +"So far, we've implemented our client by subclassing " +"``flwr.client.NumPyClient``. The three methods we implemented are " +"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " +"creation of instances of this class in a function called ``client_fn``:" msgstr "" -"现在,我们可以创建一个 :code:`XgbClient` 类的实例,并添加一行来实际运行该客户" -"端:" +"到目前为止,我们通过子类化 ``flwr.client.NumPyClient`` " +"实现了我们的客户端。我们实现了三个方法:``get_parameters``, ``fit`, 和``evaluate``。最后,我们用一个名为 " +"``client_fn`` 的函数来创建该类的实例:" -#: ../../source/tutorial-quickstart-xgboost.rst:300 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 msgid "" -"That's it for the client. We only have to implement :code:`Client`and call :" -"code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` tells the " -"client which server to connect to. In our case we can run the server and the " -"client on the same machine, therefore we use :code:`\"[::]:8080\"`. If we " -"run a truly federated workload with the server and clients running on " -"different machines, all that needs to change is the :code:`server_address` " -"we point the client at." +"We've seen this before, there's nothing new so far. The only *tiny* " +"difference compared to the previous notebook is naming, we've changed " +"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " +"``numpyclient_fn``. Let's run it to see the output we get:" msgstr "" -"这就是客户端。我们只需实现 :code:`客户端`并调用 :code:`fl.client." -"start_client()`。字符串 :code:`\"[::]:8080\"`会告诉客户端要连接的服务器。在本" -"例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 :code:" -"`\"[::]:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同" -"的机器上,那么需要改变的只是客户端指向的 :code:`server_address`。" +"我们以前见过这种情况,目前没有什么新东西。与之前的笔记相比,唯一*小*的不同是命名,我们把 ``FlowerClient`` 改成了 " +"``FlowerNumPyClient``,把 `client_fn` 改成了 ``numpyclient_fn``。让我们运行它看看输出结果:" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 +msgid "" +"This works as expected, two clients are training for three rounds of " +"federated learning." +msgstr "结果不出所料,两个客户端正在进行三轮联邦学习训练。" -#: ../../source/tutorial-quickstart-xgboost.rst:311 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 msgid "" -"These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version of " -"the model back to each *client* to finish a complete FL round." +"Let's dive a little bit deeper and discuss how Flower executes this " +"simulation. Whenever a client is selected to do some work, " +"``start_simulation`` calls the function ``numpyclient_fn`` to create an " +"instance of our ``FlowerNumPyClient`` (along with loading the model and " +"the data)." msgstr "" -"然后,这些更新会被发送到*服务器*,由*服务器*聚合后生成一个更好的模型。最后,*" -"服务器*将这个改进版的模型发回给每个*客户端*,以完成一轮完整的 FL。" +"让我们再深入一点,讨论一下 Flower 是如何执行模拟的。每当一个客户端被选中进行工作时,`start_simulation`` 就会调用函数 " +"`numpyclient_fn` 来创建我们的 ``FlowerNumPyClient`` 实例(同时加载模型和数据)。" -#: ../../source/tutorial-quickstart-xgboost.rst:314 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from :" -"code:`flwr.server.strategy`." -msgstr "" -"在名为 :code:`server.py` 的文件中,从 :code:`flwr.server.strategy` 导入 " -"Flower 和 FedXgbBagging。" - -#: ../../source/tutorial-quickstart-xgboost.rst:316 -msgid "We first define a strategy for XGBoost bagging aggregation." -msgstr "我们首先定义了 XGBoost bagging聚合策略。" +"But here's the perhaps surprising part: Flower doesn't actually use the " +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " +"makes it look like a subclass of ``flwr.client.Client``, not " +"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " +"know how to handle ``NumPyClient``'s, it only knows how to handle " +"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " +"top of ``Client``." +msgstr "" +"但令人惊讶的部分也许就在这里: Flower 实际上并不直接使用 ``FlowerNumPyClient`` " +"对象。相反,它封装了该对象,使其看起来像 ``flwr.client.Client`` 的子类,而不是 " +"``flwr.client.NumPyClient``。事实上,Flower 核心框架不知道如何处理 " +"``NumPyClient``,它只知道如何处理 ``Client``。``NumPyClient`` " +"只是建立在``Client``之上的便捷抽象类。" -#: ../../source/tutorial-quickstart-xgboost.rst:339 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"We use two clients for this example. An :code:`evaluate_metrics_aggregation` " -"function is defined to collect and wighted average the AUC values from " -"clients." -msgstr "" -"本示例使用两个客户端。我们定义了一个 :code:`evaluate_metrics_aggregation` 函" -"数,用于收集客户机的 AUC 值并求取平均值。" +"Instead of building on top of ``NumPyClient``, we can directly build on " +"top of ``Client``." +msgstr "与其在 ``NumPyClient`` 上构建,我们可以直接在 ``Client`` 上构建。" -#: ../../source/tutorial-quickstart-xgboost.rst:342 -msgid "Then, we start the server:" -msgstr "然后,我们启动服务器:" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 +msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" +msgstr "步骤 2:从 ``NumPyClient`` 移至 ``Client``" -#: ../../source/tutorial-quickstart-xgboost.rst:354 -msgid "Tree-based bagging aggregation" -msgstr "基于树的bagging聚合" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 +msgid "" +"Let's try to do the same thing using ``Client`` instead of " +"``NumPyClient``." +msgstr "让我们尝试使用 ``Client`` 代替 ``NumPyClient`` 做同样的事情。" -#: ../../source/tutorial-quickstart-xgboost.rst:356 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"You must be curious about how bagging aggregation works. Let's look into the " -"details." -msgstr "您一定很好奇bagging聚合是如何工作的。让我们来详细了解一下。" +"Before we discuss the code in more detail, let's try to run it! Gotta " +"make sure our new ``Client``-based client works, right?" +msgstr "在详细讨论代码之前,让我们试着运行它!必须确保我们基于 ``Client`` 的新客户端能正常运行,对吗?" -#: ../../source/tutorial-quickstart-xgboost.rst:358 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define :code:" -"`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`. Then, we " -"override the :code:`aggregate_fit`, :code:`aggregate_evaluate` and :code:" -"`evaluate` methods as follows:" -msgstr "" -"在文件 :code:`flwr.server.strategy.fedxgb_bagging.py`中,我们定义了从 :code:" -"`flwr.server.strategy.FedAvg`继承的 :code:`FedXgbBagging`。然后,我们覆盖 :" -"code:`aggregate_fit`、:code:`aggregate_evaluate` 和 :code:`evaluate` 方法如" -"下:" +"That's it, we're now using ``Client``. It probably looks similar to what " +"we've done with ``NumPyClient``. So what's the difference?" +msgstr "就是这样,我们现在开始使用 ``Client``。它看起来可能与我们使用 ``NumPyClient`` 所做的类似。那么有什么不同呢?" -#: ../../source/tutorial-quickstart-xgboost.rst:454 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"In :code:`aggregate_fit`, we sequentially aggregate the clients' XGBoost " -"trees by calling :code:`aggregate()` function:" -msgstr "" -"在 :code:`aggregate_fit` 中,我们通过调用 :code:`aggregate()` 函数,按顺序聚" -"合客户端的 XGBoost 树:" +"First of all, it's more code. But why? The difference comes from the fact" +" that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the " +"network, it eventually needs to turn these parameters into ``bytes``. " +"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"serialization. Turning raw bytes into something more useful (like NumPy " +"``ndarray``'s) is called deserialization. Flower needs to do both: it " +"needs to serialize parameters on the server-side and send them to the " +"client, the client needs to deserialize them to use them for local " +"training, and then serialize the updated parameters again to send them " +"back to the server, which (finally!) deserializes them again in order to " +"aggregate them with the updates received from other clients." +msgstr "" +"首先,它的代码更多。但为什么呢?区别在于 ``Client`` 希望我们处理参数的序列化和反序列化。Flower " +"要想通过网络发送参数,最终需要将这些参数转化为 ``字节``。把参数(例如 NumPy 的 ``ndarray`` " +"参数)变成原始字节叫做序列化。将原始字节转换成更有用的东西(如 NumPy ``ndarray`)称为反序列化。Flower " +"需要同时做这两件事:它需要在服务器端序列化参数并将其发送到客户端,客户端需要反序列化参数以便将其用于本地训练,然后再次序列化更新后的参数并将其发送回服务器,服务器(最后)再次反序列化参数以便将其与从其他客户端接收到的更新汇总在一起。" -#: ../../source/tutorial-quickstart-xgboost.rst:513 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" -"In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling :code:" -"`_get_tree_nums`. Then, the fetched information will be aggregated. After " -"that, the trees (containing model weights) are aggregated to generate a new " -"tree model." +"The only *real* difference between Client and NumPyClient is that " +"NumPyClient takes care of serialization and deserialization for you. It " +"can do so because it expects you to return parameters as NumPy ndarray's," +" and it knows how to handle these. This makes working with machine " +"learning libraries that have good NumPy support (most of them) a breeze." msgstr "" -"在该函数中,我们首先通过调用 :code:`_get_tree_nums` 获取当前模型和上一个模型" -"的树数和并行树数。然后,对获取的信息进行聚合。然后,聚合树(包含模型参数)生" -"成新的树模型。" +"Client 与 NumPyClient 之间的唯一**真正区别在于,NumPyClient " +"会为你处理序列化和反序列化。NumPyClient之所以能做到这一点,是因为它预计你会以NumPy " +"ndarray的形式返回参数,而且它知道如何处理这些参数。这使得与具有良好 NumPy 支持的大多数机器学习库一起工作变得轻而易举。" -#: ../../source/tutorial-quickstart-xgboost.rst:518 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"After traversal of all clients' models, a new global model is generated, " -"followed by the serialisation, and sending back to each client." +"In terms of API, there's one major difference: all methods in Client take" +" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " +"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"``NumPyClient`` on the other hand have multiple arguments (e.g., " +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" +" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These " +"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " +"values you're used to from ``NumPyClient``." msgstr "" -"在遍历所有客户端的模型后,会生成一个新的全局模型,然后进行序列化,并发回给每" -"个客户端。" +"在 API 方面,有一个主要区别:Client 中的所有方法都只接受一个参数(例如,``Client.fit`` 中的 " +"``FitIns``),并只返回一个值(例如,``Client.fit`` 中的 " +"``FitRes``)。另一方面,``NumPyClient``中的方法有多个参数(例如,``NumPyClient.fit``中的``parameters``和``config``)和多个返回值(例如,``NumPyClient.fit``中的``parameters``、``num_example``和``metrics``)。在" +" ``Client`` 中的这些 ``*Ins`` 和 ``*Res`` 对象封装了你在 ``NumPyClient`` 中习惯使用的所有单个值。" -#: ../../source/tutorial-quickstart-xgboost.rst:523 -msgid "Launch Federated XGBoost!" -msgstr "启动联邦 XGBoost!" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 +msgid "Step 3: Custom serialization" +msgstr "步骤 3:自定义序列化" -#: ../../source/tutorial-quickstart-xgboost.rst:585 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 msgid "" -"Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in :code:" -"`metrics_distributed`. One can see that the average AUC increases over FL " -"rounds." -msgstr "" -"恭喜您!您已成功构建并运行了第一个联邦 XGBoost 系统。可以在 :code:" -"`metrics_distributed` 中查看 AUC 值。我们可以看到,平均 AUC 随 FL 轮数的增加" -"而增加。" +"Here we will explore how to implement custom serialization with a simple " +"example." +msgstr "下面我们将通过一个简单的示例来探讨如何实现自定义序列化。" -#: ../../source/tutorial-quickstart-xgboost.rst:590 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 msgid "" -"The full `source code `_ for this example can be found in :code:`examples/" -"xgboost-quickstart`." +"But first what is serialization? Serialization is just the process of " +"converting an object into raw bytes, and equally as important, " +"deserialization is the process of converting raw bytes back into an " +"object. This is very useful for network communication. Indeed, without " +"serialization, you could not just a Python object through the internet." msgstr "" -"此示例的`完整源代码 `_ 可在 :code:`examples/xgboost-quickstart` 中找到。" +"首先,什么是序列化?序列化只是将对象转换为原始字节的过程,同样重要的是,反序列化是将原始字节转换回对象的过程。这对网络通信非常有用。事实上,如果没有序列化,你就无法通过互联网传输一个" +" Python 对象。" -#: ../../source/tutorial-quickstart-xgboost.rst:594 -msgid "Comprehensive Federated XGBoost" -msgstr "综合的联邦 XGBoost" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 +msgid "" +"Federated Learning relies heavily on internet communication for training " +"by sending Python objects back and forth between the clients and the " +"server. This means that serialization is an essential part of Federated " +"Learning." +msgstr "通过在客户端和服务器之间来回发送 Python 对象,联合学习在很大程度上依赖于互联网通信进行训练。这意味着序列化是联邦学习的重要组成部分。" -#: ../../source/tutorial-quickstart-xgboost.rst:596 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time to " -"run some more comprehensive experiments by customising the experimental " -"settings. In the xgboost-comprehensive example (`full code `_), we provide " -"more options to define various experimental setups, including aggregation " -"strategies, data partitioning and centralised/distributed evaluation. We " -"also support :doc:`Flower simulation ` making it " -"easy to simulate large client cohorts in a resource-aware manner. Let's take " -"a look!" +"In the following section, we will write a basic example where instead of " +"sending a serialized version of our ``ndarray``\\ s containing our " +"parameters, we will first convert the ``ndarray`` into sparse matrices, " +"before sending them. This technique can be used to save bandwidth, as in " +"certain cases where the weights of a model are sparse (containing many 0 " +"entries), converting them to a sparse matrix can greatly improve their " +"bytesize." msgstr "" -"既然您已经知道联合 XGBoost 如何与 Flower 协同工作,那么现在就该通过自定义实验" -"设置来运行一些更综合的实验了。在 xgboost-comprehensive 示例 (`完整代码 " -"`_)" -"中,我们提供了更多选项来定义各种实验设置,包括数据分区和集中/分布式评估。让我" -"们一起来看看!" +"在下面的章节中,我们将编写一个基本示例,在发送包含参数的 ``ndarray`` 前,我们将首先把 ``ndarray`` " +"转换为稀疏矩阵,而不是发送序列化版本。这种技术可以用来节省带宽,因为在某些情况下,模型的参数是稀疏的(包含许多 0 " +"条目),将它们转换成稀疏矩阵可以大大提高它们的字节数。" -#: ../../source/tutorial-quickstart-xgboost.rst:603 -#, fuzzy -msgid "Cyclic training" -msgstr "集中式训练" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 +msgid "Our custom serialization/deserialization functions" +msgstr "我们的定制序列化/反序列化功能" -#: ../../source/tutorial-quickstart-xgboost.rst:605 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, which " -"performs FL in a client-by-client fashion. Instead of aggregating multiple " -"clients, there is only one single client participating in the training per " -"round in the cyclic training scenario. The trained local XGBoost trees will " -"be passed to the next client as an initialised model for next round's " -"boosting." +"This is where the real serialization/deserialization will happen, " +"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"``sparse_bytes_to_ndarray`` for deserialization." msgstr "" +"这才是真正的序列化/反序列化,尤其是在用于序列化的 ``ndarray_too_sparse_bytes`` 和用于反序列化的 " +"``sparse_bytes_too_ndarray`` 中。" -#: ../../source/tutorial-quickstart-xgboost.rst:609 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"To do this, we first customise a :code:`ClientManager` in :code:" -"`server_utils.py`:" -msgstr "" +"Note that we imported the ``scipy.sparse`` library in order to convert " +"our arrays." +msgstr "请注意,为了转换数组,我们导入了 ``scipy.sparse`` 库。" -#: ../../source/tutorial-quickstart-xgboost.rst:649 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 +msgid "Client-side" +msgstr "客户端" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"The customised :code:`ClientManager` samples all available clients in each " -"FL round based on the order of connection to the server. Then, we define a " -"new strategy :code:`FedXgbCyclic` in :code:`flwr.server.strategy." -"fedxgb_cyclic.py`, in order to sequentially select only one client in given " -"round and pass the received model to next client." -msgstr "" +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " +"will just have to call our custom functions in our " +"``flwr.client.Client``." +msgstr "为了能够将我们的 ``ndarray`` 序列化为稀疏参数,我们只需在 ``flwr.client.Client`` 中调用我们的自定义函数。" -#: ../../source/tutorial-quickstart-xgboost.rst:690 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 msgid "" -"Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model by " -"overriding :code:`aggregate_fit`." +"Indeed, in ``get_parameters`` we need to serialize the parameters we got " +"from our network using our custom ``ndarrays_to_sparse_parameters`` " +"defined above." msgstr "" +"事实上,在 `get_parameters` 中,我们需要使用上文定义的自定义 `ndarrays_too_sparse_parameters` " +"序列化从网络中获取的参数。" -#: ../../source/tutorial-quickstart-xgboost.rst:693 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate` " -"methods ensure the clients to be sequentially selected given FL round:" +"In ``fit``, we first need to deserialize the parameters coming from the " +"server using our custom ``sparse_parameters_to_ndarrays`` and then we " +"need to serialize our local results with " +"``ndarrays_to_sparse_parameters``." msgstr "" +"在 ``fit`` 中,我们首先需要使用自定义的 ``sparse_parameters_to_ndarrays`` " +"反序列化来自服务器的参数,然后使用 ``ndarrays_to_sparse_parameters`` 序列化本地结果。" -#: ../../source/tutorial-quickstart-xgboost.rst:757 -msgid "Customised data partitioning" -msgstr "定制数据分区" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +msgid "" +"In ``evaluate``, we will only need to deserialize the global parameters " +"with our custom function." +msgstr "在 ``evaluate`` 中,我们只需要用自定义函数反序列化全局参数。" -#: ../../source/tutorial-quickstart-xgboost.rst:759 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 +msgid "Server-side" +msgstr "服务器端" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner` to " -"instantiate the data partitioner based on the given :code:`num_partitions` " -"and :code:`partitioner_type`. Currently, we provide four supported " -"partitioner type to simulate the uniformity/non-uniformity in data quantity " -"(uniform, linear, square, exponential)." +"For this example, we will just use ``FedAvg`` as a strategy. To change " +"the serialization and deserialization here, we only need to reimplement " +"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" +" functions of the strategy will be inherited from the super class " +"``FedAvg``." msgstr "" -"在 :code:`dataset.py` 中,我们有一个函数 :code:`instantiate_partitioner` 来根" -"据给定的 :code:`num_partitions` 和 :code:`partitioner_type` 来实例化数据分区" -"器。目前,我们提供四种支持的分区器类型(均匀、线性、正方形、指数)来模拟数据" -"量的均匀性/非均匀性。" +"在本例中,我们将只使用 ``FedAvg`` 作为策略。要改变这里的序列化和反序列化,我们只需重新实现 ``FedAvg`` 的 " +"``evaluate`` 和 ``aggregate_fit`` 函数。策略的其他函数将从超类 ``FedAvg`` 继承。" -#: ../../source/tutorial-quickstart-xgboost.rst:790 -msgid "Customised centralised/distributed evaluation" -msgstr "定制的集中/分布式评估" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 +msgid "As you can see only one line as change in ``evaluate``:" +msgstr "正如你所看到的,``evaluate``中只修改了一行:" -#: ../../source/tutorial-quickstart-xgboost.rst:792 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 msgid "" -"To facilitate centralised evaluation, we define a function in :code:" -"`server_utils.py`:" -msgstr "为便于集中评估,我们在 :code:`server.py` 中定义了一个函数:" +"And for ``aggregate_fit``, we will first deserialize every result we " +"received:" +msgstr "而对于 ``aggregate_fit``,我们将首先反序列化收到的每个结果:" -#: ../../source/tutorial-quickstart-xgboost.rst:824 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 +msgid "And then serialize the aggregated result:" +msgstr "然后将汇总结果序列化:" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 +msgid "We can now run our custom serialization example!" +msgstr "现在我们可以运行自定义序列化示例!" + +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 msgid "" -"This function returns a evaluation function which instantiates a :code:" -"`Booster` object and loads the global model weights to it. The evaluation is " -"conducted by calling :code:`eval_set()` method, and the tested AUC value is " -"reported." +"In this part of the tutorial, we've seen how we can build clients by " +"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " +"convenience abstraction that makes it easier to work with machine " +"learning libraries that have good NumPy interoperability. ``Client`` is a" +" more flexible abstraction that allows us to do things that are not " +"possible in ``NumPyClient``. In order to do so, it requires us to handle " +"parameter serialization and deserialization ourselves." msgstr "" -"此函数返回一个评估函数,该函数实例化一个 :code:`Booster` 对象,并向其加载全局" -"模型参数。评估通过调用 :code:`eval_set()` 方法进行,并报告测试的 AUC 值。" +"在本部分教程中,我们已经了解了如何通过子类化 ``NumPyClient`` 或 ``Client`` 来构建客户端。NumPyClient " +"\"是一个便捷的抽象类,可以让我们更容易地与具有良好NumPy互操作性的机器学习库一起工作。``Client``是一个更灵活的抽象类,允许我们做一些在`NumPyClient``中做不到的事情。为此,它要求我们自己处理参数序列化和反序列化。" -#: ../../source/tutorial-quickstart-xgboost.rst:827 -#, fuzzy +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"As for distributed evaluation on the clients, it's same as the quick-start " -"example by overriding the :code:`evaluate()` method insides the :code:" -"`XgbClient` class in :code:`client_utils.py`." -msgstr "" -"至于客户端上的分布式评估,与快速启动示例相同,通过覆盖 :code:`client.py` 中 :" -"code:`XgbClient` 类内部的 :code:`evaluate()` 方法。" +"This is the final part of the Flower tutorial (for now!), " +"congratulations! You're now well equipped to understand the rest of the " +"documentation. There are many topics we didn't cover in the tutorial, we " +"recommend the following resources:" +msgstr "这暂时是 Flower 教程的最后一部分,恭喜您!您现在已经具备了理解其余文档的能力。本教程还有许多内容没有涉及,我们推荐您参考以下资源:" -#: ../../source/tutorial-quickstart-xgboost.rst:831 -#, fuzzy -msgid "Flower simulation" -msgstr "运行模拟" +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 +msgid "`Read Flower Docs `__" +msgstr "阅读Flower文档 `__" -#: ../../source/tutorial-quickstart-xgboost.rst:832 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a " -"single machine or a cluster of machines." -msgstr "" +"`Check out Flower Code Examples " +"`__" +msgstr "查看 Flower 代码示例 `__" -#: ../../source/tutorial-quickstart-xgboost.rst:866 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"After importing all required packages, we define a :code:`main()` function " -"to perform the simulation process:" -msgstr "" +"`Use Flower Baselines for your research " +"`__" +msgstr "使用 \"Flower Baselines \"进行研究 `__" -#: ../../source/tutorial-quickstart-xgboost.rst:921 +#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, the " -"clients won't need to pre-process their partitions again." -msgstr "" +"`Watch Flower Summit 2023 videos `__" +msgstr "观看 2023 年Flower峰会视频 `__" -#: ../../source/tutorial-quickstart-xgboost.rst:924 -msgid "Then, we define the strategies and other hyper-parameters:" -msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 +msgid "Get started with Flower" +msgstr "开始使用Flower" -#: ../../source/tutorial-quickstart-xgboost.rst:975 -msgid "" -"After that, we start the simulation by calling :code:`fl.simulation." -"start_simulation`:" -msgstr "" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 +msgid "Welcome to the Flower federated learning tutorial!" +msgstr "欢迎阅读Flower联邦学习教程!" -#: ../../source/tutorial-quickstart-xgboost.rst:995 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 +#, fuzzy msgid "" -"One of key parameters for :code:`start_simulation` is :code:`client_fn` " -"which returns a function to construct a client. We define it as follows:" +"In this notebook, we'll build a federated learning system using Flower, " +"`Flower Datasets `__ and PyTorch. In " +"part 1, we use PyTorch for the model training pipeline and data loading. " +"In part 2, we continue to federate the PyTorch-based pipeline using " +"Flower." msgstr "" +"在本笔记中,我们将使用 Flower 和 PyTorch 构建一个联邦学习系统。在第一部分中,我们使用 PyTorch " +"进行模型训练和数据加载。在第二部分中,我们将继续使用 Flower 联邦化基于 PyTorch 的框架。" -#: ../../source/tutorial-quickstart-xgboost.rst:1038 -msgid "Arguments parser" -msgstr "参数解析器" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 +msgid "Let's get started!" +msgstr "让我们开始吧!" -#: ../../source/tutorial-quickstart-xgboost.rst:1040 -#, fuzzy +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server and " -"simulation, allowing users to specify different experimental settings. Let's " -"first see the sever side:" -msgstr "" -"在 :code:`utils.py` 中,我们定义了客户端和服务器端的参数解析器,允许用户指定" -"不同的实验设置。让我们先看看服务器端:" +"Before we begin with any actual code, let's make sure that we have " +"everything we need." +msgstr "在开始编写实际代码之前,让我们先确保我们已经准备好了所需的一切。" -#: ../../source/tutorial-quickstart-xgboost.rst:1086 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 #, fuzzy msgid "" -"This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and " -"evaluation fashion. Note that with :code:`--centralised-eval`, the sever " -"will do centralised evaluation and all functionalities for client evaluation " -"will be disabled." -msgstr "" -"这允许用户指定总客户数/FL 轮数/参与客户数/评估客户数以及评估方式。请注意,如" -"果使用 :code:`--centralised-eval`,服务器将进行集中评估,客户端评估的所有功能" -"将被禁用。" - -#: ../../source/tutorial-quickstart-xgboost.rst:1090 -msgid "Then, the argument parser on client side:" -msgstr "然后是客户端的参数解析器:" +"Next, we install the necessary packages for PyTorch (``torch`` and " +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " +"(``flwr``):" +msgstr "接下来,我们为 PyTorch(`torch`` 和`torchvision``)和 Flower(`flwr`)安装必要的软件包:" -#: ../../source/tutorial-quickstart-xgboost.rst:1144 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 #, fuzzy msgid "" -"This defines various options for client data partitioning. Besides, clients " -"also have an option to conduct evaluation on centralised test set by " -"setting :code:`--centralised-eval`, as well as an option to perform scaled " -"learning rate based on the number of clients by setting :code:`--scaled-lr`." -msgstr "" -"这定义了客户端数据分区的各种选项。此外,通过设置 :code:`-centralised-eval`," -"客户端还可以选择在集中测试集上进行评估。" - -#: ../../source/tutorial-quickstart-xgboost.rst:1148 -msgid "We also have an argument parser for simulation:" -msgstr "" - -#: ../../source/tutorial-quickstart-xgboost.rst:1226 -msgid "This integrates all arguments for both client and server sides." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" +" GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" +"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类型 > 硬件加速: GPU > " +"保存``)。但请注意,Google Colab 并非总能提供 GPU 加速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 " +"``DEVICE = torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU " +"加速,你应该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" -#: ../../source/tutorial-quickstart-xgboost.rst:1229 -msgid "Example commands" -msgstr "命令示例" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 +msgid "Loading the data" +msgstr "加载数据" -#: ../../source/tutorial-quickstart-xgboost.rst:1231 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 #, fuzzy msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 clients " -"with exponential distribution for 50 rounds, we first start the server as " -"below:" +"Federated learning can be applied to many different types of tasks across" +" different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular " +"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " +"distinguish between images from ten different classes: 'airplane', " +"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " +"'truck'." msgstr "" -"为了在 5 个客户端上进行 50 轮指数分布的集中评估实验,我们首先启动服务器,如下" -"所示:" - -#: ../../source/tutorial-quickstart-xgboost.rst:1238 -msgid "Then, on each client terminal, we start the clients:" -msgstr "然后,我们在每个客户终端上启动客户机:" +"联邦学习可应用于不同领域的多种不同类型任务。在本教程中,我们将通过在流行的 CIFAR-10 数据集上训练一个简单的卷积神经网络 (CNN) " +"来介绍联合学习。CIFAR-10 可用于训练图像分类器,以区分来自十个不同类别的图像:" -#: ../../source/tutorial-quickstart-xgboost.rst:1244 -msgid "To run the same experiment with Flower simulation:" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 +msgid "" +"We simulate having multiple datasets from multiple organizations (also " +"called the \"cross-silo\" setting in federated learning) by splitting the" +" original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely " +"for experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the " +"data is naturally partitioned)." msgstr "" +"我们通过将原始 CIFAR-10 数据集拆分成多个分区来模拟来自多个组织的多个数据集(也称为联邦学习中的 \"跨分区 " +"\"设置)。每个分区代表一个组织的数据。我们这样做纯粹是为了实验目的,在现实世界中不需要拆分数据,因为每个组织都已经有了自己的数据(所以数据是自然分区的)。" -#: ../../source/tutorial-quickstart-xgboost.rst:1250 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 #, fuzzy msgid "" -"The full `code `_ for this comprehensive example can be found in :code:" -"`examples/xgboost-comprehensive`." +"Each organization will act as a client in the federated learning system. " +"So having ten organizations participate in a federation means having ten " +"clients connected to the federated learning server." +msgstr "每个组织都将充当联邦学习系统中的客户端。因此,有十个组织参与联邦学习,就意味着有十个客户端连接到联邦学习服务器:" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +msgid "" +"Let's now create the Federated Dataset abstraction that from ``flwr-" +"datasets`` that partitions the CIFAR-10. We will create small training " +"and test set for each edge device and wrap each of them into a PyTorch " +"``DataLoader``:" msgstr "" -"此综合示例的全部`源代码 `_ 可在 :code:`examples/xgboost-comprehensive` 中找" -"到。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 -msgid "Build a strategy from scratch" -msgstr "从零开始制定策略" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 +#, fuzzy +msgid "" +"We now have a list of ten training sets and ten validation sets " +"(``trainloaders`` and ``valloaders``) representing the data of ten " +"different organizations. Each ``trainloader``/``valloader`` pair contains" +" 4000 training examples and 1000 validation examples. There's also a " +"single ``testloader`` (we did not split the test set). Again, this is " +"only necessary for building research or educational systems, actual " +"federated learning systems have their data naturally distributed across " +"multiple partitions." +msgstr "" +"现在,我们有一个包含十个训练集和十个验证集(`trainloaders`` 和`valloaders``)的列表,代表十个不同组织的数据。每对 " +"``trainloader``/``valloader`` 都包含 4500 个训练示例和 500 个验证数据。还有一个单独的 " +"``测试加载器``(我们没有拆分测试集)。同样,这只有在构建研究或教育系统时才有必要,实际的联邦学习系统的数据自然分布在多个分区中。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:11 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 msgid "" -"Welcome to the third part of the Flower federated learning tutorial. In " -"previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies can be " -"used to customize the execution on both the server and the clients (`part 2 " -"`__)." -msgstr "" -"欢迎来到 Flower 联邦学习教程的第三部分。在本教程的前几部分,我们介绍了 " -"PyTorch 和 Flower 的联邦学习(`part 1 `__),并学习了如何使用策略来定" -"制服务器和客户端的执行(`part 2 `__)。" +"Let's take a look at the first batch of images and labels in the first " +"training set (i.e., ``trainloaders[0]``) before we move on:" +msgstr "在继续之前,让我们先看看第一个训练集中的第一批图像和标签(即 ``trainloaders[0]``):" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 msgid "" -"In this notebook, we'll continue to customize the federated learning system " -"we built previously by creating a custom version of FedAvg (again, using " -"`Flower `__ and `PyTorch `__)." +"The output above shows a random batch of images from the first " +"``trainloader`` in our list of ten ``trainloaders``. It also prints the " +"labels associated with each image (i.e., one of the ten possible labels " +"we've seen above). If you run the cell again, you should see another " +"batch of images." msgstr "" -"在本笔记中,我们将通过创建 FedAvg 的自定义版本(再次使用 `Flower `__ 和 `PyTorch `__),继续定制我们之前构建" -"的联邦学习系统。" +"上面的输出显示了来自十个 \"trainloader \"列表中第一个 \"trainloader " +"\"的随机图像。它还打印了与每幅图像相关的标签(即我们上面看到的十个可能标签之一)。如果您再次运行该单元,应该会看到另一批图像。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:16 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 +msgid "Step 1: Centralized Training with PyTorch" +msgstr "步骤 1:使用 PyTorch 进行集中训练" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join the " -"Flower community on Slack to connect, ask questions, and get help: `Join " -"Slack `__ 🌼 We'd love to hear from you in the " -"``#introductions`` channel! And if anything is unclear, head over to the " -"``#questions`` channel." +"Next, we're going to use PyTorch to define a simple convolutional neural " +"network. This introduction assumes basic familiarity with PyTorch, so it " +"doesn't cover the PyTorch-related aspects in full detail. If you want to " +"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " +"MINUTE BLITZ " +"`__." msgstr "" -"`Star Flower on GitHub `__ ⭐️ 并加入 Slack 上" -"的 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何" -"不清楚的地方,请访问 ``#questions`` 频道。" - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 -msgid "Let's build a new ``Strategy`` from scratch!" -msgstr "让我们从头开始构建一个新的``Strategy``!" +"接下来,我们将使用 PyTorch 来定义一个简单的卷积神经网络。本介绍假定您对 PyTorch 有基本的了解,因此不会详细介绍与 PyTorch" +" 相关的内容。如果你想更深入地了解 PyTorch,我们推荐你阅读 `DEEP LEARNING WITH PYTORCH: a 60 " +"minute blitz " +"`__。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:29 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:29 -msgid "Preparation" -msgstr "准备工作" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 +msgid "Defining the model" +msgstr "定义模型" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:31 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:32 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:31 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"Before we begin with the actual code, let's make sure that we have " -"everything we need." -msgstr "在开始实际代码之前,让我们先确保我们已经准备好了所需的一切。" +"We use the simple CNN described in the `PyTorch tutorial " +"`__:" +msgstr "" +"我们使用` PyTorch 教程 " +"`__ 中描述的简单 CNN:" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:43 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:44 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:43 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:43 -msgid "Installing dependencies" -msgstr "安装依赖项" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 +msgid "Let's continue with the usual training and test functions:" +msgstr "让我们继续进行常规的训练和测试功能:" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:45 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:46 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:45 -msgid "First, we install the necessary packages:" -msgstr "首先,我们安装必要的软件包:" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 +msgid "Training the model" +msgstr "训练模型" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:65 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:66 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:65 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:65 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" -"Now that we have all dependencies installed, we can import everything we " -"need for this tutorial:" -msgstr "现在我们已经安装了所有依赖项,可以导入本教程所需的所有内容:" +"We now have all the basic building blocks we need: a dataset, a model, a " +"training function, and a test function. Let's put them together to train " +"the model on the dataset of one of our organizations " +"(``trainloaders[0]``). This simulates the reality of most machine " +"learning projects today: each organization has their own data and trains " +"models only on this internal data:" +msgstr "现在我们拥有了所需的所有基本构件:数据集、模型、训练函数和测试函数。让我们把它们放在一起,在我们其中一个组织的数据集(``trainloaders[0]``)上训练模型。这模拟了当今大多数机器学习项目的实际情况:每个组织都有自己的数据,并且只在这些内部数据上训练模型:" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:101 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled (on " -"Google Colab: ``Runtime > Change runtime type > Hardware acclerator: GPU > " -"Save``). Note, however, that Google Colab is not always able to offer GPU " -"acceleration. If you see an error related to GPU availability in one of the " -"following sections, consider switching back to CPU-based execution by " -"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " -"acceleration enabled, you should see the output ``Training on cuda``, " -"otherwise it'll say ``Training on cpu``." -msgstr "" -"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类" -"型 > 硬件加速: GPU > 保存``)。但请注意,Google Colab 并非总能提供 GPU 加" -"速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 ``DEVICE = " -"torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU 加速,你应" -"该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " +"in a test set accuracy of about 41%, which is not good, but at the same " +"time, it doesn't really matter for the purposes of this tutorial. The " +"intent was just to show a simplistic centralized training pipeline that " +"sets the stage for what comes next - federated learning!" +msgstr "" +"在我们的 CIFAR-10 分片上对简单 CNN 进行 5 个遍历的训练后,测试集的准确率应为 " +"41%,这并不理想,但同时对本教程而言也并不重要。我们只是想展示一个简单的集中式训练流程,为接下来的联邦学习做好铺垫!" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:115 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:114 -msgid "Data loading" -msgstr "数据加载" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 +msgid "Step 2: Federated Learning with Flower" +msgstr "步骤 2:使用 Flower 联邦学习" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into ten " -"smaller datasets (each split into training and validation set), and wrap " -"everything in their own ``DataLoader``. We introduce a new parameter " -"``num_clients`` which allows us to call ``load_datasets`` with different " -"numbers of clients." +"Step 1 demonstrated a simple centralized training pipeline. All data was " +"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." +" Next, we'll simulate a situation where we have multiple datasets in " +"multiple organizations and where we train a model over these " +"organizations using federated learning." msgstr "" -"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 个较小的数据集(每" -"个数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` " -"中。我们引入了一个新参数 ``num_clients``,它允许我们使用不同数量的客户端调用 " -"``load_datasets``。" +"步骤 1 演示了一个简单的集中式训练流程。所有数据都在一个地方(即一个 \"trainloader \"和一个 " +"\"valloader\")。接下来,我们将模拟在多个组织中拥有多个数据集的情况,并使用联邦学习在这些组织中训练一个模型。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:168 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:167 -msgid "Model training/evaluation" -msgstr "模型培训/评估" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 +msgid "Updating model parameters" +msgstr "更新模型参数" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:169 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"Let's continue with the usual model definition (including ``set_parameters`` " -"and ``get_parameters``), training and test functions:" -msgstr "" -"让我们继续使用常见的模型定义(包括 `set_parameters` 和 `get_parameters`)、训" -"练和测试函数:" - -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:258 -msgid "Flower client" -msgstr "Flower 客户端" +"In federated learning, the server sends the global model parameters to " +"the client, and the client updates the local model with the parameters " +"received from the server. It then trains the model on the local data " +"(which changes the model parameters locally) and sends the " +"updated/changed model parameters back to the server (or, alternatively, " +"it sends just the gradients back to the server, not the full model " +"parameters)." +msgstr "在联邦学习中,服务器将全局模型参数发送给客户端,客户端根据从服务器接收到的参数更新本地模型。然后,客户端根据本地数据对模型进行训练(在本地更改模型参数),并将更新/更改后的模型参数发回服务器(或者,客户端只将梯度参数发回服务器,而不是全部模型参数)。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" -"To implement the Flower client, we (again) create a subclass of ``flwr." -"client.NumPyClient`` and implement the three methods ``get_parameters``, " -"``fit``, and ``evaluate``. Here, we also pass the ``cid`` to the client and " -"use it log additional details:" +"We need two helper functions to update the local model with parameters " +"received from the server and to get the updated model parameters from the" +" local model: ``set_parameters`` and ``get_parameters``. The following " +"two functions do just that for the PyTorch model above." msgstr "" -"为了实现 Flower 客户端,我们(再次)创建了 ``flwr.client.NumPyClient`` 的子" -"类,并实现了 ``get_parameters``、``fit`` 和 ``evaluate``三个方法。在这里,我" -"们还将 ``cid`` 传递给客户端,并使用它记录其他详细信息:" +"我们需要两个辅助函数,用从服务器接收到的参数更新本地模型,并从本地模型获取更新后的模型参数:`` " +"set_parameters```和`get_parameters``。下面两个函数就是为上面的 PyTorch 模型做这些工作的。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 -msgid "Let's test what we have so far before we continue:" -msgstr "在继续之前,让我们先测试一下我们目前掌握的情况:" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 +msgid "" +"The details of how this works are not really important here (feel free to" +" consult the PyTorch documentation if you want to learn more). In " +"essence, we use ``state_dict`` to access PyTorch model parameter tensors." +" The parameter tensors are then converted to/from a list of NumPy " +"ndarray's (which Flower knows how to serialize/deserialize):" +msgstr "" +"在这里,如何工作的细节并不重要(如果你想了解更多,请随时查阅 PyTorch 文档)。本质上,我们使用 ``state_dict`` 访问 " +"PyTorch 模型参数张量。然后,参数张量会被转换成/转换成 NumPy ndarray 列表(Flower 知道如何序列化/反序列化):" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:339 -msgid "Build a Strategy from scratch" -msgstr "从零开始构建策略" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 +msgid "Implementing a Flower client" +msgstr "实现 Flower 客户端" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher " -"learning rate (potentially also other hyperparameters) to the optimizer of a " -"fraction of the clients. We will keep the sampling of the clients as it is " -"in ``FedAvg`` and then change the configuration dictionary (one of the " -"``FitIns`` attributes)." +"With that out of the way, let's move on to the interesting part. " +"Federated learning systems consist of a server and multiple clients. In " +"Flower, we create clients by implementing subclasses of " +"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " +"``NumPyClient`` in this tutorial because it is easier to implement and " +"requires us to write less boilerplate." msgstr "" -"让我们重写 ``configure_fit`` 方法,使其向一部分客户的优化器传递更高的学习率" -"(可能还有其他超参数)。我们将保持 ``FedAvg`` 中的客户端采样,然后更改配置字" -"典(``FitIns`` 属性之一)。" +"说完这些,让我们进入有趣的部分。联邦学习系统由一个服务器和多个客户端组成。在 Flower 中,我们通过实现 " +"``flwr.client.Client`` 或 ``flwr.client.NumPyClient`` " +"的子类来创建客户端。在本教程中,我们使用``NumPyClient``,因为它更容易实现,需要我们编写的模板也更少。" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"The only thing left is to use the newly created custom Strategy " -"``FedCustom`` when starting the experiment:" -msgstr "剩下的唯一工作就是在启动实验时使用新创建的自定义策略 ``FedCustom`` :" +"To implement the Flower client, we create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``:" +msgstr "" +"为实现 Flower 客户端,我们创建了 ``flwr.client.NumPyClient`` 的子类,并实现了 " +"``get_parameters``、``fit`` 和``evaluate`` 三个方法:" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:534 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:932 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:697 -msgid "Recap" -msgstr "回顾" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 +msgid "``get_parameters``: Return the current local model parameters" +msgstr "``get_parameters``: 返回当前本地模型参数" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom " -"strategy enables granular control over client node configuration, result " -"aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``. To " -"make custom strategies even more powerful, you can pass custom functions to " -"the constructor of your new class (``__init__``) and then call these " -"functions whenever needed." -msgstr "" -"在本笔记中,我们了解了如何实施自定义策略。自定义策略可以对客户端节点配置、结" -"果聚合等进行细粒度控制。要定义自定义策略,只需覆盖(抽象)基类 ``Strategy`` " -"的抽象方法即可。为使自定义策略更加强大,您可以将自定义函数传递给新类的构造函" -"数(`__init__``),然后在需要时调用这些函数。" +"``fit``: Receive model parameters from the server, train the model " +"parameters on the local data, and return the (updated) model parameters " +"to the server" +msgstr "``fit``: 从服务器接收模型参数,在本地数据上训练模型参数,并将(更新的)模型参数返回服务器" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:948 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:729 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"Before you continue, make sure to join the Flower community on Slack: `Join " -"Slack `__" -msgstr "" -"在继续之前,请务必加入 Slack 上的 Flower 社区:`Join Slack `__" +"``evaluate``: Receive model parameters from the server, evaluate the " +"model parameters on the local data, and return the evaluation result to " +"the server" +msgstr "``evaluate ``: 从服务器接收模型参数,在本地数据上评估模型参数,并将评估结果返回服务器" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:950 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:731 -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd also " -"love to hear who you are in ``#introductions``!" +"We mentioned that our clients will use the previously defined PyTorch " +"components for model training and evaluation. Let's see a simple Flower " +"client implementation that brings everything together:" msgstr "" -"如果您需要帮助,我们有专门的 ``#questions`` 频道,但我们也很乐意在 " -"``#introductions`` 中了解您是谁!" +"我们提到,我们的客户端将使用之前定义的 PyTorch 组件进行模型训练和评估。让我们来看看一个简单的 Flower " +"客户端实现,它将一切都整合在一起:" -#: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 `__ introduces " -"``Client``, the flexible API underlying ``NumPyClient``." -msgstr "" -"Flower联邦学习教程 - 第4部分 `__ 介绍了``Client``,它是``NumPyClient``底" -"层的灵活应用程序接口。" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 -msgid "Customize the client" -msgstr "自定义客户端" +"Our class ``FlowerClient`` defines how local training/evaluation will be " +"performed and allows Flower to call the local training/evaluation through" +" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" +" *single client* in our federated learning system. Federated learning " +"systems have multiple clients (otherwise, there's not much to federate), " +"so each client will be represented by its own instance of " +"``FlowerClient``. If we have, for example, three clients in our workload," +" then we'd have three instances of ``FlowerClient``. Flower calls " +"``FlowerClient.fit`` on the respective instance when the server selects a" +" particular client for training (and ``FlowerClient.evaluate`` for " +"evaluation)." +msgstr "" +"我们的类 ``FlowerClient`` 定义了本地训练/评估的执行方式,并允许 Flower 通过 ``fit`` 和 " +"``evaluate`` 调用本地训练/评估。每个 ``FlowerClient`` " +"实例都代表联邦学习系统中的*单个客户端*。联邦学习系统有多个客户端(否则就没有什么可联邦的),因此每个客户端都将由自己的 " +"``FlowerClient`` 实例来代表。例如,如果我们的工作负载中有三个客户端,那么我们就会有三个 ``FlowerClient`` " +"实例。当服务器选择特定客户端进行训练时,Flower 会调用相应实例上的 ``FlowerClient.fit`` (评估时调用 " +"``FlowerClient.evaluate``)。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 -msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In the " -"previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__), we learned how strategies can be used " -"to customize the execution on both the server and the clients (`part 2 " -"`__), and we built our own custom strategy from scratch (`part " -"3 `__)." -msgstr "" -"欢迎来到 Flower 联邦学习教程的第四部分。在本教程的前几部分中,我们介绍了 " -"PyTorch 和 Flower 的联邦学习(`part 1 `__),了解了如何使用策略来定制" -"服务器和客户端的执行(`part 2 `__),并从头开始构建了我们自己的" -"定制策略(`part 3 `__)。" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 +msgid "Using the Virtual Client Engine" +msgstr "使用虚拟客户端引擎" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new baseclass " -"for building clients, simply named ``Client``. In previous parts of this " -"tutorial, we've based our client on ``NumPyClient``, a convenience class " -"which makes it easy to work with machine learning libraries that have good " -"NumPy interoperability. With ``Client``, we gain a lot of flexibility that " -"we didn't have before, but we'll also have to do a few things the we didn't " -"have to do before." +"In this notebook, we want to simulate a federated learning system with 10" +" clients on a single machine. This means that the server and all 10 " +"clients will live on a single machine and share resources such as CPU, " +"GPU, and memory. Having 10 clients would mean having 10 instances of " +"``FlowerClient`` in memory. Doing this on a single machine can quickly " +"exhaust the available memory resources, even if only a subset of these " +"clients participates in a single round of federated learning." msgstr "" -"在本笔记中,我们将重温 ``NumPyClient`` 并引入一个用于构建客户端的新基类,简单" -"命名为 ``Client``。在本教程的前几部分中,我们的客户端基于``NumPyClient``,这" -"是一个便捷类,可以让我们轻松地与具有良好 NumPy 互操作性的机器学习库协同工作。" -"有了 ``Client``,我们获得了很多以前没有的灵活性,但我们也必须做一些以前不需要" -"做的事情。" +"在本笔记中,我们要模拟一个联邦学习系统,在一台机器上有 10 个客户端。这意味着服务器和所有 10 个客户端都将位于一台机器上,并共享 " +"CPU、GPU 和内存等资源。有 10 个客户端就意味着内存中有 10 个 ``FlowerClient`` " +"实例。在单台机器上这样做会很快耗尽可用的内存资源,即使这些客户端中只有一个子集参与了一轮联邦学习。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 msgid "" -"Let's go deeper and see what it takes to move from ``NumPyClient`` to " -"``Client``!" -msgstr "让我们深入了解一下从 ``NumPyClient`` 到 ``Client`` 的过程!" +"In addition to the regular capabilities where server and clients run on " +"multiple machines, Flower, therefore, provides special simulation " +"capabilities that create ``FlowerClient`` instances only when they are " +"actually necessary for training or evaluation. To enable the Flower " +"framework to create clients when necessary, we need to implement a " +"function called ``client_fn`` that creates a ``FlowerClient`` instance on" +" demand. Flower calls ``client_fn`` whenever it needs an instance of one " +"particular client to call ``fit`` or ``evaluate`` (those instances are " +"usually discarded after use, so they should not keep any local state). " +"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " +"be used, for example, to load different local data partitions for " +"different clients, as can be seen below:" +msgstr "" +"除了服务器和客户端在多台机器上运行的常规功能外,Flower 还提供了特殊的模拟功能,即只有在训练或评估实际需要时才创建 " +"``FlowerClient`` 实例。为了让 Flower 框架能在必要时创建客户端,我们需要实现一个名为 ``client_fn`` " +"的函数,它能按需创建一个 ``FlowerClient`` 实例。每当 Flower 需要一个特定的客户端实例来调用 ``fit`` 或 " +"``evaluate`` 时,它就会调用 " +"``client_fn``(这些实例在使用后通常会被丢弃,因此它们不应保留任何本地状态)。客户端由一个客户端 ID 或简短的 ``cid`` " +"标识。例如,可以使用 ``cid`` 为不同的客户端加载不同的本地数据分区,如下所示:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:30 -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:29 -msgid "Step 0: Preparation" -msgstr "步骤 0:准备工作" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 +msgid "Starting the training" +msgstr "开始训练" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into ten " -"smaller datasets (each split into training and validation set), and wrap " -"everything in their own ``DataLoader``." +"We now have the class ``FlowerClient`` which defines client-side " +"training/evaluation and ``client_fn`` which allows Flower to create " +"``FlowerClient`` instances whenever it needs to call ``fit`` or " +"``evaluate`` on one particular client. The last step is to start the " +"actual simulation using ``flwr.simulation.start_simulation``." msgstr "" -"现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成十个较小的数据集(每个" -"数据集又分为训练集和验证集),并将所有数据都封装在各自的 ``DataLoader`` 中。" +"现在我们有了定义客户端训练/评估的类 ``FlowerClient`` 和允许 Flower 在需要调用某个客户端的 ``fit` 或 " +"``evaluate` 时创建 ``FlowerClient`` 实例的 ``client_fn` 类。最后一步是使用 " +"``flwr.simulation.start_simulation`` 启动实际模拟。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 -msgid "Step 1: Revisiting NumPyClient" -msgstr "步骤 1:重温 NumPyClient" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +msgid "" +"The function ``start_simulation`` accepts a number of arguments, amongst " +"them the ``client_fn`` used to create ``FlowerClient`` instances, the " +"number of clients to simulate (``num_clients``), the number of federated " +"learning rounds (``num_rounds``), and the strategy. The strategy " +"encapsulates the federated learning approach/algorithm, for example, " +"*Federated Averaging* (FedAvg)." +msgstr "" +"函数 ``start_simulation`` 接受许多参数,其中包括用于创建 ``FlowerClient`` 实例的 " +"``client_fn``、要模拟的客户端数量(``num_clients``)、联邦学习轮数(``num_rounds``)和策略。策略封装了联邦学习方法/算法,例如*联邦平均*" +" (FedAvg)。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" -"So far, we've implemented our client by subclassing ``flwr.client." -"NumPyClient``. The three methods we implemented are ``get_parameters``, " -"``fit``, and ``evaluate``. Finally, we wrap the creation of instances of " -"this class in a function called ``client_fn``:" +"Flower has a number of built-in strategies, but we can also use our own " +"strategy implementations to customize nearly all aspects of the federated" +" learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last " +"step is the actual call to ``start_simulation`` which - you guessed it - " +"starts the simulation:" msgstr "" -"到目前为止,我们通过子类化 ``flwr.client.NumPyClient`` 实现了我们的客户端。我" -"们实现了三个方法:``get_parameters``, ``fit`, 和``evaluate``。最后,我们用一" -"个名为 ``client_fn`` 的函数来创建该类的实例:" +"Flower 有许多内置策略,但我们也可以使用自己的策略实现来定制联邦学习方法的几乎所有方面。在本例中,我们使用内置的 ``FedAvg`` " +"实现,并使用一些基本参数对其进行定制。最后一步是实际调用 ``start_simulation``开始模拟:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 +msgid "Behind the scenes" +msgstr "幕后" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 +msgid "So how does this work? How does Flower execute this simulation?" +msgstr "那么它是如何工作的呢?Flower 如何进行模拟?" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 +#, python-format msgid "" -"We've seen this before, there's nothing new so far. The only *tiny* " -"difference compared to the previous notebook is naming, we've changed " -"``FlowerClient`` to ``FlowerNumPyClient`` and ``client_fn`` to " -"``numpyclient_fn``. Let's run it to see the output we get:" +"When we call ``start_simulation``, we tell Flower that there are 10 " +"clients (``num_clients=10``). Flower then goes ahead an asks the " +"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " +"select 100% of the available clients (``fraction_fit=1.0``), so it goes " +"ahead and selects 10 random clients (i.e., 100% of 10)." msgstr "" -"我们以前见过这种情况,目前没有什么新东西。与之前的笔记相比,唯一*小*的不同是" -"命名,我们把 ``FlowerClient`` 改成了 ``FlowerNumPyClient``,把 `client_fn` 改" -"成了 ``numpyclient_fn``。让我们运行它看看输出结果:" +"当我们调用 ``start_simulation`` 时,我们会告诉 Flower 有 10 " +"个客户(`num_clients=10``)。然后,Flower 会要求 ``FedAvg`` 策略选择客户。``FedAvg`` 知道它应该选择" +" 100%的可用客户(``fraction_fit=1.0``),所以它会随机选择 10 个客户(即 10 的 100%)。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:339 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 msgid "" -"This works as expected, two clients are training for three rounds of " -"federated learning." -msgstr "结果不出所料,两个客户端正在进行三轮联邦学习训练。" +"Flower then asks the selected 10 clients to train the model. When the " +"server receives the model parameter updates from the clients, it hands " +"those updates over to the strategy (*FedAvg*) for aggregation. The " +"strategy aggregates those updates and returns the new global model, which" +" then gets used in the next round of federated learning." +msgstr "" +"然后,Flower 会要求选定的 10 " +"个客户端对模型进行训练。服务器收到客户端的模型参数更新后,会将这些更新交给策略(*FedAvg*)进行聚合。策略会聚合这些更新并返回新的全局模型,然后将其用于下一轮联邦学习。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:341 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 +msgid "Where's the accuracy?" +msgstr "准确度在哪里找?" + +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 msgid "" -"Let's dive a little bit deeper and discuss how Flower executes this " -"simulation. Whenever a client is selected to do some work, " -"``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and the " -"data)." +"You may have noticed that all metrics except for ``losses_distributed`` " +"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" msgstr "" -"让我们再深入一点,讨论一下 Flower 是如何执行模拟的。每当一个客户端被选中进行" -"工作时,`start_simulation`` 就会调用函数 `numpyclient_fn` 来创建我们的 " -"``FlowerNumPyClient`` 实例(同时加载模型和数据)。" +"您可能已经注意到,除了 ``losses_distributed`` 以外,所有指标都是空的。{\"准确度\": " +"float(准确度)}``去哪儿了?" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 msgid "" -"But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to makes " -"it look like a subclass of ``flwr.client.Client``, not ``flwr.client." -"NumPyClient``. In fact, the Flower core framework doesn't know how to handle " -"``NumPyClient``'s, it only knows how to handle ``Client``'s. ``NumPyClient`` " -"is just a convenience abstraction built on top of ``Client``." -msgstr "" -"但令人惊讶的部分也许就在这里: Flower 实际上并不直接使用 " -"``FlowerNumPyClient`` 对象。相反,它封装了该对象,使其看起来像 ``flwr.client." -"Client`` 的子类,而不是 ``flwr.client.NumPyClient``。事实上,Flower 核心框架" -"不知道如何处理 ``NumPyClient``,它只知道如何处理 ``Client``。``NumPyClient`` " -"只是建立在``Client``之上的便捷抽象类。" +"Flower can automatically aggregate losses returned by individual clients," +" but it cannot do the same for metrics in the generic metrics dictionary " +"(the one with the ``accuracy`` key). Metrics dictionaries can contain " +"very different kinds of metrics and even key/value pairs that are not " +"metrics at all, so the framework does not (and can not) know how to " +"handle these automatically." +msgstr "" +"Flower 可以自动汇总单个客户端返回的损失值,但无法对通用度量字典中的度量进行同样的处理(即带有 \"准确度 " +"\"键的度量字典)。度量值字典可以包含非常不同种类的度量值,甚至包含根本不是度量值的键/值对,因此框架不知道(也无法知道)如何自动处理这些度量值。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on top " -"of ``Client``." -msgstr "与其在 ``NumPyClient`` 上构建,我们可以直接在 ``Client`` 上构建。" +"As users, we need to tell the framework how to handle/aggregate these " +"custom metrics, and we do so by passing metric aggregation functions to " +"the strategy. The strategy will then call these functions whenever it " +"receives fit or evaluate metrics from clients. The two possible functions" +" are ``fit_metrics_aggregation_fn`` and " +"``evaluate_metrics_aggregation_fn``." +msgstr "" +"作为用户,我们需要告诉框架如何处理/聚合这些自定义指标,为此,我们将指标聚合函数传递给策略。然后,只要从客户端接收到拟合或评估指标,策略就会调用这些函数。两个可能的函数是" +" ``fit_metrics_aggregation_fn`` 和 ``evaluate_metrics_aggregation_fn``。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 -msgid "Step 2: Moving from ``NumPyClient`` to ``Client``" -msgstr "步骤 2:从 ``NumPyClient`` 移至 ``Client``" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 +msgid "" +"Let's create a simple weighted averaging function to aggregate the " +"``accuracy`` metric we return from ``evaluate``:" +msgstr "让我们创建一个简单的加权平均函数来汇总从 ``evaluate`` 返回的 ``accuracy`` 指标:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 msgid "" -"Let's try to do the same thing using ``Client`` instead of ``NumPyClient``." -msgstr "让我们尝试使用 ``Client`` 代替 ``NumPyClient`` 做同样的事情。" +"The only thing left to do is to tell the strategy to call this function " +"whenever it receives evaluation metric dictionaries from the clients:" +msgstr "剩下要做的就是告诉策略,每当它从客户端接收到评估度量字典时,都要调用这个函数:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta make " -"sure our new ``Client``-based client works, right?" +"We now have a full system that performs federated training and federated " +"evaluation. It uses the ``weighted_average`` function to aggregate custom" +" evaluation metrics and calculates a single ``accuracy`` metric across " +"all clients on the server side." msgstr "" -"在详细讨论代码之前,让我们试着运行它!必须确保我们基于 ``Client`` 的新客户端" -"能正常运行,对吗?" +"我们现在有了一个完整的系统,可以执行联邦训练和联邦评估。它使用 ``weighted_average`` " +"函数汇总自定义评估指标,并在服务器端计算所有客户端的单一 ``accuracy`` 指标。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 msgid "" -"That's it, we're now using ``Client``. It probably looks similar to what " -"we've done with ``NumPyClient``. So what's the difference?" +"The other two categories of metrics (``losses_centralized`` and " +"``metrics_centralized``) are still empty because they only apply when " +"centralized evaluation is being used. Part two of the Flower tutorial " +"will cover centralized evaluation." msgstr "" -"就是这样,我们现在开始使用 ``Client``。它看起来可能与我们使用 " -"``NumPyClient`` 所做的类似。那么有什么不同呢?" +"其他两类指标(`losses_centralized`` 和 " +"`metrics_centralized`)仍然是空的,因为它们只适用于集中评估。Flower 教程的第二部分将介绍集中式评估。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 -msgid "" -"First of all, it's more code. But why? The difference comes from the fact " -"that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the network, " -"it eventually needs to turn these parameters into ``bytes``. Turning " -"parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " -"serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it needs " -"to serialize parameters on the server-side and send them to the client, the " -"client needs to deserialize them to use them for local training, and then " -"serialize the updated parameters again to send them back to the server, " -"which (finally!) deserializes them again in order to aggregate them with the " -"updates received from other clients." -msgstr "" -"首先,它的代码更多。但为什么呢?区别在于 ``Client`` 希望我们处理参数的序列化" -"和反序列化。Flower 要想通过网络发送参数,最终需要将这些参数转化为 ``字节``。" -"把参数(例如 NumPy 的 ``ndarray`` 参数)变成原始字节叫做序列化。将原始字节转" -"换成更有用的东西(如 NumPy ``ndarray`)称为反序列化。Flower 需要同时做这两件" -"事:它需要在服务器端序列化参数并将其发送到客户端,客户端需要反序列化参数以便" -"将其用于本地训练,然后再次序列化更新后的参数并将其发送回服务器,服务器(最" -"后)再次反序列化参数以便将其与从其他客户端接收到的更新汇总在一起。" +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 +msgid "Final remarks" +msgstr "结束语" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 msgid "" -"The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It can " -"do so because it expects you to return parameters as NumPy ndarray's, and it " -"knows how to handle these. This makes working with machine learning " -"libraries that have good NumPy support (most of them) a breeze." +"Congratulations, you just trained a convolutional neural network, " +"federated over 10 clients! With that, you understand the basics of " +"federated learning with Flower. The same approach you've seen can be used" +" with other machine learning frameworks (not just PyTorch) and tasks (not" +" just CIFAR-10 images classification), for example NLP with Hugging Face " +"Transformers or speech with SpeechBrain." msgstr "" -"Client 与 NumPyClient 之间的唯一**真正区别在于,NumPyClient 会为你处理序列化" -"和反序列化。NumPyClient之所以能做到这一点,是因为它预计你会以NumPy ndarray的" -"形式返回参数,而且它知道如何处理这些参数。这使得与具有良好 NumPy 支持的大多数" -"机器学习库一起工作变得轻而易举。" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 -msgid "" -"In terms of API, there's one major difference: all methods in Client take " -"exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return exactly " -"one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " -"``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return " -"values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These ``*Ins`` " -"and ``*Res`` objects in ``Client`` wrap all the individual values you're " -"used to from ``NumPyClient``." -msgstr "" -"在 API 方面,有一个主要区别:Client 中的所有方法都只接受一个参数(例如," -"``Client.fit`` 中的 ``FitIns``),并只返回一个值(例如,``Client.fit`` 中的 " -"``FitRes``)。另一方面,``NumPyClient``中的方法有多个参数(例如," -"``NumPyClient.fit``中的``parameters``和``config``)和多个返回值(例如," -"``NumPyClient.fit``中的``parameters``、``num_example``和``metrics``)。在 " -"``Client`` 中的这些 ``*Ins`` 和 ``*Res`` 对象封装了你在 ``NumPyClient`` 中习" -"惯使用的所有单个值。" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 -msgid "Step 3: Custom serialization" -msgstr "步骤 3:自定义序列化" +"恭喜您,你刚刚训练了一个由 10 个客户端组成的卷积神经网络!这样,你就了解了使用 Flower " +"进行联邦学习的基础知识。你所看到的方法同样适用于其他机器学习框架(不只是 PyTorch)和任务(不只是 CIFAR-10 图像分类),例如使用 " +"Hugging Face Transformers 的 NLP 或使用 SpeechBrain 的语音。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:512 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 msgid "" -"Here we will explore how to implement custom serialization with a simple " -"example." -msgstr "下面我们将通过一个简单的示例来探讨如何实现自定义序列化。" +"In the next notebook, we're going to cover some more advanced concepts. " +"Want to customize your strategy? Initialize parameters on the server " +"side? Or evaluate the aggregated model on the server side? We'll cover " +"all this and more in the next tutorial." +msgstr "在下一个笔记中,我们将介绍一些更先进的概念。想定制你的策略吗?在服务器端初始化参数?或者在服务器端评估聚合模型?我们将在下一个教程中介绍所有这些内容以及更多。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:514 +#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 msgid "" -"But first what is serialization? Serialization is just the process of " -"converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an object. " -"This is very useful for network communication. Indeed, without " -"serialization, you could not just a Python object through the internet." +"The `Flower Federated Learning Tutorial - Part 2 " +"`__ goes into more depth about strategies and all " +"the advanced things you can build with them." msgstr "" -"首先,什么是序列化?序列化只是将对象转换为原始字节的过程,同样重要的是,反序" -"列化是将原始字节转换回对象的过程。这对网络通信非常有用。事实上,如果没有序列" -"化,你就无法通过互联网传输一个 Python 对象。" +"`Flower 联邦学习教程 - 第 2 部分 `__ 更深入地介绍了策略以及可以使用策略构建的所有高级功能。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 +msgid "Use a federated learning strategy" +msgstr "使用联邦学习策略" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 msgid "" -"Federated Learning relies heavily on internet communication for training by " -"sending Python objects back and forth between the clients and the server. " -"This means that serialization is an essential part of Federated Learning." +"Welcome to the next part of the federated learning tutorial. In previous " +"parts of this tutorial, we introduced federated learning with PyTorch and" +" Flower (`part 1 `__)." msgstr "" -"通过在客户端和服务器之间来回发送 Python 对象,联合学习在很大程度上依赖于互联" -"网通信进行训练。这意味着序列化是联邦学习的重要组成部分。" +"欢迎来到联邦学习教程的下一部分。在本教程的前几部分,我们介绍了使用 PyTorch 和 Flower 进行联邦学习(`第 1 部分 " +"`___)。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 msgid "" -"In the following section, we will write a basic example where instead of " -"sending a serialized version of our ``ndarray``\\ s containing our " -"parameters, we will first convert the ``ndarray`` into sparse matrices, " -"before sending them. This technique can be used to save bandwidth, as in " -"certain cases where the weights of a model are sparse (containing many 0 " -"entries), converting them to a sparse matrix can greatly improve their " -"bytesize." +"In this notebook, we'll begin to customize the federated learning system " +"we built in the introductory notebook (again, using `Flower " +"`__ and `PyTorch `__)." msgstr "" -"在下面的章节中,我们将编写一个基本示例,在发送包含参数的 ``ndarray`` 前,我们" -"将首先把 ``ndarray`` 转换为稀疏矩阵,而不是发送序列化版本。这种技术可以用来节" -"省带宽,因为在某些情况下,模型的参数是稀疏的(包含许多 0 条目),将它们转换成" -"稀疏矩阵可以大大提高它们的字节数。" +"在本笔记中,我们将开始定制在入门笔记中构建的联邦学习系统(再次使用 `Flower `__ 和 " +"`PyTorch `__)。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:521 -msgid "Our custom serialization/deserialization functions" -msgstr "我们的定制序列化/反序列化功能" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 +msgid "Let's move beyond FedAvg with Flower strategies!" +msgstr "让我们超越 FedAvg,采用Flower策略!" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 -msgid "" -"This is where the real serialization/deserialization will happen, especially " -"in ``ndarray_to_sparse_bytes`` for serialization and " -"``sparse_bytes_to_ndarray`` for deserialization." -msgstr "" -"这才是真正的序列化/反序列化,尤其是在用于序列化的 " -"``ndarray_too_sparse_bytes`` 和用于反序列化的 ``sparse_bytes_too_ndarray`` " -"中。" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 +msgid "Strategy customization" +msgstr "策略定制" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert our " -"arrays." -msgstr "请注意,为了转换数组,我们导入了 ``scipy.sparse`` 库。" +"So far, everything should look familiar if you've worked through the " +"introductory notebook. With that, we're ready to introduce a number of " +"new features." +msgstr "到目前为止,如果您已经阅读过入门笔记本,那么一切都应该很熟悉了。接下来,我们将介绍一些新功能。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 -msgid "Client-side" -msgstr "客户端" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 +msgid "Server-side parameter **initialization**" +msgstr "服务器端参数 **初始化**" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we will " -"just have to call our custom functions in our ``flwr.client.Client``." +"Flower, by default, initializes the global model by asking one random " +"client for the initial parameters. In many cases, we want more control " +"over parameter initialization though. Flower therefore allows you to " +"directly pass the initial parameters to the Strategy:" msgstr "" -"为了能够将我们的 ``ndarray`` 序列化为稀疏参数,我们只需在 ``flwr.client." -"Client`` 中调用我们的自定义函数。" +"默认情况下,Flower 会通过向一个随机客户端询问初始参数来初始化全局模型。但在许多情况下,我们需要对参数初始化进行更多控制。因此,Flower" +" 允许您直接将初始参数传递给策略:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 msgid "" -"Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` defined " -"above." +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" +" from asking one of the clients for the initial parameters. If we look " +"closely, we can see that the logs do not show any calls to the " +"``FlowerClient.get_parameters`` method." msgstr "" -"事实上,在 `get_parameters` 中,我们需要使用上文定义的自定义 " -"`ndarrays_too_sparse_parameters` 序列化从网络中获取的参数。" +"向 ``FedAvg`` 策略传递 ``initial_parameters`` 可以防止 Flower " +"向其中一个客户端询问初始参数。如果我们仔细观察,就会发现日志中没有显示对 ``FlowerClient.get_parameters`` " +"方法的任何调用。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 +msgid "Starting with a customized strategy" +msgstr "从定制战略开始" + +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 msgid "" -"In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we need " -"to serialize our local results with ``ndarrays_to_sparse_parameters``." +"We've seen the function ``start_simulation`` before. It accepts a number " +"of arguments, amongst them the ``client_fn`` used to create " +"``FlowerClient`` instances, the number of clients to simulate " +"``num_clients``, the number of rounds ``num_rounds``, and the strategy." msgstr "" -"在 ``fit`` 中,我们首先需要使用自定义的 ``sparse_parameters_to_ndarrays`` 反" -"序列化来自服务器的参数,然后使用 ``ndarrays_to_sparse_parameters`` 序列化本地" -"结果。" +"我们以前见过函数 ``start_simulation``。它接受许多参数,其中包括用于创建 ``FlowerClient`` 实例的 " +"``client_fn``、要模拟的客户数量 ``num_clients``、回合数 ``num_rounds``和策略。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters with " -"our custom function." -msgstr "在 ``evaluate`` 中,我们只需要用自定义函数反序列化全局参数。" +"The strategy encapsulates the federated learning approach/algorithm, for " +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " +"strategy this time:" +msgstr "该策略封装了联邦学习方法/算法,例如`FedAvg``或`FedAdagrad``。这次让我们尝试使用不同的策略:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 -msgid "Server-side" -msgstr "服务器端" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 +msgid "Server-side parameter **evaluation**" +msgstr "服务器端参数**评估**" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change the " -"serialization and deserialization here, we only need to reimplement the " -"``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other " -"functions of the strategy will be inherited from the super class ``FedAvg``." -msgstr "" -"在本例中,我们将只使用 ``FedAvg`` 作为策略。要改变这里的序列化和反序列化,我" -"们只需重新实现 ``FedAvg`` 的 ``evaluate`` 和 ``aggregate_fit`` 函数。策略的其" -"他函数将从超类 ``FedAvg`` 继承。" +"Flower can evaluate the aggregated model on the server-side or on the " +"client-side. Client-side and server-side evaluation are similar in some " +"ways, but different in others." +msgstr "Flower 可以在服务器端或客户端评估聚合模型。客户端和服务器端评估在某些方面相似,但也有不同之处。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 -msgid "As you can see only one line as change in ``evaluate``:" -msgstr "正如你所看到的,``evaluate``中只修改了一行:" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 +msgid "" +"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " +"simple: it works the same way that evaluation in centralized machine " +"learning does. If there is a server-side dataset that can be used for " +"evaluation purposes, then that's great. We can evaluate the newly " +"aggregated model after each round of training without having to send the " +"model to clients. We're also fortunate in the sense that our entire " +"evaluation dataset is available at all times." +msgstr "**集中评估**(或*服务器端评估*)在概念上很简单:它的工作方式与集中式机器学习中的评估方式相同。如果有一个服务器端数据集可用于评估目的,那就太好了。我们可以在每一轮训练后对新聚合的模型进行评估,而无需将模型发送给客户端。我们也很幸运,因为我们的整个评估数据集随时可用。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:735 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 msgid "" -"And for ``aggregate_fit``, we will first deserialize every result we " -"received:" -msgstr "而对于 ``aggregate_fit``,我们将首先反序列化收到的每个结果:" +"**Federated Evaluation** (or *client-side evaluation*) is more complex, " +"but also more powerful: it doesn't require a centralized dataset and " +"allows us to evaluate models over a larger set of data, which often " +"yields more realistic evaluation results. In fact, many scenarios require" +" us to use **Federated Evaluation** if we want to get representative " +"evaluation results at all. But this power comes at a cost: once we start " +"to evaluate on the client side, we should be aware that our evaluation " +"dataset can change over consecutive rounds of learning if those clients " +"are not always available. Moreover, the dataset held by each client can " +"also change over consecutive rounds. This can lead to evaluation results " +"that are not stable, so even if we would not change the model, we'd see " +"our evaluation results fluctuate over consecutive rounds." +msgstr "**联邦评估**(或*客户端评估*)更为复杂,但也更为强大:它不需要集中的数据集,允许我们在更大的数据集上对模型进行评估,这通常会产生更真实的评估结果。事实上,如果我们想得到有代表性的评估结果,很多情况下都需要使用**联邦评估**。但是,这种能力是有代价的:一旦我们开始在客户端进行评估,我们就应该意识到,如果这些客户端并不总是可用,我们的评估数据集可能会在连续几轮学习中发生变化。此外,每个客户端所拥有的数据集也可能在连续几轮学习中发生变化。这可能会导致评估结果不稳定,因此即使我们不改变模型,也会看到评估结果在连续几轮中波动。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:744 -msgid "And then serialize the aggregated result:" -msgstr "然后将汇总结果序列化:" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +msgid "" +"We've seen how federated evaluation works on the client side (i.e., by " +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " +"how we can evaluate aggregated model parameters on the server-side:" +msgstr "" +"我们已经了解了联邦评估如何在客户端工作(即通过在 ``FlowerClient`` 中实现 ``evaluate`` " +"方法)。现在让我们看看如何在服务器端评估聚合模型参数:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:903 -msgid "We can now run our custom serialization example!" -msgstr "现在我们可以运行自定义序列化示例!" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 +msgid "Sending/receiving arbitrary values to/from clients" +msgstr "向/从客户端发送/接收任意值" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:934 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 msgid "" -"In this part of the tutorial, we've seen how we can build clients by " -"subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine learning " -"libraries that have good NumPy interoperability. ``Client`` is a more " -"flexible abstraction that allows us to do things that are not possible in " -"``NumPyClient``. In order to do so, it requires us to handle parameter " -"serialization and deserialization ourselves." -msgstr "" -"在本部分教程中,我们已经了解了如何通过子类化 ``NumPyClient`` 或 ``Client`` 来" -"构建客户端。NumPyClient \"是一个便捷的抽象类,可以让我们更容易地与具有良好" -"NumPy互操作性的机器学习库一起工作。``Client``是一个更灵活的抽象类,允许我们做" -"一些在`NumPyClient``中做不到的事情。为此,它要求我们自己处理参数序列化和反序" -"列化。" +"In some situations, we want to configure client-side execution (training," +" evaluation) from the server-side. One example for that is the server " +"asking the clients to train for a certain number of local epochs. Flower " +"provides a way to send configuration values from the server to the " +"clients using a dictionary. Let's look at an example where the clients " +"receive values from the server through the ``config`` parameter in " +"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " +"method receives the configuration dictionary through the ``config`` " +"parameter and can then read values from this dictionary. In this example," +" it reads ``server_round`` and ``local_epochs`` and uses those values to " +"improve the logging and configure the number of local training epochs:" +msgstr "" +"在某些情况下,我们希望从服务器端配置客户端的执行(训练、评估)。其中一个例子就是服务器要求客户端训练一定数量的本地遍历。Flower " +"提供了一种使用字典从服务器向客户端发送配置值的方法。让我们来看一个例子:客户端通过 ``fit`` 中的 ``config`` " +"参数从服务器接收配置值(``evaluate`` 中也有 ``config`` 参数)。``fit`` 方法通过 ``config`` " +"参数接收配置字典,然后从字典中读取值。在本例中,它读取了 ``server_round`` 和 " +"``local_epochs``,并使用这些值来改进日志记录和配置本地训练遍历的数量:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 msgid "" -"This is the final part of the Flower tutorial (for now!), congratulations! " -"You're now well equipped to understand the rest of the documentation. There " -"are many topics we didn't cover in the tutorial, we recommend the following " -"resources:" +"So how can we send this config dictionary from server to clients? The " +"built-in Flower Strategies provide way to do this, and it works similarly" +" to the way server-side evaluation works. We provide a function to the " +"strategy, and the strategy calls this function for every round of " +"federated learning:" msgstr "" -"这暂时是 Flower 教程的最后一部分,恭喜您!您现在已经具备了理解其余文档的能" -"力。本教程还有许多内容没有涉及,我们推荐您参考以下资源:" - -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 -msgid "`Read Flower Docs `__" -msgstr "阅读Flower文档 `__" +"那么,如何将配置字典从服务器发送到客户端呢?内置的 \"Flower策略\"(Flower " +"Strategies)提供了这样的方法,其工作原理与服务器端评估的工作原理类似。我们为策略提供一个函数,策略会在每一轮联邦学习中调用这个函数:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 msgid "" -"`Check out Flower Code Examples `__" -msgstr "" -"查看 Flower 代码示例 `__" +"Next, we'll just pass this function to the FedAvg strategy before " +"starting the simulation:" +msgstr "接下来,我们只需在开始模拟前将此函数传递给 FedAvg 策略即可:" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 msgid "" -"`Use Flower Baselines for your research `__" +"As we can see, the client logs now include the current round of federated" +" learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second" +" round of federated learning, and then for two epochs during the third " +"round." msgstr "" -"使用 \"Flower Baselines \"进行研究 `__" +"我们可以看到,客户端日志现在包含了当前一轮的联邦学习(从 ``config`` " +"字典中读取)。我们还可以将本地训练配置为在第一轮和第二轮联邦学习期间运行一个遍历,然后在第三轮联邦学习期间运行两个遍历。" -#: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 msgid "" -"`Watch Flower Summit 2023 videos `__" +"Clients can also return arbitrary values to the server. To do so, they " +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " +"used this concept throughout this notebook without mentioning it " +"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" +" key/value pair as the third return value in ``evaluate``." msgstr "" -"观看 2023 年Flower峰会视频 `__" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 -msgid "Get started with Flower" -msgstr "开始使用Flower" +"客户端还可以向服务器返回任意值。为此,它们会从 ``fit`` 和/或 ``evaluate`` " +"返回一个字典。我们在本笔记中看到并使用了这一概念,但并未明确提及:我们的 ``FlowerClient`` 返回一个包含自定义键/值对的字典,作为" +" ``evaluate`` 中的第三个返回值。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:11 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:11 -msgid "Welcome to the Flower federated learning tutorial!" -msgstr "欢迎阅读Flower联邦学习教程!" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 +msgid "Scaling federated learning" +msgstr "扩大联邦学习的规模" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 -#, fuzzy +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 msgid "" -"In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In part " -"1, we use PyTorch for the model training pipeline and data loading. In part " -"2, we continue to federate the PyTorch-based pipeline using Flower." -msgstr "" -"在本笔记中,我们将使用 Flower 和 PyTorch 构建一个联邦学习系统。在第一部分中," -"我们使用 PyTorch 进行模型训练和数据加载。在第二部分中,我们将继续使用 Flower " -"联邦化基于 PyTorch 的框架。" +"As a last step in this notebook, let's see how we can use Flower to " +"experiment with a large number of clients." +msgstr "作为本笔记的最后一步,让我们看看如何使用 Flower 对大量客户端进行实验。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 -msgid "Let's get stated!" -msgstr "让我们开始吧!" +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 +#, python-format +msgid "" +"We now have 1000 partitions, each holding 45 training and 5 validation " +"examples. Given that the number of training examples on each client is " +"quite small, we should probably train the model a bit longer, so we " +"configure the clients to perform 3 local training epochs. We should also " +"adjust the fraction of clients selected for training during each round " +"(we don't want all 1000 clients participating in every round), so we " +"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " +"available clients (so 50 clients) will be selected for training each " +"round:" +msgstr "" +"现在我们有 1000 个分区,每个分区有 45 个训练数据和 5 " +"个验证数据。鉴于每个客户端上的训练示例数量较少,我们可能需要对模型进行更长时间的训练,因此我们将客户端配置为执行 3 " +"个本地训练遍历。我们还应该调整每轮训练中被选中的客户端的比例(我们不希望每轮训练都有 1000 个客户端参与),因此我们将 " +"``fraction_fit`` 调整为 ``0.05``,这意味着每轮训练只选中 5%的可用客户端(即 50 个客户端):" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:31 +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 msgid "" -"Before we begin with any actual code, let's make sure that we have " -"everything we need." -msgstr "在开始编写实际代码之前,让我们先确保我们已经准备好了所需的一切。" +"In this notebook, we've seen how we can gradually enhance our system by " +"customizing the strategy, initializing parameters on the server side, " +"choosing a different strategy, and evaluating models on the server-side. " +"That's quite a bit of flexibility with so little code, right?" +msgstr "在本笔记中,我们看到了如何通过自定义策略、在服务器端初始化参数、选择不同的策略以及在服务器端评估模型来逐步增强我们的系统。用这么少的代码就能实现这么大的灵活性,不是吗?" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 -#, fuzzy +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 msgid "" -"Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower (``flwr``):" +"In the later sections, we've seen how we can communicate arbitrary values" +" between server and clients to fully customize client-side execution. " +"With that capability, we built a large-scale Federated Learning " +"simulation using the Flower Virtual Client Engine and ran an experiment " +"involving 1000 clients in the same workload - all in a Jupyter Notebook!" msgstr "" -"接下来,我们为 PyTorch(`torch`` 和`torchvision``)和 Flower(`flwr`)安装必" -"要的软件包:" +"在后面的章节中,我们将看到如何在服务器和客户端之间传递任意值,以完全自定义客户端执行。有了这种能力,我们使用 Flower " +"虚拟客户端引擎构建了一个大规模的联邦学习模拟,并在 Jupyter Notebook 中进行了一次实验,在相同的工作负载中运行了 1000 " +"个客户端!" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 -#, fuzzy +#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled (on " -"Google Colab: ``Runtime > Change runtime type > Hardware accelerator: GPU > " -"Save``). Note, however, that Google Colab is not always able to offer GPU " -"acceleration. If you see an error related to GPU availability in one of the " -"following sections, consider switching back to CPU-based execution by " -"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " -"acceleration enabled, you should see the output ``Training on cuda``, " -"otherwise it'll say ``Training on cpu``." +"The `Flower Federated Learning Tutorial - Part 3 " +"`__ shows how to build a fully custom ``Strategy`` from " +"scratch." msgstr "" -"可以切换到已启用 GPU 加速的运行时(在 Google Colab 上: 运行时 > 更改运行时类" -"型 > 硬件加速: GPU > 保存``)。但请注意,Google Colab 并非总能提供 GPU 加" -"速。如果在以下部分中看到与 GPU 可用性相关的错误,请考虑通过设置 ``DEVICE = " -"torch.device(\"cpu\")`` 切回基于 CPU 的执行。如果运行时已启用 GPU 加速,你应" -"该会看到输出``Training on cuda``,否则会显示``Training on cpu``。" +"`Flower 联邦学习教程 - 第 3 部分 `__ 展示了如何从头开始构建完全自定义的 \"策略\"。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 -msgid "Loading the data" -msgstr "加载数据" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 +msgid "What is Federated Learning?" +msgstr "什么是联邦学习?" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 -#, fuzzy +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 msgid "" -"Federated learning can be applied to many different types of tasks across " -"different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular CIFAR-10 " -"dataset. CIFAR-10 can be used to train image classifiers that distinguish " -"between images from ten different classes: 'airplane', 'automobile', 'bird', " -"'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and 'truck'." +"In this tutorial, you will learn what federated learning is, build your " +"first system in Flower, and gradually extend it. If you work through all " +"parts of the tutorial, you will be able to build advanced federated " +"learning systems that approach the current state of the art in the field." msgstr "" -"联邦学习可应用于不同领域的多种不同类型任务。在本教程中,我们将通过在流行的 " -"CIFAR-10 数据集上训练一个简单的卷积神经网络 (CNN) 来介绍联合学习。CIFAR-10 可" -"用于训练图像分类器,以区分来自十个不同类别的图像:" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 -msgid "" -"We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the " -"original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely for " -"experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the data " -"is naturally partitioned)." -msgstr "" -"我们通过将原始 CIFAR-10 数据集拆分成多个分区来模拟来自多个组织的多个数据集" -"(也称为联邦学习中的 \"跨分区 \"设置)。每个分区代表一个组织的数据。我们这样" -"做纯粹是为了实验目的,在现实世界中不需要拆分数据,因为每个组织都已经有了自己" -"的数据(所以数据是自然分区的)。" +"在本教程中,你将了解什么是联邦学习,用 Flower " +"搭建第一个系统,并逐步对其进行扩展。如果你能完成本教程的所有部分,你就能构建高级的联邦学习系统,从而接近该领域当前的技术水平。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 -#, fuzzy +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 msgid "" -"Each organization will act as a client in the federated learning system. So " -"having ten organizations participate in a federation means having ten " -"clients connected to the federated learning server." -msgstr "" -"每个组织都将充当联邦学习系统中的客户端。因此,有十个组织参与联邦学习,就意味" -"着有十个客户端连接到联邦学习服务器:" +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " +"federated learning. Only a basic understanding of data science and Python" +" programming is assumed." +msgstr "🧑‍🏫 本教程从零开始,不要求熟悉联邦学习。仅假定对数据科学和 Python 编程有基本了解。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 msgid "" -"Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training and " -"test set for each edge device and wrap each of them into a PyTorch " -"``DataLoader``:" +"`Star Flower on GitHub `__ ⭐️ and join " +"the open-source Flower community on Slack to connect, ask questions, and " +"get help: `Join Slack `__ 🌼 We'd love to " +"hear from you in the ``#introductions`` channel! And if anything is " +"unclear, head over to the ``#questions`` channel." msgstr "" +"`Star Flower on GitHub `__ ⭐️ 并加入 Slack " +"上的开源 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼" +" 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何不清楚的地方,请访问 ``#questions`` 频道。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 -msgid "" -"We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten different " -"organizations. Each ``trainloader``/``valloader`` pair contains 4500 " -"training examples and 500 validation examples. There's also a single " -"``testloader`` (we did not split the test set). Again, this is only " -"necessary for building research or educational systems, actual federated " -"learning systems have their data naturally distributed across multiple " -"partitions." -msgstr "" -"现在,我们有一个包含十个训练集和十个验证集(`trainloaders`` 和`valloaders``)" -"的列表,代表十个不同组织的数据。每对 ``trainloader``/``valloader`` 都包含 " -"4500 个训练示例和 500 个验证数据。还有一个单独的 ``测试加载器``(我们没有拆分" -"测试集)。同样,这只有在构建研究或教育系统时才有必要,实际的联邦学习系统的数" -"据自然分布在多个分区中。" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 +msgid "Classic machine learning" +msgstr "经典机器学习" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 msgid "" -"Let's take a look at the first batch of images and labels in the first " -"training set (i.e., ``trainloaders[0]``) before we move on:" -msgstr "" -"在继续之前,让我们先看看第一个训练集中的第一批图像和标签(即 " -"``trainloaders[0]``):" +"Before we begin to discuss federated learning, let us quickly recap how " +"most machine learning works today." +msgstr "在开始讨论联邦学习之前,让我们先快速回顾一下目前大多数机器学习的工作原理。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:240 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 msgid "" -"The output above shows a random batch of images from the first " -"``trainloader`` in our list of ten ``trainloaders``. It also prints the " -"labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another batch " -"of images." -msgstr "" -"上面的输出显示了来自十个 \"trainloader \"列表中第一个 \"trainloader \"的随机" -"图像。它还打印了与每幅图像相关的标签(即我们上面看到的十个可能标签之一)。如" -"果您再次运行该单元,应该会看到另一批图像。" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 -msgid "Step 1: Centralized Training with PyTorch" -msgstr "步骤 1:使用 PyTorch 进行集中训练" +"In machine learning, we have a model, and we have data. The model could " +"be a neural network (as depicted here), or something else, like classical" +" linear regression." +msgstr "在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可以是其他东西,比如经典的线性回归。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:263 -msgid "" -"Next, we're going to use PyTorch to define a simple convolutional neural " -"network. This introduction assumes basic familiarity with PyTorch, so it " -"doesn't cover the PyTorch-related aspects in full detail. If you want to " -"dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ `__." +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 +msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" msgstr "" -"接下来,我们将使用 PyTorch 来定义一个简单的卷积神经网络。本介绍假定您对 " -"PyTorch 有基本的了解,因此不会详细介绍与 PyTorch 相关的内容。如果你想更深入地" -"了解 PyTorch,我们推荐你阅读 `DEEP LEARNING WITH PYTORCH: a 60 minute blitz " -"`__。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 -msgid "Defining the model" -msgstr "定义模型" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 +msgid "Model and data" +msgstr "模型和数据" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 msgid "" -"We use the simple CNN described in the `PyTorch tutorial `__:" -msgstr "" -"我们使用` PyTorch 教程 `__ 中描述的简单 " -"CNN:" +"We train the model using the data to perform a useful task. A task could " +"be to detect objects in images, transcribe an audio recording, or play a " +"game like Go." +msgstr "我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转录音频或玩围棋等游戏。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 -msgid "Let's continue with the usual training and test functions:" -msgstr "让我们继续进行常规的训练和测试功能:" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 +msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgstr "" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:374 -msgid "Training the model" -msgstr "训练模型" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 +msgid "Train model using data" +msgstr "使用数据训练模型" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 msgid "" -"We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train the " -"model on the dataset of one of our organizations (``trainloaders[0]``). This " -"simulates the reality of most machine learning projects today: each " -"organization has their own data and trains models only on this internal data:" -msgstr "" -"现在我们拥有了所需的所有基本构件:数据集、模型、训练函数和测试函数。让我们把" -"它们放在一起,在我们其中一个组织的数据集(``trainloaders[0]``)上训练模型。这" -"模拟了当今大多数机器学习项目的实际情况:每个组织都有自己的数据,并且只在这些" -"内部数据上训练模型:" +"Now, in practice, the training data we work with doesn't originate on the" +" machine we train the model on. It gets created somewhere else." +msgstr "实际上,我们使用的训练数据并不来自我们训练模型的机器。它是在其他地方创建的。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result in " -"a test set accuracy of about 41%, which is not good, but at the same time, " -"it doesn't really matter for the purposes of this tutorial. The intent was " -"just to show a simplistic centralized training pipeline that sets the stage " -"for what comes next - federated learning!" +"It originates on a smartphone by the user interacting with an app, a car " +"collecting sensor data, a laptop receiving input via the keyboard, or a " +"smart speaker listening to someone trying to sing a song." +msgstr "它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键盘输入的接收,或者智能扬声器上某人试着唱的歌。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 +msgid "|2bc8e069228d4873804061ff4a95048c|" msgstr "" -"在我们的 CIFAR-10 分片上对简单 CNN 进行 5 个遍历的训练后,测试集的准确率应为 " -"41%,这并不理想,但同时对本教程而言也并不重要。我们只是想展示一个简单的集中式" -"训练流程,为接下来的联邦学习做好铺垫!" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 -msgid "Step 2: Federated Learning with Flower" -msgstr "步骤 2:使用 Flower 联邦学习" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 +msgid "Data on a phone" +msgstr "手机上的数据" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was in " -"one place (i.e., a single ``trainloader`` and a single ``valloader``). Next, " -"we'll simulate a situation where we have multiple datasets in multiple " -"organizations and where we train a model over these organizations using " -"federated learning." +"What's also important to mention, this \"somewhere else\" is usually not " +"just one place, it's many places. It could be several devices all running" +" the same app. But it could also be several organizations, all generating" +" data for the same task." msgstr "" -"步骤 1 演示了一个简单的集中式训练流程。所有数据都在一个地方(即一个 " -"\"trainloader \"和一个 \"valloader\")。接下来,我们将模拟在多个组织中拥有多" -"个数据集的情况,并使用联邦学习在这些组织中训练一个模型。" - -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 -msgid "Updating model parameters" -msgstr "更新模型参数" +"值得一提的是,这个 \"其他地方 " +"\"通常不只是一个地方,而是很多地方。它可能是多个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 -msgid "" -"In federated learning, the server sends the global model parameters to the " -"client, and the client updates the local model with the parameters received " -"from the server. It then trains the model on the local data (which changes " -"the model parameters locally) and sends the updated/changed model parameters " -"back to the server (or, alternatively, it sends just the gradients back to " -"the server, not the full model parameters)." +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 +msgid "|c258488766324dc9a6807f0e7c4fd5f4|" msgstr "" -"在联邦学习中,服务器将全局模型参数发送给客户端,客户端根据从服务器接收到的参" -"数更新本地模型。然后,客户端根据本地数据对模型进行训练(在本地更改模型参" -"数),并将更新/更改后的模型参数发回服务器(或者,客户端只将梯度参数发回服务" -"器,而不是全部模型参数)。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 +msgid "Data is on many devices" +msgstr "数据存在于多种设备中" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 msgid "" -"We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the " -"local model: ``set_parameters`` and ``get_parameters``. The following two " -"functions do just that for the PyTorch model above." +"So to use machine learning, or any kind of data analysis, the approach " +"that has been used in the past was to collect all data on a central " +"server. This server can be somewhere in a data center, or somewhere in " +"the cloud." +msgstr "因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 +msgid "|d5f962c3f4ec48529efda980868c14b0|" msgstr "" -"我们需要两个辅助函数,用从服务器接收到的参数更新本地模型,并从本地模型获取更" -"新后的模型参数:`` set_parameters```和`get_parameters``。下面两个函数就是为上" -"面的 PyTorch 模型做这些工作的。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 +msgid "Central data collection" +msgstr "集中数据收集" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 msgid "" -"The details of how this works are not really important here (feel free to " -"consult the PyTorch documentation if you want to learn more). In essence, we " -"use ``state_dict`` to access PyTorch model parameter tensors. The parameter " -"tensors are then converted to/from a list of NumPy ndarray's (which Flower " -"knows how to serialize/deserialize):" +"Once all the data is collected in one place, we can finally use machine " +"learning algorithms to train our model on the data. This is the machine " +"learning approach that we've basically always relied on." +msgstr "一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模型。这就是我们基本上一直依赖的机器学习方法。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 +msgid "|a5eccea18d4c43a68b54b65043cabef8|" msgstr "" -"在这里,如何工作的细节并不重要(如果你想了解更多,请随时查阅 PyTorch 文档)。" -"本质上,我们使用 ``state_dict`` 访问 PyTorch 模型参数张量。然后,参数张量会被" -"转换成/转换成 NumPy ndarray 列表(Flower 知道如何序列化/反序列化):" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 -msgid "Implementing a Flower client" -msgstr "实现 Flower 客户端" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 +msgid "Central model training" +msgstr "集中模型训练" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 +msgid "Challenges of classical machine learning" +msgstr "经典机器学习面临的挑战" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 msgid "" -"With that out of the way, let's move on to the interesting part. Federated " -"learning systems consist of a server and multiple clients. In Flower, we " -"create clients by implementing subclasses of ``flwr.client.Client`` or " -"``flwr.client.NumPyClient``. We use ``NumPyClient`` in this tutorial because " -"it is easier to implement and requires us to write less boilerplate." +"The classic machine learning approach we've just seen can be used in some" +" cases. Great examples include categorizing holiday photos, or analyzing " +"web traffic. Cases, where all the data is naturally available on a " +"centralized server." +msgstr "我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 +msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" msgstr "" -"说完这些,让我们进入有趣的部分。联邦学习系统由一个服务器和多个客户端组成。在 " -"Flower 中,我们通过实现 ``flwr.client.Client`` 或 ``flwr.client." -"NumPyClient`` 的子类来创建客户端。在本教程中,我们使用``NumPyClient``,因为它" -"更容易实现,需要我们编写的模板也更少。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 +msgid "Centralized possible" +msgstr "可集中管理" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 msgid "" -"To implement the Flower client, we create a subclass of ``flwr.client." -"NumPyClient`` and implement the three methods ``get_parameters``, ``fit``, " -"and ``evaluate``:" +"But the approach can not be used in many other cases. Cases, where the " +"data is not available on a centralized server, or cases where the data " +"available on one server is not enough to train a good model." +msgstr "但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器上的数据不足以训练出一个好的模型。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 +msgid "|241fc906441a4f038c625a19d30d01b2|" msgstr "" -"为实现 Flower 客户端,我们创建了 ``flwr.client.NumPyClient`` 的子类,并实现" -"了 ``get_parameters``、``fit`` 和``evaluate`` 三个方法:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 -msgid "``get_parameters``: Return the current local model parameters" -msgstr "``get_parameters``: 返回当前本地模型参数" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 +msgid "Centralized impossible" +msgstr "无法集中" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 msgid "" -"``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters to " -"the server" -msgstr "" -"``fit``: 从服务器接收模型参数,在本地数据上训练模型参数,并将(更新的)模型" -"参数返回服务器" +"There are many reasons why the classic centralized machine learning " +"approach does not work for a large number of highly important real-world " +"use cases. Those reasons include:" +msgstr "传统的集中式机器学习方法无法满足现实世界中大量极为重要的使用案例,原因有很多。这些原因包括:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the model " -"parameters on the local data, and return the evaluation result to the server" +"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " +"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " +"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " +"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " +"protect sensitive data from being moved. In fact, those regulations " +"sometimes even prevent single organizations from combining their own " +"users' data for artificial intelligence training because those users live" +" in different parts of the world, and their data is governed by different" +" data protection regulations." msgstr "" -"``evaluate ``: 从服务器接收模型参数,在本地数据上评估模型参数,并将评估结果" -"返回服务器" +"**法规**: " +"GDPR(欧洲)、CCPA(加利福尼亚)、PIPEDA(加拿大)、LGPD(巴西)、PDPL(阿根廷)、KVKK(土耳其)、POPI(南非)、FSS(俄罗斯)、CDPR(中国)、PDPB(印度)、PIPA(韩国)、APPI(日本)、PDP(印度尼西亚)、PDPA(新加坡)、APP(澳大利亚)等法规保护敏感数据不被移动。事实上,这些法规有时甚至会阻止单个组织将自己的用户数据用于人工智能培训,因为这些用户生活在世界不同地区,他们的数据受不同的数据保护法规管辖。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 msgid "" -"We mentioned that our clients will use the previously defined PyTorch " -"components for model training and evaluation. Let's see a simple Flower " -"client implementation that brings everything together:" +"**User preference**: In addition to regulation, there are use cases where" +" users just expect that no data leaves their device, ever. If you type " +"your passwords and credit card info into the digital keyboard of your " +"phone, you don't expect those passwords to end up on the server of the " +"company that developed that keyboard, do you? In fact, that use case was " +"the reason federated learning was invented in the first place." msgstr "" -"我们提到,我们的客户端将使用之前定义的 PyTorch 组件进行模型训练和评估。让我们" -"来看看一个简单的 Flower 客户端实现,它将一切都整合在一起:" +"**用户偏好**: " +"除了法规之外,在一些使用案例中,用户只是希望数据永远不会离开他们的设备。如果你在手机的数字键盘上输入密码和信用卡信息,你不会希望这些密码最终出现在开发该键盘的公司的服务器上吧?事实上,这种用例正是联邦学习发明的初衷。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 msgid "" -"Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through " -"``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a " -"*single client* in our federated learning system. Federated learning systems " -"have multiple clients (otherwise, there's not much to federate), so each " -"client will be represented by its own instance of ``FlowerClient``. If we " -"have, for example, three clients in our workload, then we'd have three " -"instances of ``FlowerClient``. Flower calls ``FlowerClient.fit`` on the " -"respective instance when the server selects a particular client for training " -"(and ``FlowerClient.evaluate`` for evaluation)." -msgstr "" -"我们的类 ``FlowerClient`` 定义了本地训练/评估的执行方式,并允许 Flower 通过 " -"``fit`` 和 ``evaluate`` 调用本地训练/评估。每个 ``FlowerClient`` 实例都代表联" -"邦学习系统中的*单个客户端*。联邦学习系统有多个客户端(否则就没有什么可联邦" -"的),因此每个客户端都将由自己的 ``FlowerClient`` 实例来代表。例如,如果我们" -"的工作负载中有三个客户端,那么我们就会有三个 ``FlowerClient`` 实例。当服务器" -"选择特定客户端进行训练时,Flower 会调用相应实例上的 ``FlowerClient.fit`` (评" -"估时调用 ``FlowerClient.evaluate``)。" +"**Data volume**: Some sensors, like cameras, produce such a high data " +"volume that it is neither feasible nor economic to collect all the data " +"(due to, for example, bandwidth or communication efficiency). Think about" +" a national rail service with hundreds of train stations across the " +"country. If each of these train stations is outfitted with a number of " +"security cameras, the volume of raw on-device data they produce requires " +"incredibly powerful and exceedingly expensive infrastructure to process " +"and store. And most of the data isn't even useful." +msgstr "" +"**数据量**: " +"有些传感器(如摄像头)产生的数据量很大,收集所有数据既不可行,也不经济(例如,由于带宽或通信效率的原因)。试想一下全国铁路服务,全国有数百个火车站。如果每个火车站都安装了许多安全摄像头,那么它们所产生的大量原始设备数据就需要功能强大且极其昂贵的基础设施来处理和存储。而大部分数据甚至都是无用的。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 -msgid "Using the Virtual Client Engine" -msgstr "使用虚拟客户端引擎" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 +msgid "Examples where centralized machine learning does not work include:" +msgstr "集中式机器学习不起作用的例子包括:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 msgid "" -"In this notebook, we want to simulate a federated learning system with 10 " -"clients on a single machine. This means that the server and all 10 clients " -"will live on a single machine and share resources such as CPU, GPU, and " -"memory. Having 10 clients would mean having 10 instances of ``FlowerClient`` " -"in memory. Doing this on a single machine can quickly exhaust the available " -"memory resources, even if only a subset of these clients participates in a " -"single round of federated learning." -msgstr "" -"在本笔记中,我们要模拟一个联邦学习系统,在一台机器上有 10 个客户端。这意味着" -"服务器和所有 10 个客户端都将位于一台机器上,并共享 CPU、GPU 和内存等资源。有 " -"10 个客户端就意味着内存中有 10 个 ``FlowerClient`` 实例。在单台机器上这样做会" -"很快耗尽可用的内存资源,即使这些客户端中只有一个子集参与了一轮联邦学习。" +"Sensitive healthcare records from multiple hospitals to train cancer " +"detection models" +msgstr "用多家医院的敏感医疗记录训练癌症检测模型" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 msgid "" -"In addition to the regular capabilities where server and clients run on " -"multiple machines, Flower, therefore, provides special simulation " -"capabilities that create ``FlowerClient`` instances only when they are " -"actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a function " -"called ``client_fn`` that creates a ``FlowerClient`` instance on demand. " -"Flower calls ``client_fn`` whenever it needs an instance of one particular " -"client to call ``fit`` or ``evaluate`` (those instances are usually " -"discarded after use, so they should not keep any local state). Clients are " -"identified by a client ID, or short ``cid``. The ``cid`` can be used, for " -"example, to load different local data partitions for different clients, as " -"can be seen below:" -msgstr "" -"除了服务器和客户端在多台机器上运行的常规功能外,Flower 还提供了特殊的模拟功" -"能,即只有在训练或评估实际需要时才创建 ``FlowerClient`` 实例。为了让 Flower " -"框架能在必要时创建客户端,我们需要实现一个名为 ``client_fn`` 的函数,它能按需" -"创建一个 ``FlowerClient`` 实例。每当 Flower 需要一个特定的客户端实例来调用 " -"``fit`` 或 ``evaluate`` 时,它就会调用 ``client_fn``(这些实例在使用后通常会" -"被丢弃,因此它们不应保留任何本地状态)。客户端由一个客户端 ID 或简短的 " -"``cid`` 标识。例如,可以使用 ``cid`` 为不同的客户端加载不同的本地数据分区,如" -"下所示:" +"Financial information from different organizations to detect financial " +"fraud" +msgstr "不同组织的财务信息,以侦查财务欺诈行为" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 -msgid "Starting the training" -msgstr "开始训练" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 +msgid "Location data from your electric car to make better range prediction" +msgstr "通过电动汽车的定位数据更好地预测续航里程" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 -msgid "" -"We now have the class ``FlowerClient`` which defines client-side training/" -"evaluation and ``client_fn`` which allows Flower to create ``FlowerClient`` " -"instances whenever it needs to call ``fit`` or ``evaluate`` on one " -"particular client. The last step is to start the actual simulation using " -"``flwr.simulation.start_simulation``." -msgstr "" -"现在我们有了定义客户端训练/评估的类 ``FlowerClient`` 和允许 Flower 在需要调用" -"某个客户端的 ``fit` 或 ``evaluate` 时创建 ``FlowerClient`` 实例的 " -"``client_fn` 类。最后一步是使用 ``flwr.simulation.start_simulation`` 启动实际" -"模拟。" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 +msgid "End-to-end encrypted messages to train better auto-complete models" +msgstr "端到端加密信息可训练出更好的自动完成模型" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 msgid "" -"The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the number " -"of clients to simulate (``num_clients``), the number of federated learning " -"rounds (``num_rounds``), and the strategy. The strategy encapsulates the " -"federated learning approach/algorithm, for example, *Federated Averaging* " -"(FedAvg)." +"The popularity of privacy-enhancing systems like the `Brave " +"`__ browser or the `Signal `__ " +"messenger shows that users care about privacy. In fact, they choose the " +"privacy-enhancing version over other alternatives, if such an alternative" +" exists. But what can we do to apply machine learning and data science to" +" these cases to utilize private data? After all, these are all areas that" +" would benefit significantly from recent advances in AI." msgstr "" -"函数 ``start_simulation`` 接受许多参数,其中包括用于创建 ``FlowerClient`` 实" -"例的 ``client_fn``、要模拟的客户端数量(``num_clients``)、联邦学习轮数" -"(``num_rounds``)和策略。策略封装了联邦学习方法/算法,例如*联邦平均* " -"(FedAvg)。" +"像 `Brave `__浏览器或 `Signal " +"`__信息管理器这样的隐私增强系统的流行表明,用户关心隐私。事实上,他们会选择隐私性更好的产品。但是,我们能做些什么来将机器学习和数据科学应用到这些情况中,以利用隐私数据呢?毕竟,这些领域都将从人工智能的最新进展中受益匪浅。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 +msgid "Federated learning" +msgstr "联邦学习" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 msgid "" -"Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated " -"learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last step " -"is the actual call to ``start_simulation`` which - you guessed it - starts " -"the simulation:" -msgstr "" -"Flower 有许多内置策略,但我们也可以使用自己的策略实现来定制联邦学习方法的几乎" -"所有方面。在本例中,我们使用内置的 ``FedAvg`` 实现,并使用一些基本参数对其进" -"行定制。最后一步是实际调用 ``start_simulation``开始模拟:" +"Federated learning simply reverses this approach. It enables machine " +"learning on distributed data by moving the training to the data, instead " +"of moving the data to the training. Here's the single-sentence " +"explanation:" +msgstr "联邦学习简单地颠覆了这种方法。它通过将训练转移到数据上,而不是将数据转移到训练上,在分布式数据上实现机器学习。下面是一句话的解释:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 -msgid "Behind the scenes" -msgstr "幕后" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 +msgid "Central machine learning: move the data to the computation" +msgstr "集中式机器学习:将数据转移到计算中心" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:610 -msgid "So how does this work? How does Flower execute this simulation?" -msgstr "那么它是如何工作的呢?Flower 如何进行模拟?" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 +msgid "Federated (machine) learning: move the computation to the data" +msgstr "联邦式(机器)学习:将计算转移到数据上" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 -#, python-format +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 clients " -"(``num_clients=10``). Flower then goes ahead an asks the ``FedAvg`` strategy " -"to select clients. ``FedAvg`` knows that it should select 100% of the " -"available clients (``fraction_fit=1.0``), so it goes ahead and selects 10 " -"random clients (i.e., 100% of 10)." -msgstr "" -"当我们调用 ``start_simulation`` 时,我们会告诉 Flower 有 10 个客户" -"(`num_clients=10``)。然后,Flower 会要求 ``FedAvg`` 策略选择客户。" -"``FedAvg`` 知道它应该选择 100%的可用客户(``fraction_fit=1.0``),所以它会随" -"机选择 10 个客户(即 10 的 100%)。" +"By doing so, it enables us to use machine learning (and other data " +"science approaches) in areas where it wasn't possible before. We can now " +"train excellent medical AI models by enabling different hospitals to work" +" together. We can solve financial fraud by training AI models on the data" +" of different financial institutions. We can build novel privacy-" +"enhancing applications (such as secure messaging) that have better built-" +"in AI than their non-privacy-enhancing alternatives. And those are just a" +" few of the examples that come to mind. As we deploy federated learning, " +"we discover more and more areas that can suddenly be reinvented because " +"they now have access to vast amounts of previously inaccessible data." +msgstr "这样,我们就能在以前不可能的领域使用机器学习(和其他数据科学方法)。现在,我们可以通过让不同的医院协同工作来训练优秀的医疗人工智能模型。我们可以通过在不同金融机构的数据上训练人工智能模型来解决金融欺诈问题。我们可以构建新颖的隐私增强型应用(如安全信息),其内置的人工智能比非隐私增强型应用更好。以上只是我想到的几个例子。随着联邦学习的部署,我们会发现越来越多的领域可以突然重获新生,因为它们现在可以访问大量以前无法访问的数据。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 msgid "" -"Flower then asks the selected 10 clients to train the model. When the server " -"receives the model parameter updates from the clients, it hands those " -"updates over to the strategy (*FedAvg*) for aggregation. The strategy " -"aggregates those updates and returns the new global model, which then gets " -"used in the next round of federated learning." -msgstr "" -"然后,Flower 会要求选定的 10 个客户端对模型进行训练。服务器收到客户端的模型参" -"数更新后,会将这些更新交给策略(*FedAvg*)进行聚合。策略会聚合这些更新并返回" -"新的全局模型,然后将其用于下一轮联邦学习。" +"So how does federated learning work, exactly? Let's start with an " +"intuitive explanation." +msgstr "那么,联邦学习究竟是如何运作的呢?让我们从直观的解释开始。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 -msgid "Where's the accuracy?" -msgstr "准确度在哪里找?" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 +msgid "Federated learning in five steps" +msgstr "联邦学习的五个步骤" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 -msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` are " -"empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" -msgstr "" -"您可能已经注意到,除了 ``losses_distributed`` 以外,所有指标都是空的。{\"准确" -"度\": float(准确度)}``去哪儿了?" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 +msgid "Step 0: Initialize global model" +msgstr "步骤 0:初始化全局模型" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 msgid "" -"Flower can automatically aggregate losses returned by individual clients, " -"but it cannot do the same for metrics in the generic metrics dictionary (the " -"one with the ``accuracy`` key). Metrics dictionaries can contain very " -"different kinds of metrics and even key/value pairs that are not metrics at " -"all, so the framework does not (and can not) know how to handle these " -"automatically." +"We start by initializing the model on the server. This is exactly the " +"same in classic centralized learning: we initialize the model parameters," +" either randomly or from a previously saved checkpoint." +msgstr "我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前保存的检查点初始化模型参数。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 +msgid "|0aa5aa05810b44b6a835cecce28f3137|" msgstr "" -"Flower 可以自动汇总单个客户端返回的损失值,但无法对通用度量字典中的度量进行同" -"样的处理(即带有 \"准确度 \"键的度量字典)。度量值字典可以包含非常不同种类的" -"度量值,甚至包含根本不是度量值的键/值对,因此框架不知道(也无法知道)如何自动" -"处理这些度量值。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 +msgid "Initialize global model" +msgstr "初始化全局模型" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 msgid "" -"As users, we need to tell the framework how to handle/aggregate these custom " -"metrics, and we do so by passing metric aggregation functions to the " -"strategy. The strategy will then call these functions whenever it receives " -"fit or evaluate metrics from clients. The two possible functions are " -"``fit_metrics_aggregation_fn`` and ``evaluate_metrics_aggregation_fn``." -msgstr "" -"作为用户,我们需要告诉框架如何处理/聚合这些自定义指标,为此,我们将指标聚合函" -"数传递给策略。然后,只要从客户端接收到拟合或评估指标,策略就会调用这些函数。" -"两个可能的函数是 ``fit_metrics_aggregation_fn`` 和 " -"``evaluate_metrics_aggregation_fn``。" +"Step 1: Send model to a number of connected organizations/devices (client" +" nodes)" +msgstr "第 1 步:将模型发送到多个连接的组织/设备(客户节点)" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 msgid "" -"Let's create a simple weighted averaging function to aggregate the " -"``accuracy`` metric we return from ``evaluate``:" +"Next, we send the parameters of the global model to the connected client " +"nodes (think: edge devices like smartphones or servers belonging to " +"organizations). This is to ensure that each participating node starts " +"their local training using the same model parameters. We often use only a" +" few of the connected nodes instead of all nodes. The reason for this is " +"that selecting more and more client nodes has diminishing returns." +msgstr "接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户端节点会导致收益递减。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 +msgid "|c742940dd4bf4de09d8d0d5e8d179638|" msgstr "" -"让我们创建一个简单的加权平均函数来汇总从 ``evaluate`` 返回的 ``accuracy`` 指" -"标:" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:660 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 +msgid "Send global model" +msgstr "发送全局模型" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 msgid "" -"The only thing left to do is to tell the strategy to call this function " -"whenever it receives evaluation metric dictionaries from the clients:" -msgstr "" -"剩下要做的就是告诉策略,每当它从客户端接收到评估度量字典时,都要调用这个函" -"数:" +"Step 2: Train model locally on the data of each organization/device " +"(client node)" +msgstr "步骤 2:在本地对每个机构/设备(客户端节点)的数据进行模型训练" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 msgid "" -"We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom " -"evaluation metrics and calculates a single ``accuracy`` metric across all " -"clients on the server side." +"Now that all (selected) client nodes have the latest version of the " +"global model parameters, they start the local training. They use their " +"own local dataset to train their own local model. They don't train the " +"model until full convergence, but they only train for a little while. " +"This could be as little as one epoch on the local data, or even just a " +"few steps (mini-batches)." msgstr "" -"我们现在有了一个完整的系统,可以执行联邦训练和联邦评估。它使用 " -"``weighted_average`` 函数汇总自定义评估指标,并在服务器端计算所有客户端的单" -"一 ``accuracy`` 指标。" +"现在,所有(选定的)客户端节点都有了最新版本的全局模型参数,它们开始进行本地训练。它们使用自己的本地数据集来训练自己的本地模型。它们不会一直训练到模型完全收敛为止,而只是训练一小段时间。这可能只是本地数据上的一个遍历,甚至只是几个步骤" +"(mini-batches)。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 -msgid "" -"The other two categories of metrics (``losses_centralized`` and " -"``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial will " -"cover centralized evaluation." +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 +msgid "|1f169ab4601a47e1a226f1628f4ebddb|" msgstr "" -"其他两类指标(`losses_centralized`` 和 `metrics_centralized`)仍然是空的,因" -"为它们只适用于集中评估。Flower 教程的第二部分将介绍集中式评估。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:351 -msgid "Final remarks" -msgstr "结束语" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 +msgid "Train on local data" +msgstr "根据本地数据进行训练" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 -msgid "" -"Congratulations, you just trained a convolutional neural network, federated " -"over 10 clients! With that, you understand the basics of federated learning " -"with Flower. The same approach you've seen can be used with other machine " -"learning frameworks (not just PyTorch) and tasks (not just CIFAR-10 images " -"classification), for example NLP with Hugging Face Transformers or speech " -"with SpeechBrain." -msgstr "" -"恭喜您,你刚刚训练了一个由 10 个客户端组成的卷积神经网络!这样,你就了解了使" -"用 Flower 进行联邦学习的基础知识。你所看到的方法同样适用于其他机器学习框架" -"(不只是 PyTorch)和任务(不只是 CIFAR-10 图像分类),例如使用 Hugging Face " -"Transformers 的 NLP 或使用 SpeechBrain 的语音。" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 +msgid "Step 3: Return model updates back to the server" +msgstr "步骤 3:将模型参数更新返回服务器" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. Want " -"to customize your strategy? Initialize parameters on the server side? Or " -"evaluate the aggregated model on the server side? We'll cover all this and " -"more in the next tutorial." -msgstr "" -"在下一个笔记中,我们将介绍一些更先进的概念。想定制你的策略吗?在服务器端初始" -"化参数?或者在服务器端评估聚合模型?我们将在下一个教程中介绍所有这些内容以及" -"更多。" +"After local training, each client node has a slightly different version " +"of the model parameters they originally received. The parameters are all " +"different because each client node has different examples in its local " +"dataset. The client nodes then send those model updates back to the " +"server. The model updates they send can either be the full model " +"parameters or just the gradients that were accumulated during local " +"training." +msgstr "经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同,是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练过程中积累的梯度。" -#: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 -msgid "" -"The `Flower Federated Learning Tutorial - Part 2 `__ goes " -"into more depth about strategies and all the advanced things you can build " -"with them." +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 +msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" msgstr "" -"`Flower 联邦学习教程 - 第 2 部分 `__ 更深入地介绍了策略以及可以" -"使用策略构建的所有高级功能。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 -msgid "Use a federated learning strategy" -msgstr "使用联邦学习策略" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 +msgid "Send model updates" +msgstr "发送模型参数更新" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 +msgid "Step 4: Aggregate model updates into a new global model" +msgstr "步骤 4:将模型更新聚合到新的全局模型中" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 msgid "" -"Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and " -"Flower (`part 1 `__)." +"The server receives model updates from the selected client nodes. If it " +"selected 100 client nodes, it now has 100 slightly different versions of " +"the original global model, each trained on the local data of one client. " +"But didn't we want to have one model that contains the learnings from the" +" data of all 100 client nodes?" msgstr "" -"欢迎来到联邦学习教程的下一部分。在本教程的前几部分,我们介绍了使用 PyTorch " -"和 Flower 进行联邦学习(`第 1 部分 `___)。" +"服务器从选定的客户端节点接收模型更新。如果服务器选择了 100 个客户端节点,那么它现在就拥有 100 " +"个略有不同的原始全局模型版本,每个版本都是根据一个客户端的本地数据训练出来的。难道我们不希望有一个包含所有 100 个客户节点数据的模型吗?" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 msgid "" -"In this notebook, we'll begin to customize the federated learning system we " -"built in the introductory notebook (again, using `Flower `__ and `PyTorch `__)." +"In order to get one single model, we have to combine all the model " +"updates we received from the client nodes. This process is called " +"*aggregation*, and there are many different ways to do it. The most basic" +" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " +"`__), often abbreviated as *FedAvg*. " +"*FedAvg* takes the 100 model updates and, as the name suggests, averages " +"them. To be more precise, it takes the *weighted average* of the model " +"updates, weighted by the number of examples each client used for " +"training. The weighting is important to make sure that each data example " +"has the same \"influence\" on the resulting global model. If one client " +"has 10 examples, and another client has 100 examples, then - without " +"weighting - each of the 10 examples would influence the global model ten " +"times as much as each of the 100 examples." +msgstr "" +"为了得到一个单一的模型,我们必须将从客户端节点收到的所有模型更新合并起来。这个过程称为*聚合*,有许多不同的方法。最基本的方法称为 " +"*Federated Averaging* (`McMahan等人,2016 " +"`__),通常缩写为*FedAvg*。*FedAvg* 可以把100 " +"个模型更新进行平均。更准确地说,它取的是模型更新的*加权平均值*,根据每个客户端用于训练的数据数量进行加权。加权对于确保每个数据示例对生成的全局模型具有相同的" +" \"影响 \"非常重要。如果一个客户端有 10 个数据点,而另一个客户有 100 个数据点,那么在不加权的情况下,10 个示例对全局模型的影响是" +" 100 个示例的 10 倍。" + +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 +msgid "|72939caf6e294b0986fee6dde96614d7|" msgstr "" -"在本笔记中,我们将开始定制在入门笔记中构建的联邦学习系统(再次使用 `Flower " -"`__ 和 `PyTorch `__)。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 -msgid "Let's move beyond FedAvg with Flower strategies!" -msgstr "让我们超越 FedAvg,采用Flower策略!" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 +msgid "Aggregate model updates" +msgstr "聚合模型参数更新" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:309 -msgid "Strategy customization" -msgstr "策略定制" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 +msgid "Step 5: Repeat steps 1 to 4 until the model converges" +msgstr "步骤 5:重复步骤 1 至 4,直至模型收敛" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 msgid "" -"So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of new " -"features." +"Steps 1 to 4 are what we call a single round of federated learning. The " +"global model parameters get sent to the participating client nodes (step " +"1), the client nodes train on their local data (step 2), they send their " +"updated models to the server (step 3), and the server then aggregates the" +" model updates to get a new version of the global model (step 4)." msgstr "" -"到目前为止,如果您已经阅读过入门笔记本,那么一切都应该很熟悉了。接下来,我们" -"将介绍一些新功能。" +"步骤 1 至 4 就是我们所说的单轮联邦学习。全局模型参数被发送到参与的客户端节点(第 1 步),客户端节点对其本地数据进行训练(第 2 " +"步),然后将更新后的模型发送到服务器(第 3 步),服务器汇总模型更新,得到新版本的全局模型(第 4 步)。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 -msgid "Server-side parameter **initialization**" -msgstr "服务器端参数 **初始化**" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 +msgid "" +"During a single round, each client node that participates in that " +"iteration only trains for a little while. This means that after the " +"aggregation step (step 4), we have a model that has been trained on all " +"the data of all participating client nodes, but only for a little while. " +"We then have to repeat this training process over and over again to " +"eventually arrive at a fully trained model that performs well across the " +"data of all client nodes." +msgstr "" +"在一轮迭代中,每个参与迭代的客户节点只训练一小段时间。这意味着,在聚合步骤(步骤 " +"4)之后,我们的模型已经在所有参与的客户节点的所有数据上训练过了,但只训练了一小会儿。然后,我们必须一次又一次地重复这一训练过程,最终得到一个经过全面训练的模型,该模型在所有客户节点的数据中都表现良好。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 msgid "" -"Flower, by default, initializes the global model by asking one random client " -"for the initial parameters. In many cases, we want more control over " -"parameter initialization though. Flower therefore allows you to directly " -"pass the initial parameters to the Strategy:" +"Congratulations, you now understand the basics of federated learning. " +"There's a lot more to discuss, of course, but that was federated learning" +" in a nutshell. In later parts of this tutorial, we will go into more " +"detail. Interesting questions include: How can we select the best client " +"nodes that should participate in the next round? What's the best way to " +"aggregate model updates? How can we handle failing client nodes " +"(stragglers)?" msgstr "" -"默认情况下,Flower 会通过向一个随机客户端询问初始参数来初始化全局模型。但在许" -"多情况下,我们需要对参数初始化进行更多控制。因此,Flower 允许您直接将初始参数" -"传递给策略:" +"恭喜您,现在您已经了解了联邦学习的基础知识。当然,要讨论的内容还有很多,但这只是联邦学习的一个缩影。在本教程的后半部分,我们将进行更详细的介绍。有趣的问题包括" +" 我们如何选择最好的客户端节点参与下一轮学习?聚合模型更新的最佳方法是什么?如何处理失败的客户端节点(落伍者)?" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower " -"from asking one of the clients for the initial parameters. If we look " -"closely, we can see that the logs do not show any calls to the " -"``FlowerClient.get_parameters`` method." +"Just like we can train a model on the decentralized data of different " +"client nodes, we can also evaluate the model on that data to receive " +"valuable metrics. This is called federated evaluation, sometimes " +"abbreviated as FE. In fact, federated evaluation is an integral part of " +"most federated learning systems." msgstr "" -"向 ``FedAvg`` 策略传递 ``initial_parameters`` 可以防止 Flower 向其中一个客户" -"端询问初始参数。如果我们仔细观察,就会发现日志中没有显示对 ``FlowerClient." -"get_parameters`` 方法的任何调用。" +"就像我们可以在不同客户节点的分散数据上训练一个模型一样,我们也可以在这些数据上对模型进行评估,以获得有价值的指标。这就是所谓的联邦评估,有时简称为" +" FE。事实上,联邦评估是大多数联邦学习系统不可或缺的一部分。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:382 -msgid "Starting with a customized strategy" -msgstr "从定制战略开始" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 +msgid "Federated analytics" +msgstr "联邦分析" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number of " -"arguments, amongst them the ``client_fn`` used to create ``FlowerClient`` " -"instances, the number of clients to simulate ``num_clients``, the number of " -"rounds ``num_rounds``, and the strategy." -msgstr "" -"我们以前见过函数 ``start_simulation``。它接受许多参数,其中包括用于创建 " -"``FlowerClient`` 实例的 ``client_fn``、要模拟的客户数量 ``num_clients``、回合" -"数 ``num_rounds``和策略。" +"In many cases, machine learning isn't necessary to derive value from " +"data. Data analysis can yield valuable insights, but again, there's often" +" not enough data to get a clear answer. What's the average age at which " +"people develop a certain type of health condition? Federated analytics " +"enables such queries over multiple client nodes. It is usually used in " +"conjunction with other privacy-enhancing technologies like secure " +"aggregation to prevent the server from seeing the results submitted by " +"individual client nodes." +msgstr "在很多情况下,机器学习并不是从数据中获取价值的必要条件。数据分析可以产生有价值的见解,但同样,往往没有足够的数据来获得明确的答案。人们患某种健康疾病的平均年龄是多少?联邦分析可以通过多个客户端节点进行此类查询。它通常与安全聚合等其他隐私增强技术结合使用,以防止服务器看到单个客户端节点提交的结果。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 msgid "" -"The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different strategy " -"this time:" +"Differential privacy (DP) is often mentioned in the context of Federated " +"Learning. It is a privacy-preserving method used when analyzing and " +"sharing statistical data, ensuring the privacy of individual " +"participants. DP achieves this by adding statistical noise to the model " +"updates, ensuring any individual participants’ information cannot be " +"distinguished or re-identified. This technique can be considered an " +"optimization that provides a quantifiable privacy protection measure." msgstr "" -"该策略封装了联邦学习方法/算法,例如`FedAvg``或`FedAdagrad``。这次让我们尝试使" -"用不同的策略:" +"差分隐私(DP)经常在联邦学习中被提及。这是一种在分析和共享统计数据时使用的隐私保护方法,可确保单个参与者的隐私。DP " +"通过在模型更新中添加统计噪声来实现这一目的,确保任何个体参与者的信息都无法被区分或重新识别。这种技术可被视为一种优化,提供了一种可量化的隐私保护措施。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 -msgid "Server-side parameter **evaluation**" -msgstr "服务器端参数**评估**" +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 +msgid "Flower" +msgstr "Flower" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the client-" -"side. Client-side and server-side evaluation are similar in some ways, but " -"different in others." +"Federated learning, federated evaluation, and federated analytics require" +" infrastructure to move machine learning models back and forth, train and" +" evaluate them on local data, and then aggregate the updated models. " +"Flower provides the infrastructure to do exactly that in an easy, " +"scalable, and secure way. In short, Flower presents a unified approach to" +" federated learning, analytics, and evaluation. It allows the user to " +"federate any workload, any ML framework, and any programming language." msgstr "" -"Flower 可以在服务器端或客户端评估聚合模型。客户端和服务器端评估在某些方面相" -"似,但也有不同之处。" +"联邦学习、联邦评估和联邦分析需要基础框架来来回移动机器学习模型,在本地数据上对其进行训练和评估,然后汇总更新的模型。Flower " +"提供的基础架构正是以简单、可扩展和安全的方式实现这些目标的。简而言之,Flower " +"为联邦学习、分析和评估提供了一种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 -msgid "" -"**Centralized Evaluation** (or *server-side evaluation*) is conceptually " -"simple: it works the same way that evaluation in centralized machine " -"learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly aggregated " -"model after each round of training without having to send the model to " -"clients. We're also fortunate in the sense that our entire evaluation " -"dataset is available at all times." +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 +msgid "|83a8daee45da4a98b8d6f24ae098fc50|" msgstr "" -"**集中评估**(或*服务器端评估*)在概念上很简单:它的工作方式与集中式机器学习" -"中的评估方式相同。如果有一个服务器端数据集可用于评估目的,那就太好了。我们可" -"以在每一轮训练后对新聚合的模型进行评估,而无需将模型发送给客户端。我们也很幸" -"运,因为我们的整个评估数据集随时可用。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, but " -"also more powerful: it doesn't require a centralized dataset and allows us " -"to evaluate models over a larger set of data, which often yields more " -"realistic evaluation results. In fact, many scenarios require us to use " -"**Federated Evaluation** if we want to get representative evaluation results " -"at all. But this power comes at a cost: once we start to evaluate on the " -"client side, we should be aware that our evaluation dataset can change over " -"consecutive rounds of learning if those clients are not always available. " -"Moreover, the dataset held by each client can also change over consecutive " -"rounds. This can lead to evaluation results that are not stable, so even if " -"we would not change the model, we'd see our evaluation results fluctuate " -"over consecutive rounds." -msgstr "" -"**联邦评估**(或*客户端评估*)更为复杂,但也更为强大:它不需要集中的数据集," -"允许我们在更大的数据集上对模型进行评估,这通常会产生更真实的评估结果。事实" -"上,如果我们想得到有代表性的评估结果,很多情况下都需要使用**联邦评估**。但" -"是,这种能力是有代价的:一旦我们开始在客户端进行评估,我们就应该意识到,如果" -"这些客户端并不总是可用,我们的评估数据集可能会在连续几轮学习中发生变化。此" -"外,每个客户端所拥有的数据集也可能在连续几轮学习中发生变化。这可能会导致评估" -"结果不稳定,因此即使我们不改变模型,也会看到评估结果在连续几轮中波动。" +"Flower federated learning server and client nodes (car, scooter, personal" +" computer, roomba, and phone)" +msgstr "Flower联邦学习服务器和客户端节点(汽车、滑板车、个人电脑、roomba 和电话)" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 msgid "" -"We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see how " -"we can evaluate aggregated model parameters on the server-side:" -msgstr "" -"我们已经了解了联邦评估如何在客户端工作(即通过在 ``FlowerClient`` 中实现 " -"``evaluate`` 方法)。现在让我们看看如何在服务器端评估聚合模型参数:" - -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 -msgid "Sending/receiving arbitrary values to/from clients" -msgstr "向/从客户端发送/接收任意值" +"Congratulations, you just learned the basics of federated learning and " +"how it relates to the classic (centralized) machine learning!" +msgstr "恭喜您,您刚刚了解了联邦学习的基础知识,以及它与传统(集中式)机器学习的关系!" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 msgid "" -"In some situations, we want to configure client-side execution (training, " -"evaluation) from the server-side. One example for that is the server asking " -"the clients to train for a certain number of local epochs. Flower provides a " -"way to send configuration values from the server to the clients using a " -"dictionary. Let's look at an example where the clients receive values from " -"the server through the ``config`` parameter in ``fit`` (``config`` is also " -"available in ``evaluate``). The ``fit`` method receives the configuration " -"dictionary through the ``config`` parameter and can then read values from " -"this dictionary. In this example, it reads ``server_round`` and " -"``local_epochs`` and uses those values to improve the logging and configure " -"the number of local training epochs:" -msgstr "" -"在某些情况下,我们希望从服务器端配置客户端的执行(训练、评估)。其中一个例子" -"就是服务器要求客户端训练一定数量的本地遍历。Flower 提供了一种使用字典从服务器" -"向客户端发送配置值的方法。让我们来看一个例子:客户端通过 ``fit`` 中的 " -"``config`` 参数从服务器接收配置值(``evaluate`` 中也有 ``config`` 参数)。" -"``fit`` 方法通过 ``config`` 参数接收配置字典,然后从字典中读取值。在本例中," -"它读取了 ``server_round`` 和 ``local_epochs``,并使用这些值来改进日志记录和配" -"置本地训练遍历的数量:" +"In the next part of this tutorial, we are going to build a first " +"federated learning system with Flower." +msgstr "在本教程的下一部分,我们将用 Flower 建立第一个联邦学习系统。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 +#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 msgid "" -"So how can we send this config dictionary from server to clients? The built-" -"in Flower Strategies provide way to do this, and it works similarly to the " -"way server-side evaluation works. We provide a function to the strategy, and " -"the strategy calls this function for every round of federated learning:" +"The `Flower Federated Learning Tutorial - Part 1 " +"`__ shows how to build a simple federated learning system " +"with PyTorch and Flower." msgstr "" -"那么,如何将配置字典从服务器发送到客户端呢?内置的 \"Flower策略\"(Flower " -"Strategies)提供了这样的方法,其工作原理与服务器端评估的工作原理类似。我们为" -"策略提供一个函数,策略会在每一轮联邦学习中调用这个函数:" +"`Flower 联邦学习教程 - 第 1 部分 `__ 展示了如何使用 PyTorch 和 Flower " +"构建一个简单的联邦学习系统。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 -msgid "" -"Next, we'll just pass this function to the FedAvg strategy before starting " -"the simulation:" -msgstr "接下来,我们只需在开始模拟前将此函数传递给 FedAvg 策略即可:" +#~ msgid "Before the release" +#~ msgstr "发布前" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 -msgid "" -"As we can see, the client logs now include the current round of federated " -"learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second " -"round of federated learning, and then for two epochs during the third round." -msgstr "" -"我们可以看到,客户端日志现在包含了当前一轮的联邦学习(从 ``config`` 字典中读" -"取)。我们还可以将本地训练配置为在第一轮和第二轮联邦学习期间运行一个遍历,然" -"后在第三轮联邦学习期间运行两个遍历。" +#~ msgid "" +#~ "Update the changelog (``changelog.md``) with" +#~ " all relevant changes that happened " +#~ "after the last release. If the " +#~ "last release was tagged ``v1.2.0``, you" +#~ " can use the following URL to " +#~ "see all commits that got merged " +#~ "into ``main`` since then:" +#~ msgstr "" +#~ "更新更新日志 (``changelog.md``),加入上次发布后发生的所有相关变更。如果上次发布的版本被标记为 " +#~ "``v1.2.0``,则可以使用以下 URL 查看此后合并到 ``main`` 的所有提交:" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 -msgid "" -"Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and used " -"this concept throughout this notebook without mentioning it explicitly: our " -"``FlowerClient`` returns a dictionary containing a custom key/value pair as " -"the third return value in ``evaluate``." -msgstr "" -"客户端还可以向服务器返回任意值。为此,它们会从 ``fit`` 和/或 ``evaluate`` 返" -"回一个字典。我们在本笔记中看到并使用了这一概念,但并未明确提及:我们的 " -"``FlowerClient`` 返回一个包含自定义键/值对的字典,作为 ``evaluate`` 中的第三" -"个返回值。" +#~ msgid "" +#~ "`GitHub: Compare v1.2.0...main " +#~ "`_" +#~ msgstr "" +#~ "`GitHub: Compare v1.2.0...main " +#~ "`_" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 -msgid "Scaling federated learning" -msgstr "扩大联邦学习的规模" +#~ msgid "" +#~ "Thank the authors who contributed since" +#~ " the last release. This can be " +#~ "done by running the ``./dev/add-" +#~ "shortlog.sh`` convenience script (it can " +#~ "be ran multiple times and will " +#~ "update the names in the list if" +#~ " new contributors were added in the" +#~ " meantime)." +#~ msgstr "" +#~ "感谢自上次发布以来做出贡献的作者。可以通过运行 ``./dev/add-shortlog.sh`` " +#~ "方便脚本来完成(可以多次运行,如果在此期间有新的贡献者加入,则会更新列表中的名字)。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:629 -msgid "" -"As a last step in this notebook, let's see how we can use Flower to " -"experiment with a large number of clients." -msgstr "作为本笔记的最后一步,让我们看看如何使用 Flower 对大量客户端进行实验。" +#~ msgid "" +#~ "Update the ``changelog.md`` section header " +#~ "``Unreleased`` to contain the version " +#~ "number and date for the release " +#~ "you are building. Create a pull " +#~ "request with the change." +#~ msgstr "" +#~ "更新 ``changelog.md`` 部分的标题 ``Unreleased`` " +#~ "以包含你正在构建的版本的版本号和日期。创建一个包含更改的拉取请求。" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:651 -#, python-format -msgid "" -"We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is quite " -"small, we should probably train the model a bit longer, so we configure the " -"clients to perform 3 local training epochs. We should also adjust the " -"fraction of clients selected for training during each round (we don't want " -"all 1000 clients participating in every round), so we adjust " -"``fraction_fit`` to ``0.05``, which means that only 5% of available clients " -"(so 50 clients) will be selected for training each round:" -msgstr "" -"现在我们有 1000 个分区,每个分区有 45 个训练数据和 5 个验证数据。鉴于每个客户" -"端上的训练示例数量较少,我们可能需要对模型进行更长时间的训练,因此我们将客户" -"端配置为执行 3 个本地训练遍历。我们还应该调整每轮训练中被选中的客户端的比例" -"(我们不希望每轮训练都有 1000 个客户端参与),因此我们将 ``fraction_fit`` 调" -"整为 ``0.05``,这意味着每轮训练只选中 5%的可用客户端(即 50 个客户端):" +#~ msgid "" +#~ "Second, create a virtual environment " +#~ "(and activate it). If you chose to" +#~ " use :code:`pyenv` (with the :code" +#~ ":`pyenv-virtualenv` plugin) and already " +#~ "have it installed , you can use" +#~ " the following convenience script (by " +#~ "default it will use :code:`Python " +#~ "3.8.17`, but you can change it by" +#~ " providing a specific :code:``)::" +#~ msgstr "" +#~ "其次,创建虚拟环境(并激活它)。如果您选择使用 :code:`pyenv`(使用 :code:`pyenv-" +#~ "virtualenv`插件),并且已经安装了该插件,则可以使用下面的便捷脚本(默认情况下使用 " +#~ ":code:`Python3.8.17`,但您可以通过提供特定的 :code:`<版本>`来更改)::" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 -msgid "" -"In this notebook, we've seen how we can gradually enhance our system by " -"customizing the strategy, initializing parameters on the server side, " -"choosing a different strategy, and evaluating models on the server-side. " -"That's quite a bit of flexibility with so little code, right?" -msgstr "" -"在本笔记中,我们看到了如何通过自定义策略、在服务器端初始化参数、选择不同的策" -"略以及在服务器端评估模型来逐步增强我们的系统。用这么少的代码就能实现这么大的" -"灵活性,不是吗?" +#~ msgid "flwr (Python API reference)" +#~ msgstr "flwr(Python API 参考)" -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 -msgid "" -"In the later sections, we've seen how we can communicate arbitrary values " -"between server and clients to fully customize client-side execution. With " -"that capability, we built a large-scale Federated Learning simulation using " -"the Flower Virtual Client Engine and ran an experiment involving 1000 " -"clients in the same workload - all in a Jupyter Notebook!" -msgstr "" -"在后面的章节中,我们将看到如何在服务器和客户端之间传递任意值,以完全自定义客" -"户端执行。有了这种能力,我们使用 Flower 虚拟客户端引擎构建了一个大规模的联邦" -"学习模拟,并在 Jupyter Notebook 中进行了一次实验,在相同的工作负载中运行了 " -"1000 个客户端!" +#~ msgid "..." +#~ msgstr "..." -#: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 -msgid "" -"The `Flower Federated Learning Tutorial - Part 3 `__ shows how " -"to build a fully custom ``Strategy`` from scratch." -msgstr "" -"`Flower 联邦学习教程 - 第 3 部分 `__ 展示了如何从头开始构建完全自定" -"义的 \"策略\"。" +#~ msgid "Starting a client with an insecure server connection:" +#~ msgstr "使用不安全的服务器连接启动客户端:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 -msgid "What is Federated Learning?" -msgstr "什么是联邦学习?" +#~ msgid "server.strategy.FedAvg" +#~ msgstr "server.strategy.FedAvg" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 -msgid "" -"In this tutorial, you will learn what federated learning is, build your " -"first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated learning " -"systems that approach the current state of the art in the field." -msgstr "" -"在本教程中,你将了解什么是联邦学习,用 Flower 搭建第一个系统,并逐步对其进行" -"扩展。如果你能完成本教程的所有部分,你就能构建高级的联邦学习系统,从而接近该" -"领域当前的技术水平。" +#~ msgid "server.strategy.FedAvgM" +#~ msgstr "server.strategy.FedAvgM" + +#~ msgid "Configurable FedAvg with Momentum strategy implementation." +#~ msgstr "可配置的 FedAvg 动量策略实施。" + +#~ msgid "Fraction of clients used during training. Defaults to 0.1." +#~ msgstr "训练期间使用客户的比例。默认为 0.1。" + +#~ msgid "Fraction of clients used during validation. Defaults to 0.1." +#~ msgstr "验证过程中使用的客户端比例。默认为 0.1。" + +#~ msgid "server.strategy.FedMedian" +#~ msgstr "server.strategy.FedMedian" + +#~ msgid "server.strategy.QFedAvg" +#~ msgstr "server.strategy.QFedAvg" + +#~ msgid "server.strategy.FedOpt" +#~ msgstr "server.strategy.FedOpt" + +#~ msgid "Configurable FedAdagrad strategy implementation." +#~ msgstr "可配置的 FedAdagrad 策略实施。" + +#~ msgid "Federated Optim strategy interface." +#~ msgstr "Federated Optim 策略界面。" + +#~ msgid "server.strategy.FedProx" +#~ msgstr "server.strategy.FedProx" + +#~ msgid "Configurable FedProx strategy implementation." +#~ msgstr "可配置的 FedProx 策略实施。" + +#~ msgid "server.strategy.FedAdagrad" +#~ msgstr "server.strategy.FedAdagrad" + +#~ msgid "Paper: https://arxiv.org/abs/2003.00295" +#~ msgstr "论文: https://arxiv.org/abs/2003.00295" + +#~ msgid "Federated learning strategy using Adagrad on server-side." +#~ msgstr "在服务器端使用 Adagrad 的联邦学习策略。" + +#~ msgid "server.strategy.FedAdam" +#~ msgstr "server.strategy.FedAdam" + +#~ msgid "server.strategy.FedYogi" +#~ msgstr "server.strategy.FedYogi" + +#~ msgid "Adaptive Federated Optimization using Yogi." +#~ msgstr "使用 Yogi 的自适应联合优化。" + +#~ msgid "Federated learning strategy using Yogi on server-side." +#~ msgstr "在服务器端使用 Yogi 的联邦学习策略。" + +#~ msgid "Paper: https://arxiv.org/abs/1803.01498" +#~ msgstr "论文:https://arxiv.org/abs/1803.01498" + +#~ msgid "server.strategy.Krum" +#~ msgstr "server.strategy.Krum" + +#~ msgid "Configurable Krum strategy implementation." +#~ msgstr "可配置的 Krum 策略实施。" + +#~ msgid "server.strategy.Bulyan" +#~ msgstr "server.strategy.Bulyan" + +#~ msgid "Bulyan strategy implementation." +#~ msgstr "Bulyan策略的实施。" + +#~ msgid "server.strategy.FedXgbNnAvg" +#~ msgstr "server.strategy.FedXgbNnAvg" + +#~ msgid "Federated XGBoost [Ma et al., 2023] strategy." +#~ msgstr "Federated XGBoost [Ma 等人,2023] 策略。" + +#~ msgid "server.strategy.DPFedAvgAdaptive" +#~ msgstr "server.strategy.DPFedAvgAdaptive" + +#~ msgid "" +#~ "**Fix the incorrect return types of " +#~ "Strategy** " +#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" +#~ msgstr "" +#~ "**修复策略的错误返回类型** " +#~ "([#2432](https://github.com/adap/flower/pull/2432/files))" + +#~ msgid "" +#~ "The types of the return values in" +#~ " the docstrings in two methods " +#~ "(`aggregate_fit` and `aggregate_evaluate`) now " +#~ "match the hint types in the code." +#~ msgstr "" +#~ "两个方法(\"aggregate_fit \"和 " +#~ "\"aggregate_evaluate\")的文档说明中的返回值类型现在与代码中的提示类型一致。" + +#~ msgid "" +#~ "**Update Flower Examples** " +#~ "([#2384](https://github.com/adap/flower/pull/2384),[#2425](https://github.com/adap/flower/pull/2425)," +#~ " [#2526](https://github.com/adap/flower/pull/2526))" +#~ msgstr "" +#~ "** 更新 Flower Examples** " +#~ "([#2384](https://github.com/adap/flower/pull/2384),[#2425](https://github.com/adap/flower/pull/2425)," +#~ " [#2526](https://github.com/adap/flower/pull/2526))" + +#~ msgid "" +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()`. The string " +#~ ":code:`\"0.0.0.0:8080\"` tells the client " +#~ "which server to connect to. In our" +#~ " case we can run the server and" +#~ " the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" +#~ " we run a truly federated workload" +#~ " with the server and clients running" +#~ " on different machines, all that " +#~ "needs to change is the " +#~ ":code:`server_address` we pass to the " +#~ "client." +#~ msgstr "" +#~ "对于客户端就需要做这么多。我们仅需要实现 " +#~ ":code:`Client`或者:code:`NumPyClient`然后调用:code:`fl.client.start_client()`。字符串" +#~ " :code:`\"0.0.0.0:8080\"` " +#~ "告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同一台机器上运行服务器和客户端,因此我们使用:code:`\"0.0.0.0:8080\"`。如果我们运行真正联邦学习的工作负载,服务器和客户端在不同的机器上运行,则需要更改的只是我们传递给客户端的" +#~ " server_address 。" + +#~ msgid "" +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()`. The string " +#~ ":code:`\"[::]:8080\"` tells the client which" +#~ " server to connect to. In our " +#~ "case we can run the server and " +#~ "the client on the same machine, " +#~ "therefore we use :code:`\"[::]:8080\"`. If " +#~ "we run a truly federated workload " +#~ "with the server and clients running " +#~ "on different machines, all that needs" +#~ " to change is the :code:`server_address`" +#~ " we point the client at." +#~ msgstr "" +#~ "对于客户来说就是这样了。我们只需实现 :code:`Client` 或 " +#~ ":code:`NumPyClient` 并调用:code:`fl.client.start_client()` " +#~ "即可。字符串 :code:`\"[::]:8080\"` " +#~ "告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同一台机器上运行服务器和客户端,因此我们使用 " +#~ ":code:`\"[::]:8080\"`。如果我们运行真正联邦的工作负载,服务器和客户端运行在不同的机器上,则需要更改的只是我们指向客户端的" +#~ " server_address 。" + +#~ msgid "" +#~ "Let's now load the CIFAR-10 training " +#~ "and test set, partition them into " +#~ "ten smaller datasets (each split into" +#~ " training and validation set), and " +#~ "wrap the resulting partitions by " +#~ "creating a PyTorch ``DataLoader`` for " +#~ "each of them:" +#~ msgstr "" +#~ "现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 " +#~ "个较小的数据集(每个数据集又分为训练集和验证集),并通过为每个数据集创建 PyTorch " +#~ "``DataLoader`` 来包装由此产生的分割集:" + +#~ msgid "|e1dd4b4129b040bea23a894266227080|" +#~ msgstr "|e1dd4b4129b040bea23a894266227080|" + +#~ msgid "|c0d4cc6a442948dca8da40d2440068d9|" +#~ msgstr "|c0d4cc6a442948dca8da40d2440068d9|" + +#~ msgid "|174e1e4fa1f149a19bfbc8bc1126f46a|" +#~ msgstr "|174e1e4fa1f149a19bfbc8bc1126f46a|" + +#~ msgid "|4e021a3dc08249d2a89daa3ab03c2714|" +#~ msgstr "|4e021a3dc08249d2a89daa3ab03c2714|" + +#~ msgid "|e74a1d5ce7eb49688651f2167a59065b|" +#~ msgstr "|e74a1d5ce7eb49688651f2167a59065b|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 -msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with federated " -"learning. Only a basic understanding of data science and Python programming " -"is assumed." -msgstr "" -"🧑‍🏫 本教程从零开始,不要求熟悉联邦学习。仅假定对数据科学和 Python 编程有基本" -"了解。" +#~ msgid "|eb29ec4c7aef4e93976795ed72df647e|" +#~ msgstr "|eb29ec4c7aef4e93976795ed72df647e|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 -msgid "" -"`Star Flower on GitHub `__ ⭐️ and join the " -"open-source Flower community on Slack to connect, ask questions, and get " -"help: `Join Slack `__ 🌼 We'd love to hear " -"from you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." -msgstr "" -"`Star Flower on GitHub `__ ⭐️ 并加入 Slack 上" -"的开源 Flower 社区,进行交流、提问并获得帮助: 加入 Slack `__ 🌼 我们希望在 ``#introductions`` 频道听到您的声音!如果有任何" -"不清楚的地方,请访问 ``#questions`` 频道。" +#~ msgid "|c2f699d8ac484f5081721a6f1511f70d|" +#~ msgstr "|c2f699d8ac484f5081721a6f1511f70d|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:19 -msgid "Let's get started!" -msgstr "让我们开始吧!" +#~ msgid "|cf42accdacbf4e5eb4fa0503108ba7a7|" +#~ msgstr "|cf42accdacbf4e5eb4fa0503108ba7a7|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 -msgid "Classic machine learning" -msgstr "经典机器学习" +#~ msgid "|5ec8356bc2564fa09178b1ceed5beccc|" +#~ msgstr "|5ec8356bc2564fa09178b1ceed5beccc|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 -msgid "" -"Before we begin to discuss federated learning, let us quickly recap how most " -"machine learning works today." -msgstr "" -"在开始讨论联邦学习之前,让我们先快速回顾一下目前大多数机器学习的工作原理。" +#~ msgid "|7c9329e97bd0430bad335ab605a897a7|" +#~ msgstr "|7c9329e97bd0430bad335ab605a897a7|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 -msgid "" -"In machine learning, we have a model, and we have data. The model could be a " -"neural network (as depicted here), or something else, like classical linear " -"regression." -msgstr "" -"在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可" -"以是其他东西,比如经典的线性回归。" +#~ msgid "|88002bbce1094ba1a83c9151df18f707|" +#~ msgstr "|88002bbce1094ba1a83c9151df18f707|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|2b5c62c529f6416f840c594cce062fbb|" -msgstr "" +#~ msgid "|391766aee87c482c834c93f7c22225e2|" +#~ msgstr "|391766aee87c482c834c93f7c22225e2|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 -msgid "Model and data" -msgstr "模型和数据" +#~ msgid "|93b9a15bd27f4e91b40f642c253dfaac|" +#~ msgstr "|93b9a15bd27f4e91b40f642c253dfaac|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 -msgid "" -"We train the model using the data to perform a useful task. A task could be " -"to detect objects in images, transcribe an audio recording, or play a game " -"like Go." -msgstr "" -"我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转" -"录音频或玩围棋等游戏。" +#~ msgid "|a23d9638f96342ef9d25209951e2d564|" +#~ msgstr "|a23d9638f96342ef9d25209951e2d564|" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|90b334680cb7467d9a04d39b8e8dca9f|" -msgstr "" +#~ msgid "Upload the whl (e.g., ``flwr-1.6.0-py3-none-any.whl``)" +#~ msgstr "上传 whl(例如 ``flwr-1.6.0-py3-none-any.whl``)" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 -msgid "Train model using data" -msgstr "使用数据训练模型" +#~ msgid "" +#~ "Change ``!pip install -q 'flwr[simulation]'" +#~ " torch torchvision matplotlib`` to ``!pip" +#~ " install -q 'flwr-1.6.0-py3-none-" +#~ "any.whl[simulation]' torch torchvision matplotlib``" +#~ msgstr "" +#~ "将``!pip install -q 'flwr[simulation]' torch" +#~ " torchvision matplotlib``更改为``!pip install -q " +#~ "'flwr-1.6.0-py3-none-any.whl[simulation]' torch " +#~ "torch torchvision matplotlib``" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 -msgid "" -"Now, in practice, the training data we work with doesn't originate on the " -"machine we train the model on. It gets created somewhere else." -msgstr "" -"实际上,我们使用的训练数据并不来自我们训练模型的机器。它是在其他地方创建的。" +#~ msgid "" +#~ "All that's left to do it to " +#~ "define a function that loads both " +#~ "model and data, creates a " +#~ ":code:`CifarClient`, and starts this client." +#~ " You load your data and model " +#~ "by using :code:`cifar.py`. Start " +#~ ":code:`CifarClient` with the function " +#~ ":code:`fl.client.start_numpy_client()` by pointing " +#~ "it at the same IP address we " +#~ "used in :code:`server.py`:" +#~ msgstr "" +#~ "剩下要做的就是定义一个加载模型和数据的函数,创建一个 :code:`CifarClient` 并启动该客户端。使用" +#~ " :code:`cifar.py` 加载数据和模型。使用函数 " +#~ ":code:`fl.client.start_numpy_client()` 启动 " +#~ ":code:`CifarClient`,将其指向我们在 :code:`server.py` 中使用的相同 " +#~ "IP 地址:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 -msgid "" -"It originates on a smartphone by the user interacting with an app, a car " -"collecting sensor data, a laptop receiving input via the keyboard, or a " -"smart speaker listening to someone trying to sing a song." -msgstr "" -"它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键" -"盘输入的接收,或者智能扬声器上某人试着唱的歌。" +#~ msgid "" +#~ "The :code:`VirtualClientEngine` schedules, launches" +#~ " and manages `virtual` clients. These " +#~ "clients are identical to `non-virtual`" +#~ " clients (i.e. the ones you launch" +#~ " via the command `flwr.client.start_numpy_client" +#~ " `_)" +#~ " in the sense that they can be" +#~ " configure by creating a class " +#~ "inheriting, for example, from " +#~ "`flwr.client.NumPyClient `_ and therefore " +#~ "behave in an identical way. In " +#~ "addition to that, clients managed by " +#~ "the :code:`VirtualClientEngine` are:" +#~ msgstr "" +#~ "代码:`VirtualClientEngine`调度、启动和管理`虚拟`客户端。这些客户端与 \"非虚拟 " +#~ "\"客户端(即通过命令 `flwr.client.start_numpy_client `_启动的客户端)完全相同,它们可以通过创建一个继承自 \"flwr.client.NumPyClient " +#~ "`_\" " +#~ "的类来配置,因此行为方式也完全相同。除此之外,由 :code:`VirtualClientEngine` " +#~ "管理的客户端还包括:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|65764ceee89f4335bfd93fd0b115e831|" -msgstr "" +#~ msgid "Example: Walk-Through PyTorch & MNIST" +#~ msgstr "实例: PyTorch 和 MNIST 的演练" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 -msgid "Data on a phone" -msgstr "手机上的数据" +#~ msgid "" +#~ "In this tutorial we will learn, " +#~ "how to train a Convolutional Neural " +#~ "Network on MNIST using Flower and " +#~ "PyTorch." +#~ msgstr "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 MNIST 上训练卷积神经网络。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 -msgid "" -"What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running " -"the same app. But it could also be several organizations, all generating " -"data for the same task." -msgstr "" -"值得一提的是,这个 \"其他地方 \"通常不只是一个地方,而是很多地方。它可能是多" -"个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" +#~ msgid "" +#~ "Since we want to use PyTorch to" +#~ " solve a computer vision task, let's" +#~ " go ahead an install PyTorch and " +#~ "the **torchvision** library:" +#~ msgstr "我们想用 PyTorch 来做计算机视觉任务,需要先安装 PyTorch 和 **torchvision** 库:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" -msgstr "" +#~ msgid "Ready... Set... Train!" +#~ msgstr "准备...设置...训练!" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 -msgid "Data is on many devices" -msgstr "数据存在于多种设备中" +#~ msgid "" +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on PyTorch's `Basic MNIST Example" +#~ " `_. " +#~ "This will allow you see how easy" +#~ " it is to wrap your code with" +#~ " Flower and begin training in a " +#~ "federated way. We provide you with " +#~ "two helper scripts, namely *run-" +#~ "server.sh*, and *run-clients.sh*. Don't " +#~ "be afraid to look inside, they are" +#~ " simple enough =)." +#~ msgstr "" +#~ "现在我们已经安装了所有的依赖包,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练过程和网络架构基于 " +#~ "PyTorch 的 `Basic MNIST Example " +#~ "`_。您会发现用 " +#~ "Flower 来封装您的代码并进行联邦学习训练是多么容易。我们为您提供了两个辅助脚本,即 *run-" +#~ "server.sh* 和 *run-clients.sh*。别害怕,它们很简单 =)。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 -msgid "" -"So to use machine learning, or any kind of data analysis, the approach that " -"has been used in the past was to collect all data on a central server. This " -"server can be somewhere in a data center, or somewhere in the cloud." -msgstr "" -"因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集" -"所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" +#~ msgid "" +#~ "Go ahead and launch on a terminal" +#~ " the *run-server.sh* script first as" +#~ " follows:" +#~ msgstr "首先在终端上启动 *run-server.sh* 脚本,如下所示:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|11e95ac83a8548d8b3505b4663187d07|" -msgstr "" +#~ msgid "Now that the server is up and running, go ahead and launch the clients." +#~ msgstr "现在服务器已经启动并运行,请继续启动客户端。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 -msgid "Central data collection" -msgstr "集中数据收集" +#~ msgid "" +#~ "Et voilà! You should be seeing the" +#~ " training procedure and, after a few" +#~ " iterations, the test accuracy for " +#~ "each client." +#~ msgstr "然后就可以了!您应该能看到训练过程,以及经过几次反复后,每个客户端的测试准确率。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 -msgid "" -"Once all the data is collected in one place, we can finally use machine " -"learning algorithms to train our model on the data. This is the machine " -"learning approach that we've basically always relied on." -msgstr "" -"一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模" -"型。这就是我们基本上一直依赖的机器学习方法。" +#~ msgid "Now, let's see what is really happening inside." +#~ msgstr "现在,让我们看看里面到底发生了什么。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|1dab2f3a23674abc8a6731f20fa10730|" -msgstr "" +#~ msgid "" +#~ "Inside the server helper script *run-" +#~ "server.sh* you will find the following" +#~ " code that basically runs the " +#~ ":code:`server.py`" +#~ msgstr "在服务器辅助脚本 *run-server.sh* 中,你可以找到以下代码,这些代码基本上都是运行 :code:`server.py` 的代码" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 -msgid "Central model training" -msgstr "集中模型训练" +#~ msgid "" +#~ "We can go a bit deeper and " +#~ "see that :code:`server.py` simply launches " +#~ "a server that will coordinate three " +#~ "rounds of training. Flower Servers are" +#~ " very customizable, but for simple " +#~ "workloads, we can start a server " +#~ "using the :ref:`start_server ` function and leave " +#~ "all the configuration possibilities at " +#~ "their default values, as seen below." +#~ msgstr "" +#~ "我们可以再深入一点,:code:`server.py` 只是启动了一个服务器,该服务器将协调三轮训练。Flower " +#~ "服务器是非常容易修改的,但对于简单的工作,我们可以使用 :ref:`start_server `函数启动服务器,并将所有可能的配置保留为默认值,如下所示。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 -msgid "Challenges of classical machine learning" -msgstr "经典机器学习面临的挑战" +#~ msgid "" +#~ "Next, let's take a look at the " +#~ "*run-clients.sh* file. You will see " +#~ "that it contains the main loop " +#~ "that starts a set of *clients*." +#~ msgstr "接下来,让我们看看 *run-clients.sh* 文件。您会看到它包含了用来启动多个 *客户端* 的代码。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 -msgid "" -"The classic machine learning approach we've just seen can be used in some " -"cases. Great examples include categorizing holiday photos, or analyzing web " -"traffic. Cases, where all the data is naturally available on a centralized " -"server." -msgstr "" -"我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片" -"进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" +#~ msgid "" +#~ "**cid**: is the client ID. It is" +#~ " an integer that uniquely identifies " +#~ "client identifier." +#~ msgstr "**cid**:是客户 ID。它是一个整数,可唯一标识客户标识符。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|7f0ee162da38450788493a21627306f7|" -msgstr "" +#~ msgid "**sever_address**: String that identifies IP and port of the server." +#~ msgstr "**sever_address**: 标识服务器 IP 和端口的字符串。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 -msgid "Centralized possible" -msgstr "可集中管理" +#~ msgid "" +#~ "**nb_clients**: This defines the number " +#~ "of clients being created. This piece " +#~ "of information is not required by " +#~ "the client, but it helps us " +#~ "partition the original MNIST dataset to" +#~ " make sure that every client is " +#~ "working on unique subsets of both " +#~ "*training* and *test* sets." +#~ msgstr "" +#~ "**nb_clients**: 这定义了正在创建的客户端数量。客户端并不需要这一信息,但它有助于我们对原始 " +#~ "MNIST 数据集进行划分,以确保每个客户端都在 *training* 和 *test*" +#~ " 数据集上有独立的数据。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 -msgid "" -"But the approach can not be used in many other cases. Cases, where the data " -"is not available on a centralized server, or cases where the data available " -"on one server is not enough to train a good model." -msgstr "" -"但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器" -"上的数据不足以训练出一个好的模型。" +#~ msgid "" +#~ "Again, we can go deeper and look" +#~ " inside :code:`flwr_example/quickstart-" +#~ "pytorch/client.py`. After going through the" +#~ " argument parsing code at the " +#~ "beginning of our :code:`main` function, " +#~ "you will find a call to " +#~ ":code:`mnist.load_data`. This function is " +#~ "responsible for partitioning the original " +#~ "MNIST datasets (*training* and *test*) " +#~ "and returning a :code:`torch.utils.data.DataLoader`" +#~ " s for each of them. We then" +#~ " instantiate a :code:`PytorchMNISTClient` object" +#~ " with our client ID, our DataLoaders," +#~ " the number of epochs in each " +#~ "round, and which device we want to" +#~ " use for training (CPU or GPU)." +#~ msgstr "" +#~ "我们可以深入看一下 :code:`flwr_example/quickstart-" +#~ "pytorch/client.py`。查看 :code:`main` 函数开头的参数解析代码后,你会发现一个对" +#~ " :code:`mnist.load_data` 的调用。该函数负责分割原始 MNIST " +#~ "数据集(*training* 和 *test*),并为每个数据集返回一个 " +#~ ":code:`torch.utils.data.DataLoader` 。然后,我们实例化一个 " +#~ ":code:`PytorchMNISTClient` 对象,其中包含我们的客户端 ID、 " +#~ "DataLoader、每一轮中的遍历数,以及我们希望用于训练的设备(CPU 或 GPU)。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" -msgstr "" +#~ msgid "" +#~ "The :code:`PytorchMNISTClient` object when " +#~ "finally passed to :code:`fl.client.start_client` " +#~ "along with the server's address as " +#~ "the training process begins." +#~ msgstr "" +#~ "当训练过程开始时,:code:`PytorchMNISTClient` 对象会连同服务器地址一起传递给 " +#~ ":code:`fl.client.start_client`。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 -msgid "Centralized impossible" -msgstr "无法集中" +#~ msgid "A Closer Look" +#~ msgstr "仔细看一下" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 -msgid "" -"There are many reasons why the classic centralized machine learning approach " -"does not work for a large number of highly important real-world use cases. " -"Those reasons include:" -msgstr "" -"传统的集中式机器学习方法无法满足现实世界中大量极为重要的使用案例,原因有很" -"多。这些原因包括:" +#~ msgid "" +#~ "Now, let's look closely into the " +#~ ":code:`PytorchMNISTClient` inside :code:`flwr_example" +#~ ".quickstart-pytorch.mnist` and see what it" +#~ " is doing:" +#~ msgstr "" +#~ "现在,让我们仔细研究一下 :code:`flwr_example.quickstart-pytorch.mnist`" +#~ " 中的 :code:`PytorchMNISTClient`,看看它在做什么:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 -msgid "" -"**Regulations**: GDPR (Europe), CCPA (California), PIPEDA (Canada), LGPD " -"(Brazil), PDPL (Argentina), KVKK (Turkey), POPI (South Africa), FSS " -"(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " -"(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " -"protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own users' " -"data for artificial intelligence training because those users live in " -"different parts of the world, and their data is governed by different data " -"protection regulations." -msgstr "" -"**法规**: GDPR(欧洲)、CCPA(加利福尼亚)、PIPEDA(加拿大)、LGPD(巴西)、" -"PDPL(阿根廷)、KVKK(土耳其)、POPI(南非)、FSS(俄罗斯)、CDPR(中国)、" -"PDPB(印度)、PIPA(韩国)、APPI(日本)、PDP(印度尼西亚)、PDPA(新加坡)、" -"APP(澳大利亚)等法规保护敏感数据不被移动。事实上,这些法规有时甚至会阻止单个" -"组织将自己的用户数据用于人工智能培训,因为这些用户生活在世界不同地区,他们的" -"数据受不同的数据保护法规管辖。" +#~ msgid "" +#~ "The first thing to notice is that" +#~ " :code:`PytorchMNISTClient` instantiates a CNN" +#~ " model inside its constructor" +#~ msgstr "首先要注意的是 :code:`PytorchMNISTClient` 在其构造函数中实例化了一个 CNN 模型" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 -msgid "" -"**User preference**: In addition to regulation, there are use cases where " -"users just expect that no data leaves their device, ever. If you type your " -"passwords and credit card info into the digital keyboard of your phone, you " -"don't expect those passwords to end up on the server of the company that " -"developed that keyboard, do you? In fact, that use case was the reason " -"federated learning was invented in the first place." -msgstr "" -"**用户偏好**: 除了法规之外,在一些使用案例中,用户只是希望数据永远不会离开他" -"们的设备。如果你在手机的数字键盘上输入密码和信用卡信息,你不会希望这些密码最" -"终出现在开发该键盘的公司的服务器上吧?事实上,这种用例正是联邦学习发明的初" -"衷。" +#~ msgid "" +#~ "The code for the CNN is available" +#~ " under :code:`quickstart-pytorch.mnist` and " +#~ "it is reproduced below. It is the" +#~ " same network found in `Basic MNIST" +#~ " Example " +#~ "`_." +#~ msgstr "" +#~ "CNN 的代码可在 :code:`quickstart-pytorch.mnist` " +#~ "下找到,现复制如下。它与 `Basic MNIST Example " +#~ "`_中的网络相同。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 -msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data volume " -"that it is neither feasible nor economic to collect all the data (due to, " -"for example, bandwidth or communication efficiency). Think about a national " -"rail service with hundreds of train stations across the country. If each of " -"these train stations is outfitted with a number of security cameras, the " -"volume of raw on-device data they produce requires incredibly powerful and " -"exceedingly expensive infrastructure to process and store. And most of the " -"data isn't even useful." -msgstr "" -"**数据量**: 有些传感器(如摄像头)产生的数据量很大,收集所有数据既不可行,也" -"不经济(例如,由于带宽或通信效率的原因)。试想一下全国铁路服务,全国有数百个" -"火车站。如果每个火车站都安装了许多安全摄像头,那么它们所产生的大量原始设备数" -"据就需要功能强大且极其昂贵的基础设施来处理和存储。而大部分数据甚至都是无用" -"的。" +#~ msgid "" +#~ "The second thing to notice is that" +#~ " :code:`PytorchMNISTClient` class inherits from" +#~ " the :code:`fl.client.Client`, and hence it" +#~ " must implement the following methods:" +#~ msgstr "" +#~ "第二件要注意的事是 :code:`PytorchMNISTClient` 类继承自 " +#~ ":code:`fl.client.Client`,因此它必须实现以下方法:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 -msgid "Examples where centralized machine learning does not work include:" -msgstr "集中式机器学习不起作用的例子包括:" +#~ msgid "" +#~ "When comparing the abstract class to " +#~ "its derived class :code:`PytorchMNISTClient` " +#~ "you will notice that :code:`fit` calls" +#~ " a :code:`train` function and that " +#~ ":code:`evaluate` calls a :code:`test`: " +#~ "function." +#~ msgstr "" +#~ "将抽象类与其派生类 :code:`PytorchMNISTClient` 进行比较时,您会发现 " +#~ ":code:`fit` 调用了一个 :code:`train` 函数,而 " +#~ ":code:`evaluate` 则调用了一个 :code:`test`: 函数。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:166 -msgid "" -"Sensitive healthcare records from multiple hospitals to train cancer " -"detection models" -msgstr "用多家医院的敏感医疗记录训练癌症检测模型" +#~ msgid "" +#~ "These functions can both be found " +#~ "inside the same :code:`quickstart-" +#~ "pytorch.mnist` module:" +#~ msgstr "这些函数都可以在同一个 :code:`quickstart-pytorch.mnist` 模块中找到:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 -msgid "" -"Financial information from different organizations to detect financial fraud" -msgstr "不同组织的财务信息,以侦查财务欺诈行为" +#~ msgid "" +#~ "Observe that these functions encapsulate " +#~ "regular training and test loops and " +#~ "provide :code:`fit` and :code:`evaluate` with" +#~ " final statistics for each round. You" +#~ " could substitute them with your " +#~ "custom train and test loops and " +#~ "change the network architecture, and the" +#~ " entire example would still work " +#~ "flawlessly. As a matter of fact, " +#~ "why not try and modify the code" +#~ " to an example of your liking?" +#~ msgstr "" +#~ "请注意,这些函数封装了常规的训练和测试循环,并为 :code:`fit` 和 " +#~ ":code:`evaluate` " +#~ "提供了每轮的最终统计数据。您可以用自定义的训练和测试循环来替代它们,并改变网络结构,整个示例仍然可以完美运行。事实上,为什么不按照自己的喜好修改代码呢?" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 -msgid "Location data from your electric car to make better range prediction" -msgstr "通过电动汽车的定位数据更好地预测续航里程" +#~ msgid "Give It a Try" +#~ msgstr "试试看" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:169 -msgid "End-to-end encrypted messages to train better auto-complete models" -msgstr "端到端加密信息可训练出更好的自动完成模型" +#~ msgid "" +#~ "Looking through the quickstart code " +#~ "description above will have given a " +#~ "good understanding of how *clients* and" +#~ " *servers* work in Flower, how to " +#~ "run a simple experiment, and the " +#~ "internals of a client wrapper. Here " +#~ "are a few things you could try " +#~ "on your own and get more " +#~ "experience with Flower:" +#~ msgstr "" +#~ "通过上面的快速入门代码描述,你将对 Flower " +#~ "中*客户端*和*服务器*的工作方式、如何运行一个简单的实验以及客户端封装器的内部结构有一个很好的了解。您可以自己尝试以下内容,以获得更多使用" +#~ " Flower 的经验:" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 -msgid "" -"The popularity of privacy-enhancing systems like the `Brave `__ browser or the `Signal `__ messenger shows " -"that users care about privacy. In fact, they choose the privacy-enhancing " -"version over other alternatives, if such an alternative exists. But what can " -"we do to apply machine learning and data science to these cases to utilize " -"private data? After all, these are all areas that would benefit " -"significantly from recent advances in AI." -msgstr "" -"像 `Brave `__浏览器或 `Signal `__信" -"息管理器这样的隐私增强系统的流行表明,用户关心隐私。事实上,他们会选择隐私性" -"更好的产品。但是,我们能做些什么来将机器学习和数据科学应用到这些情况中,以利" -"用隐私数据呢?毕竟,这些领域都将从人工智能的最新进展中受益匪浅。" +#~ msgid "" +#~ "Try and change :code:`PytorchMNISTClient` so" +#~ " it can accept different architectures." +#~ msgstr "尝试修改 :code:`PytorchMNISTClient`,使其可以接受不同的架构。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 -msgid "Federated learning" -msgstr "联邦学习" +#~ msgid "" +#~ "Modify the :code:`train` function so " +#~ "that it accepts different optimizers" +#~ msgstr "修改 :code:`train` 函数,使其接受不同的优化器" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 -msgid "" -"Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead of " -"moving the data to the training. Here's the single-sentence explanation:" -msgstr "" -"联邦学习简单地颠覆了这种方法。它通过将训练转移到数据上,而不是将数据转移到训" -"练上,在分布式数据上实现机器学习。下面是一句话的解释:" +#~ msgid "" +#~ "Modify the :code:`test` function so that" +#~ " it proves not only the top-1 " +#~ "(regular accuracy) but also the top-5" +#~ " accuracy?" +#~ msgstr "修改 :code:`test` 函数,使其不仅能输出前 1 名(常规精确度),还能证明前 5 名的精确度?" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 -msgid "Central machine learning: move the data to the computation" -msgstr "集中式机器学习:将数据转移到计算中心" +#~ msgid "" +#~ "Go larger! Try to adapt the code" +#~ " to larger images and datasets. Why" +#~ " not try training on ImageNet with" +#~ " a ResNet-50?" +#~ msgstr "让我们尝试让代码适应更大的图像和数据集。为什么不尝试使用 ResNet-50 在 ImageNet 上进行训练呢?" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:191 -msgid "Federated (machine) learning: move the computation to the data" -msgstr "联邦式(机器)学习:将计算转移到数据上" +#~ msgid "You are ready now. Enjoy learning in a federated way!" +#~ msgstr "您现在已经准备就绪。尽情享受联邦学习的乐趣吧!" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 -msgid "" -"By doing so, it enables us to use machine learning (and other data science " -"approaches) in areas where it wasn't possible before. We can now train " -"excellent medical AI models by enabling different hospitals to work " -"together. We can solve financial fraud by training AI models on the data of " -"different financial institutions. We can build novel privacy-enhancing " -"applications (such as secure messaging) that have better built-in AI than " -"their non-privacy-enhancing alternatives. And those are just a few of the " -"examples that come to mind. As we deploy federated learning, we discover " -"more and more areas that can suddenly be reinvented because they now have " -"access to vast amounts of previously inaccessible data." -msgstr "" -"这样,我们就能在以前不可能的领域使用机器学习(和其他数据科学方法)。现在,我" -"们可以通过让不同的医院协同工作来训练优秀的医疗人工智能模型。我们可以通过在不" -"同金融机构的数据上训练人工智能模型来解决金融欺诈问题。我们可以构建新颖的隐私" -"增强型应用(如安全信息),其内置的人工智能比非隐私增强型应用更好。以上只是我" -"想到的几个例子。随着联邦学习的部署,我们会发现越来越多的领域可以突然重获新" -"生,因为它们现在可以访问大量以前无法访问的数据。" +#~ msgid "Differential privacy" +#~ msgstr "差别隐私" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 -msgid "" -"So how does federated learning work, exactly? Let's start with an intuitive " -"explanation." -msgstr "那么,联邦学习究竟是如何运作的呢?让我们从直观的解释开始。" +#~ msgid "" +#~ "Flower provides differential privacy (DP) " +#~ "wrapper classes for the easy integration" +#~ " of the central DP guarantees " +#~ "provided by DP-FedAvg into training " +#~ "pipelines defined in any of the " +#~ "various ML frameworks that Flower is " +#~ "compatible with." +#~ msgstr "" +#~ "Flower 提供了差分隐私 (DP) 封装类,可将 DP-FedAvg " +#~ "提供的核心 DP 轻松集成到 Flower 兼容的各种 ML " +#~ "框架中定义的训练模式中。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 -msgid "Federated learning in five steps" -msgstr "联邦学习的五个步骤" +#~ msgid "" +#~ "Please note that these components are" +#~ " still experimental; the correct " +#~ "configuration of DP for a specific " +#~ "task is still an unsolved problem." +#~ msgstr "请注意,这些组件仍处于试验阶段,如何为特定任务正确配置 DP 仍是一个尚未解决的问题。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:202 -msgid "Step 0: Initialize global model" -msgstr "步骤 0:初始化全局模型" +#~ msgid "" +#~ "The name DP-FedAvg is misleading " +#~ "since it can be applied on top " +#~ "of any FL algorithm that conforms " +#~ "to the general structure prescribed by" +#~ " the FedOpt family of algorithms." +#~ msgstr "DP-FedAvg 这个名称容易引起误解,因为它可以应用于任何符合 FedOpt 系列算法规定的一般结构的 FL 算法之上。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 -msgid "" -"We start by initializing the model on the server. This is exactly the same " -"in classic centralized learning: we initialize the model parameters, either " -"randomly or from a previously saved checkpoint." -msgstr "" -"我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前" -"保存的检查点初始化模型参数。" +#~ msgid "DP-FedAvg" +#~ msgstr "DP-FedAvg" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|5b1408eec0d746cdb91162a9107b6089|" -msgstr "" +#~ msgid "" +#~ "DP-FedAvg, originally proposed by " +#~ "McMahan et al. [mcmahan]_ and extended" +#~ " by Andrew et al. [andrew]_, is " +#~ "essentially FedAvg with the following " +#~ "modifications." +#~ msgstr "DP-FedAvg 最初由McMahan等人提出,并由Andrew等人加以扩展。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 -msgid "Initialize global model" -msgstr "初始化全局模型" +#~ msgid "" +#~ "**Clipping** : The influence of each " +#~ "client's update is bounded by clipping" +#~ " it. This is achieved by enforcing" +#~ " a cap on the L2 norm of " +#~ "the update, scaling it down if " +#~ "needed." +#~ msgstr "**裁剪** : 裁剪会影响到每个客户端的模型参数。具体做法是对参数的 L2 准则设置上限,必要时将其缩减。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 -msgid "" -"Step 1: Send model to a number of connected organizations/devices (client " -"nodes)" -msgstr "第 1 步:将模型发送到多个连接的组织/设备(客户节点)" +#~ msgid "" +#~ "**Noising** : Gaussian noise, calibrated " +#~ "to the clipping threshold, is added " +#~ "to the average computed at the " +#~ "server." +#~ msgstr "**噪声** : 在服务器计算出的平均值中加入高斯噪声,该噪声根据剪切阈值进行校准。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 -msgid "" -"Next, we send the parameters of the global model to the connected client " -"nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts their " -"local training using the same model parameters. We often use only a few of " -"the connected nodes instead of all nodes. The reason for this is that " -"selecting more and more client nodes has diminishing returns." -msgstr "" -"接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或" -"企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我" -"们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户" -"端节点会导致收益递减。" +#~ msgid "" +#~ "The distribution of the update norm " +#~ "has been shown to vary from " +#~ "task-to-task and to evolve as " +#~ "training progresses. This variability is " +#~ "crucial in understanding its impact on" +#~ " differential privacy guarantees, emphasizing " +#~ "the need for an adaptive approach " +#~ "[andrew]_ that continuously adjusts the " +#~ "clipping threshold to track a " +#~ "prespecified quantile of the update norm" +#~ " distribution." +#~ msgstr "事实证明,参数更新准则的分布会随着任务的不同而变化,并随着训练的进展而演变。因此,我们采用了一种自适应方法,该方法会不断调整剪切阈值,以跟踪参数更新准则分布的预设量化值。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" -msgstr "" +#~ msgid "Simplifying Assumptions" +#~ msgstr "简化假设" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 -msgid "Send global model" -msgstr "发送全局模型" +#~ msgid "" +#~ "We make (and attempt to enforce) a" +#~ " number of assumptions that must be" +#~ " satisfied to ensure that the " +#~ "training process actually realizes the " +#~ ":math:`(\\epsilon, \\delta)` guarantees the " +#~ "user has in mind when configuring " +#~ "the setup." +#~ msgstr "" +#~ "我们提出(并试图执行)了一系列必须满足的假设,以确保训练过程真正实现用户在配置设置时所定的 " +#~ ":math:`(\\epsilon,\\delta)` 。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 -msgid "" -"Step 2: Train model locally on the data of each organization/device (client " -"node)" -msgstr "步骤 2:在本地对每个机构/设备(客户端节点)的数据进行模型训练" +#~ msgid "" +#~ "**Fixed-size subsampling** :Fixed-size " +#~ "subsamples of the clients must be " +#~ "taken at each round, as opposed to" +#~ " variable-sized Poisson subsamples." +#~ msgstr "** 固定大小的子样本** :与可变大小的泊松分布子样本相比,每轮必须抽取固定大小的客户端子样本。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 -msgid "" -"Now that all (selected) client nodes have the latest version of the global " -"model parameters, they start the local training. They use their own local " -"dataset to train their own local model. They don't train the model until " -"full convergence, but they only train for a little while. This could be as " -"little as one epoch on the local data, or even just a few steps (mini-" -"batches)." -msgstr "" -"现在,所有(选定的)客户端节点都有了最新版本的全局模型参数,它们开始进行本地" -"训练。它们使用自己的本地数据集来训练自己的本地模型。它们不会一直训练到模型完" -"全收敛为止,而只是训练一小段时间。这可能只是本地数据上的一个遍历,甚至只是几" -"个步骤(mini-batches)。" +#~ msgid "" +#~ "**Unweighted averaging** : The contributions" +#~ " from all the clients must weighted" +#~ " equally in the aggregate to " +#~ "eliminate the requirement for the server" +#~ " to know in advance the sum of" +#~ " the weights of all clients available" +#~ " for selection." +#~ msgstr "**非加权平均**: 所有客户端的贡献必须加权相等,这样服务器就不需要事先知道所有客户的权重总和。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" -msgstr "" +#~ msgid "" +#~ "**No client failures** : The set " +#~ "of available clients must stay constant" +#~ " across all rounds of training. In" +#~ " other words, clients cannot drop out" +#~ " or fail." +#~ msgstr "**没有失败的客户端** : 在各轮训练中,可用客户端的数量必须保持不变。换句话说,客户端不能退出或失败。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 -msgid "Train on local data" -msgstr "根据本地数据进行训练" +#~ msgid "" +#~ "The first two are useful for " +#~ "eliminating a multitude of complications " +#~ "associated with calibrating the noise to" +#~ " the clipping threshold, while the " +#~ "third one is required to comply " +#~ "with the assumptions of the privacy " +#~ "analysis." +#~ msgstr "前两种方法有助于消除将噪声校准为削波阈值所带来的诸多复杂问题,而第三种方法则需要符合隐私分析的假设。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:247 -msgid "Step 3: Return model updates back to the server" -msgstr "步骤 3:将模型参数更新返回服务器" +#~ msgid "" +#~ "These restrictions are in line with " +#~ "constraints imposed by Andrew et al. " +#~ "[andrew]_." +#~ msgstr "这些限制与 Andrew 等人所施加的限制一致。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 -msgid "" -"After local training, each client node has a slightly different version of " -"the model parameters they originally received. The parameters are all " -"different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the server. " -"The model updates they send can either be the full model parameters or just " -"the gradients that were accumulated during local training." -msgstr "" -"经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同," -"是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型" -"更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练" -"过程中积累的梯度。" +#~ msgid "Customizable Responsibility for Noise injection" +#~ msgstr "可定制的噪声注入" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|ec1fe880237247e0975f52766775ab84|" -msgstr "" +#~ msgid "" +#~ "In contrast to other implementations " +#~ "where the addition of noise is " +#~ "performed at the server, you can " +#~ "configure the site of noise injection" +#~ " to better match your threat model." +#~ " We provide users with the " +#~ "flexibility to set up the training " +#~ "such that each client independently adds" +#~ " a small amount of noise to the" +#~ " clipped update, with the result that" +#~ " simply aggregating the noisy updates " +#~ "is equivalent to the explicit addition" +#~ " of noise to the non-noisy " +#~ "aggregate at the server." +#~ msgstr "与其他在服务器上添加噪声的实现方法不同,您可以配置噪声注入的位置,以便更好地匹配您的威胁模型。我们为用户提供了设置训练的灵活性,使每个客户端都能独立地为剪切参数更新添加少量噪声,这样,只需聚合噪声更新,就相当于在服务器上为非噪声聚合添加噪声了。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 -msgid "Send model updates" -msgstr "发送模型参数更新" +#~ msgid "" +#~ "To be precise, if we let :math:`m`" +#~ " be the number of clients sampled " +#~ "each round and :math:`\\sigma_\\Delta` be " +#~ "the scale of the total Gaussian " +#~ "noise that needs to be added to" +#~ " the sum of the model updates, " +#~ "we can use simple maths to show" +#~ " that this is equivalent to each " +#~ "client adding noise with scale " +#~ ":math:`\\sigma_\\Delta/\\sqrt{m}`." +#~ msgstr "" +#~ "准确地说,我们假设每轮采样的客户端数量为:math:`m`,:math:`\\sigma_\\Delta` " +#~ "为需要添加到模型更新总和中的总高斯噪声的规模,我们就可以用简单的数学方法证明了,这相当于每个客户端都添加了规模为 " +#~ ":math:`\\sigma_\\Delta/\\sqrt{m}` 的噪声。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:262 -msgid "Step 4: Aggregate model updates into a new global model" -msgstr "步骤 4:将模型更新聚合到新的全局模型中" +#~ msgid "Wrapper-based approach" +#~ msgstr "基于封装的方法" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 -msgid "" -"The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of the " -"original global model, each trained on the local data of one client. But " -"didn't we want to have one model that contains the learnings from the data " -"of all 100 client nodes?" -msgstr "" -"服务器从选定的客户端节点接收模型更新。如果服务器选择了 100 个客户端节点,那么" -"它现在就拥有 100 个略有不同的原始全局模型版本,每个版本都是根据一个客户端的本" -"地数据训练出来的。难道我们不希望有一个包含所有 100 个客户节点数据的模型吗?" +#~ msgid "" +#~ "Introducing DP to an existing workload" +#~ " can be thought of as adding an" +#~ " extra layer of security around it." +#~ " This inspired us to provide the " +#~ "additional server and client-side logic" +#~ " needed to make the training process" +#~ " differentially private as wrappers for " +#~ "instances of the :code:`Strategy` and " +#~ ":code:`NumPyClient` abstract classes respectively." +#~ " This wrapper-based approach has the" +#~ " advantage of being easily composable " +#~ "with other wrappers that someone might" +#~ " contribute to the Flower library in" +#~ " the future, e.g., for secure " +#~ "aggregation. Using Inheritance instead can " +#~ "be tedious because that would require" +#~ " the creation of new sub- classes " +#~ "every time a new class implementing " +#~ ":code:`Strategy` or :code:`NumPyClient` is " +#~ "defined." +#~ msgstr "" +#~ "在现有工作负载中引入 DP " +#~ "可以被认为是在其周围增加了一层额外的安全性。受此启发,我们提供了额外的服务器端和客户端逻辑,分别作为 " +#~ ":code:`Strategy` 和 :code:`NumPyClient` " +#~ "抽象类实例的封装器,使训练过程具有不同的隐私性。这种基于封装器的方法的优点是可以很容易地与将来有人贡献给 Flower " +#~ "的其他封装器(例如用于安全聚合的封装器)进行组合。使用继承可能会比较繁琐,因为每次定义实现 :code:`Strategy`" +#~ " 或 :code:`NumPyClient` 的新类时,都需要创建新的子类。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 -msgid "" -"In order to get one single model, we have to combine all the model updates " -"we received from the client nodes. This process is called *aggregation*, and " -"there are many different ways to do it. The most basic way to do it is " -"called *Federated Averaging* (`McMahan et al., 2016 `__), often abbreviated as *FedAvg*. *FedAvg* takes the 100 " -"model updates and, as the name suggests, averages them. To be more precise, " -"it takes the *weighted average* of the model updates, weighted by the number " -"of examples each client used for training. The weighting is important to " -"make sure that each data example has the same \"influence\" on the resulting " -"global model. If one client has 10 examples, and another client has 100 " -"examples, then - without weighting - each of the 10 examples would influence " -"the global model ten times as much as each of the 100 examples." -msgstr "" -"为了得到一个单一的模型,我们必须将从客户端节点收到的所有模型更新合并起来。这" -"个过程称为*聚合*,有许多不同的方法。最基本的方法称为 *Federated Averaging* " -"(`McMahan等人,2016 `__),通常缩写为" -"*FedAvg*。*FedAvg* 可以把100 个模型更新进行平均。更准确地说,它取的是模型更新" -"的*加权平均值*,根据每个客户端用于训练的数据数量进行加权。加权对于确保每个数" -"据示例对生成的全局模型具有相同的 \"影响 \"非常重要。如果一个客户端有 10 个数" -"据点,而另一个客户有 100 个数据点,那么在不加权的情况下,10 个示例对全局模型" -"的影响是 100 个示例的 10 倍。" +#~ msgid "" +#~ "The first version of our solution " +#~ "was to define a decorator whose " +#~ "constructor accepted, among other things, " +#~ "a boolean-valued variable indicating " +#~ "whether adaptive clipping was to be " +#~ "enabled or not. We quickly realized " +#~ "that this would clutter its " +#~ ":code:`__init__()` function with variables " +#~ "corresponding to hyperparameters of adaptive" +#~ " clipping that would remain unused " +#~ "when it was disabled. A cleaner " +#~ "implementation could be achieved by " +#~ "splitting the functionality into two " +#~ "decorators, :code:`DPFedAvgFixed` and " +#~ ":code:`DPFedAvgAdaptive`, with the latter sub-" +#~ " classing the former. The constructors " +#~ "for both classes accept a boolean " +#~ "parameter :code:`server_side_noising`, which, as " +#~ "the name suggests, determines where " +#~ "noising is to be performed." +#~ msgstr "" +#~ "我们的第一版解决方案是定义一个装饰器,其构造函数接受一个布尔值变量,表示是否启用自适应剪裁。我们很快意识到,这样会使其 " +#~ ":code:`__init__()` " +#~ "函数中与自适应裁剪超参数相对应的变量变得杂乱无章,而这些变量在自适应裁剪被禁用时将保持未使用状态。要实现更简洁的功能,可以将该功能拆分为两个装饰器,即" +#~ " :code:`DPFedAvgFixed` 和 " +#~ ":code:`DPFedAvgAdaptive`,后者是前者的子类。这两个类的构造函数都接受一个布尔参数 " +#~ ":code:`server_side_noising`,顾名思义,它决定了在哪里加噪声。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" -msgstr "" +#~ msgid "" +#~ "The server-side capabilities required " +#~ "for the original version of DP-" +#~ "FedAvg, i.e., the one which performed" +#~ " fixed clipping, can be completely " +#~ "captured with the help of wrapper " +#~ "logic for just the following two " +#~ "methods of the :code:`Strategy` abstract " +#~ "class." +#~ msgstr "" +#~ "只需对 :code:`Strategy` 抽象类的以下两个方法进行封装,就能完全捕获 DP-" +#~ "FedAvg 原始版本(即执行固定剪裁的版本)所需的服务器端功能。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 -msgid "Aggregate model updates" -msgstr "聚合模型参数更新" +#~ msgid "" +#~ ":code:`configure_fit()` : The config " +#~ "dictionary being sent by the wrapped " +#~ ":code:`Strategy` to each client needs to" +#~ " be augmented with an additional " +#~ "value equal to the clipping threshold" +#~ " (keyed under :code:`dpfedavg_clip_norm`) and," +#~ " if :code:`server_side_noising=true`, another one" +#~ " equal to the scale of the " +#~ "Gaussian noise that needs to be " +#~ "added at the client (keyed under " +#~ ":code:`dpfedavg_noise_stddev`). This entails " +#~ "*post*-processing of the results returned " +#~ "by the wrappee's implementation of " +#~ ":code:`configure_fit()`." +#~ msgstr "" +#~ ":code:`configure_fit()` :由封装的 :code:`Strategy` " +#~ "发送到每个客户端的配置字典需要使用等于裁剪阈值的附加值(在 :code:`dpfedavg_clip_norm` " +#~ "下键入)进行扩充。并且,如果 " +#~ "server_side_noising=true,则另一个值等于需要在客户端添加的高斯噪声的大小(在 " +#~ "dpfedavg_noise_stddev 下键入)。这需要对封装后的configure_fit() " +#~ "所返回的结果进行后处理。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:280 -msgid "Step 5: Repeat steps 1 to 4 until the model converges" -msgstr "步骤 5:重复步骤 1 至 4,直至模型收敛" +#~ msgid "" +#~ ":code:`aggregate_fit()`: We check whether any" +#~ " of the sampled clients dropped out" +#~ " or failed to upload an update " +#~ "before the round timed out. In " +#~ "that case, we need to abort the" +#~ " current round, discarding any successful" +#~ " updates that were received, and move" +#~ " on to the next one. On the " +#~ "other hand, if all clients responded " +#~ "successfully, we must force the " +#~ "averaging of the updates to happen " +#~ "in an unweighted manner by intercepting" +#~ " the :code:`parameters` field of " +#~ ":code:`FitRes` for each received update " +#~ "and setting it to 1. Furthermore, " +#~ "if :code:`server_side_noising=true`, each update " +#~ "is perturbed with an amount of " +#~ "noise equal to what it would have" +#~ " been subjected to had client-side" +#~ " noising being enabled. This entails " +#~ "*pre*-processing of the arguments to " +#~ "this method before passing them on " +#~ "to the wrappee's implementation of " +#~ ":code:`aggregate_fit()`." +#~ msgstr "" +#~ ":code:`aggregate_fit()`: " +#~ "我们会检查是否有任何客户端在本轮超时前退出或未能上传参数更新。在这种情况下,我们需要中止当前一轮,丢弃已收到的所有参数更新,然后继续下一轮。另一方面,如果所有客户端都成功响应,我们就必须通过拦截" +#~ " :code:`FitRes` 的 :code:`parameters` 字段并将其设置为 " +#~ "1,强制以不加权的方式平均更新。此外,如果 " +#~ ":code:`server_side_noising=true`,每次更新都会受到一定量的噪声扰动,其扰动量相当于启用客户端噪声时的扰动量。" +#~ " 这就需要在将本方法的参数传递给封装的 :code:`aggregate_fit()` " +#~ "之前,对参数进行*预*处理。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 -msgid "" -"Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step 1), " -"the client nodes train on their local data (step 2), they send their updated " -"models to the server (step 3), and the server then aggregates the model " -"updates to get a new version of the global model (step 4)." -msgstr "" -"步骤 1 至 4 就是我们所说的单轮联邦学习。全局模型参数被发送到参与的客户端节点" -"(第 1 步),客户端节点对其本地数据进行训练(第 2 步),然后将更新后的模型发" -"送到服务器(第 3 步),服务器汇总模型更新,得到新版本的全局模型(第 4 步)。" +#~ msgid "" +#~ "We can't directly change the aggregation" +#~ " function of the wrapped strategy to" +#~ " force it to add noise to the" +#~ " aggregate, hence we simulate client-" +#~ "side noising to implement server-side" +#~ " noising." +#~ msgstr "我们无法直接改变封装策略的聚合函数,迫使它在聚合中添加噪声,因此我们模拟客户端噪声来实现服务器端噪声。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 -msgid "" -"During a single round, each client node that participates in that iteration " -"only trains for a little while. This means that after the aggregation step " -"(step 4), we have a model that has been trained on all the data of all " -"participating client nodes, but only for a little while. We then have to " -"repeat this training process over and over again to eventually arrive at a " -"fully trained model that performs well across the data of all client nodes." -msgstr "" -"在一轮迭代中,每个参与迭代的客户节点只训练一小段时间。这意味着,在聚合步骤" -"(步骤 4)之后,我们的模型已经在所有参与的客户节点的所有数据上训练过了,但只" -"训练了一小会儿。然后,我们必须一次又一次地重复这一训练过程,最终得到一个经过" -"全面训练的模型,该模型在所有客户节点的数据中都表现良好。" +#~ msgid "" +#~ "These changes have been put together " +#~ "into a class called :code:`DPFedAvgFixed`, " +#~ "whose constructor accepts the strategy " +#~ "being decorated, the clipping threshold " +#~ "and the number of clients sampled " +#~ "every round as compulsory arguments. The" +#~ " user is expected to specify the " +#~ "clipping threshold since the order of" +#~ " magnitude of the update norms is " +#~ "highly dependent on the model being " +#~ "trained and providing a default value" +#~ " would be misleading. The number of" +#~ " clients sampled at every round is" +#~ " required to calculate the amount of" +#~ " noise that must be added to " +#~ "each individual update, either by the" +#~ " server or the clients." +#~ msgstr "" +#~ "这些变化被整合到一个名为 :code:`DPFedAvgFixed` " +#~ "的类中,其构造函数接受被装饰的策略、剪切阈值和每轮采样的客户数作为必选参数。用户需要指定剪切阈值,因为参数更新规范的数量级在很大程度上取决于正在训练的模型,提供默认值会产生误导。每轮采样的客户端数量是计算服务器或客户在每次参数更新时添加的噪音量所必需的。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 -msgid "" -"Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning in " -"a nutshell. In later parts of this tutorial, we will go into more detail. " -"Interesting questions include: How can we select the best client nodes that " -"should participate in the next round? What's the best way to aggregate model " -"updates? How can we handle failing client nodes (stragglers)?" -msgstr "" -"恭喜您,现在您已经了解了联邦学习的基础知识。当然,要讨论的内容还有很多,但这" -"只是联邦学习的一个缩影。在本教程的后半部分,我们将进行更详细的介绍。有趣的问" -"题包括 我们如何选择最好的客户端节点参与下一轮学习?聚合模型更新的最佳方法是什" -"么?如何处理失败的客户端节点(落伍者)?" +#~ msgid "" +#~ "The additional functionality required to " +#~ "facilitate adaptive clipping has been " +#~ "provided in :code:`DPFedAvgAdaptive`, a " +#~ "subclass of :code:`DPFedAvgFixed`. It " +#~ "overrides the above-mentioned methods to" +#~ " do the following." +#~ msgstr "" +#~ "自适应剪裁所需的附加功能在 :code:`DPFedAvgAdaptive` 中提供,其是 " +#~ ":code:`DPFedAvgFixed` 的子类。它重写了上述方法,以实现以下功能。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 -msgid "" -"Just like we can train a model on the decentralized data of different client " -"nodes, we can also evaluate the model on that data to receive valuable " -"metrics. This is called federated evaluation, sometimes abbreviated as FE. " -"In fact, federated evaluation is an integral part of most federated learning " -"systems." -msgstr "" -"就像我们可以在不同客户节点的分散数据上训练一个模型一样,我们也可以在这些数据" -"上对模型进行评估,以获得有价值的指标。这就是所谓的联邦评估,有时简称为 FE。事" -"实上,联邦评估是大多数联邦学习系统不可或缺的一部分。" +#~ msgid "" +#~ ":code:`configure_fit()` : It intercepts the" +#~ " config dict returned by " +#~ ":code:`super.configure_fit()` to add the " +#~ "key-value pair " +#~ ":code:`dpfedavg_adaptive_clip_enabled:True` to it, " +#~ "which the client interprets as an " +#~ "instruction to include an indicator bit" +#~ " (1 if update norm <= clipping " +#~ "threshold, 0 otherwise) in the results" +#~ " returned by it." +#~ msgstr "" +#~ ":code:`configure_fit()`:它截取由 :code:`super.configure_fit()` " +#~ "返回的 config 字典,并在其中添加键-值对 " +#~ ":code:`dpfedavg_adaptive_clip_enabled:True\",客户端将其解释为在返回结果中包含一个指示位(如果参数更新范式" +#~ " <= 剪裁阈值,则为 1,否则为 0)的指令。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 -msgid "Federated analytics" -msgstr "联邦分析" +#~ msgid "" +#~ ":code:`aggregate_fit()` : It follows a " +#~ "call to :code:`super.aggregate_fit()` with one" +#~ " to :code:`__update_clip_norm__()`, a procedure" +#~ " which adjusts the clipping threshold " +#~ "on the basis of the indicator bits" +#~ " received from the sampled clients." +#~ msgstr ":code:`aggregate_fit()`:在调用:code:`super.aggregate_fit()`后,再调用:code:`__update_clip_norm__()`,该过程根据从采样客户端接收到的指示位调整裁剪阈值。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 -msgid "" -"In many cases, machine learning isn't necessary to derive value from data. " -"Data analysis can yield valuable insights, but again, there's often not " -"enough data to get a clear answer. What's the average age at which people " -"develop a certain type of health condition? Federated analytics enables such " -"queries over multiple client nodes. It is usually used in conjunction with " -"other privacy-enhancing technologies like secure aggregation to prevent the " -"server from seeing the results submitted by individual client nodes." -msgstr "" -"在很多情况下,机器学习并不是从数据中获取价值的必要条件。数据分析可以产生有价" -"值的见解,但同样,往往没有足够的数据来获得明确的答案。人们患某种健康疾病的平" -"均年龄是多少?联邦分析可以通过多个客户端节点进行此类查询。它通常与安全聚合等" -"其他隐私增强技术结合使用,以防止服务器看到单个客户端节点提交的结果。" +#~ msgid "" +#~ "The client-side capabilities required " +#~ "can be completely captured through " +#~ "wrapper logic for just the :code:`fit()`" +#~ " method of the :code:`NumPyClient` abstract" +#~ " class. To be precise, we need " +#~ "to *post-process* the update computed" +#~ " by the wrapped client to clip " +#~ "it, if necessary, to the threshold " +#~ "value supplied by the server as " +#~ "part of the config dictionary. In " +#~ "addition to this, it may need to" +#~ " perform some extra work if either" +#~ " (or both) of the following keys " +#~ "are also present in the dict." +#~ msgstr "" +#~ "客户端所需的功能完全可以通过 :code:`NumPyClient` 抽象类的 " +#~ ":code:`fit()` " +#~ "方法的封装逻辑来实现。准确地说,我们需要对封装客户端计算的参数更新进行处理,以便在必要时将其剪切到服务器作为配置字典的一部分提供的阈值。除此之外,如果配置字典中还存在以下任一(或两个)键,客户端可能还需要执行一些额外的工作。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 -msgid "" -"Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and sharing " -"statistical data, ensuring the privacy of individual participants. DP " -"achieves this by adding statistical noise to the model updates, ensuring any " -"individual participants’ information cannot be distinguished or re-" -"identified. This technique can be considered an optimization that provides a " -"quantifiable privacy protection measure." -msgstr "" -"差分隐私(DP)经常在联邦学习中被提及。这是一种在分析和共享统计数据时使用的隐" -"私保护方法,可确保单个参与者的隐私。DP 通过在模型更新中添加统计噪声来实现这一" -"目的,确保任何个体参与者的信息都无法被区分或重新识别。这种技术可被视为一种优" -"化,提供了一种可量化的隐私保护措施。" +#~ msgid "" +#~ ":code:`dpfedavg_noise_stddev` : Generate and " +#~ "add the specified amount of noise " +#~ "to the clipped update." +#~ msgstr "code:`dpfedavg_noise_stddev`:生成并在剪切参数更新中添加指定数量的噪声。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 -msgid "Flower" -msgstr "Flower" +#~ msgid "" +#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the" +#~ " metrics dict in the :code:`FitRes` " +#~ "object being returned to the server " +#~ "with an indicator bit, calculated as " +#~ "described earlier." +#~ msgstr "" +#~ ":code:`dpfedavg_adaptive_clip_enabled`:在返回给服务器的 :code:`FitRes`" +#~ " 对象中的度量值字典中增加一个指标位,计算方法如前所述。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 -msgid "" -"Federated learning, federated evaluation, and federated analytics require " -"infrastructure to move machine learning models back and forth, train and " -"evaluate them on local data, and then aggregate the updated models. Flower " -"provides the infrastructure to do exactly that in an easy, scalable, and " -"secure way. In short, Flower presents a unified approach to federated " -"learning, analytics, and evaluation. It allows the user to federate any " -"workload, any ML framework, and any programming language." -msgstr "" -"联邦学习、联邦评估和联邦分析需要基础框架来来回移动机器学习模型,在本地数据上" -"对其进行训练和评估,然后汇总更新的模型。Flower 提供的基础架构正是以简单、可扩" -"展和安全的方式实现这些目标的。简而言之,Flower 为联邦学习、分析和评估提供了一" -"种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" +#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" +#~ msgstr "进行 :math:`(epsilon, \\delta)` 分析" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|ff726bc5505e432388ee2fdd6ef420b9|" -msgstr "" +#~ msgid "" +#~ "Assume you have trained for :math:`n`" +#~ " rounds with sampling fraction :math:`q`" +#~ " and noise multiplier :math:`z`. In " +#~ "order to calculate the :math:`\\epsilon` " +#~ "value this would result in for a" +#~ " particular :math:`\\delta`, the following " +#~ "script may be used." +#~ msgstr "" +#~ "假设您已经训练了 :math:`n` 轮,采样比例为 :math:`q`,噪声乘数为 " +#~ ":math:`z`。为了计算特定 :math:`\\delta` 的 :math:`epsilon`" +#~ " 值,可以使用下面的脚本。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 -msgid "" -"Flower federated learning server and client nodes (car, scooter, personal " -"computer, roomba, and phone)" -msgstr "" -"Flower联邦学习服务器和客户端节点(汽车、滑板车、个人电脑、roomba 和电话)" +#~ msgid "Flower driver SDK." +#~ msgstr "Flower 服务器。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 -msgid "" -"Congratulations, you just learned the basics of federated learning and how " -"it relates to the classic (centralized) machine learning!" -msgstr "" -"恭喜您,您刚刚了解了联邦学习的基础知识,以及它与传统(集中式)机器学习的关" -"系!" +#~ msgid "driver" +#~ msgstr "服务器" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 -msgid "" -"In the next part of this tutorial, we are going to build a first federated " -"learning system with Flower." -msgstr "在本教程的下一部分,我们将用 Flower 建立第一个联邦学习系统。" +#~ msgid "Get task results." +#~ msgstr "汇总训练结果。" -#: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 -msgid "" -"The `Flower Federated Learning Tutorial - Part 1 `__ shows how to " -"build a simple federated learning system with PyTorch and Flower." -msgstr "" -"`Flower 联邦学习教程 - 第 1 部分 `__ 展示了如何使用 PyTorch 和 Flower 构" -"建一个简单的联邦学习系统。" +#~ msgid "Request for run ID." +#~ msgstr "Flower 基线申请" -#~ msgid "Before the release" -#~ msgstr "发布前" +#~ msgid "Get client IDs." +#~ msgstr "返回客户端(本身)。" #~ msgid "" -#~ "Update the changelog (``changelog.md``) with all relevant changes that " -#~ "happened after the last release. If the last release was tagged " -#~ "``v1.2.0``, you can use the following URL to see all commits that got " -#~ "merged into ``main`` since then:" +#~ "Flower usage examples used to be " +#~ "bundled with Flower in a package " +#~ "called ``flwr_example``. We are migrating " +#~ "those examples to standalone projects to" +#~ " make them easier to use. All " +#~ "new examples are based in the " +#~ "directory `examples " +#~ "`_." #~ msgstr "" -#~ "更新更新日志 (``changelog.md``),加入上次发布后发生的所有相关变更。如果上" -#~ "次发布的版本被标记为 ``v1.2.0``,则可以使用以下 URL 查看此后合并到 " -#~ "``main`` 的所有提交:" +#~ "Flower 的使用示例曾与 Flower 捆绑在一个名为 ``flwr_example``" +#~ " 的软件包中。我们正在将这些示例迁移到独立项目中,以使它们更易于使用。所有新示例都位于目录 `examples " +#~ "`_。" + +#~ msgid "Quickstart TensorFlow/Keras" +#~ msgstr "快速入门 TensorFlow/Keras" + +#~ msgid "Legacy Examples (`flwr_example`)" +#~ msgstr "传统示例 (`flwr_example`)" #~ msgid "" -#~ "`GitHub: Compare v1.2.0...main `_" +#~ "The useage examples in `flwr_example` " +#~ "are deprecated and will be removed " +#~ "in the future. New examples are " +#~ "provided as standalone projects in " +#~ "`examples `_." #~ msgstr "" -#~ "`GitHub: Compare v1.2.0...main `_" +#~ "在 `flwr_example` 中的使用示例已被弃用,今后将被移除。新示例将作为独立项目在 " +#~ "`examples `_" +#~ " 中提供。" + +#~ msgid "Extra Dependencies" +#~ msgstr "额外依赖" #~ msgid "" -#~ "Thank the authors who contributed since the last release. This can be " -#~ "done by running the ``./dev/add-shortlog.sh`` convenience script (it can " -#~ "be ran multiple times and will update the names in the list if new " -#~ "contributors were added in the meantime)." +#~ "The core Flower framework keeps a " +#~ "minimal set of dependencies. The " +#~ "examples demonstrate Flower in the " +#~ "context of different machine learning " +#~ "frameworks, so additional dependencies need" +#~ " to be installed before an example" +#~ " can be run." #~ msgstr "" -#~ "感谢自上次发布以来做出贡献的作者。可以通过运行 ``./dev/add-shortlog.sh`` " -#~ "方便脚本来完成(可以多次运行,如果在此期间有新的贡献者加入,则会更新列表中" -#~ "的名字)。" +#~ "Flower 核心框架只保留了最低限度的依赖项。这些示例在不同机器学习框架的背景下演示了 " +#~ "Flower,因此在运行示例之前需要安装额外的依赖项。" + +#~ msgid "For PyTorch examples::" +#~ msgstr "PyTorch 示例::" + +#~ msgid "For TensorFlow examples::" +#~ msgstr "TensorFlow 示例::" + +#~ msgid "For both PyTorch and TensorFlow examples::" +#~ msgstr "PyTorch 和 TensorFlow 示例::" #~ msgid "" -#~ "Update the ``changelog.md`` section header ``Unreleased`` to contain the " -#~ "version number and date for the release you are building. Create a pull " -#~ "request with the change." +#~ "Please consult :code:`pyproject.toml` for a" +#~ " full list of possible extras " +#~ "(section :code:`[tool.poetry.extras]`)." #~ msgstr "" -#~ "更新 ``changelog.md`` 部分的标题 ``Unreleased`` 以包含你正在构建的版本的版" -#~ "本号和日期。创建一个包含更改的拉取请求。" +#~ "请参阅 :code:`pyproject.toml`,了解可能的 extras 的完整列表(章节 " +#~ ":code:`[tool.poems.extras]`)。" + +#~ msgid "PyTorch Examples" +#~ msgstr "PyTorch 示例" + +#~ msgid "" +#~ "Our PyTorch examples are based on " +#~ "PyTorch 1.7. They should work with " +#~ "other releases as well. So far, we" +#~ " provide the following examples." +#~ msgstr "我们的 PyTorch 示例基于 PyTorch 1.7。它们应该也能在其他版本中使用。到目前为止,我们提供了以下示例。" + +#~ msgid "CIFAR-10 Image Classification" +#~ msgstr "CIFAR-10 图像分类" #~ msgid "" -#~ "Second, create a virtual environment (and activate it). If you chose to " -#~ "use :code:`pyenv` (with the :code:`pyenv-virtualenv` plugin) and already " -#~ "have it installed , you can use the following convenience script (by " -#~ "default it will use :code:`Python 3.8.17`, but you can change it by " -#~ "providing a specific :code:``)::" +#~ "`CIFAR-10 and CIFAR-100 " +#~ "`_ are " +#~ "popular RGB image datasets. The Flower" +#~ " CIFAR-10 example uses PyTorch to " +#~ "train a simple CNN classifier in a" +#~ " federated learning setup with two " +#~ "clients." #~ msgstr "" -#~ "其次,创建虚拟环境(并激活它)。如果您选择使用 :code:`pyenv`(使用 :code:" -#~ "`pyenv-virtualenv`插件),并且已经安装了该插件,则可以使用下面的便捷脚本" -#~ "(默认情况下使用 :code:`Python3.8.17`,但您可以通过提供特定的 :code:`<版本" -#~ ">`来更改)::" +#~ "CIFAR-10 和 CIFAR-100 " +#~ "``_ 是流行的 RGB" +#~ " 图像数据集。Flower CIFAR-10 示例使用 PyTorch " +#~ "在有两个客户端的联邦学习设置中训练一个简单的 CNN 分类器。" -#~ msgid "flwr (Python API reference)" -#~ msgstr "flwr(Python API 参考)" +#~ msgid "First, start a Flower server:" +#~ msgstr "首先,启动 Flower 服务器:" -#~ msgid "..." -#~ msgstr "..." +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" -#~ msgid "Starting a client with an insecure server connection:" -#~ msgstr "使用不安全的服务器连接启动客户端:" +#~ msgid "Then, start the two clients in a new terminal window:" +#~ msgstr "然后,在新的终端窗口中启动两个客户端:" -#~ msgid "server.strategy.FedAvg" -#~ msgstr "server.strategy.FedAvg" +#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" -#~ msgid "server.strategy.FedAvgM" -#~ msgstr "server.strategy.FedAvgM" +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." +#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/pytorch_cifar`。" -#~ msgid "Configurable FedAvg with Momentum strategy implementation." -#~ msgstr "可配置的 FedAvg 动量策略实施。" +#~ msgid "ImageNet-2012 Image Classification" +#~ msgstr "ImageNet-2012 图像分类" -#~ msgid "Fraction of clients used during training. Defaults to 0.1." -#~ msgstr "训练期间使用客户的比例。默认为 0.1。" +#~ msgid "" +#~ "`ImageNet-2012 `_ is " +#~ "one of the major computer vision " +#~ "datasets. The Flower ImageNet example " +#~ "uses PyTorch to train a ResNet-18 " +#~ "classifier in a federated learning setup" +#~ " with ten clients." +#~ msgstr "" +#~ "ImageNet-2012 `_ " +#~ "是主要的计算机视觉数据集之一。Flower ImageNet 示例使用 PyTorch " +#~ "在有十个客户端的联邦学习设置中训练 ResNet-18 分类器。" -#~ msgid "Fraction of clients used during validation. Defaults to 0.1." -#~ msgstr "验证过程中使用的客户端比例。默认为 0.1。" +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" -#~ msgid "server.strategy.FedMedian" -#~ msgstr "server.strategy.FedMedian" +#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" -#~ msgid "server.strategy.QFedAvg" -#~ msgstr "server.strategy.QFedAvg" +#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." +#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/pytorch_imagenet`。" -#~ msgid "server.strategy.FedOpt" -#~ msgstr "server.strategy.FedOpt" +#~ msgid "TensorFlow Examples" +#~ msgstr "TensorFlow 示例" -#~ msgid "Configurable FedAdagrad strategy implementation." -#~ msgstr "可配置的 FedAdagrad 策略实施。" +#~ msgid "" +#~ "Our TensorFlow examples are based on " +#~ "TensorFlow 2.0 or newer. So far, " +#~ "we provide the following examples." +#~ msgstr "我们的 TensorFlow 示例基于 TensorFlow 2.0 或更新版本。到目前为止,我们提供了以下示例。" -#~ msgid "Federated Optim strategy interface." -#~ msgstr "Federated Optim 策略界面。" +#~ msgid "Fashion-MNIST Image Classification" +#~ msgstr "Fashion-MNIST 图像分类" -#~ msgid "server.strategy.FedProx" -#~ msgstr "server.strategy.FedProx" +#~ msgid "" +#~ "`Fashion-MNIST `_ is often used as " +#~ "the \"Hello, world!\" of machine " +#~ "learning. We follow this tradition and" +#~ " provide an example which samples " +#~ "random local datasets from Fashion-MNIST" +#~ " and trains a simple image " +#~ "classification model over those partitions." +#~ msgstr "" +#~ "`Fashion-MNIST `_ 经常被用作机器学习的 \"你好,世界!\"。我们遵循这一传统" +#~ ",提供了一个从Fashion-MNIST 中随机抽样本地数据集的示例,并在这些分区上训练一个简单的图像分类模型。" -#~ msgid "Configurable FedProx strategy implementation." -#~ msgstr "可配置的 FedProx 策略实施。" +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" + +#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" +#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" + +#~ msgid "" +#~ "For more details, see " +#~ ":code:`src/py/flwr_example/tensorflow_fashion_mnist`." +#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/tensorflow_fashion_mnist`。" + +#~ msgid "``BASE_IMAGE_TAG``" +#~ msgstr "基本图像标签" -#~ msgid "server.strategy.FedAdagrad" -#~ msgstr "server.strategy.FedAdagrad" +#~ msgid "The image tag of the base image." +#~ msgstr "基础图像的图像标记。" -#~ msgid "Paper: https://arxiv.org/abs/2003.00295" -#~ msgstr "论文: https://arxiv.org/abs/2003.00295" +#~ msgid "" +#~ "It is important to follow the " +#~ "instructions described in comments. For " +#~ "instance, in order to not break " +#~ "how our changelog system works, you " +#~ "should read the information above the" +#~ " ``Changelog entry`` section carefully. You" +#~ " can also checkout some examples and" +#~ " details in the :ref:`changelogentry` " +#~ "appendix." +#~ msgstr "" +#~ "请务必遵守注释中的说明。例如,为了不破坏我们的更新日志系统,你应该仔细阅读\"`更新日志条目``\"部分上面的信息。您还可以查看 " +#~ ":ref:`changelogentry` 附录中的一些示例和细节。" -#~ msgid "Federated learning strategy using Adagrad on server-side." -#~ msgstr "在服务器端使用 Adagrad 的联邦学习策略。" +#~ msgid "Open a PR (as shown above)" +#~ msgstr "打开 PR(如上图所示)" -#~ msgid "server.strategy.FedAdam" -#~ msgstr "server.strategy.FedAdam" +#~ msgid "How to write a good PR title" +#~ msgstr "如何撰写好的公关标题" -#~ msgid "server.strategy.FedYogi" -#~ msgstr "server.strategy.FedYogi" +#~ msgid "" +#~ "A well-crafted PR title helps team" +#~ " members quickly understand the purpose " +#~ "and scope of the changes being " +#~ "proposed. Here's a guide to help " +#~ "you write a good GitHub PR title:" +#~ msgstr "一个精心撰写的公关标题能帮助团队成员迅速了解所提修改的目的和范围。以下指南可帮助您撰写一个好的 GitHub PR 标题:" -#~ msgid "Adaptive Federated Optimization using Yogi." -#~ msgstr "使用 Yogi 的自适应联合优化。" +#~ msgid "" +#~ "1. Be Clear and Concise: Provide a" +#~ " clear summary of the changes in " +#~ "a concise manner. 1. Use Actionable " +#~ "Verbs: Start with verbs like \"Add,\"" +#~ " \"Update,\" or \"Fix\" to indicate " +#~ "the purpose. 1. Include Relevant " +#~ "Information: Mention the affected feature " +#~ "or module for context. 1. Keep it" +#~ " Short: Avoid lengthy titles for easy" +#~ " readability. 1. Use Proper Capitalization" +#~ " and Punctuation: Follow grammar rules " +#~ "for clarity." +#~ msgstr "" +#~ "1. 简明扼要: 以简明扼要的方式清楚地概述变化。1. 使用可操作的动词: 使用 " +#~ "\"添加\"、\"更新 \"或 \"修复 \"等动词来表明目的。1. 包含相关信息: " +#~ "提及受影响的功能或模块以了解上下文。1. 简短:避免冗长的标题,以方便阅读。1. 使用正确的大小写和标点符号:" +#~ " 遵守语法规则,以确保清晰。" -#~ msgid "Federated learning strategy using Yogi on server-side." -#~ msgstr "在服务器端使用 Yogi 的联邦学习策略。" +#~ msgid "" +#~ "Let's start with a few examples " +#~ "for titles that should be avoided " +#~ "because they do not provide meaningful" +#~ " information:" +#~ msgstr "让我们先举例说明几个应该避免使用的标题,因为它们不能提供有意义的信息:" -#~ msgid "Paper: https://arxiv.org/abs/1803.01498" -#~ msgstr "论文:https://arxiv.org/abs/1803.01498" +#~ msgid "Implement Algorithm" +#~ msgstr "执行算法" -#~ msgid "server.strategy.Krum" -#~ msgstr "server.strategy.Krum" +#~ msgid "Add my_new_file.py to codebase" +#~ msgstr "在代码库中添加 my_new_file.py" -#~ msgid "Configurable Krum strategy implementation." -#~ msgstr "可配置的 Krum 策略实施。" +#~ msgid "Improve code in module" +#~ msgstr "改进模块中的代码" -#~ msgid "server.strategy.Bulyan" -#~ msgstr "server.strategy.Bulyan" +#~ msgid "Change SomeModule" +#~ msgstr "更改 SomeModule" -#~ msgid "Bulyan strategy implementation." -#~ msgstr "Bulyan策略的实施。" +#~ msgid "" +#~ "Here are a few positive examples " +#~ "which provide helpful information without " +#~ "repeating how they do it, as that" +#~ " is already visible in the \"Files" +#~ " changed\" section of the PR:" +#~ msgstr "这里有几个正面的例子,提供了有用的信息,但没有重复他们是如何做的,因为在 PR 的 \"已更改文件 \"部分已经可以看到:" -#~ msgid "server.strategy.FedXgbNnAvg" -#~ msgstr "server.strategy.FedXgbNnAvg" +#~ msgid "Update docs banner to mention Flower Summit 2023" +#~ msgstr "更新文件横幅,提及 2023 年 Flower 峰会" -#~ msgid "Federated XGBoost [Ma et al., 2023] strategy." -#~ msgstr "Federated XGBoost [Ma 等人,2023] 策略。" +#~ msgid "Remove unnecessary XGBoost dependency" +#~ msgstr "移除不必要的 XGBoost 依赖性" -#~ msgid "server.strategy.DPFedAvgAdaptive" -#~ msgstr "server.strategy.DPFedAvgAdaptive" +#~ msgid "Remove redundant attributes in strategies subclassing FedAvg" +#~ msgstr "删除 FedAvg 子类化策略中的多余属性" #~ msgid "" -#~ "**Fix the incorrect return types of Strategy** ([#2432](https://github." -#~ "com/adap/flower/pull/2432/files))" -#~ msgstr "" -#~ "**修复策略的错误返回类型** ([#2432](https://github.com/adap/flower/" -#~ "pull/2432/files))" +#~ "Add CI job to deploy the staging" +#~ " system when the ``main`` branch " +#~ "changes" +#~ msgstr "添加 CI 作业,以便在 \"主 \"分支发生变化时部署暂存系统" #~ msgid "" -#~ "The types of the return values in the docstrings in two methods " -#~ "(`aggregate_fit` and `aggregate_evaluate`) now match the hint types in " -#~ "the code." -#~ msgstr "" -#~ "两个方法(\"aggregate_fit \"和 \"aggregate_evaluate\")的文档说明中的返回" -#~ "值类型现在与代码中的提示类型一致。" +#~ "Add new amazing library which will " +#~ "be used to improve the simulation " +#~ "engine" +#~ msgstr "添加新的惊人库,用于改进模拟引擎" -#~ msgid "" -#~ "**Update Flower Examples** ([#2384](https://github.com/adap/flower/" -#~ "pull/2384),[#2425](https://github.com/adap/flower/pull/2425), [#2526]" -#~ "(https://github.com/adap/flower/pull/2526))" -#~ msgstr "" -#~ "** 更新 Flower Examples** ([#2384](https://github.com/adap/flower/" -#~ "pull/2384),[#2425](https://github.com/adap/flower/pull/2425), [#2526]" -#~ "(https://github.com/adap/flower/pull/2526))" +#~ msgid "Changelog entry" +#~ msgstr "更新日志" #~ msgid "" -#~ "That's it for the client. We only have to implement :code:`Client` or :" -#~ "code:`NumPyClient` and call :code:`fl.client.start_client()`. The string :" -#~ "code:`\"0.0.0.0:8080\"` tells the client which server to connect to. In " -#~ "our case we can run the server and the client on the same machine, " -#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If we run a truly federated " -#~ "workload with the server and clients running on different machines, all " -#~ "that needs to change is the :code:`server_address` we pass to the client." -#~ msgstr "" -#~ "对于客户端就需要做这么多。我们仅需要实现 :code:`Client`或者:code:" -#~ "`NumPyClient`然后调用:code:`fl.client.start_client()`。字符串 :code:" -#~ "`\"0.0.0.0:8080\"` 告诉客户端要连接到哪个服务器。在我们的例子中,我们可以" -#~ "在同一台机器上运行服务器和客户端,因此我们使用:code:`\"0.0.0.0:8080\"`。如" -#~ "果我们运行真正联邦学习的工作负载,服务器和客户端在不同的机器上运行,则需要" -#~ "更改的只是我们传递给客户端的 server_address 。" +#~ "When opening a new PR, inside its" +#~ " description, there should be a " +#~ "``Changelog entry`` header." +#~ msgstr "打开一个新 PR 时,在其描述中应有一个 ``Changelog entry`` 标头。" #~ msgid "" -#~ "That's it for the client. We only have to implement :code:`Client` or :" -#~ "code:`NumPyClient` and call :code:`fl.client.start_client()`. The string :" -#~ "code:`\"[::]:8080\"` tells the client which server to connect to. In our " -#~ "case we can run the server and the client on the same machine, therefore " -#~ "we use :code:`\"[::]:8080\"`. If we run a truly federated workload with " -#~ "the server and clients running on different machines, all that needs to " -#~ "change is the :code:`server_address` we point the client at." -#~ msgstr "" -#~ "对于客户来说就是这样了。我们只需实现 :code:`Client` 或 :code:" -#~ "`NumPyClient` 并调用:code:`fl.client.start_client()` 即可。字符串 :code:" -#~ "`\"[::]:8080\"` 告诉客户端要连接到哪个服务器。在我们的例子中,我们可以在同" -#~ "一台机器上运行服务器和客户端,因此我们使用 :code:`\"[::]:8080\"`。如果我们" -#~ "运行真正联邦的工作负载,服务器和客户端运行在不同的机器上,则需要更改的只是" -#~ "我们指向客户端的 server_address 。" +#~ "Above this header you should see " +#~ "the following comment that explains how" +#~ " to write your changelog entry:" +#~ msgstr "在页眉上方,你会看到以下注释,说明如何编写更新日志条目:" #~ msgid "" -#~ "Let's now load the CIFAR-10 training and test set, partition them into " -#~ "ten smaller datasets (each split into training and validation set), and " -#~ "wrap the resulting partitions by creating a PyTorch ``DataLoader`` for " -#~ "each of them:" -#~ msgstr "" -#~ "现在,让我们加载 CIFAR-10 训练集和测试集,将它们分割成 10 个较小的数据集" -#~ "(每个数据集又分为训练集和验证集),并通过为每个数据集创建 PyTorch " -#~ "``DataLoader`` 来包装由此产生的分割集:" - -#~ msgid "|e1dd4b4129b040bea23a894266227080|" -#~ msgstr "|e1dd4b4129b040bea23a894266227080|" +#~ "Inside the following 'Changelog entry' " +#~ "section, you should put the description" +#~ " of your changes that will be " +#~ "added to the changelog alongside your" +#~ " PR title." +#~ msgstr "在下面的 \"更新日志条目 \"部分中,您应该在 PR 标题旁边写上将添加到更新日志中的更改描述。" -#~ msgid "|c0d4cc6a442948dca8da40d2440068d9|" -#~ msgstr "|c0d4cc6a442948dca8da40d2440068d9|" +#~ msgid "" +#~ "If the section is completely empty " +#~ "(without any token) or non-existent, " +#~ "the changelog will just contain the " +#~ "title of the PR for the changelog" +#~ " entry, without any description." +#~ msgstr "如果该部分完全为空(没有任何标记)或不存在,更新日志将只包含更新日志条目的 PR 标题,而不包含任何描述。" -#~ msgid "|174e1e4fa1f149a19bfbc8bc1126f46a|" -#~ msgstr "|174e1e4fa1f149a19bfbc8bc1126f46a|" +#~ msgid "" +#~ "If the section contains some text " +#~ "other than tokens, it will use it" +#~ " to add a description to the " +#~ "change." +#~ msgstr "如果该部分包含标记以外的文本,它将使用这些文本为更改添加说明。" -#~ msgid "|4e021a3dc08249d2a89daa3ab03c2714|" -#~ msgstr "|4e021a3dc08249d2a89daa3ab03c2714|" +#~ msgid "" +#~ "If the section contains one of the" +#~ " following tokens it will ignore any" +#~ " other text and put the PR " +#~ "under the corresponding section of the" +#~ " changelog:" +#~ msgstr "如果该部分包含以下标记之一,它将忽略任何其他文本,并将 PR 放在更新日志的相应部分下:" -#~ msgid "|e74a1d5ce7eb49688651f2167a59065b|" -#~ msgstr "|e74a1d5ce7eb49688651f2167a59065b|" +#~ msgid " is for classifying a PR as a general improvement." +#~ msgstr " 用于将 PR 划分为一般改进。" -#~ msgid "|eb29ec4c7aef4e93976795ed72df647e|" -#~ msgstr "|eb29ec4c7aef4e93976795ed72df647e|" +#~ msgid " is to not add the PR to the changelog" +#~ msgstr "表示不将 PR 添加到更新日志中" -#~ msgid "|c2f699d8ac484f5081721a6f1511f70d|" -#~ msgstr "|c2f699d8ac484f5081721a6f1511f70d|" +#~ msgid " is to add a general baselines change to the PR" +#~ msgstr " 是指在 PR 中添加一般基线更改" -#~ msgid "|cf42accdacbf4e5eb4fa0503108ba7a7|" -#~ msgstr "|cf42accdacbf4e5eb4fa0503108ba7a7|" +#~ msgid " is to add a general examples change to the PR" +#~ msgstr " 是在 PR 中添加对一般示例的修改" -#~ msgid "|5ec8356bc2564fa09178b1ceed5beccc|" -#~ msgstr "|5ec8356bc2564fa09178b1ceed5beccc|" +#~ msgid " is to add a general sdk change to the PR" +#~ msgstr " 是指在 PR 中添加一般的 sdk 更改" -#~ msgid "|7c9329e97bd0430bad335ab605a897a7|" -#~ msgstr "|7c9329e97bd0430bad335ab605a897a7|" +#~ msgid " is to add a general simulations change to the PR" +#~ msgstr "(模拟)是在 PR 中添加一般模拟变更" -#~ msgid "|88002bbce1094ba1a83c9151df18f707|" -#~ msgstr "|88002bbce1094ba1a83c9151df18f707|" +#~ msgid "Note that only one token should be used." +#~ msgstr "请注意,只能使用一个标记。" -#~ msgid "|391766aee87c482c834c93f7c22225e2|" -#~ msgstr "|391766aee87c482c834c93f7c22225e2|" +#~ msgid "" +#~ "Its content must have a specific " +#~ "format. We will break down what " +#~ "each possibility does:" +#~ msgstr "其内容必须有特定的格式。我们将分析每种可能性的作用:" -#~ msgid "|93b9a15bd27f4e91b40f642c253dfaac|" -#~ msgstr "|93b9a15bd27f4e91b40f642c253dfaac|" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains nothing or doesn't exist, " +#~ "the following text will be added " +#~ "to the changelog::" +#~ msgstr "如果 ``#### Changelog entry`` 部分不包含任何内容或不存在,则会在更新日志中添加以下文本::" -#~ msgid "|a23d9638f96342ef9d25209951e2d564|" -#~ msgstr "|a23d9638f96342ef9d25209951e2d564|" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains a description (and no " +#~ "token), the following text will be " +#~ "added to the changelog::" +#~ msgstr "如果 ``#### Changelog entry`` 部分包含描述(但没有标记),则会在更新日志中添加以下文本::" -#~ msgid "Upload the whl (e.g., ``flwr-1.6.0-py3-none-any.whl``)" -#~ msgstr "上传 whl(例如 ``flwr-1.6.0-py3-none-any.whl``)" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, nothing will change" +#~ " in the changelog." +#~ msgstr "如果 ``#### Changelog entry`` 部分包含 ````,更新日志中将不会有任何更改。" #~ msgid "" -#~ "Change ``!pip install -q 'flwr[simulation]' torch torchvision " -#~ "matplotlib`` to ``!pip install -q 'flwr-1.6.0-py3-none-any." -#~ "whl[simulation]' torch torchvision matplotlib``" -#~ msgstr "" -#~ "将``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``更改" -#~ "为``!pip install -q 'flwr-1.6.0-py3-none-any.whl[simulation]' torch torch " -#~ "torchvision matplotlib``" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text" +#~ " will be added to the changelog::" +#~ msgstr "如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加以下文本::" #~ msgid "" -#~ "All that's left to do it to define a function that loads both model and " -#~ "data, creates a :code:`CifarClient`, and starts this client. You load " -#~ "your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " -#~ "with the function :code:`fl.client.start_numpy_client()` by pointing it " -#~ "at the same IP address we used in :code:`server.py`:" -#~ msgstr "" -#~ "剩下要做的就是定义一个加载模型和数据的函数,创建一个 :code:`CifarClient` " -#~ "并启动该客户端。使用 :code:`cifar.py` 加载数据和模型。使用函数 :code:`fl." -#~ "client.start_numpy_client()` 启动 :code:`CifarClient`,将其指向我们在 :" -#~ "code:`server.py` 中使用的相同 IP 地址:" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "如果``### 更新日志条目``部分包含``<基准线>``,则会在更新日志中添加以下文本::" #~ msgid "" -#~ "The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " -#~ "clients. These clients are identical to `non-virtual` clients (i.e. the " -#~ "ones you launch via the command `flwr.client.start_numpy_client `_) in the sense that they can be configure " -#~ "by creating a class inheriting, for example, from `flwr.client." -#~ "NumPyClient `_ and therefore " -#~ "behave in an identical way. In addition to that, clients managed by the :" -#~ "code:`VirtualClientEngine` are:" -#~ msgstr "" -#~ "代码:`VirtualClientEngine`调度、启动和管理`虚拟`客户端。这些客户端与 \"非" -#~ "虚拟 \"客户端(即通过命令 `flwr.client.start_numpy_client `_启动的客户端)完全相同,它们可以通过创建一个继承" -#~ "自 \"flwr.client.NumPyClient `_\" 的类来配置,因此行为方式也完全相同。除此之外,由 :code:" -#~ "`VirtualClientEngine` 管理的客户端还包括:" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "如果``### 更新日志条目``部分包含``<示例>``,则会在更新日志中添加以下文本::" -#~ msgid "Example: Walk-Through PyTorch & MNIST" -#~ msgstr "实例: PyTorch 和 MNIST 的演练" +#~ msgid "" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following text " +#~ "will be added to the changelog::" +#~ msgstr "如果``### 更新日志条目``部分包含````,则会在更新日志中添加以下文本::" #~ msgid "" -#~ "In this tutorial we will learn, how to train a Convolutional Neural " -#~ "Network on MNIST using Flower and PyTorch." -#~ msgstr "" -#~ "在本教程中,我们将学习如何使用 Flower 和 PyTorch 在 MNIST 上训练卷积神经网" -#~ "络。" +#~ "If the ``### Changelog entry`` section" +#~ " contains ````, the following " +#~ "text will be added to the " +#~ "changelog::" +#~ msgstr "如果 ``### Changelog entry`` 部分包含 ````,则会在更新日志中添加以下文本::" #~ msgid "" -#~ "Since we want to use PyTorch to solve a computer vision task, let's go " -#~ "ahead an install PyTorch and the **torchvision** library:" -#~ msgstr "" -#~ "我们想用 PyTorch 来做计算机视觉任务,需要先安装 PyTorch 和 " -#~ "**torchvision** 库:" +#~ "Note that only one token must be" +#~ " provided, otherwise, only the first " +#~ "action (in the order listed above), " +#~ "will be performed." +#~ msgstr "请注意,必须只提供一个标记,否则将只执行第一个操作(按上述顺序)。" -#~ msgid "Ready... Set... Train!" -#~ msgstr "准备...设置...训练!" +#~ msgid "Example: MXNet - Run MXNet Federated" +#~ msgstr "示例: MXNet - 运行联邦式 MXNet" #~ msgid "" -#~ "Now that we have all our dependencies installed, let's run a simple " -#~ "distributed training with two clients and one server. Our training " -#~ "procedure and network architecture are based on PyTorch's `Basic MNIST " -#~ "Example `_. This " -#~ "will allow you see how easy it is to wrap your code with Flower and begin " -#~ "training in a federated way. We provide you with two helper scripts, " -#~ "namely *run-server.sh*, and *run-clients.sh*. Don't be afraid to look " -#~ "inside, they are simple enough =)." +#~ "This tutorial will show you how to" +#~ " use Flower to build a federated " +#~ "version of an existing MXNet workload." +#~ " We are using MXNet to train a" +#~ " Sequential model on the MNIST " +#~ "dataset. We will structure the example" +#~ " similar to our `PyTorch - From " +#~ "Centralized To Federated " +#~ "`_ walkthrough. " +#~ "MXNet and PyTorch are very similar " +#~ "and a very good comparison between " +#~ "MXNet and PyTorch is given `here " +#~ "`_. First, " +#~ "we build a centralized training approach" +#~ " based on the `Handwritten Digit " +#~ "Recognition " +#~ "`_" +#~ " tutorial. Then, we build upon the" +#~ " centralized training code to run the" +#~ " training in a federated fashion." #~ msgstr "" -#~ "现在我们已经安装了所有的依赖包,让我们用两个客户端和一个服务器来运行一个简" -#~ "单的分布式训练。我们的训练过程和网络架构基于 PyTorch 的 `Basic MNIST " -#~ "Example `_。您会发" -#~ "现用 Flower 来封装您的代码并进行联邦学习训练是多么容易。我们为您提供了两个" -#~ "辅助脚本,即 *run-server.sh* 和 *run-clients.sh*。别害怕,它们很简单 =)。" +#~ "本教程将向您展示如何使用 Flower 构建现有 MXNet 的联学习版本。我们将使用" +#~ " MXNet 在 MNIST 数据集上训练一个序列模型。另外,我们将采用与我们的 " +#~ "`PyTorch - 从集中式到联邦式 " +#~ "`_ 教程类似的示例结构。MXNet" +#~ " 和 PyTorch 非常相似,参考 `此处 " +#~ "`_对 MXNet " +#~ "和 PyTorch 进行了详细的比较。首先,我们根据 `手写数字识别 " +#~ "`" +#~ " 教程 建立了集中式训练方法。然后,我们在集中式训练代码的基础上,以联邦方式运行训练。" #~ msgid "" -#~ "Go ahead and launch on a terminal the *run-server.sh* script first as " -#~ "follows:" -#~ msgstr "首先在终端上启动 *run-server.sh* 脚本,如下所示:" +#~ "Before we start setting up our " +#~ "MXNet example, we install the " +#~ ":code:`mxnet` and :code:`flwr` packages:" +#~ msgstr "在开始设置 MXNet 示例之前,我们先安装 :code:`mxnet` 和 :code:`flwr` 软件包:" -#~ msgid "" -#~ "Now that the server is up and running, go ahead and launch the clients." -#~ msgstr "现在服务器已经启动并运行,请继续启动客户端。" +#~ msgid "MNIST Training with MXNet" +#~ msgstr "使用 MXNet 进行 MNIST 训练" #~ msgid "" -#~ "Et voilà! You should be seeing the training procedure and, after a few " -#~ "iterations, the test accuracy for each client." +#~ "We begin with a brief description " +#~ "of the centralized training code based" +#~ " on a :code:`Sequential` model. If " +#~ "you want a more in-depth " +#~ "explanation of what's going on then " +#~ "have a look at the official `MXNet" +#~ " tutorial " +#~ "`_." #~ msgstr "" -#~ "然后就可以了!您应该能看到训练过程,以及经过几次反复后,每个客户端的测试准" -#~ "确率。" - -#~ msgid "Now, let's see what is really happening inside." -#~ msgstr "现在,让我们看看里面到底发生了什么。" +#~ "首先,我们将简要介绍基于 :code:`Sequential` " +#~ "模型的集中式训练代码。如果您想获得更深入的解释,请参阅官方的 `MXNet教程 " +#~ "`_。" #~ msgid "" -#~ "Inside the server helper script *run-server.sh* you will find the " -#~ "following code that basically runs the :code:`server.py`" +#~ "Let's create a new file " +#~ "called:code:`mxnet_mnist.py` with all the " +#~ "components required for a traditional " +#~ "(centralized) MNIST training. First, the " +#~ "MXNet package :code:`mxnet` needs to be" +#~ " imported. You can see that we " +#~ "do not yet import the :code:`flwr` " +#~ "package for federated learning. This " +#~ "will be done later." #~ msgstr "" -#~ "在服务器辅助脚本 *run-server.sh* 中,你可以找到以下代码,这些代码基本上都" -#~ "是运行 :code:`server.py` 的代码" +#~ "让我们创建一个名为:code:`mxnet_mnist.py`的新文件,其中包含传统(集中式)MNIST " +#~ "训练所需的所有组件。首先,需要导入 MXNet 包 " +#~ ":code:`mxnet`。您可以看到,我们尚未导入用于联合学习的 :code:`flwr` 包,这将在稍后完成。" #~ msgid "" -#~ "We can go a bit deeper and see that :code:`server.py` simply launches a " -#~ "server that will coordinate three rounds of training. Flower Servers are " -#~ "very customizable, but for simple workloads, we can start a server using " -#~ "the :ref:`start_server ` function and " -#~ "leave all the configuration possibilities at their default values, as " -#~ "seen below." -#~ msgstr "" -#~ "我们可以再深入一点,:code:`server.py` 只是启动了一个服务器,该服务器将协调" -#~ "三轮训练。Flower 服务器是非常容易修改的,但对于简单的工作,我们可以使用 :" -#~ "ref:`start_server `函数启动服务器,并将所" -#~ "有可能的配置保留为默认值,如下所示。" +#~ "The :code:`load_data()` function loads the " +#~ "MNIST training and test sets." +#~ msgstr ":code:`load_data()` 函数加载 MNIST 训练集和测试集。" #~ msgid "" -#~ "Next, let's take a look at the *run-clients.sh* file. You will see that " -#~ "it contains the main loop that starts a set of *clients*." +#~ "As already mentioned, we will use " +#~ "the MNIST dataset for this machine " +#~ "learning workload. The model architecture " +#~ "(a very simple :code:`Sequential` model) " +#~ "is defined in :code:`model()`." #~ msgstr "" -#~ "接下来,让我们看看 *run-clients.sh* 文件。您会看到它包含了用来启动多个 *客" -#~ "户端* 的代码。" +#~ "如前所述,我们将使用 MNIST 数据集进行机器学习。模型架构(一个非常简单的 " +#~ ":code:`Sequential` 模型)在 :code:`model()` 中定义。" #~ msgid "" -#~ "**cid**: is the client ID. It is an integer that uniquely identifies " -#~ "client identifier." -#~ msgstr "**cid**:是客户 ID。它是一个整数,可唯一标识客户标识符。" - -#~ msgid "**sever_address**: String that identifies IP and port of the server." -#~ msgstr "**sever_address**: 标识服务器 IP 和端口的字符串。" +#~ "We now need to define the training" +#~ " (function :code:`train()`) which loops " +#~ "over the training set and measures " +#~ "the loss for each batch of " +#~ "training examples." +#~ msgstr "现在,我们需要定义训练函数( :code:`train()`),该函数在训练集上循环训练,并计算每批训练示例的损失值。" #~ msgid "" -#~ "**nb_clients**: This defines the number of clients being created. This " -#~ "piece of information is not required by the client, but it helps us " -#~ "partition the original MNIST dataset to make sure that every client is " -#~ "working on unique subsets of both *training* and *test* sets." -#~ msgstr "" -#~ "**nb_clients**: 这定义了正在创建的客户端数量。客户端并不需要这一信息,但" -#~ "它有助于我们对原始 MNIST 数据集进行划分,以确保每个客户端都在 *training* " -#~ "和 *test* 数据集上有独立的数据。" +#~ "The evaluation of the model is " +#~ "defined in function :code:`test()`. The " +#~ "function loops over all test samples " +#~ "and measures the loss and accuracy " +#~ "of the model based on the test " +#~ "dataset." +#~ msgstr "模型的评估在函数 :code:`test()` 中定义。该函数循环遍历所有测试样本,并根据测试数据集计算模型的损失值和准确度。" #~ msgid "" -#~ "Again, we can go deeper and look inside :code:`flwr_example/quickstart-" -#~ "pytorch/client.py`. After going through the argument parsing code at the " -#~ "beginning of our :code:`main` function, you will find a call to :code:" -#~ "`mnist.load_data`. This function is responsible for partitioning the " -#~ "original MNIST datasets (*training* and *test*) and returning a :code:" -#~ "`torch.utils.data.DataLoader` s for each of them. We then instantiate a :" -#~ "code:`PytorchMNISTClient` object with our client ID, our DataLoaders, the " -#~ "number of epochs in each round, and which device we want to use for " -#~ "training (CPU or GPU)." +#~ "Having defined the data loading, model" +#~ " architecture, training, and evaluation we" +#~ " can put everything together and " +#~ "train our model on MNIST. Note " +#~ "that the GPU/CPU device for the " +#~ "training and testing is defined within" +#~ " the :code:`ctx` (context)." #~ msgstr "" -#~ "我们可以深入看一下 :code:`flwr_example/quickstart-pytorch/client.py`。查" -#~ "看 :code:`main` 函数开头的参数解析代码后,你会发现一个对 :code:`mnist." -#~ "load_data` 的调用。该函数负责分割原始 MNIST 数据集(*training* 和 " -#~ "*test*),并为每个数据集返回一个 :code:`torch.utils.data.DataLoader` 。然" -#~ "后,我们实例化一个 :code:`PytorchMNISTClient` 对象,其中包含我们的客户端 " -#~ "ID、 DataLoader、每一轮中的遍历数,以及我们希望用于训练的设备(CPU 或 " -#~ "GPU)。" +#~ "在定义了数据加载、模型架构、训练和评估之后,我们就可以把所有放在一起,在 MNIST " +#~ "上训练我们的模型了。请注意,用于训练和测试的 GPU/CPU 设备是在 :code:`ctx`中定义的。" + +#~ msgid "You can now run your (centralized) MXNet machine learning workload:" +#~ msgstr "现在,您可以运行(集中式)MXNet 机器学习工作:" #~ msgid "" -#~ "The :code:`PytorchMNISTClient` object when finally passed to :code:`fl." -#~ "client.start_client` along with the server's address as the training " -#~ "process begins." +#~ "So far this should all look fairly" +#~ " familiar if you've used MXNet (or" +#~ " even PyTorch) before. Let's take the" +#~ " next step and use what we've " +#~ "built to create a simple federated " +#~ "learning system consisting of one server" +#~ " and two clients." #~ msgstr "" -#~ "当训练过程开始时,:code:`PytorchMNISTClient` 对象会连同服务器地址一起传递" -#~ "给 :code:`fl.client.start_client`。" +#~ "到目前为止,如果你以前使用过 MXNet(甚至 " +#~ "PyTorch),这一切看起来应该相当熟悉。下一步,让我们利用已构建的内容创建一个简单联邦学习系统(由一个服务器和两个客户端组成)。" -#~ msgid "A Closer Look" -#~ msgstr "仔细看一下" +#~ msgid "MXNet meets Flower" +#~ msgstr "MXNet 结合 Flower" #~ msgid "" -#~ "Now, let's look closely into the :code:`PytorchMNISTClient` inside :code:" -#~ "`flwr_example.quickstart-pytorch.mnist` and see what it is doing:" +#~ "So far, it was not easily possible" +#~ " to use MXNet workloads for federated" +#~ " learning because federated learning is " +#~ "not supported in MXNet. Since Flower " +#~ "is fully agnostic towards the underlying" +#~ " machine learning framework, it can " +#~ "be used to federated arbitrary machine" +#~ " learning workloads. This section will " +#~ "show you how Flower can be used" +#~ " to federate our centralized MXNet " +#~ "workload." #~ msgstr "" -#~ "现在,让我们仔细研究一下 :code:`flwr_example.quickstart-pytorch.mnist` 中" -#~ "的 :code:`PytorchMNISTClient`,看看它在做什么:" +#~ "由于 MXNet 目前不支持联邦学习,因此无法轻松地直接将 MXNet " +#~ "用于联邦学习之中。Flower 与底层机器学习框架完全无关,因此它可用于任意联邦式机器学习工作。本节将向你展示如何使用 " +#~ "Flower 将我们的集中式 MXNet 改为联邦式训练。" #~ msgid "" -#~ "The first thing to notice is that :code:`PytorchMNISTClient` instantiates " -#~ "a CNN model inside its constructor" +#~ "The concept to federate an existing " +#~ "workload is always the same and " +#~ "easy to understand. We have to " +#~ "start a *server* and then use the" +#~ " code in :code:`mxnet_mnist.py` for the " +#~ "*clients* that are connected to the " +#~ "*server*. The *server* sends model " +#~ "parameters to the clients. The *clients*" +#~ " run the training and update the " +#~ "parameters. The updated parameters are " +#~ "sent back to the *server* which " +#~ "averages all received parameter updates. " +#~ "This describes one round of the " +#~ "federated learning process and we repeat" +#~ " this for multiple rounds." #~ msgstr "" -#~ "首先要注意的是 :code:`PytorchMNISTClient` 在其构造函数中实例化了一个 CNN " -#~ "模型" +#~ "将现有模型框架联邦化的概念始终是相同的,也很容易理解。我们必须启动一个*服务器*,然后对连接到*服务器*的*客户端*使用 " +#~ ":code:`mxnet_mnist.py`中的代码。*服务器*向客户端发送模型参数,然后*客户端*运行训练并更新参数。更新后的参数被发回*服务器*,然后会对所有收到的参数更新进行平均聚合。以上描述的是一轮联邦学习过程,我们将重复进行多轮学习。" #~ msgid "" -#~ "The code for the CNN is available under :code:`quickstart-pytorch.mnist` " -#~ "and it is reproduced below. It is the same network found in `Basic MNIST " -#~ "Example `_." +#~ "Finally, we will define our *client* " +#~ "logic in :code:`client.py` and build " +#~ "upon the previously defined MXNet " +#~ "training in :code:`mxnet_mnist.py`. Our " +#~ "*client* needs to import :code:`flwr`, " +#~ "but also :code:`mxnet` to update the " +#~ "parameters on our MXNet model:" #~ msgstr "" -#~ "CNN 的代码可在 :code:`quickstart-pytorch.mnist` 下找到,现复制如下。它与 " -#~ "`Basic MNIST Example `_中的网络相同。" +#~ "最后,我们将在 :code:`client.py` 中定义我们的 *client* " +#~ "逻辑,并以之前在 :code:`mxnet_mnist.py` 中定义的 MXNet " +#~ "训练为基础。我们的 *client* 不仅需要导入 :code:`flwr`,还需要导入 " +#~ ":code:`mxnet`,以更新 MXNet 模型的参数:" #~ msgid "" -#~ "The second thing to notice is that :code:`PytorchMNISTClient` class " -#~ "inherits from the :code:`fl.client.Client`, and hence it must implement " -#~ "the following methods:" +#~ "Implementing a Flower *client* basically " +#~ "means implementing a subclass of either" +#~ " :code:`flwr.client.Client` or " +#~ ":code:`flwr.client.NumPyClient`. Our implementation " +#~ "will be based on " +#~ ":code:`flwr.client.NumPyClient` and we'll call " +#~ "it :code:`MNISTClient`. :code:`NumPyClient` is " +#~ "slightly easier to implement than " +#~ ":code:`Client` if you use a framework" +#~ " with good NumPy interoperability (like " +#~ "PyTorch or MXNet) because it avoids " +#~ "some of the boilerplate that would " +#~ "otherwise be necessary. :code:`MNISTClient` " +#~ "needs to implement four methods, two " +#~ "methods for getting/setting model parameters," +#~ " one method for training the model," +#~ " and one method for testing the " +#~ "model:" #~ msgstr "" -#~ "第二件要注意的事是 :code:`PytorchMNISTClient` 类继承自 :code:`fl.client." -#~ "Client`,因此它必须实现以下方法:" +#~ "实现 Flower *client*基本上意味着要实现 " +#~ ":code:`flwr.client.Client` 或 " +#~ ":code:`flwr.client.NumPyClient` 的子类。我们的代码实现将基于 " +#~ ":code:`flwr.client.NumPyClient`,并将其命名为 " +#~ ":code:`MNISTClient`。如果使用具有良好 NumPy 互操作性的框架(如 PyTorch" +#~ " 或 MXNet),:code:`NumPyClient` 比 " +#~ ":code:`Client`更容易实现,因为它避免了一些不必要的操作。:code:`MNISTClient` " +#~ "需要实现四个方法,两个用于获取/设置模型参数,一个用于训练模型,一个用于测试模型:" + +#~ msgid "transform MXNet :code:`NDArray`'s to NumPy :code:`ndarray`'s" +#~ msgstr "将 MXNet :code:`NDArray` 转换为 NumPy :code:`ndarray`" #~ msgid "" -#~ "When comparing the abstract class to its derived class :code:" -#~ "`PytorchMNISTClient` you will notice that :code:`fit` calls a :code:" -#~ "`train` function and that :code:`evaluate` calls a :code:`test`: function." +#~ "The challenging part is to transform " +#~ "the MXNet parameters from :code:`NDArray` " +#~ "to :code:`NumPy Arrays` to make it " +#~ "readable for Flower." #~ msgstr "" -#~ "将抽象类与其派生类 :code:`PytorchMNISTClient` 进行比较时,您会发现 :code:" -#~ "`fit` 调用了一个 :code:`train` 函数,而 :code:`evaluate` 则调用了一个 :" -#~ "code:`test`: 函数。" +#~ "具有挑战性的部分是将 MXNet 参数从 :code:`NDArray` 转换为 " +#~ ":code:`NumPy Arrays` 以便 Flower 可以读取。" #~ msgid "" -#~ "These functions can both be found inside the same :code:`quickstart-" -#~ "pytorch.mnist` module:" +#~ "The two :code:`NumPyClient` methods " +#~ ":code:`fit` and :code:`evaluate` make use " +#~ "of the functions :code:`train()` and " +#~ ":code:`test()` previously defined in " +#~ ":code:`mxnet_mnist.py`. So what we really " +#~ "do here is we tell Flower through" +#~ " our :code:`NumPyClient` subclass which of" +#~ " our already defined functions to " +#~ "call for training and evaluation. We " +#~ "included type annotations to give you" +#~ " a better understanding of the data" +#~ " types that get passed around." #~ msgstr "" -#~ "这些函数都可以在同一个 :code:`quickstart-pytorch.mnist` 模块中找到:" +#~ "这两个 :code:`NumPyClient` 方法 :code:`fit` 和 " +#~ ":code:`evaluate` 使用了之前在 :code:`mxnet_mnist.py` " +#~ "中定义的函数 :code:`train()` 和 :code:`test()`。因此,我们要做的就是通过" +#~ " :code:`NumPyClient` 子类告知 Flower " +#~ "在训练和评估时要调用哪些已定义的函数。我们加入了类型注解,以便让您更好地理解传递的数据类型。" #~ msgid "" -#~ "Observe that these functions encapsulate regular training and test loops " -#~ "and provide :code:`fit` and :code:`evaluate` with final statistics for " -#~ "each round. You could substitute them with your custom train and test " -#~ "loops and change the network architecture, and the entire example would " -#~ "still work flawlessly. As a matter of fact, why not try and modify the " -#~ "code to an example of your liking?" +#~ "Having defined data loading, model " +#~ "architecture, training, and evaluation we " +#~ "can put everything together and train" +#~ " our :code:`Sequential` model on MNIST." #~ msgstr "" -#~ "请注意,这些函数封装了常规的训练和测试循环,并为 :code:`fit` 和 :code:" -#~ "`evaluate` 提供了每轮的最终统计数据。您可以用自定义的训练和测试循环来替代" -#~ "它们,并改变网络结构,整个示例仍然可以完美运行。事实上,为什么不按照自己的" -#~ "喜好修改代码呢?" +#~ "在定义了数据加载、模型架构、训练和评估之后,我们就可以将所有内容整合在一起,在 MNIST 上训练我们的 " +#~ ":code:`Sequential` 模型。" -#~ msgid "Give It a Try" -#~ msgstr "试试看" +#~ msgid "" +#~ "in each window (make sure that the" +#~ " server is still running before you" +#~ " do so) and see your MXNet " +#~ "project run federated learning across " +#~ "two clients. Congratulations!" +#~ msgstr "确保服务器仍在运行后,然后就能在每个窗口中看到 MXNet 项目在两个客户端上运行联邦学习了。祝贺!" #~ msgid "" -#~ "Looking through the quickstart code description above will have given a " -#~ "good understanding of how *clients* and *servers* work in Flower, how to " -#~ "run a simple experiment, and the internals of a client wrapper. Here are " -#~ "a few things you could try on your own and get more experience with " -#~ "Flower:" +#~ "The full source code for this " +#~ "example: `MXNet: From Centralized To " +#~ "Federated (Code) " +#~ "`_. Our " +#~ "example is of course somewhat over-" +#~ "simplified because both clients load the" +#~ " exact same dataset, which isn't " +#~ "realistic. You're now prepared to " +#~ "explore this topic further. How about" +#~ " using a CNN or using a " +#~ "different dataset? How about adding more" +#~ " clients?" #~ msgstr "" -#~ "通过上面的快速入门代码描述,你将对 Flower 中*客户端*和*服务器*的工作方式、" -#~ "如何运行一个简单的实验以及客户端封装器的内部结构有一个很好的了解。您可以自" -#~ "己尝试以下内容,以获得更多使用 Flower 的经验:" +#~ "此示例的完整源代码在:\"MXNet: From Centralized To " +#~ "Federated (Code) " +#~ "`_。当然,我们的示例有些过于简单,因为两个客户端都加载了完全相同的数据集,这并不真实。现在您已经准备好进一步探讨了。使用" +#~ " CNN 或使用不同的数据集会如何?添加更多客户端会如何?" -#~ msgid "" -#~ "Try and change :code:`PytorchMNISTClient` so it can accept different " -#~ "architectures." -#~ msgstr "尝试修改 :code:`PytorchMNISTClient`,使其可以接受不同的架构。" +#~ msgid "with the following command sequence:" +#~ msgstr "使用以下命令序列:" #~ msgid "" -#~ "Modify the :code:`train` function so that it accepts different optimizers" -#~ msgstr "修改 :code:`train` 函数,使其接受不同的优化器" +#~ "In case you are a researcher you" +#~ " might be just fine using the " +#~ "self-signed certificates generated using " +#~ "the scripts which are part of this" +#~ " guide." +#~ msgstr "如果你是一名研究人员,使用本指南中的脚本生成的自签名证书就可以了。" #~ msgid "" -#~ "Modify the :code:`test` function so that it proves not only the top-1 " -#~ "(regular accuracy) but also the top-5 accuracy?" -#~ msgstr "" -#~ "修改 :code:`test` 函数,使其不仅能输出前 1 名(常规精确度),还能证明前 5 " -#~ "名的精确度?" +#~ "We are now going to show how " +#~ "to write a sever which uses the" +#~ " previously generated scripts." +#~ msgstr "现在,我们将展示如何编写一个使用先前生成的脚本的服务器。" #~ msgid "" -#~ "Go larger! Try to adapt the code to larger images and datasets. Why not " -#~ "try training on ImageNet with a ResNet-50?" +#~ "When providing certificates, the server " +#~ "expects a tuple of three certificates." +#~ " :code:`Path` can be used to easily" +#~ " read the contents of those files " +#~ "into byte strings, which is the " +#~ "data type :code:`start_server` expects." #~ msgstr "" -#~ "让我们尝试让代码适应更大的图像和数据集。为什么不尝试使用 ResNet-50 在 " -#~ "ImageNet 上进行训练呢?" +#~ "在提供证书时,服务器希望得到由三个证书组成的元组。 :code:`Path` " +#~ "可用于轻松地将这些文件的内容读取为字节字符串,这就是 :code:`start_server` 期望的数据类型。" -#~ msgid "You are ready now. Enjoy learning in a federated way!" -#~ msgstr "您现在已经准备就绪。尽情享受联邦学习的乐趣吧!" +#~ msgid "Flower server" +#~ msgstr "Flower 服务器" -#~ msgid "Differential privacy" -#~ msgstr "差别隐私" +#~ msgid "flower-driver-api" +#~ msgstr "flower-driver-api" -#~ msgid "" -#~ "Flower provides differential privacy (DP) wrapper classes for the easy " -#~ "integration of the central DP guarantees provided by DP-FedAvg into " -#~ "training pipelines defined in any of the various ML frameworks that " -#~ "Flower is compatible with." -#~ msgstr "" -#~ "Flower 提供了差分隐私 (DP) 封装类,可将 DP-FedAvg 提供的核心 DP 轻松集成" -#~ "到 Flower 兼容的各种 ML 框架中定义的训练模式中。" +#~ msgid "flower-fleet-api" +#~ msgstr "flower-fleet-api" #~ msgid "" -#~ "Please note that these components are still experimental; the correct " -#~ "configuration of DP for a specific task is still an unsolved problem." +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" #~ msgstr "" -#~ "请注意,这些组件仍处于试验阶段,如何为特定任务正确配置 DP 仍是一个尚未解决" -#~ "的问题。" +#~ ":py:obj:`start_driver `\\ " +#~ "\\(\\*\\[\\, server\\_address\\, server\\, ...\\]\\)" + +#~ msgid "Start a Flower Driver API server." +#~ msgstr "启动基于 Ray 的Flower模拟服务器。" #~ msgid "" -#~ "The name DP-FedAvg is misleading since it can be applied on top of any FL " -#~ "algorithm that conforms to the general structure prescribed by the FedOpt " -#~ "family of algorithms." +#~ ":py:obj:`Driver `\\ " +#~ "\\(\\[driver\\_service\\_address\\, ...\\]\\)" #~ msgstr "" -#~ "DP-FedAvg 这个名称容易引起误解,因为它可以应用于任何符合 FedOpt 系列算法规" -#~ "定的一般结构的 FL 算法之上。" +#~ "Flower 1.0: ``start_server(..., " +#~ "config=flwr.server.ServerConfig(num_rounds=3, " +#~ "round_timeout=600.0), ...)``" -#~ msgid "DP-FedAvg" -#~ msgstr "DP-FedAvg" +#~ msgid "`Driver` class provides an interface to the Driver API." +#~ msgstr "`Driver` 类为驱动程序 API 提供了一个接口。" #~ msgid "" -#~ "DP-FedAvg, originally proposed by McMahan et al. [mcmahan]_ and extended " -#~ "by Andrew et al. [andrew]_, is essentially FedAvg with the following " -#~ "modifications." -#~ msgstr "DP-FedAvg 最初由McMahan等人提出,并由Andrew等人加以扩展。" +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:9091\"`." +#~ msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" + +#~ msgid ":py:obj:`close `\\ \\(\\)" +#~ msgstr "server.strategy.Strategy" + +#~ msgid "Disconnect from the SuperLink if connected." +#~ msgstr "如果已连接,请断开与超级链接的连接。" + +#~ msgid "start\\_driver" +#~ msgstr "启动客户端" #~ msgid "" -#~ "**Clipping** : The influence of each client's update is bounded by " -#~ "clipping it. This is achieved by enforcing a cap on the L2 norm of the " -#~ "update, scaling it down if needed." -#~ msgstr "" -#~ "**裁剪** : 裁剪会影响到每个客户端的模型参数。具体做法是对参数的 L2 准则设" -#~ "置上限,必要时将其缩减。" +#~ "The IPv4 or IPv6 address of the" +#~ " Driver API server. Defaults to " +#~ "`\"[::]:8080\"`." +#~ msgstr "服务器的 IPv4 或 IPv6 地址。默认为 `\"[::]:8080\"。" #~ msgid "" -#~ "**Noising** : Gaussian noise, calibrated to the clipping threshold, is " -#~ "added to the average computed at the server." -#~ msgstr "" -#~ "**噪声** : 在服务器计算出的平均值中加入高斯噪声,该噪声根据剪切阈值进行校" -#~ "准。" +#~ "A server implementation, either " +#~ "`flwr.server.Server` or a subclass thereof." +#~ " If no instance is provided, then " +#~ "`start_driver` will create one." +#~ msgstr "服务器实现,可以是 `flwr.server.Server` 或其子类。如果没有提供实例,`start_server` 将创建一个。" #~ msgid "" -#~ "The distribution of the update norm has been shown to vary from task-to-" -#~ "task and to evolve as training progresses. This variability is crucial in " -#~ "understanding its impact on differential privacy guarantees, emphasizing " -#~ "the need for an adaptive approach [andrew]_ that continuously adjusts the " -#~ "clipping threshold to track a prespecified quantile of the update norm " -#~ "distribution." +#~ "An implementation of the class " +#~ "`flwr.server.ClientManager`. If no implementation" +#~ " is provided, then `start_driver` will " +#~ "use `flwr.server.SimpleClientManager`." #~ msgstr "" -#~ "事实证明,参数更新准则的分布会随着任务的不同而变化,并随着训练的进展而演" -#~ "变。因此,我们采用了一种自适应方法,该方法会不断调整剪切阈值,以跟踪参数更" -#~ "新准则分布的预设量化值。" +#~ "抽象基类 `flwr.server.ClientManager` " +#~ "的实现。如果没有提供实现,`start_server` 将使用 " +#~ "`flwr.server.client_manager.SimpleClientManager`。" -#~ msgid "Simplifying Assumptions" -#~ msgstr "简化假设" +#~ msgid "The Driver object to use." +#~ msgstr "要使用的驱动程序对象。" -#~ msgid "" -#~ "We make (and attempt to enforce) a number of assumptions that must be " -#~ "satisfied to ensure that the training process actually realizes the :math:" -#~ "`(\\epsilon, \\delta)` guarantees the user has in mind when configuring " -#~ "the setup." -#~ msgstr "" -#~ "我们提出(并试图执行)了一系列必须满足的假设,以确保训练过程真正实现用户在" -#~ "配置设置时所定的 :math:`(\\epsilon,\\delta)` 。" +#~ msgid "Starting a driver that connects to an insecure server:" +#~ msgstr "启动不安全的服务器:" -#~ msgid "" -#~ "**Fixed-size subsampling** :Fixed-size subsamples of the clients must be " -#~ "taken at each round, as opposed to variable-sized Poisson subsamples." -#~ msgstr "" -#~ "** 固定大小的子样本** :与可变大小的泊松分布子样本相比,每轮必须抽取固定大" -#~ "小的客户端子样本。" +#~ msgid "Starting a driver that connects to an SSL-enabled server:" +#~ msgstr "启动支持 SSL 的服务器:" #~ msgid "" -#~ "**Unweighted averaging** : The contributions from all the clients must " -#~ "weighted equally in the aggregate to eliminate the requirement for the " -#~ "server to know in advance the sum of the weights of all clients available " -#~ "for selection." +#~ ":py:obj:`run_simulation_from_cli " +#~ "`\\ \\(\\)" #~ msgstr "" -#~ "**非加权平均**: 所有客户端的贡献必须加权相等,这样服务器就不需要事先知道" -#~ "所有客户的权重总和。" -#~ msgid "" -#~ "**No client failures** : The set of available clients must stay constant " -#~ "across all rounds of training. In other words, clients cannot drop out or " -#~ "fail." +#~ msgid "Run Simulation Engine from the CLI." #~ msgstr "" -#~ "**没有失败的客户端** : 在各轮训练中,可用客户端的数量必须保持不变。换句话" -#~ "说,客户端不能退出或失败。" -#~ msgid "" -#~ "The first two are useful for eliminating a multitude of complications " -#~ "associated with calibrating the noise to the clipping threshold, while " -#~ "the third one is required to comply with the assumptions of the privacy " -#~ "analysis." -#~ msgstr "" -#~ "前两种方法有助于消除将噪声校准为削波阈值所带来的诸多复杂问题,而第三种方法" -#~ "则需要符合隐私分析的假设。" +#~ msgid "run\\_simulation\\_from\\_cli" +#~ msgstr "运行模拟" #~ msgid "" -#~ "These restrictions are in line with constraints imposed by Andrew et al. " -#~ "[andrew]_." -#~ msgstr "这些限制与 Andrew 等人所施加的限制一致。" +#~ "Check out this Federated Learning " +#~ "quickstart tutorial for using Flower " +#~ "with MXNet to train a Sequential " +#~ "model on MNIST." +#~ msgstr "查看此联邦学习 快速入门教程,了解如何使用 Flower 和 MXNet 在 MNIST 上训练序列模型。" -#~ msgid "Customizable Responsibility for Noise injection" -#~ msgstr "可定制的噪声注入" +#~ msgid "Quickstart MXNet" +#~ msgstr "快速入门 MXNet" #~ msgid "" -#~ "In contrast to other implementations where the addition of noise is " -#~ "performed at the server, you can configure the site of noise injection to " -#~ "better match your threat model. We provide users with the flexibility to " -#~ "set up the training such that each client independently adds a small " -#~ "amount of noise to the clipped update, with the result that simply " -#~ "aggregating the noisy updates is equivalent to the explicit addition of " -#~ "noise to the non-noisy aggregate at the server." +#~ "MXNet is no longer maintained and " +#~ "has been moved into `Attic " +#~ "`_. As a " +#~ "result, we would encourage you to " +#~ "use other ML frameworks alongside " +#~ "Flower, for example, PyTorch. This " +#~ "tutorial might be removed in future " +#~ "versions of Flower." #~ msgstr "" -#~ "与其他在服务器上添加噪声的实现方法不同,您可以配置噪声注入的位置,以便更好" -#~ "地匹配您的威胁模型。我们为用户提供了设置训练的灵活性,使每个客户端都能独立" -#~ "地为剪切参数更新添加少量噪声,这样,只需聚合噪声更新,就相当于在服务器上为" -#~ "非噪声聚合添加噪声了。" #~ msgid "" -#~ "To be precise, if we let :math:`m` be the number of clients sampled each " -#~ "round and :math:`\\sigma_\\Delta` be the scale of the total Gaussian " -#~ "noise that needs to be added to the sum of the model updates, we can use " -#~ "simple maths to show that this is equivalent to each client adding noise " -#~ "with scale :math:`\\sigma_\\Delta/\\sqrt{m}`." -#~ msgstr "" -#~ "准确地说,我们假设每轮采样的客户端数量为:math:`m`,:math:" -#~ "`\\sigma_\\Delta` 为需要添加到模型更新总和中的总高斯噪声的规模,我们就可以" -#~ "用简单的数学方法证明了,这相当于每个客户端都添加了规模为 :math:" -#~ "`\\sigma_\\Delta/\\sqrt{m}` 的噪声。" +#~ "In this tutorial, we will learn " +#~ "how to train a :code:`Sequential` model" +#~ " on MNIST using Flower and MXNet." +#~ msgstr "在本教程中,我们将学习如何使用 Flower 和 MXNet 在 MNIST 上训练 :code:`Sequential` 模型。" -#~ msgid "Wrapper-based approach" -#~ msgstr "基于封装的方法" +#~ msgid "Since we want to use MXNet, let's go ahead and install it:" +#~ msgstr "既然我们要使用 MXNet,那就继续安装吧:" #~ msgid "" -#~ "Introducing DP to an existing workload can be thought of as adding an " -#~ "extra layer of security around it. This inspired us to provide the " -#~ "additional server and client-side logic needed to make the training " -#~ "process differentially private as wrappers for instances of the :code:" -#~ "`Strategy` and :code:`NumPyClient` abstract classes respectively. This " -#~ "wrapper-based approach has the advantage of being easily composable with " -#~ "other wrappers that someone might contribute to the Flower library in the " -#~ "future, e.g., for secure aggregation. Using Inheritance instead can be " -#~ "tedious because that would require the creation of new sub- classes every " -#~ "time a new class implementing :code:`Strategy` or :code:`NumPyClient` is " -#~ "defined." +#~ "Now that we have all our " +#~ "dependencies installed, let's run a " +#~ "simple distributed training with two " +#~ "clients and one server. Our training " +#~ "procedure and network architecture are " +#~ "based on MXNet´s `Hand-written Digit " +#~ "Recognition tutorial " +#~ "`_." #~ msgstr "" -#~ "在现有工作负载中引入 DP 可以被认为是在其周围增加了一层额外的安全性。受此启" -#~ "发,我们提供了额外的服务器端和客户端逻辑,分别作为 :code:`Strategy` 和 :" -#~ "code:`NumPyClient` 抽象类实例的封装器,使训练过程具有不同的隐私性。这种基" -#~ "于封装器的方法的优点是可以很容易地与将来有人贡献给 Flower 的其他封装器(例" -#~ "如用于安全聚合的封装器)进行组合。使用继承可能会比较繁琐,因为每次定义实" -#~ "现 :code:`Strategy` 或 :code:`NumPyClient` 的新类时,都需要创建新的子类。" +#~ "现在,我们已经安装了所有依赖项,让我们用两个客户端和一个服务器来运行一个简单的分布式训练。我们的训练程序和网络架构基于 " +#~ "MXNet 的 `手写数字识别教程 " +#~ "`_\"。" #~ msgid "" -#~ "The first version of our solution was to define a decorator whose " -#~ "constructor accepted, among other things, a boolean-valued variable " -#~ "indicating whether adaptive clipping was to be enabled or not. We quickly " -#~ "realized that this would clutter its :code:`__init__()` function with " -#~ "variables corresponding to hyperparameters of adaptive clipping that " -#~ "would remain unused when it was disabled. A cleaner implementation could " -#~ "be achieved by splitting the functionality into two decorators, :code:" -#~ "`DPFedAvgFixed` and :code:`DPFedAvgAdaptive`, with the latter sub- " -#~ "classing the former. The constructors for both classes accept a boolean " -#~ "parameter :code:`server_side_noising`, which, as the name suggests, " -#~ "determines where noising is to be performed." -#~ msgstr "" -#~ "我们的第一版解决方案是定义一个装饰器,其构造函数接受一个布尔值变量,表示是" -#~ "否启用自适应剪裁。我们很快意识到,这样会使其 :code:`__init__()` 函数中与自" -#~ "适应裁剪超参数相对应的变量变得杂乱无章,而这些变量在自适应裁剪被禁用时将保" -#~ "持未使用状态。要实现更简洁的功能,可以将该功能拆分为两个装饰器,即 :code:" -#~ "`DPFedAvgFixed` 和 :code:`DPFedAvgAdaptive`,后者是前者的子类。这两个类的" -#~ "构造函数都接受一个布尔参数 :code:`server_side_noising`,顾名思义,它决定了" -#~ "在哪里加噪声。" +#~ "In a file called :code:`client.py`, " +#~ "import Flower and MXNet related " +#~ "packages:" +#~ msgstr "在名为 :code:`client.py` 的文件中,导入 Flower 和 MXNet 相关软件包:" -#~ msgid "" -#~ "The server-side capabilities required for the original version of DP-" -#~ "FedAvg, i.e., the one which performed fixed clipping, can be completely " -#~ "captured with the help of wrapper logic for just the following two " -#~ "methods of the :code:`Strategy` abstract class." -#~ msgstr "" -#~ "只需对 :code:`Strategy` 抽象类的以下两个方法进行封装,就能完全捕获 DP-" -#~ "FedAvg 原始版本(即执行固定剪裁的版本)所需的服务器端功能。" +#~ msgid "In addition, define the device allocation in MXNet with:" +#~ msgstr "此外,还可以在 MXNet 中定义设备分配:" #~ msgid "" -#~ ":code:`configure_fit()` : The config dictionary being sent by the " -#~ "wrapped :code:`Strategy` to each client needs to be augmented with an " -#~ "additional value equal to the clipping threshold (keyed under :code:" -#~ "`dpfedavg_clip_norm`) and, if :code:`server_side_noising=true`, another " -#~ "one equal to the scale of the Gaussian noise that needs to be added at " -#~ "the client (keyed under :code:`dpfedavg_noise_stddev`). This entails " -#~ "*post*-processing of the results returned by the wrappee's implementation " -#~ "of :code:`configure_fit()`." +#~ "We use MXNet to load MNIST, a " +#~ "popular image classification dataset of " +#~ "handwritten digits for machine learning. " +#~ "The MXNet utility :code:`mx.test_utils.get_mnist()`" +#~ " downloads the training and test " +#~ "data." #~ msgstr "" -#~ ":code:`configure_fit()` :由封装的 :code:`Strategy` 发送到每个客户端的配置" -#~ "字典需要使用等于裁剪阈值的附加值(在 :code:`dpfedavg_clip_norm` 下键入)进" -#~ "行扩充。并且,如果 server_side_noising=true,则另一个值等于需要在客户端添" -#~ "加的高斯噪声的大小(在 dpfedavg_noise_stddev 下键入)。这需要对封装后的" -#~ "configure_fit() 所返回的结果进行后处理。" +#~ "我们使用 MXNet 加载 MNIST,这是一个用于机器学习的流行手写数字图像分类数据集。MXNet" +#~ " 工具 :code:`mx.test_utils.get_mnist()` 会下载训练和测试数据。" #~ msgid "" -#~ ":code:`aggregate_fit()`: We check whether any of the sampled clients " -#~ "dropped out or failed to upload an update before the round timed out. In " -#~ "that case, we need to abort the current round, discarding any successful " -#~ "updates that were received, and move on to the next one. On the other " -#~ "hand, if all clients responded successfully, we must force the averaging " -#~ "of the updates to happen in an unweighted manner by intercepting the :" -#~ "code:`parameters` field of :code:`FitRes` for each received update and " -#~ "setting it to 1. Furthermore, if :code:`server_side_noising=true`, each " -#~ "update is perturbed with an amount of noise equal to what it would have " -#~ "been subjected to had client-side noising being enabled. This entails " -#~ "*pre*-processing of the arguments to this method before passing them on " -#~ "to the wrappee's implementation of :code:`aggregate_fit()`." -#~ msgstr "" -#~ ":code:`aggregate_fit()`: 我们会检查是否有任何客户端在本轮超时前退出或未能" -#~ "上传参数更新。在这种情况下,我们需要中止当前一轮,丢弃已收到的所有参数更" -#~ "新,然后继续下一轮。另一方面,如果所有客户端都成功响应,我们就必须通过拦" -#~ "截 :code:`FitRes` 的 :code:`parameters` 字段并将其设置为 1,强制以不加权的" -#~ "方式平均更新。此外,如果 :code:`server_side_noising=true`,每次更新都会受" -#~ "到一定量的噪声扰动,其扰动量相当于启用客户端噪声时的扰动量。 这就需要在将" -#~ "本方法的参数传递给封装的 :code:`aggregate_fit()` 之前,对参数进行*预*处" -#~ "理。" +#~ "Define the training and loss with " +#~ "MXNet. We train the model by " +#~ "looping over the dataset, measure the" +#~ " corresponding loss, and optimize it." +#~ msgstr "用 MXNet 定义训练和损失值。我们在数据集上循环训练模型,测量相应的损失值,并对其进行优化。" #~ msgid "" -#~ "We can't directly change the aggregation function of the wrapped strategy " -#~ "to force it to add noise to the aggregate, hence we simulate client-side " -#~ "noising to implement server-side noising." -#~ msgstr "" -#~ "我们无法直接改变封装策略的聚合函数,迫使它在聚合中添加噪声,因此我们模拟客" -#~ "户端噪声来实现服务器端噪声。" +#~ "Next, we define the validation of " +#~ "our machine learning model. We loop " +#~ "over the test set and measure both" +#~ " loss and accuracy on the test " +#~ "set." +#~ msgstr "接下来,我们定义机器学习模型的验证。我们在测试集上循环,测量测试集上的损失值和准确率。" #~ msgid "" -#~ "These changes have been put together into a class called :code:" -#~ "`DPFedAvgFixed`, whose constructor accepts the strategy being decorated, " -#~ "the clipping threshold and the number of clients sampled every round as " -#~ "compulsory arguments. The user is expected to specify the clipping " -#~ "threshold since the order of magnitude of the update norms is highly " -#~ "dependent on the model being trained and providing a default value would " -#~ "be misleading. The number of clients sampled at every round is required " -#~ "to calculate the amount of noise that must be added to each individual " -#~ "update, either by the server or the clients." -#~ msgstr "" -#~ "这些变化被整合到一个名为 :code:`DPFedAvgFixed` 的类中,其构造函数接受被装" -#~ "饰的策略、剪切阈值和每轮采样的客户数作为必选参数。用户需要指定剪切阈值,因" -#~ "为参数更新规范的数量级在很大程度上取决于正在训练的模型,提供默认值会产生误" -#~ "导。每轮采样的客户端数量是计算服务器或客户在每次参数更新时添加的噪音量所必" -#~ "需的。" +#~ "After defining the training and testing" +#~ " of a MXNet machine learning model," +#~ " we use these functions to implement" +#~ " a Flower client." +#~ msgstr "在定义了 MXNet 机器学习模型的训练和测试后,我们使用这些函数实现了 Flower 客户端。" -#~ msgid "" -#~ "The additional functionality required to facilitate adaptive clipping has " -#~ "been provided in :code:`DPFedAvgAdaptive`, a subclass of :code:" -#~ "`DPFedAvgFixed`. It overrides the above-mentioned methods to do the " -#~ "following." -#~ msgstr "" -#~ "自适应剪裁所需的附加功能在 :code:`DPFedAvgAdaptive` 中提供,其是 :code:" -#~ "`DPFedAvgFixed` 的子类。它重写了上述方法,以实现以下功能。" +#~ msgid "Our Flower clients will use a simple :code:`Sequential` model:" +#~ msgstr "我们的 Flower 客户端将使用简单的 :code:`Sequential` 模型:" #~ msgid "" -#~ ":code:`configure_fit()` : It intercepts the config dict returned by :code:" -#~ "`super.configure_fit()` to add the key-value pair :code:" -#~ "`dpfedavg_adaptive_clip_enabled:True` to it, which the client interprets " -#~ "as an instruction to include an indicator bit (1 if update norm <= " -#~ "clipping threshold, 0 otherwise) in the results returned by it." +#~ "After loading the dataset with " +#~ ":code:`load_data()` we perform one forward " +#~ "propagation to initialize the model and" +#~ " model parameters with :code:`model(init)`. " +#~ "Next, we implement a Flower client." #~ msgstr "" -#~ ":code:`configure_fit()`:它截取由 :code:`super.configure_fit()` 返回的 " -#~ "config 字典,并在其中添加键-值对 :code:`dpfedavg_adaptive_clip_enabled:" -#~ "True\",客户端将其解释为在返回结果中包含一个指示位(如果参数更新范式 <= 剪" -#~ "裁阈值,则为 1,否则为 0)的指令。" +#~ "使用 :code:`load_data()` 加载数据集后,我们会执行一次前向传播,使用 " +#~ ":code:`model(init)` 初始化模型和模型参数。接下来,我们实现一个 Flower " +#~ "客户端。" #~ msgid "" -#~ ":code:`aggregate_fit()` : It follows a call to :code:`super." -#~ "aggregate_fit()` with one to :code:`__update_clip_norm__()`, a procedure " -#~ "which adjusts the clipping threshold on the basis of the indicator bits " -#~ "received from the sampled clients." +#~ "Flower provides a convenience class " +#~ "called :code:`NumPyClient` which makes it " +#~ "easier to implement the :code:`Client` " +#~ "interface when your workload uses MXNet." +#~ " Implementing :code:`NumPyClient` usually means" +#~ " defining the following methods " +#~ "(:code:`set_parameters` is optional though):" #~ msgstr "" -#~ ":code:`aggregate_fit()`:在调用:code:`super.aggregate_fit()`后,再调用:" -#~ "code:`__update_clip_norm__()`,该过程根据从采样客户端接收到的指示位调整裁" -#~ "剪阈值。" +#~ "Flower 提供了一个名为 :code:`NumPyClient` 的便捷类,当您的工作负载使用" +#~ " MXNet 时,它可以让您更轻松地实现 :code:`Client` 接口。实现 " +#~ ":code:`NumPyClient` 通常意味着定义以下方法(:code:`set_parameters` " +#~ "是可选的):" -#~ msgid "" -#~ "The client-side capabilities required can be completely captured through " -#~ "wrapper logic for just the :code:`fit()` method of the :code:" -#~ "`NumPyClient` abstract class. To be precise, we need to *post-process* " -#~ "the update computed by the wrapped client to clip it, if necessary, to " -#~ "the threshold value supplied by the server as part of the config " -#~ "dictionary. In addition to this, it may need to perform some extra work " -#~ "if either (or both) of the following keys are also present in the dict." -#~ msgstr "" -#~ "客户端所需的功能完全可以通过 :code:`NumPyClient` 抽象类的 :code:`fit()` 方" -#~ "法的封装逻辑来实现。准确地说,我们需要对封装客户端计算的参数更新进行处理," -#~ "以便在必要时将其剪切到服务器作为配置字典的一部分提供的阈值。除此之外,如果" -#~ "配置字典中还存在以下任一(或两个)键,客户端可能还需要执行一些额外的工作。" +#~ msgid "They can be implemented in the following way:" +#~ msgstr "它们可以通过以下方式实现:" #~ msgid "" -#~ ":code:`dpfedavg_noise_stddev` : Generate and add the specified amount of " -#~ "noise to the clipped update." -#~ msgstr "" -#~ "code:`dpfedavg_noise_stddev`:生成并在剪切参数更新中添加指定数量的噪声。" +#~ "We can now create an instance of" +#~ " our class :code:`MNISTClient` and add " +#~ "one line to actually run this " +#~ "client:" +#~ msgstr "现在我们可以创建一个 :code:`MNISTClient` 类的实例,并添加一行来实际运行该客户端:" #~ msgid "" -#~ ":code:`dpfedavg_adaptive_clip_enabled` : Augment the metrics dict in the :" -#~ "code:`FitRes` object being returned to the server with an indicator bit, " -#~ "calculated as described earlier." +#~ "That's it for the client. We only" +#~ " have to implement :code:`Client` or " +#~ ":code:`NumPyClient` and call " +#~ ":code:`fl.client.start_client()` or " +#~ ":code:`fl.client.start_numpy_client()`. The string " +#~ ":code:`\"0.0.0.0:8080\"` tells the client " +#~ "which server to connect to. In our" +#~ " case we can run the server and" +#~ " the client on the same machine, " +#~ "therefore we use :code:`\"0.0.0.0:8080\"`. If" +#~ " we run a truly federated workload" +#~ " with the server and clients running" +#~ " on different machines, all that " +#~ "needs to change is the " +#~ ":code:`server_address` we pass to the " +#~ "client." #~ msgstr "" -#~ ":code:`dpfedavg_adaptive_clip_enabled`:在返回给服务器的 :code:`FitRes` 对" -#~ "象中的度量值字典中增加一个指标位,计算方法如前所述。" +#~ "这就是客户端。我们只需实现 :code:`Client` 或 :code:`NumPyClient`" +#~ " 并调用 :code:`fl.client.start_client()` 或 " +#~ ":code:`fl.client.start_numpy_client()`。字符串 " +#~ ":code:`\"0.0.0.0:8080\"`会告诉客户端要连接的服务器。在本例中,我们可以在同一台机器上运行服务器和客户端,因此我们使用" +#~ " " +#~ ":code:`\"0.0.0.0:8080\"`。如果我们运行的是真正的联邦工作负载,服务器和客户端运行在不同的机器上,那么需要改变的只是传递给客户端的" +#~ " :code:`server_address`。" -#~ msgid "Performing the :math:`(\\epsilon, \\delta)` analysis" -#~ msgstr "进行 :math:`(epsilon, \\delta)` 分析" +#~ msgid "" +#~ "With both client and server ready, " +#~ "we can now run everything and see" +#~ " federated learning in action. Federated" +#~ " learning systems usually have a " +#~ "server and multiple clients. We " +#~ "therefore have to start the server " +#~ "first:" +#~ msgstr "客户端和服务器都准备就绪后,我们现在就可以运行一切,看看联邦学习的运行情况。联邦学习系统通常有一个服务器和多个客户端。因此,我们必须先启动服务器:" #~ msgid "" -#~ "Assume you have trained for :math:`n` rounds with sampling fraction :math:" -#~ "`q` and noise multiplier :math:`z`. In order to calculate the :math:" -#~ "`\\epsilon` value this would result in for a particular :math:`\\delta`, " -#~ "the following script may be used." +#~ "Congratulations! You've successfully built and" +#~ " run your first federated learning " +#~ "system. The full `source code " +#~ "`_ for this example can " +#~ "be found in :code:`examples/quickstart-mxnet`." #~ msgstr "" -#~ "假设您已经训练了 :math:`n` 轮,采样比例为 :math:`q`,噪声乘数为 :math:" -#~ "`z`。为了计算特定 :math:`\\delta` 的 :math:`epsilon` 值,可以使用下面的脚" -#~ "本。" - -#~ msgid "Flower driver SDK." -#~ msgstr "Flower 服务器。" +#~ "恭喜您!您已经成功构建并运行了第一个联邦学习系统。本示例的`完整源代码 " +#~ "`_ 可在 :code:`examples/quickstart-" +#~ "mxnet` 中找到。" -#~ msgid "driver" -#~ msgstr "服务器" - -#~ msgid "Get task results." -#~ msgstr "汇总训练结果。" +#~ msgid ":code:`load_mnist()`" +#~ msgstr ":code:`load_mnist()`" -#~ msgid "Request for run ID." -#~ msgstr "Flower 基线申请" +#~ msgid "Loads the MNIST dataset using OpenML" +#~ msgstr "使用 OpenML 加载 MNIST 数据集" -#~ msgid "Get client IDs." -#~ msgstr "返回客户端(本身)。" +#~ msgid ":code:`shuffle()`" +#~ msgstr ":code:`shuffle()`" -#~ msgid "" -#~ "Flower usage examples used to be bundled with Flower in a package called " -#~ "``flwr_example``. We are migrating those examples to standalone projects " -#~ "to make them easier to use. All new examples are based in the directory " -#~ "`examples `_." -#~ msgstr "" -#~ "Flower 的使用示例曾与 Flower 捆绑在一个名为 ``flwr_example`` 的软件包中。" -#~ "我们正在将这些示例迁移到独立项目中,以使它们更易于使用。所有新示例都位于目" -#~ "录 `examples `_。" +#~ msgid "Shuffles data and its label" +#~ msgstr "对数据及其标签进行洗牌" -#~ msgid "Quickstart TensorFlow/Keras" -#~ msgstr "快速入门 TensorFlow/Keras" +#~ msgid ":code:`partition()`" +#~ msgstr ":code:`partition()`" -#~ msgid "Legacy Examples (`flwr_example`)" -#~ msgstr "传统示例 (`flwr_example`)" +#~ msgid "Splits datasets into a number of partitions" +#~ msgstr "将数据集分割成多个分区" #~ msgid "" -#~ "The useage examples in `flwr_example` are deprecated and will be removed " -#~ "in the future. New examples are provided as standalone projects in " -#~ "`examples `_." +#~ "We load the MNIST dataset from " +#~ "`OpenML " +#~ "`_, a" +#~ " popular image classification dataset of" +#~ " handwritten digits for machine learning." +#~ " The utility :code:`utils.load_mnist()` downloads" +#~ " the training and test data. The " +#~ "training set is split afterwards into" +#~ " 10 partitions with :code:`utils.partition()`." #~ msgstr "" -#~ "在 `flwr_example` 中的使用示例已被弃用,今后将被移除。新示例将作为独立项目" -#~ "在 `examples `_ 中提" -#~ "供。" +#~ "我们从 `OpenML `_ 中加载 " +#~ "MNIST 数据集,这是一个用于机器学习的流行手写数字图像分类数据集。实用程序 " +#~ ":code:`utils.load_mnist()` 下载训练和测试数据。然后使用 " +#~ ":code:`utils.partition()`将训练集分割成 10 个分区。" -#~ msgid "Extra Dependencies" -#~ msgstr "额外依赖" +#~ msgid "Let's get stated!" +#~ msgstr "让我们开始吧!" -#~ msgid "" -#~ "The core Flower framework keeps a minimal set of dependencies. The " -#~ "examples demonstrate Flower in the context of different machine learning " -#~ "frameworks, so additional dependencies need to be installed before an " -#~ "example can be run." +#~ msgid "|2b5c62c529f6416f840c594cce062fbb|" #~ msgstr "" -#~ "Flower 核心框架只保留了最低限度的依赖项。这些示例在不同机器学习框架的背景" -#~ "下演示了 Flower,因此在运行示例之前需要安装额外的依赖项。" -#~ msgid "For PyTorch examples::" -#~ msgstr "PyTorch 示例::" - -#~ msgid "For TensorFlow examples::" -#~ msgstr "TensorFlow 示例::" - -#~ msgid "For both PyTorch and TensorFlow examples::" -#~ msgstr "PyTorch 和 TensorFlow 示例::" - -#~ msgid "" -#~ "Please consult :code:`pyproject.toml` for a full list of possible extras " -#~ "(section :code:`[tool.poetry.extras]`)." +#~ msgid "|90b334680cb7467d9a04d39b8e8dca9f|" #~ msgstr "" -#~ "请参阅 :code:`pyproject.toml`,了解可能的 extras 的完整列表(章节 :code:" -#~ "`[tool.poems.extras]`)。" - -#~ msgid "PyTorch Examples" -#~ msgstr "PyTorch 示例" -#~ msgid "" -#~ "Our PyTorch examples are based on PyTorch 1.7. They should work with " -#~ "other releases as well. So far, we provide the following examples." +#~ msgid "|65764ceee89f4335bfd93fd0b115e831|" #~ msgstr "" -#~ "我们的 PyTorch 示例基于 PyTorch 1.7。它们应该也能在其他版本中使用。到目前" -#~ "为止,我们提供了以下示例。" - -#~ msgid "CIFAR-10 Image Classification" -#~ msgstr "CIFAR-10 图像分类" -#~ msgid "" -#~ "`CIFAR-10 and CIFAR-100 `_ " -#~ "are popular RGB image datasets. The Flower CIFAR-10 example uses PyTorch " -#~ "to train a simple CNN classifier in a federated learning setup with two " -#~ "clients." +#~ msgid "|d97319ec28bb407ea0ab9705e38f3bcf|" #~ msgstr "" -#~ "CIFAR-10 和 CIFAR-100 ``_ 是" -#~ "流行的 RGB 图像数据集。Flower CIFAR-10 示例使用 PyTorch 在有两个客户端的联" -#~ "邦学习设置中训练一个简单的 CNN 分类器。" - -#~ msgid "First, start a Flower server:" -#~ msgstr "首先,启动 Flower 服务器:" - -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-server.sh" - -#~ msgid "Then, start the two clients in a new terminal window:" -#~ msgstr "然后,在新的终端窗口中启动两个客户端:" - -#~ msgid "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_cifar/run-clients.sh" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_cifar`." -#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/pytorch_cifar`。" - -#~ msgid "ImageNet-2012 Image Classification" -#~ msgstr "ImageNet-2012 图像分类" - -#~ msgid "" -#~ "`ImageNet-2012 `_ is one of the major computer " -#~ "vision datasets. The Flower ImageNet example uses PyTorch to train a " -#~ "ResNet-18 classifier in a federated learning setup with ten clients." +#~ msgid "|11e95ac83a8548d8b3505b4663187d07|" #~ msgstr "" -#~ "ImageNet-2012 `_ 是主要的计算机视觉数据集之一。" -#~ "Flower ImageNet 示例使用 PyTorch 在有十个客户端的联邦学习设置中训练 " -#~ "ResNet-18 分类器。" - -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-server.sh" -#~ msgid "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/pytorch_imagenet/run-clients.sh" +#~ msgid "|1dab2f3a23674abc8a6731f20fa10730|" +#~ msgstr "" -#~ msgid "For more details, see :code:`src/py/flwr_example/pytorch_imagenet`." -#~ msgstr "更多详情,请参阅 :code:`src/py/flwr_example/pytorch_imagenet`。" +#~ msgid "|7f0ee162da38450788493a21627306f7|" +#~ msgstr "" -#~ msgid "TensorFlow Examples" -#~ msgstr "TensorFlow 示例" +#~ msgid "|296a1fb72c514b23b3d8905ff0ff98c6|" +#~ msgstr "" -#~ msgid "" -#~ "Our TensorFlow examples are based on TensorFlow 2.0 or newer. So far, we " -#~ "provide the following examples." +#~ msgid "|5b1408eec0d746cdb91162a9107b6089|" #~ msgstr "" -#~ "我们的 TensorFlow 示例基于 TensorFlow 2.0 或更新版本。到目前为止,我们提供" -#~ "了以下示例。" -#~ msgid "Fashion-MNIST Image Classification" -#~ msgstr "Fashion-MNIST 图像分类" +#~ msgid "|aef19f4b122c4e8d9f4c57f99bcd5dd2|" +#~ msgstr "" -#~ msgid "" -#~ "`Fashion-MNIST `_ is " -#~ "often used as the \"Hello, world!\" of machine learning. We follow this " -#~ "tradition and provide an example which samples random local datasets from " -#~ "Fashion-MNIST and trains a simple image classification model over those " -#~ "partitions." +#~ msgid "|2881a86d8fc54ba29d96b29fc2819f4a|" #~ msgstr "" -#~ "`Fashion-MNIST `_ 经常被" -#~ "用作机器学习的 \"你好,世界!\"。我们遵循这一传统,提供了一个从Fashion-" -#~ "MNIST 中随机抽样本地数据集的示例,并在这些分区上训练一个简单的图像分类模" -#~ "型。" -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" -#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-server.sh" +#~ msgid "|ec1fe880237247e0975f52766775ab84|" +#~ msgstr "" -#~ msgid "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" -#~ msgstr "$ ./src/py/flwr_example/tensorflow_fashion_mnist/run-clients.sh" +#~ msgid "|9fdf048ed58d4467b2718cdf4aaf1ec3|" +#~ msgstr "" -#~ msgid "" -#~ "For more details, see :code:`src/py/flwr_example/" -#~ "tensorflow_fashion_mnist`." +#~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" -#~ "更多详情,请参阅 :code:`src/py/flwr_example/tensorflow_fashion_mnist`。" + diff --git a/doc/locales/zh_Hans/LC_MESSAGES/sphinx.po b/doc/locales/zh_Hans/LC_MESSAGES/sphinx.po index 98f300b872e3..6c786f9ed8ac 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/sphinx.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/sphinx.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-11-23 18:31+0100\n" +"POT-Creation-Date: 2024-05-28 11:47+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language: zh_Hans\n" @@ -17,7 +17,7 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Generated-By: Babel 2.13.1\n" +"Generated-By: Babel 2.15.0\n" #: ../../source/_templates/base.html:18 msgid "About these documents" @@ -28,6 +28,7 @@ msgid "Index" msgstr "" #: ../../source/_templates/base.html:24 +#: ../../source/_templates/sidebar/search.html:2 msgid "Search" msgstr "" @@ -35,3 +36,7 @@ msgstr "" msgid "Copyright" msgstr "" +#: ../../source/_templates/sidebar/search.html:2 +msgid "Type / to search" +msgstr "" + From d402a56a39a29eb90449f040dff21e306c8ad063 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Tue, 28 May 2024 16:12:30 +0200 Subject: [PATCH 026/124] docs(datasets) Update Pytorch how-to for `divide_dataset` (#3060) --- datasets/doc/source/how-to-use-with-pytorch.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/datasets/doc/source/how-to-use-with-pytorch.rst b/datasets/doc/source/how-to-use-with-pytorch.rst index 4228ead2a281..4e00194e6155 100644 --- a/datasets/doc/source/how-to-use-with-pytorch.rst +++ b/datasets/doc/source/how-to-use-with-pytorch.rst @@ -67,13 +67,20 @@ If you want to divide the dataset, you can use (at any point before passing the partition_train = partition_train_test["train"] partition_test = partition_train_test["test"] +If you want to keep the order of samples intact and need a division into 2 or more subsets, you can use:: + + from flwr_datasets.utils import divide_dataset + train, valid, test = divide_dataset(partition, [0.6, 0.2, 0.2]) + Or you can simply calculate the indices yourself:: partition_len = len(partition) # Split `partition` 80:20 num_train_examples = int(0.8 * partition_len) - partition_train = partition.select(range(num_train_examples)) ) # use first 80% - partition_test = partition.select(range(num_train_examples, partition_len)) ) # use last 20% + # use first 80% + partition_train = partition.select(range(num_train_examples)) ) + # use last 20% + partition_test = partition.select(range(num_train_examples, partition_len)) ) And during the training loop, you need to apply one change. With a typical dataloader, you get a list returned for each iteration:: From 4d6cc1bf5eb241038c1e711ee28912a0637f9fa4 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Tue, 28 May 2024 15:45:41 +0100 Subject: [PATCH 027/124] ci(*:skip) Fix cache cleanup (#3521) --- .github/workflows/cache-cleanup.yml | 63 +++++++++++++++++++++++++++++ .github/workflows/e2e.yml | 15 ++++--- 2 files changed, 73 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/cache-cleanup.yml diff --git a/.github/workflows/cache-cleanup.yml b/.github/workflows/cache-cleanup.yml new file mode 100644 index 000000000000..aa2da65d0a47 --- /dev/null +++ b/.github/workflows/cache-cleanup.yml @@ -0,0 +1,63 @@ +name: Cache cleanup + +on: + workflow_dispatch + +jobs: + e2e-cleanup: + runs-on: ubuntu-22.04 + timeout-minutes: 10 + # Using approach described here: + # https://docs.github.com/en/actions/using-jobs/using-a-matrix-for-your-jobs + strategy: + matrix: + include: + - directory: bare + - directory: bare-https + - directory: bare-client-auth + - directory: jax + - directory: pytorch + - directory: tensorflow + - directory: tabnet + - directory: opacus + - directory: pytorch-lightning + - directory: scikit-learn + - directory: fastai + - directory: pandas + + name: Framework / ${{ matrix.directory }} + + steps: + - name: Check out code + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.8 + + - name: Cleanup caches by directories + # Only keep caches that match the latest keys for each directory + run: | + gh extension install actions/gh-actions-cache + + REPO=${{ github.repository }} + LATEST_KEY=pythonloc-${{ matrix.directory }}-${{ env.pythonLocation }}-${{ hashFiles(format('./e2e/{0}/pyproject.toml', matrix.directory)) }} + + echo "Fetching list of cache keys" + cacheKeys=$(gh actions-cache list -R $REPO | grep "${{ matrix.directory }}" | cut -f 1 ) + + ## Setting this to not fail the workflow while deleting cache keys. + set +e + echo "Deleting caches..." + for cacheKey in $cacheKeys + do + if [ "$cacheKey" != "$LATEST_KEY" ]; then + echo -e "\tOld key found -> $cacheKey" + gh actions-cache delete "$cacheKey" --confirm + fi + done + + echo "Done" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 18ca4e46d593..d66362de9d32 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -129,13 +129,11 @@ jobs: # Using approach described here for Python location caching: # https://blog.allenai.org/python-caching-in-github-actions-e9452698e98d - name: Cache Python location - id: cache-python - uses: actions/cache@v4 + id: cache-restore-python + uses: actions/cache/restore@v4 with: path: ${{ env.pythonLocation }} - key: pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }}-${{ hashFiles('**/pyproject.toml') }} - restore-keys: | - pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }} + key: pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }}-${{ hashFiles(format('./e2e/{0}/pyproject.toml', matrix.directory)) }} - name: Install dependencies run: python -m pip install --upgrade . - name: Install Flower wheel from artifact store @@ -166,6 +164,13 @@ jobs: - name: Run driver test with client authentication if: ${{ matrix.directory == 'bare-client-auth' }} run: ./../test_driver.sh bare client-auth + - name: Cache save Python location + id: cache-save-python + uses: actions/cache/save@v4 + if: ${{ github.ref_name == 'main' && !steps.cache-restore-python.outputs.cache-hit }} + with: + path: ${{ env.pythonLocation }} + key: pythonloc-${{ runner.os }}-${{ matrix.directory }}-${{ env.pythonLocation }}-${{ hashFiles(format('./e2e/{0}/pyproject.toml', matrix.directory)) }} strategies: runs-on: ubuntu-22.04 From 737178997054a0cb7e8dc2baa9da58fae690bbbd Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Tue, 28 May 2024 18:18:10 +0200 Subject: [PATCH 028/124] refactor(framework) Update CLI SSL flags (#3512) --- doc/source/how-to-authenticate-supernodes.rst | 4 +- doc/source/how-to-enable-ssl-connections.rst | 5 +- doc/source/how-to-run-flower-using-docker.rst | 17 ++- doc/source/how-to-upgrade-to-flower-next.rst | 12 +- e2e/test_driver.sh | 4 +- examples/flower-authentication/README.md | 4 +- examples/flower-authentication/generate.sh | 0 src/py/flwr/server/app.py | 142 +++++++++--------- 8 files changed, 98 insertions(+), 90 deletions(-) mode change 100644 => 100755 examples/flower-authentication/generate.sh diff --git a/doc/source/how-to-authenticate-supernodes.rst b/doc/source/how-to-authenticate-supernodes.rst index e0834a1aff0a..9eb5e010ea4b 100644 --- a/doc/source/how-to-authenticate-supernodes.rst +++ b/doc/source/how-to-authenticate-supernodes.rst @@ -28,7 +28,9 @@ Use the following terminal command to start a Flower :code:`SuperNode` that has .. code-block:: bash flower-superlink - --certificates certificates/ca.crt certificates/server.pem certificates/server.key + --ssl-ca-certfile certificates/ca.crt + --ssl-certfile certificates/server.pem + --ssl-keyfile certificates/server.key --auth-list-public-keys keys/client_public_keys.csv --auth-superlink-private-key keys/server_credentials --auth-superlink-public-key keys/server_credentials.pub diff --git a/doc/source/how-to-enable-ssl-connections.rst b/doc/source/how-to-enable-ssl-connections.rst index 5c762fe1169a..870f4b0f64c9 100644 --- a/doc/source/how-to-enable-ssl-connections.rst +++ b/doc/source/how-to-enable-ssl-connections.rst @@ -42,7 +42,10 @@ Use the following terminal command to start a sever (SuperLink) that uses the pr .. code-block:: bash - flower-superlink --certificates certificates/ca.crt certificates/server.pem certificates/server.key + flower-superlink + --ssl-ca-certfile certificates/ca.crt + --ssl-certfile certificates/server.pem + --ssl-keyfile certificates/server.key When providing certificates, the server expects a tuple of three certificates paths: CA certificate, server certificate and server private key. diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index 5812066f59de..09bd952daafc 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -102,13 +102,15 @@ PEM-encoded certificate chain. Assuming all files we need are in the local ``certificates`` directory, we can use the flag ``--volume`` to mount the local directory into the ``/app/`` directory of the container. This allows the SuperLink to access the files within the container. Finally, we pass the names of the -certificates to the SuperLink with the ``--certificates`` flag. +certificates to the SuperLink with the ``--root-certificates`` flag. .. code-block:: bash $ docker run --rm \ - -p 9091:9091 -p 9092:9092 --volume ./certificates/:/app/ flwr/superlink:1.8.0 \ - --certificates ca.crt server.pem server.key + -p 9091:9091 -p 9092:9092 --volume ./certificates/:/app/ flwr/superlink:1.9.0 \ + --ssl-ca-certfile ca.crt \ + --ssl-certfile server.pem \ + --ssl-keyfile server.key Flower SuperNode ---------------- @@ -264,13 +266,13 @@ To enable SSL, we will need to mount a PEM-encoded root certificate into your Su Assuming the certificate already exists locally, we can use the flag ``--volume`` to mount the local certificate into the container's ``/app/`` directory. This allows the SuperNode to access the -certificate within the container. Use the ``--certificates`` flag when starting the container. +certificate within the container. Use the ``--root-certificates`` flag when starting the container. .. code-block:: bash $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 \ --server 192.168.1.100:9092 \ - --certificates ca.crt + --root-certificates ca.crt Flower ServerApp ---------------- @@ -379,13 +381,14 @@ To enable SSL, we will need to mount a PEM-encoded root certificate into your Se Assuming the certificate already exists locally, we can use the flag ``--volume`` to mount the local certificate into the container's ``/app/`` directory. This allows the ServerApp to access the -certificate within the container. Use the ``--certificates`` flag when starting the container. +certificate within the container. Use the ``--ssl-ca-certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` +flags when starting the container. .. code-block:: bash $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 \ --server 192.168.1.100:9091 \ - --certificates ca.crt + --root-certificates ca.crt Advanced Docker options ----------------------- diff --git a/doc/source/how-to-upgrade-to-flower-next.rst b/doc/source/how-to-upgrade-to-flower-next.rst index 44fad51546b6..eebe894f56ec 100644 --- a/doc/source/how-to-upgrade-to-flower-next.rst +++ b/doc/source/how-to-upgrade-to-flower-next.rst @@ -171,16 +171,16 @@ Deployment # In yet another terminal window, run the ServerApp (this starts the actual training run) $ flower-server-app server:app --insecure -- Here's another example to start with HTTPS. Use the ``--certificates`` command line - argument to pass paths to (CA certificate, server certificate, and server private key). +- Here's another example to start with HTTPS. Use the ``--ssl-ca-certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line + options to pass paths to (CA certificate, server certificate, and server private key). .. code-block:: bash # Start a secure Superlink - $ flower-superlink --certificates \ - \ - \ - + $ flower-superlink \ + --ssl-ca-certfile \ + --ssl-certfile \ + --ssl-keyfile # In a new terminal window, start a long-running secure SuperNode $ flower-client-app client:app \ diff --git a/e2e/test_driver.sh b/e2e/test_driver.sh index 7a312004990d..7a50764ab0ca 100755 --- a/e2e/test_driver.sh +++ b/e2e/test_driver.sh @@ -9,7 +9,7 @@ case "$1" in ;; bare-https) ./generate.sh - server_arg="--certificates certificates/ca.crt certificates/server.pem certificates/server.key" + server_arg="--ssl-ca-certfile certificates/ca.crt --ssl-certfile certificates/server.pem --ssl-keyfile certificates/server.key" client_arg="--root-certificates certificates/ca.crt" server_dir="./" ;; @@ -45,7 +45,7 @@ case "$2" in server_address="127.0.0.1:9092" server_app_address="127.0.0.1:9091" db_arg="--database :flwr-in-memory-state:" - server_arg="--certificates certificates/ca.crt certificates/server.pem certificates/server.key" + server_arg="--ssl-ca-certfile certificates/ca.crt --ssl-certfile certificates/server.pem --ssl-keyfile certificates/server.key" client_arg="--root-certificates certificates/ca.crt" server_auth="--auth-list-public-keys keys/client_public_keys.csv --auth-superlink-private-key keys/server_credentials --auth-superlink-public-key keys/server_credentials.pub" client_auth_1="--auth-supernode-private-key keys/client_credentials_1 --auth-supernode-public-key keys/client_credentials_1.pub" diff --git a/examples/flower-authentication/README.md b/examples/flower-authentication/README.md index e2403be7608d..589270e621c9 100644 --- a/examples/flower-authentication/README.md +++ b/examples/flower-authentication/README.md @@ -68,7 +68,9 @@ containing file path to the SuperLink's private key `server_credentials`, and `- ```bash flower-superlink \ - --certificates certificates/ca.crt certificates/server.pem certificates/server.key \ + --ssl-ca-certfile certificates/ca.crt \ + --ssl-certfile certificates/server.pem \ + --ssl-keyfile certificates/server.key \ --auth-list-public-keys keys/client_public_keys.csv \ --auth-superlink-private-key keys/server_credentials \ --auth-superlink-public-key keys/server_credentials.pub diff --git a/examples/flower-authentication/generate.sh b/examples/flower-authentication/generate.sh old mode 100644 new mode 100755 diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 8049a864fd5d..147ec5fb0f65 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -19,10 +19,10 @@ import importlib.util import sys import threading -from logging import ERROR, INFO, WARN +from logging import INFO, WARN from os.path import isfile from pathlib import Path -from typing import List, Optional, Sequence, Set, Tuple +from typing import Optional, Sequence, Set, Tuple import grpc from cryptography.exceptions import UnsupportedAlgorithm @@ -346,6 +346,9 @@ def run_superlink() -> None: sys.exit(MISSING_EXTRA_REST) address_arg = args.rest_fleet_api_address parsed_address = parse_address(address_arg) + _, ssl_certfile, ssl_keyfile = ( + certificates if certificates is not None else (None, None, None) + ) if not parsed_address: sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") host, port, _ = parsed_address @@ -354,8 +357,8 @@ def run_superlink() -> None: args=( host, port, - args.ssl_keyfile, - args.ssl_certfile, + ssl_keyfile, + ssl_certfile, state_factory, args.rest_fleet_api_workers, ), @@ -442,8 +445,8 @@ def _try_setup_client_authentication( if certificates is None: sys.exit( "Authentication requires secure connections. " - "Please provide certificate paths using '--certificates' and " - "try again." + "Please provide certificate paths to `--ssl-certfile`, " + "`--ssl-keyfile`, and `—-ssl-ca-certfile` and try again." ) client_keys_file_path = Path(args.auth_list_public_keys) @@ -512,21 +515,52 @@ def _try_obtain_certificates( # Obtain certificates if args.insecure: log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.") - certificates = None + return None # Check if certificates are provided - elif args.certificates: - certificates = ( - Path(args.certificates[0]).read_bytes(), # CA certificate - Path(args.certificates[1]).read_bytes(), # server certificate - Path(args.certificates[2]).read_bytes(), # server private key - ) - else: - sys.exit( - "Certificates are required unless running in insecure mode. " - "Please provide certificate paths with '--certificates' or run the server " - "in insecure mode using '--insecure' if you understand the risks." - ) - return certificates + if args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE: + if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile: + if not isfile(args.ssl_ca_certfile): + sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.") + if not isfile(args.ssl_certfile): + sys.exit("Path argument `--ssl-certfile` does not point to a file.") + if not isfile(args.ssl_keyfile): + sys.exit("Path argument `--ssl-keyfile` does not point to a file.") + certificates = ( + Path(args.ssl_ca_certfile).read_bytes(), # CA certificate + Path(args.ssl_certfile).read_bytes(), # server certificate + Path(args.ssl_keyfile).read_bytes(), # server private key + ) + return certificates + if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile: + sys.exit( + "You need to provide valid file paths to `--ssl-certfile`, " + "`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure " + "connection in Fleet API server (gRPC-rere)." + ) + if args.fleet_api_type == TRANSPORT_TYPE_REST: + if args.ssl_certfile and args.ssl_keyfile: + if not isfile(args.ssl_certfile): + sys.exit("Path argument `--ssl-certfile` does not point to a file.") + if not isfile(args.ssl_keyfile): + sys.exit("Path argument `--ssl-keyfile` does not point to a file.") + certificates = ( + b"", + Path(args.ssl_certfile).read_bytes(), # server certificate + Path(args.ssl_keyfile).read_bytes(), # server private key + ) + return certificates + if args.ssl_certfile or args.ssl_keyfile: + sys.exit( + "You need to provide valid file paths to `--ssl-certfile` " + "and `--ssl-keyfile` to create a secure connection " + "in Fleet API server (REST, experimental)." + ) + sys.exit( + "Certificates are required unless running in insecure mode. " + "Please provide certificate paths to `--ssl-certfile`, " + "`--ssl-keyfile`, and `—-ssl-ca-certfile` or run the server " + "in insecure mode using '--insecure' if you understand the risks." + ) def _run_fleet_api_grpc_rere( @@ -582,14 +616,6 @@ def _run_fleet_api_rest( # See: https://www.starlette.io/applications/#accessing-the-app-instance fast_api_app.state.STATE_FACTORY = state_factory - validation_exceptions = _validate_ssl_files( - ssl_certfile=ssl_certfile, ssl_keyfile=ssl_keyfile - ) - if any(validation_exceptions): - # Starting with 3.11 we can use ExceptionGroup but for now - # this seems to be the reasonable approach. - raise ValueError(validation_exceptions) - uvicorn.run( app="flwr.server.superlink.fleet.rest_rere.rest_api:app", port=port, @@ -602,32 +628,6 @@ def _run_fleet_api_rest( ) -def _validate_ssl_files( - ssl_keyfile: Optional[str], ssl_certfile: Optional[str] -) -> List[ValueError]: - validation_exceptions = [] - - if ssl_keyfile is not None and not isfile(ssl_keyfile): - msg = "Path argument `--ssl-keyfile` does not point to a file." - log(ERROR, msg) - validation_exceptions.append(ValueError(msg)) - - if ssl_certfile is not None and not isfile(ssl_certfile): - msg = "Path argument `--ssl-certfile` does not point to a file." - log(ERROR, msg) - validation_exceptions.append(ValueError(msg)) - - if not bool(ssl_keyfile) == bool(ssl_certfile): - msg = ( - "When setting one of `--ssl-keyfile` and " - "`--ssl-certfile`, both have to be used." - ) - log(ERROR, msg) - validation_exceptions.append(ValueError(msg)) - - return validation_exceptions - - def _parse_args_run_driver_api() -> argparse.ArgumentParser: """Parse command line arguments for Driver API.""" parser = argparse.ArgumentParser( @@ -684,13 +684,23 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None: "Use this flag only if you understand the risks.", ) parser.add_argument( - "--certificates", - nargs=3, - metavar=("CA_CERT", "SERVER_CERT", "PRIVATE_KEY"), + "--ssl-certfile", + help="Fleet API server SSL certificate file (as a path str) " + "to create a secure connection.", + type=str, + default=None, + ) + parser.add_argument( + "--ssl-keyfile", + help="Fleet API server SSL private key file (as a path str) " + "to create a secure connection.", + type=str, + ) + parser.add_argument( + "--ssl-ca-certfile", + help="Fleet API server SSL CA certificate file (as a path str) " + "to create a secure connection.", type=str, - help="Paths to the CA certificate, server certificate, and server private " - "key, in that order. Note: The server can only be started without " - "certificates by enabling the `--insecure` flag.", ) parser.add_argument( "--database", @@ -763,18 +773,6 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: help="Fleet API (REST) server address (IPv4, IPv6, or a domain name)", default=ADDRESS_FLEET_API_REST, ) - rest_group.add_argument( - "--ssl-certfile", - help="Fleet API (REST) server SSL certificate file (as a path str), " - "needed for using 'https'.", - default=None, - ) - rest_group.add_argument( - "--ssl-keyfile", - help="Fleet API (REST) server SSL private key file (as a path str), " - "needed for using 'https'.", - default=None, - ) rest_group.add_argument( "--rest-fleet-api-workers", help="Set the number of concurrent workers for the Fleet API REST server.", From 03c9f797023258148739adbc58852e458b2ecd5e Mon Sep 17 00:00:00 2001 From: mohammadnaseri Date: Tue, 28 May 2024 22:56:42 +0100 Subject: [PATCH 029/124] fix(examples) Fix TensorFlow-Privacy example (#3488) Co-authored-by: Taner Topal Co-authored-by: jafermarq --- README.md | 1 + examples/dp-sgd-mnist/README.md | 105 ------------- examples/dp-sgd-mnist/client.py | 162 --------------------- examples/dp-sgd-mnist/common.py | 103 ------------- examples/dp-sgd-mnist/pyproject.toml | 20 --- examples/dp-sgd-mnist/requirements.txt | 4 - examples/dp-sgd-mnist/server.py | 56 ------- examples/tensorflow-privacy/README.md | 60 ++++++++ examples/tensorflow-privacy/client.py | 139 ++++++++++++++++++ examples/tensorflow-privacy/pyproject.toml | 22 +++ examples/tensorflow-privacy/server.py | 22 +++ 11 files changed, 244 insertions(+), 450 deletions(-) delete mode 100644 examples/dp-sgd-mnist/README.md delete mode 100644 examples/dp-sgd-mnist/client.py delete mode 100644 examples/dp-sgd-mnist/common.py delete mode 100644 examples/dp-sgd-mnist/pyproject.toml delete mode 100644 examples/dp-sgd-mnist/requirements.txt delete mode 100644 examples/dp-sgd-mnist/server.py create mode 100644 examples/tensorflow-privacy/README.md create mode 100644 examples/tensorflow-privacy/client.py create mode 100644 examples/tensorflow-privacy/pyproject.toml create mode 100644 examples/tensorflow-privacy/server.py diff --git a/README.md b/README.md index dabeb0a9eba9..a010abfcb2f5 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples): - [Flower through Docker Compose and with Grafana dashboard](https://github.com/adap/flower/tree/main/examples/flower-via-docker-compose) - [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter) - [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus) +- [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy) ## Community diff --git a/examples/dp-sgd-mnist/README.md b/examples/dp-sgd-mnist/README.md deleted file mode 100644 index fcf602306c90..000000000000 --- a/examples/dp-sgd-mnist/README.md +++ /dev/null @@ -1,105 +0,0 @@ -# Flower Example Using Tensorflow/Keras and Tensorflow Privacy - -This example of Flower trains a federeated learning system where clients are free to choose -between non-private and private optimizers. Specifically, clients can choose to train Keras models using the standard SGD optimizer or __Differentially Private__ SGD (DPSGD) from [Tensorflow Privacy](https://github.com/tensorflow/privacy). For this task we use the MNIST dataset which is split artificially among clients. This causes the dataset to be i.i.d. The clients using DPSGD track the amount of privacy spent and display it at the end of the training. - -This example is adapted from https://github.com/tensorflow/privacy/blob/master/tutorials/mnist_dpsgd_tutorial_keras.py - -## Project Setup - -Start by cloning the example project. We prepared a single-line command that you can copy into your shell which will checkout the example for you: - -```shell -git clone --depth=1 https://github.com/adap/flower.git && mv flower/examples/dp-sgd-mnist . && rm -rf flower && cd dp-sgd-mnist -``` - -This will create a new directory called `dp-sgd-mnist` containing the following files: - -```shell --- pyproject.toml --- requirements.txt --- client.py --- server.py --- common.py --- README.md -``` - -### Installing Dependencies - -Project dependencies (such as `tensorflow` and `tensorflow-privacy`) are defined in `pyproject.toml` and `requirements.txt`. We recommend [Poetry](https://python-poetry.org/docs/) to install those dependencies and manage your virtual environment ([Poetry installation](https://python-poetry.org/docs/#installation)) or [pip](https://pip.pypa.io/en/latest/development/), but feel free to use a different way of installing dependencies and managing virtual environments if you have other preferences. - -#### Poetry - -```shell -poetry install -poetry shell -``` - -Poetry will install all your dependencies in a newly created virtual environment. To verify that everything works correctly you can run the following command: - -```shell -poetry run python3 -c "import flwr" -``` - -If you don't see any errors you're good to go! - -#### pip - -Write the command below in your terminal to install the dependencies according to the configuration file requirements.txt. - -```shell -pip install -r requirements.txt -``` - -## Run Federated Learning with TensorFlow/Keras/Tensorflow-Privacy and Flower - -Afterwards you are ready to start the Flower server as well as the clients. You can simply start the server in a terminal as follows: - -```shell -# terminal 1 -poetry run python3 server.py -``` - -Now you are ready to start the Flower clients which will participate in the learning. To do so simply open two more terminals and run the following command in each: - -```shell -# terminal 2 -poetry run python3 client.py --partition 0 -``` - -```shell -# terminal 3 -# We will set the second client to use `dpsgd` -poetry run python3 client.py --partition 1 --dpsgd True -``` - -Alternatively you can run all of it in one shell as follows: - -```shell -poetry run python3 server.py & -poetry run python3 client.py --partition 0 & -poetry run python3 client.py --partition 1 --dpsgd True -``` - -It should be noted that when starting more than 2 clients, the total number of clients you intend to run and the data partition the client is expected to use must be specified. This is because the `num_clients` is used to split the dataset. - -For example, in case of 3 clients - -```shell -poetry run python3 server.py --num-clients 3 & -poetry run python3 client.py --num-clients 3 --partition 0 --dpsgd True & -poetry run python3 client.py --num-clients 3 --partition 1 & -poetry run python3 client.py --num-clients 3 --partition 2 --dpsgd True -``` - -Additional training parameters for the client and server can be referenced by passing `--help` to either script. - -Other things to note is that when all clients are running `dpsgd`, either train for more rounds or increase the local epochs to achieve optimal performance. You shall need to carefully tune the hyperparameters to your specific setup. - -```shell -poetry run python3 server.py --num-clients 3 --num-rounds 20 -``` - -```shell -poetry run python3 client.py --num-clients 3 --partition 1 --local-epochs 4 --dpsgd True -``` diff --git a/examples/dp-sgd-mnist/client.py b/examples/dp-sgd-mnist/client.py deleted file mode 100644 index cffe0e241645..000000000000 --- a/examples/dp-sgd-mnist/client.py +++ /dev/null @@ -1,162 +0,0 @@ -import argparse -import os - -import tensorflow as tf -from tensorflow_privacy.privacy.optimizers.dp_optimizer_keras_vectorized import ( - VectorizedDPKerasSGDOptimizer, -) - -import flwr as fl - -import common - - -# Make TensorFlow logs less verbose -os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" - -# global for tracking privacy -PRIVACY_LOSS = 0 - - -# Define Flower client -class MnistClient(fl.client.NumPyClient): - def __init__(self, model, x_train, y_train, x_test, y_test, args): - self.model = model - self.x_train, self.y_train = x_train, y_train - self.x_test, self.y_test = x_test, y_test - self.batch_size = args.batch_size - self.local_epochs = args.local_epochs - self.dpsgd = args.dpsgd - - if args.dpsgd: - self.noise_multiplier = args.noise_multiplier - if args.batch_size % args.microbatches != 0: - raise ValueError( - "Number of microbatches should divide evenly batch_size" - ) - optimizer = VectorizedDPKerasSGDOptimizer( - l2_norm_clip=args.l2_norm_clip, - noise_multiplier=args.noise_multiplier, - num_microbatches=args.microbatches, - learning_rate=args.learning_rate, - ) - # Compute vector of per-example loss rather than its mean over a minibatch. - loss = tf.keras.losses.CategoricalCrossentropy( - from_logits=True, reduction=tf.losses.Reduction.NONE - ) - else: - optimizer = tf.keras.optimizers.SGD(learning_rate=args.learning_rate) - loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True) - - # Compile model with Keras - model.compile(optimizer=optimizer, loss=loss, metrics=["accuracy"]) - - def get_parameters(self, config): - """Get parameters of the local model.""" - raise Exception("Not implemented (server-side parameter initialization)") - - def fit(self, parameters, config): - """Train parameters on the locally held training set.""" - # Update local model parameters - global PRIVACY_LOSS - if self.dpsgd: - privacy_spent = common.compute_epsilon( - self.local_epochs, - len(self.x_train), - self.batch_size, - self.noise_multiplier, - ) - PRIVACY_LOSS += privacy_spent - - self.model.set_weights(parameters) - # Train the model - self.model.fit( - self.x_train, - self.y_train, - epochs=self.local_epochs, - batch_size=self.batch_size, - ) - - return self.model.get_weights(), len(self.x_train), {} - - def evaluate(self, parameters, config): - """Evaluate parameters on the locally held test set.""" - - # Update local model with global parameters - self.model.set_weights(parameters) - - # Evaluate global model parameters on the local test data and return results - loss, accuracy = self.model.evaluate(self.x_test, self.y_test) - num_examples_test = len(self.x_test) - return loss, num_examples_test, {"accuracy": accuracy} - - -def main(args) -> None: - # Load Keras model - model = common.create_cnn_model() - - # Load a subset of MNIST to simulate the local data partition - (x_train, y_train), (x_test, y_test) = common.load(args.num_clients)[args.partition] - - # drop samples to form exact batches for dpsgd - # this is necessary since dpsgd is sensitive to uneven batches - # due to microbatching - if args.dpsgd and x_train.shape[0] % args.batch_size != 0: - drop_num = x_train.shape[0] % args.batch_size - x_train = x_train[:-drop_num] - y_train = y_train[:-drop_num] - - # Start Flower client - client = MnistClient(model, x_train, y_train, x_test, y_test, args) - fl.client.start_numpy_client(server_address="127.0.0.1:8080", client=client) - if args.dpsgd: - print("Privacy Loss: ", PRIVACY_LOSS) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Flower Client") - parser.add_argument( - "--num-clients", - default=2, - type=int, - help="Total number of fl participants, requied to get correct partition", - ) - parser.add_argument( - "--partition", - type=int, - required=True, - help="Data Partion to train on. Must be less than number of clients", - ) - parser.add_argument( - "--local-epochs", - default=1, - type=int, - help="Total number of local epochs to train", - ) - parser.add_argument("--batch-size", default=32, type=int, help="Batch size") - parser.add_argument( - "--learning-rate", default=0.15, type=float, help="Learning rate for training" - ) - # DPSGD specific arguments - parser.add_argument( - "--dpsgd", - default=False, - type=bool, - help="If True, train with DP-SGD. If False, " "train with vanilla SGD.", - ) - parser.add_argument("--l2-norm-clip", default=1.0, type=float, help="Clipping norm") - parser.add_argument( - "--noise-multiplier", - default=1.1, - type=float, - help="Ratio of the standard deviation to the clipping norm", - ) - parser.add_argument( - "--microbatches", - default=32, - type=int, - help="Number of microbatches " "(must evenly divide batch_size)", - ) - args = parser.parse_args() - - main(args) diff --git a/examples/dp-sgd-mnist/common.py b/examples/dp-sgd-mnist/common.py deleted file mode 100644 index fbb2f6374203..000000000000 --- a/examples/dp-sgd-mnist/common.py +++ /dev/null @@ -1,103 +0,0 @@ -from typing import List, Tuple - -import numpy as np -import tensorflow as tf - -from tensorflow_privacy.privacy.analysis.rdp_accountant import compute_rdp -from tensorflow_privacy.privacy.analysis.rdp_accountant import get_privacy_spent - - -XY = Tuple[np.ndarray, np.ndarray] -XYList = List[XY] -PartitionedDataset = List[Tuple[XY, XY]] - - -def compute_epsilon( - epochs: int, num_train_examples: int, batch_size: int, noise_multiplier: float -) -> float: - """Computes epsilon value for given hyperparameters. - - Based on - github.com/tensorflow/privacy/blob/master/tutorials/mnist_dpsgd_tutorial_keras.py - """ - if noise_multiplier == 0.0: - return float("inf") - steps = epochs * num_train_examples // batch_size - orders = [1 + x / 10.0 for x in range(1, 100)] + list(range(12, 64)) - sampling_probability = batch_size / num_train_examples - rdp = compute_rdp( - q=sampling_probability, - noise_multiplier=noise_multiplier, - steps=steps, - orders=orders, - ) - # Delta is set to approximate 1 / (number of training points). - return get_privacy_spent(orders, rdp, target_delta=1 / num_train_examples)[0] - - -def create_cnn_model() -> tf.keras.Model: - """Returns a sequential keras CNN Model.""" - return tf.keras.Sequential( - [ - tf.keras.layers.Conv2D( - 16, - 8, - strides=2, - padding="same", - activation="relu", - input_shape=(28, 28, 1), - ), - tf.keras.layers.MaxPool2D(2, 1), - tf.keras.layers.Conv2D( - 32, 4, strides=2, padding="valid", activation="relu" - ), - tf.keras.layers.MaxPool2D(2, 1), - tf.keras.layers.Flatten(), - tf.keras.layers.Dense(32, activation="relu"), - tf.keras.layers.Dense(10), - ] - ) - - -def shuffle(X: np.ndarray, y: np.ndarray) -> XY: - """Shuffle X and y.""" - rng = np.random.default_rng() - idx = rng.permutation(len(X)) - return X[idx], y[idx] - - -def partition(X: np.ndarray, y: np.ndarray, num_partitions: int) -> XYList: - """Split X and y into a number of partitions.""" - return list( - zip(np.array_split(X, num_partitions), np.array_split(y, num_partitions)) - ) - - -def preprocess(X: np.ndarray, y: np.ndarray) -> XY: - """Basic preprocessing for MNIST dataset.""" - X = np.array(X, dtype=np.float32) / 255 - X = X.reshape((X.shape[0], 28, 28, 1)) - - y = np.array(y, dtype=np.int32) - y = tf.keras.utils.to_categorical(y, num_classes=10) - - return X, y - - -def create_partitions(source_dataset: XY, num_partitions: int) -> XYList: - """Create partitioned version of a source dataset.""" - X, y = source_dataset - X, y = shuffle(X, y) - X, y = preprocess(X, y) - xy_partitions = partition(X, y, num_partitions) - return xy_partitions - - -def load( - num_partitions: int, -) -> PartitionedDataset: - """Create partitioned version of MNIST.""" - xy_train, xy_test = tf.keras.datasets.mnist.load_data() - xy_train_partitions = create_partitions(xy_train, num_partitions) - xy_test_partitions = create_partitions(xy_test, num_partitions) - return list(zip(xy_train_partitions, xy_test_partitions)) diff --git a/examples/dp-sgd-mnist/pyproject.toml b/examples/dp-sgd-mnist/pyproject.toml deleted file mode 100644 index 161952fd2aa4..000000000000 --- a/examples/dp-sgd-mnist/pyproject.toml +++ /dev/null @@ -1,20 +0,0 @@ -[build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" - -[tool.poetry] -name = "dp-sgd-mnist" -version = "0.1.0" -description = "Federated training with Tensorflow Privacy" -authors = [ - "The Flower Authors ", - "Kaushik Amar Das ", -] - -[tool.poetry.dependencies] -python = ">=3.8,<3.11" -# flwr = { path = "../../", develop = true } # Development -flwr = ">=1.0,<2.0" -tensorflow-cpu = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "platform_machine == \"x86_64\"" } -tensorflow-macos = { version = ">=2.9.1,<2.11.1 || >2.11.1", markers = "sys_platform == \"darwin\" and platform_machine == \"arm64\"" } -tensorflow-privacy = "0.8.10" diff --git a/examples/dp-sgd-mnist/requirements.txt b/examples/dp-sgd-mnist/requirements.txt deleted file mode 100644 index bd5478de342b..000000000000 --- a/examples/dp-sgd-mnist/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -flwr>=1.0, <2.0 -tensorflow-macos>=2.9.1, != 2.11.1 ; sys_platform == "darwin" and platform_machine == "arm64" -tensorflow-cpu>=2.9.1, != 2.11.1 ; platform_machine == "x86_64" -tensorflow-privacy==0.8.10 diff --git a/examples/dp-sgd-mnist/server.py b/examples/dp-sgd-mnist/server.py deleted file mode 100644 index 5f6f7163834e..000000000000 --- a/examples/dp-sgd-mnist/server.py +++ /dev/null @@ -1,56 +0,0 @@ -import argparse -import os - -import tensorflow as tf - -import flwr as fl - -import common - -# Make TensorFlow logs less verbose -os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" - - -def get_evaluate_fn(model): - """Return an evaluation function for server-side evaluation.""" - - # Load test data here to avoid the overhead of doing it in `evaluate` itself - _, test = tf.keras.datasets.mnist.load_data() - test_data, test_labels = test - - # preprocessing - test_data, test_labels = common.preprocess(test_data, test_labels) - - # The `evaluate` function will be called after every round - def evaluate(weights: fl.common.NDArrays): - model.set_weights(weights) # Update model with the latest parameters - loss, accuracy = model.evaluate(test_data, test_labels) - return loss, {"accuracy": accuracy} - - return evaluate - - -def main(args) -> None: - model = common.create_cnn_model() - loss = tf.keras.losses.CategoricalCrossentropy(from_logits=True) - model.compile("sgd", loss=loss, metrics=["accuracy"]) - strategy = fl.server.strategy.FedAvg( - fraction_fit=args.fraction_fit, - min_available_clients=args.num_clients, - evaluate_fn=get_evaluate_fn(model), - initial_parameters=fl.common.ndarrays_to_parameters(model.get_weights()), - ) - fl.server.start_server( - server_address="0.0.0.0:8080", - strategy=strategy, - config=fl.server.ServerConfig(num_rounds=args.num_rounds), - ) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser(description="Server Script") - parser.add_argument("--num-clients", default=2, type=int) - parser.add_argument("--num-rounds", default=1, type=int) - parser.add_argument("--fraction-fit", default=1.0, type=float) - args = parser.parse_args() - main(args) diff --git a/examples/tensorflow-privacy/README.md b/examples/tensorflow-privacy/README.md new file mode 100644 index 000000000000..a1f1be00f6b0 --- /dev/null +++ b/examples/tensorflow-privacy/README.md @@ -0,0 +1,60 @@ +# Training with Sample-Level Differential Privacy using TensorFlow-Privacy Engine + +In this example, we demonstrate how to train a model with sample-level differential privacy (DP) using Flower. We employ TensorFlow and integrate the tensorflow-privacy Engine to achieve sample-level differential privacy. This setup ensures robust privacy guarantees during the client training phase. + +For more information about DP in Flower please refer to the [tutorial](https://flower.ai/docs/framework/how-to-use-differential-privacy.html). For additional information about tensorflow-privacy, visit the official [website](https://www.tensorflow.org/responsible_ai/privacy/guide). + +## Environments Setup + +Start by cloning the example. We prepared a single-line command that you can copy into your shell which will checkout the example for you: + +```shell +git clone --depth=1 https://github.com/adap/flower.git && mv flower/examples/tensorflow-privacy . && rm -rf flower && cd tensorflow-privacy +``` + +This will create a new directory called `tensorflow-privacy` containing the following files: + +```shell +-- pyproject.toml +-- client.py +-- server.py +-- README.md +``` + +### Installing dependencies + +Project dependencies are defined in `pyproject.toml`. Install them with: + +```shell +pip install . +``` + +## Run Flower with tensorflow-privacy and TensorFlow + +### 1. Start the long-running Flower server (SuperLink) + +```bash +flower-superlink --insecure +``` + +### 2. Start the long-running Flower clients (SuperNodes) + +Start 2 Flower `SuperNodes` in 2 separate terminal windows, using: + +```bash +flower-client-app client:appA --insecure +``` + +```bash +flower-client-app client:appB --insecure +``` + +tensorflow-privacy hyperparameters can be passed for each client in `ClientApp` instantiation (in `client.py`). In this example, `noise_multiplier=1.5` and `noise_multiplier=1` are used for the first and second client respectively. + +### 3. Run the Flower App + +With both the long-running server (SuperLink) and two clients (SuperNode) up and running, we can now run the actual Flower App: + +```bash +flower-server-app server:app --insecure +``` diff --git a/examples/tensorflow-privacy/client.py b/examples/tensorflow-privacy/client.py new file mode 100644 index 000000000000..1032d12e69a2 --- /dev/null +++ b/examples/tensorflow-privacy/client.py @@ -0,0 +1,139 @@ +import argparse +import os +from flwr.client import ClientApp, NumPyClient +import tensorflow as tf +from flwr_datasets import FederatedDataset +import tensorflow_privacy + +from tensorflow_privacy.privacy.analysis.compute_dp_sgd_privacy_lib import ( + compute_dp_sgd_privacy_statement, +) + +# Make TensorFlow log less verbose +os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" + + +def load_data(partition_id, batch_size): + fds = FederatedDataset(dataset="cifar10", partitioners={"train": 2}) + partition = fds.load_partition(partition_id, "train") + partition.set_format("numpy") + + # Divide data on each node: 80% train, 20% test + partition = partition.train_test_split(test_size=0.2, seed=42) + x_train, y_train = partition["train"]["img"] / 255.0, partition["train"]["label"] + x_test, y_test = partition["test"]["img"] / 255.0, partition["test"]["label"] + + # Adjust the size of the training dataset to make it evenly divisible by the batch size + remainder = len(x_train) % batch_size + if remainder != 0: + x_train = x_train[:-remainder] + y_train = y_train[:-remainder] + + return (x_train, y_train), (x_test, y_test) + + +class FlowerClient(NumPyClient): + def __init__( + self, + model, + train_data, + test_data, + l2_norm_clip, + noise_multiplier, + num_microbatches, + learning_rate, + batch_size, + ) -> None: + super().__init__() + self.model = model + self.x_train, self.y_train = train_data + self.x_test, self.y_test = test_data + self.noise_multiplier = noise_multiplier + self.l2_norm_clip = l2_norm_clip + self.num_microbatches = num_microbatches + self.learning_rate = learning_rate + self.batch_size = batch_size + if self.batch_size % self.num_microbatches != 0: + raise ValueError( + f"Batch size {self.batch_size} is not divisible by the number of microbatches {self.num_microbatches}" + ) + + self.optimizer = tensorflow_privacy.DPKerasSGDOptimizer( + l2_norm_clip=l2_norm_clip, + noise_multiplier=noise_multiplier, + num_microbatches=num_microbatches, + learning_rate=learning_rate, + ) + loss = tf.keras.losses.SparseCategoricalCrossentropy( + reduction=tf.losses.Reduction.NONE + ) + self.model.compile(optimizer=self.optimizer, loss=loss, metrics=["accuracy"]) + + def get_parameters(self, config): + return self.model.get_weights() + + def fit(self, parameters, config): + self.model.set_weights(parameters) + + self.model.fit( + self.x_train, + self.y_train, + epochs=1, + batch_size=self.batch_size, + ) + + compute_dp_sgd_privacy_statement( + number_of_examples=self.x_train.shape[0], + batch_size=self.batch_size, + num_epochs=1, + noise_multiplier=self.noise_multiplier, + delta=1e-5, + ) + + return self.model.get_weights(), len(self.x_train), {} + + def evaluate(self, parameters, config): + self.model.set_weights(parameters) + self.model.compile( + optimizer=self.optimizer, + loss="sparse_categorical_crossentropy", + metrics=["accuracy"], + ) + loss, accuracy = self.model.evaluate(self.x_test, self.y_test) + return loss, len(self.x_test), {"accuracy": accuracy} + + +def client_fn_parameterized( + partition_id, + noise_multiplier, + l2_norm_clip=1.0, + num_microbatches=64, + learning_rate=0.01, + batch_size=64, +): + def client_fn(cid: str): + model = tf.keras.applications.MobileNetV2((32, 32, 3), classes=10, weights=None) + train_data, test_data = load_data( + partition_id=partition_id, batch_size=batch_size + ) + return FlowerClient( + model, + train_data, + test_data, + noise_multiplier, + l2_norm_clip, + num_microbatches, + learning_rate, + batch_size, + ).to_client() + + return client_fn + + +appA = ClientApp( + client_fn=client_fn_parameterized(partition_id=0, noise_multiplier=1.0), +) + +appB = ClientApp( + client_fn=client_fn_parameterized(partition_id=1, noise_multiplier=1.5), +) diff --git a/examples/tensorflow-privacy/pyproject.toml b/examples/tensorflow-privacy/pyproject.toml new file mode 100644 index 000000000000..884ba3b5f07b --- /dev/null +++ b/examples/tensorflow-privacy/pyproject.toml @@ -0,0 +1,22 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "tensorflow-privacy-fl" +version = "0.1.0" +description = "Sample-level Differential Privacy with Tensorflow-Privacy in Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr>=1.8.0,<2.0", + "flwr-datasets[vision]>=0.1.0,<1.0.0", + "tensorflow-estimator~=2.4", + "tensorflow-probability~=0.22.0", + "tensorflow>=2.4.0,<=2.15.0", + "tensorflow-privacy == 0.9.0" +] + +[tool.hatch.build.targets.wheel] +packages = ["."] diff --git a/examples/tensorflow-privacy/server.py b/examples/tensorflow-privacy/server.py new file mode 100644 index 000000000000..1e399fa7e833 --- /dev/null +++ b/examples/tensorflow-privacy/server.py @@ -0,0 +1,22 @@ +from typing import List, Tuple + +from flwr.server import ServerApp, ServerConfig +from flwr.server.strategy import FedAvg +from flwr.common import Metrics + + +def weighted_average(metrics: List[Tuple[int, Metrics]]) -> Metrics: + accuracies = [num_examples * m["accuracy"] for num_examples, m in metrics] + examples = [num_examples for num_examples, _ in metrics] + + return {"accuracy": sum(accuracies) / sum(examples)} + + +strategy = FedAvg(evaluate_metrics_aggregation_fn=weighted_average) + +config = ServerConfig(num_rounds=3) + +app = ServerApp( + config=config, + strategy=strategy, +) From a443f86ee7a59e4dbdb9c76200cc924d19edbc29 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Wed, 29 May 2024 12:47:07 +0200 Subject: [PATCH 030/124] break(datasets) Rename resplitter parameter and type to preprocessor (#3476) --- datasets/flwr_datasets/__init__.py | 4 +- datasets/flwr_datasets/federated_dataset.py | 22 +++--- .../flwr_datasets/federated_dataset_test.py | 14 ++-- .../{resplitter => preprocessor}/__init__.py | 14 ++-- .../divider.py} | 12 +-- .../divider_test.py} | 74 +++++++------------ .../merger.py} | 8 +- .../merger_test.py} | 46 ++++++------ .../preprocessor.py} | 4 +- datasets/flwr_datasets/utils.py | 18 ++--- 10 files changed, 100 insertions(+), 116 deletions(-) rename datasets/flwr_datasets/{resplitter => preprocessor}/__init__.py (76%) rename datasets/flwr_datasets/{resplitter/divide_resplitter.py => preprocessor/divider.py} (98%) rename datasets/flwr_datasets/{resplitter/divide_resplitter_test.py => preprocessor/divider_test.py} (79%) rename datasets/flwr_datasets/{resplitter/merge_resplitter.py => preprocessor/merger.py} (96%) rename datasets/flwr_datasets/{resplitter/merge_resplitter_test.py => preprocessor/merger_test.py} (81%) rename datasets/flwr_datasets/{resplitter/resplitter.py => preprocessor/preprocessor.py} (91%) diff --git a/datasets/flwr_datasets/__init__.py b/datasets/flwr_datasets/__init__.py index 0b9a6685427b..2d6ecb414498 100644 --- a/datasets/flwr_datasets/__init__.py +++ b/datasets/flwr_datasets/__init__.py @@ -15,7 +15,7 @@ """Flower Datasets main package.""" -from flwr_datasets import partitioner, resplitter +from flwr_datasets import partitioner, preprocessor from flwr_datasets import utils as utils from flwr_datasets.common.version import package_version as _package_version from flwr_datasets.federated_dataset import FederatedDataset @@ -23,7 +23,7 @@ __all__ = [ "FederatedDataset", "partitioner", - "resplitter", + "preprocessor", "utils", ] diff --git a/datasets/flwr_datasets/federated_dataset.py b/datasets/flwr_datasets/federated_dataset.py index 6c41eaa3562f..5d98d01d4941 100644 --- a/datasets/flwr_datasets/federated_dataset.py +++ b/datasets/flwr_datasets/federated_dataset.py @@ -20,11 +20,11 @@ import datasets from datasets import Dataset, DatasetDict from flwr_datasets.partitioner import Partitioner -from flwr_datasets.resplitter import Resplitter +from flwr_datasets.preprocessor import Preprocessor from flwr_datasets.utils import ( _check_if_dataset_tested, + _instantiate_merger_if_needed, _instantiate_partitioners, - _instantiate_resplitter_if_needed, ) @@ -45,9 +45,11 @@ class FederatedDataset: subset : str Secondary information regarding the dataset, most often subset or version (that is passed to the name in datasets.load_dataset). - resplitter : Optional[Union[Resplitter, Dict[str, Tuple[str, ...]]]] - `Callable` that transforms `DatasetDict` splits, or configuration dict for - `MergeResplitter`. + preprocessor : Optional[Union[Preprocessor, Dict[str, Tuple[str, ...]]]] + `Callable` that transforms `DatasetDict` by resplitting, removing + features, creating new features, performing any other preprocessing operation, + or configuration dict for `Merger`. Applied after shuffling. If None, + no operation is applied. partitioners : Dict[str, Union[Partitioner, int]] A dictionary mapping the Dataset split (a `str`) to a `Partitioner` or an `int` (representing the number of IID partitions that this split should be partitioned @@ -79,7 +81,7 @@ def __init__( *, dataset: str, subset: Optional[str] = None, - resplitter: Optional[Union[Resplitter, Dict[str, Tuple[str, ...]]]] = None, + preprocessor: Optional[Union[Preprocessor, Dict[str, Tuple[str, ...]]]] = None, partitioners: Dict[str, Union[Partitioner, int]], shuffle: bool = True, seed: Optional[int] = 42, @@ -87,8 +89,8 @@ def __init__( _check_if_dataset_tested(dataset) self._dataset_name: str = dataset self._subset: Optional[str] = subset - self._resplitter: Optional[Resplitter] = _instantiate_resplitter_if_needed( - resplitter + self._preprocessor: Optional[Preprocessor] = _instantiate_merger_if_needed( + preprocessor ) self._partitioners: Dict[str, Partitioner] = _instantiate_partitioners( partitioners @@ -242,8 +244,8 @@ def _prepare_dataset(self) -> None: # Note it shuffles all the splits. The self._dataset is DatasetDict # so e.g. {"train": train_data, "test": test_data}. All splits get shuffled. self._dataset = self._dataset.shuffle(seed=self._seed) - if self._resplitter: - self._dataset = self._resplitter(self._dataset) + if self._preprocessor: + self._dataset = self._preprocessor(self._dataset) self._dataset_prepared = True def _check_if_no_split_keyword_possible(self) -> None: diff --git a/datasets/flwr_datasets/federated_dataset_test.py b/datasets/flwr_datasets/federated_dataset_test.py index 5d5179122e3b..f65aa6346f3a 100644 --- a/datasets/flwr_datasets/federated_dataset_test.py +++ b/datasets/flwr_datasets/federated_dataset_test.py @@ -170,20 +170,20 @@ def test_resplit_dataset_into_one(self) -> None: fds = FederatedDataset( dataset=self.dataset_name, partitioners={"train": 100}, - resplitter={"full": ("train", self.test_split)}, + preprocessor={"full": ("train", self.test_split)}, ) full = fds.load_split("full") self.assertEqual(dataset_length, len(full)) # pylint: disable=protected-access def test_resplit_dataset_to_change_names(self) -> None: - """Test resplitter to change the names of the partitions.""" + """Test preprocessor to change the names of the partitions.""" if self.test_split is None: return fds = FederatedDataset( dataset=self.dataset_name, partitioners={"new_train": 100}, - resplitter={ + preprocessor={ "new_train": ("train",), "new_" + self.test_split: (self.test_split,), }, @@ -195,7 +195,7 @@ def test_resplit_dataset_to_change_names(self) -> None: ) def test_resplit_dataset_by_callable(self) -> None: - """Test resplitter to change the names of the partitions.""" + """Test preprocessor to change the names of the partitions.""" if self.test_split is None: return @@ -209,7 +209,7 @@ def resplit(dataset: DatasetDict) -> DatasetDict: ) fds = FederatedDataset( - dataset=self.dataset_name, partitioners={"train": 100}, resplitter=resplit + dataset=self.dataset_name, partitioners={"train": 100}, preprocessor=resplit ) full = fds.load_split("full") dataset = datasets.load_dataset(self.dataset_name) @@ -298,7 +298,7 @@ def resplit(dataset: DatasetDict) -> DatasetDict: fds = FederatedDataset( dataset="does-not-matter", partitioners={"train": 10}, - resplitter=resplit, + preprocessor=resplit, shuffle=True, ) train = fds.load_split("train") @@ -411,7 +411,7 @@ def test_cannot_use_the_old_split_names(self) -> None: fds = FederatedDataset( dataset="mnist", partitioners={"train": 100}, - resplitter={"full": ("train", "test")}, + preprocessor={"full": ("train", "test")}, ) with self.assertRaises(ValueError): fds.load_partition(0, "train") diff --git a/datasets/flwr_datasets/resplitter/__init__.py b/datasets/flwr_datasets/preprocessor/__init__.py similarity index 76% rename from datasets/flwr_datasets/resplitter/__init__.py rename to datasets/flwr_datasets/preprocessor/__init__.py index bf39786e0593..bab5d82a2035 100644 --- a/datasets/flwr_datasets/resplitter/__init__.py +++ b/datasets/flwr_datasets/preprocessor/__init__.py @@ -12,15 +12,15 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""Resplitter package.""" +"""Preprocessor package.""" -from .divide_resplitter import DivideResplitter -from .merge_resplitter import MergeResplitter -from .resplitter import Resplitter +from .divider import Divider +from .merger import Merger +from .preprocessor import Preprocessor __all__ = [ - "DivideResplitter", - "MergeResplitter", - "Resplitter", + "Merger", + "Preprocessor", + "Divider", ] diff --git a/datasets/flwr_datasets/resplitter/divide_resplitter.py b/datasets/flwr_datasets/preprocessor/divider.py similarity index 98% rename from datasets/flwr_datasets/resplitter/divide_resplitter.py rename to datasets/flwr_datasets/preprocessor/divider.py index 56150b51af85..9d7570de4cea 100644 --- a/datasets/flwr_datasets/resplitter/divide_resplitter.py +++ b/datasets/flwr_datasets/preprocessor/divider.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""DivideResplitter class for Flower Datasets.""" +"""Divider class for Flower Datasets.""" import collections @@ -25,7 +25,7 @@ # flake8: noqa: E501 # pylint: disable=line-too-long -class DivideResplitter: +class Divider: """Dive existing split(s) of the dataset and assign them custom names. Create new `DatasetDict` with new split names with corresponding percentages of data @@ -66,14 +66,14 @@ class DivideResplitter: >>> # Assuming there is a dataset_dict of type `DatasetDict` >>> # dataset_dict is {"train": train-data, "test": test-data} - >>> resplitter = DivideResplitter( + >>> divider = Divider( >>> divide_config={ >>> "train": 0.8, >>> "valid": 0.2, >>> } >>> divide_split="train", >>> ) - >>> new_dataset_dict = resplitter(dataset_dict) + >>> new_dataset_dict = divider(dataset_dict) >>> # new_dataset_dict is >>> # {"train": 80% of train, "valid": 20% of train, "test": test-data} @@ -83,7 +83,7 @@ class DivideResplitter: >>> # Assuming there is a dataset_dict of type `DatasetDict` >>> # dataset_dict is {"train": train-data, "test": test-data} - >>> resplitter = DivideResplitter( + >>> divider = Divider( >>> divide_config={ >>> "train": { >>> "train": 0.8, @@ -92,7 +92,7 @@ class DivideResplitter: >>> "test": {"test-a": 0.4, "test-b": 0.6 } >>> } >>> ) - >>> new_dataset_dict = resplitter(dataset_dict) + >>> new_dataset_dict = divider(dataset_dict) >>> # new_dataset_dict is >>> # {"train": 80% of train, "valid": 20% of train, >>> # "test-a": 40% of test, "test-b": 60% of test} diff --git a/datasets/flwr_datasets/resplitter/divide_resplitter_test.py b/datasets/flwr_datasets/preprocessor/divider_test.py similarity index 79% rename from datasets/flwr_datasets/resplitter/divide_resplitter_test.py rename to datasets/flwr_datasets/preprocessor/divider_test.py index 143297fcc1a7..ed282fbc18be 100644 --- a/datasets/flwr_datasets/resplitter/divide_resplitter_test.py +++ b/datasets/flwr_datasets/preprocessor/divider_test.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""DivideResplitter tests.""" +"""Divider tests.""" import unittest from typing import Dict, Union @@ -20,7 +20,7 @@ from parameterized import parameterized_class from datasets import Dataset, DatasetDict -from flwr_datasets.resplitter import DivideResplitter +from flwr_datasets.preprocessor import Divider @parameterized_class( @@ -80,8 +80,8 @@ ), ], ) -class TestDivideResplitter(unittest.TestCase): - """DivideResplitter tests.""" +class TestDivider(unittest.TestCase): + """Divider tests.""" divide_config: Union[ Dict[str, float], @@ -105,27 +105,27 @@ def setUp(self) -> None: def test_resplitting_correct_new_split_names(self) -> None: """Test if resplitting produces requested new splits.""" - resplitter = DivideResplitter( + divider = Divider( self.divide_config, self.divide_split, self.drop_remaining_splits ) - resplit_dataset = resplitter(self.dataset_dict) + resplit_dataset = divider(self.dataset_dict) new_keys = set(resplit_dataset.keys()) self.assertEqual(set(self.split_name_to_size.keys()), new_keys) def test_resplitting_correct_new_split_sizes(self) -> None: """Test if resplitting produces correct sizes of splits.""" - resplitter = DivideResplitter( + divider = Divider( self.divide_config, self.divide_split, self.drop_remaining_splits ) - resplit_dataset = resplitter(self.dataset_dict) + resplit_dataset = divider(self.dataset_dict) split_to_size = { split_name: len(split) for split_name, split in resplit_dataset.items() } self.assertEqual(self.split_name_to_size, split_to_size) -class TestDivideResplitterIncorrectUseCases(unittest.TestCase): - """Resplitter tests.""" +class TestDividerIncorrectUseCases(unittest.TestCase): + """Divider tests.""" def setUp(self) -> None: """Set up the dataset with 3 splits for tests.""" @@ -144,21 +144,17 @@ def test_doubling_names_in_config(self) -> None: drop_remaining_splits = False with self.assertRaises(ValueError): - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) - _ = resplitter(self.dataset_dict) + divider = Divider(divide_config, divide_split, drop_remaining_splits) + _ = divider(self.dataset_dict) def test_duplicate_names_in_config_and_dataset_split_names_multisplit(self) -> None: """Test if resplitting raises when the name collides with the old name.""" divide_config = {"train": {"valid": 0.5}} divide_split = None drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_duplicate_names_in_config_and_dataset_split_names_single_split( self, @@ -167,77 +163,63 @@ def test_duplicate_names_in_config_and_dataset_split_names_single_split( divide_config = {"valid": 0.5} divide_split = "train" drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_fraction_sum_up_to_more_than_one_multisplit(self) -> None: """Test if resplitting raises when fractions sum up to > 1.0 .""" divide_config = {"train": {"train_1": 0.5, "train_2": 0.7}} divide_split = None drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_fraction_sum_up_to_more_than_one_single_split(self) -> None: """Test if resplitting raises when fractions sum up to > 1.0 .""" divide_config = {"train_1": 0.5, "train_2": 0.7} divide_split = "train" drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_sample_sizes_sum_up_to_more_than_dataset_size_single_split(self) -> None: """Test if resplitting raises when samples size sum up to > len(datset) .""" divide_config = {"train": {"train_1": 20, "train_2": 25}} divide_split = None drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_sample_sizes_sum_up_to_more_than_dataset_size_multisplit(self) -> None: """Test if resplitting raises when samples size sum up to > len(datset) .""" divide_config = {"train_1": 20, "train_2": 25} divide_split = "train" drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_too_small_size_values_create_empty_dataset_single_split(self) -> None: """Test if resplitting raises when fraction creates empty dataset.""" divide_config = {"train": {"train_1": 0.2, "train_2": 0.0001}} divide_split = None drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) def test_too_small_size_values_create_empty_dataset_multisplit(self) -> None: """Test if resplitting raises when fraction creates empty dataset.""" divide_config = {"train_1": 0.2, "train_2": 0.0001} divide_split = "train" drop_remaining_splits = False - resplitter = DivideResplitter( - divide_config, divide_split, drop_remaining_splits - ) + divider = Divider(divide_config, divide_split, drop_remaining_splits) with self.assertRaises(ValueError): - _ = resplitter(self.dataset_dict) + _ = divider(self.dataset_dict) if __name__ == "__main__": diff --git a/datasets/flwr_datasets/resplitter/merge_resplitter.py b/datasets/flwr_datasets/preprocessor/merger.py similarity index 96% rename from datasets/flwr_datasets/resplitter/merge_resplitter.py rename to datasets/flwr_datasets/preprocessor/merger.py index 6bb8f23e60dc..2b76dbbafe4b 100644 --- a/datasets/flwr_datasets/resplitter/merge_resplitter.py +++ b/datasets/flwr_datasets/preprocessor/merger.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""MergeResplitter class for Flower Datasets.""" +"""Merger class for Flower Datasets.""" import collections @@ -24,7 +24,7 @@ from datasets import Dataset, DatasetDict -class MergeResplitter: +class Merger: """Merge existing splits of the dataset and assign them custom names. Create new `DatasetDict` with new split names corresponding to the merged existing @@ -43,13 +43,13 @@ class MergeResplitter: >>> # Assuming there is a dataset_dict of type `DatasetDict` >>> # dataset_dict is {"train": train-data, "valid": valid-data, "test": test-data} - >>> merge_resplitter = MergeResplitter( + >>> merger = Merger( >>> merge_config={ >>> "new_train": ("train", "valid"), >>> "test": ("test", ) >>> } >>> ) - >>> new_dataset_dict = merge_resplitter(dataset_dict) + >>> new_dataset_dict = merger(dataset_dict) >>> # new_dataset_dict is >>> # {"new_train": concatenation of train-data and valid-data, "test": test-data} """ diff --git a/datasets/flwr_datasets/resplitter/merge_resplitter_test.py b/datasets/flwr_datasets/preprocessor/merger_test.py similarity index 81% rename from datasets/flwr_datasets/resplitter/merge_resplitter_test.py rename to datasets/flwr_datasets/preprocessor/merger_test.py index ebbdfb4022b0..d5c69387e53d 100644 --- a/datasets/flwr_datasets/resplitter/merge_resplitter_test.py +++ b/datasets/flwr_datasets/preprocessor/merger_test.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""Resplitter tests.""" +"""Preprocessor tests.""" import unittest @@ -21,11 +21,11 @@ import pytest from datasets import Dataset, DatasetDict -from flwr_datasets.resplitter.merge_resplitter import MergeResplitter +from flwr_datasets.preprocessor.merger import Merger -class TestResplitter(unittest.TestCase): - """Resplitter tests.""" +class TestMerger(unittest.TestCase): + """Preprocessor tests.""" def setUp(self) -> None: """Set up the dataset with 3 splits for tests.""" @@ -40,29 +40,29 @@ def setUp(self) -> None: def test_resplitting_train_size(self) -> None: """Test if resplitting for just renaming keeps the lengths correct.""" strategy: Dict[str, Tuple[str, ...]] = {"new_train": ("train",)} - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertEqual(len(new_dataset["new_train"]), 3) def test_resplitting_valid_size(self) -> None: """Test if resplitting for just renaming keeps the lengths correct.""" strategy: Dict[str, Tuple[str, ...]] = {"new_valid": ("valid",)} - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertEqual(len(new_dataset["new_valid"]), 2) def test_resplitting_test_size(self) -> None: """Test if resplitting for just renaming keeps the lengths correct.""" strategy: Dict[str, Tuple[str, ...]] = {"new_test": ("test",)} - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertEqual(len(new_dataset["new_test"]), 1) def test_resplitting_train_the_same(self) -> None: """Test if resplitting for just renaming keeps the dataset the same.""" strategy: Dict[str, Tuple[str, ...]] = {"new_train": ("train",)} - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertTrue( datasets_are_equal(self.dataset_dict["train"], new_dataset["new_train"]) ) @@ -72,8 +72,8 @@ def test_combined_train_valid_size(self) -> None: strategy: Dict[str, Tuple[str, ...]] = { "train_valid_combined": ("train", "valid") } - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertEqual(len(new_dataset["train_valid_combined"]), 5) def test_resplitting_test_with_combined_strategy_size(self) -> None: @@ -82,8 +82,8 @@ def test_resplitting_test_with_combined_strategy_size(self) -> None: "train_valid_combined": ("train", "valid"), "test": ("test",), } - resplitter = MergeResplitter(strategy) - new_dataset = resplitter(self.dataset_dict) + merger = Merger(strategy) + new_dataset = merger(self.dataset_dict) self.assertEqual(len(new_dataset["test"]), 1) def test_invalid_resplit_strategy_exception_message(self) -> None: @@ -92,20 +92,20 @@ def test_invalid_resplit_strategy_exception_message(self) -> None: "new_train": ("invalid_split",), "new_test": ("test",), } - resplitter = MergeResplitter(strategy) + merger = Merger(strategy) with self.assertRaisesRegex( ValueError, "The given dataset key 'invalid_split' is not present" ): - resplitter(self.dataset_dict) + merger(self.dataset_dict) def test_nonexistent_split_in_strategy(self) -> None: """Test if the exception is raised when the nonexistent split name is given.""" strategy: Dict[str, Tuple[str, ...]] = {"new_split": ("nonexistent_split",)} - resplitter = MergeResplitter(strategy) + merger = Merger(strategy) with self.assertRaisesRegex( ValueError, "The given dataset key 'nonexistent_split' is not present" ): - resplitter(self.dataset_dict) + merger(self.dataset_dict) def test_duplicate_merge_split_name(self) -> None: # pylint: disable=R0201 """Test that the new split names are not the same.""" @@ -114,17 +114,17 @@ def test_duplicate_merge_split_name(self) -> None: # pylint: disable=R0201 "test": ("train",), } with pytest.warns(UserWarning): - _ = MergeResplitter(strategy) + _ = Merger(strategy) def test_empty_dataset_dict(self) -> None: """Test that the error is raised when the empty DatasetDict is given.""" empty_dataset = DatasetDict({}) strategy: Dict[str, Tuple[str, ...]] = {"new_train": ("train",)} - resplitter = MergeResplitter(strategy) + merger = Merger(strategy) with self.assertRaisesRegex( ValueError, "The given dataset key 'train' is not present" ): - resplitter(empty_dataset) + merger(empty_dataset) def datasets_are_equal(ds1: Dataset, ds2: Dataset) -> bool: diff --git a/datasets/flwr_datasets/resplitter/resplitter.py b/datasets/flwr_datasets/preprocessor/preprocessor.py similarity index 91% rename from datasets/flwr_datasets/resplitter/resplitter.py rename to datasets/flwr_datasets/preprocessor/preprocessor.py index 206e2e85730c..c137b98eeeee 100644 --- a/datasets/flwr_datasets/resplitter/resplitter.py +++ b/datasets/flwr_datasets/preprocessor/preprocessor.py @@ -12,11 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""Resplitter.""" +"""Preprocessor.""" from typing import Callable from datasets import DatasetDict -Resplitter = Callable[[DatasetDict], DatasetDict] +Preprocessor = Callable[[DatasetDict], DatasetDict] diff --git a/datasets/flwr_datasets/utils.py b/datasets/flwr_datasets/utils.py index c6f6900a99cd..0ecb96ac9456 100644 --- a/datasets/flwr_datasets/utils.py +++ b/datasets/flwr_datasets/utils.py @@ -20,8 +20,8 @@ from datasets import Dataset, DatasetDict, concatenate_datasets from flwr_datasets.partitioner import IidPartitioner, Partitioner -from flwr_datasets.resplitter import Resplitter -from flwr_datasets.resplitter.merge_resplitter import MergeResplitter +from flwr_datasets.preprocessor import Preprocessor +from flwr_datasets.preprocessor.merger import Merger tested_datasets = [ "mnist", @@ -75,13 +75,13 @@ def _instantiate_partitioners( return instantiated_partitioners -def _instantiate_resplitter_if_needed( - resplitter: Optional[Union[Resplitter, Dict[str, Tuple[str, ...]]]] -) -> Optional[Resplitter]: - """Instantiate `MergeResplitter` if resplitter is merge_config.""" - if resplitter and isinstance(resplitter, Dict): - resplitter = MergeResplitter(merge_config=resplitter) - return cast(Optional[Resplitter], resplitter) +def _instantiate_merger_if_needed( + merger: Optional[Union[Preprocessor, Dict[str, Tuple[str, ...]]]] +) -> Optional[Preprocessor]: + """Instantiate `Merger` if preprocessor is merge_config.""" + if merger and isinstance(merger, Dict): + merger = Merger(merge_config=merger) + return cast(Optional[Preprocessor], merger) def _check_if_dataset_tested(dataset: str) -> None: From ee00d70a4f73abc339c53fcb402d9a164f3b9bf1 Mon Sep 17 00:00:00 2001 From: mohammadnaseri Date: Wed, 29 May 2024 11:52:36 +0100 Subject: [PATCH 031/124] fix(examples) Update TensorFlow-Privacy example dataset and model (#3526) --- examples/tensorflow-privacy/client.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/examples/tensorflow-privacy/client.py b/examples/tensorflow-privacy/client.py index 1032d12e69a2..4aec85da014a 100644 --- a/examples/tensorflow-privacy/client.py +++ b/examples/tensorflow-privacy/client.py @@ -14,14 +14,14 @@ def load_data(partition_id, batch_size): - fds = FederatedDataset(dataset="cifar10", partitioners={"train": 2}) + fds = FederatedDataset(dataset="mnist", partitioners={"train": 2}) partition = fds.load_partition(partition_id, "train") partition.set_format("numpy") # Divide data on each node: 80% train, 20% test partition = partition.train_test_split(test_size=0.2, seed=42) - x_train, y_train = partition["train"]["img"] / 255.0, partition["train"]["label"] - x_test, y_test = partition["test"]["img"] / 255.0, partition["test"]["label"] + x_train, y_train = partition["train"]["image"] / 255.0, partition["train"]["label"] + x_test, y_test = partition["test"]["image"] / 255.0, partition["test"]["label"] # Adjust the size of the training dataset to make it evenly divisible by the batch size remainder = len(x_train) % batch_size @@ -112,7 +112,18 @@ def client_fn_parameterized( batch_size=64, ): def client_fn(cid: str): - model = tf.keras.applications.MobileNetV2((32, 32, 3), classes=10, weights=None) + model = tf.keras.Sequential( + [ + tf.keras.layers.InputLayer(input_shape=(28, 28, 1)), + tf.keras.layers.Conv2D(32, kernel_size=(3, 3), activation="relu"), + tf.keras.layers.MaxPooling2D(pool_size=(2, 2)), + tf.keras.layers.Conv2D(64, kernel_size=(3, 3), activation="relu"), + tf.keras.layers.MaxPooling2D(pool_size=(2, 2)), + tf.keras.layers.Flatten(), + tf.keras.layers.Dense(128, activation="relu"), + tf.keras.layers.Dense(10, activation="softmax"), + ] + ) train_data, test_data = load_data( partition_id=partition_id, batch_size=batch_size ) From a1216e2f8a7f7bd4ee2c37974cfbbb07893dfeaf Mon Sep 17 00:00:00 2001 From: Yan Gao Date: Thu, 30 May 2024 18:33:27 +0800 Subject: [PATCH 032/124] fix(examples) Update XGBoost quick-start example for independent object instantiation (#3426) Co-authored-by: jafermarq --- examples/xgboost-quickstart/README.md | 23 ++---- examples/xgboost-quickstart/client.py | 86 ++++++++++++++------ examples/xgboost-quickstart/pyproject.toml | 26 +++--- examples/xgboost-quickstart/requirements.txt | 3 - examples/xgboost-quickstart/server.py | 11 +++ 5 files changed, 91 insertions(+), 58 deletions(-) delete mode 100644 examples/xgboost-quickstart/requirements.txt diff --git a/examples/xgboost-quickstart/README.md b/examples/xgboost-quickstart/README.md index b196520d37e6..713b6eab8bac 100644 --- a/examples/xgboost-quickstart/README.md +++ b/examples/xgboost-quickstart/README.md @@ -21,37 +21,26 @@ This will create a new directory called `xgboost-quickstart` containing the foll -- server.py <- Defines the server-side logic -- client.py <- Defines the client-side logic -- run.sh <- Commands to run experiments --- pyproject.toml <- Example dependencies (if you use Poetry) --- requirements.txt <- Example dependencies +-- pyproject.toml <- Example dependencies ``` ### Installing Dependencies -Project dependencies (such as `xgboost` and `flwr`) are defined in `pyproject.toml` and `requirements.txt`. We recommend [Poetry](https://python-poetry.org/docs/) to install those dependencies and manage your virtual environment ([Poetry installation](https://python-poetry.org/docs/#installation)) or [pip](https://pip.pypa.io/en/latest/development/), but feel free to use a different way of installing dependencies and managing virtual environments if you have other preferences. - -#### Poetry +Project dependencies (such as `xgboost` and `flwr`) are defined in `pyproject.toml`. You can install the dependencies by invoking `pip`: ```shell -poetry install -poetry shell +# From a new python environment, run: +pip install . ``` -Poetry will install all your dependencies in a newly created virtual environment. To verify that everything works correctly you can run the following command: +Then, to verify that everything works correctly you can run the following command: ```shell -poetry run python3 -c "import flwr" +python3 -c "import flwr" ``` If you don't see any errors you're good to go! -#### pip - -Write the command below in your terminal to install the dependencies according to the configuration file requirements.txt. - -```shell -pip install -r requirements.txt -``` - ## Run Federated Learning with XGBoost and Flower Afterwards you are ready to start the Flower server as well as the clients. diff --git a/examples/xgboost-quickstart/client.py b/examples/xgboost-quickstart/client.py index 6ac23ae15148..5a4d88bb7e43 100644 --- a/examples/xgboost-quickstart/client.py +++ b/examples/xgboost-quickstart/client.py @@ -92,9 +92,21 @@ def transform_dataset_to_dmatrix(data: Union[Dataset, DatasetDict]) -> xgb.core. # Define Flower client class XgbClient(fl.client.Client): - def __init__(self): - self.bst = None - self.config = None + def __init__( + self, + train_dmatrix, + valid_dmatrix, + num_train, + num_val, + num_local_round, + params, + ): + self.train_dmatrix = train_dmatrix + self.valid_dmatrix = valid_dmatrix + self.num_train = num_train + self.num_val = num_val + self.num_local_round = num_local_round + self.params = params def get_parameters(self, ins: GetParametersIns) -> GetParametersRes: _ = (self, ins) @@ -106,41 +118,41 @@ def get_parameters(self, ins: GetParametersIns) -> GetParametersRes: parameters=Parameters(tensor_type="", tensors=[]), ) - def _local_boost(self): + def _local_boost(self, bst_input): # Update trees based on local training data. - for i in range(num_local_round): - self.bst.update(train_dmatrix, self.bst.num_boosted_rounds()) + for i in range(self.num_local_round): + bst_input.update(self.train_dmatrix, bst_input.num_boosted_rounds()) - # Extract the last N=num_local_round trees for sever aggregation - bst = self.bst[ - self.bst.num_boosted_rounds() - - num_local_round : self.bst.num_boosted_rounds() + # Bagging: extract the last N=num_local_round trees for sever aggregation + bst = bst_input[ + bst_input.num_boosted_rounds() + - self.num_local_round : bst_input.num_boosted_rounds() ] return bst def fit(self, ins: FitIns) -> FitRes: - if not self.bst: + global_round = int(ins.config["global_round"]) + if global_round == 1: # First round local training - log(INFO, "Start training at round 1") bst = xgb.train( - params, - train_dmatrix, - num_boost_round=num_local_round, - evals=[(valid_dmatrix, "validate"), (train_dmatrix, "train")], + self.params, + self.train_dmatrix, + num_boost_round=self.num_local_round, + evals=[(self.valid_dmatrix, "validate"), (self.train_dmatrix, "train")], ) - self.config = bst.save_config() - self.bst = bst else: + bst = xgb.Booster(params=self.params) for item in ins.parameters.tensors: global_model = bytearray(item) # Load global model into booster - self.bst.load_model(global_model) - self.bst.load_config(self.config) + bst.load_model(global_model) - bst = self._local_boost() + # Local training + bst = self._local_boost(bst) + # Save model local_model = bst.save_raw("json") local_model_bytes = bytes(local_model) @@ -150,27 +162,47 @@ def fit(self, ins: FitIns) -> FitRes: message="OK", ), parameters=Parameters(tensor_type="", tensors=[local_model_bytes]), - num_examples=num_train, + num_examples=self.num_train, metrics={}, ) def evaluate(self, ins: EvaluateIns) -> EvaluateRes: - eval_results = self.bst.eval_set( - evals=[(valid_dmatrix, "valid")], - iteration=self.bst.num_boosted_rounds() - 1, + # Load global model + bst = xgb.Booster(params=self.params) + for para in ins.parameters.tensors: + para_b = bytearray(para) + bst.load_model(para_b) + + # Run evaluation + eval_results = bst.eval_set( + evals=[(self.valid_dmatrix, "valid")], + iteration=bst.num_boosted_rounds() - 1, ) auc = round(float(eval_results.split("\t")[1].split(":")[1]), 4) + global_round = ins.config["global_round"] + log(INFO, f"AUC = {auc} at round {global_round}") + return EvaluateRes( status=Status( code=Code.OK, message="OK", ), loss=0.0, - num_examples=num_val, + num_examples=self.num_val, metrics={"AUC": auc}, ) # Start Flower client -fl.client.start_client(server_address="127.0.0.1:8080", client=XgbClient().to_client()) +fl.client.start_client( + server_address="127.0.0.1:8080", + client=XgbClient( + train_dmatrix, + valid_dmatrix, + num_train, + num_val, + num_local_round, + params, + ).to_client(), +) diff --git a/examples/xgboost-quickstart/pyproject.toml b/examples/xgboost-quickstart/pyproject.toml index c16542ea7ffe..f1e451fe779a 100644 --- a/examples/xgboost-quickstart/pyproject.toml +++ b/examples/xgboost-quickstart/pyproject.toml @@ -1,15 +1,19 @@ [build-system] -requires = ["poetry-core>=1.4.0"] -build-backend = "poetry.core.masonry.api" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry] -name = "xgboost-quickstart" +[project] +name = "quickstart-xgboost" version = "0.1.0" -description = "Federated XGBoost with Flower (quickstart)" -authors = ["The Flower Authors "] +description = "XGBoost Federated Learning Quickstart with Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr>=1.8.0,<2.0", + "flwr-datasets>=0.1.0,<1.0.0", + "xgboost>=2.0.0,<3.0.0", +] -[tool.poetry.dependencies] -python = ">=3.8,<3.11" -flwr = ">=1.7.0,<2.0" -flwr-datasets = ">=0.0.1,<1.0.0" -xgboost = ">=2.0.0,<3.0.0" +[tool.hatch.build.targets.wheel] +packages = ["."] diff --git a/examples/xgboost-quickstart/requirements.txt b/examples/xgboost-quickstart/requirements.txt deleted file mode 100644 index c6949e0651c5..000000000000 --- a/examples/xgboost-quickstart/requirements.txt +++ /dev/null @@ -1,3 +0,0 @@ -flwr>=1.7.0, <2.0 -flwr-datasets>=0.0.1, <1.0.0 -xgboost>=2.0.0, <3.0.0 diff --git a/examples/xgboost-quickstart/server.py b/examples/xgboost-quickstart/server.py index b45a375ce94f..e9239fde696c 100644 --- a/examples/xgboost-quickstart/server.py +++ b/examples/xgboost-quickstart/server.py @@ -1,3 +1,4 @@ +from typing import Dict import flwr as fl from flwr.server.strategy import FedXgbBagging @@ -19,6 +20,14 @@ def evaluate_metrics_aggregation(eval_metrics): return metrics_aggregated +def config_func(rnd: int) -> Dict[str, str]: + """Return a configuration with global epochs.""" + config = { + "global_round": str(rnd), + } + return config + + # Define strategy strategy = FedXgbBagging( fraction_fit=(float(num_clients_per_round) / pool_size), @@ -27,6 +36,8 @@ def evaluate_metrics_aggregation(eval_metrics): min_evaluate_clients=num_evaluate_clients, fraction_evaluate=1.0, evaluate_metrics_aggregation_fn=evaluate_metrics_aggregation, + on_evaluate_config_fn=config_func, + on_fit_config_fn=config_func, ) # Start Flower server From 568ab1e8329e1b80c635abb218fd8dcbdc60d21c Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 30 May 2024 16:51:53 +0100 Subject: [PATCH 033/124] refactor(framework) Add `adapter` argument to `grpc_request_response` (#3534) --- src/py/flwr/client/grpc_rere_client/connection.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/py/flwr/client/grpc_rere_client/connection.py b/src/py/flwr/client/grpc_rere_client/connection.py index 3778fd4061f9..8ef8e7ebf62a 100644 --- a/src/py/flwr/client/grpc_rere_client/connection.py +++ b/src/py/flwr/client/grpc_rere_client/connection.py @@ -21,7 +21,7 @@ from copy import copy from logging import DEBUG, ERROR from pathlib import Path -from typing import Callable, Iterator, Optional, Sequence, Tuple, Union, cast +from typing import Callable, Iterator, Optional, Sequence, Tuple, Type, Union, cast import grpc from cryptography.hazmat.primitives.asymmetric import ec @@ -73,6 +73,7 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915 authentication_keys: Optional[ Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey] ] = None, + adapter_cls: Optional[Type[FleetStub]] = None, ) -> Iterator[ Tuple[ Callable[[], Optional[Message]], @@ -133,7 +134,9 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915 channel.subscribe(on_channel_state_change) # Shared variables for inner functions - stub = FleetStub(channel) + if adapter_cls is None: + adapter_cls = FleetStub + stub = adapter_cls(channel) metadata: Optional[Metadata] = None node: Optional[Node] = None ping_thread: Optional[threading.Thread] = None From 77ed30b69a15723c60e004ffd4ee2c0462a35cf6 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 30 May 2024 16:57:33 +0100 Subject: [PATCH 034/124] feat(framework) Add GrpcAdapter proto (#3532) --- src/proto/flwr/proto/grpcadapter.proto | 28 +++++++++ src/py/flwr/proto/grpcadapter_pb2.py | 32 +++++++++++ src/py/flwr/proto/grpcadapter_pb2.pyi | 43 ++++++++++++++ src/py/flwr/proto/grpcadapter_pb2_grpc.py | 66 ++++++++++++++++++++++ src/py/flwr/proto/grpcadapter_pb2_grpc.pyi | 24 ++++++++ src/py/flwr_tool/protoc_test.py | 2 +- 6 files changed, 194 insertions(+), 1 deletion(-) create mode 100644 src/proto/flwr/proto/grpcadapter.proto create mode 100644 src/py/flwr/proto/grpcadapter_pb2.py create mode 100644 src/py/flwr/proto/grpcadapter_pb2.pyi create mode 100644 src/py/flwr/proto/grpcadapter_pb2_grpc.py create mode 100644 src/py/flwr/proto/grpcadapter_pb2_grpc.pyi diff --git a/src/proto/flwr/proto/grpcadapter.proto b/src/proto/flwr/proto/grpcadapter.proto new file mode 100644 index 000000000000..826efec4315e --- /dev/null +++ b/src/proto/flwr/proto/grpcadapter.proto @@ -0,0 +1,28 @@ +// Copyright 2024 Flower Labs GmbH. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================== + +syntax = "proto3"; + +package flwr.proto; + +service GrpcAdapter { + rpc SendReceive(MessageContainer) returns (MessageContainer) {} +} + +message MessageContainer { + map metadata = 1; + string grpc_message_name = 2; + bytes grpc_message_content = 3; +} diff --git a/src/py/flwr/proto/grpcadapter_pb2.py b/src/py/flwr/proto/grpcadapter_pb2.py new file mode 100644 index 000000000000..7c0374736850 --- /dev/null +++ b/src/py/flwr/proto/grpcadapter_pb2.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: flwr/proto/grpcadapter.proto +# Protobuf Python Version: 4.25.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/grpcadapter.proto\x12\nflwr.proto\"\xba\x01\n\x10MessageContainer\x12<\n\x08metadata\x18\x01 \x03(\x0b\x32*.flwr.proto.MessageContainer.MetadataEntry\x12\x19\n\x11grpc_message_name\x18\x02 \x01(\t\x12\x1c\n\x14grpc_message_content\x18\x03 \x01(\x0c\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\x32Z\n\x0bGrpcAdapter\x12K\n\x0bSendReceive\x12\x1c.flwr.proto.MessageContainer\x1a\x1c.flwr.proto.MessageContainer\"\x00\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.grpcadapter_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_MESSAGECONTAINER_METADATAENTRY']._options = None + _globals['_MESSAGECONTAINER_METADATAENTRY']._serialized_options = b'8\001' + _globals['_MESSAGECONTAINER']._serialized_start=45 + _globals['_MESSAGECONTAINER']._serialized_end=231 + _globals['_MESSAGECONTAINER_METADATAENTRY']._serialized_start=184 + _globals['_MESSAGECONTAINER_METADATAENTRY']._serialized_end=231 + _globals['_GRPCADAPTER']._serialized_start=233 + _globals['_GRPCADAPTER']._serialized_end=323 +# @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/grpcadapter_pb2.pyi b/src/py/flwr/proto/grpcadapter_pb2.pyi new file mode 100644 index 000000000000..d5f89ac27c4a --- /dev/null +++ b/src/py/flwr/proto/grpcadapter_pb2.pyi @@ -0,0 +1,43 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.internal.containers +import google.protobuf.message +import typing +import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class MessageContainer(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + class MetadataEntry(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + KEY_FIELD_NUMBER: builtins.int + VALUE_FIELD_NUMBER: builtins.int + key: typing.Text + value: builtins.bytes + def __init__(self, + *, + key: typing.Text = ..., + value: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ... + + METADATA_FIELD_NUMBER: builtins.int + GRPC_MESSAGE_NAME_FIELD_NUMBER: builtins.int + GRPC_MESSAGE_CONTENT_FIELD_NUMBER: builtins.int + @property + def metadata(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, builtins.bytes]: ... + grpc_message_name: typing.Text + grpc_message_content: builtins.bytes + def __init__(self, + *, + metadata: typing.Optional[typing.Mapping[typing.Text, builtins.bytes]] = ..., + grpc_message_name: typing.Text = ..., + grpc_message_content: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["grpc_message_content",b"grpc_message_content","grpc_message_name",b"grpc_message_name","metadata",b"metadata"]) -> None: ... +global___MessageContainer = MessageContainer diff --git a/src/py/flwr/proto/grpcadapter_pb2_grpc.py b/src/py/flwr/proto/grpcadapter_pb2_grpc.py new file mode 100644 index 000000000000..831f99d7b237 --- /dev/null +++ b/src/py/flwr/proto/grpcadapter_pb2_grpc.py @@ -0,0 +1,66 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from flwr.proto import grpcadapter_pb2 as flwr_dot_proto_dot_grpcadapter__pb2 + + +class GrpcAdapterStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SendReceive = channel.unary_unary( + '/flwr.proto.GrpcAdapter/SendReceive', + request_serializer=flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.SerializeToString, + response_deserializer=flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.FromString, + ) + + +class GrpcAdapterServicer(object): + """Missing associated documentation comment in .proto file.""" + + def SendReceive(self, request, context): + """Missing associated documentation comment in .proto file.""" + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GrpcAdapterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SendReceive': grpc.unary_unary_rpc_method_handler( + servicer.SendReceive, + request_deserializer=flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.FromString, + response_serializer=flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'flwr.proto.GrpcAdapter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class GrpcAdapter(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def SendReceive(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/flwr.proto.GrpcAdapter/SendReceive', + flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.SerializeToString, + flwr_dot_proto_dot_grpcadapter__pb2.MessageContainer.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi b/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi new file mode 100644 index 000000000000..640f983e6e04 --- /dev/null +++ b/src/py/flwr/proto/grpcadapter_pb2_grpc.pyi @@ -0,0 +1,24 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import abc +import flwr.proto.grpcadapter_pb2 +import grpc + +class GrpcAdapterStub: + def __init__(self, channel: grpc.Channel) -> None: ... + SendReceive: grpc.UnaryUnaryMultiCallable[ + flwr.proto.grpcadapter_pb2.MessageContainer, + flwr.proto.grpcadapter_pb2.MessageContainer] + + +class GrpcAdapterServicer(metaclass=abc.ABCMeta): + @abc.abstractmethod + def SendReceive(self, + request: flwr.proto.grpcadapter_pb2.MessageContainer, + context: grpc.ServicerContext, + ) -> flwr.proto.grpcadapter_pb2.MessageContainer: ... + + +def add_GrpcAdapterServicer_to_server(servicer: GrpcAdapterServicer, server: grpc.Server) -> None: ... diff --git a/src/py/flwr_tool/protoc_test.py b/src/py/flwr_tool/protoc_test.py index 2d48582eb441..8dcf4c6474d6 100644 --- a/src/py/flwr_tool/protoc_test.py +++ b/src/py/flwr_tool/protoc_test.py @@ -28,4 +28,4 @@ def test_directories() -> None: def test_proto_file_count() -> None: """Test if the correct number of proto files were captured by the glob.""" - assert len(PROTO_FILES) == 7 + assert len(PROTO_FILES) == 8 From 3d17a5ebffe969765581ab3417a1c15b77f8c138 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 30 May 2024 17:15:30 +0100 Subject: [PATCH 035/124] fix(framework) Fix the metadata type in `MessageContainer` (#3535) --- src/proto/flwr/proto/grpcadapter.proto | 2 +- src/py/flwr/proto/grpcadapter_pb2.py | 2 +- src/py/flwr/proto/grpcadapter_pb2.pyi | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/proto/flwr/proto/grpcadapter.proto b/src/proto/flwr/proto/grpcadapter.proto index 826efec4315e..acf9a9d3d94f 100644 --- a/src/proto/flwr/proto/grpcadapter.proto +++ b/src/proto/flwr/proto/grpcadapter.proto @@ -22,7 +22,7 @@ service GrpcAdapter { } message MessageContainer { - map metadata = 1; + map metadata = 1; string grpc_message_name = 2; bytes grpc_message_content = 3; } diff --git a/src/py/flwr/proto/grpcadapter_pb2.py b/src/py/flwr/proto/grpcadapter_pb2.py index 7c0374736850..2eff4bb78e47 100644 --- a/src/py/flwr/proto/grpcadapter_pb2.py +++ b/src/py/flwr/proto/grpcadapter_pb2.py @@ -14,7 +14,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/grpcadapter.proto\x12\nflwr.proto\"\xba\x01\n\x10MessageContainer\x12<\n\x08metadata\x18\x01 \x03(\x0b\x32*.flwr.proto.MessageContainer.MetadataEntry\x12\x19\n\x11grpc_message_name\x18\x02 \x01(\t\x12\x1c\n\x14grpc_message_content\x18\x03 \x01(\x0c\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\x0c:\x02\x38\x01\x32Z\n\x0bGrpcAdapter\x12K\n\x0bSendReceive\x12\x1c.flwr.proto.MessageContainer\x1a\x1c.flwr.proto.MessageContainer\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1c\x66lwr/proto/grpcadapter.proto\x12\nflwr.proto\"\xba\x01\n\x10MessageContainer\x12<\n\x08metadata\x18\x01 \x03(\x0b\x32*.flwr.proto.MessageContainer.MetadataEntry\x12\x19\n\x11grpc_message_name\x18\x02 \x01(\t\x12\x1c\n\x14grpc_message_content\x18\x03 \x01(\x0c\x1a/\n\rMetadataEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\x32Z\n\x0bGrpcAdapter\x12K\n\x0bSendReceive\x12\x1c.flwr.proto.MessageContainer\x1a\x1c.flwr.proto.MessageContainer\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) diff --git a/src/py/flwr/proto/grpcadapter_pb2.pyi b/src/py/flwr/proto/grpcadapter_pb2.pyi index d5f89ac27c4a..35889b30d2b6 100644 --- a/src/py/flwr/proto/grpcadapter_pb2.pyi +++ b/src/py/flwr/proto/grpcadapter_pb2.pyi @@ -18,11 +18,11 @@ class MessageContainer(google.protobuf.message.Message): KEY_FIELD_NUMBER: builtins.int VALUE_FIELD_NUMBER: builtins.int key: typing.Text - value: builtins.bytes + value: typing.Text def __init__(self, *, key: typing.Text = ..., - value: builtins.bytes = ..., + value: typing.Text = ..., ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["key",b"key","value",b"value"]) -> None: ... @@ -30,12 +30,12 @@ class MessageContainer(google.protobuf.message.Message): GRPC_MESSAGE_NAME_FIELD_NUMBER: builtins.int GRPC_MESSAGE_CONTENT_FIELD_NUMBER: builtins.int @property - def metadata(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, builtins.bytes]: ... + def metadata(self) -> google.protobuf.internal.containers.ScalarMap[typing.Text, typing.Text]: ... grpc_message_name: typing.Text grpc_message_content: builtins.bytes def __init__(self, *, - metadata: typing.Optional[typing.Mapping[typing.Text, builtins.bytes]] = ..., + metadata: typing.Optional[typing.Mapping[typing.Text, typing.Text]] = ..., grpc_message_name: typing.Text = ..., grpc_message_content: builtins.bytes = ..., ) -> None: ... From 4dc80062c5b810de78279a88f94884b460a38fee Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 31 May 2024 12:51:12 +0200 Subject: [PATCH 036/124] docs(framework:skip) Update the Docker contributor page (#3523) --------- Signed-off-by: Robert Steiner --- ...contributor-how-to-build-docker-images.rst | 95 +++++++++---------- 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/doc/source/contributor-how-to-build-docker-images.rst b/doc/source/contributor-how-to-build-docker-images.rst index b97ee2c434ce..2efc739f54f0 100644 --- a/doc/source/contributor-how-to-build-docker-images.rst +++ b/doc/source/contributor-how-to-build-docker-images.rst @@ -2,9 +2,10 @@ How to build Docker Flower images locally ========================================= Flower provides pre-made docker images on `Docker Hub `_ -that include all necessary dependencies for running the SuperLink. You can also build your own custom -docker images from scratch with a different version of Python or Ubuntu if that is what you need. -In this guide, we will explain what images exist and how to build them locally. +that include all necessary dependencies for running the SuperLink, SuperNode or ServerApp. +You can also build your own custom docker images from scratch with a different version of Python +or Linux distribution (Ubuntu/Alpine) if that is what you need. In this guide, we will explain what +images exist and how to build them locally. Before we can start, we need to meet a few prerequisites in our local development environment. @@ -20,19 +21,15 @@ Before we can start, we need to meet a few prerequisites in our local developmen :doc:`Run Flower using Docker ` which covers this step in more detail. -Currently, Flower provides two images, a ``base`` image and a ``superlink`` image. The base image, -as the name suggests, contains basic dependencies that the SuperLink needs. -This includes system dependencies, Python and Python tools. The SuperLink image is -based on the base image, but it additionally installs the SuperLink using ``pip``. The build instructions that assemble the images are located in the respective Dockerfiles. You can find them in the subdirectories of ``src/docker``. -Both, base and SuperLink image are configured via build arguments. Through build arguments, we can make -our build more flexible. For example, in the base image, we can specify the version of Python to -install using the ``PYTHON_VERSION`` build argument. Some of the build arguments have default -values, others must be specified when building the image. All available build arguments for each -image are listed in one of the tables below. +Flower Docker images are configured via build arguments. Through build arguments, we can make the +creation of images more flexible. For example, in the base image, we can specify the version of +Python to install using the ``PYTHON_VERSION`` build argument. Some of the build arguments have +default values, others must be specified when building the image. All available build arguments for +each image are listed in one of the tables below. Building the base image ----------------------- @@ -45,10 +42,18 @@ Building the base image - Description - Required - Example + * - ``DISTRO`` + - The Linux distribution to use as the base image. + - No + - ``ubuntu`` + * - ``DISTRO_VERSION`` + - Version of the Linux distribution. + - No + - ``22.04`` * - ``PYTHON_VERSION`` - Version of ``python`` to be installed. - - Yes - - ``3.11`` + - No + - ``3.11`` or ``3.11.1`` * - ``PIP_VERSION`` - Version of ``pip`` to be installed. - Yes @@ -57,18 +62,25 @@ Building the base image - Version of ``setuptools`` to be installed. - Yes - ``69.0.2`` - * - ``UBUNTU_VERSION`` - - Version of the official Ubuntu Docker image. - - Defaults to ``22.04``. - - + * - ``FLWR_VERSION`` + - Version of Flower to be installed. + - Yes + - ``1.8.0`` + * - ``FLWR_PACKAGE`` + - The Flower package to be installed. + - No + - ``flwr`` or ``flwr-nightly`` + -The following example creates a base image with Python 3.11.0, pip 23.0.1 and setuptools 69.0.2: +The following example creates a base Ubuntu/Alpine image with Python 3.11.0, pip 23.0.1, +setuptools 69.0.2 and Flower 1.8.0: .. code-block:: bash - $ cd src/docker/base/ubuntu + $ cd src/docker/base/ $ docker build \ --build-arg PYTHON_VERSION=3.11.0 \ + --build-arg FLWR_VERSION=1.8.0 \ --build-arg PIP_VERSION=23.0.1 \ --build-arg SETUPTOOLS_VERSION=69.0.2 \ -t flwr_base:0.1.0 . @@ -76,8 +88,8 @@ The following example creates a base image with Python 3.11.0, pip 23.0.1 and se The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the build arguments as well as the name and tag can be adapted to your needs. These values serve as examples only. -Building the SuperLink image ----------------------------- +Building the SuperLink/SuperNode or ServerApp image +--------------------------------------------------- .. list-table:: :widths: 25 45 15 15 @@ -89,50 +101,33 @@ Building the SuperLink image - Example * - ``BASE_REPOSITORY`` - The repository name of the base image. - - Defaults to ``flwr/base``. - - - * - ``PYTHON_VERSION`` - - The Python version of the base image. - - Defaults to ``py3.11``. - - - * - ``UBUNTU_VERSION`` - - The Ubuntu version of the base image. - - Defaults to ``ubuntu22.04``. - - - * - ``FLWR_PACKAGE`` - - The PyPI package to install. - - Defaults to ``flwr``. - - - * - ``FLWR_VERSION`` - - Version of Flower to be installed. + - No + - ``flwr/base`` + * - ``BASE_IMAGE`` + - The Tag of the Flower base image. - Yes - - ``1.8.0`` + - ``1.8.0-py3.10-ubuntu22.04`` - -The following example creates a SuperLink image with the official Flower base image -py3.11-ubuntu22.04 and Flower 1.8.0: +The following example creates a SuperLink/SuperNode or ServerApp image with the official Flower +base image: .. code-block:: bash - $ cd src/docker/superlink/ + $ cd src/docker// $ docker build \ - --build-arg FLWR_VERSION=1.8.0 \ + --build-arg BASE_IMAGE=-py- \ -t flwr_superlink:0.1.0 . -The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember that the build arguments as -well as the name and tag can be adapted to your needs. These values serve as examples only. If you want to use your own base image instead of the official Flower base image, all you need to do -is set the ``BASE_REPOSITORY``, ``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments. +is set the ``BASE_REPOSITORY`` build argument. .. code-block:: bash $ cd src/docker/superlink/ $ docker build \ --build-arg BASE_REPOSITORY=flwr_base \ - --build-arg PYTHON_VERSION=3.11 \ - --build-arg UBUNTU_VERSION=ubuntu22.04 \ - --build-arg FLWR_VERSION=1.8.0 \ + --build-arg BASE_IMAGE=0.1.0 -t flwr_superlink:0.1.0 . After creating the image, we can test whether the image is working: From 9b5889ee637545ba64c79ca997ccdddb4d6497ce Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 31 May 2024 13:26:02 +0200 Subject: [PATCH 037/124] fix(framework:skip) Remove pyenv in Dockerfile (#3533) Signed-off-by: Robert Steiner --- e2e/docker/supernode.Dockerfile | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/e2e/docker/supernode.Dockerfile b/e2e/docker/supernode.Dockerfile index 2770315a1b54..c94c571cebb5 100644 --- a/e2e/docker/supernode.Dockerfile +++ b/e2e/docker/supernode.Dockerfile @@ -2,8 +2,7 @@ FROM flwr/supernode:nightly WORKDIR /app COPY pyproject.toml ./ -RUN python -m pip install -U --no-cache-dir . \ - && pyenv rehash +RUN python -m pip install -U --no-cache-dir . COPY client.py ./ ENTRYPOINT [ "flower-client-app", "client:app" ] From e944ac0087dd2c804d1b175835cbd19d4d9610ad Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 31 May 2024 16:54:28 +0200 Subject: [PATCH 038/124] docs(framework:skip) Add details about the ownership of mounted volumes (#3530) Signed-off-by: Robert Steiner Co-authored-by: Danny --- doc/source/how-to-run-flower-using-docker.rst | 49 +++++++++++++------ src/docker/base/alpine/Dockerfile | 12 +++-- src/docker/base/ubuntu/Dockerfile | 6 ++- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index 09bd952daafc..375857b85b71 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -72,19 +72,27 @@ Mounting a volume to store the state on the host system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you want to persist the state of the SuperLink on your host system, all you need to do is specify -a path where you want to save the file on your host system and a name for the database file. In the -example below, we tell Docker via the flag ``--volume`` to mount the user's home directory -(``~/`` on your host) into the ``/app/`` directory of the container. Furthermore, we use the -flag ``--database`` to specify the name of the database file. +a directory where you want to save the file on your host system and a name for the database file. By +default, the SuperLink container runs with a non-root user called ``app`` with the user ID +``49999``. It is recommended to create new directory and change the user ID of the directory to +``49999`` to ensure the mounted directory has the proper permissions. If you later want to delete +the directory, you can change the user ID back to the current user ID by running +``sudo chown -R $USER:$(id -gn) state``. + +In the example below, we create a new directory, change the user ID and tell Docker via the flag +``--volume`` to mount the local ``state`` directory into the ``/app/state`` directory of the +container. Furthermore, we use the flag ``--database`` to specify the name of the database file. .. code-block:: bash + $ mkdir state + $ sudo chmod -R 49999:49999 state $ docker run --rm \ - -p 9091:9091 -p 9092:9092 --volume ~/:/app/ flwr/superlink:1.8.0 \ + -p 9091:9091 -p 9092:9092 --volume ./state/:/app/state flwr/superlink:1.8.0 \ --insecure \ --database state.db -As soon as the SuperLink starts, the file ``state.db`` is created in the user's home directory on +As soon as the SuperLink starts, the file ``state.db`` is created in the ``state`` directory on your host system. If the file already exists, the SuperLink tries to restore the state from the file. To start the SuperLink with an empty database, simply remove the ``state.db`` file. @@ -100,17 +108,27 @@ PEM-encoded certificate chain. page contains a section that will guide you through the process. Assuming all files we need are in the local ``certificates`` directory, we can use the flag -``--volume`` to mount the local directory into the ``/app/`` directory of the container. This allows -the SuperLink to access the files within the container. Finally, we pass the names of the -certificates to the SuperLink with the ``--root-certificates`` flag. +``--volume`` to mount the local directory into the ``/app/certificates/`` directory of the container. +This allows the SuperLink to access the files within the container. The ``ro`` stands for +``read-only``. Docker volumes default to ``read-write``; that option tells Docker to make the volume +``read-only`` instead. Finally, we pass the names of the certificates and key file to the SuperLink +with the ``--ssl-ca-certfile``, ``--ssl-certfile`` and ``--ssl-keyfile`` flag. .. code-block:: bash $ docker run --rm \ - -p 9091:9091 -p 9092:9092 --volume ./certificates/:/app/ flwr/superlink:1.9.0 \ - --ssl-ca-certfile ca.crt \ - --ssl-certfile server.pem \ - --ssl-keyfile server.key + -p 9091:9091 -p 9092:9092 \ + --volume ./certificates/:/app/certificates/:ro flwr/superlink:nightly \ + --ssl-ca-certfile certificates/ca.crt \ + --ssl-certfile certificates/server.pem \ + --ssl-keyfile certificates/server.key + +.. note:: + + Because Flower containers, by default, run with a non-root user ``app``, the mounted files and + directories must have the proper permissions for the user ID ``49999``. For example, to change the + user ID of all files in the ``certificates/`` directory, you can run + ``sudo chown -R 49999:49999 certificates/*``. Flower SuperNode ---------------- @@ -225,7 +243,7 @@ Now that we have built the SuperNode image, we can finally run it. .. code-block:: bash - $ docker run --rm flwr_supernode:0.0.1 client:app \ + $ docker run --rm flwr_supernode:0.0.1 \ --insecure \ --server 192.168.1.100:9092 @@ -381,8 +399,7 @@ To enable SSL, we will need to mount a PEM-encoded root certificate into your Se Assuming the certificate already exists locally, we can use the flag ``--volume`` to mount the local certificate into the container's ``/app/`` directory. This allows the ServerApp to access the -certificate within the container. Use the ``--ssl-ca-certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` -flags when starting the container. +certificate within the container. Use the ``--root-certificates`` flags when starting the container. .. code-block:: bash diff --git a/src/docker/base/alpine/Dockerfile b/src/docker/base/alpine/Dockerfile index 4d7c95721dc3..04864b525e2e 100644 --- a/src/docker/base/alpine/Dockerfile +++ b/src/docker/base/alpine/Dockerfile @@ -34,10 +34,10 @@ RUN apk add --no-cache \ g++ \ libffi-dev \ # create virtual env - && python -m venv /app/venv + && python -m venv /python/venv # Make sure we use the virtualenv -ENV PATH=/app/venv/bin:$PATH +ENV PATH=/python/venv/bin:$PATH # Install specific version of pip, setuptools and flwr ARG PIP_VERSION @@ -59,12 +59,14 @@ RUN apk add --no-cache \ --no-create-home \ --disabled-password \ --gecos "" \ - --uid 49999 app + --uid 49999 app \ + && mkdir -p /app \ + && chown -R app:app /app -COPY --from=compile --chown=app:app /app/venv /app/venv +COPY --from=compile --chown=app:app /python/venv /python/venv # Make sure we use the virtualenv -ENV PATH=/app/venv/bin:$PATH \ +ENV PATH=/python/venv/bin:$PATH \ # Send stdout and stderr stream directly to the terminal. Ensures that no # output is retained in a buffer if the application crashes. PYTHONUNBUFFERED=1 \ diff --git a/src/docker/base/ubuntu/Dockerfile b/src/docker/base/ubuntu/Dockerfile index 6f2585d4570f..4aeddc3f8d8d 100644 --- a/src/docker/base/ubuntu/Dockerfile +++ b/src/docker/base/ubuntu/Dockerfile @@ -74,8 +74,8 @@ ENV PATH=/usr/local/bin/python/bin:$PATH \ # Use a virtual environment to ensure that Python packages are installed in the same location # regardless of whether the subsequent image build is run with the app or the root user -RUN python -m venv /app/venv -ENV PATH=/app/venv/bin:$PATH +RUN python -m venv /python/venv +ENV PATH=/python/venv/bin:$PATH ARG PIP_VERSION ARG SETUPTOOLS_VERSION @@ -92,6 +92,8 @@ RUN adduser \ --disabled-password \ --gecos "" \ --uid 49999 app \ + && mkdir -p /app \ + && chown -R app:app /python \ && chown -R app:app /app WORKDIR /app From 39f995c5111922a725f34860bca2dc31aa6731e6 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 31 May 2024 17:59:59 +0200 Subject: [PATCH 039/124] docs(framework:skip) Add how to release the docker images (#3539) Signed-off-by: Robert Steiner --- doc/source/_static/docker-ci-release.png | Bin 0 -> 119422 bytes .../contributor-how-to-release-flower.rst | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 doc/source/_static/docker-ci-release.png diff --git a/doc/source/_static/docker-ci-release.png b/doc/source/_static/docker-ci-release.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec97ce9fb06405eb39bffb43c51c383140edcb2 GIT binary patch literal 119422 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

J{3tgpyKvyFgj;d+ks8sx!Cd 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 a`36QpBBpX07uWf~58{-yY5B>EasLEu_-V`l literal 0 HcmV?d00001 diff --git a/doc/source/contributor-how-to-release-flower.rst b/doc/source/contributor-how-to-release-flower.rst index 4853d87bc4c1..fc4c2d436b05 100644 --- a/doc/source/contributor-how-to-release-flower.rst +++ b/doc/source/contributor-how-to-release-flower.rst @@ -12,6 +12,24 @@ The version number of a release is stated in ``pyproject.toml``. To release a ne 2. Once the changelog has been updated with all the changes, run ``./dev/prepare-release-changelog.sh v``, where ```` is the version stated in ``pyproject.toml`` (notice the ``v`` added before it). This will replace the ``Unreleased`` header of the changelog by the version and current date, and it will add a thanking message for the contributors. Open a pull request with those changes. 3. Once the pull request is merged, tag the release commit with the version number as soon as the PR is merged: ``git tag v`` (notice the ``v`` added before the version number), then ``git push --tags``. This will create a draft release on GitHub containing the correct artifacts and the relevant part of the changelog. 4. Check the draft release on GitHub, and if everything is good, publish it. +5. Trigger the CI for building the Docker images. + +To trigger the workflow, a collaborator must create a ``workflow_dispatch`` event in the +GitHub CI. This can be done either through the UI or via the GitHub CLI. The event requires only one +input, the Flower version, to be released. + +**Via the UI** + +1. Go to the ``Build docker images`` workflow `page `_. +2. Click on the ``Run workflow`` button and type the new version of Flower in the ``Version of Flower`` input field. +3. Click on the **green** ``Run workflow`` button. + +.. image:: _static/docker-ci-release.png + +**Via the GitHub CI** + +1. Make sure you are logged in via ``gh auth login`` and that the current working directory is the root of the Flower repository. +2. Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-version=``. After the release ----------------- From 72244a874a6c24899af14cdf5c541c8c9c326642 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Tue, 4 Jun 2024 15:40:30 +0200 Subject: [PATCH 040/124] docs(framework:skip) Fix typo in docstrings (#3545) --- src/py/flwr/client/client_app.py | 2 +- src/py/flwr/server/server_app.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/py/flwr/client/client_app.py b/src/py/flwr/client/client_app.py index c9d337700147..82539834eaad 100644 --- a/src/py/flwr/client/client_app.py +++ b/src/py/flwr/client/client_app.py @@ -221,7 +221,7 @@ def _registration_error(fn_name: str) -> ValueError: >>> def client_fn(cid) -> Client: >>> return FlowerClient().to_client() >>> - >>> app = ClientApp() + >>> app = ClientApp( >>> client_fn=client_fn, >>> ) diff --git a/src/py/flwr/server/server_app.py b/src/py/flwr/server/server_app.py index ea2eb3fd1a69..43b3bcce3f36 100644 --- a/src/py/flwr/server/server_app.py +++ b/src/py/flwr/server/server_app.py @@ -39,7 +39,7 @@ class ServerApp: >>> server_config = ServerConfig(num_rounds=3) >>> strategy = FedAvg() >>> - >>> app = ServerApp() + >>> app = ServerApp( >>> server_config=server_config, >>> strategy=strategy, >>> ) @@ -106,7 +106,7 @@ def main_decorator(main_fn: ServerAppCallable) -> ServerAppCallable: >>> server_config = ServerConfig(num_rounds=3) >>> strategy = FedAvg() >>> - >>> app = ServerApp() + >>> app = ServerApp( >>> server_config=server_config, >>> strategy=strategy, >>> ) From 097b803394ce761a0c5daa1eff5e71b06e421b25 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Thu, 6 Jun 2024 12:22:58 +0200 Subject: [PATCH 041/124] feat(datasets) Add label distribution visualization (#3451) Co-authored-by: jafermarq --- datasets/flwr_datasets/__init__.py | 3 + datasets/flwr_datasets/metrics/__init__.py | 23 ++ datasets/flwr_datasets/metrics/utils.py | 78 +++++ datasets/flwr_datasets/metrics/utils_test.py | 89 ++++++ .../flwr_datasets/visualization/__init__.py | 24 ++ .../flwr_datasets/visualization/bar_plot.py | 143 +++++++++ .../comparison_label_distribution.py | 237 +++++++++++++++ .../flwr_datasets/visualization/constants.py | 19 ++ .../visualization/heatmap_plot.py | 106 +++++++ .../visualization/label_distribution.py | 279 ++++++++++++++++++ datasets/flwr_datasets/visualization/utils.py | 36 +++ datasets/pyproject.toml | 2 + 12 files changed, 1039 insertions(+) create mode 100644 datasets/flwr_datasets/metrics/__init__.py create mode 100644 datasets/flwr_datasets/metrics/utils.py create mode 100644 datasets/flwr_datasets/metrics/utils_test.py create mode 100644 datasets/flwr_datasets/visualization/__init__.py create mode 100644 datasets/flwr_datasets/visualization/bar_plot.py create mode 100644 datasets/flwr_datasets/visualization/comparison_label_distribution.py create mode 100644 datasets/flwr_datasets/visualization/constants.py create mode 100644 datasets/flwr_datasets/visualization/heatmap_plot.py create mode 100644 datasets/flwr_datasets/visualization/label_distribution.py create mode 100644 datasets/flwr_datasets/visualization/utils.py diff --git a/datasets/flwr_datasets/__init__.py b/datasets/flwr_datasets/__init__.py index 2d6ecb414498..d084780102ce 100644 --- a/datasets/flwr_datasets/__init__.py +++ b/datasets/flwr_datasets/__init__.py @@ -17,12 +17,15 @@ from flwr_datasets import partitioner, preprocessor from flwr_datasets import utils as utils +from flwr_datasets import visualization from flwr_datasets.common.version import package_version as _package_version from flwr_datasets.federated_dataset import FederatedDataset __all__ = [ "FederatedDataset", "partitioner", + "metrics", + "visualization", "preprocessor", "utils", ] diff --git a/datasets/flwr_datasets/metrics/__init__.py b/datasets/flwr_datasets/metrics/__init__.py new file mode 100644 index 000000000000..807860b5b7b8 --- /dev/null +++ b/datasets/flwr_datasets/metrics/__init__.py @@ -0,0 +1,23 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Metrics package.""" + + +from flwr_datasets.metrics.utils import compute_counts, compute_frequency + +__all__ = [ + "compute_counts", + "compute_frequency", +] diff --git a/datasets/flwr_datasets/metrics/utils.py b/datasets/flwr_datasets/metrics/utils.py new file mode 100644 index 000000000000..a11e7193fbde --- /dev/null +++ b/datasets/flwr_datasets/metrics/utils.py @@ -0,0 +1,78 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Utils for metrics computation.""" + + +from typing import List, Union + +import pandas as pd + + +def compute_counts( + labels: Union[List[int], List[str]], unique_labels: Union[List[int], List[str]] +) -> pd.Series: + """Compute the count of labels when taking into account all possible labels. + + Also known as absolute frequency. + + Parameters + ---------- + labels: Union[List[int], List[str]] + The labels from the datasets. + unique_labels: Union[List[int], List[str]] + The reference all unique label. Needed to avoid missing any label, instead + having the value equal to zero for them. + + Returns + ------- + label_counts: pd.Series + The pd.Series with label as indices and counts as values. + """ + if len(unique_labels) != len(set(unique_labels)): + raise ValueError("unique_labels must contain unique elements only.") + labels_series = pd.Series(labels) + label_counts = labels_series.value_counts() + label_counts_with_zeros = pd.Series(index=unique_labels, data=0) + label_counts_with_zeros = label_counts_with_zeros.add( + label_counts, fill_value=0 + ).astype(int) + return label_counts_with_zeros + + +def compute_frequency( + labels: Union[List[int], List[str]], unique_labels: Union[List[int], List[str]] +) -> pd.Series: + """Compute the distribution of labels when taking into account all possible labels. + + Also known as relative frequency. + + Parameters + ---------- + labels: Union[List[int], List[str]] + The labels from the datasets. + unique_labels: Union[List[int], List[str]] + The reference all unique label. Needed to avoid missing any label, instead + having the value equal to zero for them. + + Returns + ------- + The pd.Series with label as indices and probabilities as values. + """ + counts = compute_counts(labels, unique_labels) + if len(labels) == 0: + counts = counts.astype(float) + return counts + counts = counts.divide(len(labels)) + return counts diff --git a/datasets/flwr_datasets/metrics/utils_test.py b/datasets/flwr_datasets/metrics/utils_test.py new file mode 100644 index 000000000000..687aa67dbde6 --- /dev/null +++ b/datasets/flwr_datasets/metrics/utils_test.py @@ -0,0 +1,89 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for metrics utils.""" +# pylint: disable=no-self-use + + +import unittest + +import pandas as pd +from parameterized import parameterized + +from flwr_datasets.metrics.utils import compute_counts, compute_frequency + + +class TestMetricsUtils(unittest.TestCase): + """Test metrics utils.""" + + @parameterized.expand( # type: ignore + [ + ([1, 2, 2, 3], [1, 2, 3, 4], pd.Series([1, 2, 1, 0], index=[1, 2, 3, 4])), + ([], [1, 2, 3], pd.Series([0, 0, 0], index=[1, 2, 3])), + ([1, 1, 2], [1, 2, 3, 4], pd.Series([2, 1, 0, 0], index=[1, 2, 3, 4])), + ] + ) + def test_compute_counts(self, labels, unique_labels, expected) -> None: + """Test if the counts are computed correctly.""" + result = compute_counts(labels, unique_labels) + pd.testing.assert_series_equal(result, expected) + + @parameterized.expand( # type: ignore + [ + ( + [1, 1, 2, 2, 2, 3], + [1, 2, 3, 4], + pd.Series([0.3333, 0.5, 0.1667, 0.0], index=[1, 2, 3, 4]), + ), + ([], [1, 2, 3], pd.Series([0.0, 0.0, 0.0], index=[1, 2, 3])), + ( + ["a", "b", "b", "c"], + ["a", "b", "c", "d"], + pd.Series([0.25, 0.50, 0.25, 0.0], index=["a", "b", "c", "d"]), + ), + ] + ) + def test_compute_distribution(self, labels, unique_labels, expected) -> None: + """Test if the distributions are computed correctly.""" + result = compute_frequency(labels, unique_labels) + pd.testing.assert_series_equal(result, expected, atol=0.001) + + @parameterized.expand( # type: ignore + [ + (["a", "b", "b", "c"], ["a", "b", "c"]), + ([1, 2, 2, 3, 3, 3, 4], [1, 2, 3, 4]), + ] + ) + def test_distribution_sum_to_one(self, labels, unique_labels) -> None: + """Test if distributions sum up to one.""" + result = compute_frequency(labels, unique_labels) + self.assertAlmostEqual(result.sum(), 1.0) + + def test_compute_counts_non_unique_labels(self) -> None: + """Test if not having the unique labels raises ValueError.""" + labels = [1, 2, 3] + unique_labels = [1, 2, 2, 3] + with self.assertRaises(ValueError): + compute_counts(labels, unique_labels) + + def test_compute_distribution_non_unique_labels(self) -> None: + """Test if not having the unique labels raises ValueError.""" + labels = [1, 1, 2, 3] + unique_labels = [1, 1, 2, 3] + with self.assertRaises(ValueError): + compute_frequency(labels, unique_labels) + + +if __name__ == "__main__": + unittest.main() diff --git a/datasets/flwr_datasets/visualization/__init__.py b/datasets/flwr_datasets/visualization/__init__.py new file mode 100644 index 000000000000..801a38dcafc6 --- /dev/null +++ b/datasets/flwr_datasets/visualization/__init__.py @@ -0,0 +1,24 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Visualization package.""" + + +from .comparison_label_distribution import plot_comparison_label_distribution +from .label_distribution import plot_label_distributions + +__all__ = [ + "plot_label_distributions", + "plot_comparison_label_distribution", +] diff --git a/datasets/flwr_datasets/visualization/bar_plot.py b/datasets/flwr_datasets/visualization/bar_plot.py new file mode 100644 index 000000000000..6326b24a9695 --- /dev/null +++ b/datasets/flwr_datasets/visualization/bar_plot.py @@ -0,0 +1,143 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Label distribution bar plotting.""" + + +from typing import Any, Dict, Optional, Tuple, Union + +import numpy as np +import pandas as pd +from matplotlib import colors as mcolors +from matplotlib import pyplot as plt +from matplotlib.axes import Axes + + +# pylint: disable=too-many-arguments,too-many-locals,too-many-branches +def _plot_bar( + dataframe: pd.DataFrame, + axis: Optional[Axes], + figsize: Optional[Tuple[float, float]], + title: str, + colormap: Optional[Union[str, mcolors.Colormap]], + partition_id_axis: str, + size_unit: str, + legend: bool, + legend_title: Optional[str], + plot_kwargs: Optional[Dict[str, Any]], + legend_kwargs: Optional[Dict[str, Any]], +) -> Axes: + + if axis is None: + if figsize is None: + figsize = _initialize_figsize( + partition_id_axis=partition_id_axis, num_partitions=dataframe.shape[0] + ) + _, axis = plt.subplots(figsize=figsize) + + # Handle plot_kwargs + if plot_kwargs is None: + plot_kwargs = {} + + kind = "bar" if partition_id_axis == "x" else "barh" + if "kind" not in plot_kwargs: + plot_kwargs["kind"] = kind + + # Handle non-optional parameters + plot_kwargs["title"] = title + + # Handle optional parameters + if colormap is not None: + plot_kwargs["colormap"] = colormap + elif "colormap" not in plot_kwargs: + plot_kwargs["colormap"] = "RdYlGn" + + if "xlabel" not in plot_kwargs and "ylabel" not in plot_kwargs: + xlabel, ylabel = _initialize_xy_labels( + size_unit=size_unit, partition_id_axis=partition_id_axis + ) + plot_kwargs["xlabel"] = xlabel + plot_kwargs["ylabel"] = ylabel + + # Make the x ticks readable (they appear 90 degrees rotated by default) + if "rot" not in plot_kwargs: + plot_kwargs["rot"] = 0 + + # Handle hard-coded parameters + # Legend is handled separately (via axes.legend call not in the plot()) + if "legend" not in plot_kwargs: + plot_kwargs["legend"] = False + + # Make the bar plot stacked + if "stacked" not in plot_kwargs: + plot_kwargs["stacked"] = True + + axis = dataframe.plot( + ax=axis, + **plot_kwargs, + ) + + if legend: + if legend_kwargs is None: + legend_kwargs = {} + + if legend_title is not None: + legend_kwargs["title"] = legend_title + elif "title" not in legend_kwargs: + legend_kwargs["title"] = "Labels" + + if "loc" not in legend_kwargs: + legend_kwargs["loc"] = "outside center right" + + if "bbox_to_anchor" not in legend_kwargs: + max_len_label_str = max([len(str(column)) for column in dataframe.columns]) + shift = min(0.05 + max_len_label_str / 100, 0.15) + legend_kwargs["bbox_to_anchor"] = (1.0 + shift, 0.5) + + handles, legend_labels = axis.get_legend_handles_labels() + _ = axis.figure.legend( + handles=handles[::-1], labels=legend_labels[::-1], **legend_kwargs + ) + + # Heuristic to make the partition id on xticks non-overlapping + if partition_id_axis == "x": + xticklabels = axis.get_xticklabels() + if len(xticklabels) > 20: + # Make every other xtick label not visible + for i, label in enumerate(xticklabels): + if i % 2 == 1: + label.set_visible(False) + return axis + + +def _initialize_figsize( + partition_id_axis: str, + num_partitions: int, +) -> Tuple[float, float]: + figsize = (0.0, 0.0) + if partition_id_axis == "x": + figsize = (6.4, 4.8) + elif partition_id_axis == "y": + figsize = (6.4, np.sqrt(num_partitions)) + return figsize + + +def _initialize_xy_labels(size_unit: str, partition_id_axis: str) -> Tuple[str, str]: + xlabel = "Partition ID" + ylabel = "Count" if size_unit == "absolute" else "Percent %" + + if partition_id_axis == "y": + xlabel, ylabel = ylabel, xlabel + + return xlabel, ylabel diff --git a/datasets/flwr_datasets/visualization/comparison_label_distribution.py b/datasets/flwr_datasets/visualization/comparison_label_distribution.py new file mode 100644 index 000000000000..d59f8c47986d --- /dev/null +++ b/datasets/flwr_datasets/visualization/comparison_label_distribution.py @@ -0,0 +1,237 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Comparison of label distribution plotting.""" + + +from typing import Any, Dict, List, Optional, Tuple, Union + +import matplotlib.colors as mcolors +import matplotlib.pyplot as plt +import pandas as pd +from matplotlib.axes import Axes +from matplotlib.figure import Figure + +from flwr_datasets.partitioner import Partitioner +from flwr_datasets.visualization.constants import PLOT_TYPES +from flwr_datasets.visualization.label_distribution import plot_label_distributions + + +# pylint: disable=too-many-arguments,too-many-locals +def plot_comparison_label_distribution( + partitioner_list: List[Partitioner], + label_name: Union[str, List[str]], + plot_type: str = "bar", + size_unit: str = "percent", + max_num_partitions: Optional[Union[int]] = 30, + partition_id_axis: str = "y", + figsize: Optional[Tuple[float, float]] = None, + subtitle: str = "Comparison of Per Partition Label Distribution", + titles: Optional[List[str]] = None, + cmap: Optional[Union[str, mcolors.Colormap]] = None, + legend: bool = False, + legend_title: Optional[str] = None, + verbose_labels: bool = True, + plot_kwargs_list: Optional[List[Optional[Dict[str, Any]]]] = None, + legend_kwargs: Optional[Dict[str, Any]] = None, +) -> Tuple[Figure, List[Axes], List[pd.DataFrame]]: + """Compare the label distribution across multiple partitioners. + + Parameters + ---------- + partitioner_list : List[Partitioner] + List of partitioners to be compared. + label_name : Union[str, List[str]] + Column name or list of column names identifying labels for each partitioner. + plot_type : str + Type of plot, either "bar" or "heatmap". + size_unit : str + "absolute" for raw counts, or "percent" to normalize values to 100%. + max_num_partitions : Optional[int] + Maximum number of partitions to include in the plot. If None, all partitions + are included. + partition_id_axis : str + Axis on which the partition IDs will be marked, either "x" or "y". + figsize : Optional[Tuple[float, float]] + Size of the figure. If None, a default size is calculated. + subtitle : str + Subtitle for the figure. Defaults to "Comparison of Per Partition Label + Distribution" + titles : Optional[List[str]] + Titles for each subplot. If None, no titles are set. + cmap : Optional[Union[str, mcolors.Colormap]] + Colormap for determining the colorspace of the plot. + legend : bool + Whether to include a legend. If True, it will be included right-hand side after + all the plots. + legend_title : Optional[str] + Title for the legend. If None, the defaults will be takes based on the type of + plot. + verbose_labels : bool + Whether to use verbose versions of the labels. + plot_kwargs_list: Optional[List[Optional[Dict[str, Any]]]] + List of plot_kwargs. Any key value pair that can be passed to a plot function + that are not supported directly. In case of the parameter doubling + (e.g. specifying cmap here too) the chosen value will be taken from the + explicit arguments (e.g. cmap specified as an argument to this function not + the value in this dictionary). + legend_kwargs: Optional[Dict[str, Any]] + Any key value pair that can be passed to a figure.legend in case of bar plot or + cbar_kws in case of heatmap that are not supported directly. In case of + parameter doubling (e.g. specifying legend_title here too) the + chosen value will be taken from the explicit arguments (e.g. legend_title + specified as an argument to this function not the value in this dictionary). + + Returns + ------- + fig : Figure + The figure object containing the plots. + axes_list : List[Axes] + List of Axes objects for the plots. + dataframe_list : List[pd.DataFrame] + List of DataFrames used for each plot. + + Examples + -------- + Compare the difference of using different alpha (concentration) parameters in + DirichletPartitioner. + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.visualization import plot_comparison_label_distribution + >>> + >>> partitioner_list = [] + >>> alpha_list = [10_000.0, 100.0, 1.0, 0.1, 0.01, 0.00001] + >>> for alpha in alpha_list: + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=alpha, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner_list.append(fds.partitioners["train"]) + >>> fig, axes, dataframe_list = plot_comparison_label_distribution( + >>> partitioner_list=partitioner_list, + >>> label_name="label", + >>> titles=[f"Concentration = {alpha}" for alpha in alpha_list], + >>> ) + """ + num_partitioners = len(partitioner_list) + if isinstance(label_name, str): + label_name = [label_name] * num_partitioners + elif isinstance(label_name, List): + pass + else: + raise TypeError( + f"Label name has to be of type List[str] or str but given " + f"{type(label_name)}" + ) + figsize = _initialize_comparison_figsize(figsize, num_partitioners) + fig, axes = plt.subplots(1, num_partitioners, layout="constrained", figsize=figsize) + + if titles is None: + titles = ["" for _ in range(num_partitioners)] + + if plot_kwargs_list is None: + plot_kwargs_list = [None] * num_partitioners + + dataframe_list = [] + for idx, (partitioner, single_label_name, plot_kwargs) in enumerate( + zip(partitioner_list, label_name, plot_kwargs_list) + ): + if idx == (num_partitioners - 1): + *_, dataframe = plot_label_distributions( + partitioner=partitioner, + label_name=single_label_name, + plot_type=plot_type, + size_unit=size_unit, + partition_id_axis=partition_id_axis, + axis=axes[idx], + max_num_partitions=max_num_partitions, + cmap=cmap, + legend=legend, + legend_title=legend_title, + verbose_labels=verbose_labels, + plot_kwargs=plot_kwargs, + legend_kwargs=legend_kwargs, + ) + dataframe_list.append(dataframe) + else: + *_, dataframe = plot_label_distributions( + partitioner=partitioner, + label_name=single_label_name, + plot_type=plot_type, + size_unit=size_unit, + partition_id_axis=partition_id_axis, + axis=axes[idx], + max_num_partitions=max_num_partitions, + cmap=cmap, + legend=False, + plot_kwargs=plot_kwargs, + ) + dataframe_list.append(dataframe) + + # Do not use the xlabel and ylabel on each subplot plot + # (instead use global = per figure xlabel and ylabel) + for idx, axis in enumerate(axes): + axis.set_xlabel("") + axis.set_ylabel("") + axis.set_title(titles[idx]) + for axis in axes[1:]: + axis.set_yticks([]) + + # Set up figure xlabel and ylabel + xlabel, ylabel = _initialize_comparison_xy_labels(plot_type, partition_id_axis) + fig.supxlabel(xlabel) + fig.supylabel(ylabel) + fig.suptitle(subtitle) + + fig.tight_layout() + return fig, axes, dataframe_list + + +def _initialize_comparison_figsize( + figsize: Optional[Tuple[float, float]], num_partitioners: int +) -> Tuple[float, float]: + if figsize is not None: + return figsize + x_value = 4 + (num_partitioners - 1) * 2 + y_value = 4.8 + figsize = (x_value, y_value) + return figsize + + +def _initialize_comparison_xy_labels( + plot_type: str, partition_id_axis: str +) -> Tuple[str, str]: + if plot_type == "bar": + xlabel = "Partition ID" + ylabel = "Class distribution" + elif plot_type == "heatmap": + xlabel = "Partition ID" + ylabel = "Label" + else: + raise ValueError( + f"Invalid plot_type: {plot_type}. Must be one of {PLOT_TYPES}." + ) + + if partition_id_axis == "y": + xlabel, ylabel = ylabel, xlabel + + return xlabel, ylabel diff --git a/datasets/flwr_datasets/visualization/constants.py b/datasets/flwr_datasets/visualization/constants.py new file mode 100644 index 000000000000..b3c9cd2a7400 --- /dev/null +++ b/datasets/flwr_datasets/visualization/constants.py @@ -0,0 +1,19 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Constants for plot types and size units.""" + +PLOT_TYPES = ("bar", "heatmap") +SIZE_UNITS = ("absolute", "percent") +AXIS_TYPES = ("x", "y") diff --git a/datasets/flwr_datasets/visualization/heatmap_plot.py b/datasets/flwr_datasets/visualization/heatmap_plot.py new file mode 100644 index 000000000000..2e593a79368e --- /dev/null +++ b/datasets/flwr_datasets/visualization/heatmap_plot.py @@ -0,0 +1,106 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Label distribution heatmap plotting.""" + + +from typing import Any, Dict, Optional, Tuple, Union + +import numpy as np +import pandas as pd +import seaborn as sns +from matplotlib import colors as mcolors +from matplotlib import pyplot as plt +from matplotlib.axes import Axes + + +# pylint: disable=too-many-arguments,too-many-locals +def _plot_heatmap( + dataframe: pd.DataFrame, + axis: Optional[Axes], + figsize: Optional[Tuple[float, float]], + title: str, + colormap: Optional[Union[str, mcolors.Colormap]], + partition_id_axis: str, + size_unit: str, + legend: bool, + legend_title: Optional[str], + plot_kwargs: Optional[Dict[str, Any]], + legend_kwargs: Optional[Dict[str, Any]], +) -> Axes: + + if axis is None: + if figsize is None: + figsize = _initialize_figsize( + partition_id_axis=partition_id_axis, + num_partitions=dataframe.shape[0], + num_labels=dataframe.shape[1], + ) + _, axis = plt.subplots(figsize=figsize) + + # Handle plot_kwargs + if plot_kwargs is None: + plot_kwargs = {} + + # Handle optional parameters + if colormap is not None: + plot_kwargs["cmap"] = colormap + elif "cmap" not in plot_kwargs: + plot_kwargs["cmap"] = sns.light_palette("seagreen", as_cmap=True) + + if "fmt" not in plot_kwargs: + plot_kwargs["fmt"] = ",d" if size_unit == "absolute" else "0.2f" + + if legend_kwargs is None: + legend_kwargs = {} + if legend: + plot_kwargs["cbar"] = True + + if legend_title is not None: + legend_kwargs["label"] = legend_title + else: + legend_kwargs["label"] = _initialize_cbar_title(size_unit) + else: + plot_kwargs["cbar"] = False + + if partition_id_axis == "x": + dataframe = dataframe.T + + sns.heatmap( + dataframe, + ax=axis, + **plot_kwargs, + cbar_kws=legend_kwargs, + ) + axis.set_title(title) + return axis + + +def _initialize_figsize( + partition_id_axis: str, + num_partitions: int, + num_labels: int, +) -> Tuple[float, float]: + + figsize = (0.0, 0.0) + if partition_id_axis == "x": + figsize = (3 * np.sqrt(num_partitions), np.sqrt(num_labels)) + elif partition_id_axis == "y": + figsize = (3 * np.sqrt(num_labels), np.sqrt(num_partitions)) + + return figsize + + +def _initialize_cbar_title(size_unit: str) -> Optional[str]: + return "Count" if size_unit == "absolute" else "Percent %" diff --git a/datasets/flwr_datasets/visualization/label_distribution.py b/datasets/flwr_datasets/visualization/label_distribution.py new file mode 100644 index 000000000000..f959fbd856ee --- /dev/null +++ b/datasets/flwr_datasets/visualization/label_distribution.py @@ -0,0 +1,279 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Label distribution plotting.""" + + +import warnings +from typing import Any, Dict, Optional, Tuple, Union + +import matplotlib.colors as mcolors +import pandas as pd +from matplotlib.axes import Axes +from matplotlib.figure import Figure + +from flwr_datasets.metrics import compute_counts +from flwr_datasets.partitioner import Partitioner +from flwr_datasets.visualization.bar_plot import _plot_bar +from flwr_datasets.visualization.heatmap_plot import _plot_heatmap +from flwr_datasets.visualization.utils import _validate_parameters + +# pylint: disable=too-many-arguments,too-many-locals + + +def plot_label_distributions( + partitioner: Partitioner, + label_name: str, + plot_type: str = "bar", + size_unit: str = "absolute", + max_num_partitions: Optional[int] = None, + partition_id_axis: str = "x", + axis: Optional[Axes] = None, + figsize: Optional[Tuple[float, float]] = None, + title: str = "Per Partition Label Distribution", + cmap: Optional[Union[str, mcolors.Colormap]] = None, + legend: bool = False, + legend_title: Optional[str] = None, + verbose_labels: bool = True, + plot_kwargs: Optional[Dict[str, Any]] = None, + legend_kwargs: Optional[Dict[str, Any]] = None, +) -> Tuple[Figure, Axes, pd.DataFrame]: + """Plot the label distribution of the partitions. + + Parameters + ---------- + partitioner : Partitioner + Partitioner with an assigned dataset. + label_name : str + Column name identifying label based on which the plot will be created. + plot_type : str + Type of plot, either "bar" or "heatmap". + size_unit : str + "absolute" or "percent". "absolute" - (number of samples). "percent" - + normalizes each value, so they sum up to 100%. + max_num_partitions : Optional[int] + The number of partitions that will be used. If left None, then all partitions + will be used. + partition_id_axis : str + "x" or "y". The axis on which the partition_id will be marked. + axis : Optional[Axes] + Matplotlib Axes object to plot on. + figsize : Optional[Tuple[float, float]] + Size of the figure. + title : str + Title of the plot. + cmap : Optional[Union[str, mcolors.Colormap]] + Colormap for determining the colorspace of the plot. + legend : bool + Include the legend. + legend_title : Optional[str] + Title for the legend. If None, the defaults will be takes based on the type of + plot. + verbose_labels : bool + Whether to use verbose versions of the labels. + plot_kwargs: Optional[Dict[str, Any]] + Any key value pair that can be passed to a plot function that are not supported + directly. In case of the parameter doubling (e.g. specifying cmap here too) the + chosen value will be taken from the explicit arguments (e.g. cmap specified as + an argument to this function not the value in this dictionary). + legend_kwargs: Optional[Dict[str, Any]] + Any key value pair that can be passed to a figure.legend in case of bar plot or + cbar_kws in case of heatmap that are not supported directly. In case of the + parameter doubling (e.g. specifying legend_title here too) the + chosen value will be taken from the explicit arguments (e.g. legend_title + specified as an argument to this function not the value in this dictionary). + + Returns + ------- + fig : Figure + The figure object. + axis : Axes + The Axes object with the plot. + dataframe : pd.DataFrame + The DataFrame where each row represents the partition id and each column + represents the class. + + Examples + -------- + Visualize the label distribution resulting from DirichletPartitioner. + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.visualization import plot_label_distributions + >>> + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=0.3, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner = fds.partitioners["train"] + >>> figure, axis, dataframe = plot_label_distributions( + >>> partitioner=partitioner, + >>> label_name="label", + >>> legend=True, + >>> verbose_labels=True, + >>> ) + + Alternatively you can visualize each partition in terms of fraction of the data + available on that partition instead of the absolute count + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.visualization import plot_label_distributions + >>> + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=0.3, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner = fds.partitioners["train"] + >>> figure, axis, dataframe = plot_label_distributions( + >>> partitioner=partitioner, + >>> label_name="label", + >>> size_unit="percent", + >>> legend=True, + >>> verbose_labels=True, + >>> ) + >>> + + You can also visualize the data as a heatmap by changing the `plot_type` from + default "bar" to "heatmap" + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.visualization import plot_label_distributions + >>> + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=0.3, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner = fds.partitioners["train"] + >>> figure, axis, dataframe = plot_label_distributions( + >>> partitioner=partitioner, + >>> label_name="label", + >>> size_unit="percent", + >>> plot_type="heatmap", + >>> legend=True, + >>> plot_kwargs={"annot": True}, + >>> ) + + You can also visualize the returned DataFrame in Jupyter Notebook + >>> dataframe.style.background_gradient(axis=None) + """ + _validate_parameters(plot_type, size_unit, partition_id_axis) + + if label_name not in partitioner.dataset.column_names: + raise ValueError( + f"The specified 'label_name': '{label_name}' is not present in the " + f"dataset. The dataset contains columns {partitioner.dataset.column_names}." + ) + + if max_num_partitions is None: + max_num_partitions = partitioner.num_partitions + else: + max_num_partitions = min(max_num_partitions, partitioner.num_partitions) + assert isinstance(max_num_partitions, int) + partitions = [partitioner.load_partition(i) for i in range(max_num_partitions)] + + partition = partitions[0] + try: + # Unique labels are needed to represent the correct count of each class + # (some of the classes can have zero samples that's why this + # adjustment is needed) + unique_labels = partition.features[label_name].str2int( + partition.features[label_name].names + ) + except AttributeError: # If the label_name is not formally a Label + unique_labels = partitioner.dataset.unique(label_name) + + partition_id_to_label_absolute_size = { + pid: compute_counts(partition[label_name], unique_labels) + for pid, partition in enumerate(partitions) + } + + dataframe = pd.DataFrame.from_dict( + partition_id_to_label_absolute_size, orient="index" + ) + dataframe.index.name = "Partition ID" + + if size_unit == "percent": + dataframe = dataframe.div(dataframe.sum(axis=1), axis=0) * 100.0 + + if verbose_labels: + # Adjust the column name values of the dataframe + # (these values are used for as labels in bar plot and columns/rows ticks + # in heatmap) + current_labels = dataframe.columns + try: + legend_names = partition.features[label_name].int2str( + [int(v) for v in current_labels] + ) + dataframe.columns = legend_names + except AttributeError: + warnings.warn( + "The verbose label names can not be established. " + "The column specified by 'label_name' needs to be of type " + "'ClassLabel'", + stacklevel=1, + ) + + if plot_type == "bar": + axis = _plot_bar( + dataframe, + axis, + figsize, + title, + cmap, + partition_id_axis, + size_unit, + legend, + legend_title, + plot_kwargs, + legend_kwargs, + ) + elif plot_type == "heatmap": + axis = _plot_heatmap( + dataframe, + axis, + figsize, + title, + cmap, + partition_id_axis, + size_unit, + legend, + legend_title, + plot_kwargs, + legend_kwargs, + ) + assert axis is not None + return axis.figure, axis, dataframe diff --git a/datasets/flwr_datasets/visualization/utils.py b/datasets/flwr_datasets/visualization/utils.py new file mode 100644 index 000000000000..c2f1846de20e --- /dev/null +++ b/datasets/flwr_datasets/visualization/utils.py @@ -0,0 +1,36 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Plotting utils.""" + + +from flwr_datasets.visualization.constants import AXIS_TYPES, PLOT_TYPES, SIZE_UNITS + + +def _validate_parameters( + plot_type: str, size_unit: str, partition_id_axis: str +) -> None: + if plot_type not in PLOT_TYPES: + raise ValueError( + f"Invalid plot_type: {plot_type}. Must be one of {PLOT_TYPES}." + ) + if size_unit not in SIZE_UNITS: + raise ValueError( + f"Invalid size_unit: {size_unit}. Must be one of {SIZE_UNITS}." + ) + if partition_id_axis not in AXIS_TYPES: + raise ValueError( + f"Invalid partition_id_axis: {partition_id_axis}. " + f"Must be one of {AXIS_TYPES}." + ) diff --git a/datasets/pyproject.toml b/datasets/pyproject.toml index 36c0aef5ec2c..f874d4f0ce51 100644 --- a/datasets/pyproject.toml +++ b/datasets/pyproject.toml @@ -59,6 +59,8 @@ pillow = { version = ">=6.2.1", optional = true } soundfile = { version = ">=0.12.1", optional = true } librosa = { version = ">=0.10.0.post2", optional = true } tqdm ="^4.66.1" +matplotlib = "^3.7.5" +seaborn = "^0.13.0" [tool.poetry.dev-dependencies] isort = "==5.13.2" From 24f3b44b69c57f69e6d7146aeef5bd49e438165e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 6 Jun 2024 11:36:09 +0000 Subject: [PATCH 042/124] chore(deps): bump docker/login-action from 3.1.0 to 3.2.0 (#3542) Bumps [docker/login-action](https://github.com/docker/login-action) from 3.1.0 to 3.2.0. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/e92390c5fb421da1463c202d546fed0ec5c39f20...0d4c9c5ea7693da7b068278f7b52bda2a190a446) --- updated-dependencies: - dependency-name: docker/login-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Robert Steiner --- .github/workflows/_docker-build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/_docker-build.yml b/.github/workflows/_docker-build.yml index 608158fc0a5a..3508b1a7b3f6 100644 --- a/.github/workflows/_docker-build.yml +++ b/.github/workflows/_docker-build.yml @@ -79,7 +79,7 @@ jobs: uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Login to Docker Hub - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: username: ${{ secrets.dockerhub-user }} password: ${{ secrets.dockerhub-token }} @@ -134,7 +134,7 @@ jobs: uses: docker/setup-buildx-action@d70bba72b1f3fd22344832f00baa16ece964efeb # v3.3.0 - name: Login to Docker Hub - uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + uses: docker/login-action@0d4c9c5ea7693da7b068278f7b52bda2a190a446 # v3.2.0 with: username: ${{ secrets.dockerhub-user }} password: ${{ secrets.dockerhub-token }} From c58c1b795bd8cbf2c0717f6c09423569e3de3b56 Mon Sep 17 00:00:00 2001 From: mohammadnaseri Date: Sat, 8 Jun 2024 11:10:00 +0100 Subject: [PATCH 043/124] docs(framework:skip) Add built-in mods to client doc (#3559) --- src/py/flwr/client/__init__.py | 1 + src/py/flwr/client/mod/__init__.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/py/flwr/client/__init__.py b/src/py/flwr/client/__init__.py index fd8647dbaf2e..b4da71302cb4 100644 --- a/src/py/flwr/client/__init__.py +++ b/src/py/flwr/client/__init__.py @@ -28,6 +28,7 @@ "Client", "ClientApp", "ClientFn", + "mod", "NumPyClient", "run_client_app", "run_supernode", diff --git a/src/py/flwr/client/mod/__init__.py b/src/py/flwr/client/mod/__init__.py index 1cd79fa944fe..1774e4b8ca0a 100644 --- a/src/py/flwr/client/mod/__init__.py +++ b/src/py/flwr/client/mod/__init__.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""Mods.""" +"""Flower Built-in Mods.""" from .centraldp_mods import adaptiveclipping_mod, fixedclipping_mod From 353e9e8711da9bf508e6817d9f1792b0a2d8375b Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Sat, 8 Jun 2024 13:02:43 +0200 Subject: [PATCH 044/124] break(framework) Merge gRPC-rere and REST SuperLink options (#3527) Co-authored-by: jafermarq Co-authored-by: Daniel J. Beutel --- e2e/test_driver.sh | 18 +++-- src/py/flwr/server/app.py | 156 ++++++++++++++++++++------------------ 2 files changed, 94 insertions(+), 80 deletions(-) diff --git a/e2e/test_driver.sh b/e2e/test_driver.sh index 7a50764ab0ca..373a2cf327a7 100755 --- a/e2e/test_driver.sh +++ b/e2e/test_driver.sh @@ -22,7 +22,8 @@ esac case "$2" in rest) - rest_arg="--rest" + rest_arg_superlink="--fleet-api-type rest" + rest_arg_supernode="--rest" server_address="http://localhost:9093" server_app_address="127.0.0.1:9091" db_arg="--database :flwr-in-memory-state:" @@ -31,7 +32,8 @@ case "$2" in client_auth_2="" ;; sqlite) - rest_arg="" + rest_arg_superlink="" + rest_arg_supernode="" server_address="127.0.0.1:9092" server_app_address="127.0.0.1:9091" db_arg="--database $(date +%s).db" @@ -41,7 +43,8 @@ case "$2" in ;; client-auth) ./generate.sh - rest_arg="" + rest_arg_superlink="" + rest_arg_supernode="" server_address="127.0.0.1:9092" server_app_address="127.0.0.1:9091" db_arg="--database :flwr-in-memory-state:" @@ -52,7 +55,8 @@ case "$2" in client_auth_2="--auth-supernode-private-key keys/client_credentials_2 --auth-supernode-public-key keys/client_credentials_2.pub" ;; *) - rest_arg="" + rest_arg_superlink="" + rest_arg_supernode="" server_address="127.0.0.1:9092" server_app_address="127.0.0.1:9091" db_arg="--database :flwr-in-memory-state:" @@ -62,15 +66,15 @@ case "$2" in ;; esac -timeout 2m flower-superlink $server_arg $db_arg $rest_arg $server_auth & +timeout 2m flower-superlink $server_arg $db_arg $rest_arg_superlink $server_auth & sl_pid=$! sleep 3 -timeout 2m flower-client-app client:app $client_arg $rest_arg --server $server_address $client_auth_1 & +timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --server $server_address $client_auth_1 & cl1_pid=$! sleep 3 -timeout 2m flower-client-app client:app $client_arg $rest_arg --server $server_address $client_auth_2 & +timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --server $server_address $client_auth_2 & cl2_pid=$! sleep 3 diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 147ec5fb0f65..c050c983134b 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -230,6 +230,7 @@ def run_driver_api() -> None: grpc_server.wait_for_termination() +# pylint: disable=too-many-locals def run_fleet_api() -> None: """Run Flower server (Fleet API).""" log(INFO, "Starting Flower server (Fleet API)") @@ -248,6 +249,25 @@ def run_fleet_api() -> None: grpc_servers = [] bckg_threads = [] + address_arg = args.fleet_api_address + parsed_address = parse_address(address_arg) + if not parsed_address: + sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") + host, port, is_v6 = parsed_address + address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" + + num_workers = args.fleet_api_num_workers + if num_workers != 1: + log( + WARN, + "The Fleet API currently supports only 1 worker. " + "You have specified %d workers. " + "Support for multiple workers will be added in future releases. " + "Proceeding with a single worker.", + args.fleet_api_num_workers, + ) + num_workers = 1 + # Start Fleet API if args.fleet_api_type == TRANSPORT_TYPE_REST: if ( @@ -256,20 +276,19 @@ def run_fleet_api() -> None: and importlib.util.find_spec("uvicorn") ) is None: sys.exit(MISSING_EXTRA_REST) - address_arg = args.rest_fleet_api_address - parsed_address = parse_address(address_arg) - if not parsed_address: - sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") - host, port, _ = parsed_address + + _, ssl_certfile, ssl_keyfile = ( + certificates if certificates is not None else (None, None, None) + ) fleet_thread = threading.Thread( target=_run_fleet_api_rest, args=( host, port, - args.ssl_keyfile, - args.ssl_certfile, + ssl_keyfile, + ssl_certfile, state_factory, - args.rest_fleet_api_workers, + num_workers, ), ) fleet_thread.start() @@ -314,11 +333,15 @@ def run_superlink() -> None: args = _parse_args_run_superlink().parse_args() # Parse IP address - parsed_address = parse_address(args.driver_api_address) - if not parsed_address: + parsed_driver_address = parse_address(args.driver_api_address) + if not parsed_driver_address: sys.exit(f"Driver IP address ({args.driver_api_address}) cannot be parsed.") - host, port, is_v6 = parsed_address - address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" + driver_host, driver_port, driver_is_v6 = parsed_driver_address + driver_address = ( + f"[{driver_host}]:{driver_port}" + if driver_is_v6 + else f"{driver_host}:{driver_port}" + ) # Obtain certificates certificates = _try_obtain_certificates(args) @@ -328,13 +351,38 @@ def run_superlink() -> None: # Start Driver API driver_server: grpc.Server = run_driver_api_grpc( - address=address, + address=driver_address, state_factory=state_factory, certificates=certificates, ) grpc_servers = [driver_server] bckg_threads = [] + if not args.fleet_api_address: + args.fleet_api_address = ( + ADDRESS_FLEET_API_GRPC_RERE + if args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE + else ADDRESS_FLEET_API_REST + ) + parsed_fleet_address = parse_address(args.fleet_api_address) + if not parsed_fleet_address: + sys.exit(f"Fleet IP address ({args.fleet_api_address}) cannot be parsed.") + fleet_host, fleet_port, fleet_is_v6 = parsed_fleet_address + fleet_address = ( + f"[{fleet_host}]:{fleet_port}" if fleet_is_v6 else f"{fleet_host}:{fleet_port}" + ) + + num_workers = args.fleet_api_num_workers + if num_workers != 1: + log( + WARN, + "The Fleet API currently supports only 1 worker. " + "You have specified %d workers. " + "Support for multiple workers will be added in future releases. " + "Proceeding with a single worker.", + args.fleet_api_num_workers, + ) + num_workers = 1 # Start Fleet API if args.fleet_api_type == TRANSPORT_TYPE_REST: @@ -344,35 +392,25 @@ def run_superlink() -> None: and importlib.util.find_spec("uvicorn") ) is None: sys.exit(MISSING_EXTRA_REST) - address_arg = args.rest_fleet_api_address - parsed_address = parse_address(address_arg) + _, ssl_certfile, ssl_keyfile = ( certificates if certificates is not None else (None, None, None) ) - if not parsed_address: - sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") - host, port, _ = parsed_address + fleet_thread = threading.Thread( target=_run_fleet_api_rest, args=( - host, - port, + fleet_host, + fleet_port, ssl_keyfile, ssl_certfile, state_factory, - args.rest_fleet_api_workers, + num_workers, ), ) fleet_thread.start() bckg_threads.append(fleet_thread) elif args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE: - address_arg = args.grpc_rere_fleet_api_address - parsed_address = parse_address(address_arg) - if not parsed_address: - sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") - host, port, is_v6 = parsed_address - address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" - maybe_keys = _try_setup_client_authentication(args, certificates) interceptors: Optional[Sequence[grpc.ServerInterceptor]] = None if maybe_keys is not None: @@ -395,7 +433,7 @@ def run_superlink() -> None: interceptors = [AuthenticateServerInterceptor(state)] fleet_server = _run_fleet_api_grpc_rere( - address=address, + address=fleet_address, state_factory=state_factory, certificates=certificates, interceptors=interceptors, @@ -596,7 +634,7 @@ def _run_fleet_api_rest( ssl_keyfile: Optional[str], ssl_certfile: Optional[str], state_factory: StateFactory, - workers: int, + num_workers: int, ) -> None: """Run Driver API (REST-based).""" try: @@ -605,12 +643,7 @@ def _run_fleet_api_rest( from flwr.server.superlink.fleet.rest_rere.rest_api import app as fast_api_app except ModuleNotFoundError: sys.exit(MISSING_EXTRA_REST) - if workers != 1: - raise ValueError( - f"The supported number of workers for the Fleet API (REST server) is " - f"1. Instead given {workers}. The functionality of >1 workers will be " - f"added in the future releases." - ) + log(INFO, "Starting Flower REST server") # See: https://www.starlette.io/applications/#accessing-the-app-instance @@ -624,7 +657,7 @@ def _run_fleet_api_rest( access_log=True, ssl_keyfile=ssl_keyfile, ssl_certfile=ssl_certfile, - workers=workers, + workers=num_workers, ) @@ -732,50 +765,27 @@ def _add_args_common(parser: argparse.ArgumentParser) -> None: def _add_args_driver_api(parser: argparse.ArgumentParser) -> None: parser.add_argument( "--driver-api-address", - help="Driver API (gRPC) server address (IPv4, IPv6, or a domain name)", + help="Driver API (gRPC) server address (IPv4, IPv6, or a domain name).", default=ADDRESS_DRIVER_API, ) def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: # Fleet API transport layer type - ex_group = parser.add_mutually_exclusive_group() - ex_group.add_argument( - "--grpc-rere", - action="store_const", - dest="fleet_api_type", - const=TRANSPORT_TYPE_GRPC_RERE, + parser.add_argument( + "--fleet-api-type", default=TRANSPORT_TYPE_GRPC_RERE, - help="Start a Fleet API server (gRPC-rere)", - ) - ex_group.add_argument( - "--rest", - action="store_const", - dest="fleet_api_type", - const=TRANSPORT_TYPE_REST, - help="Start a Fleet API server (REST, experimental)", - ) - - # Fleet API gRPC-rere options - grpc_rere_group = parser.add_argument_group( - "Fleet API (gRPC-rere) server options", "" - ) - grpc_rere_group.add_argument( - "--grpc-rere-fleet-api-address", - help="Fleet API (gRPC-rere) server address (IPv4, IPv6, or a domain name)", - default=ADDRESS_FLEET_API_GRPC_RERE, + type=str, + choices=[TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_REST], + help="Start a gRPC-rere or REST (experimental) Fleet API server.", ) - - # Fleet API REST options - rest_group = parser.add_argument_group("Fleet API (REST) server options", "") - rest_group.add_argument( - "--rest-fleet-api-address", - help="Fleet API (REST) server address (IPv4, IPv6, or a domain name)", - default=ADDRESS_FLEET_API_REST, + parser.add_argument( + "--fleet-api-address", + help="Fleet API server address (IPv4, IPv6, or a domain name).", ) - rest_group.add_argument( - "--rest-fleet-api-workers", - help="Set the number of concurrent workers for the Fleet API REST server.", - type=int, + parser.add_argument( + "--fleet-api-num-workers", default=1, + type=int, + help="Set the number of concurrent workers for the Fleet API server.", ) From 70844c4d5d27689e83300ffae49393b82f9391f9 Mon Sep 17 00:00:00 2001 From: Javier Date: Sat, 8 Jun 2024 13:22:56 +0200 Subject: [PATCH 045/124] feat(framework) Deprecate `--server`, introduce `--superlink` to connect `ServerApp` and `SuperNode` to `SuperLink` (#3518) Co-authored-by: Daniel J. Beutel --- doc/source/how-to-authenticate-supernodes.rst | 2 +- doc/source/how-to-enable-ssl-connections.rst | 2 +- doc/source/how-to-run-flower-using-docker.rst | 13 +++---- doc/source/how-to-upgrade-to-flower-next.rst | 6 ++-- e2e/docker/compose.yaml | 4 +-- e2e/test_driver.sh | 6 ++-- src/py/flwr/client/supernode/app.py | 34 ++++++++++++++++--- src/py/flwr/server/run_serverapp.py | 34 ++++++++++++++++--- 8 files changed, 75 insertions(+), 26 deletions(-) diff --git a/doc/source/how-to-authenticate-supernodes.rst b/doc/source/how-to-authenticate-supernodes.rst index 9eb5e010ea4b..73987261b29f 100644 --- a/doc/source/how-to-authenticate-supernodes.rst +++ b/doc/source/how-to-authenticate-supernodes.rst @@ -59,7 +59,7 @@ Use the following terminal command to start an authenticated :code:`SuperNode`: flower-client-app client:app --root-certificates certificates/ca.crt - --server 127.0.0.1:9092 + --superlink 127.0.0.1:9092 --auth-supernode-private-key keys/client_credentials --auth-supernode-public-key keys/client_credentials.pub diff --git a/doc/source/how-to-enable-ssl-connections.rst b/doc/source/how-to-enable-ssl-connections.rst index 870f4b0f64c9..1828f4ed3258 100644 --- a/doc/source/how-to-enable-ssl-connections.rst +++ b/doc/source/how-to-enable-ssl-connections.rst @@ -59,7 +59,7 @@ Use the following terminal command to start a client (SuperNode) that uses the p flower-client-app client:app --root-certificates certificates/ca.crt - --server 127.0.0.1:9092 + --superlink 127.0.0.1:9092 When setting :code:`root_certificates`, the client expects a file path to PEM-encoded root certificates. diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index 375857b85b71..cffcd18129b5 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -245,7 +245,7 @@ Now that we have built the SuperNode image, we can finally run it. $ docker run --rm flwr_supernode:0.0.1 \ --insecure \ - --server 192.168.1.100:9092 + --superlink 192.168.1.100:9092 Let's break down each part of this command: @@ -261,7 +261,7 @@ Let's break down each part of this command: `SSL `__ when deploying to a production environment. -* | ``--server 192.168.1.100:9092``: This option specifies the address of the SuperLinks Fleet +* | ``--superlink 192.168.1.100:9092``: This option specifies the address of the SuperLinks Fleet | API to connect to. Remember to update it with your SuperLink IP. .. note:: @@ -288,8 +288,9 @@ certificate within the container. Use the ``--root-certificates`` flag when star .. code-block:: bash + $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_supernode:0.0.1 \ - --server 192.168.1.100:9092 \ + --superlink 192.168.1.100:9092 \ --root-certificates ca.crt Flower ServerApp @@ -361,7 +362,7 @@ Now that we have built the ServerApp image, we can finally run it. $ docker run --rm flwr_serverapp:0.0.1 \ --insecure \ - --server 192.168.1.100:9091 + --superlink 192.168.1.100:9091 Let's break down each part of this command: @@ -377,7 +378,7 @@ Let's break down each part of this command: `SSL `__ when deploying to a production environment. -* | ``--server 192.168.1.100:9091``: This option specifies the address of the SuperLinks Driver +* | ``--superlink 192.168.1.100:9091``: This option specifies the address of the SuperLinks Driver | API to connect to. Remember to update it with your SuperLink IP. .. note:: @@ -404,7 +405,7 @@ certificate within the container. Use the ``--root-certificates`` flags when sta .. code-block:: bash $ docker run --rm --volume ./ca.crt:/app/ca.crt flwr_serverapp:0.0.1 \ - --server 192.168.1.100:9091 \ + --superlink 192.168.1.100:9091 \ --root-certificates ca.crt Advanced Docker options diff --git a/doc/source/how-to-upgrade-to-flower-next.rst b/doc/source/how-to-upgrade-to-flower-next.rst index eebe894f56ec..a17756247566 100644 --- a/doc/source/how-to-upgrade-to-flower-next.rst +++ b/doc/source/how-to-upgrade-to-flower-next.rst @@ -185,17 +185,17 @@ Deployment # In a new terminal window, start a long-running secure SuperNode $ flower-client-app client:app \ --root-certificates \ - --server 127.0.0.1:9092 + --superlink 127.0.0.1:9092 # In another terminal window, start another long-running secure SuperNode (at least 2 SuperNodes are required) $ flower-client-app client:app \ --root-certificates \ - --server 127.0.0.1:9092 + --superlink 127.0.0.1:9092 # In yet another terminal window, run the ServerApp (this starts the actual training run) $ flower-server-app server:app \ --root-certificates \ - --server 127.0.0.1:9091 + --superlink 127.0.0.1:9091 Simulation in CLI ~~~~~~~~~~~~~~~~~ diff --git a/e2e/docker/compose.yaml b/e2e/docker/compose.yaml index 073ca9f60a57..c31bc81692f2 100644 --- a/e2e/docker/compose.yaml +++ b/e2e/docker/compose.yaml @@ -19,7 +19,7 @@ services: resources: limits: cpus: '2' - command: [ "--insecure", "--server", "superlink:9092" ] + command: [ "--insecure", "--superlink", "superlink:9092" ] depends_on: - superlink @@ -27,7 +27,7 @@ services: serverapp: build: dockerfile: serverapp.Dockerfile - command: [ "--insecure", "--server", "superlink:9091" ] + command: [ "--insecure", "--superlink", "superlink:9091" ] # enforce dependency for graceful execution depends_on: - superlink diff --git a/e2e/test_driver.sh b/e2e/test_driver.sh index 373a2cf327a7..e177863bab78 100755 --- a/e2e/test_driver.sh +++ b/e2e/test_driver.sh @@ -70,15 +70,15 @@ timeout 2m flower-superlink $server_arg $db_arg $rest_arg_superlink $server_auth sl_pid=$! sleep 3 -timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --server $server_address $client_auth_1 & +timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --superlink $server_address $client_auth_1 & cl1_pid=$! sleep 3 -timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --server $server_address $client_auth_2 & +timeout 2m flower-client-app client:app $client_arg $rest_arg_supernode --superlink $server_address $client_auth_2 & cl2_pid=$! sleep 3 -timeout 2m flower-server-app server:app $client_arg --dir $server_dir --server $server_app_address & +timeout 2m flower-server-app server:app $client_arg --dir $server_dir --superlink $server_app_address & pid=$! wait $pid diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index ac58e9aa4a81..336cd818d718 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -30,11 +30,13 @@ from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import EventType, event from flwr.common.exit_handlers import register_exit_handlers -from flwr.common.logger import log +from flwr.common.logger import log, warn_deprecated_feature from flwr.common.object_ref import load_app, validate from ..app import _start_client_internal +ADDRESS_FLEET_API_GRPC_RERE = "0.0.0.0:9092" + def run_supernode() -> None: """Run Flower SuperNode.""" @@ -63,6 +65,23 @@ def run_client_app() -> None: args = _parse_args_run_client_app().parse_args() + if args.server != ADDRESS_FLEET_API_GRPC_RERE: + warn = "Passing flag --server is deprecated. Use --superlink instead." + warn_deprecated_feature(warn) + + if args.superlink != ADDRESS_FLEET_API_GRPC_RERE: + # if `--superlink` also passed, then + # warn user that this argument overrides what was passed with `--server` + log( + WARN, + "Both `--server` and `--superlink` were passed. " + "`--server` will be ignored. Connecting to the Superlink Fleet API " + "at %s.", + args.superlink, + ) + else: + args.superlink = args.server + root_certificates = _get_certificates(args) log( DEBUG, @@ -73,7 +92,7 @@ def run_client_app() -> None: authentication_keys = _try_setup_client_authentication(args) _start_client_internal( - server_address=args.server, + server_address=args.superlink, load_client_app_fn=load_fn, transport="rest" if args.rest else "grpc-rere", root_certificates=root_certificates, @@ -100,7 +119,7 @@ def _get_certificates(args: argparse.Namespace) -> Optional[bytes]: WARN, "Option `--insecure` was set. " "Starting insecure HTTP client connected to %s.", - args.server, + args.superlink, ) root_certificates = None else: @@ -114,7 +133,7 @@ def _get_certificates(args: argparse.Namespace) -> Optional[bytes]: DEBUG, "Starting secure HTTPS client connected to %s " "with the following certificates: %s.", - args.server, + args.superlink, cert_path, ) return root_certificates @@ -213,9 +232,14 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None: ) parser.add_argument( "--server", - default="0.0.0.0:9092", + default=ADDRESS_FLEET_API_GRPC_RERE, help="Server address", ) + parser.add_argument( + "--superlink", + default=ADDRESS_FLEET_API_GRPC_RERE, + help="SuperLink Fleet API (gRPC-rere) address (IPv4, IPv6, or a domain name)", + ) parser.add_argument( "--max-retries", type=int, diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index 9cc7974d34da..0879dd6054d0 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -22,12 +22,14 @@ from typing import Optional from flwr.common import Context, EventType, RecordSet, event -from flwr.common.logger import log, update_console_handler +from flwr.common.logger import log, update_console_handler, warn_deprecated_feature from flwr.common.object_ref import load_app from .driver import Driver, GrpcDriver from .server_app import LoadServerAppError, ServerApp +ADDRESS_DRIVER_API = "0.0.0.0:9091" + def run( driver: Driver, @@ -76,6 +78,23 @@ def run_server_app() -> None: args = _parse_args_run_server_app().parse_args() + if args.server != ADDRESS_DRIVER_API: + warn = "Passing flag --server is deprecated. Use --superlink instead." + warn_deprecated_feature(warn) + + if args.superlink != ADDRESS_DRIVER_API: + # if `--superlink` also passed, then + # warn user that this argument overrides what was passed with `--server` + log( + WARN, + "Both `--server` and `--superlink` were passed. " + "`--server` will be ignored. Connecting to the Superlink Driver API " + "at %s.", + args.superlink, + ) + else: + args.superlink = args.server + update_console_handler( level=DEBUG if args.verbose else INFO, timestamps=args.verbose, @@ -95,7 +114,7 @@ def run_server_app() -> None: WARN, "Option `--insecure` was set. " "Starting insecure HTTP client connected to %s.", - args.server, + args.superlink, ) root_certificates = None else: @@ -109,7 +128,7 @@ def run_server_app() -> None: DEBUG, "Starting secure HTTPS client connected to %s " "with the following certificates: %s.", - args.server, + args.superlink, cert_path, ) @@ -130,7 +149,7 @@ def run_server_app() -> None: # Initialize GrpcDriver driver = GrpcDriver( - driver_service_address=args.server, + driver_service_address=args.superlink, root_certificates=root_certificates, fab_id=args.fab_id, fab_version=args.fab_version, @@ -175,9 +194,14 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser: ) parser.add_argument( "--server", - default="0.0.0.0:9091", + default=ADDRESS_DRIVER_API, help="Server address", ) + parser.add_argument( + "--superlink", + default=ADDRESS_DRIVER_API, + help="SuperLink Driver API (gRPC-rere) address (IPv4, IPv6, or a domain name)", + ) parser.add_argument( "--dir", default="", From 018dd45142a2d2375e1bfe12489ab1208bfafebc Mon Sep 17 00:00:00 2001 From: Javier Date: Sat, 8 Jun 2024 16:23:21 +0200 Subject: [PATCH 046/124] feat(framework) Introduce `RunTracker` (#3561) Co-authored-by: Charles Beauville --- src/py/flwr/client/app.py | 65 +++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index d7c05d8afbb2..4e09c53c2b00 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -14,8 +14,10 @@ # ============================================================================== """Flower client app.""" +import signal import sys import time +from dataclasses import dataclass from logging import DEBUG, ERROR, INFO, WARN from typing import Callable, ContextManager, Optional, Tuple, Type, Union @@ -37,7 +39,7 @@ ) from flwr.common.logger import log, warn_deprecated_feature from flwr.common.message import Error -from flwr.common.retry_invoker import RetryInvoker, exponential +from flwr.common.retry_invoker import RetryInvoker, RetryState, exponential from .grpc_client.connection import grpc_connection from .grpc_rere_client.connection import grpc_request_response @@ -263,6 +265,29 @@ def _load_client_app() -> ClientApp: transport, server_address ) + run_tracker = _RunTracker() + + def _on_sucess(retry_state: RetryState) -> None: + if retry_state.tries > 1: + log( + INFO, + "Connection successful after %.2f seconds and %s tries.", + retry_state.elapsed_time, + retry_state.tries, + ) + if run_tracker.create_node: + run_tracker.create_node() + + def _on_backoff(retry_state: RetryState) -> None: + if retry_state.tries == 1: + log(WARN, "Connection attempt failed, retrying...") + else: + log( + DEBUG, + "Connection attempt failed, retrying in %.2f seconds", + retry_state.actual_wait, + ) + retry_invoker = RetryInvoker( wait_gen_factory=exponential, recoverable_exceptions=connection_error_type, @@ -278,25 +303,8 @@ def _load_client_app() -> ClientApp: if retry_state.tries > 1 else None ), - on_success=lambda retry_state: ( - log( - INFO, - "Connection successful after %.2f seconds and %s tries.", - retry_state.elapsed_time, - retry_state.tries, - ) - if retry_state.tries > 1 - else None - ), - on_backoff=lambda retry_state: ( - log(WARN, "Connection attempt failed, retrying...") - if retry_state.tries == 1 - else log( - DEBUG, - "Connection attempt failed, retrying in %.2f seconds", - retry_state.actual_wait, - ) - ), + on_success=_on_sucess, + on_backoff=_on_backoff, ) node_state = NodeState() @@ -579,3 +587,20 @@ def _init_connection(transport: Optional[str], server_address: str) -> Tuple[ ) return connection, address, error_type + + +@dataclass +class _RunTracker: + create_node: Optional[Callable[[], None]] = None + interrupt: bool = False + + def register_signal_handler(self) -> None: + """Register handlers for exit signals.""" + + def signal_handler(sig, frame): # type: ignore + # pylint: disable=unused-argument + self.interrupt = True + raise StopIteration from None + + signal.signal(signal.SIGINT, signal_handler) + signal.signal(signal.SIGTERM, signal_handler) From 111eecc6231f0e7010d6a42e01db38dc475cf019 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Sun, 9 Jun 2024 17:08:45 +0200 Subject: [PATCH 047/124] refactor(framework:skip) Add no-op indent level to `_start_client_internal` (#3564) --- src/py/flwr/client/app.py | 155 +++++++++++++++++++------------------- 1 file changed, 79 insertions(+), 76 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index 4e09c53c2b00..eb07a732439d 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -327,90 +327,93 @@ def _on_backoff(retry_state: RetryState) -> None: create_node() # pylint: disable=not-callable while True: - # Receive - message = receive() - if message is None: - time.sleep(3) # Wait for 3s before asking again - continue - - log(INFO, "") - if len(message.metadata.group_id) > 0: + if True: # pylint: disable=using-constant-test + # Receive + message = receive() + if message is None: + time.sleep(3) # Wait for 3s before asking again + continue + + log(INFO, "") + if len(message.metadata.group_id) > 0: + log( + INFO, + "[RUN %s, ROUND %s]", + message.metadata.run_id, + message.metadata.group_id, + ) log( INFO, - "[RUN %s, ROUND %s]", - message.metadata.run_id, - message.metadata.group_id, + "Received: %s message %s", + message.metadata.message_type, + message.metadata.message_id, ) - log( - INFO, - "Received: %s message %s", - message.metadata.message_type, - message.metadata.message_id, - ) - - # Handle control message - out_message, sleep_duration = handle_control_message(message) - if out_message: - send(out_message) - break - - # Register context for this run - node_state.register_context(run_id=message.metadata.run_id) - - # Retrieve context for this run - context = node_state.retrieve_context(run_id=message.metadata.run_id) - - # Create an error reply message that will never be used to prevent - # the used-before-assignment linting error - reply_message = message.create_error_reply( - error=Error(code=ErrorCode.UNKNOWN, reason="Unknown") - ) - - # Handle app loading and task message - try: - # Load ClientApp instance - client_app: ClientApp = load_client_app_fn() - - # Execute ClientApp - reply_message = client_app(message=message, context=context) - except Exception as ex: # pylint: disable=broad-exception-caught - - # Legacy grpc-bidi - if transport in ["grpc-bidi", None]: - log(ERROR, "Client raised an exception.", exc_info=ex) - # Raise exception, crash process - raise ex - - # Don't update/change NodeState - - e_code = ErrorCode.CLIENT_APP_RAISED_EXCEPTION - # Reason example: ":<'division by zero'>" - reason = str(type(ex)) + ":<'" + str(ex) + "'>" - exc_entity = "ClientApp" - if isinstance(ex, LoadClientAppError): - reason = ( - "An exception was raised when attempting to load " - "`ClientApp`" - ) - e_code = ErrorCode.LOAD_CLIENT_APP_EXCEPTION - exc_entity = "SuperNode" - log(ERROR, "%s raised an exception", exc_entity, exc_info=ex) + # Handle control message + out_message, sleep_duration = handle_control_message(message) + if out_message: + send(out_message) + break - # Create error message - reply_message = message.create_error_reply( - error=Error(code=e_code, reason=reason) + # Register context for this run + node_state.register_context(run_id=message.metadata.run_id) + + # Retrieve context for this run + context = node_state.retrieve_context( + run_id=message.metadata.run_id ) - else: - # No exception, update node state - node_state.update_context( - run_id=message.metadata.run_id, - context=context, + + # Create an error reply message that will never be used to prevent + # the used-before-assignment linting error + reply_message = message.create_error_reply( + error=Error(code=ErrorCode.UNKNOWN, reason="Unknown") ) - # Send - send(reply_message) - log(INFO, "Sent reply") + # Handle app loading and task message + try: + # Load ClientApp instance + client_app: ClientApp = load_client_app_fn() + + # Execute ClientApp + reply_message = client_app(message=message, context=context) + except Exception as ex: # pylint: disable=broad-exception-caught + + # Legacy grpc-bidi + if transport in ["grpc-bidi", None]: + log(ERROR, "Client raised an exception.", exc_info=ex) + # Raise exception, crash process + raise ex + + # Don't update/change NodeState + + e_code = ErrorCode.CLIENT_APP_RAISED_EXCEPTION + # Ex fmt: ":<'division by zero'>" + reason = str(type(ex)) + ":<'" + str(ex) + "'>" + exc_entity = "ClientApp" + if isinstance(ex, LoadClientAppError): + reason = ( + "An exception was raised when attempting to load " + "`ClientApp`" + ) + e_code = ErrorCode.LOAD_CLIENT_APP_EXCEPTION + exc_entity = "SuperNode" + + log(ERROR, "%s raised an exception", exc_entity, exc_info=ex) + + # Create error message + reply_message = message.create_error_reply( + error=Error(code=e_code, reason=reason) + ) + else: + # No exception, update node state + node_state.update_context( + run_id=message.metadata.run_id, + context=context, + ) + + # Send + send(reply_message) + log(INFO, "Sent reply") # Unregister node if delete_node is not None: From 8d08e12c4caf3de02fcad57642e66f6da77b7a80 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Sun, 9 Jun 2024 17:26:06 +0200 Subject: [PATCH 048/124] fix(framework:skip) Remove create_node call on reconnect (#3566) --- src/py/flwr/client/app.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index eb07a732439d..7085df418e76 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -266,6 +266,7 @@ def _load_client_app() -> ClientApp: ) run_tracker = _RunTracker() + _ = run_tracker def _on_sucess(retry_state: RetryState) -> None: if retry_state.tries > 1: @@ -275,8 +276,6 @@ def _on_sucess(retry_state: RetryState) -> None: retry_state.elapsed_time, retry_state.tries, ) - if run_tracker.create_node: - run_tracker.create_node() def _on_backoff(retry_state: RetryState) -> None: if retry_state.tries == 1: @@ -594,7 +593,6 @@ def _init_connection(transport: Optional[str], server_address: str) -> Tuple[ @dataclass class _RunTracker: - create_node: Optional[Callable[[], None]] = None interrupt: bool = False def register_signal_handler(self) -> None: From e182983e25130d777f5897b077d32a47a7274e09 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Mon, 10 Jun 2024 11:34:32 +0200 Subject: [PATCH 049/124] feat(framework) Allow clients to exit gracefully (#3090) Co-authored-by: Heng Pan Co-authored-by: Javier --- src/py/flwr/client/app.py | 28 +++++++++++++------ .../client/grpc_rere_client/connection.py | 2 -- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index 7085df418e76..7294600288aa 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -265,10 +265,10 @@ def _load_client_app() -> ClientApp: transport, server_address ) - run_tracker = _RunTracker() - _ = run_tracker + app_state_tracker = _AppStateTracker() def _on_sucess(retry_state: RetryState) -> None: + app_state_tracker.is_connected = True if retry_state.tries > 1: log( INFO, @@ -278,6 +278,7 @@ def _on_sucess(retry_state: RetryState) -> None: ) def _on_backoff(retry_state: RetryState) -> None: + app_state_tracker.is_connected = False if retry_state.tries == 1: log(WARN, "Connection attempt failed, retrying...") else: @@ -308,7 +309,7 @@ def _on_backoff(retry_state: RetryState) -> None: node_state = NodeState() - while True: + while not app_state_tracker.interrupt: sleep_duration: int = 0 with connection( address, @@ -325,8 +326,9 @@ def _on_backoff(retry_state: RetryState) -> None: if create_node is not None: create_node() # pylint: disable=not-callable - while True: - if True: # pylint: disable=using-constant-test + app_state_tracker.register_signal_handler() + while not app_state_tracker.interrupt: + try: # Receive message = receive() if message is None: @@ -397,7 +399,10 @@ def _on_backoff(retry_state: RetryState) -> None: e_code = ErrorCode.LOAD_CLIENT_APP_EXCEPTION exc_entity = "SuperNode" - log(ERROR, "%s raised an exception", exc_entity, exc_info=ex) + if not app_state_tracker.interrupt: + log( + ERROR, "%s raised an exception", exc_entity, exc_info=ex + ) # Create error message reply_message = message.create_error_reply( @@ -414,13 +419,19 @@ def _on_backoff(retry_state: RetryState) -> None: send(reply_message) log(INFO, "Sent reply") + except StopIteration: + sleep_duration = 0 + break + # Unregister node - if delete_node is not None: + if delete_node is not None and app_state_tracker.is_connected: delete_node() # pylint: disable=not-callable if sleep_duration == 0: log(INFO, "Disconnect and shut down") + del app_state_tracker break + # Sleep and reconnect afterwards log( INFO, @@ -592,8 +603,9 @@ def _init_connection(transport: Optional[str], server_address: str) -> Tuple[ @dataclass -class _RunTracker: +class _AppStateTracker: interrupt: bool = False + is_connected: bool = False def register_signal_handler(self) -> None: """Register handlers for exit signals.""" diff --git a/src/py/flwr/client/grpc_rere_client/connection.py b/src/py/flwr/client/grpc_rere_client/connection.py index 8ef8e7ebf62a..9579d5830165 100644 --- a/src/py/flwr/client/grpc_rere_client/connection.py +++ b/src/py/flwr/client/grpc_rere_client/connection.py @@ -193,8 +193,6 @@ def delete_node() -> None: # Stop the ping-loop thread ping_stop_event.set() - if ping_thread is not None: - ping_thread.join() # Call FleetAPI delete_node_request = DeleteNodeRequest(node=node) From 578da36fd4352e749c9a07dbe90dc08c7fcdc04b Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Mon, 10 Jun 2024 11:40:18 +0200 Subject: [PATCH 050/124] docs(framework) Update documentation dependencies (#3565) --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a045987367f6..1350cb7ee03c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,7 +105,7 @@ jupyterlab = "==4.0.12" rope = "==1.11.0" semver = "==3.0.2" sphinx = "==6.2.1" -sphinx-intl = "==2.1.0" +sphinx-intl = "==2.2.0" myst-parser = "==1.0.0" sphinx-design = "==0.5.0" sphinx-copybutton = "==0.5.2" @@ -113,7 +113,7 @@ sphinxcontrib-mermaid = "==0.9.2" sphinxcontrib-youtube = "==1.4.1" furo = "==2023.9.10" sphinx-reredirects = "==0.1.3" -nbsphinx = "==0.9.3" +nbsphinx = "==0.9.4" nbstripout = "==0.6.1" ruff = "==0.1.9" sphinx-argparse = "==0.4.0" From 5b730571c6b53606d9c6062bf66a7ae7dfeb4a70 Mon Sep 17 00:00:00 2001 From: "Daniel J. Beutel" Date: Mon, 10 Jun 2024 11:55:41 +0200 Subject: [PATCH 051/124] docs(framework) Remove 'Creating New Messages' docs page (#3563) --- doc/source/conf.py | 3 +- ...contributor-how-to-create-new-messages.rst | 153 ------------------ doc/source/index.rst | 1 - 3 files changed, 2 insertions(+), 155 deletions(-) delete mode 100644 doc/source/contributor-how-to-create-new-messages.rst diff --git a/doc/source/conf.py b/doc/source/conf.py index feb173c0efa8..174465c153b7 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -248,7 +248,8 @@ def find_test_modules(package_path): "quickstart-mxnet": "index.html", "tutorial-quickstart-mxnet": "index.html", "example-mxnet-walk-through": "index.html", - "ref-api/flwr.simulation.run_simulation_from_cli.html": "index.html", + "ref-api/flwr.simulation.run_simulation_from_cli": "index.html", + "contributor-how-to-create-new-messages": "index.html", } # -- Options for HTML output ------------------------------------------------- diff --git a/doc/source/contributor-how-to-create-new-messages.rst b/doc/source/contributor-how-to-create-new-messages.rst deleted file mode 100644 index 3f1849bdce47..000000000000 --- a/doc/source/contributor-how-to-create-new-messages.rst +++ /dev/null @@ -1,153 +0,0 @@ -Creating New Messages -===================== - -This is a simple guide for creating a new type of message between the server and clients in Flower. - -Let's suppose we have the following example functions in :code:`server.py` and :code:`numpy_client.py`... - -Server's side: - -.. code-block:: python - - def example_request(self, client: ClientProxy) -> Tuple[str, int]: - question = "Could you find the sum of the list, Bob?" - l = [1, 2, 3] - return client.request(question, l) - -Client's side: - -.. code-block:: python - - def example_response(self, question: str, l: List[int]) -> Tuple[str, int]: - response = "Here you go Alice!" - answer = sum(question) - return response, answer - -Let's now see what we need to implement in order to get this simple function between the server and client to work! - - -Message Types for Protocol Buffers ----------------------------------- - -The first thing we need to do is to define a message type for the RPC system in :code:`transport.proto`. -Note that we have to do it for both the request and response messages. For more details on the syntax of proto3, please see the `official documentation `_. - -Within the :code:`ServerMessage` block: - -.. code-block:: proto - - message ExampleIns{ - string question=1; - repeated int64 l=2; - } - oneof msg { - ReconnectIns reconnect_ins = 1; - GetPropertiesIns get_properties_ins = 2; - GetParametersIns get_parameters_ins = 3; - FitIns fit_ins = 4; - EvaluateIns evaluate_ins = 5; - ExampleIns example_ins = 6; - } - -Within the ClientMessage block: - -.. code-block:: proto - - message ExampleRes{ - string response = 1; - int64 answer = 2; - } - - oneof msg { - DisconnectRes disconnect_res = 1; - GetPropertiesRes get_properties_res = 2; - GetParametersRes get_parameters_res = 3; - FitRes fit_res = 4; - EvaluateRes evaluate_res = 5; - ExampleRes examples_res = 6; - } - -Make sure to also add a field of the newly created message type in :code:`oneof msg`. - -Once that is done, we will compile the file with: - -.. code-block:: shell - - $ python -m flwr_tool.protoc - -If it compiles successfully, you should see the following message: - -.. code-block:: shell - - Writing mypy to flwr/proto/transport_pb2.pyi - Writing mypy to flwr/proto/transport_pb2_grpc.pyi - - -Serialization and Deserialization Functions --------------------------------------------- - -Our next step is to add functions to serialize and deserialize Python datatypes to or from our defined RPC message types. You should add these functions in :code:`serde.py`. - -The four functions: - -.. code-block:: python - - def example_msg_to_proto(question: str, l: List[int]) -> ServerMessage.ExampleIns: - return ServerMessage.ExampleIns(question=question, l=l) - - - def example_msg_from_proto(msg: ServerMessage.ExampleIns) -> Tuple[str, List[int]]: - return msg.question, msg.l - - - def example_res_to_proto(response: str, answer: int) -> ClientMessage.ExampleRes: - return ClientMessage.ExampleRes(response=response, answer=answer) - - - def example_res_from_proto(res: ClientMessage.ExampleRes) -> Tuple[str, int]: - return res.response, res.answer - - -Sending the Message from the Server ------------------------------------ - -Now write the request function in your Client Proxy class (e.g., :code:`grpc_client_proxy.py`) using the serde functions you just created: - -.. code-block:: python - - def request(self, question: str, l: List[int]) -> Tuple[str, int]: - request_msg = serde.example_msg_to_proto(question, l) - client_msg: ClientMessage = self.bridge.request( - ServerMessage(example_ins=request_msg) - ) - response, answer = serde.example_res_from_proto(client_msg.examples_res) - return response, answer - - -Receiving the Message by the Client ------------------------------------ - -Last step! Modify the code in :code:`message_handler.py` to check the field of your message and call the :code:`example_response` function. Remember to use the serde functions! - -Within the handle function: - -.. code-block:: python - - if server_msg.HasField("example_ins"): - return _example_response(client, server_msg.example_ins), 0, True - -And add a new function: - -.. code-block:: python - - def _example_response(client: Client, msg: ServerMessage.ExampleIns) -> ClientMessage: - question,l = serde.evaluate_ins_from_proto(msg) - response, answer = client.example_response(question,l) - example_res = serde.example_res_to_proto(response,answer) - return ClientMessage(examples_res=example_res) - -Hopefully, when you run your program you will get the intended result! - -.. code-block:: shell - - ('Here you go Alice!', 6) diff --git a/doc/source/index.rst b/doc/source/index.rst index df41d9d4ccb0..f62c5ebf4786 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -164,7 +164,6 @@ The Flower community welcomes contributions. The following docs are intended to contributor-how-to-install-development-versions contributor-how-to-set-up-a-virtual-env contributor-how-to-develop-in-vscode-dev-containers - contributor-how-to-create-new-messages contributor-how-to-write-documentation contributor-how-to-release-flower contributor-how-to-contribute-translations From d917bd41b2a0db927745a19bf0154c32ba5fdd07 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Mon, 10 Jun 2024 21:29:32 +0200 Subject: [PATCH 052/124] docs(framework) Add Flower 1.9 changelog (#3567) Co-authored-by: Daniel J. Beutel --- doc/source/ref-changelog.md | 96 ++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/doc/source/ref-changelog.md b/doc/source/ref-changelog.md index c742b8cd9cbe..58fc8b4f69b1 100644 --- a/doc/source/ref-changelog.md +++ b/doc/source/ref-changelog.md @@ -1,12 +1,104 @@ # Changelog -## Unreleased +## v1.9.0 (2024-06-10) + +### Thanks to our contributors + +We would like to give our special thanks to all the contributors who made the new version of Flower possible (in `git shortlog` order): + +`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`, `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` ### What's new? +- **Introduce built-in authentication (preview)** ([#2946](https://github.com/adap/flower/pull/2946), [#3388](https://github.com/adap/flower/pull/3388), [#2948](https://github.com/adap/flower/pull/2948), [#2917](https://github.com/adap/flower/pull/2917), [#3386](https://github.com/adap/flower/pull/3386), [#3308](https://github.com/adap/flower/pull/3308), [#3001](https://github.com/adap/flower/pull/3001), [#3409](https://github.com/adap/flower/pull/3409), [#2999](https://github.com/adap/flower/pull/2999), [#2979](https://github.com/adap/flower/pull/2979), [#3389](https://github.com/adap/flower/pull/3389), [#3503](https://github.com/adap/flower/pull/3503), [#3366](https://github.com/adap/flower/pull/3366), [#3357](https://github.com/adap/flower/pull/3357)) + + Flower 1.9 introduces the first build-in version of client node authentication. In previous releases, users often wrote glue code to connect Flower to external authentication systems. With this release, the SuperLink can authenticate SuperNodes using a built-in authentication system. A new [how-to guide](https://flower.ai/docs/framework/how-to-authenticate-supernodes.html) and a new [code example](https://github.com/adap/flower/tree/main/examples/flower-authentication) help you to get started. + + This is the first preview release of the Flower-native authentication system. Many additional features are on the roadmap for upcoming Flower releases - stay tuned. + +- **Introduce end-to-end Docker support** ([#3483](https://github.com/adap/flower/pull/3483), [#3266](https://github.com/adap/flower/pull/3266), [#3390](https://github.com/adap/flower/pull/3390), [#3283](https://github.com/adap/flower/pull/3283), [#3285](https://github.com/adap/flower/pull/3285), [#3391](https://github.com/adap/flower/pull/3391), [#3403](https://github.com/adap/flower/pull/3403), [#3458](https://github.com/adap/flower/pull/3458), [#3533](https://github.com/adap/flower/pull/3533), [#3453](https://github.com/adap/flower/pull/3453), [#3486](https://github.com/adap/flower/pull/3486), [#3290](https://github.com/adap/flower/pull/3290)) + + Full Flower Next Docker support is here! With the release of Flower 1.9, Flower provides stable Docker images for the Flower SuperLink, the Flower SuperNode, and the Flower `ServerApp`. This set of images enables you to run all Flower components in Docker. Check out the new [how-to guide](https://flower.ai/docs/framework/how-to-run-flower-using-docker.html) to get stated. + +- **Re-architect Flower Next simulation engine** ([#3307](https://github.com/adap/flower/pull/3307), [#3355](https://github.com/adap/flower/pull/3355), [#3272](https://github.com/adap/flower/pull/3272), [#3273](https://github.com/adap/flower/pull/3273), [#3417](https://github.com/adap/flower/pull/3417), [#3281](https://github.com/adap/flower/pull/3281), [#3343](https://github.com/adap/flower/pull/3343), [#3326](https://github.com/adap/flower/pull/3326)) + + Flower Next simulations now use a new in-memory `Driver` that improves the reliability of simulations, especially in notebook environments. This is a significant step towards a complete overhaul of the Flower Next simulation architecture. + +- **Upgrade simulation engine** ([#3354](https://github.com/adap/flower/pull/3354), [#3378](https://github.com/adap/flower/pull/3378), [#3262](https://github.com/adap/flower/pull/3262), [#3435](https://github.com/adap/flower/pull/3435), [#3501](https://github.com/adap/flower/pull/3501), [#3482](https://github.com/adap/flower/pull/3482), [#3494](https://github.com/adap/flower/pull/3494)) + + The Flower Next simulation engine comes with improved and configurable logging. The Ray-based simulation backend in Flower 1.9 was updated to use Ray 2.10. + +- **Introduce FedPFT baseline** ([#3268](https://github.com/adap/flower/pull/3268)) + + FedPFT allows you to perform one-shot Federated Learning by leveraging widely available foundational models, dramatically reducing communication costs while delivering high performing models. This is work led by Mahdi Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the details in their paper: "Parametric Feature Transfer: One-shot Federated Learning with Foundation Models" ([arxiv](https://arxiv.org/abs/2402.01862)) + +- **Launch additional** `flwr new` **templates for Apple MLX, Hugging Face Transformers, scikit-learn and TensorFlow** ([#3291](https://github.com/adap/flower/pull/3291), [#3139](https://github.com/adap/flower/pull/3139), [#3284](https://github.com/adap/flower/pull/3284), [#3251](https://github.com/adap/flower/pull/3251), [#3376](https://github.com/adap/flower/pull/3376), [#3287](https://github.com/adap/flower/pull/3287)) + + The `flwr` CLI's `flwr new` command is starting to become everone's favorite way of creating new Flower projects. This release introduces additional `flwr new` templates for Apple MLX, Hugging Face Transformers, scikit-learn and TensorFlow. In addition to that, existing templates also received updates. + +- **Refine** `RecordSet` **API** ([#3209](https://github.com/adap/flower/pull/3209), [#3331](https://github.com/adap/flower/pull/3331), [#3334](https://github.com/adap/flower/pull/3334), [#3335](https://github.com/adap/flower/pull/3335), [#3375](https://github.com/adap/flower/pull/3375), [#3368](https://github.com/adap/flower/pull/3368)) + + `RecordSet` is part of the Flower Next low-level API preview release. In Flower 1.9, `RecordSet` received a number of usability improvements that make it easier to build `RecordSet`-based `ServerApp`s and `ClientApp`s. + +- **Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), [#3430](https://github.com/adap/flower/pull/3430), [#3461](https://github.com/adap/flower/pull/3461), [#3360](https://github.com/adap/flower/pull/3360), [#3433](https://github.com/adap/flower/pull/3433)) + + Logs received a substantial update. Not only are logs now much nicer to look at, but they are also more configurable. + +- **Improve reliability** ([#3564](https://github.com/adap/flower/pull/3564), [#3561](https://github.com/adap/flower/pull/3561), [#3566](https://github.com/adap/flower/pull/3566), [#3462](https://github.com/adap/flower/pull/3462), [#3225](https://github.com/adap/flower/pull/3225), [#3514](https://github.com/adap/flower/pull/3514), [#3535](https://github.com/adap/flower/pull/3535), [#3372](https://github.com/adap/flower/pull/3372)) + + Flower 1.9 includes reliability improvements across many parts of the system. One example is a much improved SuperNode shutdown procedure. + +- **Update Swift and C++ SDKs** ([#3321](https://github.com/adap/flower/pull/3321), [#2763](https://github.com/adap/flower/pull/2763)) + + In the C++ SDK, communication-related code is now separate from main client logic. A new abstract class `Communicator` has been introduced alongside a gRPC implementation of it. + +- **Improve testing, tooling and CI/CD infrastructure** ([#3294](https://github.com/adap/flower/pull/3294), [#3282](https://github.com/adap/flower/pull/3282), [#3311](https://github.com/adap/flower/pull/3311), [#2878](https://github.com/adap/flower/pull/2878), [#3333](https://github.com/adap/flower/pull/3333), [#3255](https://github.com/adap/flower/pull/3255), [#3349](https://github.com/adap/flower/pull/3349), [#3400](https://github.com/adap/flower/pull/3400), [#3401](https://github.com/adap/flower/pull/3401), [#3399](https://github.com/adap/flower/pull/3399), [#3346](https://github.com/adap/flower/pull/3346), [#3398](https://github.com/adap/flower/pull/3398), [#3397](https://github.com/adap/flower/pull/3397), [#3347](https://github.com/adap/flower/pull/3347), [#3502](https://github.com/adap/flower/pull/3502), [#3387](https://github.com/adap/flower/pull/3387), [#3542](https://github.com/adap/flower/pull/3542), [#3396](https://github.com/adap/flower/pull/3396), [#3496](https://github.com/adap/flower/pull/3496), [#3465](https://github.com/adap/flower/pull/3465), [#3473](https://github.com/adap/flower/pull/3473), [#3484](https://github.com/adap/flower/pull/3484), [#3521](https://github.com/adap/flower/pull/3521), [#3363](https://github.com/adap/flower/pull/3363), [#3497](https://github.com/adap/flower/pull/3497), [#3464](https://github.com/adap/flower/pull/3464), [#3495](https://github.com/adap/flower/pull/3495), [#3478](https://github.com/adap/flower/pull/3478), [#3271](https://github.com/adap/flower/pull/3271)) + + As always, the Flower tooling, testing, and CI/CD infrastructure has received many updates. + +- **Improve documentation** ([#3530](https://github.com/adap/flower/pull/3530), [#3539](https://github.com/adap/flower/pull/3539), [#3425](https://github.com/adap/flower/pull/3425), [#3520](https://github.com/adap/flower/pull/3520), [#3286](https://github.com/adap/flower/pull/3286), [#3516](https://github.com/adap/flower/pull/3516), [#3523](https://github.com/adap/flower/pull/3523), [#3545](https://github.com/adap/flower/pull/3545), [#3498](https://github.com/adap/flower/pull/3498), [#3439](https://github.com/adap/flower/pull/3439), [#3440](https://github.com/adap/flower/pull/3440), [#3382](https://github.com/adap/flower/pull/3382), [#3559](https://github.com/adap/flower/pull/3559), [#3432](https://github.com/adap/flower/pull/3432), [#3278](https://github.com/adap/flower/pull/3278), [#3371](https://github.com/adap/flower/pull/3371), [#3519](https://github.com/adap/flower/pull/3519), [#3267](https://github.com/adap/flower/pull/3267), [#3204](https://github.com/adap/flower/pull/3204), [#3274](https://github.com/adap/flower/pull/3274)) + + As always, the Flower documentation has received many updates. Notable new pages include: + + - [How-to upgrate to Flower Next (Flower Next migration guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-next.html) + + - [How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-run-flower-using-docker.html) + + - [Flower Mods reference](https://flower.ai/docs/framework/ref-api/flwr.client.mod.html#module-flwr.client.mod) + +- **General updates to Flower Examples** ([#3205](https://github.com/adap/flower/pull/3205), [#3226](https://github.com/adap/flower/pull/3226), [#3211](https://github.com/adap/flower/pull/3211), [#3252](https://github.com/adap/flower/pull/3252), [#3427](https://github.com/adap/flower/pull/3427), [#3410](https://github.com/adap/flower/pull/3410), [#3426](https://github.com/adap/flower/pull/3426), [#3228](https://github.com/adap/flower/pull/3228), [#3342](https://github.com/adap/flower/pull/3342), [#3200](https://github.com/adap/flower/pull/3200), [#3202](https://github.com/adap/flower/pull/3202), [#3394](https://github.com/adap/flower/pull/3394), [#3488](https://github.com/adap/flower/pull/3488), [#3329](https://github.com/adap/flower/pull/3329), [#3526](https://github.com/adap/flower/pull/3526), [#3392](https://github.com/adap/flower/pull/3392), [#3474](https://github.com/adap/flower/pull/3474), [#3269](https://github.com/adap/flower/pull/3269)) + + As always, Flower code examples have received many updates. + +- **General improvements** ([#3532](https://github.com/adap/flower/pull/3532), [#3318](https://github.com/adap/flower/pull/3318), [#3565](https://github.com/adap/flower/pull/3565), [#3296](https://github.com/adap/flower/pull/3296), [#3305](https://github.com/adap/flower/pull/3305), [#3246](https://github.com/adap/flower/pull/3246), [#3224](https://github.com/adap/flower/pull/3224), [#3475](https://github.com/adap/flower/pull/3475), [#3297](https://github.com/adap/flower/pull/3297), [#3317](https://github.com/adap/flower/pull/3317), [#3429](https://github.com/adap/flower/pull/3429), [#3196](https://github.com/adap/flower/pull/3196), [#3534](https://github.com/adap/flower/pull/3534), [#3240](https://github.com/adap/flower/pull/3240), [#3365](https://github.com/adap/flower/pull/3365), [#3407](https://github.com/adap/flower/pull/3407), [#3563](https://github.com/adap/flower/pull/3563), [#3344](https://github.com/adap/flower/pull/3344), [#3330](https://github.com/adap/flower/pull/3330), [#3436](https://github.com/adap/flower/pull/3436), [#3300](https://github.com/adap/flower/pull/3300), [#3327](https://github.com/adap/flower/pull/3327), [#3254](https://github.com/adap/flower/pull/3254), [#3253](https://github.com/adap/flower/pull/3253), [#3419](https://github.com/adap/flower/pull/3419), [#3289](https://github.com/adap/flower/pull/3289), [#3208](https://github.com/adap/flower/pull/3208), [#3245](https://github.com/adap/flower/pull/3245), [#3319](https://github.com/adap/flower/pull/3319), [#3203](https://github.com/adap/flower/pull/3203), [#3423](https://github.com/adap/flower/pull/3423), [#3352](https://github.com/adap/flower/pull/3352), [#3292](https://github.com/adap/flower/pull/3292), [#3261](https://github.com/adap/flower/pull/3261)) + +### Deprecations + +- **Deprecate Python 3.8 support** + + Python 3.8 will stop receiving security fixes in [October 2024](https://devguide.python.org/versions/). Support for Python 3.8 is now deprecated and will be removed in an upcoming release. + +- **Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-api` ([#3416](https://github.com/adap/flower/pull/3416), [#3420](https://github.com/adap/flower/pull/3420)) + + Flower 1.9 deprecates the two (experimental) commands `flower-driver-api` and `flower-fleet-api`. Both commands will be removed in an upcoming release. Use `flower-superlink` instead. + +- **Deprecate** `--server` **in favor of** `--superlink` ([#3518](https://github.com/adap/flower/pull/3518)) + + The commands `flower-server-app` and `flower-client-app` should use `--superlink` instead of the now deprecated `--server`. Support for `--server` will be removed in a future release. + ### Incompatible changes -None +- **Replace** `flower-superlink` **CLI option** `--certificates` **with** `--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` ([#3512](https://github.com/adap/flower/pull/3512), [#3408](https://github.com/adap/flower/pull/3408)) + + SSL-related `flower-superlink` CLI arguments were restructured in an incompatible way. Instead of passing a single `--certificates` flag with three values, you now need to pass three flags (`--ssl-ca-certfile`, `--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the [SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-connections.html) documentation page for details. + +- **Remove SuperLink** `--vce` **option** ([#3513](https://github.com/adap/flower/pull/3513)) + + Instead of separately starting a SuperLink and a `ServerApp` for simulation, simulations must now be started using the single `flower-simulation` command. + +- **Merge** `--grpc-rere` **and** `--rest` **SuperLink options** ([#3527](https://github.com/adap/flower/pull/3527)) + + To simplify the usage of `flower-superlink`, previously separate sets of CLI options for gRPC and REST were merged into one unified set of options. Consult the [Flower CLI reference documentation](https://flower.ai/docs/framework/ref-api-cli.html) for details. ## v1.8.0 (2024-04-03) From 04ce922560253ec2764e41eaca4f8b8313a6a29f Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Mon, 10 Jun 2024 23:15:43 +0200 Subject: [PATCH 053/124] refactor(*:skip) Bump development version to Flower 1.10.0 (#3571) Co-authored-by: Daniel J. Beutel --- baselines/doc/source/conf.py | 2 +- dev/build-docker-image-matrix.py | 2 +- doc/source/conf.py | 2 +- doc/source/how-to-install-flower.rst | 2 +- examples/doc/source/conf.py | 2 +- pyproject.toml | 2 +- src/py/flwr/cli/config_utils_test.py | 8 ++++---- src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl | 2 +- src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl | 2 +- src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl | 2 +- .../flwr/cli/new/templates/app/pyproject.numpy.toml.tpl | 2 +- .../flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl | 2 +- .../flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl | 2 +- .../cli/new/templates/app/pyproject.tensorflow.toml.tpl | 2 +- 14 files changed, 17 insertions(+), 17 deletions(-) diff --git a/baselines/doc/source/conf.py b/baselines/doc/source/conf.py index a9525c44ab7b..8184bd223ea7 100644 --- a/baselines/doc/source/conf.py +++ b/baselines/doc/source/conf.py @@ -37,7 +37,7 @@ author = "The Flower Authors" # The full version, including alpha/beta/rc tags -release = "1.8.0" +release = "1.9.0" # -- General configuration --------------------------------------------------- diff --git a/dev/build-docker-image-matrix.py b/dev/build-docker-image-matrix.py index 5b9c63434bfb..51d7fd0083d1 100644 --- a/dev/build-docker-image-matrix.py +++ b/dev/build-docker-image-matrix.py @@ -1,5 +1,5 @@ """ -Usage: python dev/build-docker-image-matrix.py --flwr-version +Usage: python dev/build-docker-image-matrix.py --flwr-version """ import argparse diff --git a/doc/source/conf.py b/doc/source/conf.py index 174465c153b7..85bfe9404521 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -86,7 +86,7 @@ author = "The Flower Authors" # The full version, including alpha/beta/rc tags -release = "1.9.0" +release = "1.10.0" # -- General configuration --------------------------------------------------- diff --git a/doc/source/how-to-install-flower.rst b/doc/source/how-to-install-flower.rst index 964b23125c0b..725a7468090c 100644 --- a/doc/source/how-to-install-flower.rst +++ b/doc/source/how-to-install-flower.rst @@ -48,7 +48,7 @@ Verify installation The following command can be used to verify if Flower was successfully installed. If everything worked, it should print the version of Flower to the command line:: python -c "import flwr;print(flwr.__version__)" - 1.8.0 + 1.9.0 Advanced installation options diff --git a/examples/doc/source/conf.py b/examples/doc/source/conf.py index b9c18fba2e18..47847a0fd767 100644 --- a/examples/doc/source/conf.py +++ b/examples/doc/source/conf.py @@ -29,7 +29,7 @@ author = "The Flower Authors" # The full version, including alpha/beta/rc tags -release = "1.9.0" +release = "1.10.0" # -- General configuration --------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 1350cb7ee03c..a1a21a6b94cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "flwr" -version = "1.9.0" +version = "1.10.0" description = "Flower: A Friendly Federated Learning Framework" license = "Apache-2.0" authors = ["The Flower Authors "] diff --git a/src/py/flwr/cli/config_utils_test.py b/src/py/flwr/cli/config_utils_test.py index b47206249dfc..b24425cd08f4 100644 --- a/src/py/flwr/cli/config_utils_test.py +++ b/src/py/flwr/cli/config_utils_test.py @@ -39,7 +39,7 @@ def test_load_pyproject_toml_load_from_cwd(tmp_path: Path) -> None: ] license = {text = "Apache License (2.0)"} dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "numpy>=1.21.0", ] @@ -64,7 +64,7 @@ def test_load_pyproject_toml_load_from_cwd(tmp_path: Path) -> None: "description": "", "authors": [{"email": "hello@flower.ai", "name": "The Flower Authors"}], "license": {"text": "Apache License (2.0)"}, - "dependencies": ["flwr[simulation]>=1.8.0,<2.0", "numpy>=1.21.0"], + "dependencies": ["flwr[simulation]>=1.9.0,<2.0", "numpy>=1.21.0"], }, "flower": { "publisher": "flwrlabs", @@ -114,7 +114,7 @@ def test_load_pyproject_toml_from_path(tmp_path: Path) -> None: ] license = {text = "Apache License (2.0)"} dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "numpy>=1.21.0", ] @@ -139,7 +139,7 @@ def test_load_pyproject_toml_from_path(tmp_path: Path) -> None: "description": "", "authors": [{"email": "hello@flower.ai", "name": "The Flower Authors"}], "license": {"text": "Apache License (2.0)"}, - "dependencies": ["flwr[simulation]>=1.8.0,<2.0", "numpy>=1.21.0"], + "dependencies": ["flwr[simulation]>=1.9.0,<2.0", "numpy>=1.21.0"], }, "flower": { "publisher": "flwrlabs", diff --git a/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl index 6a235b7b15cf..71004f3421cd 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.hf.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets>=0.0.2,<1.0.0", "torch==2.2.1", "transformers>=4.30.0,<5.0" diff --git a/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl index 1d32cfd77481..c5463e08b92c 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.jax.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = {text = "Apache License (2.0)"} dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "jax==0.4.26", "jaxlib==0.4.26", "scikit-learn==1.4.2", diff --git a/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl index 321dfaab41cc..a850135a1fc5 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.mlx.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets[vision]>=0.0.2,<1.0.0", "mlx==0.10.0", "numpy==1.24.4", diff --git a/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl index 6b1c40d12561..d49015eb567f 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.numpy.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "numpy>=1.21.0", ] diff --git a/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl index df404d178495..b56c0041b96c 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.pytorch.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets[vision]>=0.0.2,<1.0.0", "torch==2.2.1", "torchvision==0.17.1", diff --git a/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl index 7ee655967c4a..6f914ae659b1 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.sklearn.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets[vision]>=0.0.2,<1.0.0", "scikit-learn>=1.1.1", ] diff --git a/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl index f453bce668fa..4ecd16143dcc 100644 --- a/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl +++ b/src/py/flwr/cli/new/templates/app/pyproject.tensorflow.toml.tpl @@ -11,7 +11,7 @@ authors = [ ] license = { text = "Apache License (2.0)" } dependencies = [ - "flwr[simulation]>=1.8.0,<2.0", + "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets[vision]>=0.0.2,<1.0.0", "tensorflow>=2.11.1", ] From 2f99e54080167d08343c702c9e025fff0b4b733a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 11 Jun 2024 09:29:23 +0200 Subject: [PATCH 054/124] docs(framework) Add latest Hosted Weblate translation updates (#3570) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 박태현 --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 176 +++++++++++++------ 1 file changed, 127 insertions(+), 49 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 17960b663150..3eda16eebb71 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -8,15 +8,16 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-28 11:47+0200\n" -"PO-Revision-Date: 2024-05-14 21:01+0000\n" -"Last-Translator: \"Young D. Kwon\" \n" +"PO-Revision-Date: 2024-06-11 06:22+0000\n" +"Last-Translator: 박태현 \n" +"Language-Team: Korean \n" "Language: ko\n" -"Language-Team: Korean \n" -"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -66,21 +67,27 @@ msgid "" "is what you need. In this guide, we will explain what images exist and " "how to build them locally." msgstr "" +"Flower는 'Docker Hub '_에서 미리 만들어진 " +"Docker 이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 " +"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 " +"다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 " +"정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 " +"이미지들과 이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." #: ../../source/contributor-how-to-build-docker-images.rst:9 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." -msgstr "" +msgstr "시작하기 전에, 로컬 개발 환경에서 몇 가지 전제 조건을 충족해야 합니다." #: ../../source/contributor-how-to-build-docker-images.rst:11 msgid "Clone the flower repository." -msgstr "" +msgstr "Flower 리포지토리를 복제합니다." #: ../../source/contributor-how-to-build-docker-images.rst:17 #: ../../source/how-to-run-flower-using-docker.rst:144 msgid "Verify the Docker daemon is running." -msgstr "" +msgstr "Docker 데몬이 실행 중인지 확인하십시오." #: ../../source/contributor-how-to-build-docker-images.rst:19 #: ../../source/how-to-run-flower-using-docker.rst:146 @@ -88,6 +95,8 @@ msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" +":doc:Run Flower using Docker 의 첫 번째 " +"섹션을 따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." #: ../../source/contributor-how-to-build-docker-images.rst:23 msgid "" @@ -97,6 +106,11 @@ msgid "" "dependencies, Python and Python tools. The SuperLink image is based on " "the base image, but it additionally installs the SuperLink using ``pip``." msgstr "" +"현재, Flower는 \"base\" 이미지 그리고 \"superlink\" 이미지를 제공합니다. " +"base 이미지는 이름에서 알 수 있듯이 SuperLink가 필요로 하는 기본 " +"dependencies를 포함하고 있습니다. 여기에는 시스템 dependencies, Python 및 " +"Python 도구가 포함됩니다. SuperLink 이미지는 base 이미지를 기반으로 하지만 " +"\"pip\"을 사용하여 SuperLink를 추가로 설치합니다." #: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" @@ -104,6 +118,8 @@ msgid "" "respective Dockerfiles. You can find them in the subdirectories of " "``src/docker``." msgstr "" +"이미지들을 조합하는 빌드 instruction들은 해당 Dockerfile에 있습니다. \"src/" +"docker\" 의 하위 디렉토리에서 찾을 수 있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:31 msgid "" @@ -115,93 +131,101 @@ msgid "" " image. All available build arguments for each image are listed in one of" " the tables below." msgstr "" +"base 이미지와 SuperLink 이미지 둘 다 빌드 argument들을 통해 구성됩니다. 빌드 " +"argument들을 통해, 빌드를 더 유연하게 만들 수 있습니다. 예를 들어, base " +"이미지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 " +"수 있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 " +"합니다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 " +"있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:38 msgid "Building the base image" -msgstr "" +msgstr "base 이미지 빌드" #: ../../source/contributor-how-to-build-docker-images.rst:44 #: ../../source/contributor-how-to-build-docker-images.rst:86 msgid "Build argument" -msgstr "" +msgstr "빌드 argument" #: ../../source/contributor-how-to-build-docker-images.rst:45 #: ../../source/contributor-how-to-build-docker-images.rst:87 msgid "Description" -msgstr "" +msgstr "설명" #: ../../source/contributor-how-to-build-docker-images.rst:46 #: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "Required" -msgstr "" +msgstr "필수" #: ../../source/contributor-how-to-build-docker-images.rst:47 #: ../../source/contributor-how-to-build-docker-images.rst:89 msgid "Example" -msgstr "" +msgstr "예시" #: ../../source/contributor-how-to-build-docker-images.rst:48 #: ../../source/contributor-how-to-build-docker-images.rst:94 msgid "``PYTHON_VERSION``" -msgstr "" +msgstr "``PYTHON_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:49 msgid "Version of ``python`` to be installed." -msgstr "" +msgstr "설치 된 ``python`` 버전." #: ../../source/contributor-how-to-build-docker-images.rst:50 #: ../../source/contributor-how-to-build-docker-images.rst:54 #: ../../source/contributor-how-to-build-docker-images.rst:58 #: ../../source/contributor-how-to-build-docker-images.rst:108 msgid "Yes" -msgstr "" +msgstr "예" #: ../../source/contributor-how-to-build-docker-images.rst:51 msgid "``3.11``" -msgstr "" +msgstr "``3.11``" #: ../../source/contributor-how-to-build-docker-images.rst:52 msgid "``PIP_VERSION``" -msgstr "" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:53 msgid "Version of ``pip`` to be installed." -msgstr "" +msgstr "설치 된 ``pip`` 버전." #: ../../source/contributor-how-to-build-docker-images.rst:55 msgid "``23.0.1``" -msgstr "" +msgstr "``23.0.1``" #: ../../source/contributor-how-to-build-docker-images.rst:56 msgid "``SETUPTOOLS_VERSION``" -msgstr "" +msgstr "``SETUPTOOLS_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:57 msgid "Version of ``setuptools`` to be installed." -msgstr "" +msgstr "설치 된 ``setuptools`` 버전." #: ../../source/contributor-how-to-build-docker-images.rst:59 msgid "``69.0.2``" -msgstr "" +msgstr "``69.0.2``" #: ../../source/contributor-how-to-build-docker-images.rst:60 #: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "``UBUNTU_VERSION``" -msgstr "" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:61 msgid "Version of the official Ubuntu Docker image." -msgstr "" +msgstr "공식 Ubuntu Docker 이미지 버전." #: ../../source/contributor-how-to-build-docker-images.rst:62 msgid "Defaults to ``22.04``." -msgstr "" +msgstr "``22.04``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:65 msgid "" "The following example creates a base image with Python 3.11.0, pip 23.0.1" " and setuptools 69.0.2:" msgstr "" +"다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base " +"이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:76 msgid "" @@ -209,68 +233,73 @@ msgid "" "the build arguments as well as the name and tag can be adapted to your " "needs. These values serve as examples only." msgstr "" +"이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 " +"argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 " +"뿐입니다." #: ../../source/contributor-how-to-build-docker-images.rst:80 msgid "Building the SuperLink image" -msgstr "" +msgstr "SuperLink 이미지 빌드" #: ../../source/contributor-how-to-build-docker-images.rst:90 msgid "``BASE_REPOSITORY``" -msgstr "" +msgstr "``BASE_REPOSITORY``" #: ../../source/contributor-how-to-build-docker-images.rst:91 msgid "The repository name of the base image." -msgstr "" +msgstr "base 이미지의 리포지토리 이름." #: ../../source/contributor-how-to-build-docker-images.rst:92 msgid "Defaults to ``flwr/base``." -msgstr "" +msgstr "``flwr/base``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:95 msgid "The Python version of the base image." -msgstr "" +msgstr "base 이미지의 Python 버전." #: ../../source/contributor-how-to-build-docker-images.rst:96 msgid "Defaults to ``py3.11``." -msgstr "" +msgstr "``py3.11``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:99 msgid "The Ubuntu version of the base image." -msgstr "" +msgstr "base 이미지의 Ubuntu 버전." #: ../../source/contributor-how-to-build-docker-images.rst:100 msgid "Defaults to ``ubuntu22.04``." -msgstr "" +msgstr "``ubuntu22.04``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:102 msgid "``FLWR_PACKAGE``" -msgstr "" +msgstr "``FLWR_PACKAGE``" #: ../../source/contributor-how-to-build-docker-images.rst:103 msgid "The PyPI package to install." -msgstr "" +msgstr "설치 할 PyPI 패키지." #: ../../source/contributor-how-to-build-docker-images.rst:104 msgid "Defaults to ``flwr``." -msgstr "" +msgstr "``flwr``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:106 msgid "``FLWR_VERSION``" -msgstr "" +msgstr "``FLWR_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:107 msgid "Version of Flower to be installed." -msgstr "" +msgstr "설치 된 Flower 버전." #: ../../source/contributor-how-to-build-docker-images.rst:109 msgid "``1.8.0``" -msgstr "" +msgstr "``1.8.0``" #: ../../source/contributor-how-to-build-docker-images.rst:112 msgid "" "The following example creates a SuperLink image with the official Flower " "base image py3.11-ubuntu22.04 and Flower 1.8.0:" msgstr "" +"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base " +"이미지로 SuperLink 이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" @@ -278,6 +307,9 @@ msgid "" "that the build arguments as well as the name and tag can be adapted to " "your needs. These values serve as examples only." msgstr "" +"이미지의 이름은 ``flwr_superlink``이고 태그는 ``0.1.0``입니다. 필요에 따라 " +"빌드 argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 " +"뿐입니다." #: ../../source/contributor-how-to-build-docker-images.rst:125 msgid "" @@ -285,14 +317,17 @@ msgid "" "base image, all you need to do is set the ``BASE_REPOSITORY``, " "``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." msgstr "" +"공식 Flower base 이미지 대신 자체 base 이미지를 사용 하길 원한다면, " +"``BASE_REPOSITORY``, ``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 " +"argument들을 설정해야 합니다." #: ../../source/contributor-how-to-build-docker-images.rst:138 msgid "After creating the image, we can test whether the image is working:" -msgstr "" +msgstr "이미지 생성 후에, 이미지가 작동하는지 테스트할 수 있습니다:" #: ../../source/contributor-how-to-contribute-translations.rst:2 msgid "Contribute translations" -msgstr "" +msgstr "번역 기여" #: ../../source/contributor-how-to-contribute-translations.rst:4 msgid "" @@ -305,6 +340,12 @@ msgid "" "also be a great opportunity for those wanting to become open source " "contributors with little prerequisites." msgstr "" +"`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 " +"번역이 불안전한 경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 " +"사람들이 Federated Learning에 접근할 수 있도록 번역 작업에 기여함으로써 " +"저희의 노력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 " +"기여자가 되고자 하는 사람들에게 좋은 기회가 될 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" @@ -312,10 +353,12 @@ msgid "" "`_, this " "where most of the work will happen." msgstr "" +"번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." #: ../../source/contributor-how-to-contribute-translations.rst:18 msgid "Contribute to existing languages" -msgstr "" +msgstr "기존 언어에 기여하기" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" @@ -325,6 +368,10 @@ msgid "" " profile settings can be found `here " "`_." msgstr "" +"기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page `_에서 무료 Weblate 계정을 만드는 것입니다. 프로필 " +"설정에 대한 자세한 정보는 `here `_를 참조하세요." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" @@ -333,12 +380,15 @@ msgid "" "docs/framework/>`_. Here, you should see the different existing languages" " that can be found on the website." msgstr "" +"Weblate에 로그인한 후, `Flower Framework project `_로 이동할 수 있습니다. 여기에서 웹사이트에 " +"있는 다양한 기존 언어들을 확인할 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" "Once you have selected the language you want to contribute to, you should" " see a similar interface to this:" -msgstr "" +msgstr "기여하고자 하는 언어를 선택하면, 다음과 같은 인터페이스가 나타납니다:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" @@ -347,10 +397,13 @@ msgid "" "will automatically bring you to the translation interface for " "untranslated strings." msgstr "" +"여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 " +"``Translate`` 버튼을 클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 " +"인터페이스로 자동으로 이동합니다." #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" -msgstr "" +msgstr "인터페이스는 다음과 같습니다:" #: ../../source/contributor-how-to-contribute-translations.rst:47 msgid "" @@ -361,6 +414,11 @@ msgid "" "your translation to suggestions for other users to view), or ``Skip`` (to" " go to the next untranslated string without saving anything)." msgstr "" +"번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and " +"continue``(번역을 저장하고 다음 미번역 문장으로 이동), ``Save and stay``(" +"번역을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 볼 수 " +"있도록 번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 " +"문장으로 이동) 중 하나를 선택하면 됩니다." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" @@ -370,13 +428,17 @@ msgid "" "translations in ``Other languages``, and the ``History`` of translations " "for this string." msgstr "" +"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``" +"자동 제안``(기계 번역의), ``다른 언어``의 번역 및 해당 문장의 " +"번역``히스토리``를 볼 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" "On the right, under the ``String information`` section, you can also " "click the link under ``Source string location`` in order to view the " "source of the doc file containing the string." -msgstr "" +msgstr "오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 " +"포함된 문서의 파일 소스를 볼 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" @@ -384,10 +446,12 @@ msgid "" "this `in-depth guide " "`_." msgstr "" +"Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide `_를 확인하세요." #: ../../source/contributor-how-to-contribute-translations.rst:67 msgid "Add new languages" -msgstr "" +msgstr "새 언어 추가" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" @@ -395,6 +459,9 @@ msgid "" "either on `Slack `_, or by opening an issue" " on our `GitHub repo `_." msgstr "" +"새 언어를 추가하려면, `Slack `에 문의하거나 `" +"GitHub repo `_에서 issue에 들어가 문의 해야 " +"합니다." #: ../../source/contributor-how-to-create-new-messages.rst:2 msgid "Creating New Messages" @@ -511,7 +578,7 @@ msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" -msgstr "" +msgstr "VSCode Dev Container에서 개발" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" @@ -520,6 +587,10 @@ msgid "" "tests. For this purpose we are using the VSCode Remote Containers " "extension. What is it? Read the following quote:" msgstr "" +"Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 " +"동일한 개발 환경을 사용하길 원합니다. 이를 위해 VSCode Remote Containers " +"확장을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 " +"읽어보세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" @@ -533,6 +604,14 @@ msgid "" "separate tools, libraries, or runtimes needed for working with a " "codebase." msgstr "" +"Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 " +"기능을 갖춘 개발 환경으로 사용할 수 있습니다. 이 확장 기능을 사용하면 " +"컨테이너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio " +"Code의 모든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer." +"json` 파일은 잘 정의된 도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(" +"또는 생성)하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 애플리케이션을 " +"실행하거나 코드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 " +"데 사용할 수 있습니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" @@ -21224,4 +21303,3 @@ msgstr "" #~ msgid "|2c13f726c8c843fc8aae997bf906125b|" #~ msgstr "" - From 6ffcf006f80ee72f4436d2008cbb24a3d857f4d8 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Tue, 11 Jun 2024 09:35:04 +0200 Subject: [PATCH 055/124] docs(framework) Add latest Hosted Weblate translation updates (#3572) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 박태현 --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 10975 ++++++++--------- 1 file changed, 4950 insertions(+), 6025 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 3eda16eebb71..68440f928f08 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -30,9 +30,11 @@ msgstr "엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" -"`Flower `_ core framework architecture with Edge " -"Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔진" +"`Flower `_ core framework architecture with Edge Client " +"Engine" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔" +"진" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" @@ -42,7 +44,9 @@ msgstr "가상 클라이언트 엔진" msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔진" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔" +"진" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" @@ -50,9 +54,11 @@ msgstr "동일 작업에서 가상 클라이언트 엔진과 엣지 클라이언 #: ../../source/contributor-explanation-architecture.rst:23 msgid "" -"`Flower `_ core framework architecture with both " -"Virtual Client Engine and Edge Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라이언트 엔진" +"`Flower `_ core framework architecture with both Virtual " +"Client Engine and Edge Client Engine" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라" +"이언트 엔진" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" @@ -60,19 +66,18 @@ msgstr "Docker Flower 이미지를 Locally 구축하는 방법" #: ../../source/contributor-how-to-build-docker-images.rst:4 msgid "" -"Flower provides pre-made docker images on `Docker Hub " -"`_ that include all necessary dependencies" -" for running the SuperLink. You can also build your own custom docker " -"images from scratch with a different version of Python or Ubuntu if that " -"is what you need. In this guide, we will explain what images exist and " -"how to build them locally." +"Flower provides pre-made docker images on `Docker Hub `_ that include all necessary dependencies for running the " +"SuperLink. You can also build your own custom docker images from scratch " +"with a different version of Python or Ubuntu if that is what you need. In " +"this guide, we will explain what images exist and how to build them locally." msgstr "" "Flower는 'Docker Hub '_에서 미리 만들어진 " "Docker 이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 " -"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 " -"다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 " -"정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 " -"이미지들과 이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." +"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 다" +"른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 정" +"의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 이미지들과 " +"이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." #: ../../source/contributor-how-to-build-docker-images.rst:9 msgid "" @@ -92,51 +97,49 @@ msgstr "Docker 데몬이 실행 중인지 확인하십시오." #: ../../source/contributor-how-to-build-docker-images.rst:19 #: ../../source/how-to-run-flower-using-docker.rst:146 msgid "" -"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." +"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -":doc:Run Flower using Docker 의 첫 번째 " -"섹션을 따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." +":doc:Run Flower using Docker 의 첫 번째 섹션" +"을 따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." #: ../../source/contributor-how-to-build-docker-images.rst:23 msgid "" -"Currently, Flower provides two images, a ``base`` image and a " -"``superlink`` image. The base image, as the name suggests, contains basic" -" dependencies that the SuperLink needs. This includes system " -"dependencies, Python and Python tools. The SuperLink image is based on " -"the base image, but it additionally installs the SuperLink using ``pip``." +"Currently, Flower provides two images, a ``base`` image and a ``superlink`` " +"image. The base image, as the name suggests, contains basic dependencies " +"that the SuperLink needs. This includes system dependencies, Python and " +"Python tools. The SuperLink image is based on the base image, but it " +"additionally installs the SuperLink using ``pip``." msgstr "" "현재, Flower는 \"base\" 이미지 그리고 \"superlink\" 이미지를 제공합니다. " -"base 이미지는 이름에서 알 수 있듯이 SuperLink가 필요로 하는 기본 " -"dependencies를 포함하고 있습니다. 여기에는 시스템 dependencies, Python 및 " -"Python 도구가 포함됩니다. SuperLink 이미지는 base 이미지를 기반으로 하지만 " -"\"pip\"을 사용하여 SuperLink를 추가로 설치합니다." +"base 이미지는 이름에서 알 수 있듯이 SuperLink가 필요로 하는 기본 dependencies" +"를 포함하고 있습니다. 여기에는 시스템 dependencies, Python 및 Python 도구가 " +"포함됩니다. SuperLink 이미지는 base 이미지를 기반으로 하지만 \"pip\"을 사용하" +"여 SuperLink를 추가로 설치합니다." #: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" "The build instructions that assemble the images are located in the " -"respective Dockerfiles. You can find them in the subdirectories of " -"``src/docker``." +"respective Dockerfiles. You can find them in the subdirectories of ``src/" +"docker``." msgstr "" "이미지들을 조합하는 빌드 instruction들은 해당 Dockerfile에 있습니다. \"src/" "docker\" 의 하위 디렉토리에서 찾을 수 있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:31 msgid "" -"Both, base and SuperLink image are configured via build arguments. " -"Through build arguments, we can make our build more flexible. For " -"example, in the base image, we can specify the version of Python to " -"install using the ``PYTHON_VERSION`` build argument. Some of the build " -"arguments have default values, others must be specified when building the" -" image. All available build arguments for each image are listed in one of" -" the tables below." +"Both, base and SuperLink image are configured via build arguments. Through " +"build arguments, we can make our build more flexible. For example, in the " +"base image, we can specify the version of Python to install using the " +"``PYTHON_VERSION`` build argument. Some of the build arguments have default " +"values, others must be specified when building the image. All available " +"build arguments for each image are listed in one of the tables below." msgstr "" "base 이미지와 SuperLink 이미지 둘 다 빌드 argument들을 통해 구성됩니다. 빌드 " -"argument들을 통해, 빌드를 더 유연하게 만들 수 있습니다. 예를 들어, base " -"이미지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 " -"수 있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 " -"합니다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 " -"있습니다." +"argument들을 통해, 빌드를 더 유연하게 만들 수 있습니다. 예를 들어, base 이미" +"지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 수 있" +"습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 합니" +"다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:38 msgid "Building the base image" @@ -221,21 +224,21 @@ msgstr "``22.04``이 기본값." #: ../../source/contributor-how-to-build-docker-images.rst:65 msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1" -" and setuptools 69.0.2:" +"The following example creates a base image with Python 3.11.0, pip 23.0.1 " +"and setuptools 69.0.2:" msgstr "" -"다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base " -"이미지를 만듭니다:" +"다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base 이" +"미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:76 msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the " +"build arguments as well as the name and tag can be adapted to your needs. " +"These values serve as examples only." msgstr "" "이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 " -"argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 " -"뿐입니다." +"argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 뿐입" +"니다." #: ../../source/contributor-how-to-build-docker-images.rst:80 msgid "Building the SuperLink image" @@ -298,28 +301,28 @@ msgid "" "The following example creates a SuperLink image with the official Flower " "base image py3.11-ubuntu22.04 and Flower 1.8.0:" msgstr "" -"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base " -"이미지로 SuperLink 이미지를 만듭니다:" +"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base 이미지" +"로 SuperLink 이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" -"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " -"that the build arguments as well as the name and tag can be adapted to " -"your needs. These values serve as examples only." +"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember that " +"the build arguments as well as the name and tag can be adapted to your " +"needs. These values serve as examples only." msgstr "" -"이미지의 이름은 ``flwr_superlink``이고 태그는 ``0.1.0``입니다. 필요에 따라 " -"빌드 argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 " -"뿐입니다." +"이미지의 이름은 ``flwr_superlink``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌" +"드 argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 뿐" +"입니다." #: ../../source/contributor-how-to-build-docker-images.rst:125 msgid "" -"If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." +"If you want to use your own base image instead of the official Flower base " +"image, all you need to do is set the ``BASE_REPOSITORY``, ``PYTHON_VERSION`` " +"and ``UBUNTU_VERSION`` build arguments." msgstr "" "공식 Flower base 이미지 대신 자체 base 이미지를 사용 하길 원한다면, " -"``BASE_REPOSITORY``, ``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 " -"argument들을 설정해야 합니다." +"``BASE_REPOSITORY``, ``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 argument들" +"을 설정해야 합니다." #: ../../source/contributor-how-to-build-docker-images.rst:138 msgid "After creating the image, we can test whether the image is working:" @@ -331,27 +334,27 @@ msgstr "번역 기여" #: ../../source/contributor-how-to-contribute-translations.rst:4 msgid "" -"Since `Flower 1.5 `_ we have introduced translations to " -"our doc pages, but, as you might have noticed, the translations are often" -" imperfect. If you speak languages other than English, you might be able " -"to help us in our effort to make Federated Learning accessible to as many" -" people as possible by contributing to those translations! This might " -"also be a great opportunity for those wanting to become open source " -"contributors with little prerequisites." +"Since `Flower 1.5 `_ we have introduced translations to our doc pages, " +"but, as you might have noticed, the translations are often imperfect. If you " +"speak languages other than English, you might be able to help us in our " +"effort to make Federated Learning accessible to as many people as possible " +"by contributing to those translations! This might also be a great " +"opportunity for those wanting to become open source contributors with little " +"prerequisites." msgstr "" "`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 " -"번역이 불안전한 경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 " -"사람들이 Federated Learning에 접근할 수 있도록 번역 작업에 기여함으로써 " -"저희의 노력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 " -"기여자가 되고자 하는 사람들에게 좋은 기회가 될 수도 있습니다." +"html#v1-5-0-2023-08-31>`_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 번" +"역이 불안전한 경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 사람" +"들이 Federated Learning에 접근할 수 있도록 번역 작업에 기여함으로써 저희의 노" +"력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 기여자가 " +"되고자 하는 사람들에게 좋은 기회가 될 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" -"Our translation project is publicly available over on `Weblate " -"`_, this " -"where most of the work will happen." +"Our translation project is publicly available over on `Weblate `_, this where most of " +"the work will happen." msgstr "" "번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." @@ -362,23 +365,22 @@ msgstr "기존 언어에 기여하기" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" -"The first thing you will need to do in order to contribute is to create a" -" free Weblate account on this `page " -"`_. More information about" -" profile settings can be found `here " +"The first thing you will need to do in order to contribute is to create a " +"free Weblate account on this `page `_. More information about profile settings can be found `here " "`_." msgstr "" "기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page `_에서 무료 Weblate 계정을 만드는 것입니다. 프로필 " -"설정에 대한 자세한 정보는 `here `_에서 무료 Weblate 계정을 만드는 것입니다. 프로필 설" +"정에 대한 자세한 정보는 `here `_를 참조하세요." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" -"Once you are signed in to Weblate, you can navigate to the `Flower " -"Framework project `_. Here, you should see the different existing languages" -" that can be found on the website." +"Once you are signed in to Weblate, you can navigate to the `Flower Framework " +"project `_. " +"Here, you should see the different existing languages that can be found on " +"the website." msgstr "" "Weblate에 로그인한 후, `Flower Framework project `_로 이동할 수 있습니다. 여기에서 웹사이트에 " @@ -386,20 +388,20 @@ msgstr "" #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" -"Once you have selected the language you want to contribute to, you should" -" see a similar interface to this:" +"Once you have selected the language you want to contribute to, you should " +"see a similar interface to this:" msgstr "기여하고자 하는 언어를 선택하면, 다음과 같은 인터페이스가 나타납니다:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" "The most straight forward option here is to click on the ``Translate`` " -"button on the top right (in the ``Translation status`` section). This " -"will automatically bring you to the translation interface for " -"untranslated strings." +"button on the top right (in the ``Translation status`` section). This will " +"automatically bring you to the translation interface for untranslated " +"strings." msgstr "" "여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 " -"``Translate`` 버튼을 클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 " -"인터페이스로 자동으로 이동합니다." +"``Translate`` 버튼을 클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 인터" +"페이스로 자동으로 이동합니다." #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" @@ -407,44 +409,44 @@ msgstr "인터페이스는 다음과 같습니다:" #: ../../source/contributor-how-to-contribute-translations.rst:47 msgid "" -"You input your translation in the text box at the top and then, once you " -"are happy with it, you either press ``Save and continue`` (to save the " -"translation and go to the next untranslated string), ``Save and stay`` " -"(to save the translation and stay on the same page), ``Suggest`` (to add " -"your translation to suggestions for other users to view), or ``Skip`` (to" -" go to the next untranslated string without saving anything)." +"You input your translation in the text box at the top and then, once you are " +"happy with it, you either press ``Save and continue`` (to save the " +"translation and go to the next untranslated string), ``Save and stay`` (to " +"save the translation and stay on the same page), ``Suggest`` (to add your " +"translation to suggestions for other users to view), or ``Skip`` (to go to " +"the next untranslated string without saving anything)." msgstr "" "번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and " -"continue``(번역을 저장하고 다음 미번역 문장으로 이동), ``Save and stay``(" -"번역을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 볼 수 " -"있도록 번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 " -"문장으로 이동) 중 하나를 선택하면 됩니다." +"continue``(번역을 저장하고 다음 미번역 문장으로 이동), ``Save and stay``(번역" +"을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 볼 수 있도록 " +"번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 문장으" +"로 이동) 중 하나를 선택하면 됩니다." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" "In order to help with the translations, you can see on the bottom the " "``Nearby strings``, the ``Comments`` (from other contributors), the " "``Automatic suggestions`` (from machine translation engines), the " -"translations in ``Other languages``, and the ``History`` of translations " -"for this string." +"translations in ``Other languages``, and the ``History`` of translations for " +"this string." msgstr "" -"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``" -"자동 제안``(기계 번역의), ``다른 언어``의 번역 및 해당 문장의 " -"번역``히스토리``를 볼 수 있습니다." +"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``자" +"동 제안``(기계 번역의), ``다른 언어``의 번역 및 해당 문장의 번역``히스토리``" +"를 볼 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" -"On the right, under the ``String information`` section, you can also " -"click the link under ``Source string location`` in order to view the " -"source of the doc file containing the string." -msgstr "오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 " -"포함된 문서의 파일 소스를 볼 수도 있습니다." +"On the right, under the ``String information`` section, you can also click " +"the link under ``Source string location`` in order to view the source of the " +"doc file containing the string." +msgstr "" +"오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 포함" +"된 문서의 파일 소스를 볼 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" -"For more information about translating using Weblate, you can check out " -"this `in-depth guide " -"`_." +"For more information about translating using Weblate, you can check out this " +"`in-depth guide `_." msgstr "" "Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide `_를 확인하세요." @@ -455,12 +457,12 @@ msgstr "새 언어 추가" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" -"If you want to add a new language, you will first have to contact us, " -"either on `Slack `_, or by opening an issue" -" on our `GitHub repo `_." +"If you want to add a new language, you will first have to contact us, either " +"on `Slack `_, or by opening an issue on our " +"`GitHub repo `_." msgstr "" -"새 언어를 추가하려면, `Slack `에 문의하거나 `" -"GitHub repo `_에서 issue에 들어가 문의 해야 " +"새 언어를 추가하려면, `Slack `에 문의하거나 " +"`GitHub repo `_에서 issue에 들어가 문의 해야 " "합니다." #: ../../source/contributor-how-to-create-new-messages.rst:2 @@ -469,14 +471,14 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:4 msgid "" -"This is a simple guide for creating a new type of message between the " -"server and clients in Flower." +"This is a simple guide for creating a new type of message between the server " +"and clients in Flower." msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:6 msgid "" -"Let's suppose we have the following example functions in " -":code:`server.py` and :code:`numpy_client.py`..." +"Let's suppose we have the following example functions in :code:`server.py` " +"and :code:`numpy_client.py`..." msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:8 @@ -489,8 +491,8 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:26 msgid "" -"Let's now see what we need to implement in order to get this simple " -"function between the server and client to work!" +"Let's now see what we need to implement in order to get this simple function " +"between the server and client to work!" msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:30 @@ -499,11 +501,11 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:32 msgid "" -"The first thing we need to do is to define a message type for the RPC " -"system in :code:`transport.proto`. Note that we have to do it for both " -"the request and response messages. For more details on the syntax of " -"proto3, please see the `official documentation `_." +"The first thing we need to do is to define a message type for the RPC system " +"in :code:`transport.proto`. Note that we have to do it for both the request " +"and response messages. For more details on the syntax of proto3, please see " +"the `official documentation `_." msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:35 @@ -516,8 +518,8 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:70 msgid "" -"Make sure to also add a field of the newly created message type in " -":code:`oneof msg`." +"Make sure to also add a field of the newly created message type in :code:" +"`oneof msg`." msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:72 @@ -549,8 +551,8 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:114 msgid "" -"Now write the request function in your Client Proxy class (e.g., " -":code:`grpc_client_proxy.py`) using the serde functions you just created:" +"Now write the request function in your Client Proxy class (e.g., :code:" +"`grpc_client_proxy.py`) using the serde functions you just created:" msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:128 @@ -559,9 +561,9 @@ msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:130 msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the " -"field of your message and call the :code:`example_response` function. " -"Remember to use the serde functions!" +"Last step! Modify the code in :code:`message_handler.py` to check the field " +"of your message and call the :code:`example_response` function. Remember to " +"use the serde functions!" msgstr "" #: ../../source/contributor-how-to-create-new-messages.rst:132 @@ -582,50 +584,48 @@ msgstr "VSCode Dev Container에서 개발" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" -"When working on the Flower framework we want to ensure that all " -"contributors use the same developer environment to format code or run " -"tests. For this purpose we are using the VSCode Remote Containers " -"extension. What is it? Read the following quote:" +"When working on the Flower framework we want to ensure that all contributors " +"use the same developer environment to format code or run tests. For this " +"purpose we are using the VSCode Remote Containers extension. What is it? " +"Read the following quote:" msgstr "" "Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 " -"동일한 개발 환경을 사용하길 원합니다. 이를 위해 VSCode Remote Containers " -"확장을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 " -"읽어보세요:" +"동일한 개발 환경을 사용하길 원합니다. 이를 위해 VSCode Remote Containers 확장" +"을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 읽어보세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" -"The Visual Studio Code Remote - Containers extension lets you use a " -"Docker container as a fully-featured development environment. It allows " -"you to open any folder inside (or mounted into) a container and take " -"advantage of Visual Studio Code's full feature set. A " -":code:`devcontainer.json` file in your project tells VS Code how to " -"access (or create) a development container with a well-defined tool and " -"runtime stack. This container can be used to run an application or to " -"separate tools, libraries, or runtimes needed for working with a " -"codebase." +"The Visual Studio Code Remote - Containers extension lets you use a Docker " +"container as a fully-featured development environment. It allows you to open " +"any folder inside (or mounted into) a container and take advantage of Visual " +"Studio Code's full feature set. A :code:`devcontainer.json` file in your " +"project tells VS Code how to access (or create) a development container with " +"a well-defined tool and runtime stack. This container can be used to run an " +"application or to separate tools, libraries, or runtimes needed for working " +"with a codebase." msgstr "" "Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 " -"기능을 갖춘 개발 환경으로 사용할 수 있습니다. 이 확장 기능을 사용하면 " -"컨테이너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio " -"Code의 모든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer." -"json` 파일은 잘 정의된 도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(" -"또는 생성)하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 애플리케이션을 " -"실행하거나 코드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 " -"데 사용할 수 있습니다." +"기능을 갖춘 개발 환경으로 사용할 수 있습니다. 이 확장 기능을 사용하면 컨테이" +"너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio Code의 모" +"든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer.json` 파일" +"은 잘 정의된 도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(또는 생성)" +"하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 애플리케이션을 실행하거나 코" +"드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 데 사용할 수 " +"있습니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" -"Workspace files are mounted from the local file system or copied or " -"cloned into the container. Extensions are installed and run inside the " -"container, where they have full access to the tools, platform, and file " -"system. This means that you can seamlessly switch your entire development" -" environment just by connecting to a different container." +"Workspace files are mounted from the local file system or copied or cloned " +"into the container. Extensions are installed and run inside the container, " +"where they have full access to the tools, platform, and file system. This " +"means that you can seamlessly switch your entire development environment " +"just by connecting to a different container." msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 msgid "" -"Source: `Official VSCode documentation " -"`_" +"Source: `Official VSCode documentation `_" msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 @@ -634,42 +634,40 @@ msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 msgid "" -"Configuring and setting up the :code:`Dockerfile` as well the " -"configuration for the devcontainer can be a bit more involved. The good " -"thing is you don't have to do it. Usually it should be enough to install " -"`Docker `_ on your system and " -"ensure its available on your command line. Additionally, install the " -"`VSCode Containers Extension `_." +"Configuring and setting up the :code:`Dockerfile` as well the configuration " +"for the devcontainer can be a bit more involved. The good thing is you don't " +"have to do it. Usually it should be enough to install `Docker `_ on your system and ensure its available on " +"your command line. Additionally, install the `VSCode Containers Extension " +"`_." msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" -"Now you should be good to go. When starting VSCode, it will ask you to " -"run in the container environment and - if you confirm - automatically " -"build the container and use it. To manually instruct VSCode to use the " -"devcontainer, you can, after installing the extension, click the green " -"area in the bottom left corner of your VSCode window and select the " -"option *(Re)Open Folder in Container*." +"Now you should be good to go. When starting VSCode, it will ask you to run " +"in the container environment and - if you confirm - automatically build the " +"container and use it. To manually instruct VSCode to use the devcontainer, " +"you can, after installing the extension, click the green area in the bottom " +"left corner of your VSCode window and select the option *(Re)Open Folder in " +"Container*." msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" -"In some cases your setup might be more involved. For those cases consult " -"the following sources:" +"In some cases your setup might be more involved. For those cases consult the " +"following sources:" msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 msgid "" -"`Developing inside a Container " -"`_" +"`Developing inside a Container `_" msgstr "" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 msgid "" -"`Remote development in Containers " -"`_" +"`Remote development in Containers `_" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:2 @@ -686,9 +684,9 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" -"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency " -"in ``pyproject.toml`` and then reinstall (don't forget to delete " -"``poetry.lock`` (``rm poetry.lock``) before running ``poetry install``)." +"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency in " +"``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." +"lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:12 @@ -705,8 +703,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" -"Install ``flwr`` from a local copy of the Flower source code via " -"``pyproject.toml``:" +"Install ``flwr`` from a local copy of the Flower source code via ``pyproject." +"toml``:" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:17 @@ -715,8 +713,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " -"}`` (with extras)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " +"(with extras)" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:20 @@ -725,8 +723,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:22 msgid "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without" -" extras)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " +"extras)" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:23 @@ -770,8 +768,7 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" -"``pip install flwr@git+https://github.com/adap/flower.git`` (without " -"extras)" +"``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:40 @@ -792,8 +789,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" -"@branch-name`` (with extras)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" +"name`` (with extras)" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:49 @@ -808,20 +805,20 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" -"Open a development version of the same notebook from branch `branch-name`" -" by changing ``main`` to ``branch-name`` (right after ``blob``):" +"Open a development version of the same notebook from branch `branch-name` by " +"changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:59 @@ -830,8 +827,8 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" -"In the vertical icon grid on the left hand side, select ``Files`` > " -"``Upload to session storage``" +"In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " +"to session storage``" msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:62 @@ -840,9 +837,9 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:63 msgid "" -"Change ``!pip install -q 'flwr[simulation]' torch torchvision " -"matplotlib`` to ``!pip install -q 'flwr-1.8.0-py3-none-" -"any.whl[simulation]' torch torchvision matplotlib``" +"Change ``!pip install -q 'flwr[simulation]' torch torchvision matplotlib`` " +"to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " +"torchvision matplotlib``" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:2 @@ -861,9 +858,8 @@ msgstr "" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" -"The version number of a release is stated in ``pyproject.toml``. To " -"release a new version of Flower, the following things need to happen (in " -"that order):" +"The version number of a release is stated in ``pyproject.toml``. To release " +"a new version of Flower, the following things need to happen (in that order):" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:11 @@ -875,25 +871,26 @@ msgstr "" #: ../../source/contributor-how-to-release-flower.rst:12 msgid "" -"Once the changelog has been updated with all the changes, run ``./dev" -"/prepare-release-changelog.sh v``, where ```` " -"is the version stated in ``pyproject.toml`` (notice the ``v`` added " -"before it). This will replace the ``Unreleased`` header of the changelog " -"by the version and current date, and it will add a thanking message for " -"the contributors. Open a pull request with those changes." +"Once the changelog has been updated with all the changes, run ``./dev/" +"prepare-release-changelog.sh v``, where ```` is " +"the version stated in ``pyproject.toml`` (notice the ``v`` added before it). " +"This will replace the ``Unreleased`` header of the changelog by the version " +"and current date, and it will add a thanking message for the contributors. " +"Open a pull request with those changes." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:13 msgid "" "Once the pull request is merged, tag the release commit with the version " -"number as soon as the PR is merged: ``git tag v`` (notice " -"the ``v`` added before the version number), then ``git push --tags``. " -"This will create a draft release on GitHub containing the correct " -"artifacts and the relevant part of the changelog." +"number as soon as the PR is merged: ``git tag v`` (notice the " +"``v`` added before the version number), then ``git push --tags``. This will " +"create a draft release on GitHub containing the correct artifacts and the " +"relevant part of the changelog." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:14 -msgid "Check the draft release on GitHub, and if everything is good, publish it." +msgid "" +"Check the draft release on GitHub, and if everything is good, publish it." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:17 @@ -918,8 +915,8 @@ msgstr "" #: ../../source/contributor-how-to-release-flower.rst:25 msgid "" -"Merge the pull request on the same day (i.e., before a new nightly " -"release gets published to PyPI)." +"Merge the pull request on the same day (i.e., before a new nightly release " +"gets published to PyPI)." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:28 @@ -932,8 +929,8 @@ msgstr "" #: ../../source/contributor-how-to-release-flower.rst:33 msgid "" -"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" -" MUST use one of the following naming patterns:" +"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases " +"MUST use one of the following naming patterns:" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:35 @@ -980,17 +977,17 @@ msgstr "" #: ../../source/contributor-how-to-release-flower.rst:50 msgid "" -"`PyPA Choosing a versioning scheme " -"`_" +"`PyPA Choosing a versioning scheme `_" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:52 msgid "" -"Note that the approach defined by PyPA is not compatible with SemVer " -"2.0.0 spec, for details consult the `Semantic Versioning Specification " -"`_ (specifically item " -"11 on precedence)." +"Note that the approach defined by PyPA is not compatible with SemVer 2.0.0 " +"spec, for details consult the `Semantic Versioning Specification `_ (specifically item 11 on " +"precedence)." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:55 @@ -998,14 +995,15 @@ msgid "Pre-release classification" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:57 -msgid "Should the next pre-release be called alpha, beta, or release candidate?" +msgid "" +"Should the next pre-release be called alpha, beta, or release candidate?" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:59 msgid "" -"RC: feature complete, no known issues (apart from issues that are " -"classified as \"won't fix\" for the next stable release) - if no issues " -"surface this will become the next stable release" +"RC: feature complete, no known issues (apart from issues that are classified " +"as \"won't fix\" for the next stable release) - if no issues surface this " +"will become the next stable release" msgstr "" #: ../../source/contributor-how-to-release-flower.rst:60 @@ -1024,8 +1022,8 @@ msgstr "" msgid "" "It is recommended to run your Python setup within a virtual environment. " "This guide shows three different examples how to create a virtual " -"environment with pyenv virtualenv, poetry, or Anaconda. You can follow " -"the instructions or choose your preferred setup." +"environment with pyenv virtualenv, poetry, or Anaconda. You can follow the " +"instructions or choose your preferred setup." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 @@ -1035,17 +1033,15 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 msgid "" -"Flower requires at least `Python 3.8 `_, " -"but `Python 3.10 `_ or above is " -"recommended." +"Flower requires at least `Python 3.8 `_, but " +"`Python 3.10 `_ or above is recommended." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 msgid "" -"Due to a known incompatibility with `ray " -"`_, we currently recommend utilizing at " -"most `Python 3.11 `_ for running Flower " -"simulations." +"Due to a known incompatibility with `ray `_, " +"we currently recommend utilizing at most `Python 3.11 `_ for running Flower simulations." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 @@ -1054,10 +1050,10 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" -"One of the recommended virtual environment is `pyenv " -"`_/`virtualenv `_. Please see `Flower examples " -"`_ for details." +"One of the recommended virtual environment is `pyenv `_/`virtualenv `_. " +"Please see `Flower examples `_ for details." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 @@ -1080,15 +1076,15 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" -"The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " -"simply create a virtual environment with:" +"The Flower examples are based on `Poetry `_ " +"to manage dependencies. After installing Poetry you simply create a virtual " +"environment with:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" -"If you open a new terminal you can activate the previously created " -"virtual environment with the following command:" +"If you open a new terminal you can activate the previously created virtual " +"environment with the following command:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 @@ -1097,10 +1093,10 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" -"If you prefer to use Anaconda for your virtual environment then install " -"and setup the `conda `_ package. After setting it up you can " -"create a virtual environment with:" +"If you prefer to use Anaconda for your virtual environment then install and " +"setup the `conda `_ package. After setting it up you can create a virtual " +"environment with:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:68 @@ -1113,8 +1109,8 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" -"As soon as you created your virtual environment you clone one of the " -"`Flower examples `_." +"As soon as you created your virtual environment you clone one of the `Flower " +"examples `_." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:2 @@ -1127,18 +1123,17 @@ msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" -"The Flower documentation lives in the ``doc`` directory. The Sphinx-based" -" documentation system supports both reStructuredText (``.rst`` files) and" -" Markdown (``.md`` files)." +"The Flower documentation lives in the ``doc`` directory. The Sphinx-based " +"documentation system supports both reStructuredText (``.rst`` files) and " +"Markdown (``.md`` files)." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:10 #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 msgid "" -"Note that, in order to build the documentation locally (with ``poetry run" -" make html``, like described below), `Pandoc " -"`_ needs to be installed on the " -"system." +"Note that, in order to build the documentation locally (with ``poetry run " +"make html``, like described below), `Pandoc `_ needs to be installed on the system." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:14 @@ -1181,10 +1176,10 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" -"We welcome contributions to Flower! However, it is not always easy to " -"know where to start. We therefore put together a few recommendations on " -"where to start to increase your chances of getting your PR accepted into " -"the Flower codebase." +"We welcome contributions to Flower! However, it is not always easy to know " +"where to start. We therefore put together a few recommendations on where to " +"start to increase your chances of getting your PR accepted into the Flower " +"codebase." msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:11 @@ -1193,9 +1188,9 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" -"Until the Flower core library matures it will be easier to get PR's " -"accepted if they only touch non-core areas of the codebase. Good " -"candidates to get started are:" +"Until the Flower core library matures it will be easier to get PR's accepted " +"if they only touch non-core areas of the codebase. Good candidates to get " +"started are:" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:17 @@ -1216,24 +1211,23 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:25 msgid "" -"If you are not familiar with Flower Baselines, you should probably check-" -"out our `contributing guide for baselines " -"`_." +"If you are not familiar with Flower Baselines, you should probably check-out " +"our `contributing guide for baselines `_." msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:27 msgid "" -"You should then check out the open `issues " -"`_" -" for baseline requests. If you find a baseline that you'd like to work on" -" and that has no assignees, feel free to assign it to yourself and start " -"working on it!" +"You should then check out the open `issues `_ for baseline " +"requests. If you find a baseline that you'd like to work on and that has no " +"assignees, feel free to assign it to yourself and start working on it!" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" -"Otherwise, if you don't find a baseline you'd like to work on, be sure to" -" open a new issue with the baseline request template!" +"Otherwise, if you don't find a baseline you'd like to work on, be sure to " +"open a new issue with the baseline request template!" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:34 @@ -1243,8 +1237,8 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" "We wish we had more time to write usage examples because we believe they " -"help users to get started with building what they want to build. Here are" -" a few ideas where we'd be happy to accept a PR:" +"help users to get started with building what they want to build. Here are a " +"few ideas where we'd be happy to accept a PR:" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:40 @@ -1265,10 +1259,10 @@ msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" -"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg " -"protocol has not been implemented yet, so its diagram and abstraction may" -" not be accurate in practice. The SecAgg protocol can be considered as a " -"special case of the SecAgg+ protocol." +"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg protocol " +"has not been implemented yet, so its diagram and abstraction may not be " +"accurate in practice. The SecAgg protocol can be considered as a special " +"case of the SecAgg+ protocol." msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 @@ -1279,15 +1273,15 @@ msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 msgid "" "In this implementation, each client will be assigned with a unique index " -"(int) for secure aggregation, and thus many python dictionaries used have" -" keys of int type rather than ClientProxy type." +"(int) for secure aggregation, and thus many python dictionaries used have " +"keys of int type rather than ClientProxy type." msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" -"The Flower server will execute and process received results in the " -"following order:" +"The Flower server will execute and process received results in the following " +"order:" msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 @@ -1304,15 +1298,15 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" -"This guide is for people who want to get involved with Flower, but who " -"are not used to contributing to GitHub projects." +"This guide is for people who want to get involved with Flower, but who are " +"not used to contributing to GitHub projects." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:6 msgid "" -"If you're familiar with how contributing on GitHub works, you can " -"directly checkout our :doc:`getting started guide for contributors " -"`." +"If you're familiar with how contributing on GitHub works, you can directly " +"checkout our :doc:`getting started guide for contributors `." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:10 @@ -1328,15 +1322,15 @@ msgid "" "Git is a distributed version control tool. This allows for an entire " "codebase's history to be stored and every developer's machine. It is a " "software that will need to be installed on your local machine, you can " -"follow this `guide `_ to set it up." +"follow this `guide `_ to set it up." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" "GitHub, itself, is a code hosting platform for version control and " -"collaboration. It allows for everyone to collaborate and work from " -"anywhere on remote repositories." +"collaboration. It allows for everyone to collaborate and work from anywhere " +"on remote repositories." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:18 @@ -1347,10 +1341,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" -"The idea behind the generic Git and GitHub workflow boils down to this: " -"you download code from a remote repository on GitHub, make changes " -"locally and keep track of them using Git and then you upload your new " -"history back to GitHub." +"The idea behind the generic Git and GitHub workflow boils down to this: you " +"download code from a remote repository on GitHub, make changes locally and " +"keep track of them using Git and then you upload your new history back to " +"GitHub." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:32 @@ -1359,18 +1353,18 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 msgid "" -"A fork is a personal copy of a GitHub repository. To create one for " -"Flower, you must navigate to ``_ (while " -"connected to your GitHub account) and click the ``Fork`` button situated " -"on the top right of the page." +"A fork is a personal copy of a GitHub repository. To create one for Flower, " +"you must navigate to ``_ (while connected to " +"your GitHub account) and click the ``Fork`` button situated on the top right " +"of the page." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" "You can change the name if you want, but this is not necessary as this " -"version of Flower will be yours and will sit inside your own account " -"(i.e., in your own list of repositories). Once created, you should see on" -" the top left corner that you are looking at your own version of Flower." +"version of Flower will be yours and will sit inside your own account (i.e., " +"in your own list of repositories). Once created, you should see on the top " +"left corner that you are looking at your own version of Flower." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 @@ -1380,9 +1374,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" "The next step is to download the forked repository on your machine to be " -"able to make changes to it. On your forked repository page, you should " -"first click on the ``Code`` button on the right, this will give you the " -"ability to copy the HTTPS link of the repository." +"able to make changes to it. On your forked repository page, you should first " +"click on the ``Code`` button on the right, this will give you the ability to " +"copy the HTTPS link of the repository." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:41 @@ -1393,8 +1387,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "" -"This will create a ``flower/`` (or the name of your fork if you renamed " -"it) folder in the current working directory." +"This will create a ``flower/`` (or the name of your fork if you renamed it) " +"folder in the current working directory." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:66 @@ -1407,10 +1401,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" -"And here we will need to add an origin to our repository. The origin is " -"the \\ of the remote fork repository. To obtain it, we can do as " -"previously mentioned by going to our fork repository on our GitHub " -"account and copying the link." +"And here we will need to add an origin to our repository. The origin is the " +"\\ of the remote fork repository. To obtain it, we can do as " +"previously mentioned by going to our fork repository on our GitHub account " +"and copying the link." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:61 @@ -1430,16 +1424,16 @@ msgid "" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 -msgid "The following diagram visually explains what we did in the previous steps:" +msgid "" +"The following diagram visually explains what we did in the previous steps:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" -"The upstream is the GitHub remote address of the parent repository (in " -"this case Flower), i.e. the one we eventually want to contribute to and " -"therefore need an up-to-date history of. The origin is just the GitHub " -"remote address of the forked repository we created, i.e. the copy (fork) " -"in our own account." +"The upstream is the GitHub remote address of the parent repository (in this " +"case Flower), i.e. the one we eventually want to contribute to and therefore " +"need an up-to-date history of. The origin is just the GitHub remote address " +"of the forked repository we created, i.e. the copy (fork) in our own account." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:84 @@ -1455,9 +1449,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:95 msgid "" "This can be achieved by following this :doc:`getting started guide for " -"contributors ` (note " -"that you won't need to clone the repository). Once you are able to write " -"code and test it, you can finally start making changes!" +"contributors ` (note that " +"you won't need to clone the repository). Once you are able to write code and " +"test it, you can finally start making changes!" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 @@ -1466,8 +1460,7 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" -"Before making any changes make sure you are up-to-date with your " -"repository:" +"Before making any changes make sure you are up-to-date with your repository:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 @@ -1480,15 +1473,13 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" -"To make the history cleaner and easier to work with, it is good practice " -"to create a new branch for each feature/project that needs to be " -"implemented." +"To make the history cleaner and easier to work with, it is good practice to " +"create a new branch for each feature/project that needs to be implemented." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" -"To do so, just run the following command inside the repository's " -"directory:" +"To do so, just run the following command inside the repository's directory:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 @@ -1496,7 +1487,8 @@ msgid "**Make changes**" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 -msgid "Write great code and create wonderful changes using your favorite editor!" +msgid "" +"Write great code and create wonderful changes using your favorite editor!" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 @@ -1505,9 +1497,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" -"Don't forget to test and format your code! Otherwise your code won't be " -"able to be merged into the Flower repository. This is done so the " -"codebase stays consistent and easy to understand." +"Don't forget to test and format your code! Otherwise your code won't be able " +"to be merged into the Flower repository. This is done so the codebase stays " +"consistent and easy to understand." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:131 @@ -1520,8 +1512,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" -"Before creating a commit that will update your history, you must specify " -"to Git which files it needs to take into account." +"Before creating a commit that will update your history, you must specify to " +"Git which files it needs to take into account." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:143 @@ -1530,9 +1522,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" -"To check which files have been modified compared to the last version " -"(last commit) and to see which files are staged for commit, you can use " -"the :code:`git status` command." +"To check which files have been modified compared to the last version (last " +"commit) and to see which files are staged for commit, you can use the :code:" +"`git status` command." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:160 @@ -1547,9 +1539,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" -"The \\ is there to explain to others what the commit " -"does. It should be written in an imperative style and be concise. An " -"example would be :code:`git commit -m \"Add images to README\"`." +"The \\ is there to explain to others what the commit does. " +"It should be written in an imperative style and be concise. An example would " +"be :code:`git commit -m \"Add images to README\"`." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:171 @@ -1558,9 +1550,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" -"Once we have committed our changes, we have effectively updated our local" -" history, but GitHub has no way of knowing this unless we push our " -"changes to our origin's remote address:" +"Once we have committed our changes, we have effectively updated our local " +"history, but GitHub has no way of knowing this unless we push our changes to " +"our origin's remote address:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 @@ -1579,8 +1571,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" -"Once you have pushed changes, on the GitHub webpage of your repository " -"you should see the following message:" +"Once you have pushed changes, on the GitHub webpage of your repository you " +"should see the following message:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 @@ -1594,29 +1586,29 @@ msgid "" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 -msgid "At the top you have an explanation of which branch will be merged where:" +msgid "" +"At the top you have an explanation of which branch will be merged where:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" -"In this example you can see that the request is to merge the branch " -"``doc-fixes`` from my forked repository to branch ``main`` from the " -"Flower repository." +"In this example you can see that the request is to merge the branch ``doc-" +"fixes`` from my forked repository to branch ``main`` from the Flower " +"repository." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" "The title should be changed to adhere to the :ref:`pr_title_format` " -"guidelines, otherwise it won't be possible to merge the PR. So in this " -"case, a correct title might be ``docs(framework:skip) Fix typos``." +"guidelines, otherwise it won't be possible to merge the PR. So in this case, " +"a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" -"The input box in the middle is there for you to describe what your PR " -"does and to link it to existing issues. We have placed comments (that " -"won't be rendered once the PR is opened) to guide you through the " -"process." +"The input box in the middle is there for you to describe what your PR does " +"and to link it to existing issues. We have placed comments (that won't be " +"rendered once the PR is opened) to guide you through the process." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:199 @@ -1626,14 +1618,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " -"reviewers that a new PR has been opened and that they should look over it" -" to merge or to request changes." +"reviewers that a new PR has been opened and that they should look over it to " +"merge or to request changes." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" -"If your PR is not yet ready for review, and you don't want to notify " -"anyone, you have the option to create a draft pull request:" +"If your PR is not yet ready for review, and you don't want to notify anyone, " +"you have the option to create a draft pull request:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 @@ -1643,8 +1635,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " -"commits to it the same way we did before, by making changes to the branch" -" associated with the PR." +"commits to it the same way we did before, by making changes to the branch " +"associated with the PR." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:231 @@ -1653,14 +1645,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" -"Once the PR has been opened or once the draft PR has been marked as " -"ready, a review from code owners will be automatically requested:" +"Once the PR has been opened or once the draft PR has been marked as ready, a " +"review from code owners will be automatically requested:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" -"Code owners will then look into the code, ask questions, request changes " -"or validate the PR." +"Code owners will then look into the code, ask questions, request changes or " +"validate the PR." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:218 @@ -1669,8 +1661,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" -"To resolve them, just push the necessary changes to the branch associated" -" with the PR:" +"To resolve them, just push the necessary changes to the branch associated " +"with the PR:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:226 @@ -1679,8 +1671,7 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" -"Once all the conversations have been resolved, you can re-request a " -"review." +"Once all the conversations have been resolved, you can re-request a review." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:251 @@ -1689,8 +1680,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" -"If all the automatic tests have passed and reviewers have no more changes" -" to request, they can approve the PR and merge it." +"If all the automatic tests have passed and reviewers have no more changes to " +"request, they can approve the PR and merge it." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:238 @@ -1713,14 +1704,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" -"For our documentation, we've started to use the `Diàtaxis framework " -"`_." +"For our documentation, we've started to use the `Diàtaxis framework `_." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" -"Our \"How to\" guides should have titles that continue the sentence \"How" -" to …\", for example, \"How to upgrade to Flower 1.0\"." +"Our \"How to\" guides should have titles that continue the sentence \"How to " +"…\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:263 @@ -1731,8 +1722,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" -"This issue is about changing the title of a doc from present continuous " -"to present simple." +"This issue is about changing the title of a doc from present continuous to " +"present simple." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:267 @@ -1771,8 +1762,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" -"Build the docs and `check the result `_" +"Build the docs and `check the result `_" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:283 @@ -1781,10 +1772,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" -"You might have noticed that the file name still reflects the old wording." -" If we just change the file, then we break all existing links to it - it " -"is **very important** to avoid that, breaking links can harm our search " -"engine ranking." +"You might have noticed that the file name still reflects the old wording. If " +"we just change the file, then we break all existing links to it - it is " +"**very important** to avoid that, breaking links can harm our search engine " +"ranking." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:288 @@ -1801,8 +1792,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" -"This will cause a redirect from ``saving-progress.html`` to ``save-" -"progress.html``, old links will continue to work." +"This will cause a redirect from ``saving-progress.html`` to ``save-progress." +"html``, old links will continue to work." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:296 @@ -1826,8 +1817,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" -"Commit the changes (commit messages are always imperative: \"Do " -"something\", in this case \"Change …\")" +"Commit the changes (commit messages are always imperative: \"Do something\", " +"in this case \"Change …\")" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:307 @@ -1836,8 +1827,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 msgid "" -"Open a PR (as shown above) with title ``docs(framework) Update how-to " -"guide title``" +"Open a PR (as shown above) with title ``docs(framework) Update how-to guide " +"title``" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 @@ -1859,15 +1850,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" -"Once you have made your first PR, and want to contribute more, be sure to" -" check out the following :" +"Once you have made your first PR, and want to contribute more, be sure to " +"check out the following :" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" -":doc:`Good first contributions `, where you should particularly look into the " -":code:`baselines` contributions." +":doc:`Good first contributions `, " +"where you should particularly look into the :code:`baselines` contributions." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:322 @@ -1885,17 +1875,16 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"(or ``(:skip) `` to ignore the PR in the " -"changelog)" +"(or ``(:skip) `` to ignore the PR in the changelog)" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " -"break}``, ```` should be in ``{framework, baselines, datasets, " -"examples, or '*' when modifying multiple projects which requires the " -"':skip' flag to be used}``, and ```` starts with a capitalised " -"verb in the imperative mood." +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, break}``, " +"```` should be in ``{framework, baselines, datasets, examples, or " +"'*' when modifying multiple projects which requires the ':skip' flag to be " +"used}``, and ```` starts with a capitalised verb in the imperative " +"mood." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:341 @@ -1966,14 +1955,15 @@ msgid "(Optional) `pyenv `_" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 -msgid "(Optional) `pyenv-virtualenv `_" +msgid "" +"(Optional) `pyenv-virtualenv `_" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 msgid "" "Flower uses :code:`pyproject.toml` to manage dependencies and configure " -"development tools (the ones which support it). Poetry is a build tool " -"which supports `PEP 517 `_." +"development tools (the ones which support it). Poetry is a build tool which " +"supports `PEP 517 `_." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 @@ -1994,14 +1984,14 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 msgid "" -"Install `homebrew `_. Don't forget the post-" -"installation actions to add `brew` to your PATH." +"Install `homebrew `_. Don't forget the post-installation " +"actions to add `brew` to your PATH." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 msgid "" -"Install `xz` (to install different Python versions) and `pandoc` to build" -" the docs::" +"Install `xz` (to install different Python versions) and `pandoc` to build " +"the docs::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 @@ -2010,8 +2000,8 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 msgid "" -"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " -"necessary packages::" +"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all necessary " +"packages::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 @@ -2026,31 +2016,31 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 msgid "" -"Let's create the Python environment for all-things Flower. If you wish to" -" use :code:`pyenv`, we provide two convenience scripts that you can use. " -"If you prefer using something else than :code:`pyenv`, create a new " +"Let's create the Python environment for all-things Flower. If you wish to " +"use :code:`pyenv`, we provide two convenience scripts that you can use. If " +"you prefer using something else than :code:`pyenv`, create a new " "environment, activate and skip to the last point where all packages are " "installed." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 msgid "" -"If you don't have :code:`pyenv` installed, the following script that will" -" install it, set it up, and create the virtual environment (with " -":code:`Python 3.8.17` by default)::" +"If you don't have :code:`pyenv` installed, the following script that will " +"install it, set it up, and create the virtual environment (with :code:" +"`Python 3.8.17` by default)::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 msgid "" "If you already have :code:`pyenv` installed (along with the :code:`pyenv-" -"virtualenv` plugin), you can use the following convenience script (with " -":code:`Python 3.8.17` by default)::" +"virtualenv` plugin), you can use the following convenience script (with :" +"code:`Python 3.8.17` by default)::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 msgid "" -"3. Install the Flower package in development mode (think :code:`pip " -"install -e`) along with all necessary dependencies::" +"3. Install the Flower package in development mode (think :code:`pip install -" +"e`) along with all necessary dependencies::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 @@ -2060,9 +2050,9 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" "The Flower repository contains a number of convenience scripts to make " -"recurring development tasks easier and less error-prone. See the " -":code:`/dev` subdirectory for a full list. The following scripts are " -"amongst the most important ones:" +"recurring development tasks easier and less error-prone. See the :code:`/" +"dev` subdirectory for a full list. The following scripts are amongst the " +"most important ones:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 @@ -2087,10 +2077,10 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 msgid "" -"Developers may integrate a pre-commit hook into their workflow utilizing " -"the `pre-commit `_ library. The pre-" -"commit hook is configured to execute two primary operations: " -"``./dev/format.sh`` and ``./dev/test.sh`` scripts." +"Developers may integrate a pre-commit hook into their workflow utilizing the " +"`pre-commit `_ library. The pre-commit hook " +"is configured to execute two primary operations: ``./dev/format.sh`` and ``./" +"dev/test.sh`` scripts." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 @@ -2098,26 +2088,27 @@ msgid "There are multiple ways developers can use this:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 -msgid "Install the pre-commit hook to your local git directory by simply running:" +msgid "" +"Install the pre-commit hook to your local git directory by simply running:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 msgid "" -"Each ``git commit`` will trigger the execution of formatting and " -"linting/test scripts." +"Each ``git commit`` will trigger the execution of formatting and linting/" +"test scripts." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 msgid "" -"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " -"commit`` command. ::" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git commit`` " +"command. ::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 msgid "" "For developers who prefer not to install the hook permanently, it is " -"possible to execute a one-time check prior to committing changes by using" -" the following command:" +"possible to execute a one-time check prior to committing changes by using " +"the following command:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 @@ -2132,10 +2123,10 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 msgid "" -"Developers could run the full set of Github Actions workflows under their" -" local environment by using `Act `_. " -"Please refer to the installation instructions under the linked repository" -" and run the next command under Flower main cloned repository folder::" +"Developers could run the full set of Github Actions workflows under their " +"local environment by using `Act `_. Please " +"refer to the installation instructions under the linked repository and run " +"the next command under Flower main cloned repository folder::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 @@ -2150,14 +2141,14 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" -"Flower uses Poetry to build releases. The necessary command is wrapped in" -" a simple script::" +"Flower uses Poetry to build releases. The necessary command is wrapped in a " +"simple script::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" -"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" -" the :code:`/dist` subdirectory." +"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in " +"the :code:`/dist` subdirectory." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 @@ -2166,9 +2157,9 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" -"Flower's documentation uses `Sphinx `_. " -"There's no convenience script to re-build the documentation yet, but it's" -" pretty easy::" +"Flower's documentation uses `Sphinx `_. There's " +"no convenience script to re-build the documentation yet, but it's pretty " +"easy::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 @@ -2181,14 +2172,13 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload with `FedBN " -"`_, a federated training strategy " -"designed for non-iid data. We are using PyTorch to train a Convolutional " -"Neural Network(with Batch Normalization layers) on the CIFAR-10 dataset. " -"When applying FedBN, only few changes needed compared to :doc:`Example: " -"PyTorch - From Centralized To Federated `." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload with `FedBN `_, a federated training strategy designed for non-iid data. We " +"are using PyTorch to train a Convolutional Neural Network(with Batch " +"Normalization layers) on the CIFAR-10 dataset. When applying FedBN, only few " +"changes needed compared to :doc:`Example: PyTorch - From Centralized To " +"Federated `." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 @@ -2198,10 +2188,10 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 msgid "" -"All files are revised based on :doc:`Example: PyTorch - From Centralized " -"To Federated `. The only " -"thing to do is modifying the file called :code:`cifar.py`, revised part " -"is shown below:" +"All files are revised based on :doc:`Example: PyTorch - From Centralized To " +"Federated `. The only thing " +"to do is modifying the file called :code:`cifar.py`, revised part is shown " +"below:" msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:13 @@ -2217,10 +2207,10 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 msgid "" -"So far this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"federated learning system within FedBN, the system consists of one server" -" and two clients." +"So far this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a federated " +"learning system within FedBN, the system consists of one server and two " +"clients." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 @@ -2231,25 +2221,25 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:53 msgid "" "If you have read :doc:`Example: PyTorch - From Centralized To Federated " -"`, the following parts are" -" easy to follow, only :code:`get_parameters` and :code:`set_parameters` " -"function in :code:`client.py` needed to revise. If not, please read the " -":doc:`Example: PyTorch - From Centralized To Federated `. first." +"`, the following parts are " +"easy to follow, only :code:`get_parameters` and :code:`set_parameters` " +"function in :code:`client.py` needed to revise. If not, please read the :doc:" +"`Example: PyTorch - From Centralized To Federated `. first." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" -"Our example consists of one *server* and two *clients*. In FedBN, " -":code:`server.py` keeps unchanged, we can start the server directly." +"Our example consists of one *server* and two *clients*. In FedBN, :code:" +"`server.py` keeps unchanged, we can start the server directly." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" -"Finally, we will revise our *client* logic by changing " -":code:`get_parameters` and :code:`set_parameters` in :code:`client.py`, " -"we will exclude batch normalization parameters from model parameter list " -"when sending to or receiving from the server." +"Finally, we will revise our *client* logic by changing :code:" +"`get_parameters` and :code:`set_parameters` in :code:`client.py`, we will " +"exclude batch normalization parameters from model parameter list when " +"sending to or receiving from the server." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 @@ -2258,9 +2248,9 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your (previously centralized) PyTorch project run federated " -"learning with FedBN strategy across two clients. Congratulations!" +"in each window (make sure that the server is still running before you do so) " +"and see your (previously centralized) PyTorch project run federated learning " +"with FedBN strategy across two clients. Congratulations!" msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 @@ -2272,13 +2262,12 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" -"The full source code for this example can be found `here " -"`_. Our example is of course somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using different subsets of CIFAR-10 on each client? How about adding more" -" clients?" +"The full source code for this example can be found `here `_. Our " +"example is of course somewhat over-simplified because both clients load the " +"exact same dataset, which isn't realistic. You're now prepared to explore " +"this topic further. How about using different subsets of CIFAR-10 on each " +"client? How about adding more clients?" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:2 @@ -2288,23 +2277,22 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing JAX workload. We are using JAX to train a linear " -"regression model on a scikit-learn dataset. We will structure the example" -" similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. First, we build a centralized " -"training approach based on the `Linear Regression with JAX " -"`_" -" tutorial`. Then, we build upon the centralized training code to run the " -"training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing JAX workload. We are using JAX to train a linear regression " +"model on a scikit-learn dataset. We will structure the example similar to " +"our `PyTorch - From Centralized To Federated `_ walkthrough. " +"First, we build a centralized training approach based on the `Linear " +"Regression with JAX `_ tutorial`. Then, we build upon the centralized " +"training code to run the training in a federated fashion." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 msgid "" -"Before we start building our JAX example, we need install the packages " -":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" +"Before we start building our JAX example, we need install the packages :code:" +"`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:18 @@ -2315,10 +2303,10 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Linear Regression` model. If you want a more in-depth " -"explanation of what's going on then have a look at the official `JAX " -"documentation `_." +"We begin with a brief description of the centralized training code based on " +"a :code:`Linear Regression` model. If you want a more in-depth explanation " +"of what's going on then have a look at the official `JAX documentation " +"`_." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:23 @@ -2326,53 +2314,51 @@ msgstr "" msgid "" "Let's create a new file called :code:`jax_training.py` with all the " "components required for a traditional (centralized) linear regression " -"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to " -"be imported. In addition, we need to import :code:`sklearn` since we use " -":code:`make_regression` for the dataset and :code:`train_test_split` to " -"split the dataset into a training and test set. You can see that we do " -"not yet import the :code:`flwr` package for federated learning. This will" -" be done later." +"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to be " +"imported. In addition, we need to import :code:`sklearn` since we use :code:" +"`make_regression` for the dataset and :code:`train_test_split` to split the " +"dataset into a training and test set. You can see that we do not yet import " +"the :code:`flwr` package for federated learning. This will be done later." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" -"The :code:`load_data()` function loads the mentioned training and test " -"sets." +"The :code:`load_data()` function loads the mentioned training and test sets." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" -"The model architecture (a very simple :code:`Linear Regression` model) is" -" defined in :code:`load_model()`." +"The model architecture (a very simple :code:`Linear Regression` model) is " +"defined in :code:`load_model()`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 msgid "" -"We now need to define the training (function :code:`train()`), which " -"loops over the training set and measures the loss (function " -":code:`loss_fn()`) for each batch of training examples. The loss function" -" is separate since JAX takes derivatives with a :code:`grad()` function " -"(defined in the :code:`main()` function and called in :code:`train()`)." +"We now need to define the training (function :code:`train()`), which loops " +"over the training set and measures the loss (function :code:`loss_fn()`) for " +"each batch of training examples. The loss function is separate since JAX " +"takes derivatives with a :code:`grad()` function (defined in the :code:" +"`main()` function and called in :code:`train()`)." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 msgid "" -"The evaluation of the model is defined in the function " -":code:`evaluation()`. The function takes all test examples and measures " -"the loss of the linear regression model." +"The evaluation of the model is defined in the function :code:`evaluation()`. " +"The function takes all test examples and measures the loss of the linear " +"regression model." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:88 #: ../../source/tutorial-quickstart-jax.rst:94 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model using JAX. " -"As already mentioned, the :code:`jax.grad()` function is defined in " -":code:`main()` and passed to :code:`train()`." +"evaluation we can put everything together and train our model using JAX. As " +"already mentioned, the :code:`jax.grad()` function is defined in :code:" +"`main()` and passed to :code:`train()`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:105 @@ -2383,9 +2369,9 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 msgid "" -"So far this should all look fairly familiar if you've used JAX before. " -"Let's take the next step and use what we've built to create a simple " -"federated learning system consisting of one server and two clients." +"So far this should all look fairly familiar if you've used JAX before. Let's " +"take the next step and use what we've built to create a simple federated " +"learning system consisting of one server and two clients." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:115 @@ -2396,24 +2382,24 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 msgid "" -"The concept of federating an existing workload is always the same and " -"easy to understand. We have to start a *server* and then use the code in " -":code:`jax_training.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server*, which averages all received " -"parameter updates. This describes one round of the federated learning " -"process, and we repeat this for multiple rounds." +"The concept of federating an existing workload is always the same and easy " +"to understand. We have to start a *server* and then use the code in :code:" +"`jax_training.py` for the *clients* that are connected to the *server*. The " +"*server* sends model parameters to the clients. The *clients* run the " +"training and update the parameters. The updated parameters are sent back to " +"the *server*, which averages all received parameter updates. This describes " +"one round of the federated learning process, and we repeat this for multiple " +"rounds." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:123 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" -"Our example consists of one *server* and two *clients*. Let's set up " -":code:`server.py` first. The *server* needs to import the Flower package " -":code:`flwr`. Next, we use the :code:`start_server` function to start a " -"server and tell it to perform three rounds of federated learning." +"Our example consists of one *server* and two *clients*. Let's set up :code:" +"`server.py` first. The *server* needs to import the Flower package :code:" +"`flwr`. Next, we use the :code:`start_server` function to start a server and " +"tell it to perform three rounds of federated learning." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:133 @@ -2425,25 +2411,24 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined JAX training in :code:`jax_training.py`. Our" -" *client* needs to import :code:`flwr`, but also :code:`jax` and " -":code:`jaxlib` to update the parameters on our JAX model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined JAX training in :code:`jax_training.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`jax` and :code:" +"`jaxlib` to update the parameters on our JAX model:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`FlowerClient`. :code:`NumPyClient` is slightly " -"easier to implement than :code:`Client` if you use a framework with good " -"NumPy interoperability (like JAX) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`FlowerClient` needs" -" to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`FlowerClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like JAX) because it avoids some of the boilerplate that " +"would otherwise be necessary. :code:`FlowerClient` needs to implement four " +"methods, two methods for getting/setting model parameters, one method for " +"training the model, and one method for testing the model:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2455,8 +2440,7 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" -"set the model parameters on the local model that are received from the " -"server" +"set the model parameters on the local model that are received from the server" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2468,8 +2452,8 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" -"loop over the list of model parameters received as NumPy " -":code:`ndarray`'s (think list of neural network layers)" +"loop over the list of model parameters received as NumPy :code:`ndarray`'s " +"(think list of neural network layers)" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:163 @@ -2484,8 +2468,8 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" -"get the model parameters and return them as a list of NumPy " -":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" +"get the model parameters and return them as a list of NumPy :code:" +"`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2503,8 +2487,8 @@ msgstr "" #: ../../source/tutorial-quickstart-jax.rst:172 #: ../../source/tutorial-quickstart-jax.rst:176 msgid "" -"update the parameters of the local model with the parameters received " -"from the server" +"update the parameters of the local model with the parameters received from " +"the server" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2540,21 +2524,20 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 msgid "" -"The challenging part is to transform the JAX model parameters from " -":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" -" `NumPyClient`." +"The challenging part is to transform the JAX model parameters from :code:" +"`DeviceArray` to :code:`NumPy ndarray` to make them compatible with " +"`NumPyClient`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`evaluate()` previously " +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`evaluate()` previously " "defined in :code:`jax_training.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." +"Flower through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type annotations " +"to give you a better understanding of the data types that get passed around." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:245 @@ -2571,8 +2554,8 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:274 #: ../../source/tutorial-quickstart-jax.rst:280 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your JAX project run federated learning across two clients. " +"in each window (make sure that the server is still running before you do so) " +"and see your JAX project run federated learning across two clients. " "Congratulations!" msgstr "" @@ -2580,16 +2563,16 @@ msgstr "" #: ../../source/tutorial-quickstart-jax.rst:285 msgid "" "The source code of this example was improved over time and can be found " -"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " +"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 msgid "" -"You're now prepared to explore this topic further. How about using a more" -" sophisticated model or using a different dataset? How about adding more " +"You're now prepared to explore this topic further. How about using a more " +"sophisticated model or using a different dataset? How about adding more " "clients?" msgstr "" @@ -2599,32 +2582,31 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload. We are using PyTorch to" -" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " -"introduce this machine learning task with a centralized training approach" -" based on the `Deep Learning with PyTorch " -"`_ " -"tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload. We are using PyTorch to train a " +"Convolutional Neural Network on the CIFAR-10 dataset. First, we introduce " +"this machine learning task with a centralized training approach based on the " +"`Deep Learning with PyTorch `_ tutorial. Then, we build upon the centralized " +"training code to run the training in a federated fashion." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"We begin with a brief description of the centralized CNN training code. " -"If you want a more in-depth explanation of what's going on then have a " -"look at the official `PyTorch tutorial " -"`_." +"We begin with a brief description of the centralized CNN training code. If " +"you want a more in-depth explanation of what's going on then have a look at " +"the official `PyTorch tutorial `_." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" "Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all" -" required packages (such as :code:`torch` and :code:`torchvision`) need " -"to be imported. You can see that we do not import any package for " -"federated learning. You can keep all these imports as they are even when " -"we add the federated learning components at a later point." +"required for a traditional (centralized) training on CIFAR-10. First, all " +"required packages (such as :code:`torch` and :code:`torchvision`) need to be " +"imported. You can see that we do not import any package for federated " +"learning. You can keep all these imports as they are even when we add the " +"federated learning components at a later point." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 @@ -2636,22 +2618,22 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test " -"sets. The :code:`transform` normalized the data after loading." +"The :code:`load_data()` function loads the CIFAR-10 training and test sets. " +"The :code:`transform` normalized the data after loading." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set, measures the loss, backpropagates it, and then " -"takes one optimizer step for each batch of training examples." +"We now need to define the training (function :code:`train()`) which loops " +"over the training set, measures the loss, backpropagates it, and then takes " +"one optimizer step for each batch of training examples." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in the function :code:`test()`. " -"The function loops over all test samples and measures the loss of the " -"model based on the test dataset." +"The evaluation of the model is defined in the function :code:`test()`. The " +"function loops over all test samples and measures the loss of the model " +"based on the test dataset." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 @@ -2662,60 +2644,59 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far, this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"simple federated learning system consisting of one server and two " -"clients." +"So far, this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a simple " +"federated learning system consisting of one server and two clients." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" -"The simple machine learning project discussed in the previous section " -"trains the model on a single dataset (CIFAR-10), we call this centralized" -" learning. This concept of centralized learning, as shown in the previous" -" section, is probably known to most of you, and many of you have used it " -"previously. Normally, if you'd want to run machine learning workloads in " -"a federated fashion, then you'd have to change most of your code and set " -"everything up from scratch. This can be a considerable effort." +"The simple machine learning project discussed in the previous section trains " +"the model on a single dataset (CIFAR-10), we call this centralized learning. " +"This concept of centralized learning, as shown in the previous section, is " +"probably known to most of you, and many of you have used it previously. " +"Normally, if you'd want to run machine learning workloads in a federated " +"fashion, then you'd have to change most of your code and set everything up " +"from scratch. This can be a considerable effort." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"However, with Flower you can evolve your pre-existing code into a " -"federated learning setup without the need for a major rewrite." +"However, with Flower you can evolve your pre-existing code into a federated " +"learning setup without the need for a major rewrite." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept is easy to understand. We have to start a *server* and then " -"use the code in :code:`cifar.py` for the *clients* that are connected to " -"the *server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." +"The concept is easy to understand. We have to start a *server* and then use " +"the code in :code:`cifar.py` for the *clients* that are connected to the " +"*server*. The *server* sends model parameters to the clients. The *clients* " +"run the training and update the parameters. The updated parameters are sent " +"back to the *server* which averages all received parameter updates. This " +"describes one round of the federated learning process and we repeat this for " +"multiple rounds." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined centralized training in :code:`cifar.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " -"update the parameters on our PyTorch model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined centralized training in :code:`cifar.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`torch` to update the " +"parameters on our PyTorch model:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " -"some of the boilerplate that would otherwise be necessary. " -":code:`CifarClient` needs to implement four methods, two methods for " -"getting/setting model parameters, one method for training the model, and " -"one method for testing the model:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids some " +"of the boilerplate that would otherwise be necessary. :code:`CifarClient` " +"needs to implement four methods, two methods for getting/setting model " +"parameters, one method for training the model, and one method for testing " +"the model:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 @@ -2732,40 +2713,39 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`cifar.py`. So what we really do here is we tell Flower " -"through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`test()` previously defined " +"in :code:`cifar.py`. So what we really do here is we tell Flower through " +"our :code:`NumPyClient` subclass which of our already defined functions to " +"call for training and evaluation. We included type annotations to give you a " +"better understanding of the data types that get passed around." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" "All that's left to do it to define a function that loads both model and " -"data, creates a :code:`CifarClient`, and starts this client. You load " -"your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " -"with the function :code:`fl.client.start_client()` by pointing it at the " -"same IP address we used in :code:`server.py`:" +"data, creates a :code:`CifarClient`, and starts this client. You load your " +"data and model by using :code:`cifar.py`. Start :code:`CifarClient` with the " +"function :code:`fl.client.start_client()` by pointing it at the same IP " +"address we used in :code:`server.py`:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" -"in each window (make sure that the server is running before you do so) " -"and see your (previously centralized) PyTorch project run federated " -"learning across two clients. Congratulations!" +"in each window (make sure that the server is running before you do so) and " +"see your (previously centralized) PyTorch project run federated learning " +"across two clients. Congratulations!" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" "The full source code for this example: `PyTorch: From Centralized To " -"Federated (Code) `_. Our example is, of course, " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using different subsets of CIFAR-10 on each client? " -"How about adding more clients?" +"Federated (Code) `_. Our example is, of course, somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using different subsets of CIFAR-10 on each client? How about adding more " +"clients?" msgstr "" #: ../../source/explanation-differential-privacy.rst:2 @@ -2776,19 +2756,18 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:3 msgid "" -"The information in datasets like healthcare, financial transactions, user" -" preferences, etc., is valuable and has the potential for scientific " -"breakthroughs and provides important business insights. However, such " -"data is also sensitive and there is a risk of compromising individual " -"privacy." +"The information in datasets like healthcare, financial transactions, user " +"preferences, etc., is valuable and has the potential for scientific " +"breakthroughs and provides important business insights. However, such data " +"is also sensitive and there is a risk of compromising individual privacy." msgstr "" #: ../../source/explanation-differential-privacy.rst:6 msgid "" "Traditional methods like anonymization alone would not work because of " -"attacks like Re-identification and Data Linkage. That's where " -"differential privacy comes in. It provides the possibility of analyzing " -"data while ensuring the privacy of individuals." +"attacks like Re-identification and Data Linkage. That's where differential " +"privacy comes in. It provides the possibility of analyzing data while " +"ensuring the privacy of individuals." msgstr "" #: ../../source/explanation-differential-privacy.rst:12 @@ -2797,8 +2776,8 @@ msgid "" "instance, Alice's data). Differential Privacy (DP) guarantees that any " "analysis (M), like calculating the average income, will produce nearly " "identical results for both datasets (O and O' would be similar). This " -"preserves group patterns while obscuring individual details, ensuring the" -" individual's information remains hidden in the crowd." +"preserves group patterns while obscuring individual details, ensuring the " +"individual's information remains hidden in the crowd." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2809,8 +2788,7 @@ msgstr "" msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " -"individual in the data while preserving the overall accuracy of the " -"analysis." +"individual in the data while preserving the overall accuracy of the analysis." msgstr "" #: ../../source/explanation-differential-privacy.rst:25 @@ -2821,12 +2799,12 @@ msgstr "" msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " -"algorithm. It provides an unconditional upper bound on the influence of a" -" single individual on the output of the algorithm by adding noise [1]. A " -"randomized mechanism M provides (:math:`\\epsilon`, " -":math:`\\delta`)-differential privacy if for any two neighboring " -"databases, D :sub:`1` and D :sub:`2`, that differ in only a single " -"record, and for all possible outputs S ⊆ Range(A):" +"algorithm. It provides an unconditional upper bound on the influence of a " +"single individual on the output of the algorithm by adding noise [1]. A " +"randomized mechanism M provides (:math:`\\epsilon`, :math:`\\delta`)-" +"differential privacy if for any two neighboring databases, D :sub:`1` and D :" +"sub:`2`, that differ in only a single record, and for all possible outputs S " +"⊆ Range(A):" msgstr "" #: ../../source/explanation-differential-privacy.rst:32 @@ -2840,11 +2818,11 @@ msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " "lower :math:`\\epsilon` values indicate higher levels of privacy but are " -"likely to reduce utility as well. The :math:`\\delta` parameter accounts " -"for a small probability on which the upper bound :math:`\\epsilon` does " -"not hold. The amount of noise needed to achieve differential privacy is " -"proportional to the sensitivity of the output, which measures the maximum" -" change in the output due to the inclusion or removal of a single record." +"likely to reduce utility as well. The :math:`\\delta` parameter accounts for " +"a small probability on which the upper bound :math:`\\epsilon` does not " +"hold. The amount of noise needed to achieve differential privacy is " +"proportional to the sensitivity of the output, which measures the maximum " +"change in the output due to the inclusion or removal of a single record." msgstr "" #: ../../source/explanation-differential-privacy.rst:45 @@ -2855,15 +2833,14 @@ msgstr "" msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " -"designed in a way to prevent the algorithm to learn any specific " -"information about any individual data points and subsequently prevent the" -" model from revealing sensitive information. Depending on the stage at " -"which noise is introduced, various methods exist for applying DP to " -"machine learning algorithms. One approach involves adding noise to the " -"training data (either to the features or labels), while another method " -"entails injecting noise into the gradients of the loss function during " -"model training. Additionally, such noise can be incorporated into the " -"model's output." +"designed in a way to prevent the algorithm to learn any specific information " +"about any individual data points and subsequently prevent the model from " +"revealing sensitive information. Depending on the stage at which noise is " +"introduced, various methods exist for applying DP to machine learning " +"algorithms. One approach involves adding noise to the training data (either " +"to the features or labels), while another method entails injecting noise " +"into the gradients of the loss function during model training. Additionally, " +"such noise can be incorporated into the model's output." msgstr "" #: ../../source/explanation-differential-privacy.rst:53 @@ -2875,40 +2852,40 @@ msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " "However, federated learning also introduces new privacy challenges. The " -"model updates between parties and the central server can leak information" -" about the local data. These leaks can be exploited by attacks such as " +"model updates between parties and the central server can leak information " +"about the local data. These leaks can be exploited by attacks such as " "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" #: ../../source/explanation-differential-privacy.rst:58 msgid "" -"DP can play a crucial role in federated learning to provide privacy for " -"the clients' data." +"DP can play a crucial role in federated learning to provide privacy for the " +"clients' data." msgstr "" #: ../../source/explanation-differential-privacy.rst:60 msgid "" -"Depending on the granularity of privacy provision or the location of " -"noise addition, different forms of DP exist in federated learning. In " -"this explainer, we focus on two approaches of DP utilization in federated" -" learning based on where the noise is added: at the server (also known as" -" the center) or at the client (also known as the local)." +"Depending on the granularity of privacy provision or the location of noise " +"addition, different forms of DP exist in federated learning. In this " +"explainer, we focus on two approaches of DP utilization in federated " +"learning based on where the noise is added: at the server (also known as the " +"center) or at the client (also known as the local)." msgstr "" #: ../../source/explanation-differential-privacy.rst:63 msgid "" -"**Central Differential Privacy**: DP is applied by the server and the " -"goal is to prevent the aggregated model from leaking information about " -"each client's data." +"**Central Differential Privacy**: DP is applied by the server and the goal " +"is to prevent the aggregated model from leaking information about each " +"client's data." msgstr "" #: ../../source/explanation-differential-privacy.rst:65 msgid "" "**Local Differential Privacy**: DP is applied on the client side before " -"sending any information to the server and the goal is to prevent the " -"updates that are sent to the server from leaking any information about " -"the client's data." +"sending any information to the server and the goal is to prevent the updates " +"that are sent to the server from leaking any information about the client's " +"data." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2919,24 +2896,24 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:69 msgid "" -"In this approach, which is also known as user-level DP, the central " -"server is responsible for adding noise to the globally aggregated " -"parameters. It should be noted that trust in the server is required." +"In this approach, which is also known as user-level DP, the central server " +"is responsible for adding noise to the globally aggregated parameters. It " +"should be noted that trust in the server is required." msgstr "" #: ../../source/explanation-differential-privacy.rst:76 msgid "" -"While there are various ways to implement central DP in federated " -"learning, we concentrate on the algorithms proposed by [2] and [3]. The " -"overall approach is to clip the model updates sent by the clients and add" -" some amount of noise to the aggregated model. In each iteration, a " -"random set of clients is chosen with a specific probability for training." -" Each client performs local training on its own data. The update of each " -"client is then clipped by some value `S` (sensitivity `S`). This would " -"limit the impact of any individual client which is crucial for privacy " -"and often beneficial for robustness. A common approach to achieve this is" -" by restricting the `L2` norm of the clients' model updates, ensuring " -"that larger updates are scaled down to fit within the norm `S`." +"While there are various ways to implement central DP in federated learning, " +"we concentrate on the algorithms proposed by [2] and [3]. The overall " +"approach is to clip the model updates sent by the clients and add some " +"amount of noise to the aggregated model. In each iteration, a random set of " +"clients is chosen with a specific probability for training. Each client " +"performs local training on its own data. The update of each client is then " +"clipped by some value `S` (sensitivity `S`). This would limit the impact of " +"any individual client which is crucial for privacy and often beneficial for " +"robustness. A common approach to achieve this is by restricting the `L2` " +"norm of the clients' model updates, ensuring that larger updates are scaled " +"down to fit within the norm `S`." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2945,11 +2922,11 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:89 msgid "" -"Afterwards, the Gaussian mechanism is used to add noise in order to " -"distort the sum of all clients' updates. The amount of noise is scaled to" -" the sensitivity value to obtain a privacy guarantee. The Gaussian " -"mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " -"noise_scale * S ) / (number of sampled clients)`." +"Afterwards, the Gaussian mechanism is used to add noise in order to distort " +"the sum of all clients' updates. The amount of noise is scaled to the " +"sensitivity value to obtain a privacy guarantee. The Gaussian mechanism is " +"used with a noise sampled from `N (0, σ²)` where `σ = ( noise_scale * S ) / " +"(number of sampled clients)`." msgstr "" #: ../../source/explanation-differential-privacy.rst:94 @@ -2958,29 +2935,29 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:96 msgid "" -"There are two forms of clipping commonly used in Central DP: Fixed " -"Clipping and Adaptive Clipping." +"There are two forms of clipping commonly used in Central DP: Fixed Clipping " +"and Adaptive Clipping." msgstr "" #: ../../source/explanation-differential-privacy.rst:98 msgid "" -"**Fixed Clipping** : A predefined fix threshold is set for the magnitude " -"of clients' updates. Any update exceeding this threshold is clipped back " -"to the threshold value." +"**Fixed Clipping** : A predefined fix threshold is set for the magnitude of " +"clients' updates. Any update exceeding this threshold is clipped back to the " +"threshold value." msgstr "" #: ../../source/explanation-differential-privacy.rst:100 msgid "" -"**Adaptive Clipping** : The clipping threshold dynamically adjusts based " -"on the observed update distribution [4]. It means that the clipping value" -" is tuned during the rounds with respect to the quantile of the update " -"norm distribution." +"**Adaptive Clipping** : The clipping threshold dynamically adjusts based on " +"the observed update distribution [4]. It means that the clipping value is " +"tuned during the rounds with respect to the quantile of the update norm " +"distribution." msgstr "" #: ../../source/explanation-differential-privacy.rst:102 msgid "" -"The choice between fixed and adaptive clipping depends on various factors" -" such as privacy requirements, data distribution, model complexity, and " +"The choice between fixed and adaptive clipping depends on various factors " +"such as privacy requirements, data distribution, model complexity, and " "others." msgstr "" @@ -2993,9 +2970,9 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:107 msgid "" "In this approach, each client is responsible for performing DP. Local DP " -"avoids the need for a fully trusted aggregator, but it should be noted " -"that local DP leads to a decrease in accuracy but better privacy in " -"comparison to central DP." +"avoids the need for a fully trusted aggregator, but it should be noted that " +"local DP leads to a decrease in accuracy but better privacy in comparison to " +"central DP." msgstr "" #: ../../source/explanation-differential-privacy.rst:116 @@ -3005,16 +2982,16 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:118 msgid "" "Each client adds noise to the local updates before sending them to the " -"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " -"the sensitivity of the local model to be ∆, Gaussian noise is applied " -"with a noise scale of σ where:" +"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering the " +"sensitivity of the local model to be ∆, Gaussian noise is applied with a " +"noise scale of σ where:" msgstr "" #: ../../source/explanation-differential-privacy.rst:120 msgid "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times " -"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" +"{\\epsilon}\n" "\n" msgstr "" @@ -3041,18 +3018,18 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:135 msgid "" -"[2] McMahan et al. Learning Differentially Private Recurrent Language " -"Models." +"[2] McMahan et al. Learning Differentially Private Recurrent Language Models." msgstr "" #: ../../source/explanation-differential-privacy.rst:137 msgid "" -"[3] Geyer et al. Differentially Private Federated Learning: A Client " -"Level Perspective." +"[3] Geyer et al. Differentially Private Federated Learning: A Client Level " +"Perspective." msgstr "" #: ../../source/explanation-differential-privacy.rst:139 -msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." +msgid "" +"[4] Galen et al. Differentially Private Learning with Adaptive Clipping." msgstr "" #: ../../source/explanation-federated-evaluation.rst:2 @@ -3063,8 +3040,8 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" "There are two main approaches to evaluating models in federated learning " -"systems: centralized (or server-side) evaluation and federated (or " -"client-side) evaluation." +"systems: centralized (or server-side) evaluation and federated (or client-" +"side) evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:8 @@ -3089,11 +3066,10 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" -"The :code:`Strategy` abstraction provides a method called " -":code:`evaluate` that can directly be used to evaluate the current global" -" model parameters. The current server implementation calls " -":code:`evaluate` after parameter aggregation and before federated " -"evaluation (see next paragraph)." +"The :code:`Strategy` abstraction provides a method called :code:`evaluate` " +"that can directly be used to evaluate the current global model parameters. " +"The current server implementation calls :code:`evaluate` after parameter " +"aggregation and before federated evaluation (see next paragraph)." msgstr "" #: ../../source/explanation-federated-evaluation.rst:65 @@ -3106,8 +3082,8 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" -"Client-side evaluation happens in the :code:`Client.evaluate` method and " -"can be configured from the server side." +"Client-side evaluation happens in the :code:`Client.evaluate` method and can " +"be configured from the server side." msgstr "" #: ../../source/explanation-federated-evaluation.rst:101 @@ -3122,40 +3098,39 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:105 msgid "" -":code:`fraction_evaluate`: a :code:`float` defining the fraction of " -"clients that will be selected for evaluation. If " -":code:`fraction_evaluate` is set to :code:`0.1` and :code:`100` clients " -"are connected to the server, then :code:`10` will be randomly selected " -"for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " -"federated evaluation will be disabled." +":code:`fraction_evaluate`: a :code:`float` defining the fraction of clients " +"that will be selected for evaluation. If :code:`fraction_evaluate` is set " +"to :code:`0.1` and :code:`100` clients are connected to the server, then :" +"code:`10` will be randomly selected for evaluation. If :code:" +"`fraction_evaluate` is set to :code:`0.0`, federated evaluation will be " +"disabled." msgstr "" #: ../../source/explanation-federated-evaluation.rst:106 msgid "" -":code:`min_evaluate_clients`: an :code:`int`: the minimum number of " -"clients to be selected for evaluation. If :code:`fraction_evaluate` is " -"set to :code:`0.1`, :code:`min_evaluate_clients` is set to 20, and " -":code:`100` clients are connected to the server, then :code:`20` clients " -"will be selected for evaluation." +":code:`min_evaluate_clients`: an :code:`int`: the minimum number of clients " +"to be selected for evaluation. If :code:`fraction_evaluate` is set to :code:" +"`0.1`, :code:`min_evaluate_clients` is set to 20, and :code:`100` clients " +"are connected to the server, then :code:`20` clients will be selected for " +"evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:107 msgid "" ":code:`min_available_clients`: an :code:`int` that defines the minimum " -"number of clients which need to be connected to the server before a round" -" of federated evaluation can start. If fewer than " -":code:`min_available_clients` are connected to the server, the server " -"will wait until more clients are connected before it continues to sample " -"clients for evaluation." +"number of clients which need to be connected to the server before a round of " +"federated evaluation can start. If fewer than :code:`min_available_clients` " +"are connected to the server, the server will wait until more clients are " +"connected before it continues to sample clients for evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:108 msgid "" ":code:`on_evaluate_config_fn`: a function that returns a configuration " -"dictionary which will be sent to the selected clients. The function will " -"be called during each round and provides a convenient way to customize " -"client-side evaluation from the server side, for example, to configure " -"the number of validation steps performed." +"dictionary which will be sent to the selected clients. The function will be " +"called during each round and provides a convenient way to customize client-" +"side evaluation from the server side, for example, to configure the number " +"of validation steps performed." msgstr "" #: ../../source/explanation-federated-evaluation.rst:135 @@ -3164,9 +3139,8 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" -"Model parameters can also be evaluated during training. " -":code:`Client.fit` can return arbitrary evaluation results as a " -"dictionary:" +"Model parameters can also be evaluated during training. :code:`Client.fit` " +"can return arbitrary evaluation results as a dictionary:" msgstr "" #: ../../source/explanation-federated-evaluation.rst:177 @@ -3175,10 +3149,10 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" -"For a full code example that uses both centralized and federated " -"evaluation, see the *Advanced TensorFlow Example* (the same approach can " -"be applied to workloads implemented in any other framework): " -"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" +"For a full code example that uses both centralized and federated evaluation, " +"see the *Advanced TensorFlow Example* (the same approach can be applied to " +"workloads implemented in any other framework): https://github.com/adap/" +"flower/tree/main/examples/advanced-tensorflow" msgstr "" #: ../../source/fed/0000-20200102-fed-template.md:10 @@ -3352,9 +3326,9 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" -"ensure community participants can successfully drive changes to " -"completion across one or more releases while stakeholders are adequately " -"represented throughout the process" +"ensure community participants can successfully drive changes to completion " +"across one or more releases while stakeholders are adequately represented " +"throughout the process" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 @@ -3382,54 +3356,54 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" "For far-fetching changes or features proposed to Flower, an abstraction " -"beyond a single GitHub issue or pull request is required to understand " -"and communicate upcoming changes to the project." +"beyond a single GitHub issue or pull request is required to understand and " +"communicate upcoming changes to the project." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" -"The purpose of this process is to reduce the amount of \"tribal " -"knowledge\" in our community. By moving decisions from Slack threads, " -"video calls, and hallway conversations into a well-tracked artifact, this" -" process aims to enhance communication and discoverability." +"The purpose of this process is to reduce the amount of \"tribal knowledge\" " +"in our community. By moving decisions from Slack threads, video calls, and " +"hallway conversations into a well-tracked artifact, this process aims to " +"enhance communication and discoverability." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" -"Roughly any larger, user-facing enhancement should follow the Enhancement" -" process. If an enhancement would be described in either written or " -"verbal communication to anyone besides the author or developer, then " -"consider creating an Enhancement Doc." +"Roughly any larger, user-facing enhancement should follow the Enhancement " +"process. If an enhancement would be described in either written or verbal " +"communication to anyone besides the author or developer, then consider " +"creating an Enhancement Doc." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" -"Similarly, any technical effort (refactoring, major architectural change)" -" that will impact a large section of the development community should " -"also be communicated widely. The Enhancement process is suited for this " -"even if it will have zero impact on the typical user or operator." +"Similarly, any technical effort (refactoring, major architectural change) " +"that will impact a large section of the development community should also be " +"communicated widely. The Enhancement process is suited for this even if it " +"will have zero impact on the typical user or operator." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" -"For small changes and additions, going through the Enhancement process " -"would be time-consuming and unnecessary. This includes, for example, " -"adding new Federated Learning algorithms, as these only add features " -"without changing how Flower works or is used." +"For small changes and additions, going through the Enhancement process would " +"be time-consuming and unnecessary. This includes, for example, adding new " +"Federated Learning algorithms, as these only add features without changing " +"how Flower works or is used." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " -"providing a laid-out path for implementation and are championed by " -"members of the community." +"providing a laid-out path for implementation and are championed by members " +"of the community." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" "An Enhancement is captured in a Markdown file that follows a defined " -"template and a workflow to review and store enhancement docs for " -"reference — the Enhancement Doc." +"template and a workflow to review and store enhancement docs for reference " +"— the Enhancement Doc." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:69 @@ -3481,8 +3455,8 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" -"**fed-number** (Required) The `fed-number` of the last Flower Enhancement" -" Doc + 1. With this number, it becomes easy to reference other proposals." +"**fed-number** (Required) The `fed-number` of the last Flower Enhancement " +"Doc + 1. With this number, it becomes easy to reference other proposals." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 @@ -3491,20 +3465,20 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" -"**status** (Required) The current status of the proposal. See " -"[workflow](#workflow) for the possible states." +"**status** (Required) The current status of the proposal. See [workflow]" +"(#workflow) for the possible states." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" -"**authors** (Required) A list of authors of the proposal. This is simply " -"the GitHub ID." +"**authors** (Required) A list of authors of the proposal. This is simply the " +"GitHub ID." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" -"**creation-date** (Required) The date that the proposal was first " -"submitted in a PR." +"**creation-date** (Required) The date that the proposal was first submitted " +"in a PR." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 @@ -3515,8 +3489,8 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" -"**see-also** (Optional) A list of other proposals that are relevant to " -"this one." +"**see-also** (Optional) A list of other proposals that are relevant to this " +"one." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 @@ -3524,7 +3498,8 @@ msgid "**replaces** (Optional) A list of proposals that this one replaces." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 -msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." +msgid "" +"**superseded-by** (Optional) A list of proposals that this one supersedes." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 @@ -3534,40 +3509,40 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" "The idea forming the enhancement should already have been discussed or " -"pitched in the community. As such, it needs a champion, usually the " -"author, who shepherds the enhancement. This person also has to find " -"committers to Flower willing to review the proposal." +"pitched in the community. As such, it needs a champion, usually the author, " +"who shepherds the enhancement. This person also has to find committers to " +"Flower willing to review the proposal." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" "New enhancements are checked in with a file name in the form of `NNNN-" -"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement " -"Doc number, to `enhancements`. All enhancements start in `provisional` " -"state as part of a pull request. Discussions are done as part of the pull" -" request review." +"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement Doc " +"number, to `enhancements`. All enhancements start in `provisional` state as " +"part of a pull request. Discussions are done as part of the pull request " +"review." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" -"Once an enhancement has been reviewed and approved, its status is changed" -" to `implementable`. The actual implementation is then done in separate " -"pull requests. These pull requests should mention the respective " -"enhancement as part of their description. After the implementation is " -"done, the proposal status is changed to `implemented`." +"Once an enhancement has been reviewed and approved, its status is changed to " +"`implementable`. The actual implementation is then done in separate pull " +"requests. These pull requests should mention the respective enhancement as " +"part of their description. After the implementation is done, the proposal " +"status is changed to `implemented`." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" -"Under certain conditions, other states are possible. An Enhancement has " -"the following states:" +"Under certain conditions, other states are possible. An Enhancement has the " +"following states:" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" "`provisional`: The enhancement has been proposed and is actively being " -"defined. This is the starting state while the proposal is being fleshed " -"out and actively defined and discussed." +"defined. This is the starting state while the proposal is being fleshed out " +"and actively defined and discussed." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 @@ -3581,13 +3556,14 @@ msgid "" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 -msgid "`deferred`: The enhancement is proposed but not actively being worked on." +msgid "" +"`deferred`: The enhancement is proposed but not actively being worked on." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" -"`rejected`: The authors and reviewers have decided that this enhancement " -"is not moving forward." +"`rejected`: The authors and reviewers have decided that this enhancement is " +"not moving forward." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 @@ -3600,16 +3576,16 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" -"Adding an additional process to the ones already provided by GitHub " -"(Issues and Pull Requests) adds more complexity and can be a barrier for " -"potential first-time contributors." +"Adding an additional process to the ones already provided by GitHub (Issues " +"and Pull Requests) adds more complexity and can be a barrier for potential " +"first-time contributors." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" "Expanding the proposal template beyond the single-sentence description " -"currently required in the features issue template may be a heavy burden " -"for non-native English speakers." +"currently required in the features issue template may be a heavy burden for " +"non-native English speakers." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 @@ -3619,12 +3595,12 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" "Using GitHub Issues for these kinds of enhancements is doable. One could " -"use, for example, tags, to differentiate and filter them from other " -"issues. The main issue is in discussing and reviewing an enhancement: " -"GitHub issues only have a single thread for comments. Enhancements " -"usually have multiple threads of discussion at the same time for various " -"parts of the doc. Managing these multiple discussions can be confusing " -"when using GitHub Issues." +"use, for example, tags, to differentiate and filter them from other issues. " +"The main issue is in discussing and reviewing an enhancement: GitHub issues " +"only have a single thread for comments. Enhancements usually have multiple " +"threads of discussion at the same time for various parts of the doc. " +"Managing these multiple discussions can be confusing when using GitHub " +"Issues." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 @@ -3633,12 +3609,11 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" -"Google Docs allow for multiple threads of discussions. But as Google Docs" -" are hosted outside the project, their discoverability by the community " -"needs to be taken care of. A list of links to all proposals has to be " -"managed and made available for the community. Compared to shipping " -"proposals as part of Flower's repository, the potential for missing links" -" is much higher." +"Google Docs allow for multiple threads of discussions. But as Google Docs " +"are hosted outside the project, their discoverability by the community needs " +"to be taken care of. A list of links to all proposals has to be managed and " +"made available for the community. Compared to shipping proposals as part of " +"Flower's repository, the potential for missing links is much higher." msgstr "" #: ../../source/fed/index.md:1 @@ -3651,8 +3626,8 @@ msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" -"The Flower server does not prescribe a way to aggregate evaluation " -"results, but it enables the user to fully customize result aggregation." +"The Flower server does not prescribe a way to aggregate evaluation results, " +"but it enables the user to fully customize result aggregation." msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:8 @@ -3661,9 +3636,9 @@ msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" -"The same :code:`Strategy`-customization approach can be used to aggregate" -" custom evaluation results coming from individual clients. Clients can " -"return custom metrics to the server by returning a dictionary:" +"The same :code:`Strategy`-customization approach can be used to aggregate " +"custom evaluation results coming from individual clients. Clients can return " +"custom metrics to the server by returning a dictionary:" msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:36 @@ -3678,10 +3653,9 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:4 msgid "" -"Flower has built-in support for authenticated SuperNodes that you can use" -" to verify the identities of each SuperNode connecting to a SuperLink. " -"Flower node authentication works similar to how GitHub SSH authentication" -" works:" +"Flower has built-in support for authenticated SuperNodes that you can use to " +"verify the identities of each SuperNode connecting to a SuperLink. Flower " +"node authentication works similar to how GitHub SSH authentication works:" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:7 @@ -3690,8 +3664,7 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:8 msgid "" -"Using ECDH, both SuperNode and SuperLink independently derive a shared " -"secret" +"Using ECDH, both SuperNode and SuperLink independently derive a shared secret" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:9 @@ -3706,22 +3679,21 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:12 msgid "" -"We recommend you to check out the complete `code example " -"`_ demonstrating federated learning with Flower in an " -"authenticated setting." +"We recommend you to check out the complete `code example `_ demonstrating " +"federated learning with Flower in an authenticated setting." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:15 msgid "" -"This guide covers a preview feature that might change in future versions " -"of Flower." +"This guide covers a preview feature that might change in future versions of " +"Flower." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:18 msgid "" -"For increased security, node authentication can only be used when " -"encrypted connections (SSL/TLS) are enabled." +"For increased security, node authentication can only be used when encrypted " +"connections (SSL/TLS) are enabled." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:21 @@ -3731,13 +3703,12 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:23 msgid "" "To enable node authentication, first you need to configure SSL/TLS " -"connections to secure the SuperLink<>SuperNode communication. You can " -"find the complete guide `here `_. After configuring secure connections, you" -" can enable client authentication in a long-running Flower " -":code:`SuperLink`. Use the following terminal command to start a Flower " -":code:`SuperNode` that has both secure connections and node " -"authentication enabled:" +"connections to secure the SuperLink<>SuperNode communication. You can find " +"the complete guide `here `_. After configuring secure connections, you can enable " +"client authentication in a long-running Flower :code:`SuperLink`. Use the " +"following terminal command to start a Flower :code:`SuperNode` that has both " +"secure connections and node authentication enabled:" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:36 @@ -3746,35 +3717,35 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:38 msgid "" -"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " -"file storing all known node public keys. You need to store all known node" -" public keys that are allowed to participate in a federation in one CSV " -"file (:code:`.csv`)." +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV file " +"storing all known node public keys. You need to store all known node public " +"keys that are allowed to participate in a federation in one CSV file (:code:" +"`.csv`)." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " -"example, refer to our code sample, which contains a CSV file with two " -"known node public keys." +"example, refer to our code sample, which contains a CSV file with two known " +"node public keys." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" -"The second and third flags :code:`--auth-superlink-private-key` and :code" -":`--auth-superlink-public-key` expect paths to the server's private and " -"public keys. For development purposes, you can generate a private and " -"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." +"The second and third flags :code:`--auth-superlink-private-key` and :code:`--" +"auth-superlink-public-key` expect paths to the server's private and public " +"keys. For development purposes, you can generate a private and public key " +"pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:45 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " -"adding known node public keys to the SuperLink. To change the set of " -"known nodes, you need to shut the server down, edit the CSV file, and " -"start the server again. Support for dynamically changing the set of known" -" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." +"adding known node public keys to the SuperLink. To change the set of known " +"nodes, you need to shut the server down, edit the CSV file, and start the " +"server again. Support for dynamically changing the set of known nodes is on " +"the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:51 @@ -3784,18 +3755,18 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:53 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " -"easily enable node authentication in the long-running Flower client " -"(:code:`SuperNode`). Use the following terminal command to start an " -"authenticated :code:`SuperNode`:" +"easily enable node authentication in the long-running Flower client (:code:" +"`SuperNode`). Use the following terminal command to start an authenticated :" +"code:`SuperNode`:" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:64 msgid "" -"The :code:`--auth-supernode-private-key` flag expects a path to the " -"node's private key file and the :code:`--auth-supernode-public-key` flag " -"expects a path to the node's public key file. For development purposes, " -"you can generate a private and public key pair using :code:`ssh-keygen -t" -" ecdsa -b 384`." +"The :code:`--auth-supernode-private-key` flag expects a path to the node's " +"private key file and the :code:`--auth-supernode-public-key` flag expects a " +"path to the node's public key file. For development purposes, you can " +"generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b " +"384`." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:68 @@ -3804,13 +3775,12 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:70 msgid "" -"The system's security relies on the credentials of the SuperLink and each" -" SuperNode. Therefore, it is imperative to safeguard and safely store the" -" credentials to avoid security risks such as Public Key Infrastructure " -"(PKI) impersonation attacks. The node authentication mechanism also " -"involves human interaction, so please ensure that all of the " -"communication is done in a secure manner, using trusted communication " -"methods." +"The system's security relies on the credentials of the SuperLink and each " +"SuperNode. Therefore, it is imperative to safeguard and safely store the " +"credentials to avoid security risks such as Public Key Infrastructure (PKI) " +"impersonation attacks. The node authentication mechanism also involves human " +"interaction, so please ensure that all of the communication is done in a " +"secure manner, using trusted communication methods." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:75 @@ -3822,10 +3792,10 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:77 msgid "" -"You should now have learned how to start a long-running Flower server " -"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " -"authentication enabled. You should also know the significance of the " -"private key and store it safely to minimize security risks." +"You should now have learned how to start a long-running Flower server (:code:" +"`SuperLink`) and client (:code:`SuperNode`) with node authentication " +"enabled. You should also know the significance of the private key and store " +"it safely to minimize security risks." msgstr "" #: ../../source/how-to-configure-clients.rst:2 @@ -3835,9 +3805,9 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:4 msgid "" "Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are," -" for example, a popular way to control client-side hyperparameters from " -"the server." +"clients. Configuration values can be used for various purposes. They are, " +"for example, a popular way to control client-side hyperparameters from the " +"server." msgstr "" #: ../../source/how-to-configure-clients.rst:7 @@ -3846,34 +3816,34 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:9 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys " -"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " -"float), ``int``, or ``str`` (or equivalent types in different languages)." -" Here is an example of a configuration dictionary in Python:" +"Configuration values are represented as a dictionary with ``str`` keys and " +"values of type ``bool``, ``bytes``, ``double`` (64-bit precision float), " +"``int``, or ``str`` (or equivalent types in different languages). Here is an " +"example of a configuration dictionary in Python:" msgstr "" #: ../../source/how-to-configure-clients.rst:20 msgid "" "Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client " -"using gRPC, and then deserializes them back to Python dictionaries." +"short) to their ProtoBuf representation, transports them to the client using " +"gRPC, and then deserializes them back to Python dictionaries." msgstr "" #: ../../source/how-to-configure-clients.rst:24 msgid "" -"Currently, there is no support for directly sending collection types " -"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " -"dictionaries. There are several workarounds to send collections as values" -" by converting them to one of the supported value types (and converting " -"them back on the client-side)." +"Currently, there is no support for directly sending collection types (e.g., " +"``Set``, ``List``, ``Map``) as values in configuration dictionaries. There " +"are several workarounds to send collections as values by converting them to " +"one of the supported value types (and converting them back on the client-" +"side)." msgstr "" #: ../../source/how-to-configure-clients.rst:26 msgid "" "One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and" -" then convert the JSON string back to a list of floating-point numbers on" -" the client." +"string, then send the JSON string using the configuration dictionary, and " +"then convert the JSON string back to a list of floating-point numbers on the " +"client." msgstr "" #: ../../source/how-to-configure-clients.rst:30 @@ -3882,49 +3852,50 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:32 msgid "" -"The easiest way to send configuration values to clients is to use a " -"built-in strategy like :code:`FedAvg`. Built-in strategies support so-" -"called configuration functions. A configuration function is a function " -"that the built-in strategy calls to get the configuration dictionary for " -"the current round. It then forwards the configuration dictionary to all " -"the clients selected during that round." +"The easiest way to send configuration values to clients is to use a built-in " +"strategy like :code:`FedAvg`. Built-in strategies support so-called " +"configuration functions. A configuration function is a function that the " +"built-in strategy calls to get the configuration dictionary for the current " +"round. It then forwards the configuration dictionary to all the clients " +"selected during that round." msgstr "" #: ../../source/how-to-configure-clients.rst:34 msgid "" "Let's start with a simple example. Imagine we want to send (a) the batch " -"size that the client should use, (b) the current global round of " -"federated learning, and (c) the number of epochs to train on the client-" -"side. Our configuration function could look like this:" +"size that the client should use, (b) the current global round of federated " +"learning, and (c) the number of epochs to train on the client-side. Our " +"configuration function could look like this:" msgstr "" #: ../../source/how-to-configure-clients.rst:47 msgid "" "To make the built-in strategies use this function, we can pass it to " -"``FedAvg`` during initialization using the parameter " -":code:`on_fit_config_fn`:" +"``FedAvg`` during initialization using the parameter :code:" +"`on_fit_config_fn`:" msgstr "" #: ../../source/how-to-configure-clients.rst:56 -msgid "One the client side, we receive the configuration dictionary in ``fit``:" +msgid "" +"One the client side, we receive the configuration dictionary in ``fit``:" msgstr "" #: ../../source/how-to-configure-clients.rst:67 msgid "" "There is also an `on_evaluate_config_fn` to configure evaluation, which " -"works the same way. They are separate functions because one might want to" -" send different configuration values to `evaluate` (for example, to use a" -" different batch size)." +"works the same way. They are separate functions because one might want to " +"send different configuration values to `evaluate` (for example, to use a " +"different batch size)." msgstr "" #: ../../source/how-to-configure-clients.rst:69 msgid "" -"The built-in strategies call this function every round (that is, every " -"time `Strategy.configure_fit` or `Strategy.configure_evaluate` runs). " -"Calling `on_evaluate_config_fn` every round allows us to vary/change the " -"config dict over consecutive rounds. If we wanted to implement a " -"hyperparameter schedule, for example, to increase the number of local " -"epochs during later rounds, we could do the following:" +"The built-in strategies call this function every round (that is, every time " +"`Strategy.configure_fit` or `Strategy.configure_evaluate` runs). Calling " +"`on_evaluate_config_fn` every round allows us to vary/change the config dict " +"over consecutive rounds. If we wanted to implement a hyperparameter " +"schedule, for example, to increase the number of local epochs during later " +"rounds, we could do the following:" msgstr "" #: ../../source/how-to-configure-clients.rst:82 @@ -3943,13 +3914,12 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:89 msgid "" -"This can be achieved by customizing an existing strategy or by " -":doc:`implementing a custom strategy from scratch `. Here's a nonsensical example that customizes :code:`FedAvg`" -" by adding a custom ``\"hello\": \"world\"`` configuration key/value pair" -" to the config dict of a *single client* (only the first client in the " -"list, the other clients in this round to not receive this \"special\" " -"config value):" +"This can be achieved by customizing an existing strategy or by :doc:" +"`implementing a custom strategy from scratch `. " +"Here's a nonsensical example that customizes :code:`FedAvg` by adding a " +"custom ``\"hello\": \"world\"`` configuration key/value pair to the config " +"dict of a *single client* (only the first client in the list, the other " +"clients in this round to not receive this \"special\" config value):" msgstr "" #: ../../source/how-to-configure-logging.rst:2 @@ -3959,16 +3929,16 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:4 msgid "" "The Flower logger keeps track of all core events that take place in " -"federated learning workloads. It presents information by default " -"following a standard message format:" +"federated learning workloads. It presents information by default following a " +"standard message format:" msgstr "" #: ../../source/how-to-configure-logging.rst:13 msgid "" -"containing relevant information including: log message level (e.g. " -":code:`INFO`, :code:`DEBUG`), a timestamp, the line where the logging " -"took place from, as well as the log message itself. In this way, the " -"logger would typically display information on your terminal as follows:" +"containing relevant information including: log message level (e.g. :code:" +"`INFO`, :code:`DEBUG`), a timestamp, the line where the logging took place " +"from, as well as the log message itself. In this way, the logger would " +"typically display information on your terminal as follows:" msgstr "" #: ../../source/how-to-configure-logging.rst:34 @@ -3979,21 +3949,20 @@ msgstr "" msgid "" "By default, the Flower log is outputted to the terminal where you launch " "your Federated Learning workload from. This applies for both gRPC-based " -"federation (i.e. when you do :code:`fl.server.start_server`) and when " -"using the :code:`VirtualClientEngine` (i.e. when you do " -":code:`fl.simulation.start_simulation`). In some situations you might " -"want to save this log to disk. You can do so by calling the " -"`fl.common.logger.configure() " -"`_" -" function. For example:" +"federation (i.e. when you do :code:`fl.server.start_server`) and when using " +"the :code:`VirtualClientEngine` (i.e. when you do :code:`fl.simulation." +"start_simulation`). In some situations you might want to save this log to " +"disk. You can do so by calling the `fl.common.logger.configure() `_ function. " +"For example:" msgstr "" #: ../../source/how-to-configure-logging.rst:53 msgid "" -"With the above, Flower will record the log you see on your terminal to " -":code:`log.txt`. This file will be created in the same directory as were " -"you are running the code from. If we inspect we see the log above is also" -" recorded but prefixing with :code:`identifier` each line:" +"With the above, Flower will record the log you see on your terminal to :code:" +"`log.txt`. This file will be created in the same directory as were you are " +"running the code from. If we inspect we see the log above is also recorded " +"but prefixing with :code:`identifier` each line:" msgstr "" #: ../../source/how-to-configure-logging.rst:74 @@ -4002,15 +3971,15 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:76 msgid "" -"You might expand the information shown by default with the Flower logger " -"by adding more messages relevant to your application. You can achieve " -"this easily as follows." +"You might expand the information shown by default with the Flower logger by " +"adding more messages relevant to your application. You can achieve this " +"easily as follows." msgstr "" #: ../../source/how-to-configure-logging.rst:102 msgid "" -"In this way your logger will show, in addition to the default messages, " -"the ones introduced by the clients as specified above." +"In this way your logger will show, in addition to the default messages, the " +"ones introduced by the clients as specified above." msgstr "" #: ../../source/how-to-configure-logging.rst:128 @@ -4019,15 +3988,14 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:130 msgid "" -"The :code:`fl.common.logger.configure` function, also allows specifying a" -" host to which logs can be pushed (via :code:`POST`) through a native " -"Python :code:`logging.handler.HTTPHandler`. This is a particularly useful" -" feature in :code:`gRPC`-based Federated Learning workloads where " -"otherwise gathering logs from all entities (i.e. the server and the " -"clients) might be cumbersome. Note that in Flower simulation, the server " -"automatically displays all logs. You can still specify a " -":code:`HTTPHandler` should you wish to backup or analyze the logs " -"somewhere else." +"The :code:`fl.common.logger.configure` function, also allows specifying a " +"host to which logs can be pushed (via :code:`POST`) through a native Python :" +"code:`logging.handler.HTTPHandler`. This is a particularly useful feature " +"in :code:`gRPC`-based Federated Learning workloads where otherwise gathering " +"logs from all entities (i.e. the server and the clients) might be " +"cumbersome. Note that in Flower simulation, the server automatically " +"displays all logs. You can still specify a :code:`HTTPHandler` should you " +"wish to backup or analyze the logs somewhere else." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:2 @@ -4036,24 +4004,23 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:4 msgid "" -"This guide describes how to a SSL-enabled secure Flower server " -"(:code:`SuperLink`) can be started and how a Flower client " -"(:code:`SuperNode`) can establish a secure connections to it." +"This guide describes how to a SSL-enabled secure Flower server (:code:" +"`SuperLink`) can be started and how a Flower client (:code:`SuperNode`) can " +"establish a secure connections to it." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" -"A complete code example demonstrating a secure connection can be found " -"`here `_." +"A complete code example demonstrating a secure connection can be found `here " +"`_." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" -"The code example comes with a :code:`README.md` file which explains how " -"to start it. Although it is already SSL-enabled, it might be less " -"descriptive on how it does so. Stick to this guide for a deeper " -"introduction to the topic." +"The code example comes with a :code:`README.md` file which explains how to " +"start it. Although it is already SSL-enabled, it might be less descriptive " +"on how it does so. Stick to this guide for a deeper introduction to the " +"topic." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:16 @@ -4063,27 +4030,27 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:18 msgid "" "Using SSL-enabled connections requires certificates to be passed to the " -"server and client. For the purpose of this guide we are going to generate" -" self-signed certificates. As this can become quite complex we are going " -"to ask you to run the script in :code:`examples/advanced-" -"tensorflow/certificates/generate.sh` with the following command sequence:" +"server and client. For the purpose of this guide we are going to generate " +"self-signed certificates. As this can become quite complex we are going to " +"ask you to run the script in :code:`examples/advanced-tensorflow/" +"certificates/generate.sh` with the following command sequence:" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" -"This will generate the certificates in :code:`examples/advanced-" -"tensorflow/.cache/certificates`." +"This will generate the certificates in :code:`examples/advanced-tensorflow/." +"cache/certificates`." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:31 msgid "" -"The approach for generating SSL certificates in the context of this " -"example can serve as an inspiration and starting point, but it should not" -" be used as a reference for production environments. Please refer to " -"other sources regarding the issue of correctly generating certificates " -"for production environments. For non-critical prototyping or research " -"projects, it might be sufficient to use the self-signed certificates " -"generated using the scripts mentioned in this guide." +"The approach for generating SSL certificates in the context of this example " +"can serve as an inspiration and starting point, but it should not be used as " +"a reference for production environments. Please refer to other sources " +"regarding the issue of correctly generating certificates for production " +"environments. For non-critical prototyping or research projects, it might be " +"sufficient to use the self-signed certificates generated using the scripts " +"mentioned in this guide." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:39 @@ -4092,15 +4059,15 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:41 msgid "" -"Use the following terminal command to start a sever (SuperLink) that uses" -" the previously generated certificates:" +"Use the following terminal command to start a sever (SuperLink) that uses " +"the previously generated certificates:" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:47 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates paths: CA certificate, server certificate and server private" -" key." +"certificates paths: CA certificate, server certificate and server private " +"key." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:51 @@ -4109,21 +4076,21 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:53 msgid "" -"Use the following terminal command to start a client (SuperNode) that " -"uses the previously generated certificates:" +"Use the following terminal command to start a client (SuperNode) that uses " +"the previously generated certificates:" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:61 msgid "" -"When setting :code:`root_certificates`, the client expects a file path to" -" PEM-encoded root certificates." +"When setting :code:`root_certificates`, the client expects a file path to " +"PEM-encoded root certificates." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:67 msgid "" -"You should now have learned how to generate self-signed certificates " -"using the given script, start an SSL-enabled server and have a client " -"establish a secure connection to it." +"You should now have learned how to generate self-signed certificates using " +"the given script, start an SSL-enabled server and have a client establish a " +"secure connection to it." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:72 @@ -4132,8 +4099,8 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:74 msgid "" -"These additional sources might be relevant if you would like to dive " -"deeper into the topic of certificates:" +"These additional sources might be relevant if you would like to dive deeper " +"into the topic of certificates:" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:76 @@ -4150,12 +4117,12 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:4 msgid "" -"The strategy abstraction enables implementation of fully custom " -"strategies. A strategy is basically the federated learning algorithm that" -" runs on the server. Strategies decide how to sample clients, how to " -"configure clients for training, how to aggregate updates, and how to " -"evaluate models. Flower provides a few built-in strategies which are " -"based on the same API described below." +"The strategy abstraction enables implementation of fully custom strategies. " +"A strategy is basically the federated learning algorithm that runs on the " +"server. Strategies decide how to sample clients, how to configure clients " +"for training, how to aggregate updates, and how to evaluate models. Flower " +"provides a few built-in strategies which are based on the same API described " +"below." msgstr "" #: ../../source/how-to-implement-strategies.rst:11 @@ -4164,11 +4131,10 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:13 msgid "" -"All strategy implementation are derived from the abstract base class " -":code:`flwr.server.strategy.Strategy`, both built-in implementations and " -"third party implementations. This means that custom strategy " -"implementations have the exact same capabilities at their disposal as " -"built-in ones." +"All strategy implementation are derived from the abstract base class :code:" +"`flwr.server.strategy.Strategy`, both built-in implementations and third " +"party implementations. This means that custom strategy implementations have " +"the exact same capabilities at their disposal as built-in ones." msgstr "" #: ../../source/how-to-implement-strategies.rst:18 @@ -4179,9 +4145,9 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:75 msgid "" -"Creating a new strategy means implementing a new :code:`class` (derived " -"from the abstract base class :code:`Strategy`) that implements for the " -"previously shown abstract methods:" +"Creating a new strategy means implementing a new :code:`class` (derived from " +"the abstract base class :code:`Strategy`) that implements for the previously " +"shown abstract methods:" msgstr "" #: ../../source/how-to-implement-strategies.rst:100 @@ -4198,37 +4164,35 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:182 msgid "" -":code:`initialize_parameters` is called only once, at the very beginning " -"of an execution. It is responsible for providing the initial global model" -" parameters in a serialized form (i.e., as a :code:`Parameters` object)." +":code:`initialize_parameters` is called only once, at the very beginning of " +"an execution. It is responsible for providing the initial global model " +"parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" #: ../../source/how-to-implement-strategies.rst:184 msgid "" -"Built-in strategies return user-provided initial parameters. The " -"following example shows how initial parameters can be passed to " -":code:`FedAvg`:" +"Built-in strategies return user-provided initial parameters. The following " +"example shows how initial parameters can be passed to :code:`FedAvg`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:209 msgid "" "The Flower server will call :code:`initialize_parameters`, which either " -"returns the parameters that were passed to :code:`initial_parameters`, or" -" :code:`None`. If no parameters are returned from " -":code:`initialize_parameters` (i.e., :code:`None`), the server will " -"randomly select one client and ask it to provide its parameters. This is " -"a convenience feature and not recommended in practice, but it can be " -"useful for prototyping. In practice, it is recommended to always use " -"server-side parameter initialization." +"returns the parameters that were passed to :code:`initial_parameters`, or :" +"code:`None`. If no parameters are returned from :code:" +"`initialize_parameters` (i.e., :code:`None`), the server will randomly " +"select one client and ask it to provide its parameters. This is a " +"convenience feature and not recommended in practice, but it can be useful " +"for prototyping. In practice, it is recommended to always use server-side " +"parameter initialization." msgstr "" #: ../../source/how-to-implement-strategies.rst:213 msgid "" "Server-side parameter initialization is a powerful mechanism. It can be " -"used, for example, to resume training from a previously saved checkpoint." -" It is also the fundamental capability needed to implement hybrid " -"approaches, for example, to fine-tune a pre-trained model using federated" -" learning." +"used, for example, to resume training from a previously saved checkpoint. It " +"is also the fundamental capability needed to implement hybrid approaches, " +"for example, to fine-tune a pre-trained model using federated learning." msgstr "" #: ../../source/how-to-implement-strategies.rst:216 @@ -4237,17 +4201,17 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:218 msgid "" -":code:`configure_fit` is responsible for configuring the upcoming round " -"of training. What does *configure* mean in this context? Configuring a " -"round means selecting clients and deciding what instructions to send to " -"these clients. The signature of :code:`configure_fit` makes this clear:" +":code:`configure_fit` is responsible for configuring the upcoming round of " +"training. What does *configure* mean in this context? Configuring a round " +"means selecting clients and deciding what instructions to send to these " +"clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" #: ../../source/how-to-implement-strategies.rst:231 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_fit`:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_fit`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:233 @@ -4266,19 +4230,18 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:236 msgid "" "More sophisticated implementations can use :code:`configure_fit` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_fit`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_fit`." msgstr "" #: ../../source/how-to-implement-strategies.rst:240 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to train, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"train, for example, different models on different clients, or use different " +"hyperparameters on different clients (via the :code:`config` dict)." msgstr "" #: ../../source/how-to-implement-strategies.rst:243 @@ -4287,24 +4250,23 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:245 msgid "" -":code:`aggregate_fit` is responsible for aggregating the results returned" -" by the clients that were selected and asked to train in " -":code:`configure_fit`." +":code:`aggregate_fit` is responsible for aggregating the results returned by " +"the clients that were selected and asked to train in :code:`configure_fit`." msgstr "" #: ../../source/how-to-implement-strategies.rst:258 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " -"of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_fit`). :code:`aggregate_fit` therefore receives a list of :code:" +"`results`, but also a list of :code:`failures`." msgstr "" #: ../../source/how-to-implement-strategies.rst:260 msgid "" -":code:`aggregate_fit` returns an optional :code:`Parameters` object and a" -" dictionary of aggregated metrics. The :code:`Parameters` return value is" -" optional because :code:`aggregate_fit` might decide that the results " +":code:`aggregate_fit` returns an optional :code:`Parameters` object and a " +"dictionary of aggregated metrics. The :code:`Parameters` return value is " +"optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" @@ -4314,42 +4276,40 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:265 msgid "" -":code:`configure_evaluate` is responsible for configuring the upcoming " -"round of evaluation. What does *configure* mean in this context? " -"Configuring a round means selecting clients and deciding what " -"instructions to send to these clients. The signature of " -":code:`configure_evaluate` makes this clear:" +":code:`configure_evaluate` is responsible for configuring the upcoming round " +"of evaluation. What does *configure* mean in this context? Configuring a " +"round means selecting clients and deciding what instructions to send to " +"these clients. The signature of :code:`configure_evaluate` makes this clear:" msgstr "" #: ../../source/how-to-implement-strategies.rst:278 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_evaluate`:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_evaluate`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:281 msgid "" -"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " -"the current global model :code:`parameters` and :code:`config` dict" +"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding the " +"current global model :code:`parameters` and :code:`config` dict" msgstr "" #: ../../source/how-to-implement-strategies.rst:283 msgid "" "More sophisticated implementations can use :code:`configure_evaluate` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_evaluate`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_evaluate`." msgstr "" #: ../../source/how-to-implement-strategies.rst:287 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to evaluate, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"evaluate, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` dict)." msgstr "" #: ../../source/how-to-implement-strategies.rst:291 @@ -4359,24 +4319,24 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:293 msgid "" ":code:`aggregate_evaluate` is responsible for aggregating the results " -"returned by the clients that were selected and asked to evaluate in " -":code:`configure_evaluate`." +"returned by the clients that were selected and asked to evaluate in :code:" +"`configure_evaluate`." msgstr "" #: ../../source/how-to-implement-strategies.rst:306 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " -"receives a list of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_evaluate`). :code:`aggregate_evaluate` therefore receives a list " +"of :code:`results`, but also a list of :code:`failures`." msgstr "" #: ../../source/how-to-implement-strategies.rst:308 msgid "" -":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a" -" dictionary of aggregated metrics. The :code:`float` return value is " -"optional because :code:`aggregate_evaluate` might decide that the results" -" provided are not sufficient for aggregation (e.g., too many failures)." +":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a " +"dictionary of aggregated metrics. The :code:`float` return value is optional " +"because :code:`aggregate_evaluate` might decide that the results provided " +"are not sufficient for aggregation (e.g., too many failures)." msgstr "" #: ../../source/how-to-implement-strategies.rst:311 @@ -4386,17 +4346,17 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:313 msgid "" ":code:`evaluate` is responsible for evaluating model parameters on the " -"server-side. Having :code:`evaluate` in addition to " -":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " -"to perform both servers-side and client-side (federated) evaluation." +"server-side. Having :code:`evaluate` in addition to :code:" +"`configure_evaluate`/:code:`aggregate_evaluate` enables strategies to " +"perform both servers-side and client-side (federated) evaluation." msgstr "" #: ../../source/how-to-implement-strategies.rst:323 msgid "" -"The return value is again optional because the strategy might not need to" -" implement server-side evaluation or because the user-defined " -":code:`evaluate` method might not complete successfully (e.g., it might " -"fail to load the server-side evaluation data)." +"The return value is again optional because the strategy might not need to " +"implement server-side evaluation or because the user-defined :code:" +"`evaluate` method might not complete successfully (e.g., it might fail to " +"load the server-side evaluation data)." msgstr "" #: ../../source/how-to-install-flower.rst:2 @@ -4418,8 +4378,7 @@ msgstr "" #: ../../source/how-to-install-flower.rst:17 msgid "" -"Stable releases are available on `PyPI " -"`_::" +"Stable releases are available on `PyPI `_::" msgstr "" #: ../../source/how-to-install-flower.rst:21 @@ -4438,14 +4397,14 @@ msgstr "" #: ../../source/how-to-install-flower.rst:31 msgid "" -"If you have not added ``conda-forge`` to your channels, you will first " -"need to run the following::" +"If you have not added ``conda-forge`` to your channels, you will first need " +"to run the following::" msgstr "" #: ../../source/how-to-install-flower.rst:36 msgid "" -"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " -"installed with ``conda``::" +"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be installed " +"with ``conda``::" msgstr "" #: ../../source/how-to-install-flower.rst:40 @@ -4459,8 +4418,8 @@ msgstr "" #: ../../source/how-to-install-flower.rst:48 msgid "" "The following command can be used to verify if Flower was successfully " -"installed. If everything worked, it should print the version of Flower to" -" the command line::" +"installed. If everything worked, it should print the version of Flower to " +"the command line::" msgstr "" #: ../../source/how-to-install-flower.rst:55 @@ -4481,15 +4440,15 @@ msgstr "" #: ../../source/how-to-install-flower.rst:65 msgid "" -"New (possibly unstable) versions of Flower are sometimes available as " -"pre-release versions (alpha, beta, release candidate) before the stable " -"release happens::" +"New (possibly unstable) versions of Flower are sometimes available as pre-" +"release versions (alpha, beta, release candidate) before the stable release " +"happens::" msgstr "" #: ../../source/how-to-install-flower.rst:69 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" -" should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases " +"should be installed with the ``simulation`` extra::" msgstr "" #: ../../source/how-to-install-flower.rst:74 @@ -4498,14 +4457,14 @@ msgstr "" #: ../../source/how-to-install-flower.rst:76 msgid "" -"The latest (potentially unstable) changes in Flower are available as " -"nightly releases::" +"The latest (potentially unstable) changes in Flower are available as nightly " +"releases::" msgstr "" #: ../../source/how-to-install-flower.rst:80 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr-nightly`` " -"should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr-nightly`` should " +"be installed with the ``simulation`` extra::" msgstr "" #: ../../source/how-to-monitor-simulation.rst:2 @@ -4514,17 +4473,17 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" -"Flower allows you to monitor system resources while running your " -"simulation. Moreover, the Flower simulation engine is powerful and " -"enables you to decide how to allocate resources per client manner and " -"constrain the total usage. Insights from resource consumption can help " -"you make smarter decisions and speed up the execution time." +"Flower allows you to monitor system resources while running your simulation. " +"Moreover, the Flower simulation engine is powerful and enables you to decide " +"how to allocate resources per client manner and constrain the total usage. " +"Insights from resource consumption can help you make smarter decisions and " +"speed up the execution time." msgstr "" #: ../../source/how-to-monitor-simulation.rst:6 msgid "" -"The specific instructions assume you are using macOS and have the " -"`Homebrew `_ package manager installed." +"The specific instructions assume you are using macOS and have the `Homebrew " +"`_ package manager installed." msgstr "" #: ../../source/how-to-monitor-simulation.rst:10 @@ -4533,10 +4492,10 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" -"`Prometheus `_ is used for data collection, while" -" `Grafana `_ will enable you to visualize the " -"collected data. They are both well integrated with `Ray " -"`_ which Flower uses under the hood." +"`Prometheus `_ is used for data collection, while " +"`Grafana `_ will enable you to visualize the collected " +"data. They are both well integrated with `Ray `_ which " +"Flower uses under the hood." msgstr "" #: ../../source/how-to-monitor-simulation.rst:18 @@ -4555,22 +4514,21 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" -"Open the respective configuration files and change them. Depending on " -"your device, use one of the two following commands:" +"Open the respective configuration files and change them. Depending on your " +"device, use one of the two following commands:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" -"and then delete all the text in the file and paste a new Prometheus " -"config you see below. You may adjust the time intervals to your " -"requirements:" +"and then delete all the text in the file and paste a new Prometheus config " +"you see below. You may adjust the time intervals to your requirements:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" -"Now after you have edited the Prometheus configuration, do the same with " -"the Grafana configuration files. Open those using one of the following " -"commands as before:" +"Now after you have edited the Prometheus configuration, do the same with the " +"Grafana configuration files. Open those using one of the following commands " +"as before:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:69 @@ -4581,8 +4539,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:84 msgid "" -"Congratulations, you just downloaded all the necessary software needed " -"for metrics tracking. Now, let’s start it." +"Congratulations, you just downloaded all the necessary software needed for " +"metrics tracking. Now, let’s start it." msgstr "" #: ../../source/how-to-monitor-simulation.rst:88 @@ -4597,8 +4555,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:97 msgid "" -"Please include the following argument in your Python code when starting a" -" simulation." +"Please include the following argument in your Python code when starting a " +"simulation." msgstr "" #: ../../source/how-to-monitor-simulation.rst:108 @@ -4607,8 +4565,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:110 msgid "" -"Shortly after the simulation starts, you should see the following logs in" -" your terminal:" +"Shortly after the simulation starts, you should see the following logs in " +"your terminal:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:117 @@ -4617,17 +4575,17 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:119 msgid "" -"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" -" lowest option)." +"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the " +"lowest option)." msgstr "" #: ../../source/how-to-monitor-simulation.rst:121 msgid "" -"Or alternatively, you can just see them in Grafana by clicking on the " -"right-up corner, “View in Grafana”. Please note that the Ray dashboard is" -" only accessible during the simulation. After the simulation ends, you " -"can only use Grafana to explore the metrics. You can start Grafana by " -"going to ``http://localhost:3000/``." +"Or alternatively, you can just see them in Grafana by clicking on the right-" +"up corner, “View in Grafana”. Please note that the Ray dashboard is only " +"accessible during the simulation. After the simulation ends, you can only " +"use Grafana to explore the metrics. You can start Grafana by going to " +"``http://localhost:3000/``." msgstr "" #: ../../source/how-to-monitor-simulation.rst:123 @@ -4643,18 +4601,18 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" -"You must understand how the Ray library works to efficiently allocate " -"system resources to simulation clients on your own." +"You must understand how the Ray library works to efficiently allocate system " +"resources to simulation clients on your own." msgstr "" #: ../../source/how-to-monitor-simulation.rst:136 msgid "" "Initially, the simulation (which Ray handles under the hood) starts by " "default with all the available resources on the system, which it shares " -"among the clients. It doesn't mean it divides it equally among all of " -"them, nor that the model training happens at all of them simultaneously. " -"You will learn more about that in the later part of this blog. You can " -"check the system resources by running the following:" +"among the clients. It doesn't mean it divides it equally among all of them, " +"nor that the model training happens at all of them simultaneously. You will " +"learn more about that in the later part of this blog. You can check the " +"system resources by running the following:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:143 @@ -4663,8 +4621,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:155 msgid "" -"However, you can overwrite the defaults. When starting a simulation, do " -"the following (you don't need to overwrite all of them):" +"However, you can overwrite the defaults. When starting a simulation, do the " +"following (you don't need to overwrite all of them):" msgstr "" #: ../../source/how-to-monitor-simulation.rst:175 @@ -4673,19 +4631,19 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:205 msgid "" -"Now comes the crucial part. Ray will start a new client only when it has " -"all the required resources (such that they run in parallel) when the " -"resources allow." +"Now comes the crucial part. Ray will start a new client only when it has all " +"the required resources (such that they run in parallel) when the resources " +"allow." msgstr "" #: ../../source/how-to-monitor-simulation.rst:207 msgid "" -"In the example above, only one client will be run, so your clients won't " -"run concurrently. Setting :code:`client_num_gpus = 0.5` would allow " -"running two clients and therefore enable them to run concurrently. Be " -"careful not to require more resources than available. If you specified " -":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " -"had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." +"In the example above, only one client will be run, so your clients won't run " +"concurrently. Setting :code:`client_num_gpus = 0.5` would allow running two " +"clients and therefore enable them to run concurrently. Be careful not to " +"require more resources than available. If you specified :code:" +"`client_num_gpus = 2`, the simulation wouldn't start (even if you had 2 GPUs " +"but decided to set 1 in :code:`ray_init_args`)." msgstr "" #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 @@ -4698,22 +4656,21 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:216 msgid "" -"A: The timeframe might not be properly set. The setting is in the top " -"right corner (\"Last 30 minutes\" by default). Please change the " -"timeframe to reflect the period when the simulation was running." +"A: The timeframe might not be properly set. The setting is in the top right " +"corner (\"Last 30 minutes\" by default). Please change the timeframe to " +"reflect the period when the simulation was running." msgstr "" #: ../../source/how-to-monitor-simulation.rst:218 msgid "" -"Q: I see “Grafana server not detected. Please make sure the Grafana " -"server is running and refresh this page” after going to the Metrics tab " -"in Ray Dashboard." +"Q: I see “Grafana server not detected. Please make sure the Grafana server " +"is running and refresh this page” after going to the Metrics tab in Ray " +"Dashboard." msgstr "" #: ../../source/how-to-monitor-simulation.rst:220 msgid "" -"A: You probably don't have Grafana running. Please check the running " -"services" +"A: You probably don't have Grafana running. Please check the running services" msgstr "" #: ../../source/how-to-monitor-simulation.rst:226 @@ -4724,8 +4681,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:228 msgid "" -"A: Either the simulation has already finished, or you still need to start" -" Prometheus." +"A: Either the simulation has already finished, or you still need to start " +"Prometheus." msgstr "" #: ../../source/how-to-monitor-simulation.rst:232 @@ -4748,9 +4705,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:4 msgid "" -"The simplest way to get started with Flower is by using the pre-made " -"Docker images, which you can find on `Docker Hub " -"`__." +"The simplest way to get started with Flower is by using the pre-made Docker " +"images, which you can find on `Docker Hub `__." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:7 @@ -4759,26 +4715,25 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:14 msgid "" -"If you do not see the version of Docker but instead get an error saying " -"that the command was not found, you will need to install Docker first. " -"You can find installation instruction `here `_." +"If you do not see the version of Docker but instead get an error saying that " +"the command was not found, you will need to install Docker first. You can " +"find installation instruction `here `_." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:20 msgid "" -"On Linux, Docker commands require ``sudo`` privilege. If you want to " -"avoid using ``sudo``, you can follow the `Post-installation steps " -"`_ on the " -"official Docker website." +"On Linux, Docker commands require ``sudo`` privilege. If you want to avoid " +"using ``sudo``, you can follow the `Post-installation steps `_ on the official Docker " +"website." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:26 msgid "" -"To ensure optimal performance and compatibility, the SuperLink, SuperNode" -" and ServerApp image must have the same version when running together. " -"This guarantees seamless integration and avoids potential conflicts or " -"issues that may arise from using different versions." +"To ensure optimal performance and compatibility, the SuperLink, SuperNode " +"and ServerApp image must have the same version when running together. This " +"guarantees seamless integration and avoids potential conflicts or issues " +"that may arise from using different versions." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:31 @@ -4795,27 +4750,25 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:42 msgid "" -"The command pulls the Docker image with the tag ``1.8.0`` from Docker " -"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " -"The ``--rm`` flag tells Docker to remove the container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker Hub. " +"The tag specifies the Flower version. In this case, Flower 1.8.0. The ``--" +"rm`` flag tells Docker to remove the container after it exits." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:48 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " -"Docker flag ``--rm``, the state is not persisted between container " -"starts. We will show below how to save the state in a file on your host " -"system." +"Docker flag ``--rm``, the state is not persisted between container starts. " +"We will show below how to save the state in a file on your host system." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:52 msgid "" -"The ``-p :`` flag tells Docker to map the ports " -"``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " -"allowing you to access the Driver API on ``http://localhost:9091`` and " -"the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " -"after the tag is passed to the Flower SuperLink. Here, we are passing the" -" flag ``--insecure``." +"The ``-p :`` flag tells Docker to map the ports ``9091``/" +"``9092`` of the host to ``9091``/``9092`` of the container, allowing you to " +"access the Driver API on ``http://localhost:9091`` and the Fleet API on " +"``http://localhost:9092``. Lastly, any flag that comes after the tag is " +"passed to the Flower SuperLink. Here, we are passing the flag ``--insecure``." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:59 @@ -4823,10 +4776,10 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:354 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " -"HTTPS) and should only be used for testing purposes. We strongly " -"recommend enabling `SSL `__ when " -"deploying to a production environment." +"HTTPS) and should only be used for testing purposes. We strongly recommend " +"enabling `SSL `__ when deploying to a " +"production environment." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:64 @@ -4841,21 +4794,20 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:73 msgid "" -"If you want to persist the state of the SuperLink on your host system, " -"all you need to do is specify a path where you want to save the file on " -"your host system and a name for the database file. In the example below, " -"we tell Docker via the flag ``--volume`` to mount the user's home " -"directory (``~/`` on your host) into the ``/app/`` directory of the " -"container. Furthermore, we use the flag ``--database`` to specify the " -"name of the database file." +"If you want to persist the state of the SuperLink on your host system, all " +"you need to do is specify a path where you want to save the file on your " +"host system and a name for the database file. In the example below, we tell " +"Docker via the flag ``--volume`` to mount the user's home directory (``~/`` " +"on your host) into the ``/app/`` directory of the container. Furthermore, we " +"use the flag ``--database`` to specify the name of the database file." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:86 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, " -"the SuperLink tries to restore the state from the file. To start the " -"SuperLink with an empty database, simply remove the ``state.db`` file." +"user's home directory on your host system. If the file already exists, the " +"SuperLink tries to restore the state from the file. To start the SuperLink " +"with an empty database, simply remove the ``state.db`` file." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:91 @@ -4866,25 +4818,25 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:93 msgid "" -"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" -"encoded private key and a PEM-encoded certificate chain." +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-encoded " +"private key and a PEM-encoded certificate chain." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:97 msgid "" -"For testing purposes, you can generate your own self-signed certificates." -" The `Enable SSL connections `__ page contains a section that" -" will guide you through the process." +"For testing purposes, you can generate your own self-signed certificates. " +"The `Enable SSL connections `__ page contains a section that will " +"guide you through the process." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:101 msgid "" -"Assuming all files we need are in the local ``certificates`` directory, " -"we can use the flag ``--volume`` to mount the local directory into the " -"``/app/`` directory of the container. This allows the SuperLink to access" -" the files within the container. Finally, we pass the names of the " -"certificates to the SuperLink with the ``--certificates`` flag." +"Assuming all files we need are in the local ``certificates`` directory, we " +"can use the flag ``--volume`` to mount the local directory into the ``/app/" +"`` directory of the container. This allows the SuperLink to access the files " +"within the container. Finally, we pass the names of the certificates to the " +"SuperLink with the ``--certificates`` flag." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:113 @@ -4893,31 +4845,31 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:115 msgid "" -"The SuperNode Docker image comes with a pre-installed version of Flower " -"and serves as a base for building your own SuperNode image." +"The SuperNode Docker image comes with a pre-installed version of Flower and " +"serves as a base for building your own SuperNode image." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:120 msgid "" "The SuperNode Docker image currently works only with the 1.9.0-nightly " -"release. A stable version will be available when Flower 1.9.0 (stable) " -"gets released (ETA: May). A SuperNode nightly image must be paired with " -"the corresponding SuperLink and ServerApp nightly images released on the " -"same day. To ensure the versions are in sync, using the concrete tag, " -"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." +"release. A stable version will be available when Flower 1.9.0 (stable) gets " +"released (ETA: May). A SuperNode nightly image must be paired with the " +"corresponding SuperLink and ServerApp nightly images released on the same " +"day. To ensure the versions are in sync, using the concrete tag, e.g., " +"``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:126 msgid "" -"We will use the ``quickstart-pytorch`` example, which you can find in the" -" Flower repository, to illustrate how you can dockerize your ClientApp." +"We will use the ``quickstart-pytorch`` example, which you can find in the " +"Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:134 msgid "" "Before we can start, we need to meet a few prerequisites in our local " -"development environment. You can skip the first part if you want to run " -"your ClientApp instead of the ``quickstart-pytorch`` example." +"development environment. You can skip the first part if you want to run your " +"ClientApp instead of the ``quickstart-pytorch`` example." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:138 @@ -4935,24 +4887,24 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:163 msgid "" -"First, we need to create a ``requirements.txt`` file in the directory " -"where the ``ClientApp`` code is located. In the file, we list all the " -"dependencies that the ClientApp requires." +"First, we need to create a ``requirements.txt`` file in the directory where " +"the ``ClientApp`` code is located. In the file, we list all the dependencies " +"that the ClientApp requires." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:175 msgid "" -"Note that `flwr `__ is already installed " -"in the ``flwr/supernode`` base image, so you only need to include other " -"package dependencies in your ``requirements.txt``, such as ``torch``, " +"Note that `flwr `__ is already installed in " +"the ``flwr/supernode`` base image, so you only need to include other package " +"dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:179 msgid "" -"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " -"example, create a new file called ``Dockerfile.supernode`` in ``examples" -"/quickstart-pytorch``." +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` example, " +"create a new file called ``Dockerfile.supernode`` in ``examples/quickstart-" +"pytorch``." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:182 @@ -4963,15 +4915,15 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:196 msgid "" -"In the first two lines, we instruct Docker to use the SuperNode image " -"tagged ``nightly`` as a base image and set our working directory to " -"``/app``. The following instructions will now be executed in the ``/app``" -" directory. Next, we install the ClientApp dependencies by copying the " -"``requirements.txt`` file into the image and run ``pip install``. In the " -"last two lines, we copy the ``client.py`` module into the image and set " -"the entry point to ``flower-client-app`` with the argument " -"``client:app``. The argument is the object reference of the ClientApp " -"(``:``) that will be run inside the ClientApp." +"In the first two lines, we instruct Docker to use the SuperNode image tagged " +"``nightly`` as a base image and set our working directory to ``/app``. The " +"following instructions will now be executed in the ``/app`` directory. Next, " +"we install the ClientApp dependencies by copying the ``requirements.txt`` " +"file into the image and run ``pip install``. In the last two lines, we copy " +"the ``client.py`` module into the image and set the entry point to ``flower-" +"client-app`` with the argument ``client:app``. The argument is the object " +"reference of the ClientApp (``:``) that will be run " +"inside the ClientApp." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:205 @@ -4980,8 +4932,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:207 msgid "" -"Next, we build the SuperNode Docker image by running the following " -"command in the directory where Dockerfile and ClientApp code are located." +"Next, we build the SuperNode Docker image by running the following command " +"in the directory where Dockerfile and ClientApp code are located." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:214 @@ -5012,8 +4964,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:232 #: ../../source/how-to-run-flower-using-docker.rst:348 msgid "" -"``--rm``: This option specifies that the container should be " -"automatically removed when it stops." +"``--rm``: This option specifies that the container should be automatically " +"removed when it stops." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:233 @@ -5027,8 +4979,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the" -" SuperLinks Fleet" +"``--server 192.168.1.100:9092``: This option specifies the address of the " +"SuperLinks Fleet" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst @@ -5037,10 +4989,10 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:248 msgid "" -"To test running Flower locally, you can create a `bridge network " -"`__, use the ``--network`` argument and pass the " -"name of the Docker network to run your SuperNodes." +"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " +"network to run your SuperNodes." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:252 @@ -5057,11 +5009,10 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:264 msgid "" -"Assuming the certificate already exists locally, we can use the flag " -"``--volume`` to mount the local certificate into the container's " -"``/app/`` directory. This allows the SuperNode to access the certificate " -"within the container. Use the ``--certificates`` flag when starting the " -"container." +"Assuming the certificate already exists locally, we can use the flag ``--" +"volume`` to mount the local certificate into the container's ``/app/`` " +"directory. This allows the SuperNode to access the certificate within the " +"container. Use the ``--certificates`` flag when starting the container." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:275 @@ -5070,22 +5021,22 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:277 msgid "" -"The procedure for building and running a ServerApp image is almost " -"identical to the SuperNode image." +"The procedure for building and running a ServerApp image is almost identical " +"to the SuperNode image." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:279 msgid "" -"Similar to the SuperNode image, the ServerApp Docker image comes with a " -"pre-installed version of Flower and serves as a base for building your " -"own ServerApp image." +"Similar to the SuperNode image, the ServerApp Docker image comes with a pre-" +"installed version of Flower and serves as a base for building your own " +"ServerApp image." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:282 msgid "" -"We will use the same ``quickstart-pytorch`` example as we do in the " -"Flower SuperNode section. If you have not already done so, please follow " -"the `SuperNode Prerequisites`_ before proceeding." +"We will use the same ``quickstart-pytorch`` example as we do in the Flower " +"SuperNode section. If you have not already done so, please follow the " +"`SuperNode Prerequisites`_ before proceeding." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:287 @@ -5096,8 +5047,8 @@ msgstr "" msgid "" "First, we need to create a Dockerfile in the directory where the " "``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " -"example, create a new file called ``Dockerfile.serverapp`` in ``examples" -"/quickstart-pytorch``." +"example, create a new file called ``Dockerfile.serverapp`` in ``examples/" +"quickstart-pytorch``." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:302 @@ -5108,14 +5059,13 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:313 msgid "" -"In the first two lines, we instruct Docker to use the ServerApp image " -"tagged ``1.8.0`` as a base image and set our working directory to " -"``/app``. The following instructions will now be executed in the ``/app``" -" directory. In the last two lines, we copy the ``server.py`` module into " -"the image and set the entry point to ``flower-server-app`` with the " -"argument ``server:app``. The argument is the object reference of the " -"ServerApp (``:``) that will be run inside the " -"ServerApp container." +"In the first two lines, we instruct Docker to use the ServerApp image tagged " +"``1.8.0`` as a base image and set our working directory to ``/app``. The " +"following instructions will now be executed in the ``/app`` directory. In " +"the last two lines, we copy the ``server.py`` module into the image and set " +"the entry point to ``flower-server-app`` with the argument ``server:app``. " +"The argument is the object reference of the ServerApp (``:" +"``) that will be run inside the ServerApp container." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:321 @@ -5124,8 +5074,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:323 msgid "" -"Next, we build the ServerApp Docker image by running the following " -"command in the directory where Dockerfile and ServerApp code are located." +"Next, we build the ServerApp Docker image by running the following command " +"in the directory where Dockerfile and ServerApp code are located." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:330 @@ -5149,16 +5099,16 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9091``: This option specifies the address of the" -" SuperLinks Driver" +"``--server 192.168.1.100:9091``: This option specifies the address of the " +"SuperLinks Driver" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:363 msgid "" -"To test running Flower locally, you can create a `bridge network " -"`__, use the ``--network`` argument and pass the " -"name of the Docker network to run your ServerApps." +"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " +"network to run your ServerApps." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:367 @@ -5175,11 +5125,10 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:379 msgid "" -"Assuming the certificate already exists locally, we can use the flag " -"``--volume`` to mount the local certificate into the container's " -"``/app/`` directory. This allows the ServerApp to access the certificate " -"within the container. Use the ``--certificates`` flag when starting the " -"container." +"Assuming the certificate already exists locally, we can use the flag ``--" +"volume`` to mount the local certificate into the container's ``/app/`` " +"directory. This allows the ServerApp to access the certificate within the " +"container. Use the ``--certificates`` flag when starting the container." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:390 @@ -5193,8 +5142,8 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:395 msgid "" "If you want to use a different version of Flower, for example Flower " -"nightly, you can do so by changing the tag. All available versions are on" -" `Docker Hub `__." +"nightly, you can do so by changing the tag. All available versions are on " +"`Docker Hub `__." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:400 @@ -5205,9 +5154,9 @@ msgstr "" msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that " -"you always use the same image, you can specify the hash of the image " -"instead of the tag." +"change the functionality of Flower. However, if you want to ensure that you " +"always use the same image, you can specify the hash of the image instead of " +"the tag." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:407 @@ -5237,63 +5186,60 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:8 msgid "" "Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients " -"but without having to source, configure and mange a large number of " -"physical devices; you might want to run your FL workloads as fast as " -"possible on the compute systems you have access to without having to go " -"through a complex setup process; you might want to validate your " -"algorithm on different scenarios at varying levels of data and system " -"heterogeneity, client availability, privacy budgets, etc. These are among" -" some of the use-cases where simulating FL workloads makes sense. Flower " -"can accommodate these scenarios by means of its `VirtualClientEngine " -"`_ or " -"VCE." +"cases: you might want to run your workload on a large cohort of clients but " +"without having to source, configure and mange a large number of physical " +"devices; you might want to run your FL workloads as fast as possible on the " +"compute systems you have access to without having to go through a complex " +"setup process; you might want to validate your algorithm on different " +"scenarios at varying levels of data and system heterogeneity, client " +"availability, privacy budgets, etc. These are among some of the use-cases " +"where simulating FL workloads makes sense. Flower can accommodate these " +"scenarios by means of its `VirtualClientEngine `_ or VCE." msgstr "" #: ../../source/how-to-run-simulations.rst:10 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" -" clients. These clients are identical to `non-virtual` clients (i.e. the " -"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " -"creating a class inheriting, for example, from `flwr.client.NumPyClient " -"`_ and therefore behave in an " -"identical way. In addition to that, clients managed by the " -":code:`VirtualClientEngine` are:" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " +"clients. These clients are identical to `non-virtual` clients (i.e. the ones " +"you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by creating a " +"class inheriting, for example, from `flwr.client.NumPyClient `_ and therefore behave in an identical way. In " +"addition to that, clients managed by the :code:`VirtualClientEngine` are:" msgstr "" #: ../../source/how-to-run-simulations.rst:12 msgid "" -"resource-aware: this means that each client gets assigned a portion of " -"the compute and memory on your system. You as a user can control this at " -"the beginning of the simulation and allows you to control the degree of " +"resource-aware: this means that each client gets assigned a portion of the " +"compute and memory on your system. You as a user can control this at the " +"beginning of the simulation and allows you to control the degree of " "parallelism of your Flower FL simulation. The fewer the resources per " "client, the more clients can run concurrently on the same hardware." msgstr "" #: ../../source/how-to-run-simulations.rst:13 msgid "" -"self-managed: this means that you as a user do not need to launch clients" -" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"self-managed: this means that you as a user do not need to launch clients " +"manually, instead this gets delegated to :code:`VirtualClientEngine`'s " "internals." msgstr "" #: ../../source/how-to-run-simulations.rst:14 msgid "" -"ephemeral: this means that a client is only materialized when it is " -"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," -" releasing the resources it was assigned and allowing in this way other " -"clients to participate." +"ephemeral: this means that a client is only materialized when it is required " +"in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards, releasing the resources it was " +"assigned and allowing in this way other clients to participate." msgstr "" #: ../../source/how-to-run-simulations.rst:16 msgid "" "The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " "`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " -"of `Actors `_ to " -"spawn `virtual` clients and run their workload." +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use of " +"`Actors `_ to spawn " +"`virtual` clients and run their workload." msgstr "" #: ../../source/how-to-run-simulations.rst:20 @@ -5302,12 +5248,11 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:22 msgid "" -"Running Flower simulations still require you to define your client class," -" a strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your " -"simulation is done with `start_simulation `_ and a minimal example looks" -" as follows:" +"Running Flower simulations still require you to define your client class, a " +"strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your simulation " +"is done with `start_simulation `_ and a minimal example looks as follows:" msgstr "" #: ../../source/how-to-run-simulations.rst:44 @@ -5316,16 +5261,16 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:45 msgid "" -"By default the VCE has access to all system resources (i.e. all CPUs, all" -" GPUs, etc) since that is also the default behavior when starting Ray. " -"However, in some settings you might want to limit how many of your system" -" resources are used for simulation. You can do this via the " -":code:`ray_init_args` input argument to :code:`start_simulation` which " -"the VCE internally passes to Ray's :code:`ray.init` command. For a " -"complete list of settings you can configure check the `ray.init " -"`_" -" documentation. Do not set :code:`ray_init_args` if you want the VCE to " -"use all your system's CPUs and GPUs." +"By default the VCE has access to all system resources (i.e. all CPUs, all " +"GPUs, etc) since that is also the default behavior when starting Ray. " +"However, in some settings you might want to limit how many of your system " +"resources are used for simulation. You can do this via the :code:" +"`ray_init_args` input argument to :code:`start_simulation` which the VCE " +"internally passes to Ray's :code:`ray.init` command. For a complete list of " +"settings you can configure check the `ray.init `_ documentation. Do not set :" +"code:`ray_init_args` if you want the VCE to use all your system's CPUs and " +"GPUs." msgstr "" #: ../../source/how-to-run-simulations.rst:62 @@ -5334,20 +5279,19 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:63 msgid "" -"By default the :code:`VirtualClientEngine` assigns a single CPU core (and" -" nothing else) to each virtual client. This means that if your system has" -" 10 cores, that many virtual clients can be concurrently running." +"By default the :code:`VirtualClientEngine` assigns a single CPU core (and " +"nothing else) to each virtual client. This means that if your system has 10 " +"cores, that many virtual clients can be concurrently running." msgstr "" #: ../../source/how-to-run-simulations.rst:65 msgid "" -"More often than not, you would probably like to adjust the resources your" -" clients get assigned based on the complexity (i.e. compute and memory " -"footprint) of your FL workload. You can do so when starting your " -"simulation by setting the argument `client_resources` to " -"`start_simulation `_." -" Two keys are internally used by Ray to schedule and spawn workloads (in " -"our case Flower clients):" +"More often than not, you would probably like to adjust the resources your " +"clients get assigned based on the complexity (i.e. compute and memory " +"footprint) of your FL workload. You can do so when starting your simulation " +"by setting the argument `client_resources` to `start_simulation `_. Two keys are internally used " +"by Ray to schedule and spawn workloads (in our case Flower clients):" msgstr "" #: ../../source/how-to-run-simulations.rst:67 @@ -5368,21 +5312,21 @@ msgstr "" msgid "" "While the :code:`client_resources` can be used to control the degree of " "concurrency in your FL simulation, this does not stop you from running " -"dozens, hundreds or even thousands of clients in the same round and " -"having orders of magnitude more `dormant` (i.e. not participating in a " -"round) clients. Let's say you want to have 100 clients per round but your" -" system can only accommodate 8 clients concurrently. The " -":code:`VirtualClientEngine` will schedule 100 jobs to run (each " -"simulating a client sampled by the strategy) and then will execute them " -"in a resource-aware manner in batches of 8." +"dozens, hundreds or even thousands of clients in the same round and having " +"orders of magnitude more `dormant` (i.e. not participating in a round) " +"clients. Let's say you want to have 100 clients per round but your system " +"can only accommodate 8 clients concurrently. The :code:`VirtualClientEngine` " +"will schedule 100 jobs to run (each simulating a client sampled by the " +"strategy) and then will execute them in a resource-aware manner in batches " +"of 8." msgstr "" #: ../../source/how-to-run-simulations.rst:91 msgid "" "To understand all the intricate details on how resources are used to " -"schedule FL clients and how to define custom resources, please take a " -"look at the `Ray documentation `_." +"schedule FL clients and how to define custom resources, please take a look " +"at the `Ray documentation `_." msgstr "" #: ../../source/how-to-run-simulations.rst:94 @@ -5391,22 +5335,22 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:96 msgid "" -"A few ready-to-run complete examples for Flower simulation in " -"Tensorflow/Keras and PyTorch are provided in the `Flower repository " -"`_. You can run them on Google Colab too:" +"A few ready-to-run complete examples for Flower simulation in Tensorflow/" +"Keras and PyTorch are provided in the `Flower repository `_. You can run them on Google Colab too:" msgstr "" #: ../../source/how-to-run-simulations.rst:98 msgid "" -"`Tensorflow/Keras Simulation " -"`_: 100 clients collaboratively train a MLP model on MNIST." +"`Tensorflow/Keras Simulation `_: 100 clients collaboratively train a MLP " +"model on MNIST." msgstr "" #: ../../source/how-to-run-simulations.rst:99 msgid "" -"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " +"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " "MNIST." msgstr "" @@ -5416,9 +5360,9 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:106 msgid "" -"Flower's :code:`VirtualClientEngine` allows you to run FL simulations " -"across multiple compute nodes. Before starting your multi-node simulation" -" ensure that you:" +"Flower's :code:`VirtualClientEngine` allows you to run FL simulations across " +"multiple compute nodes. Before starting your multi-node simulation ensure " +"that you:" msgstr "" #: ../../source/how-to-run-simulations.rst:108 @@ -5431,29 +5375,29 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:110 msgid "" -"Have a copy of your dataset in all nodes (more about this in " -":ref:`simulation considerations `)" +"Have a copy of your dataset in all nodes (more about this in :ref:" +"`simulation considerations `)" msgstr "" #: ../../source/how-to-run-simulations.rst:111 msgid "" -"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation " -"`_ so the " -":code:`VirtualClientEngine` attaches to a running Ray instance." +"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation `_ so the :code:" +"`VirtualClientEngine` attaches to a running Ray instance." msgstr "" #: ../../source/how-to-run-simulations.rst:112 msgid "" -"Start Ray on you head node: on the terminal type :code:`ray start " -"--head`. This command will print a few lines, one of which indicates how " -"to attach other nodes to the head node." +"Start Ray on you head node: on the terminal type :code:`ray start --head`. " +"This command will print a few lines, one of which indicates how to attach " +"other nodes to the head node." msgstr "" #: ../../source/how-to-run-simulations.rst:113 msgid "" -"Attach other nodes to the head node: copy the command shown after " -"starting the head and execute it on terminal of a new node: for example " -":code:`ray start --address='192.168.1.132:6379'`" +"Attach other nodes to the head node: copy the command shown after starting " +"the head and execute it on terminal of a new node: for example :code:`ray " +"start --address='192.168.1.132:6379'`" msgstr "" #: ../../source/how-to-run-simulations.rst:115 @@ -5464,9 +5408,9 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:117 msgid "" -"Once your simulation is finished, if you'd like to dismantle your cluster" -" you simply need to run the command :code:`ray stop` in each node's " -"terminal (including the head node)." +"Once your simulation is finished, if you'd like to dismantle your cluster " +"you simply need to run the command :code:`ray stop` in each node's terminal " +"(including the head node)." msgstr "" #: ../../source/how-to-run-simulations.rst:120 @@ -5481,21 +5425,19 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:124 msgid "" -"User :code:`ray status` to check all nodes connected to your head node as" -" well as the total resources available to the " -":code:`VirtualClientEngine`." +"User :code:`ray status` to check all nodes connected to your head node as " +"well as the total resources available to the :code:`VirtualClientEngine`." msgstr "" #: ../../source/how-to-run-simulations.rst:126 msgid "" -"When attaching a new node to the head, all its resources (i.e. all CPUs, " -"all GPUs) will be visible by the head node. This means that the " -":code:`VirtualClientEngine` can schedule as many `virtual` clients as " -"that node can possible run. In some settings you might want to exclude " -"certain resources from the simulation. You can do this by appending " -"`--num-cpus=` and/or `--num-" -"gpus=` in any :code:`ray start` command (including " -"when starting the head)" +"When attaching a new node to the head, all its resources (i.e. all CPUs, all " +"GPUs) will be visible by the head node. This means that the :code:" +"`VirtualClientEngine` can schedule as many `virtual` clients as that node " +"can possible run. In some settings you might want to exclude certain " +"resources from the simulation. You can do this by appending `--num-" +"cpus=` and/or `--num-gpus=` in any :" +"code:`ray start` command (including when starting the head)" msgstr "" #: ../../source/how-to-run-simulations.rst:132 @@ -5504,19 +5446,19 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:135 msgid "" -"We are actively working on these fronts so to make it trivial to run any " -"FL workload with Flower simulation." +"We are actively working on these fronts so to make it trivial to run any FL " +"workload with Flower simulation." msgstr "" #: ../../source/how-to-run-simulations.rst:138 msgid "" -"The current VCE allows you to run Federated Learning workloads in " -"simulation mode whether you are prototyping simple scenarios on your " -"personal laptop or you want to train a complex FL pipeline across " -"multiple high-performance GPU nodes. While we add more capabilities to " -"the VCE, the points below highlight some of the considerations to keep in" -" mind when designing your FL pipeline with Flower. We also highlight a " -"couple of current limitations in our implementation." +"The current VCE allows you to run Federated Learning workloads in simulation " +"mode whether you are prototyping simple scenarios on your personal laptop or " +"you want to train a complex FL pipeline across multiple high-performance GPU " +"nodes. While we add more capabilities to the VCE, the points below highlight " +"some of the considerations to keep in mind when designing your FL pipeline " +"with Flower. We also highlight a couple of current limitations in our " +"implementation." msgstr "" #: ../../source/how-to-run-simulations.rst:141 @@ -5525,17 +5467,16 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:143 msgid "" -"The VCE assigns a share of GPU memory to a client that specifies the key " -":code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " +"The VCE assigns a share of GPU memory to a client that specifies the key :" +"code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " "internally by the VCE) is by default:" msgstr "" #: ../../source/how-to-run-simulations.rst:146 msgid "" -"not aware of the total VRAM available on the GPUs. This means that if you" -" set :code:`num_gpus=0.5` and you have two GPUs in your system with " -"different (e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients" -" concurrently." +"not aware of the total VRAM available on the GPUs. This means that if you " +"set :code:`num_gpus=0.5` and you have two GPUs in your system with different " +"(e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients concurrently." msgstr "" #: ../../source/how-to-run-simulations.rst:147 @@ -5554,17 +5495,16 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:150 msgid "" "If you want to run several independent Flower simulations on the same " -"machine you need to mask-out your GPUs with " -":code:`CUDA_VISIBLE_DEVICES=\"\"` when launching your " -"experiment." +"machine you need to mask-out your GPUs with :code:" +"`CUDA_VISIBLE_DEVICES=\"\"` when launching your experiment." msgstr "" #: ../../source/how-to-run-simulations.rst:153 msgid "" -"In addition, the GPU resource limits passed to :code:`client_resources` " -"are not `enforced` (i.e. they can be exceeded) which can result in the " -"situation of client using more VRAM than the ratio specified when " -"starting the simulation." +"In addition, the GPU resource limits passed to :code:`client_resources` are " +"not `enforced` (i.e. they can be exceeded) which can result in the situation " +"of client using more VRAM than the ratio specified when starting the " +"simulation." msgstr "" #: ../../source/how-to-run-simulations.rst:156 @@ -5573,31 +5513,29 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:158 msgid "" -"When `using a GPU with TensorFlow " -"`_ nearly your entire GPU memory of" -" all your GPUs visible to the process will be mapped. This is done by " -"TensorFlow for optimization purposes. However, in settings such as FL " -"simulations where we want to split the GPU into multiple `virtual` " -"clients, this is not a desirable mechanism. Luckily we can disable this " -"default behavior by `enabling memory growth " -"`_." +"When `using a GPU with TensorFlow `_ " +"nearly your entire GPU memory of all your GPUs visible to the process will " +"be mapped. This is done by TensorFlow for optimization purposes. However, in " +"settings such as FL simulations where we want to split the GPU into multiple " +"`virtual` clients, this is not a desirable mechanism. Luckily we can disable " +"this default behavior by `enabling memory growth `_." msgstr "" #: ../../source/how-to-run-simulations.rst:160 msgid "" -"This would need to be done in the main process (which is where the server" -" would run) and in each Actor created by the VCE. By means of " -":code:`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` " -"in order to specify a function to be executed upon actor initialization. " -"In this case, to enable GPU growth for TF workloads. It would look as " -"follows:" +"This would need to be done in the main process (which is where the server " +"would run) and in each Actor created by the VCE. By means of :code:" +"`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` in order " +"to specify a function to be executed upon actor initialization. In this " +"case, to enable GPU growth for TF workloads. It would look as follows:" msgstr "" #: ../../source/how-to-run-simulations.rst:179 msgid "" "This is precisely the mechanism used in `Tensorflow/Keras Simulation " -"`_ example." +"`_ " +"example." msgstr "" #: ../../source/how-to-run-simulations.rst:183 @@ -5606,26 +5544,25 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:185 msgid "" -"The VCE does not currently offer a way to control on which node a " -"particular `virtual` client is executed. In other words, if more than a " -"single node have the resources needed by a client to run, then any of " -"those nodes could get the client workload scheduled onto. Later in the FL" -" process (i.e. in a different round) the same client could be executed by" -" a different node. Depending on how your clients access their datasets, " -"this might require either having a copy of all dataset partitions on all " -"nodes or a dataset serving mechanism (e.g. using nfs, a database) to " -"circumvent data duplication." +"The VCE does not currently offer a way to control on which node a particular " +"`virtual` client is executed. In other words, if more than a single node " +"have the resources needed by a client to run, then any of those nodes could " +"get the client workload scheduled onto. Later in the FL process (i.e. in a " +"different round) the same client could be executed by a different node. " +"Depending on how your clients access their datasets, this might require " +"either having a copy of all dataset partitions on all nodes or a dataset " +"serving mechanism (e.g. using nfs, a database) to circumvent data " +"duplication." msgstr "" #: ../../source/how-to-run-simulations.rst:187 msgid "" -"By definition virtual clients are `stateless` due to their ephemeral " -"nature. A client state can be implemented as part of the Flower client " -"class but users need to ensure this saved to persistent storage (e.g. a " -"database, disk) and that can be retrieve later by the same client " -"regardless on which node it is running from. This is related to the point" -" above also since, in some way, the client's dataset could be seen as a " -"type of `state`." +"By definition virtual clients are `stateless` due to their ephemeral nature. " +"A client state can be implemented as part of the Flower client class but " +"users need to ensure this saved to persistent storage (e.g. a database, " +"disk) and that can be retrieve later by the same client regardless on which " +"node it is running from. This is related to the point above also since, in " +"some way, the client's dataset could be seen as a type of `state`." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:2 @@ -5634,9 +5571,9 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:4 msgid "" -"Flower does not automatically save model updates on the server-side. This" -" how-to guide describes the steps to save (and load) model checkpoints in" -" Flower." +"Flower does not automatically save model updates on the server-side. This " +"how-to guide describes the steps to save (and load) model checkpoints in " +"Flower." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:8 @@ -5645,16 +5582,15 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:10 msgid "" -"Model updates can be persisted on the server-side by customizing " -":code:`Strategy` methods. Implementing custom strategies is always an " -"option, but for many cases it may be more convenient to simply customize " -"an existing strategy. The following code example defines a new " -":code:`SaveModelStrategy` which customized the existing built-in " -":code:`FedAvg` strategy. In particular, it customizes " -":code:`aggregate_fit` by calling :code:`aggregate_fit` in the base class " -"(:code:`FedAvg`). It then continues to save returned (aggregated) weights" -" before it returns those aggregated weights to the caller (i.e., the " -"server):" +"Model updates can be persisted on the server-side by customizing :code:" +"`Strategy` methods. Implementing custom strategies is always an option, but " +"for many cases it may be more convenient to simply customize an existing " +"strategy. The following code example defines a new :code:`SaveModelStrategy` " +"which customized the existing built-in :code:`FedAvg` strategy. In " +"particular, it customizes :code:`aggregate_fit` by calling :code:" +"`aggregate_fit` in the base class (:code:`FedAvg`). It then continues to " +"save returned (aggregated) weights before it returns those aggregated " +"weights to the caller (i.e., the server):" msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:47 @@ -5663,25 +5599,25 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:49 msgid "" -"Similar to the previous example but with a few extra steps, we'll show " -"how to store a PyTorch checkpoint we'll use the ``torch.save`` function. " -"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be" -" transformed into a list of NumPy ``ndarray``'s, then those are " -"transformed into the PyTorch ``state_dict`` following the ``OrderedDict``" -" class structure." +"Similar to the previous example but with a few extra steps, we'll show how " +"to store a PyTorch checkpoint we'll use the ``torch.save`` function. " +"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be " +"transformed into a list of NumPy ``ndarray``'s, then those are transformed " +"into the PyTorch ``state_dict`` following the ``OrderedDict`` class " +"structure." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:85 msgid "" -"To load your progress, you simply append the following lines to your " -"code. Note that this will iterate over all saved checkpoints and load the" -" latest one:" +"To load your progress, you simply append the following lines to your code. " +"Note that this will iterate over all saved checkpoints and load the latest " +"one:" msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 msgid "" -"Return/use this object of type ``Parameters`` wherever necessary, such as" -" in the ``initial_parameters`` when defining a ``Strategy``." +"Return/use this object of type ``Parameters`` wherever necessary, such as in " +"the ``initial_parameters`` when defining a ``Strategy``." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:2 @@ -5690,10 +5626,10 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:4 msgid "" -"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable" -" foundation for future growth. Compared to Flower 0.19 (and other 0.x " -"series releases), there are a few breaking changes that make it necessary" -" to change the code of existing 0.x-series projects." +"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable " +"foundation for future growth. Compared to Flower 0.19 (and other 0.x series " +"releases), there are a few breaking changes that make it necessary to change " +"the code of existing 0.x-series projects." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 @@ -5703,8 +5639,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:10 msgid "" -"Here's how to update an existing installation to Flower 1.0 using either " -"pip or Poetry:" +"Here's how to update an existing installation to Flower 1.0 using either pip " +"or Poetry:" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:12 @@ -5731,13 +5667,14 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:19 -msgid "``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" +msgid "" +"``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:20 msgid "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when " -"using ``start_simulation``)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when using " +"``start_simulation``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 @@ -5768,8 +5705,7 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:34 msgid "" "Flower 1.0 (keyword arguments): " -"``start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())``" +"``start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:37 @@ -5807,9 +5743,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:48 msgid "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:50 @@ -5821,9 +5756,9 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:51 msgid "" "Remove ``force_final_distributed_eval`` parameter from calls to " -"``start_server``. Distributed evaluation on all clients can be enabled by" -" configuring the strategy to sample all clients for evaluation after the " -"last round of training." +"``start_server``. Distributed evaluation on all clients can be enabled by " +"configuring the strategy to sample all clients for evaluation after the last " +"round of training." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:52 @@ -5840,12 +5775,12 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:57 msgid "" -"Strategy initialization: if the strategy relies on the default values for" -" ``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " +"Strategy initialization: if the strategy relies on the default values for " +"``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " "``fraction_evaluate`` manually to ``0.1``. Projects that do not manually " "create a strategy (by calling ``start_server`` or ``start_simulation`` " -"without passing a strategy instance) should now manually initialize " -"FedAvg with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." +"without passing a strategy instance) should now manually initialize FedAvg " +"with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:58 @@ -5877,15 +5812,14 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:67 msgid "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " -"Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " +"Dict[str, Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:68 msgid "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " -"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " -"Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " +"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:71 @@ -5894,11 +5828,10 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:73 msgid "" -"The type of parameter ``failures`` has changed from " -"``List[BaseException]`` to ``List[Union[Tuple[ClientProxy, FitRes], " -"BaseException]]`` (in ``aggregate_fit``) and " -"``List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]]`` (in " -"``aggregate_evaluate``)" +"The type of parameter ``failures`` has changed from ``List[BaseException]`` " +"to ``List[Union[Tuple[ClientProxy, FitRes], BaseException]]`` (in " +"``aggregate_fit``) and ``List[Union[Tuple[ClientProxy, EvaluateRes], " +"BaseException]]`` (in ``aggregate_evaluate``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:74 @@ -5915,8 +5848,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:77 msgid "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " -"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" +"> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:80 @@ -5932,9 +5865,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:84 msgid "" "Remove \"placeholder\" methods from subclasses of ``Client`` or " -"``NumPyClient``. If you, for example, use server-side evaluation, then " -"empty placeholder implementations of ``evaluate`` are no longer " -"necessary." +"``NumPyClient``. If you, for example, use server-side evaluation, then empty " +"placeholder implementations of ``evaluate`` are no longer necessary." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:85 @@ -5951,11 +5883,11 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:91 msgid "" -"Most official `Flower code examples " -"`_ are already updated" -" to Flower 1.0, they can serve as a reference for using the Flower 1.0 " -"API. If there are further questions, `join the Flower Slack " -"`_ and use the channel ``#questions``." +"Most official `Flower code examples `_ are already updated to Flower 1.0, they can serve as a " +"reference for using the Flower 1.0 API. If there are further questions, " +"`join the Flower Slack `_ and use the channel " +"``#questions``." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:2 @@ -5964,19 +5896,17 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:4 msgid "" -"Welcome to the migration guide for updating Flower to Flower Next! " -"Whether you're a seasoned user or just getting started, this guide will " -"help you smoothly transition your existing setup to take advantage of the" -" latest features and improvements in Flower Next, starting from version " -"1.8." +"Welcome to the migration guide for updating Flower to Flower Next! Whether " +"you're a seasoned user or just getting started, this guide will help you " +"smoothly transition your existing setup to take advantage of the latest " +"features and improvements in Flower Next, starting from version 1.8." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:9 msgid "" "This guide shows how to reuse pre-``1.8`` Flower code with minimum code " -"changes by using the *compatibility layer* in Flower Next. In another " -"guide, we will show how to run Flower Next end-to-end with pure Flower " -"Next APIs." +"changes by using the *compatibility layer* in Flower Next. In another guide, " +"we will show how to run Flower Next end-to-end with pure Flower Next APIs." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:13 @@ -5985,8 +5915,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:48 msgid "" -"Here's how to update an existing installation of Flower to Flower Next " -"with ``pip``:" +"Here's how to update an existing installation of Flower to Flower Next with " +"``pip``:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:54 @@ -5995,8 +5925,7 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:61 msgid "" -"Ensure you set the following version constraint in your " -"``requirements.txt``" +"Ensure you set the following version constraint in your ``requirements.txt``" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:71 @@ -6016,21 +5945,19 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:86 msgid "" -"Ensure you set the following version constraint in your " -"``pyproject.toml``:" +"Ensure you set the following version constraint in your ``pyproject.toml``:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" "In Flower Next, the *infrastructure* and *application layers* have been " -"decoupled. Instead of starting a client in code via ``start_client()``, " -"you create a |clientapp_link|_ and start it via the command line. Instead" -" of starting a server in code via ``start_server()``, you create a " -"|serverapp_link|_ and start it via the command line. The long-running " +"decoupled. Instead of starting a client in code via ``start_client()``, you " +"create a |clientapp_link|_ and start it via the command line. Instead of " +"starting a server in code via ``start_server()``, you create a |" +"serverapp_link|_ and start it via the command line. The long-running " "components of server and client are called SuperLink and SuperNode. The " -"following non-breaking changes that require manual updates and allow you " -"to run your project both in the traditional way and in the Flower Next " -"way:" +"following non-breaking changes that require manual updates and allow you to " +"run your project both in the traditional way and in the Flower Next way:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:109 @@ -6039,8 +5966,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" -"Wrap your existing client with |clientapp_link|_ instead of launching it " -"via |startclient_link|_. Here's an example:" +"Wrap your existing client with |clientapp_link|_ instead of launching it via " +"|startclient_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:132 @@ -6049,8 +5976,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:133 msgid "" -"Wrap your existing strategy with |serverapp_link|_ instead of starting " -"the server via |startserver_link|_. Here's an example:" +"Wrap your existing strategy with |serverapp_link|_ instead of starting the " +"server via |startserver_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:154 @@ -6059,23 +5986,21 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:155 msgid "" -"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " -"in sequence, |flowernext_clientapp_link|_ (2x) and " -"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" -" `server.py` as Python scripts." +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, in " +"sequence, |flowernext_clientapp_link|_ (2x) and |flowernext_serverapp_link|" +"_. There is no need to execute `client.py` and `server.py` as Python scripts." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:158 msgid "" -"Here's an example to start the server without HTTPS (only for " -"prototyping):" +"Here's an example to start the server without HTTPS (only for prototyping):" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" "Here's another example to start with HTTPS. Use the ``--certificates`` " -"command line argument to pass paths to (CA certificate, server " -"certificate, and server private key)." +"command line argument to pass paths to (CA certificate, server certificate, " +"and server private key)." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:201 @@ -6084,24 +6009,24 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:202 msgid "" -"Wrap your existing client and strategy with |clientapp_link|_ and " -"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" -" anymore. Here's an example:" +"Wrap your existing client and strategy with |clientapp_link|_ and |" +"serverapp_link|_, respectively. There is no need to use |startsim_link|_ " +"anymore. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:232 msgid "" "Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " -"``client_app`` object in the code instead of executing the Python script." -" Here's an example (assuming the ``server_app`` and ``client_app`` " -"objects are in a ``sim.py`` module):" +"``client_app`` object in the code instead of executing the Python script. " +"Here's an example (assuming the ``server_app`` and ``client_app`` objects " +"are in a ``sim.py`` module):" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:249 msgid "" "Set default resources for each |clientapp_link|_ using the ``--backend-" -"config`` command line argument instead of setting the " -"``client_resources`` argument in |startsim_link|_. Here's an example:" +"config`` command line argument instead of setting the ``client_resources`` " +"argument in |startsim_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:275 @@ -6110,19 +6035,19 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:276 msgid "" -"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " -"an example:" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's an " +"example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:319 msgid "" -"Some official `Flower code examples `_ " -"are already updated to Flower Next so they can serve as a reference for " -"using the Flower Next API. If there are further questions, `join the " -"Flower Slack `_ and use the channel " -"``#questions``. You can also `participate in Flower Discuss " -"`_ where you can find us answering questions," -" or share and learn from others about migrating to Flower Next." +"Some official `Flower code examples `_ are " +"already updated to Flower Next so they can serve as a reference for using " +"the Flower Next API. If there are further questions, `join the Flower Slack " +"`_ and use the channel ``#questions``. You " +"can also `participate in Flower Discuss `_ where " +"you can find us answering questions, or share and learn from others about " +"migrating to Flower Next." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:325 @@ -6146,16 +6071,16 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:4 msgid "" -"**Note: This tutorial covers experimental features. The functionality and" -" interfaces may change in future versions.**" +"**Note: This tutorial covers experimental features. The functionality and " +"interfaces may change in future versions.**" msgstr "" #: ../../source/how-to-use-built-in-mods.rst:6 msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment " -"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " -"allow us to perform operations before and after a task is processed in " -"the ``ClientApp``." +"In this tutorial, we will learn how to utilize built-in mods to augment the " +"behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) allow us " +"to perform operations before and after a task is processed in the " +"``ClientApp``." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:9 @@ -6164,9 +6089,9 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:11 msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " -"or inspect the incoming ``Message`` and the resulting outgoing " -"``Message``. The signature for a ``Mod`` is as follows:" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate or " +"inspect the incoming ``Message`` and the resulting outgoing ``Message``. The " +"signature for a ``Mod`` is as follows:" msgstr "" #: ../../source/how-to-use-built-in-mods.rst:18 @@ -6243,16 +6168,16 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:82 msgid "" -"Each mod has a chance to inspect and modify the incoming ``Message`` " -"before passing it to the next mod, and likewise with the outgoing " -"``Message`` before returning it up the stack." +"Each mod has a chance to inspect and modify the incoming ``Message`` before " +"passing it to the next mod, and likewise with the outgoing ``Message`` " +"before returning it up the stack." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:87 msgid "" "By following this guide, you have learned how to effectively use mods to " -"enhance your ``ClientApp``'s functionality. Remember that the order of " -"mods is crucial and affects how the input and output are processed." +"enhance your ``ClientApp``'s functionality. Remember that the order of mods " +"is crucial and affects how the input and output are processed." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:89 @@ -6265,25 +6190,25 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:3 msgid "" -"This guide explains how you can utilize differential privacy in the " -"Flower framework. If you are not yet familiar with differential privacy, " -"you can refer to :doc:`explanation-differential-privacy`." +"This guide explains how you can utilize differential privacy in the Flower " +"framework. If you are not yet familiar with differential privacy, you can " +"refer to :doc:`explanation-differential-privacy`." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:7 msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " -"these features in a production environment with sensitive data, feel free" -" contact us to discuss your requirements and to receive guidance on how " -"to best use these features." +"these features in a production environment with sensitive data, feel free " +"contact us to discuss your requirements and to receive guidance on how to " +"best use these features." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:12 msgid "" -"This approach consists of two seprate phases: clipping of the updates and" -" adding noise to the aggregated model. For the clipping phase, Flower " -"framework has made it possible to decide whether to perform clipping on " -"the server side or the client side." +"This approach consists of two seprate phases: clipping of the updates and " +"adding noise to the aggregated model. For the clipping phase, Flower " +"framework has made it possible to decide whether to perform clipping on the " +"server side or the client side." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:15 @@ -6291,16 +6216,16 @@ msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " "communication overhead for clipping values. However, it also has the " -"disadvantage of increasing the computational load on the server due to " -"the need to perform the clipping operation for all clients." +"disadvantage of increasing the computational load on the server due to the " +"need to perform the clipping operation for all clients." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:16 msgid "" -"**Client-side Clipping**: This approach has the advantage of reducing the" -" computational overhead on the server. However, it also has the " -"disadvantage of lacking centralized control, as the server has less " -"control over the clipping process." +"**Client-side Clipping**: This approach has the advantage of reducing the " +"computational overhead on the server. However, it also has the disadvantage " +"of lacking centralized control, as the server has less control over the " +"clipping process." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:21 @@ -6311,10 +6236,10 @@ msgstr "" msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " -"(for example, :code:`FedAvg`). The two wrapper classes are " -":code:`DifferentialPrivacyServerSideFixedClipping` and " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " -"adaptive clipping." +"(for example, :code:`FedAvg`). The two wrapper classes are :code:" +"`DifferentialPrivacyServerSideFixedClipping` and :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and adaptive " +"clipping." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6323,11 +6248,10 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:31 msgid "" -"The code sample below enables the :code:`FedAvg` strategy to use server-" -"side fixed clipping using the " -":code:`DifferentialPrivacyServerSideFixedClipping` wrapper class. The " -"same approach can be used with " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " +"The code sample below enables the :code:`FedAvg` strategy to use server-side " +"fixed clipping using the :code:`DifferentialPrivacyServerSideFixedClipping` " +"wrapper class. The same approach can be used with :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" @@ -6338,12 +6262,12 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:53 msgid "" "For central DP with client-side clipping, the server sends the clipping " -"value to selected clients on each round. Clients can use existing Flower " -":code:`Mods` to perform the clipping. Two mods are available for fixed " -"and adaptive client-side clipping: :code:`fixedclipping_mod` and " -":code:`adaptiveclipping_mod` with corresponding server-side wrappers " -":code:`DifferentialPrivacyClientSideFixedClipping` and " -":code:`DifferentialPrivacyClientSideAdaptiveClipping`." +"value to selected clients on each round. Clients can use existing Flower :" +"code:`Mods` to perform the clipping. Two mods are available for fixed and " +"adaptive client-side clipping: :code:`fixedclipping_mod` and :code:" +"`adaptiveclipping_mod` with corresponding server-side wrappers :code:" +"`DifferentialPrivacyClientSideFixedClipping` and :code:" +"`DifferentialPrivacyClientSideAdaptiveClipping`." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6353,24 +6277,24 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:63 msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " -"differential privacy with client-side fixed clipping using both the " -":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " -"the client, :code:`fixedclipping_mod`:" +"differential privacy with client-side fixed clipping using both the :code:" +"`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on the " +"client, :code:`fixedclipping_mod`:" msgstr "" #: ../../source/how-to-use-differential-privacy.rst:80 msgid "" -"In addition to the server-side strategy wrapper, the :code:`ClientApp` " -"needs to configure the matching :code:`fixedclipping_mod` to perform the " -"client-side clipping:" +"In addition to the server-side strategy wrapper, the :code:`ClientApp` needs " +"to configure the matching :code:`fixedclipping_mod` to perform the client-" +"side clipping:" msgstr "" #: ../../source/how-to-use-differential-privacy.rst:97 msgid "" -"To utilize local differential privacy (DP) and add noise to the client " -"model parameters before transmitting them to the server in Flower, you " -"can use the `LocalDpMod`. The following hyperparameters need to be set: " -"clipping norm value, sensitivity, epsilon, and delta." +"To utilize local differential privacy (DP) and add noise to the client model " +"parameters before transmitting them to the server in Flower, you can use the " +"`LocalDpMod`. The following hyperparameters need to be set: clipping norm " +"value, sensitivity, epsilon, and delta." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6383,10 +6307,9 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:122 msgid "" -"Please note that the order of mods, especially those that modify " -"parameters, is important when using multiple modifiers. Typically, " -"differential privacy (DP) modifiers should be the last to operate on " -"parameters." +"Please note that the order of mods, especially those that modify parameters, " +"is important when using multiple modifiers. Typically, differential privacy " +"(DP) modifiers should be the last to operate on parameters." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:125 @@ -6395,13 +6318,12 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:126 msgid "" -"For ensuring data instance-level privacy during local model training on " -"the client side, consider leveraging privacy engines such as Opacus and " -"TensorFlow Privacy. For examples of using Flower with these engines, " -"please refer to the Flower examples directory (`Opacus " -"`_, `Tensorflow" -" Privacy `_)." +"For ensuring data instance-level privacy during local model training on the " +"client side, consider leveraging privacy engines such as Opacus and " +"TensorFlow Privacy. For examples of using Flower with these engines, please " +"refer to the Flower examples directory (`Opacus `_, `Tensorflow Privacy `_)." msgstr "" #: ../../source/how-to-use-strategies.rst:2 @@ -6410,15 +6332,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:4 msgid "" -"Flower allows full customization of the learning process through the " -":code:`Strategy` abstraction. A number of built-in strategies are " -"provided in the core framework." +"Flower allows full customization of the learning process through the :code:" +"`Strategy` abstraction. A number of built-in strategies are provided in the " +"core framework." msgstr "" #: ../../source/how-to-use-strategies.rst:6 msgid "" -"There are three ways to customize the way Flower orchestrates the " -"learning process on the server side:" +"There are three ways to customize the way Flower orchestrates the learning " +"process on the server side:" msgstr "" #: ../../source/how-to-use-strategies.rst:8 @@ -6441,15 +6363,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:16 msgid "" -"Flower comes with a number of popular federated learning strategies " -"built-in. A built-in strategy can be instantiated as follows:" +"Flower comes with a number of popular federated learning strategies built-" +"in. A built-in strategy can be instantiated as follows:" msgstr "" #: ../../source/how-to-use-strategies.rst:25 msgid "" -"This creates a strategy with all parameters left at their default values " -"and passes it to the :code:`start_server` function. It is usually " -"recommended to adjust a few parameters during instantiation:" +"This creates a strategy with all parameters left at their default values and " +"passes it to the :code:`start_server` function. It is usually recommended to " +"adjust a few parameters during instantiation:" msgstr "" #: ../../source/how-to-use-strategies.rst:42 @@ -6466,28 +6388,27 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:47 msgid "" "The server can pass new configuration values to the client each round by " -"providing a function to :code:`on_fit_config_fn`. The provided function " -"will be called by the strategy and must return a dictionary of " -"configuration key values pairs that will be sent to the client. It must " -"return a dictionary of arbitrary configuration values :code:`client.fit`" -" and :code:`client.evaluate` functions during each round of federated " -"learning." +"providing a function to :code:`on_fit_config_fn`. The provided function will " +"be called by the strategy and must return a dictionary of configuration key " +"values pairs that will be sent to the client. It must return a dictionary of " +"arbitrary configuration values :code:`client.fit` and :code:`client." +"evaluate` functions during each round of federated learning." msgstr "" #: ../../source/how-to-use-strategies.rst:75 msgid "" "The :code:`on_fit_config_fn` can be used to pass arbitrary configuration " "values from server to client, and poetentially change these values each " -"round, for example, to adjust the learning rate. The client will receive " -"the dictionary returned by the :code:`on_fit_config_fn` in its own " -":code:`client.fit()` function." +"round, for example, to adjust the learning rate. The client will receive the " +"dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client." +"fit()` function." msgstr "" #: ../../source/how-to-use-strategies.rst:78 msgid "" -"Similar to :code:`on_fit_config_fn`, there is also " -":code:`on_evaluate_config_fn` to customize the configuration sent to " -":code:`client.evaluate()`" +"Similar to :code:`on_fit_config_fn`, there is also :code:" +"`on_evaluate_config_fn` to customize the configuration sent to :code:`client." +"evaluate()`" msgstr "" #: ../../source/how-to-use-strategies.rst:81 @@ -6496,15 +6417,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:83 msgid "" -"Server-side evaluation can be enabled by passing an evaluation function " -"to :code:`evaluate_fn`." +"Server-side evaluation can be enabled by passing an evaluation function to :" +"code:`evaluate_fn`." msgstr "" #: ../../source/how-to-use-strategies.rst:89 msgid "" -"Writing a fully custom strategy is a bit more involved, but it provides " -"the most flexibility. Read the `Implementing Strategies `_ guide to learn more." +"Writing a fully custom strategy is a bit more involved, but it provides the " +"most flexibility. Read the `Implementing Strategies `_ guide to learn more." msgstr "" #: ../../source/index.rst:34 @@ -6590,8 +6511,8 @@ msgstr "" msgid "" "The user guide is targeted at researchers and developers who want to use " "Flower to bring existing machine learning workloads into a federated " -"setting. One of Flower's design goals was to make this simple. Read on to" -" learn more." +"setting. One of Flower's design goals was to make this simple. Read on to " +"learn more." msgstr "" #: ../../source/index.rst:30 @@ -6600,21 +6521,20 @@ msgstr "" #: ../../source/index.rst:32 msgid "" -"A learning-oriented series of federated learning tutorials, the best " -"place to start." +"A learning-oriented series of federated learning tutorials, the best place " +"to start." msgstr "" #: ../../source/index.rst:61 msgid "" -"QUICKSTART TUTORIALS: :doc:`PyTorch ` | " -":doc:`TensorFlow ` | :doc:`🤗 Transformers" -" ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " -"` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " -":doc:`Android ` | :doc:`iOS `" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" +"`TensorFlow ` | :doc:`🤗 Transformers " +"` | :doc:`JAX ` | :" +"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:" +"`XGBoost ` | :doc:`Android ` | :doc:`iOS `" msgstr "" #: ../../source/index.rst:63 @@ -6627,8 +6547,8 @@ msgstr "" #: ../../source/index.rst:76 msgid "" -"Problem-oriented how-to guides show step-by-step how to achieve a " -"specific goal." +"Problem-oriented how-to guides show step-by-step how to achieve a specific " +"goal." msgstr "" #: ../../source/index.rst:110 @@ -6659,8 +6579,8 @@ msgstr "" #: ../../source/index.rst:150 msgid "" -"The Flower community welcomes contributions. The following docs are " -"intended to help along the way." +"The Flower community welcomes contributions. The following docs are intended " +"to help along the way." msgstr "" #: ../../source/ref-api-cli.rst:2 @@ -6767,8 +6687,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.rst:25::1 msgid "" -":py:obj:`start_numpy_client `\\ \\(\\*\\," -" server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\, " +"server\\_address\\, client\\)" msgstr "" #: ../../source/ref-api/flwr.client.rst:25::1 @@ -6795,8 +6715,7 @@ msgstr "" #: ../../source/ref-api/flwr.client.rst:34::1 msgid "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " -"mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" msgstr "" #: ../../source/ref-api/flwr.client.rst:34::1 @@ -6919,7 +6838,8 @@ msgid "Get the run context from this client." msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid ":py:obj:`get_parameters `\\ \\(ins\\)" +msgid "" +":py:obj:`get_parameters `\\ \\(ins\\)" msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 @@ -6930,7 +6850,8 @@ msgid "Return the current local model parameters." msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid ":py:obj:`get_properties `\\ \\(ins\\)" +msgid "" +":py:obj:`get_properties `\\ \\(ins\\)" msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 @@ -7044,9 +6965,9 @@ msgstr "" #: flwr.client.client.Client.evaluate:3 of msgid "" -"The evaluation instructions containing (global) model parameters received" -" from the server and a dictionary of configuration values used to " -"customize the local evaluation process." +"The evaluation instructions containing (global) model parameters received " +"from the server and a dictionary of configuration values used to customize " +"the local evaluation process." msgstr "" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit @@ -7113,15 +7034,15 @@ msgstr "" #: flwr.client.client.Client.fit:3 of msgid "" -"The training instructions containing (global) model parameters received " -"from the server and a dictionary of configuration values used to " -"customize the local training process." +"The training instructions containing (global) model parameters received from " +"the server and a dictionary of configuration values used to customize the " +"local training process." msgstr "" #: flwr.client.client.Client.fit:8 of msgid "" -"The training result containing updated parameters and other details such " -"as the number of local training examples used for training." +"The training result containing updated parameters and other details such as " +"the number of local training examples used for training." msgstr "" #: flwr.client.client.Client.get_parameters:3 of @@ -7190,15 +7111,15 @@ msgstr "" #: flwr.client.client_app.ClientApp:16 of msgid "" -"If the above code is in a Python module called `client`, it can be " -"started as follows:" +"If the above code is in a Python module called `client`, it can be started " +"as follows:" msgstr "" #: flwr.client.client_app.ClientApp:21 of msgid "" -"In this `client:app` example, `client` refers to the Python module " -"`client.py` in which the previous code lives in and `app` refers to the " -"global attribute `app` that points to an object of type `ClientApp`." +"In this `client:app` example, `client` refers to the Python module `client." +"py` in which the previous code lives in and `app` refers to the global " +"attribute `app` that points to an object of type `ClientApp`." msgstr "" #: flwr.client.client_app.ClientApp.evaluate:1::1 of @@ -7239,7 +7160,8 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 -msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgid "" +":py:obj:`fit `\\ \\(parameters\\, config\\)" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7270,8 +7192,7 @@ msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" -":py:obj:`set_context `\\ " -"\\(context\\)" +":py:obj:`set_context `\\ \\(context\\)" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7299,10 +7220,10 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:5 of msgid "" -"Configuration parameters which allow the server to influence evaluation " -"on the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to influence the number of examples " -"used for evaluation." +"Configuration parameters which allow the server to influence evaluation on " +"the client. It can be used to communicate arbitrary values from the server " +"to the client, for example, to influence the number of examples used for " +"evaluation." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of @@ -7310,14 +7231,13 @@ msgid "" "* **loss** (*float*) -- The evaluation loss of the model on the local " "dataset. * **num_examples** (*int*) -- The number of examples used for " "evaluation. * **metrics** (*Dict[str, Scalar]*) -- A dictionary mapping " -"arbitrary string keys to values of type bool, bytes, float, int, or " -"str. It can be used to communicate arbitrary values back to the server." +"arbitrary string keys to values of type bool, bytes, float, int, or str. " +"It can be used to communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" -"**loss** (*float*) -- The evaluation loss of the model on the local " -"dataset." +"**loss** (*float*) -- The evaluation loss of the model on the local dataset." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:12 of @@ -7327,33 +7247,32 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:13 #: flwr.client.numpy_client.NumPyClient.fit:13 of msgid "" -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can be " -"used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:19 of msgid "" -"The previous return type format (int, float, float) and the extended " -"format (int, float, float, Dict[str, Scalar]) have been deprecated and " -"removed since Flower 0.19." +"The previous return type format (int, float, float) and the extended format " +"(int, float, float, Dict[str, Scalar]) have been deprecated and removed " +"since Flower 0.19." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:5 of msgid "" -"Configuration parameters which allow the server to influence training on " -"the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to set the number of (local) training " -"epochs." +"Configuration parameters which allow the server to influence training on the " +"client. It can be used to communicate arbitrary values from the server to " +"the client, for example, to set the number of (local) training epochs." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "" "* **parameters** (*NDArrays*) -- The locally updated model parameters. * " "**num_examples** (*int*) -- The number of examples used for training. * " -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can " -"be used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:11 of @@ -7366,26 +7285,25 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.get_parameters:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which parameters are needed along with some Scalar " -"attributes." +"Configuration parameters requested by the server. This can be used to tell " +"the client which parameters are needed along with some Scalar attributes." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_parameters:8 of -msgid "**parameters** -- The local model parameters as a list of NumPy ndarrays." +msgid "" +"**parameters** -- The local model parameters as a list of NumPy ndarrays." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_properties:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which properties are needed along with some Scalar " -"attributes." +"Configuration parameters requested by the server. This can be used to tell " +"the client which properties are needed along with some Scalar attributes." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_properties:8 of msgid "" -"**properties** -- A dictionary mapping arbitrary string keys to values of" -" type bool, bytes, float, int, or str. It can be used to communicate " +"**properties** -- A dictionary mapping arbitrary string keys to values of " +"type bool, bytes, float, int, or str. It can be used to communicate " "arbitrary property values back to the server." msgstr "" @@ -7404,8 +7322,7 @@ msgstr "" #: flwr.client.app.start_client:3 flwr.client.app.start_numpy_client:9 of msgid "" "The IPv4 or IPv6 address of the server. If the Flower server runs on the " -"same machine on port 8080, then `server_address` would be " -"`\"[::]:8080\"`." +"same machine on port 8080, then `server_address` would be `\"[::]:8080\"`." msgstr "" #: flwr.client.app.start_client:7 of @@ -7414,52 +7331,52 @@ msgstr "" #: flwr.client.app.start_client:9 of msgid "" -"An implementation of the abstract base class `flwr.client.Client` " -"(default: None)" +"An implementation of the abstract base class `flwr.client.Client` (default: " +"None)" msgstr "" #: flwr.client.app.start_client:12 flwr.client.app.start_numpy_client:15 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" server. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower server needs to be started with the same value (see " -"`flwr.server.start_server`), otherwise it will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"server. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"server needs to be started with the same value (see `flwr.server." +"start_server`), otherwise it will not know about the increased limit and " +"block larger messages." msgstr "" #: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " -"provided, a secure connection using the certificates will be established " -"to an SSL-enabled Flower server." +"provided, a secure connection using the certificates will be established to " +"an SSL-enabled Flower server." msgstr "" #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of msgid "" -"Starts an insecure gRPC connection when True. Enables HTTPS connection " -"when False, using system certificates if `root_certificates` is None." +"Starts an insecure gRPC connection when True. Enables HTTPS connection when " +"False, using system certificates if `root_certificates` is None." msgstr "" #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" "Configure the transport layer. Allowed values: - 'grpc-bidi': gRPC, " -"bidirectional streaming - 'grpc-rere': gRPC, request-response " -"(experimental) - 'rest': HTTP (experimental)" +"bidirectional streaming - 'grpc-rere': gRPC, request-response (experimental) " +"- 'rest': HTTP (experimental)" msgstr "" #: flwr.client.app.start_client:31 of msgid "" "The maximum number of times the client will try to connect to the server " -"before giving up in case of a connection error. If set to None, there is " -"no limit to the number of tries." +"before giving up in case of a connection error. If set to None, there is no " +"limit to the number of tries." msgstr "" #: flwr.client.app.start_client:35 of msgid "" -"The maximum duration before the client stops trying to connect to the " -"server in case of connection error. If set to None, there is no limit to " -"the total time." +"The maximum duration before the client stops trying to connect to the server " +"in case of connection error. If set to None, there is no limit to the total " +"time." msgstr "" #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of @@ -7480,10 +7397,9 @@ msgstr "" #: flwr.client.app.start_numpy_client:5 of msgid "" -"This function is deprecated since 1.7.0. Use " -":code:`flwr.client.start_client` instead and first convert your " -":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " -":code:`to_client()` method." +"This function is deprecated since 1.7.0. Use :code:`flwr.client." +"start_client` instead and first convert your :code:`NumPyClient` to type :" +"code:`flwr.client.Client` by executing its :code:`to_client()` method." msgstr "" #: flwr.client.app.start_numpy_client:13 of @@ -7495,7 +7411,8 @@ msgid "common" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgid "" +":py:obj:`array_from_numpy `\\ \\(ndarray\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7504,7 +7421,8 @@ msgid "Create Array from NumPy ndarray." msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgid "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7546,7 +7464,8 @@ msgid "Log 'msg % args' with the integer severity 'level'." msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgid "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7590,8 +7509,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " -"data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7650,8 +7568,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, " -"config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7709,7 +7626,8 @@ msgid "A dataclass that stores information about an error that occurred." msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 -msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetParametersIns `\\ \\(config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7729,7 +7647,8 @@ msgid "Response when asked to return parameters." msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 -msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetPropertiesIns `\\ \\(config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7779,8 +7698,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Metadata `\\ \\(run\\_id\\, " -"message\\_id\\, src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " +"src\\_node\\_id\\, ...\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7805,8 +7724,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " -":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" +"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7883,21 +7802,21 @@ msgstr "" #: flwr.common.record.parametersrecord.Array:6 of msgid "" -"A string representing the data type of the serialised object (e.g. " -"`np.float32`)" +"A string representing the data type of the serialised object (e.g. `np." +"float32`)" msgstr "" #: flwr.common.record.parametersrecord.Array:8 of msgid "" -"A list representing the shape of the unserialized array-like object. This" -" is used to deserialize the data (depending on the serialization method) " -"or simply as a metadata field." +"A list representing the shape of the unserialized array-like object. This is " +"used to deserialize the data (depending on the serialization method) or " +"simply as a metadata field." msgstr "" #: flwr.common.record.parametersrecord.Array:12 of msgid "" -"A string indicating the type of serialisation mechanism used to generate " -"the bytes in `data` from an array-like or tensor-like object." +"A string indicating the type of serialisation mechanism used to generate the " +"bytes in `data` from an array-like or tensor-like object." msgstr "" #: flwr.common.record.parametersrecord.Array:15 of @@ -7943,14 +7862,12 @@ msgstr "" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_res " -"`\\" +":py:obj:`get_parameters_res `\\" msgstr "" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_properties_res " -"`\\" +":py:obj:`get_properties_res `\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:2 @@ -7967,14 +7884,14 @@ msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 @@ -7983,8 +7900,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED " -"`\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" msgstr "" #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:2 @@ -7993,12 +7910,12 @@ msgstr "" #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" -" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " -"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " -":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" -" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` | :py:class:" +"`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ [:py:class:`int`] | :" +"py:class:`~typing.List`\\ [:py:class:`float`] | :py:class:`~typing.List`\\ [:" +"py:class:`str`] | :py:class:`~typing.List`\\ [:py:class:`bytes`] | :py:class:" +"`~typing.List`\\ [:py:class:`bool`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -8044,7 +7961,8 @@ msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of -msgid "If key is not found, d is returned if given, otherwise KeyError is raised." +msgid "" +"If key is not found, d is returned if given, otherwise KeyError is raised." msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -8072,12 +7990,11 @@ msgstr "" #: flwr.common.context.Context:3 of msgid "" -"Holds records added by the entity in a given run and that will stay " -"local. This means that the data it holds will never leave the system it's" -" running from. This can be used as an intermediate storage or scratchpad " -"when executing mods. It can also be used as a memory to access at " -"different points during the lifecycle of this entity (e.g. across " -"multiple rounds)" +"Holds records added by the entity in a given run and that will stay local. " +"This means that the data it holds will never leave the system it's running " +"from. This can be used as an intermediate storage or scratchpad when " +"executing mods. It can also be used as a memory to access at different " +"points during the lifecycle of this entity (e.g. across multiple rounds)" msgstr "" #: ../../source/ref-api/flwr.common.Context.rst:28::1 @@ -8184,21 +8101,19 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`split `\\ \\(\\[sep\\, " -"maxsplit\\]\\)" +":py:obj:`split `\\ \\(\\[sep\\, maxsplit\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -"Return a list of the substrings in the string, using sep as the separator" -" string." +"Return a list of the substrings in the string, using sep as the separator " +"string." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rsplit `\\ \\(\\[sep\\, " -"maxsplit\\]\\)" +":py:obj:`rsplit `\\ \\(\\[sep\\, maxsplit\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8256,14 +8171,13 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the number of non-overlapping occurrences of substring sub in " -"string S[start:end]." +"Return the number of non-overlapping occurrences of substring sub in string " +"S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`expandtabs `\\ " -"\\(\\[tabsize\\]\\)" +":py:obj:`expandtabs `\\ \\(\\[tabsize\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8279,12 +8193,13 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the lowest index in S where substring sub is found, such that sub " -"is contained within S[start:end]." +"Return the lowest index in S where substring sub is found, such that sub is " +"contained within S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" +msgid "" +":py:obj:`partition `\\ \\(sep\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8300,8 +8215,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`ljust `\\ \\(width\\[\\, " -"fillchar\\]\\)" +":py:obj:`ljust `\\ \\(width\\[\\, fillchar\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8335,20 +8249,19 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the highest index in S where substring sub is found, such that sub" -" is contained within S[start:end]." +"Return the highest index in S where substring sub is found, such that sub is " +"contained within S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rindex `\\ \\(sub\\[\\, " -"start\\[\\, end\\]\\]\\)" +":py:obj:`rindex `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rjust `\\ \\(width\\[\\, " -"fillchar\\]\\)" +":py:obj:`rjust `\\ \\(width\\[\\, fillchar\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8366,7 +8279,8 @@ msgid "Return a copy of the string with trailing whitespace removed." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" +msgid "" +":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8386,7 +8300,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.strip:1 of -msgid "Return a copy of the string with leading and trailing whitespace removed." +msgid "" +"Return a copy of the string with leading and trailing whitespace removed." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8401,7 +8316,8 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" +msgid "" +":py:obj:`translate `\\ \\(table\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8420,8 +8336,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`startswith `\\ \\(prefix\\[\\," -" start\\[\\, end\\]\\]\\)" +":py:obj:`startswith `\\ \\(prefix\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8440,8 +8356,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removeprefix `\\ " -"\\(prefix\\, \\/\\)" +":py:obj:`removeprefix `\\ \\(prefix\\, " +"\\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8451,8 +8367,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removesuffix `\\ " -"\\(suffix\\, \\/\\)" +":py:obj:`removesuffix `\\ \\(suffix\\, " +"\\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8556,7 +8472,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isidentifier:1 of -msgid "Return True if the string is a valid Python identifier, False otherwise." +msgid "" +"Return True if the string is a valid Python identifier, False otherwise." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8575,8 +8492,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.zfill:1 of msgid "" -"Pad a numeric string with zeros on the left, to fill a field of the given" -" width." +"Pad a numeric string with zeros on the left, to fill a field of the given " +"width." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8586,7 +8503,8 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "Return a formatted version of S, using substitutions from args and kwargs." +msgid "" +"Return a formatted version of S, using substitutions from args and kwargs." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8611,67 +8529,65 @@ msgid ":py:obj:`PING `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_CLIENT_ENTER `\\" +msgid "" +":py:obj:`START_CLIENT_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_CLIENT_LEAVE `\\" +msgid "" +":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_SERVER_ENTER `\\" +msgid "" +":py:obj:`START_SERVER_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_SERVER_LEAVE `\\" +msgid "" +":py:obj:`START_SERVER_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_ENTER " -"`\\" +":py:obj:`RUN_DRIVER_API_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE " -"`\\" +":py:obj:`RUN_DRIVER_API_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_ENTER " -"`\\" +":py:obj:`RUN_FLEET_API_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_LEAVE " -"`\\" +":py:obj:`RUN_FLEET_API_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_ENTER " -"`\\" +":py:obj:`RUN_SUPERLINK_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE " -"`\\" +":py:obj:`RUN_SUPERLINK_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_ENTER " -"`\\" +":py:obj:`START_SIMULATION_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_LEAVE " -"`\\" +":py:obj:`START_SIMULATION_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of @@ -8683,47 +8599,43 @@ msgid ":py:obj:`DRIVER_DISCONNECT `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_DRIVER_ENTER `\\" +msgid "" +":py:obj:`START_DRIVER_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_DRIVER_LEAVE `\\" +msgid "" +":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER " -"`\\" +":py:obj:`RUN_CLIENT_APP_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE " -"`\\" +":py:obj:`RUN_CLIENT_APP_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_ENTER " -"`\\" +":py:obj:`RUN_SERVER_APP_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE " -"`\\" +":py:obj:`RUN_SERVER_APP_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_ENTER " -"`\\" +":py:obj:`RUN_SUPERNODE_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_LEAVE " -"`\\" +":py:obj:`RUN_SUPERNODE_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:3 of @@ -8734,14 +8646,15 @@ msgstr "" #: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 #: flwr.common.EventType.rjust:3 of -msgid "Padding is done using the specified fill character (default is a space)." +msgid "" +"Padding is done using the specified fill character (default is a space)." msgstr "" #: flwr.common.EventType.count:1 of msgid "" -"Return the number of non-overlapping occurrences of substring sub in " -"string S[start:end]. Optional arguments start and end are interpreted as" -" in slice notation." +"Return the number of non-overlapping occurrences of substring sub in string " +"S[start:end]. Optional arguments start and end are interpreted as in slice " +"notation." msgstr "" #: flwr.common.EventType.encode:3 of @@ -8760,17 +8673,16 @@ msgstr "" msgid "" "The error handling scheme to use for encoding errors. The default is " "'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " -"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " -"as any other name registered with codecs.register_error that can handle " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as " +"any other name registered with codecs.register_error that can handle " "UnicodeEncodeErrors." msgstr "" #: flwr.common.EventType.endswith:1 of msgid "" "Return True if S ends with the specified suffix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, " -"stop comparing S at that position. suffix can also be a tuple of strings " -"to try." +"optional start, test S beginning at that position. With optional end, stop " +"comparing S at that position. suffix can also be a tuple of strings to try." msgstr "" #: flwr.common.EventType.expandtabs:3 of @@ -8779,8 +8691,8 @@ msgstr "" #: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of msgid "" -"Return the lowest index in S where substring sub is found, such that sub " -"is contained within S[start:end]. Optional arguments start and end are " +"Return the lowest index in S where substring sub is found, such that sub is " +"contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" @@ -8790,8 +8702,8 @@ msgstr "" #: flwr.common.EventType.format:1 of msgid "" -"Return a formatted version of S, using substitutions from args and " -"kwargs. The substitutions are identified by braces ('{' and '}')." +"Return a formatted version of S, using substitutions from args and kwargs. " +"The substitutions are identified by braces ('{' and '}')." msgstr "" #: flwr.common.EventType.format_map:1 of @@ -8806,80 +8718,80 @@ msgstr "" #: flwr.common.EventType.isalnum:3 of msgid "" -"A string is alpha-numeric if all characters in the string are alpha-" -"numeric and there is at least one character in the string." +"A string is alpha-numeric if all characters in the string are alpha-numeric " +"and there is at least one character in the string." msgstr "" #: flwr.common.EventType.isalpha:3 of msgid "" -"A string is alphabetic if all characters in the string are alphabetic and" -" there is at least one character in the string." +"A string is alphabetic if all characters in the string are alphabetic and " +"there is at least one character in the string." msgstr "" #: flwr.common.EventType.isascii:3 of msgid "" -"ASCII characters have code points in the range U+0000-U+007F. Empty " -"string is ASCII too." +"ASCII characters have code points in the range U+0000-U+007F. Empty string " +"is ASCII too." msgstr "" #: flwr.common.EventType.isdecimal:3 of msgid "" -"A string is a decimal string if all characters in the string are decimal " -"and there is at least one character in the string." +"A string is a decimal string if all characters in the string are decimal and " +"there is at least one character in the string." msgstr "" #: flwr.common.EventType.isdigit:3 of msgid "" -"A string is a digit string if all characters in the string are digits and" -" there is at least one character in the string." +"A string is a digit string if all characters in the string are digits and " +"there is at least one character in the string." msgstr "" #: flwr.common.EventType.isidentifier:3 of msgid "" -"Call keyword.iskeyword(s) to test whether string s is a reserved " -"identifier, such as \"def\" or \"class\"." +"Call keyword.iskeyword(s) to test whether string s is a reserved identifier, " +"such as \"def\" or \"class\"." msgstr "" #: flwr.common.EventType.islower:3 of msgid "" -"A string is lowercase if all cased characters in the string are lowercase" -" and there is at least one cased character in the string." +"A string is lowercase if all cased characters in the string are lowercase " +"and there is at least one cased character in the string." msgstr "" #: flwr.common.EventType.isnumeric:3 of msgid "" -"A string is numeric if all characters in the string are numeric and there" -" is at least one character in the string." +"A string is numeric if all characters in the string are numeric and there is " +"at least one character in the string." msgstr "" #: flwr.common.EventType.isprintable:3 of msgid "" -"A string is printable if all of its characters are considered printable " -"in repr() or if it is empty." +"A string is printable if all of its characters are considered printable in " +"repr() or if it is empty." msgstr "" #: flwr.common.EventType.isspace:3 of msgid "" -"A string is whitespace if all characters in the string are whitespace and" -" there is at least one character in the string." +"A string is whitespace if all characters in the string are whitespace and " +"there is at least one character in the string." msgstr "" #: flwr.common.EventType.istitle:3 of msgid "" -"In a title-cased string, upper- and title-case characters may only follow" -" uncased characters and lowercase characters only cased ones." +"In a title-cased string, upper- and title-case characters may only follow " +"uncased characters and lowercase characters only cased ones." msgstr "" #: flwr.common.EventType.isupper:3 of msgid "" -"A string is uppercase if all cased characters in the string are uppercase" -" and there is at least one cased character in the string." +"A string is uppercase if all cased characters in the string are uppercase " +"and there is at least one cased character in the string." msgstr "" #: flwr.common.EventType.join:3 of msgid "" -"The string whose method is called is inserted in between each given " -"string. The result is returned as a new string." +"The string whose method is called is inserted in between each given string. " +"The result is returned as a new string." msgstr "" #: flwr.common.EventType.join:6 of @@ -8897,9 +8809,9 @@ msgid "" "ordinals (integers) or characters to Unicode ordinals, strings or None. " "Character keys will be then converted to ordinals. If there are two " "arguments, they must be strings of equal length, and in the resulting " -"dictionary, each character in x will be mapped to the character at the " -"same position in y. If there is a third argument, it must be a string, " -"whose characters will be mapped to None in the result." +"dictionary, each character in x will be mapped to the character at the same " +"position in y. If there is a third argument, it must be a string, whose " +"characters will be mapped to None in the result." msgstr "" #: flwr.common.EventType.partition:3 of @@ -8917,8 +8829,8 @@ msgstr "" #: flwr.common.EventType.removeprefix:3 of msgid "" -"If the string starts with the prefix string, return string[len(prefix):]." -" Otherwise, return a copy of the original string." +"If the string starts with the prefix string, return string[len(prefix):]. " +"Otherwise, return a copy of the original string." msgstr "" #: flwr.common.EventType.removesuffix:3 of @@ -8940,22 +8852,22 @@ msgstr "" #: flwr.common.EventType.replace:7 of msgid "" -"If the optional argument count is given, only the first count occurrences" -" are replaced." +"If the optional argument count is given, only the first count occurrences " +"are replaced." msgstr "" #: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of msgid "" -"Return the highest index in S where substring sub is found, such that sub" -" is contained within S[start:end]. Optional arguments start and end are " +"Return the highest index in S where substring sub is found, such that sub is " +"contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" #: flwr.common.EventType.rpartition:3 of msgid "" -"This will search for the separator in the string, starting at the end. If" -" the separator is found, returns a 3-tuple containing the part before the" -" separator, the separator itself, and the part after it." +"This will search for the separator in the string, starting at the end. If " +"the separator is found, returns a 3-tuple containing the part before the " +"separator, the separator itself, and the part after it." msgstr "" #: flwr.common.EventType.rpartition:7 of @@ -8974,9 +8886,9 @@ msgstr "" #: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of msgid "" -"When set to None (the default value), will split on any whitespace " -"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" -" empty strings from the result." +"When set to None (the default value), will split on any whitespace character " +"(including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard empty " +"strings from the result." msgstr "" #: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of @@ -8985,8 +8897,8 @@ msgstr "" #: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of msgid "" -"Maximum number of splits (starting from the left). -1 (the default value)" -" means no limit." +"Maximum number of splits (starting from the left). -1 (the default value) " +"means no limit." msgstr "" #: flwr.common.EventType.rsplit:13 of @@ -8996,28 +8908,27 @@ msgstr "" #: flwr.common.EventType.split:13 of msgid "" "Note, str.split() is mainly useful for data that has been intentionally " -"delimited. With natural text that includes punctuation, consider using " -"the regular expression module." +"delimited. With natural text that includes punctuation, consider using the " +"regular expression module." msgstr "" #: flwr.common.EventType.splitlines:3 of msgid "" -"Line breaks are not included in the resulting list unless keepends is " -"given and true." +"Line breaks are not included in the resulting list unless keepends is given " +"and true." msgstr "" #: flwr.common.EventType.startswith:1 of msgid "" "Return True if S starts with the specified prefix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, " -"stop comparing S at that position. prefix can also be a tuple of strings " -"to try." +"optional start, test S beginning at that position. With optional end, stop " +"comparing S at that position. prefix can also be a tuple of strings to try." msgstr "" #: flwr.common.EventType.title:3 of msgid "" -"More specifically, words start with uppercased characters and all " -"remaining cased characters have lower case." +"More specifically, words start with uppercased characters and all remaining " +"cased characters have lower case." msgstr "" #: flwr.common.EventType.translate:5 of @@ -9026,15 +8937,15 @@ msgstr "" #: flwr.common.EventType.translate:4 of msgid "" -"Translation table, which must be a mapping of Unicode ordinals to Unicode" -" ordinals, strings, or None." +"Translation table, which must be a mapping of Unicode ordinals to Unicode " +"ordinals, strings, or None." msgstr "" #: flwr.common.EventType.translate:7 of msgid "" "The table must implement lookup/indexing via __getitem__, for instance a " -"dictionary or list. If this operation raises LookupError, the character " -"is left untouched. Characters mapped to None are deleted." +"dictionary or list. If this operation raises LookupError, the character is " +"left untouched. Characters mapped to None are deleted." msgstr "" #: flwr.common.EventType.zfill:3 of @@ -9124,14 +9035,14 @@ msgstr "" #: flwr.common.message.Message:5 of msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side" -" logic to a client, or vice-versa) or that will be sent to it." +"Holds records either sent by another entity (e.g. sent by the server-side " +"logic to a client, or vice-versa) or that will be sent to it." msgstr "" #: flwr.common.message.Message:8 of msgid "" -"A dataclass that captures information about an error that took place when" -" processing another message." +"A dataclass that captures information about an error that took place when " +"processing another message." msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 @@ -9147,8 +9058,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -":py:obj:`create_reply `\\ " -"\\(content\\[\\, ttl\\]\\)" +":py:obj:`create_reply `\\ \\(content\\[\\, " +"ttl\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 @@ -9202,18 +9113,18 @@ msgstr "" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based " -"on the remaining time for the received message before it expires. This " -"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " -"msg.meta.created_at)" +"Time-to-live for this message in seconds. If unset, it will be set based on " +"the remaining time for the received message before it expires. This follows " +"the equation: ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta." +"created_at)" msgstr "" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based " -"on the remaining time for the received message before it expires. This " -"follows the equation:" +"Time-to-live for this message in seconds. If unset, it will be set based on " +"the remaining time for the received message before it expires. This follows " +"the equation:" msgstr "" #: flwr.common.message.Message.create_error_reply:9 @@ -9223,9 +9134,9 @@ msgstr "" #: flwr.common.message.Message.create_reply:3 of msgid "" -"The method generates a new `Message` as a reply to this message. It " -"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " -"this message and sets 'reply_to_message' to the ID of this message." +"The method generates a new `Message` as a reply to this message. It inherits " +"'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from this message " +"and sets 'reply_to_message' to the ID of this message." msgstr "" #: flwr.common.message.Message.create_reply:7 of @@ -9257,11 +9168,13 @@ msgid "MessageTypeLegacy" msgstr "" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PARAMETERS `\\" +msgid "" +":py:obj:`GET_PARAMETERS `\\" msgstr "" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PROPERTIES `\\" +msgid "" +":py:obj:`GET_PROPERTIES `\\" msgstr "" #: flwr.common.Metadata.created_at:1::1 @@ -9291,8 +9204,8 @@ msgstr "" #: flwr.common.message.Metadata:13 of msgid "" -"An identifier for grouping messages. In some settings, this is used as " -"the FL round." +"An identifier for grouping messages. In some settings, this is used as the " +"FL round." msgstr "" #: flwr.common.message.Metadata:16 of @@ -9306,9 +9219,9 @@ msgstr "" #: flwr.common.message.Metadata:21 of msgid "" -"An identifier that can be used when loading a particular data partition " -"for a ClientApp. Making use of this identifier is more relevant when " -"conducting simulations." +"An identifier that can be used when loading a particular data partition for " +"a ClientApp. Making use of this identifier is more relevant when conducting " +"simulations." msgstr "" #: flwr.common.Metadata.created_at:1::1 of @@ -9377,10 +9290,9 @@ msgstr "" #: flwr.common.record.metricsrecord.MetricsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " -":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" -" [:py:class:`float`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`int` | :py:class:`float` | :py:class:`~typing.List`\\ [:py:" +"class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9435,16 +9347,15 @@ msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord:3 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds " -"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " -"viewed as an equivalent to PyTorch's state_dict, but holding serialised " -"tensors instead." +"A dataclass storing named Arrays in order. This means that it holds entries " +"as an OrderedDict[str, Array]. ParametersRecord objects can be viewed as an " +"equivalent to PyTorch's state_dict, but holding serialised tensors instead." msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9452,7 +9363,8 @@ msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +msgid "" +":py:obj:`count_bytes `\\ \\(\\)" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9483,9 +9395,9 @@ msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of msgid "" -"Note that a small amount of Bytes might also be included in this counting" -" that correspond to metadata of the serialized object (e.g. of NumPy " -"array) needed for deseralization." +"Note that a small amount of Bytes might also be included in this counting " +"that correspond to metadata of the serialized object (e.g. of NumPy array) " +"needed for deseralization." msgstr "" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 @@ -9519,7 +9431,8 @@ msgid "Dictionary holding MetricsRecord instances." msgstr "" #: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`parameters_records `\\" +msgid "" +":py:obj:`parameters_records `\\" msgstr "" #: flwr.common.RecordSet.configs_records:1::1 @@ -9541,14 +9454,12 @@ msgstr "" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_ins " -"`\\" +":py:obj:`get_parameters_ins `\\" msgstr "" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_properties_ins " -"`\\" +":py:obj:`get_properties_ins `\\" msgstr "" #: ../../source/ref-api/flwr.common.Status.rst:2 @@ -9585,8 +9496,8 @@ msgstr "" #: logging.Logger.log:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a " -"true value, e.g." +"To pass exception information, use the keyword argument exc_info with a true " +"value, e.g." msgstr "" #: logging.Logger.log:6 of @@ -9718,8 +9629,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.rst:40::1 msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," -" round\\_timeout\\]\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\, " +"round\\_timeout\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.rst:40::1 @@ -9728,7 +9639,8 @@ msgid "Flower server config." msgstr "" #: ../../source/ref-api/flwr.server.rst:40::1 -msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +msgid "" +":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" #: ../../source/ref-api/flwr.server.rst:40::1 @@ -9770,7 +9682,8 @@ msgid "Return all available clients." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`num_available `\\ \\(\\)" +msgid "" +":py:obj:`num_available `\\ \\(\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9793,8 +9706,8 @@ msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`sample `\\ \\(num\\_clients\\[\\, " +"min\\_num\\_clients\\, criterion\\]\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9805,7 +9718,8 @@ msgid "Sample a number of Flower ClientProxy instances." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`unregister `\\ \\(client\\)" +msgid "" +":py:obj:`unregister `\\ \\(client\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9837,8 +9751,7 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.register:6 of msgid "" "**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any " -"reason." +"ClientProxy is already registered or can not be registered for any reason." msgstr "" #: flwr.server.client_manager.ClientManager.unregister:3 @@ -9852,8 +9765,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`create_message `\\ " -"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" +":py:obj:`create_message `\\ \\(content\\, " +"message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1 @@ -9883,8 +9796,7 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`push_messages `\\ " -"\\(messages\\)" +":py:obj:`push_messages `\\ \\(messages\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 @@ -9905,20 +9817,20 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:3 of msgid "" -"This method constructs a new `Message` with given content and metadata. " -"The `run_id` and `src_node_id` will be set automatically." +"This method constructs a new `Message` with given content and metadata. The " +"`run_id` and `src_node_id` will be set automatically." msgstr "" #: flwr.server.driver.driver.Driver.create_message:6 of msgid "" -"The content for the new message. This holds records that are to be sent " -"to the destination node." +"The content for the new message. This holds records that are to be sent to " +"the destination node." msgstr "" #: flwr.server.driver.driver.Driver.create_message:9 of msgid "" -"The type of the message, defining the action to be executed on the " -"receiving end." +"The type of the message, defining the action to be executed on the receiving " +"end." msgstr "" #: flwr.server.driver.driver.Driver.create_message:12 of @@ -9927,17 +9839,16 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:14 of msgid "" -"The ID of the group to which this message is associated. In some " -"settings, this is used as the FL round." +"The ID of the group to which this message is associated. In some settings, " +"this is used as the FL round." msgstr "" #: flwr.server.driver.driver.Driver.create_message:17 of msgid "" -"Time-to-live for the round trip of this message, i.e., the time from " -"sending this message to receiving a reply. It specifies in seconds the " -"duration for which the message and its potential reply are considered " -"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " -"used." +"Time-to-live for the round trip of this message, i.e., the time from sending " +"this message to receiving a reply. It specifies in seconds the duration for " +"which the message and its potential reply are considered valid. If unset, " +"the default TTL (i.e., `common.DEFAULT_TTL`) will be used." msgstr "" #: flwr.server.driver.driver.Driver.create_message:23 of @@ -9948,12 +9859,13 @@ msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:3 of msgid "" -"This method is used to collect messages from the SuperLink that " -"correspond to a set of given message IDs." +"This method is used to collect messages from the SuperLink that correspond " +"to a set of given message IDs." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:6 of -msgid "An iterable of message IDs for which reply messages are to be retrieved." +msgid "" +"An iterable of message IDs for which reply messages are to be retrieved." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:9 of @@ -9962,8 +9874,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:3 of msgid "" -"This method takes an iterable of messages and sends each message to the " -"node specified in `dst_node_id`." +"This method takes an iterable of messages and sends each message to the node " +"specified in `dst_node_id`." msgstr "" #: flwr.server.driver.driver.Driver.push_messages:6 @@ -9973,26 +9885,27 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:9 of msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, " -"which can be used to pull replies." +"**message_ids** -- An iterable of IDs for the messages that were sent, which " +"can be used to pull replies." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:3 of msgid "" -"This method sends a list of messages to their destination node IDs and " -"then waits for the replies. It continues to pull replies until either all" -" replies are received or the specified timeout duration is exceeded." +"This method sends a list of messages to their destination node IDs and then " +"waits for the replies. It continues to pull replies until either all replies " +"are received or the specified timeout duration is exceeded." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:9 of msgid "" "The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the " -"method will wait until replies for all messages are received." +"replies for this duration. If `None`, there is no time limit and the method " +"will wait until replies for all messages are received." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:14 of -msgid "**replies** -- An iterable of reply messages received from the SuperLink." +msgid "" +"**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:18 @@ -10004,10 +9917,10 @@ msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:19 of msgid "" -"This method uses `push_messages` to send the messages and `pull_messages`" -" to collect the replies. If `timeout` is set, the method may not return " -"replies for all sent messages. A message remains valid until its TTL, " -"which is not affected by `timeout`." +"This method uses `push_messages` to send the messages and `pull_messages` to " +"collect the replies. If `timeout` is set, the method may not return replies " +"for all sent messages. A message remains valid until its TTL, which is not " +"affected by `timeout`." msgstr "" #: ../../source/ref-api/flwr.server.History.rst:2 @@ -10016,9 +9929,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_centralized " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_centralized `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1 @@ -10028,9 +9940,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_distributed " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_distributed `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10040,9 +9951,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_centralized " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10052,9 +9962,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10064,9 +9973,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed_fit " -"`\\ \\(server\\_round\\," -" ...\\)" +":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10117,8 +10025,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`disconnect_all_clients " -"`\\ \\(timeout\\)" +":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10148,8 +10056,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\," -" timeout\\)" +":py:obj:`fit_round `\\ \\(server\\_round\\, " +"timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10169,7 +10077,8 @@ msgid "Set the max_workers used by ThreadPoolExecutor." msgstr "" #: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +msgid "" +":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10204,8 +10113,8 @@ msgstr "" #: flwr.server.server_config.ServerConfig:3 of msgid "" -"All attributes have default values which allows users to configure just " -"the ones they care about." +"All attributes have default values which allows users to configure just the " +"ones they care about." msgstr "" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 @@ -10230,14 +10139,13 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`num_available `\\" -" \\(\\)" +":py:obj:`num_available `\\ " +"\\(\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`register `\\ " -"\\(client\\)" +":py:obj:`register `\\ \\(client\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of @@ -10260,8 +10168,8 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:3 of msgid "" -"Blocks until the requested number of clients is available or until a " -"timeout is reached. Current timeout default: 1 day." +"Blocks until the requested number of clients is available or until a timeout " +"is reached. Current timeout default: 1 day." msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:6 of @@ -10302,8 +10210,8 @@ msgstr "" #: flwr.server.app.start_server:5 of msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_server` will create one." +"A server implementation, either `flwr.server.Server` or a subclass thereof. " +"If no instance is provided, then `start_server` will create one." msgstr "" #: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of @@ -10314,41 +10222,41 @@ msgstr "" #: flwr.server.app.start_server:12 of msgid "" -"An implementation of the abstract base class " -"`flwr.server.strategy.Strategy`. If no strategy is provided, then " -"`start_server` will use `flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.strategy." +"Strategy`. If no strategy is provided, then `start_server` will use `flwr." +"server.strategy.FedAvg`." msgstr "" #: flwr.server.app.start_server:16 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_server` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_server` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" #: flwr.server.app.start_server:21 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" clients. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower clients need to be started with the same value (see " -"`flwr.client.start_client`), otherwise clients will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"clients. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"clients need to be started with the same value (see `flwr.client." +"start_client`), otherwise clients will not know about the increased limit " +"and block larger messages." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order: * CA certificate. * " -"server certificate. * server private key." +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order: * CA certificate. * server " +"certificate. * server private key." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order:" +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order:" msgstr "" #: flwr.server.app.start_server:32 of @@ -10381,8 +10289,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10414,9 +10322,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10427,9 +10334,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10440,9 +10346,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10453,9 +10358,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10500,8 +10404,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedAvgAndroid `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10550,8 +10454,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedTrimmedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10605,9 +10509,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FaultTolerantFedAvg " -"`\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10617,8 +10520,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10628,8 +10531,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " -"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " +"qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10797,8 +10700,8 @@ msgstr "" #: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of " -"the Bulyan (e.g., Krum)" +"Byzantine resilient aggregation rule that is used as the first step of the " +"Bulyan (e.g., Krum)" msgstr "" #: flwr.server.strategy.bulyan.Bulyan:29 of @@ -10807,9 +10710,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 @@ -10836,9 +10738,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -10917,9 +10818,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10936,9 +10836,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10955,8 +10854,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10987,9 +10886,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 @@ -11009,9 +10907,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 @@ -11023,9 +10920,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11036,9 +10932,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11058,15 +10953,15 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "Evaluate model parameters using an evaluation function from the strategy." +msgid "" +"Evaluate model parameters using an evaluation function from the strategy." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -11105,9 +11000,9 @@ msgstr "" msgid "" "**evaluate_configuration** -- A list of tuples. Each tuple in the list " "identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated evaluation." +"`ClientProxy`. If a particular `ClientProxy` is not included in this list, " +"it means that this `ClientProxy` will not participate in the next round of " +"federated evaluation." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 @@ -11127,16 +11022,14 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -11148,24 +11041,21 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -"Configure the next round of training incorporating Differential Privacy " -"(DP)." +"Configure the next round of training incorporating Differential Privacy (DP)." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11178,25 +11068,23 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -"Configuration of the next training round includes information related to " -"DP, such as clip norm and noise stddev." +"Configuration of the next training round includes information related to DP, " +"such as clip norm and noise stddev." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 #: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `FitIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated learning." +"**fit_configuration** -- A list of tuples. Each tuple in the list identifies " +"a `ClientProxy` and the `FitIns` for this particular `ClientProxy`. If a " +"particular `ClientProxy` is not included in this list, it means that this " +"`ClientProxy` will not participate in the next round of federated learning." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 @@ -11213,9 +11101,8 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " -"happen on the client-side, usually by using the built-in " -"`adaptiveclipping_mod`." +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `adaptiveclipping_mod`." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 @@ -11251,22 +11138,23 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of -msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." +msgid "" +"The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 #: of msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. " -"Andrew et al. recommends to set to 0.2." +"The learning rate for the clipping norm adaptation. Defaults to 0.2. Andrew " +"et al. recommends to set to 0.2." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of msgid "" -"The stddev of the noise added to the count of updates currently below the" -" estimate. Andrew et al. recommends to set to `expected_num_records/20`" +"The stddev of the noise added to the count of updates currently below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 @@ -11280,8 +11168,8 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 #: of msgid "" -"Wrap the strategy with the " -"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" +"Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` " +"wrapper:" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 @@ -11292,17 +11180,17 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -11316,33 +11204,33 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 @@ -11359,16 +11247,16 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `fixedclipping_mod`." +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen on " +"the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A " -"value of 1.0 or higher is recommended for strong privacy." +"The noise multiplier for the Gaussian mechanism for model updates. A value " +"of 1.0 or higher is recommended for strong privacy." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 @@ -11392,17 +11280,17 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 @@ -11414,33 +11302,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 @@ -11450,9 +11338,8 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 #: of msgid "" -"The standard deviation of the noise added to the count of updates below " -"the estimate. Andrew et al. recommends to set to " -"`expected_num_records/20`" +"The standard deviation of the noise added to the count of updates below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 @@ -11465,49 +11352,49 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 @@ -11517,24 +11404,23 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 #: of msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " -"wrapper" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 @@ -11546,33 +11432,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 @@ -11587,17 +11473,15 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11619,17 +11503,15 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11642,25 +11524,22 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 @@ -11713,28 +11592,26 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11745,23 +11622,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 @@ -11780,9 +11654,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11793,9 +11666,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11812,22 +11684,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -11844,17 +11713,16 @@ msgstr "" #: of msgid "" "Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will " -"still be sampled. Defaults to 1.0." +"larger than `fraction_fit * available_clients`, `min_fit_clients` will still " +"be sampled. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -"Fraction of clients used during validation. In case " -"`min_evaluate_clients` is larger than `fraction_evaluate * " -"available_clients`, `min_evaluate_clients` will still be sampled. " -"Defaults to 1.0." +"Fraction of clients used during validation. In case `min_evaluate_clients` " +"is larger than `fraction_evaluate * available_clients`, " +"`min_evaluate_clients` will still be sampled. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:33 of @@ -11863,9 +11731,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11876,9 +11743,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11895,22 +11761,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 @@ -11920,24 +11784,22 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`bytes_to_ndarray " -"`\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -11948,16 +11810,14 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -11971,16 +11831,15 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarray_to_bytes " -"`\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -11991,33 +11850,29 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarrays_to_parameters " -"`\\ " -"\\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`parameters_to_ndarrays " -"`\\ " -"\\(parameters\\)" +":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -12036,8 +11891,7 @@ msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to " -"1.0." +"Server-side learning rate used in server-side optimization. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:28 of @@ -12046,9 +11900,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12059,9 +11912,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12078,22 +11930,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12103,9 +11952,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12121,9 +11969,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12140,22 +11987,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12173,9 +12017,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12186,9 +12029,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12205,22 +12047,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 @@ -12233,9 +12073,9 @@ msgstr "" #: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"The strategy in itself will not be different than FedAvg, the client " -"needs to be adjusted. A proximal term needs to be added to the loss " -"function during the training:" +"The strategy in itself will not be different than FedAvg, the client needs " +"to be adjusted. A proximal term needs to be added to the loss function " +"during the training:" msgstr "" #: flwr.server.strategy.fedprox.FedProx:9 of @@ -12268,15 +12108,14 @@ msgstr "" msgid "" "The weight of the proximal term used in the optimization. 0.0 makes this " "strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to " -"be closer to the server parameters during training)." +"regularization will be used (that is, the client parameters will need to be " +"closer to the server parameters during training)." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12287,9 +12126,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12306,22 +12144,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12343,15 +12178,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -12362,15 +12195,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -12382,23 +12213,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 @@ -12408,9 +12236,8 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 @@ -12424,8 +12251,7 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -12439,16 +12265,14 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -12462,25 +12286,22 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 @@ -12490,33 +12311,29 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\," -" results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 @@ -12529,25 +12346,22 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 @@ -12557,36 +12371,31 @@ msgstr "" #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of msgid "" "This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: " -"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +"Baselines: https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\, " -"results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12597,23 +12406,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 @@ -12634,9 +12440,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12647,9 +12452,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12666,22 +12470,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12695,15 +12496,14 @@ msgstr "" #: flwr.server.strategy.krum.Krum:17 of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" -" that case classical Krum is applied." +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in " +"that case classical Krum is applied." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12719,9 +12519,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12738,16 +12537,14 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12762,9 +12559,8 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -12775,9 +12571,8 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -12794,22 +12589,19 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12820,9 +12612,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 @@ -12846,9 +12637,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -12873,9 +12663,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -12885,17 +12674,18 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " -"one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "Exceptions that occurred while the server was waiting for client updates." +msgid "" +"Exceptions that occurred while the server was waiting for client updates." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of @@ -12906,23 +12696,22 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" -" one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes)` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the " -"previous parameters with the ones returned from this method). If `None` " -"is returned (e.g., because there were only failures and no viable " -"results) then the server will no update the previous model parameters, " -"the updates received in this round are discarded, and the global model " -"parameters remain the same." +"these as the new global model parameters (i.e., it will replace the previous " +"parameters with the ones returned from this method). If `None` is returned " +"(e.g., because there were only failures and no viable results) then the " +"server will no update the previous model parameters, the updates received in " +"this round are discarded, and the global model parameters remain the same." msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:3 of @@ -12933,9 +12722,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple " -"containing loss and a dictionary containing task-specific metrics (e.g., " -"accuracy)." +"**evaluation_result** -- The evaluation result, usually a Tuple containing " +"loss and a dictionary containing task-specific metrics (e.g., accuracy)." msgstr "" #: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of @@ -12993,17 +12781,17 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 #: of msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors " -"owned by multiple parties, without accessing any individual integer " -"vector. This workflow allows the server to compute the weighted average " -"of model parameters across all clients, ensuring individual contributions" -" remain private. This is achieved by clients sending both, a weighting " -"factor and a weighted version of the locally updated parameters, both of " -"which are masked for privacy. Specifically, each client uploads \"[w, w *" -" params]\" with masks, where weighting factor 'w' is the number of " -"examples ('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"The SecAgg+ protocol ensures the secure summation of integer vectors owned " +"by multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " +"parameters across all clients, ensuring individual contributions remain " +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 @@ -13040,39 +12828,39 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 #: of msgid "" -"Only the aggregated model parameters are exposed and passed to " -"`Strategy.aggregate_fit`, ensuring individual data privacy." +"Only the aggregated model parameters are exposed and passed to `Strategy." +"aggregate_fit`, ensuring individual data privacy." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of msgid "" -"The number of shares into which each client's private key is split under " -"the SecAgg+ protocol. If specified as a float, it represents the " -"proportion of all selected clients, and the number of shares will be set " -"dynamically in the run time. A private key can be reconstructed from " -"these shares, allowing for the secure aggregation of model updates. Each " -"client sends one share to each of its neighbors while retaining one." +"The number of shares into which each client's private key is split under the " +"SecAgg+ protocol. If specified as a float, it represents the proportion of " +"all selected clients, and the number of shares will be set dynamically in " +"the run time. A private key can be reconstructed from these shares, allowing " +"for the secure aggregation of model updates. Each client sends one share to " +"each of its neighbors while retaining one." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 #: of msgid "" -"The minimum number of shares required to reconstruct a client's private " -"key, or, if specified as a float, it represents the proportion of the " -"total number of shares needed for reconstruction. This threshold ensures " -"privacy by allowing for the recovery of contributions from dropped " -"clients during aggregation, without compromising individual client data." +"The minimum number of shares required to reconstruct a client's private key, " +"or, if specified as a float, it represents the proportion of the total " +"number of shares needed for reconstruction. This threshold ensures privacy " +"by allowing for the recovery of contributions from dropped clients during " +"aggregation, without compromising individual client data." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 #: of msgid "" -"The maximum value of the weight that can be assigned to any single " -"client's update during the weighted average calculation on the server " -"side, e.g., in the FedAvg algorithm." +"The maximum value of the weight that can be assigned to any single client's " +"update during the weighted average calculation on the server side, e.g., in " +"the FedAvg algorithm." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 @@ -13080,8 +12868,8 @@ msgstr "" #: of msgid "" "The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within " -"[-clipping_range, clipping_range], facilitating quantization." +"This parameter ensures each model parameter is bounded within [-" +"clipping_range, clipping_range], facilitating quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 @@ -13099,31 +12887,32 @@ msgstr "" #: of msgid "" "The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " -"Please use 2**n values for `modulus_range` to prevent overflow issues." +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. Please " +"use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for" -" replies for this duration each time. If `None`, there is no time limit " -"and the workflow will wait until replies for all messages are received." +"The timeout duration in seconds. If specified, the workflow will wait for " +"replies for this duration each time. If `None`, there is no time limit and " +"the workflow will wait until replies for all messages are received." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 #: of msgid "" "Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` " -"means better privacy guarantees but less tolerance to dropouts." +"increasing the computational costs; higher `reconstruction_threshold` means " +"better privacy guarantees but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of -msgid "Too large `max_weight` may compromise the precision of the quantization." +msgid "" +"Too large `max_weight` may compromise the precision of the quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 @@ -13136,35 +12925,34 @@ msgstr "" #: of msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in " -"the runtime. This allows for dynamic adjustment based on the total number" -" of participating clients." +"selected clients, and hence the number of shares will be determined in the " +"runtime. This allows for dynamic adjustment based on the total number of " +"participating clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 #: of msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted " -"as the proportion of the number of shares needed for the reconstruction " -"of a private key. This feature enables flexibility in setting the " -"security threshold relative to the number of distributed shares." +"Similarly, when `reconstruction_threshold` is a float, it is interpreted as " +"the proportion of the number of shares needed for the reconstruction of a " +"private key. This feature enables flexibility in setting the security " +"threshold relative to the number of distributed shares." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 #: of msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters" -" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+" -" protocol." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters " +"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+ " +"protocol." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\" -" \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 @@ -13176,9 +12964,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13190,9 +12977,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage " -"`\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13204,9 +12990,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13221,51 +13006,50 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"Bases: " -":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" +"Bases: :py:class:`~flwr.server.workflow.secure_aggregation." +"secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned" -" by multiple parties, without accessing any individual integer vector. " -"This workflow allows the server to compute the weighted average of model " +"The SecAgg protocol ensures the secure summation of integer vectors owned by " +"multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " "parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and" -" a weighted version of the locally updated parameters, both of which are " -"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" -" with masks, where weighting factor 'w' is the number of examples " -"('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +"The protocol involves four main stages: - 'setup': Send SecAgg configuration " +"to clients and collect their public keys. - 'share keys': Broadcast public " +"keys among clients and collect encrypted secret" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"Each client's private key is split into N shares under the SecAgg " -"protocol, where N is the number of selected clients." +"Each client's private key is split into N shares under the SecAgg protocol, " +"where N is the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"Generally, higher `reconstruction_threshold` means better privacy " -"guarantees but less tolerance to dropouts." +"Generally, higher `reconstruction_threshold` means better privacy guarantees " +"but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in " -"setting the security threshold relative to the number of selected " -"clients." +"reconstruction of a private key. This feature enables flexibility in setting " +"the security threshold relative to the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of @@ -13279,32 +13063,29 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\ " -"\\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:2 @@ -13313,8 +13094,8 @@ msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\," -" client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\, " +"client\\_fn\\[\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 @@ -13345,15 +13126,14 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive" -" messages sent by the `ServerApp`." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive " +"messages sent by the `ServerApp`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in " -"the ServerApp and receive a Message describing what the ClientApp should " -"perform." +"Number of nodes that run a ClientApp. They can be sampled by a Driver in the " +"ServerApp and receive a Message describing what the ClientApp should perform." msgstr "" #: flwr.simulation.run_simulation.run_simulation:13 of @@ -13362,26 +13142,26 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to " -"configure a backend. Values supported in are those included by " -"`flwr.common.typing.ConfigsRecordValues`." +"'A dictionary, e.g {\"\": , \"\": } to configure a " +"backend. Values supported in are those included by `flwr.common." +"typing.ConfigsRecordValues`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. " -"This is desirable if you make use of a TensorFlow model on your " -"`ServerApp` while having your `ClientApp` running on the same GPU. " -"Without enabling this, you might encounter an out-of-memory error because" -" TensorFlow, by default, allocates all GPU memory. Read more about how " -"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " -"documentation: https://www.tensorflow.org/api/stable." +"A boolean to indicate whether to enable GPU growth on the main thread. This " +"is desirable if you make use of a TensorFlow model on your `ServerApp` while " +"having your `ClientApp` running on the same GPU. Without enabling this, you " +"might encounter an out-of-memory error because TensorFlow, by default, " +"allocates all GPU memory. Read more about how `tf.config.experimental." +"set_memory_growth()` works in the TensorFlow documentation: https://www." +"tensorflow.org/api/stable." msgstr "" #: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" -" enabled, DEBUG-level logs will be displayed." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If " +"enabled, DEBUG-level logs will be displayed." msgstr "" #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 @@ -13390,15 +13170,15 @@ msgstr "" #: flwr.simulation.app.start_simulation:3 of msgid "" -"A function creating client instances. The function must take a single " -"`str` argument called `cid`. It should return a single client instance of" -" type Client. Note that the created client instances are ephemeral and " -"will often be destroyed after a single method invocation. Since client " -"instances are not long-lived, they should not attempt to carry state over" -" method invocations. Any state required by the instance (model, dataset, " +"A function creating client instances. The function must take a single `str` " +"argument called `cid`. It should return a single client instance of type " +"Client. Note that the created client instances are ephemeral and will often " +"be destroyed after a single method invocation. Since client instances are " +"not long-lived, they should not attempt to carry state over method " +"invocations. Any state required by the instance (model, dataset, " "hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load " -"evaluation data in the `evaluate` method itself)." +"`client_fn` or the call to any of the client methods (e.g., load evaluation " +"data in the `evaluate` method itself)." msgstr "" #: flwr.simulation.app.start_simulation:13 of @@ -13409,16 +13189,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:16 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients`" -" is not set. Setting both `num_clients` and `clients_ids` with " +"List `client_id`s for each client. This is only required if `num_clients` is " +"not set. Setting both `num_clients` and `clients_ids` with " "`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" #: flwr.simulation.app.start_simulation:20 of msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` " -"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " -"as well as using custom resources, please consult the Ray documentation." +"CPU and GPU resources for a single client. Supported keys are `num_cpus` and " +"`num_gpus`. To understand the GPU utilization caused by `num_gpus`, as well " +"as using custom resources, please consult the Ray documentation." msgstr "" #: flwr.simulation.app.start_simulation:25 of @@ -13429,16 +13209,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:31 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If " -"no strategy is provided, then `start_server` will use " -"`flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.Strategy`. If no " +"strategy is provided, then `start_server` will use `flwr.server.strategy." +"FedAvg`." msgstr "" #: flwr.simulation.app.start_simulation:35 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_simulation` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_simulation` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -13447,8 +13227,7 @@ msgid "" "ray_init_args is None (the default), Ray will be initialized with the " "following default args: { \"ignore_reinit_error\": True, " "\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to " -"ray.init." +"(ray_init_args={}) to prevent any arguments from being passed to ray.init." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -13464,14 +13243,13 @@ msgstr "" #: flwr.simulation.app.start_simulation:45 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any " -"arguments from being passed to ray.init." +"An empty dictionary can be used (ray_init_args={}) to prevent any arguments " +"from being passed to ray.init." msgstr "" #: flwr.simulation.app.start_simulation:48 of msgid "" -"Set to True to prevent `ray.shutdown()` in case " -"`ray.is_initialized()=True`." +"Set to True to prevent `ray.shutdown()` in case `ray.is_initialized()=True`." msgstr "" #: flwr.simulation.app.start_simulation:50 of @@ -13483,19 +13261,19 @@ msgstr "" #: flwr.simulation.app.start_simulation:54 of msgid "" -"If you want to create your own Actor classes, you might need to pass some" -" input argument. You can use this dictionary for such purpose." +"If you want to create your own Actor classes, you might need to pass some " +"input argument. You can use this dictionary for such purpose." msgstr "" #: flwr.simulation.app.start_simulation:57 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " -"the VCE to choose in which node the actor is placed. If you are an " -"advanced user needed more control you can use lower-level scheduling " -"strategies to pin actors to specific compute nodes (e.g. via " -"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." -" For all details, please refer to the Ray documentation: " -"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for the " +"VCE to choose in which node the actor is placed. If you are an advanced user " +"needed more control you can use lower-level scheduling strategies to pin " +"actors to specific compute nodes (e.g. via NodeAffinitySchedulingStrategy). " +"Please note this is an advanced feature. For all details, please refer to " +"the Ray documentation: https://docs.ray.io/en/latest/ray-core/scheduling/" +"index.html" msgstr "" #: flwr.simulation.app.start_simulation:66 of @@ -13556,244 +13334,219 @@ msgstr "" #: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 #: ../../source/ref-changelog.md:478 msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" +"We would like to give our special thanks to all the contributors who made " +"the new version of Flower possible (in `git shortlog` order):" msgstr "" #: ../../source/ref-changelog.md:17 msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " -"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " -"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " -"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " -"`tabdar-khan` " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear Ashimine`, " +"`Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, `Sebastian van der " +"Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, `tabdar-khan` " msgstr "" #: ../../source/ref-changelog.md:21 msgid "" -"**Introduce Flower Next high-level API (stable)** " -"([#3002](https://github.com/adap/flower/pull/3002), " -"[#2934](https://github.com/adap/flower/pull/2934), " -"[#2958](https://github.com/adap/flower/pull/2958), " -"[#3173](https://github.com/adap/flower/pull/3173), " -"[#3174](https://github.com/adap/flower/pull/3174), " -"[#2923](https://github.com/adap/flower/pull/2923), " -"[#2691](https://github.com/adap/flower/pull/2691), " -"[#3079](https://github.com/adap/flower/pull/3079), " -"[#2961](https://github.com/adap/flower/pull/2961), " -"[#2924](https://github.com/adap/flower/pull/2924), " -"[#3166](https://github.com/adap/flower/pull/3166), " -"[#3031](https://github.com/adap/flower/pull/3031), " -"[#3057](https://github.com/adap/flower/pull/3057), " -"[#3000](https://github.com/adap/flower/pull/3000), " -"[#3113](https://github.com/adap/flower/pull/3113), " -"[#2957](https://github.com/adap/flower/pull/2957), " -"[#3183](https://github.com/adap/flower/pull/3183), " -"[#3180](https://github.com/adap/flower/pull/3180), " -"[#3035](https://github.com/adap/flower/pull/3035), " -"[#3189](https://github.com/adap/flower/pull/3189), " -"[#3185](https://github.com/adap/flower/pull/3185), " -"[#3190](https://github.com/adap/flower/pull/3190), " -"[#3191](https://github.com/adap/flower/pull/3191), " -"[#3195](https://github.com/adap/flower/pull/3195), " -"[#3197](https://github.com/adap/flower/pull/3197))" +"**Introduce Flower Next high-level API (stable)** ([#3002](https://github." +"com/adap/flower/pull/3002), [#2934](https://github.com/adap/flower/" +"pull/2934), [#2958](https://github.com/adap/flower/pull/2958), [#3173]" +"(https://github.com/adap/flower/pull/3173), [#3174](https://github.com/adap/" +"flower/pull/3174), [#2923](https://github.com/adap/flower/pull/2923), [#2691]" +"(https://github.com/adap/flower/pull/2691), [#3079](https://github.com/adap/" +"flower/pull/3079), [#2961](https://github.com/adap/flower/pull/2961), [#2924]" +"(https://github.com/adap/flower/pull/2924), [#3166](https://github.com/adap/" +"flower/pull/3166), [#3031](https://github.com/adap/flower/pull/3031), [#3057]" +"(https://github.com/adap/flower/pull/3057), [#3000](https://github.com/adap/" +"flower/pull/3000), [#3113](https://github.com/adap/flower/pull/3113), [#2957]" +"(https://github.com/adap/flower/pull/2957), [#3183](https://github.com/adap/" +"flower/pull/3183), [#3180](https://github.com/adap/flower/pull/3180), [#3035]" +"(https://github.com/adap/flower/pull/3035), [#3189](https://github.com/adap/" +"flower/pull/3189), [#3185](https://github.com/adap/flower/pull/3185), [#3190]" +"(https://github.com/adap/flower/pull/3190), [#3191](https://github.com/adap/" +"flower/pull/3191), [#3195](https://github.com/adap/flower/pull/3195), [#3197]" +"(https://github.com/adap/flower/pull/3197))" msgstr "" #: ../../source/ref-changelog.md:23 msgid "" "The Flower Next high-level API is stable! Flower Next is the future of " -"Flower - all new features (like Flower Mods) will be built on top of it. " -"You can start to migrate your existing projects to Flower Next by using " -"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " -"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." -" Flower Next allows you to run multiple projects concurrently (we call " -"this multi-run) and execute the same project in either simulation " -"environments or deployment environments without having to change a single" -" line of code. The best part? It's fully compatible with existing Flower " -"projects that use `Strategy`, `NumPyClient` & co." +"Flower - all new features (like Flower Mods) will be built on top of it. You " +"can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or `quickstart-" +"tensorflow`, a detailed migration guide will follow shortly). Flower Next " +"allows you to run multiple projects concurrently (we call this multi-run) " +"and execute the same project in either simulation environments or deployment " +"environments without having to change a single line of code. The best part? " +"It's fully compatible with existing Flower projects that use `Strategy`, " +"`NumPyClient` & co." msgstr "" #: ../../source/ref-changelog.md:25 msgid "" -"**Introduce Flower Next low-level API (preview)** " -"([#3062](https://github.com/adap/flower/pull/3062), " -"[#3034](https://github.com/adap/flower/pull/3034), " -"[#3069](https://github.com/adap/flower/pull/3069))" +"**Introduce Flower Next low-level API (preview)** ([#3062](https://github." +"com/adap/flower/pull/3062), [#3034](https://github.com/adap/flower/" +"pull/3034), [#3069](https://github.com/adap/flower/pull/3069))" msgstr "" #: ../../source/ref-changelog.md:27 msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " -"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " -"new Flower Next *low-level* API. The low-level API allows for granular " -"control of every aspect of the learning process by sending/receiving " -"individual messages to/from client nodes. The new `ServerApp` supports " -"registering a custom `main` function that allows writing custom training " -"loops for methods like async FL, cyclic training, or federated analytics." -" The new `ClientApp` supports registering `train`, `evaluate` and `query`" -" functions that can access the raw message received from the `ServerApp`." -" New abstractions like `RecordSet`, `Message` and `Context` further " -"enable sending multiple models, multiple sets of config values and " -"metrics, stateful computations on the client node and implementations of " -"custom SMPC protocols, to name just a few." +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the new " +"Flower Next *low-level* API. The low-level API allows for granular control " +"of every aspect of the learning process by sending/receiving individual " +"messages to/from client nodes. The new `ServerApp` supports registering a " +"custom `main` function that allows writing custom training loops for methods " +"like async FL, cyclic training, or federated analytics. The new `ClientApp` " +"supports registering `train`, `evaluate` and `query` functions that can " +"access the raw message received from the `ServerApp`. New abstractions like " +"`RecordSet`, `Message` and `Context` further enable sending multiple models, " +"multiple sets of config values and metrics, stateful computations on the " +"client node and implementations of custom SMPC protocols, to name just a few." msgstr "" #: ../../source/ref-changelog.md:29 msgid "" -"**Introduce Flower Mods (preview)** " -"([#3054](https://github.com/adap/flower/pull/3054), " -"[#2911](https://github.com/adap/flower/pull/2911), " -"[#3083](https://github.com/adap/flower/pull/3083))" +"**Introduce Flower Mods (preview)** ([#3054](https://github.com/adap/flower/" +"pull/3054), [#2911](https://github.com/adap/flower/pull/2911), [#3083]" +"(https://github.com/adap/flower/pull/3083))" msgstr "" #: ../../source/ref-changelog.md:31 msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " -"edit or handle them directly. Mods can be used to develop pluggable " -"modules that work across different projects. Flower 1.8 already includes " -"mods to log the size of a message, the number of parameters sent over the" -" network, differential privacy with fixed clipping and adaptive clipping," -" local differential privacy and secure aggregation protocols SecAgg and " -"SecAgg+. The Flower Mods API is released as a preview, but researchers " -"can already use it to experiment with arbirtrary SMPC protocols." +"edit or handle them directly. Mods can be used to develop pluggable modules " +"that work across different projects. Flower 1.8 already includes mods to log " +"the size of a message, the number of parameters sent over the network, " +"differential privacy with fixed clipping and adaptive clipping, local " +"differential privacy and secure aggregation protocols SecAgg and SecAgg+. " +"The Flower Mods API is released as a preview, but researchers can already " +"use it to experiment with arbirtrary SMPC protocols." msgstr "" #: ../../source/ref-changelog.md:33 msgid "" -"**Fine-tune LLMs with LLM FlowerTune** " -"([#3029](https://github.com/adap/flower/pull/3029), " -"[#3089](https://github.com/adap/flower/pull/3089), " -"[#3092](https://github.com/adap/flower/pull/3092), " -"[#3100](https://github.com/adap/flower/pull/3100), " -"[#3114](https://github.com/adap/flower/pull/3114), " -"[#3162](https://github.com/adap/flower/pull/3162), " -"[#3172](https://github.com/adap/flower/pull/3172))" +"**Fine-tune LLMs with LLM FlowerTune** ([#3029](https://github.com/adap/" +"flower/pull/3029), [#3089](https://github.com/adap/flower/pull/3089), [#3092]" +"(https://github.com/adap/flower/pull/3092), [#3100](https://github.com/adap/" +"flower/pull/3100), [#3114](https://github.com/adap/flower/pull/3114), [#3162]" +"(https://github.com/adap/flower/pull/3162), [#3172](https://github.com/adap/" +"flower/pull/3172))" msgstr "" #: ../../source/ref-changelog.md:35 msgid "" -"We are introducing LLM FlowerTune, an introductory example that " -"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " -"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" -" different models and/or datasets. Read our blog post [LLM FlowerTune: " -"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" -"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." +"We are introducing LLM FlowerTune, an introductory example that demonstrates " +"federated LLM fine-tuning of pre-trained Llama2 models on the Alpaca-GPT4 " +"dataset. The example is built to be easily adapted to use different models " +"and/or datasets. Read our blog post [LLM FlowerTune: Federated LLM Fine-" +"tuning with Flower](https://flower.ai/blog/2024-03-14-llm-flowertune-" +"federated-llm-finetuning-with-flower/) for more details." msgstr "" #: ../../source/ref-changelog.md:37 msgid "" -"**Introduce built-in Differential Privacy (preview)** " -"([#2798](https://github.com/adap/flower/pull/2798), " -"[#2959](https://github.com/adap/flower/pull/2959), " -"[#3038](https://github.com/adap/flower/pull/3038), " -"[#3147](https://github.com/adap/flower/pull/3147), " -"[#2909](https://github.com/adap/flower/pull/2909), " -"[#2893](https://github.com/adap/flower/pull/2893), " -"[#2892](https://github.com/adap/flower/pull/2892), " -"[#3039](https://github.com/adap/flower/pull/3039), " -"[#3074](https://github.com/adap/flower/pull/3074))" +"**Introduce built-in Differential Privacy (preview)** ([#2798](https://" +"github.com/adap/flower/pull/2798), [#2959](https://github.com/adap/flower/" +"pull/2959), [#3038](https://github.com/adap/flower/pull/3038), [#3147]" +"(https://github.com/adap/flower/pull/3147), [#2909](https://github.com/adap/" +"flower/pull/2909), [#2893](https://github.com/adap/flower/pull/2893), [#2892]" +"(https://github.com/adap/flower/pull/2892), [#3039](https://github.com/adap/" +"flower/pull/3039), [#3074](https://github.com/adap/flower/pull/3074))" msgstr "" #: ../../source/ref-changelog.md:39 msgid "" "Built-in Differential Privacy is here! Flower supports both central and " -"local differential privacy (DP). Central DP can be configured with either" -" fixed or adaptive clipping. The clipping can happen either on the " -"server-side or the client-side. Local DP does both clipping and noising " -"on the client-side. A new documentation page [explains Differential " -"Privacy approaches](https://flower.ai/docs/framework/explanation-" -"differential-privacy.html) and a new how-to guide describes [how to use " -"the new Differential Privacy components](https://flower.ai/docs/framework" -"/how-to-use-differential-privacy.html) in Flower." +"local differential privacy (DP). Central DP can be configured with either " +"fixed or adaptive clipping. The clipping can happen either on the server-" +"side or the client-side. Local DP does both clipping and noising on the " +"client-side. A new documentation page [explains Differential Privacy " +"approaches](https://flower.ai/docs/framework/explanation-differential-" +"privacy.html) and a new how-to guide describes [how to use the new " +"Differential Privacy components](https://flower.ai/docs/framework/how-to-use-" +"differential-privacy.html) in Flower." msgstr "" #: ../../source/ref-changelog.md:41 msgid "" -"**Introduce built-in Secure Aggregation (preview)** " -"([#3120](https://github.com/adap/flower/pull/3120), " -"[#3110](https://github.com/adap/flower/pull/3110), " -"[#3108](https://github.com/adap/flower/pull/3108))" +"**Introduce built-in Secure Aggregation (preview)** ([#3120](https://github." +"com/adap/flower/pull/3120), [#3110](https://github.com/adap/flower/" +"pull/3110), [#3108](https://github.com/adap/flower/pull/3108))" msgstr "" #: ../../source/ref-changelog.md:43 msgid "" -"Built-in Secure Aggregation is here! Flower now supports different secure" -" aggregation protocols out-of-the-box. The best part? You can add secure " -"aggregation to your Flower projects with only a few lines of code. In " -"this initial release, we inlcude support for SecAgg and SecAgg+, but more" -" protocols will be implemented shortly. We'll also add detailed docs that" -" explain secure aggregation and how to use it in Flower. You can already " +"Built-in Secure Aggregation is here! Flower now supports different secure " +"aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In this " +"initial release, we inlcude support for SecAgg and SecAgg+, but more " +"protocols will be implemented shortly. We'll also add detailed docs that " +"explain secure aggregation and how to use it in Flower. You can already " "check out the new code example that shows how to use Flower to easily " -"combine Federated Learning, Differential Privacy and Secure Aggregation " -"in the same project." +"combine Federated Learning, Differential Privacy and Secure Aggregation in " +"the same project." msgstr "" #: ../../source/ref-changelog.md:45 msgid "" -"**Introduce** `flwr` **CLI (preview)** " -"([#2942](https://github.com/adap/flower/pull/2942), " -"[#3055](https://github.com/adap/flower/pull/3055), " -"[#3111](https://github.com/adap/flower/pull/3111), " -"[#3130](https://github.com/adap/flower/pull/3130), " -"[#3136](https://github.com/adap/flower/pull/3136), " -"[#3094](https://github.com/adap/flower/pull/3094), " -"[#3059](https://github.com/adap/flower/pull/3059), " -"[#3049](https://github.com/adap/flower/pull/3049), " -"[#3142](https://github.com/adap/flower/pull/3142))" +"**Introduce** `flwr` **CLI (preview)** ([#2942](https://github.com/adap/" +"flower/pull/2942), [#3055](https://github.com/adap/flower/pull/3055), [#3111]" +"(https://github.com/adap/flower/pull/3111), [#3130](https://github.com/adap/" +"flower/pull/3130), [#3136](https://github.com/adap/flower/pull/3136), [#3094]" +"(https://github.com/adap/flower/pull/3094), [#3059](https://github.com/adap/" +"flower/pull/3059), [#3049](https://github.com/adap/flower/pull/3049), [#3142]" +"(https://github.com/adap/flower/pull/3142))" msgstr "" #: ../../source/ref-changelog.md:47 msgid "" -"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" -" and then running them using the Simulation Engine (`flwr run`)." +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`) " +"and then running them using the Simulation Engine (`flwr run`)." msgstr "" #: ../../source/ref-changelog.md:49 msgid "" -"**Introduce Flower Next Simulation Engine** " -"([#3024](https://github.com/adap/flower/pull/3024), " -"[#3061](https://github.com/adap/flower/pull/3061), " -"[#2997](https://github.com/adap/flower/pull/2997), " -"[#2783](https://github.com/adap/flower/pull/2783), " -"[#3184](https://github.com/adap/flower/pull/3184), " -"[#3075](https://github.com/adap/flower/pull/3075), " -"[#3047](https://github.com/adap/flower/pull/3047), " -"[#2998](https://github.com/adap/flower/pull/2998), " -"[#3009](https://github.com/adap/flower/pull/3009), " -"[#3008](https://github.com/adap/flower/pull/3008))" +"**Introduce Flower Next Simulation Engine** ([#3024](https://github.com/adap/" +"flower/pull/3024), [#3061](https://github.com/adap/flower/pull/3061), [#2997]" +"(https://github.com/adap/flower/pull/2997), [#2783](https://github.com/adap/" +"flower/pull/2783), [#3184](https://github.com/adap/flower/pull/3184), [#3075]" +"(https://github.com/adap/flower/pull/3075), [#3047](https://github.com/adap/" +"flower/pull/3047), [#2998](https://github.com/adap/flower/pull/2998), [#3009]" +"(https://github.com/adap/flower/pull/3009), [#3008](https://github.com/adap/" +"flower/pull/3008))" msgstr "" #: ../../source/ref-changelog.md:51 msgid "" -"The Flower Simulation Engine can now run Flower Next projects. For " -"notebook environments, there's also a new `run_simulation` function that " -"can run `ServerApp` and `ClientApp`." +"The Flower Simulation Engine can now run Flower Next projects. For notebook " +"environments, there's also a new `run_simulation` function that can run " +"`ServerApp` and `ClientApp`." msgstr "" #: ../../source/ref-changelog.md:53 msgid "" -"**Handle SuperNode connection errors** " -"([#2969](https://github.com/adap/flower/pull/2969))" +"**Handle SuperNode connection errors** ([#2969](https://github.com/adap/" +"flower/pull/2969))" msgstr "" #: ../../source/ref-changelog.md:55 msgid "" -"A SuperNode will now try to reconnect indefinitely to the SuperLink in " -"case of connection errors. The arguments `--max-retries` and `--max-wait-" -"time` can now be passed to the `flower-client-app` command. `--max-" -"retries` will define the number of tentatives the client should make " -"before it gives up trying to reconnect to the SuperLink, and, `--max-" -"wait-time` defines the time before the SuperNode gives up trying to " -"reconnect to the SuperLink." +"A SuperNode will now try to reconnect indefinitely to the SuperLink in case " +"of connection errors. The arguments `--max-retries` and `--max-wait-time` " +"can now be passed to the `flower-client-app` command. `--max-retries` will " +"define the number of tentatives the client should make before it gives up " +"trying to reconnect to the SuperLink, and, `--max-wait-time` defines the " +"time before the SuperNode gives up trying to reconnect to the SuperLink." msgstr "" #: ../../source/ref-changelog.md:57 msgid "" -"**General updates to Flower Baselines** " -"([#2904](https://github.com/adap/flower/pull/2904), " -"[#2482](https://github.com/adap/flower/pull/2482), " -"[#2985](https://github.com/adap/flower/pull/2985), " -"[#2968](https://github.com/adap/flower/pull/2968))" +"**General updates to Flower Baselines** ([#2904](https://github.com/adap/" +"flower/pull/2904), [#2482](https://github.com/adap/flower/pull/2482), [#2985]" +"(https://github.com/adap/flower/pull/2985), [#2968](https://github.com/adap/" +"flower/pull/2968))" msgstr "" #: ../../source/ref-changelog.md:59 @@ -13804,133 +13557,100 @@ msgstr "" #: ../../source/ref-changelog.md:61 msgid "" -"**Improve documentation and translations** " -"([#3050](https://github.com/adap/flower/pull/3050), " -"[#3044](https://github.com/adap/flower/pull/3044), " -"[#3043](https://github.com/adap/flower/pull/3043), " -"[#2986](https://github.com/adap/flower/pull/2986), " -"[#3041](https://github.com/adap/flower/pull/3041), " -"[#3046](https://github.com/adap/flower/pull/3046), " -"[#3042](https://github.com/adap/flower/pull/3042), " -"[#2978](https://github.com/adap/flower/pull/2978), " -"[#2952](https://github.com/adap/flower/pull/2952), " -"[#3167](https://github.com/adap/flower/pull/3167), " -"[#2953](https://github.com/adap/flower/pull/2953), " -"[#3045](https://github.com/adap/flower/pull/3045), " -"[#2654](https://github.com/adap/flower/pull/2654), " -"[#3082](https://github.com/adap/flower/pull/3082), " -"[#2990](https://github.com/adap/flower/pull/2990), " -"[#2989](https://github.com/adap/flower/pull/2989))" +"**Improve documentation and translations** ([#3050](https://github.com/adap/" +"flower/pull/3050), [#3044](https://github.com/adap/flower/pull/3044), [#3043]" +"(https://github.com/adap/flower/pull/3043), [#2986](https://github.com/adap/" +"flower/pull/2986), [#3041](https://github.com/adap/flower/pull/3041), [#3046]" +"(https://github.com/adap/flower/pull/3046), [#3042](https://github.com/adap/" +"flower/pull/3042), [#2978](https://github.com/adap/flower/pull/2978), [#2952]" +"(https://github.com/adap/flower/pull/2952), [#3167](https://github.com/adap/" +"flower/pull/3167), [#2953](https://github.com/adap/flower/pull/2953), [#3045]" +"(https://github.com/adap/flower/pull/3045), [#2654](https://github.com/adap/" +"flower/pull/2654), [#3082](https://github.com/adap/flower/pull/3082), [#2990]" +"(https://github.com/adap/flower/pull/2990), [#2989](https://github.com/adap/" +"flower/pull/2989))" msgstr "" #: ../../source/ref-changelog.md:63 msgid "" "As usual, we merged many smaller and larger improvements to the " -"documentation. A special thank you goes to [Sebastian van der " -"Voort](https://github.com/svdvoort) for landing a big documentation PR!" +"documentation. A special thank you goes to [Sebastian van der Voort](https://" +"github.com/svdvoort) for landing a big documentation PR!" msgstr "" #: ../../source/ref-changelog.md:65 msgid "" -"**General updates to Flower Examples** " -"([3134](https://github.com/adap/flower/pull/3134), " -"[2996](https://github.com/adap/flower/pull/2996), " -"[2930](https://github.com/adap/flower/pull/2930), " -"[2967](https://github.com/adap/flower/pull/2967), " -"[2467](https://github.com/adap/flower/pull/2467), " -"[2910](https://github.com/adap/flower/pull/2910), " -"[#2918](https://github.com/adap/flower/pull/2918), " -"[#2773](https://github.com/adap/flower/pull/2773), " -"[#3063](https://github.com/adap/flower/pull/3063), " -"[#3116](https://github.com/adap/flower/pull/3116), " -"[#3117](https://github.com/adap/flower/pull/3117))" +"**General updates to Flower Examples** ([3134](https://github.com/adap/" +"flower/pull/3134), [2996](https://github.com/adap/flower/pull/2996), [2930]" +"(https://github.com/adap/flower/pull/2930), [2967](https://github.com/adap/" +"flower/pull/2967), [2467](https://github.com/adap/flower/pull/2467), [2910]" +"(https://github.com/adap/flower/pull/2910), [#2918](https://github.com/adap/" +"flower/pull/2918), [#2773](https://github.com/adap/flower/pull/2773), [#3063]" +"(https://github.com/adap/flower/pull/3063), [#3116](https://github.com/adap/" +"flower/pull/3116), [#3117](https://github.com/adap/flower/pull/3117))" msgstr "" #: ../../source/ref-changelog.md:67 msgid "" -"Two new examples show federated training of a Vision Transformer (ViT) " -"and federated learning in a medical context using the popular MONAI " -"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" -" new Flower Next `ServerApp` and `ClientApp`. Many other examples " -"received considerable updates as well." +"Two new examples show federated training of a Vision Transformer (ViT) and " +"federated learning in a medical context using the popular MONAI library. " +"`quickstart-pytorch` and `quickstart-tensorflow` demonstrate the new Flower " +"Next `ServerApp` and `ClientApp`. Many other examples received considerable " +"updates as well." msgstr "" #: ../../source/ref-changelog.md:69 msgid "" -"**General improvements** " -"([#3171](https://github.com/adap/flower/pull/3171), " -"[3099](https://github.com/adap/flower/pull/3099), " -"[3003](https://github.com/adap/flower/pull/3003), " -"[3145](https://github.com/adap/flower/pull/3145), " -"[3017](https://github.com/adap/flower/pull/3017), " -"[3085](https://github.com/adap/flower/pull/3085), " -"[3012](https://github.com/adap/flower/pull/3012), " -"[3119](https://github.com/adap/flower/pull/3119), " -"[2991](https://github.com/adap/flower/pull/2991), " -"[2970](https://github.com/adap/flower/pull/2970), " -"[2980](https://github.com/adap/flower/pull/2980), " -"[3086](https://github.com/adap/flower/pull/3086), " -"[2932](https://github.com/adap/flower/pull/2932), " -"[2928](https://github.com/adap/flower/pull/2928), " -"[2941](https://github.com/adap/flower/pull/2941), " -"[2933](https://github.com/adap/flower/pull/2933), " -"[3181](https://github.com/adap/flower/pull/3181), " -"[2973](https://github.com/adap/flower/pull/2973), " -"[2992](https://github.com/adap/flower/pull/2992), " -"[2915](https://github.com/adap/flower/pull/2915), " -"[3040](https://github.com/adap/flower/pull/3040), " -"[3022](https://github.com/adap/flower/pull/3022), " -"[3032](https://github.com/adap/flower/pull/3032), " -"[2902](https://github.com/adap/flower/pull/2902), " -"[2931](https://github.com/adap/flower/pull/2931), " -"[3005](https://github.com/adap/flower/pull/3005), " -"[3132](https://github.com/adap/flower/pull/3132), " -"[3115](https://github.com/adap/flower/pull/3115), " -"[2944](https://github.com/adap/flower/pull/2944), " -"[3064](https://github.com/adap/flower/pull/3064), " -"[3106](https://github.com/adap/flower/pull/3106), " -"[2974](https://github.com/adap/flower/pull/2974), " -"[3178](https://github.com/adap/flower/pull/3178), " -"[2993](https://github.com/adap/flower/pull/2993), " -"[3186](https://github.com/adap/flower/pull/3186), " -"[3091](https://github.com/adap/flower/pull/3091), " -"[3125](https://github.com/adap/flower/pull/3125), " -"[3093](https://github.com/adap/flower/pull/3093), " -"[3013](https://github.com/adap/flower/pull/3013), " -"[3033](https://github.com/adap/flower/pull/3033), " -"[3133](https://github.com/adap/flower/pull/3133), " -"[3068](https://github.com/adap/flower/pull/3068), " -"[2916](https://github.com/adap/flower/pull/2916), " -"[2975](https://github.com/adap/flower/pull/2975), " -"[2984](https://github.com/adap/flower/pull/2984), " -"[2846](https://github.com/adap/flower/pull/2846), " -"[3077](https://github.com/adap/flower/pull/3077), " -"[3143](https://github.com/adap/flower/pull/3143), " -"[2921](https://github.com/adap/flower/pull/2921), " -"[3101](https://github.com/adap/flower/pull/3101), " -"[2927](https://github.com/adap/flower/pull/2927), " -"[2995](https://github.com/adap/flower/pull/2995), " -"[2972](https://github.com/adap/flower/pull/2972), " -"[2912](https://github.com/adap/flower/pull/2912), " -"[3065](https://github.com/adap/flower/pull/3065), " -"[3028](https://github.com/adap/flower/pull/3028), " -"[2922](https://github.com/adap/flower/pull/2922), " -"[2982](https://github.com/adap/flower/pull/2982), " -"[2914](https://github.com/adap/flower/pull/2914), " -"[3179](https://github.com/adap/flower/pull/3179), " -"[3080](https://github.com/adap/flower/pull/3080), " -"[2994](https://github.com/adap/flower/pull/2994), " -"[3187](https://github.com/adap/flower/pull/3187), " -"[2926](https://github.com/adap/flower/pull/2926), " -"[3018](https://github.com/adap/flower/pull/3018), " -"[3144](https://github.com/adap/flower/pull/3144), " -"[3011](https://github.com/adap/flower/pull/3011), " -"[#3152](https://github.com/adap/flower/pull/3152), " -"[#2836](https://github.com/adap/flower/pull/2836), " -"[#2929](https://github.com/adap/flower/pull/2929), " -"[#2943](https://github.com/adap/flower/pull/2943), " -"[#2955](https://github.com/adap/flower/pull/2955), " -"[#2954](https://github.com/adap/flower/pull/2954))" +"**General improvements** ([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), [3003](https://github.com/" +"adap/flower/pull/3003), [3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), [3085](https://github.com/" +"adap/flower/pull/3085), [3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), [2991](https://github.com/" +"adap/flower/pull/2991), [2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), [3086](https://github.com/" +"adap/flower/pull/3086), [2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), [2941](https://github.com/" +"adap/flower/pull/2941), [2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), [2973](https://github.com/" +"adap/flower/pull/2973), [2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), [3040](https://github.com/" +"adap/flower/pull/3040), [3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), [2902](https://github.com/" +"adap/flower/pull/2902), [2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), [3132](https://github.com/" +"adap/flower/pull/3132), [3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), [3064](https://github.com/" +"adap/flower/pull/3064), [3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), [3178](https://github.com/" +"adap/flower/pull/3178), [2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), [3091](https://github.com/" +"adap/flower/pull/3091), [3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), [3013](https://github.com/" +"adap/flower/pull/3013), [3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), [3068](https://github.com/" +"adap/flower/pull/3068), [2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), [2984](https://github.com/" +"adap/flower/pull/2984), [2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), [3143](https://github.com/" +"adap/flower/pull/3143), [2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), [2927](https://github.com/" +"adap/flower/pull/2927), [2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), [2912](https://github.com/" +"adap/flower/pull/2912), [3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), [2922](https://github.com/" +"adap/flower/pull/2922), [2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), [3179](https://github.com/" +"adap/flower/pull/3179), [3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), [3187](https://github.com/" +"adap/flower/pull/3187), [2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), [3144](https://github.com/" +"adap/flower/pull/3144), [3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), [#2836](https://github." +"com/adap/flower/pull/2836), [#2929](https://github.com/adap/flower/" +"pull/2929), [#2943](https://github.com/adap/flower/pull/2943), [#2955]" +"(https://github.com/adap/flower/pull/2955), [#2954](https://github.com/adap/" +"flower/pull/2954))" msgstr "" #: ../../source/ref-changelog.md:75 @@ -13939,97 +13659,91 @@ msgstr "" #: ../../source/ref-changelog.md:81 msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " -"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " -"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " -"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " -"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " -"Shaaban`, `Yan Gao`, `Yasar Abbas` " +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles Beauville`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S Chaitanya Kumar`, `Mohammad " +"Naseri`, `Nikos Vlachakis`, `Pritam Neog`, `Robert Kuska`, `Robert Steiner`, " +"`Taner Topal`, `Yahia Salaheldin Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" #: ../../source/ref-changelog.md:85 msgid "" -"**Introduce stateful clients (experimental)** " -"([#2770](https://github.com/adap/flower/pull/2770), " -"[#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), " -"[#2643](https://github.com/adap/flower/pull/2643), " -"[#2769](https://github.com/adap/flower/pull/2769))" +"**Introduce stateful clients (experimental)** ([#2770](https://github.com/" +"adap/flower/pull/2770), [#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), [#2643](https://github." +"com/adap/flower/pull/2643), [#2769](https://github.com/adap/flower/" +"pull/2769))" msgstr "" #: ../../source/ref-changelog.md:87 msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via " -"`start_simulation`) and networked clients (via `start_client`). It's also" -" the first preview of new abstractions like `Context` and `RecordSet`. " -"Clients can access state of type `RecordSet` via `state: RecordSet = " -"self.context.state`. Changes to this `RecordSet` are preserved across " -"different rounds of execution to enable stateful computations in a " -"unified way across simulation and deployment." +"feature is compatible with both simulated clients (via `start_simulation`) " +"and networked clients (via `start_client`). It's also the first preview of " +"new abstractions like `Context` and `RecordSet`. Clients can access state of " +"type `RecordSet` via `state: RecordSet = self.context.state`. Changes to " +"this `RecordSet` are preserved across different rounds of execution to " +"enable stateful computations in a unified way across simulation and " +"deployment." msgstr "" #: ../../source/ref-changelog.md:89 msgid "" -"**Improve performance** " -"([#2293](https://github.com/adap/flower/pull/2293))" +"**Improve performance** ([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" #: ../../source/ref-changelog.md:91 msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" -"place aggregation to reduce memory consumption. The Flower client " -"serialization/deserialization has been rewritten from the ground up, " -"which results in significant speedups, especially when the client-side " -"training time is short." +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-place " +"aggregation to reduce memory consumption. The Flower client serialization/" +"deserialization has been rewritten from the ground up, which results in " +"significant speedups, especially when the client-side training time is short." msgstr "" #: ../../source/ref-changelog.md:93 msgid "" -"**Support Federated Learning with Apple MLX and Flower** " -"([#2693](https://github.com/adap/flower/pull/2693))" +"**Support Federated Learning with Apple MLX and Flower** ([#2693](https://" +"github.com/adap/flower/pull/2693))" msgstr "" #: ../../source/ref-changelog.md:95 msgid "" -"Flower has official support for federated learning using [Apple " -"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " -"example." +"Flower has official support for federated learning using [Apple MLX](https://" +"ml-explore.github.io/mlx) via the new `quickstart-mlx` code example." msgstr "" #: ../../source/ref-changelog.md:97 msgid "" -"**Introduce new XGBoost cyclic strategy** " -"([#2666](https://github.com/adap/flower/pull/2666), " -"[#2668](https://github.com/adap/flower/pull/2668))" +"**Introduce new XGBoost cyclic strategy** ([#2666](https://github.com/adap/" +"flower/pull/2666), [#2668](https://github.com/adap/flower/pull/2668))" msgstr "" #: ../../source/ref-changelog.md:99 msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of" -" training (often called cyclic). The `xgboost-comprehensive` code example" -" shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower " -"offers best-in-class XGBoost support." +"A new strategy called `FedXgbCyclic` supports a client-by-client style of " +"training (often called cyclic). The `xgboost-comprehensive` code example " +"shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower offers " +"best-in-class XGBoost support." msgstr "" #: ../../source/ref-changelog.md:101 msgid "" -"**Support Python 3.11** " -"([#2394](https://github.com/adap/flower/pull/2394))" +"**Support Python 3.11** ([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" #: ../../source/ref-changelog.md:103 msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " -"ensure better support for users using more recent Python versions." +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will ensure " +"better support for users using more recent Python versions." msgstr "" #: ../../source/ref-changelog.md:105 msgid "" -"**Update gRPC and ProtoBuf dependencies** " -"([#2814](https://github.com/adap/flower/pull/2814))" +"**Update gRPC and ProtoBuf dependencies** ([#2814](https://github.com/adap/" +"flower/pull/2814))" msgstr "" #: ../../source/ref-changelog.md:107 @@ -14040,72 +13754,65 @@ msgstr "" #: ../../source/ref-changelog.md:109 msgid "" -"**Introduce Docker image for Flower server** " -"([#2700](https://github.com/adap/flower/pull/2700), " -"[#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), " -"[#2695](https://github.com/adap/flower/pull/2695), " -"[#2747](https://github.com/adap/flower/pull/2747), " -"[#2746](https://github.com/adap/flower/pull/2746), " -"[#2680](https://github.com/adap/flower/pull/2680), " -"[#2682](https://github.com/adap/flower/pull/2682), " -"[#2701](https://github.com/adap/flower/pull/2701))" +"**Introduce Docker image for Flower server** ([#2700](https://github.com/" +"adap/flower/pull/2700), [#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), [#2695](https://github." +"com/adap/flower/pull/2695), [#2747](https://github.com/adap/flower/" +"pull/2747), [#2746](https://github.com/adap/flower/pull/2746), [#2680]" +"(https://github.com/adap/flower/pull/2680), [#2682](https://github.com/adap/" +"flower/pull/2682), [#2701](https://github.com/adap/flower/pull/2701))" msgstr "" #: ../../source/ref-changelog.md:111 msgid "" -"The Flower server can now be run using an official Docker image. A new " -"how-to guide explains [how to run Flower using " -"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html). An official Flower client Docker image will follow." +"The Flower server can now be run using an official Docker image. A new how-" +"to guide explains [how to run Flower using Docker](https://flower.ai/docs/" +"framework/how-to-run-flower-using-docker.html). An official Flower client " +"Docker image will follow." msgstr "" #: ../../source/ref-changelog.md:113 msgid "" -"**Introduce** `flower-via-docker-compose` **example** " -"([#2626](https://github.com/adap/flower/pull/2626))" +"**Introduce** `flower-via-docker-compose` **example** ([#2626](https://" +"github.com/adap/flower/pull/2626))" msgstr "" #: ../../source/ref-changelog.md:115 msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** " -"([#2719](https://github.com/adap/flower/pull/2719))" +"**Introduce** `quickstart-sklearn-tabular` **example** ([#2719](https://" +"github.com/adap/flower/pull/2719))" msgstr "" #: ../../source/ref-changelog.md:117 msgid "" -"**Introduce** `custom-metrics` **example** " -"([#1958](https://github.com/adap/flower/pull/1958))" +"**Introduce** `custom-metrics` **example** ([#1958](https://github.com/adap/" +"flower/pull/1958))" msgstr "" #: ../../source/ref-changelog.md:119 msgid "" -"**Update code examples to use Flower Datasets** " -"([#2450](https://github.com/adap/flower/pull/2450), " -"[#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), " -"[#2712](https://github.com/adap/flower/pull/2712))" +"**Update code examples to use Flower Datasets** ([#2450](https://github.com/" +"adap/flower/pull/2450), [#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), [#2712](https://github." +"com/adap/flower/pull/2712))" msgstr "" #: ../../source/ref-changelog.md:121 msgid "" -"Several code examples were updated to use [Flower " -"Datasets](https://flower.ai/docs/datasets/)." +"Several code examples were updated to use [Flower Datasets](https://flower." +"ai/docs/datasets/)." msgstr "" #: ../../source/ref-changelog.md:123 msgid "" -"**General updates to Flower Examples** " -"([#2381](https://github.com/adap/flower/pull/2381), " -"[#2805](https://github.com/adap/flower/pull/2805), " -"[#2782](https://github.com/adap/flower/pull/2782), " -"[#2806](https://github.com/adap/flower/pull/2806), " -"[#2829](https://github.com/adap/flower/pull/2829), " -"[#2825](https://github.com/adap/flower/pull/2825), " -"[#2816](https://github.com/adap/flower/pull/2816), " -"[#2726](https://github.com/adap/flower/pull/2726), " -"[#2659](https://github.com/adap/flower/pull/2659), " -"[#2655](https://github.com/adap/flower/pull/2655))" +"**General updates to Flower Examples** ([#2381](https://github.com/adap/" +"flower/pull/2381), [#2805](https://github.com/adap/flower/pull/2805), [#2782]" +"(https://github.com/adap/flower/pull/2782), [#2806](https://github.com/adap/" +"flower/pull/2806), [#2829](https://github.com/adap/flower/pull/2829), [#2825]" +"(https://github.com/adap/flower/pull/2825), [#2816](https://github.com/adap/" +"flower/pull/2816), [#2726](https://github.com/adap/flower/pull/2726), [#2659]" +"(https://github.com/adap/flower/pull/2659), [#2655](https://github.com/adap/" +"flower/pull/2655))" msgstr "" #: ../../source/ref-changelog.md:125 @@ -14118,8 +13825,8 @@ msgstr "" #: ../../source/ref-changelog.md:129 msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " -"[#2771](https://github.com/adap/flower/pull/2771))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), [#2771]" +"(https://github.com/adap/flower/pull/2771))" msgstr "" #: ../../source/ref-changelog.md:130 @@ -14144,149 +13851,119 @@ msgstr "" #: ../../source/ref-changelog.md:136 msgid "" -"**Improve documentation** " -"([#2674](https://github.com/adap/flower/pull/2674), " -"[#2480](https://github.com/adap/flower/pull/2480), " -"[#2826](https://github.com/adap/flower/pull/2826), " -"[#2727](https://github.com/adap/flower/pull/2727), " -"[#2761](https://github.com/adap/flower/pull/2761), " -"[#2900](https://github.com/adap/flower/pull/2900))" +"**Improve documentation** ([#2674](https://github.com/adap/flower/" +"pull/2674), [#2480](https://github.com/adap/flower/pull/2480), [#2826]" +"(https://github.com/adap/flower/pull/2826), [#2727](https://github.com/adap/" +"flower/pull/2727), [#2761](https://github.com/adap/flower/pull/2761), [#2900]" +"(https://github.com/adap/flower/pull/2900))" msgstr "" #: ../../source/ref-changelog.md:138 msgid "" -"**Improved testing and development infrastructure** " -"([#2797](https://github.com/adap/flower/pull/2797), " -"[#2676](https://github.com/adap/flower/pull/2676), " -"[#2644](https://github.com/adap/flower/pull/2644), " -"[#2656](https://github.com/adap/flower/pull/2656), " -"[#2848](https://github.com/adap/flower/pull/2848), " -"[#2675](https://github.com/adap/flower/pull/2675), " -"[#2735](https://github.com/adap/flower/pull/2735), " -"[#2767](https://github.com/adap/flower/pull/2767), " -"[#2732](https://github.com/adap/flower/pull/2732), " -"[#2744](https://github.com/adap/flower/pull/2744), " -"[#2681](https://github.com/adap/flower/pull/2681), " -"[#2699](https://github.com/adap/flower/pull/2699), " -"[#2745](https://github.com/adap/flower/pull/2745), " -"[#2734](https://github.com/adap/flower/pull/2734), " -"[#2731](https://github.com/adap/flower/pull/2731), " -"[#2652](https://github.com/adap/flower/pull/2652), " -"[#2720](https://github.com/adap/flower/pull/2720), " -"[#2721](https://github.com/adap/flower/pull/2721), " -"[#2717](https://github.com/adap/flower/pull/2717), " -"[#2864](https://github.com/adap/flower/pull/2864), " -"[#2694](https://github.com/adap/flower/pull/2694), " -"[#2709](https://github.com/adap/flower/pull/2709), " -"[#2658](https://github.com/adap/flower/pull/2658), " -"[#2796](https://github.com/adap/flower/pull/2796), " -"[#2692](https://github.com/adap/flower/pull/2692), " -"[#2657](https://github.com/adap/flower/pull/2657), " -"[#2813](https://github.com/adap/flower/pull/2813), " -"[#2661](https://github.com/adap/flower/pull/2661), " -"[#2398](https://github.com/adap/flower/pull/2398))" +"**Improved testing and development infrastructure** ([#2797](https://github." +"com/adap/flower/pull/2797), [#2676](https://github.com/adap/flower/" +"pull/2676), [#2644](https://github.com/adap/flower/pull/2644), [#2656]" +"(https://github.com/adap/flower/pull/2656), [#2848](https://github.com/adap/" +"flower/pull/2848), [#2675](https://github.com/adap/flower/pull/2675), [#2735]" +"(https://github.com/adap/flower/pull/2735), [#2767](https://github.com/adap/" +"flower/pull/2767), [#2732](https://github.com/adap/flower/pull/2732), [#2744]" +"(https://github.com/adap/flower/pull/2744), [#2681](https://github.com/adap/" +"flower/pull/2681), [#2699](https://github.com/adap/flower/pull/2699), [#2745]" +"(https://github.com/adap/flower/pull/2745), [#2734](https://github.com/adap/" +"flower/pull/2734), [#2731](https://github.com/adap/flower/pull/2731), [#2652]" +"(https://github.com/adap/flower/pull/2652), [#2720](https://github.com/adap/" +"flower/pull/2720), [#2721](https://github.com/adap/flower/pull/2721), [#2717]" +"(https://github.com/adap/flower/pull/2717), [#2864](https://github.com/adap/" +"flower/pull/2864), [#2694](https://github.com/adap/flower/pull/2694), [#2709]" +"(https://github.com/adap/flower/pull/2709), [#2658](https://github.com/adap/" +"flower/pull/2658), [#2796](https://github.com/adap/flower/pull/2796), [#2692]" +"(https://github.com/adap/flower/pull/2692), [#2657](https://github.com/adap/" +"flower/pull/2657), [#2813](https://github.com/adap/flower/pull/2813), [#2661]" +"(https://github.com/adap/flower/pull/2661), [#2398](https://github.com/adap/" +"flower/pull/2398))" msgstr "" #: ../../source/ref-changelog.md:140 msgid "" -"The Flower testing and development infrastructure has received " -"substantial updates. This makes Flower 1.7 the most tested release ever." +"The Flower testing and development infrastructure has received substantial " +"updates. This makes Flower 1.7 the most tested release ever." msgstr "" #: ../../source/ref-changelog.md:142 msgid "" -"**Update dependencies** " -"([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), " -"[#2739](https://github.com/adap/flower/pull/2739), " -"[#2837](https://github.com/adap/flower/pull/2837), " -"[#2788](https://github.com/adap/flower/pull/2788), " -"[#2811](https://github.com/adap/flower/pull/2811), " -"[#2774](https://github.com/adap/flower/pull/2774), " -"[#2790](https://github.com/adap/flower/pull/2790), " -"[#2751](https://github.com/adap/flower/pull/2751), " -"[#2850](https://github.com/adap/flower/pull/2850), " -"[#2812](https://github.com/adap/flower/pull/2812), " -"[#2872](https://github.com/adap/flower/pull/2872), " -"[#2736](https://github.com/adap/flower/pull/2736), " -"[#2756](https://github.com/adap/flower/pull/2756), " -"[#2857](https://github.com/adap/flower/pull/2857), " -"[#2757](https://github.com/adap/flower/pull/2757), " -"[#2810](https://github.com/adap/flower/pull/2810), " -"[#2740](https://github.com/adap/flower/pull/2740), " -"[#2789](https://github.com/adap/flower/pull/2789))" +"**Update dependencies** ([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), [#2739](https://github." +"com/adap/flower/pull/2739), [#2837](https://github.com/adap/flower/" +"pull/2837), [#2788](https://github.com/adap/flower/pull/2788), [#2811]" +"(https://github.com/adap/flower/pull/2811), [#2774](https://github.com/adap/" +"flower/pull/2774), [#2790](https://github.com/adap/flower/pull/2790), [#2751]" +"(https://github.com/adap/flower/pull/2751), [#2850](https://github.com/adap/" +"flower/pull/2850), [#2812](https://github.com/adap/flower/pull/2812), [#2872]" +"(https://github.com/adap/flower/pull/2872), [#2736](https://github.com/adap/" +"flower/pull/2736), [#2756](https://github.com/adap/flower/pull/2756), [#2857]" +"(https://github.com/adap/flower/pull/2857), [#2757](https://github.com/adap/" +"flower/pull/2757), [#2810](https://github.com/adap/flower/pull/2810), [#2740]" +"(https://github.com/adap/flower/pull/2740), [#2789](https://github.com/adap/" +"flower/pull/2789))" msgstr "" #: ../../source/ref-changelog.md:144 msgid "" -"**General improvements** " -"([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), " -"[#2877](https://github.com/adap/flower/pull/2877), " -"[#2690](https://github.com/adap/flower/pull/2690), " -"[#2889](https://github.com/adap/flower/pull/2889), " -"[#2874](https://github.com/adap/flower/pull/2874), " -"[#2819](https://github.com/adap/flower/pull/2819), " -"[#2689](https://github.com/adap/flower/pull/2689), " -"[#2457](https://github.com/adap/flower/pull/2457), " -"[#2870](https://github.com/adap/flower/pull/2870), " -"[#2669](https://github.com/adap/flower/pull/2669), " -"[#2876](https://github.com/adap/flower/pull/2876), " -"[#2885](https://github.com/adap/flower/pull/2885), " -"[#2858](https://github.com/adap/flower/pull/2858), " -"[#2867](https://github.com/adap/flower/pull/2867), " -"[#2351](https://github.com/adap/flower/pull/2351), " -"[#2886](https://github.com/adap/flower/pull/2886), " -"[#2860](https://github.com/adap/flower/pull/2860), " -"[#2828](https://github.com/adap/flower/pull/2828), " -"[#2869](https://github.com/adap/flower/pull/2869), " -"[#2875](https://github.com/adap/flower/pull/2875), " -"[#2733](https://github.com/adap/flower/pull/2733), " -"[#2488](https://github.com/adap/flower/pull/2488), " -"[#2646](https://github.com/adap/flower/pull/2646), " -"[#2879](https://github.com/adap/flower/pull/2879), " -"[#2821](https://github.com/adap/flower/pull/2821), " -"[#2855](https://github.com/adap/flower/pull/2855), " -"[#2800](https://github.com/adap/flower/pull/2800), " -"[#2807](https://github.com/adap/flower/pull/2807), " -"[#2801](https://github.com/adap/flower/pull/2801), " -"[#2804](https://github.com/adap/flower/pull/2804), " -"[#2851](https://github.com/adap/flower/pull/2851), " -"[#2787](https://github.com/adap/flower/pull/2787), " -"[#2852](https://github.com/adap/flower/pull/2852), " -"[#2672](https://github.com/adap/flower/pull/2672), " -"[#2759](https://github.com/adap/flower/pull/2759))" +"**General improvements** ([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." +"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/" +"pull/2690), [#2889](https://github.com/adap/flower/pull/2889), [#2874]" +"(https://github.com/adap/flower/pull/2874), [#2819](https://github.com/adap/" +"flower/pull/2819), [#2689](https://github.com/adap/flower/pull/2689), [#2457]" +"(https://github.com/adap/flower/pull/2457), [#2870](https://github.com/adap/" +"flower/pull/2870), [#2669](https://github.com/adap/flower/pull/2669), [#2876]" +"(https://github.com/adap/flower/pull/2876), [#2885](https://github.com/adap/" +"flower/pull/2885), [#2858](https://github.com/adap/flower/pull/2858), [#2867]" +"(https://github.com/adap/flower/pull/2867), [#2351](https://github.com/adap/" +"flower/pull/2351), [#2886](https://github.com/adap/flower/pull/2886), [#2860]" +"(https://github.com/adap/flower/pull/2860), [#2828](https://github.com/adap/" +"flower/pull/2828), [#2869](https://github.com/adap/flower/pull/2869), [#2875]" +"(https://github.com/adap/flower/pull/2875), [#2733](https://github.com/adap/" +"flower/pull/2733), [#2488](https://github.com/adap/flower/pull/2488), [#2646]" +"(https://github.com/adap/flower/pull/2646), [#2879](https://github.com/adap/" +"flower/pull/2879), [#2821](https://github.com/adap/flower/pull/2821), [#2855]" +"(https://github.com/adap/flower/pull/2855), [#2800](https://github.com/adap/" +"flower/pull/2800), [#2807](https://github.com/adap/flower/pull/2807), [#2801]" +"(https://github.com/adap/flower/pull/2801), [#2804](https://github.com/adap/" +"flower/pull/2804), [#2851](https://github.com/adap/flower/pull/2851), [#2787]" +"(https://github.com/adap/flower/pull/2787), [#2852](https://github.com/adap/" +"flower/pull/2852), [#2672](https://github.com/adap/flower/pull/2672), [#2759]" +"(https://github.com/adap/flower/pull/2759))" msgstr "" #: ../../source/ref-changelog.md:148 msgid "" -"**Deprecate** `start_numpy_client` " -"([#2563](https://github.com/adap/flower/pull/2563), " -"[#2718](https://github.com/adap/flower/pull/2718))" +"**Deprecate** `start_numpy_client` ([#2563](https://github.com/adap/flower/" +"pull/2563), [#2718](https://github.com/adap/flower/pull/2718))" msgstr "" #: ../../source/ref-changelog.md:150 msgid "" "Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we " -"have introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need " -"to first call the `.to_client()` method and then pass returned `Client` " -"object to `start_client`. The examples and the documentation have been " -"updated accordingly." +"`start_numpy_client`. In our efforts to consolidate framework APIs, we have " +"introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need to " +"first call the `.to_client()` method and then pass returned `Client` object " +"to `start_client`. The examples and the documentation have been updated " +"accordingly." msgstr "" #: ../../source/ref-changelog.md:152 msgid "" -"**Deprecate legacy DP wrappers** " -"([#2749](https://github.com/adap/flower/pull/2749))" +"**Deprecate legacy DP wrappers** ([#2749](https://github.com/adap/flower/" +"pull/2749))" msgstr "" #: ../../source/ref-changelog.md:154 msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is " -"in preparation for an all-new pluggable version of differential privacy " -"support in Flower." +"Legacy DP wrapper classes are deprecated, but still functional. This is in " +"preparation for an all-new pluggable version of differential privacy support " +"in Flower." msgstr "" #: ../../source/ref-changelog.md:156 @@ -14297,28 +13974,26 @@ msgstr "" #: ../../source/ref-changelog.md:158 msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " -"([#2890](https://github.com/adap/flower/pull/2890))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` ([#2890]" +"(https://github.com/adap/flower/pull/2890))" msgstr "" #: ../../source/ref-changelog.md:160 msgid "" -"**Drop experimental** `Task` **fields** " -"([#2866](https://github.com/adap/flower/pull/2866), " -"[#2865](https://github.com/adap/flower/pull/2865))" +"**Drop experimental** `Task` **fields** ([#2866](https://github.com/adap/" +"flower/pull/2866), [#2865](https://github.com/adap/flower/pull/2865))" msgstr "" #: ../../source/ref-changelog.md:162 msgid "" "Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed " -"fields are superseded by the new `RecordSet` abstraction." +"`legacy_client_message` were removed from `Task` message. The removed fields " +"are superseded by the new `RecordSet` abstraction." msgstr "" #: ../../source/ref-changelog.md:164 msgid "" -"**Retire MXNet examples** " -"([#2724](https://github.com/adap/flower/pull/2724))" +"**Retire MXNet examples** ([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" #: ../../source/ref-changelog.md:166 @@ -14336,65 +14011,62 @@ msgstr "" msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," -" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " -"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " -"`cnxdeveloper`, `k3nfalt` " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, " +"`Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " +"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " +"`k3nfalt` " msgstr "" #: ../../source/ref-changelog.md:178 msgid "" -"**Add experimental support for Python 3.12** " -"([#2565](https://github.com/adap/flower/pull/2565))" +"**Add experimental support for Python 3.12** ([#2565](https://github.com/" +"adap/flower/pull/2565))" msgstr "" #: ../../source/ref-changelog.md:180 msgid "" -"**Add new XGBoost examples** " -"([#2612](https://github.com/adap/flower/pull/2612), " -"[#2554](https://github.com/adap/flower/pull/2554), " -"[#2617](https://github.com/adap/flower/pull/2617), " -"[#2618](https://github.com/adap/flower/pull/2618), " -"[#2619](https://github.com/adap/flower/pull/2619), " -"[#2567](https://github.com/adap/flower/pull/2567))" +"**Add new XGBoost examples** ([#2612](https://github.com/adap/flower/" +"pull/2612), [#2554](https://github.com/adap/flower/pull/2554), [#2617]" +"(https://github.com/adap/flower/pull/2617), [#2618](https://github.com/adap/" +"flower/pull/2618), [#2619](https://github.com/adap/flower/pull/2619), [#2567]" +"(https://github.com/adap/flower/pull/2567))" msgstr "" #: ../../source/ref-changelog.md:182 msgid "" -"We have added a new `xgboost-quickstart` example alongside a new " -"`xgboost-comprehensive` example that goes more in-depth." +"We have added a new `xgboost-quickstart` example alongside a new `xgboost-" +"comprehensive` example that goes more in-depth." msgstr "" #: ../../source/ref-changelog.md:184 msgid "" -"**Add Vertical FL example** " -"([#2598](https://github.com/adap/flower/pull/2598))" +"**Add Vertical FL example** ([#2598](https://github.com/adap/flower/" +"pull/2598))" msgstr "" #: ../../source/ref-changelog.md:186 msgid "" -"We had many questions about Vertical Federated Learning using Flower, so " -"we decided to add an simple example for it on the [Titanic " -"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " -"tutorial (in the README)." +"We had many questions about Vertical Federated Learning using Flower, so we " +"decided to add an simple example for it on the [Titanic dataset](https://www." +"kaggle.com/competitions/titanic/data) alongside a tutorial (in the README)." msgstr "" #: ../../source/ref-changelog.md:188 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` " -"([#2292](https://github.com/adap/flower/pull/2292))" +"**Support custom** `ClientManager` **in** `start_driver()` ([#2292](https://" +"github.com/adap/flower/pull/2292))" msgstr "" #: ../../source/ref-changelog.md:190 msgid "" -"**Update REST API to support create and delete nodes** " -"([#2283](https://github.com/adap/flower/pull/2283))" +"**Update REST API to support create and delete nodes** ([#2283](https://" +"github.com/adap/flower/pull/2283))" msgstr "" #: ../../source/ref-changelog.md:192 msgid "" -"**Update the Android SDK** " -"([#2187](https://github.com/adap/flower/pull/2187))" +"**Update the Android SDK** ([#2187](https://github.com/adap/flower/" +"pull/2187))" msgstr "" #: ../../source/ref-changelog.md:194 @@ -14403,11 +14075,10 @@ msgstr "" #: ../../source/ref-changelog.md:196 msgid "" -"**Update the C++ SDK** " -"([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"**Update the C++ SDK** ([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), [#2523](https://github." +"com/adap/flower/pull/2523), [#2522](https://github.com/adap/flower/" +"pull/2522))" msgstr "" #: ../../source/ref-changelog.md:198 @@ -14416,93 +14087,90 @@ msgstr "" #: ../../source/ref-changelog.md:200 msgid "" -"**Make HTTPS the new default** " -"([#2591](https://github.com/adap/flower/pull/2591), " -"[#2636](https://github.com/adap/flower/pull/2636))" +"**Make HTTPS the new default** ([#2591](https://github.com/adap/flower/" +"pull/2591), [#2636](https://github.com/adap/flower/pull/2636))" msgstr "" #: ../../source/ref-changelog.md:202 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP " -"for prototyping. The same applies to `flower-client`, which can either " -"use user-provided credentials or gRPC-bundled certificates to connect to " -"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " -"enable insecure HTTP connections." +"passing `--certificates`, but users can enable `--insecure` to use HTTP for " +"prototyping. The same applies to `flower-client`, which can either use user-" +"provided credentials or gRPC-bundled certificates to connect to an HTTPS-" +"enabled server or requires opt-out via passing `--insecure` to enable " +"insecure HTTP connections." msgstr "" #: ../../source/ref-changelog.md:204 msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` " -"will still start in insecure mode by default. In a future release, " -"insecure connections will require user opt-in by passing `insecure=True`." +"For backward compatibility, `start_client()` and `start_numpy_client()` will " +"still start in insecure mode by default. In a future release, insecure " +"connections will require user opt-in by passing `insecure=True`." msgstr "" #: ../../source/ref-changelog.md:206 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"[#2390](https://github.com/adap/flower/pull/2390), [#2493](https://github." +"com/adap/flower/pull/2493))" msgstr "" #: ../../source/ref-changelog.md:208 msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as " -"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" -" `start_simulation`) without requiring changes to how the client class is" -" defined and instantiated. The `to_client()` function is introduced to " +"Using the `client_fn`, Flower clients can interchangeably run as standalone " +"processes (i.e. via `start_client`) or in simulation (i.e. via " +"`start_simulation`) without requiring changes to how the client class is " +"defined and instantiated. The `to_client()` function is introduced to " "convert a `NumPyClient` to a `Client`." msgstr "" #: ../../source/ref-changelog.md:210 msgid "" -"**Add new** `Bulyan` **strategy** " -"([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891))" +"**Add new** `Bulyan` **strategy** ([#1817](https://github.com/adap/flower/" +"pull/1817), [#1891](https://github.com/adap/flower/pull/1891))" msgstr "" #: ../../source/ref-changelog.md:212 msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " -"2018](https://arxiv.org/abs/1802.07927)" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., 2018]" +"(https://arxiv.org/abs/1802.07927)" msgstr "" #: ../../source/ref-changelog.md:214 msgid "" -"**Add new** `XGB Bagging` **strategy** " -"([#2611](https://github.com/adap/flower/pull/2611))" +"**Add new** `XGB Bagging` **strategy** ([#2611](https://github.com/adap/" +"flower/pull/2611))" msgstr "" #: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 msgid "" -"**Introduce `WorkloadState`** " -"([#2564](https://github.com/adap/flower/pull/2564), " -"[#2632](https://github.com/adap/flower/pull/2632))" +"**Introduce `WorkloadState`** ([#2564](https://github.com/adap/flower/" +"pull/2564), [#2632](https://github.com/adap/flower/pull/2632))" msgstr "" #: ../../source/ref-changelog.md:222 msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" +"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" +"pull/2509))" msgstr "" #: ../../source/ref-changelog.md:224 msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), [#2400]" +"(https://github.com/adap/flower/pull/2400))" msgstr "" #: ../../source/ref-changelog.md:226 msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" +"github.com/adap/flower/pull/2507))" msgstr "" #: ../../source/ref-changelog.md:228 msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" +"github.com/adap/flower/pull/2508))" msgstr "" #: ../../source/ref-changelog.md:230 @@ -14535,125 +14203,106 @@ msgstr "" #: ../../source/ref-changelog.md:244 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" msgstr "" #: ../../source/ref-changelog.md:246 msgid "" -"**General updates to Flower Examples** " -"([#2384](https://github.com/adap/flower/pull/2384), " -"[#2425](https://github.com/adap/flower/pull/2425), " -"[#2526](https://github.com/adap/flower/pull/2526), " -"[#2302](https://github.com/adap/flower/pull/2302), " -"[#2545](https://github.com/adap/flower/pull/2545))" +"**General updates to Flower Examples** ([#2384](https://github.com/adap/" +"flower/pull/2384), [#2425](https://github.com/adap/flower/pull/2425), [#2526]" +"(https://github.com/adap/flower/pull/2526), [#2302](https://github.com/adap/" +"flower/pull/2302), [#2545](https://github.com/adap/flower/pull/2545))" msgstr "" #: ../../source/ref-changelog.md:248 msgid "" -"**General updates to Flower Baselines** " -"([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435), " -"[#2462](https://github.com/adap/flower/pull/2462), " -"[#2463](https://github.com/adap/flower/pull/2463), " -"[#2461](https://github.com/adap/flower/pull/2461), " -"[#2469](https://github.com/adap/flower/pull/2469), " -"[#2466](https://github.com/adap/flower/pull/2466), " -"[#2471](https://github.com/adap/flower/pull/2471), " -"[#2472](https://github.com/adap/flower/pull/2472), " -"[#2470](https://github.com/adap/flower/pull/2470))" +"**General updates to Flower Baselines** ([#2301](https://github.com/adap/" +"flower/pull/2301), [#2305](https://github.com/adap/flower/pull/2305), [#2307]" +"(https://github.com/adap/flower/pull/2307), [#2327](https://github.com/adap/" +"flower/pull/2327), [#2435](https://github.com/adap/flower/pull/2435), [#2462]" +"(https://github.com/adap/flower/pull/2462), [#2463](https://github.com/adap/" +"flower/pull/2463), [#2461](https://github.com/adap/flower/pull/2461), [#2469]" +"(https://github.com/adap/flower/pull/2469), [#2466](https://github.com/adap/" +"flower/pull/2466), [#2471](https://github.com/adap/flower/pull/2471), [#2472]" +"(https://github.com/adap/flower/pull/2472), [#2470](https://github.com/adap/" +"flower/pull/2470))" msgstr "" #: ../../source/ref-changelog.md:250 msgid "" -"**General updates to the simulation engine** " -"([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), " -"[#2294](https://github.com/adap/flower/pull/2294))" +"**General updates to the simulation engine** ([#2331](https://github.com/" +"adap/flower/pull/2331), [#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), [#2294](https://github." +"com/adap/flower/pull/2294))" msgstr "" #: ../../source/ref-changelog.md:252 msgid "" -"**General updates to Flower SDKs** " -"([#2288](https://github.com/adap/flower/pull/2288), " -"[#2429](https://github.com/adap/flower/pull/2429), " -"[#2555](https://github.com/adap/flower/pull/2555), " -"[#2543](https://github.com/adap/flower/pull/2543), " -"[#2544](https://github.com/adap/flower/pull/2544), " -"[#2597](https://github.com/adap/flower/pull/2597), " -"[#2623](https://github.com/adap/flower/pull/2623))" +"**General updates to Flower SDKs** ([#2288](https://github.com/adap/flower/" +"pull/2288), [#2429](https://github.com/adap/flower/pull/2429), [#2555]" +"(https://github.com/adap/flower/pull/2555), [#2543](https://github.com/adap/" +"flower/pull/2543), [#2544](https://github.com/adap/flower/pull/2544), [#2597]" +"(https://github.com/adap/flower/pull/2597), [#2623](https://github.com/adap/" +"flower/pull/2623))" msgstr "" #: ../../source/ref-changelog.md:254 msgid "" -"**General improvements** " -"([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[#2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[#2317](https://github.com/adap/flower/pull/2317), " -"[#2349](https://github.com/adap/flower/pull/2349), " -"[#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446), " -"[#2561](https://github.com/adap/flower/pull/2561), " -"[#2273](https://github.com/adap/flower/pull/2273), " -"[#2267](https://github.com/adap/flower/pull/2267), " -"[#2274](https://github.com/adap/flower/pull/2274), " -"[#2275](https://github.com/adap/flower/pull/2275), " -"[#2432](https://github.com/adap/flower/pull/2432), " -"[#2251](https://github.com/adap/flower/pull/2251), " -"[#2321](https://github.com/adap/flower/pull/2321), " -"[#1936](https://github.com/adap/flower/pull/1936), " -"[#2408](https://github.com/adap/flower/pull/2408), " -"[#2413](https://github.com/adap/flower/pull/2413), " -"[#2401](https://github.com/adap/flower/pull/2401), " -"[#2531](https://github.com/adap/flower/pull/2531), " -"[#2534](https://github.com/adap/flower/pull/2534), " -"[#2535](https://github.com/adap/flower/pull/2535), " -"[#2521](https://github.com/adap/flower/pull/2521), " -"[#2553](https://github.com/adap/flower/pull/2553), " -"[#2596](https://github.com/adap/flower/pull/2596))" +"**General improvements** ([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." +"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/" +"pull/2316), [#2317](https://github.com/adap/flower/pull/2317), [#2349]" +"(https://github.com/adap/flower/pull/2349), [#2360](https://github.com/adap/" +"flower/pull/2360), [#2402](https://github.com/adap/flower/pull/2402), [#2446]" +"(https://github.com/adap/flower/pull/2446), [#2561](https://github.com/adap/" +"flower/pull/2561), [#2273](https://github.com/adap/flower/pull/2273), [#2267]" +"(https://github.com/adap/flower/pull/2267), [#2274](https://github.com/adap/" +"flower/pull/2274), [#2275](https://github.com/adap/flower/pull/2275), [#2432]" +"(https://github.com/adap/flower/pull/2432), [#2251](https://github.com/adap/" +"flower/pull/2251), [#2321](https://github.com/adap/flower/pull/2321), [#1936]" +"(https://github.com/adap/flower/pull/1936), [#2408](https://github.com/adap/" +"flower/pull/2408), [#2413](https://github.com/adap/flower/pull/2413), [#2401]" +"(https://github.com/adap/flower/pull/2401), [#2531](https://github.com/adap/" +"flower/pull/2531), [#2534](https://github.com/adap/flower/pull/2534), [#2535]" +"(https://github.com/adap/flower/pull/2535), [#2521](https://github.com/adap/" +"flower/pull/2521), [#2553](https://github.com/adap/flower/pull/2553), [#2596]" +"(https://github.com/adap/flower/pull/2596))" msgstr "" #: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 #: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 #: ../../source/ref-changelog.md:531 -msgid "Flower received many improvements under the hood, too many to list here." +msgid "" +"Flower received many improvements under the hood, too many to list here." msgstr "" #: ../../source/ref-changelog.md:260 msgid "" -"**Remove support for Python 3.7** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" +"**Remove support for Python 3.7** ([#2280](https://github.com/adap/flower/" +"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" +"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" +"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" +"(https://github.com/adap/flower/pull/2356))" msgstr "" #: ../../source/ref-changelog.md:262 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes" -" support. Flower now requires Python 3.8." +"Python 3.7 support was deprecated in Flower 1.5, and this release removes " +"support. Flower now requires Python 3.8." msgstr "" #: ../../source/ref-changelog.md:264 msgid "" -"**Remove experimental argument** `rest` **from** `start_client` " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**Remove experimental argument** `rest` **from** `start_client` ([#2324]" +"(https://github.com/adap/flower/pull/2324))" msgstr "" #: ../../source/ref-changelog.md:266 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` " -"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " -"experimental REST API instead." +"The (still experimental) argument `rest` was removed from `start_client` and " +"`start_numpy_client`. Use `transport=\"rest\"` to opt into the experimental " +"REST API instead." msgstr "" #: ../../source/ref-changelog.md:268 @@ -14671,125 +14320,108 @@ msgstr "" #: ../../source/ref-changelog.md:278 msgid "" -"**Introduce new simulation engine** " -"([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"**Introduce new simulation engine** ([#1969](https://github.com/adap/flower/" +"pull/1969), [#2221](https://github.com/adap/flower/pull/2221), [#2248]" +"(https://github.com/adap/flower/pull/2248))" msgstr "" #: ../../source/ref-changelog.md:280 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and" -" memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-" -"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"remains fully backwards compatible. It offers much improved stability and " +"memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-only, " +"CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" #: ../../source/ref-changelog.md:282 msgid "" -"Comprehensive documentation includes a new [how-to run " -"simulations](https://flower.ai/docs/framework/how-to-run-" -"simulations.html) guide, new [simulation-" +"Comprehensive documentation includes a new [how-to run simulations](https://" +"flower.ai/docs/framework/how-to-run-simulations.html) guide, new [simulation-" "pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " "[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +"tensorflow.html) notebooks, and a new [YouTube tutorial series](https://www." +"youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" #: ../../source/ref-changelog.md:284 msgid "" -"**Restructure Flower Docs** " -"([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +"**Restructure Flower Docs** ([#1824](https://github.com/adap/flower/" +"pull/1824), [#1865](https://github.com/adap/flower/pull/1865), [#1884]" +"(https://github.com/adap/flower/pull/1884), [#1887](https://github.com/adap/" +"flower/pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" +"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" +"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" +"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" +"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" +"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" +"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" +"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" +"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" +"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" +"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" +"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" +"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" +"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" +"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" +"(https://github.com/adap/flower/pull/2227))" msgstr "" #: ../../source/ref-changelog.md:286 msgid "" -"Much effort went into a completely restructured Flower docs experience. " -"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " -"divided into Flower Framework, Flower Baselines, Flower Android SDK, " -"Flower iOS SDK, and code example projects." +"Much effort went into a completely restructured Flower docs experience. The " +"documentation on [flower.ai/docs](https://flower.ai/docs) is now divided " +"into Flower Framework, Flower Baselines, Flower Android SDK, Flower iOS SDK, " +"and code example projects." msgstr "" #: ../../source/ref-changelog.md:288 msgid "" -"**Introduce Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +"**Introduce Flower Swift SDK** ([#1858](https://github.com/adap/flower/" +"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" msgstr "" #: ../../source/ref-changelog.md:290 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support" -" on iOS is improving, and alongside the Swift SDK and code example, there" -" is now also an iOS quickstart tutorial." +"This is the first preview release of the Flower Swift SDK. Flower support on " +"iOS is improving, and alongside the Swift SDK and code example, there is now " +"also an iOS quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:292 msgid "" -"**Introduce Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**Introduce Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" msgstr "" #: ../../source/ref-changelog.md:294 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower " -"support on Android is improving, and alongside the Kotlin SDK and code " -"example, there is now also an Android quickstart tutorial." +"This is the first preview release of the Flower Kotlin SDK. Flower support " +"on Android is improving, and alongside the Kotlin SDK and code example, " +"there is now also an Android quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:296 msgid "" -"**Introduce new end-to-end testing infrastructure** " -"([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" +"**Introduce new end-to-end testing infrastructure** ([#1842](https://github." +"com/adap/flower/pull/1842), [#2071](https://github.com/adap/flower/" +"pull/2071), [#2072](https://github.com/adap/flower/pull/2072), [#2068]" +"(https://github.com/adap/flower/pull/2068), [#2067](https://github.com/adap/" +"flower/pull/2067), [#2069](https://github.com/adap/flower/pull/2069), [#2073]" +"(https://github.com/adap/flower/pull/2073), [#2070](https://github.com/adap/" +"flower/pull/2070), [#2074](https://github.com/adap/flower/pull/2074), [#2082]" +"(https://github.com/adap/flower/pull/2082), [#2084](https://github.com/adap/" +"flower/pull/2084), [#2093](https://github.com/adap/flower/pull/2093), [#2109]" +"(https://github.com/adap/flower/pull/2109), [#2095](https://github.com/adap/" +"flower/pull/2095), [#2140](https://github.com/adap/flower/pull/2140), [#2137]" +"(https://github.com/adap/flower/pull/2137), [#2165](https://github.com/adap/" +"flower/pull/2165))" msgstr "" #: ../../source/ref-changelog.md:298 msgid "" -"A new testing infrastructure ensures that new changes stay compatible " -"with existing framework integrations or strategies." +"A new testing infrastructure ensures that new changes stay compatible with " +"existing framework integrations or strategies." msgstr "" #: ../../source/ref-changelog.md:300 @@ -14798,124 +14430,121 @@ msgstr "" #: ../../source/ref-changelog.md:302 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" -" Python 3.7 is now deprecated and will be removed in an upcoming release." +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for " +"Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" #: ../../source/ref-changelog.md:304 msgid "" -"**Add new** `FedTrimmedAvg` **strategy** " -"([#1769](https://github.com/adap/flower/pull/1769), " -"[#1853](https://github.com/adap/flower/pull/1853))" +"**Add new** `FedTrimmedAvg` **strategy** ([#1769](https://github.com/adap/" +"flower/pull/1769), [#1853](https://github.com/adap/flower/pull/1853))" msgstr "" #: ../../source/ref-changelog.md:306 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, 2018]" +"(https://arxiv.org/abs/1803.01498)." msgstr "" #: ../../source/ref-changelog.md:308 msgid "" -"**Introduce start_driver** " -"([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce start_driver** ([#1697](https://github.com/adap/flower/" +"pull/1697))" msgstr "" #: ../../source/ref-changelog.md:310 msgid "" -"In addition to `start_server` and using the raw Driver API, there is a " -"new `start_driver` function that allows for running `start_server` " -"scripts as a Flower driver with only a single-line code change. Check out" -" the `mt-pytorch` code example to see a working example using " -"`start_driver`." +"In addition to `start_server` and using the raw Driver API, there is a new " +"`start_driver` function that allows for running `start_server` scripts as a " +"Flower driver with only a single-line code change. Check out the `mt-" +"pytorch` code example to see a working example using `start_driver`." msgstr "" #: ../../source/ref-changelog.md:312 msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** " -"([#1785](https://github.com/adap/flower/pull/1785))" +"**Add parameter aggregation to** `mt-pytorch` **code example** ([#1785]" +"(https://github.com/adap/flower/pull/1785))" msgstr "" #: ../../source/ref-changelog.md:314 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a" -" driver script. The included `driver.py` and `server.py` have been " -"aligned to demonstrate both the low-level way and the high-level way of " -"building server-side logic." +"The `mt-pytorch` example shows how to aggregate parameters when writing a " +"driver script. The included `driver.py` and `server.py` have been aligned to " +"demonstrate both the low-level way and the high-level way of building server-" +"side logic." msgstr "" #: ../../source/ref-changelog.md:316 msgid "" -"**Migrate experimental REST API to Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"**Migrate experimental REST API to Starlette** ([2171](https://github.com/" +"adap/flower/pull/2171))" msgstr "" #: ../../source/ref-changelog.md:318 msgid "" -"The (experimental) REST API used to be implemented in " -"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" -" use [Starlette](https://www.starlette.io/) directly." +"The (experimental) REST API used to be implemented in [FastAPI](https://" +"fastapi.tiangolo.com/), but it has now been migrated to use [Starlette]" +"(https://www.starlette.io/) directly." msgstr "" #: ../../source/ref-changelog.md:320 msgid "" -"Please note: The REST request-response API is still experimental and will" -" likely change significantly over time." +"Please note: The REST request-response API is still experimental and will " +"likely change significantly over time." msgstr "" #: ../../source/ref-changelog.md:322 msgid "" -"**Introduce experimental gRPC request-response API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901))" +"**Introduce experimental gRPC request-response API** ([#1867](https://github." +"com/adap/flower/pull/1867), [#1901](https://github.com/adap/flower/" +"pull/1901))" msgstr "" #: ../../source/ref-changelog.md:324 msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) " -"and the experimental REST API, there is now a new gRPC API that uses a " -"request-response model to communicate with client nodes." +"In addition to the existing gRPC API (based on bidirectional streaming) and " +"the experimental REST API, there is now a new gRPC API that uses a request-" +"response model to communicate with client nodes." msgstr "" #: ../../source/ref-changelog.md:326 msgid "" -"Please note: The gRPC request-response API is still experimental and will" -" likely change significantly over time." +"Please note: The gRPC request-response API is still experimental and will " +"likely change significantly over time." msgstr "" #: ../../source/ref-changelog.md:328 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"`start_client(transport=\"rest\")` ([#1880](https://github.com/adap/flower/" +"pull/1880))" msgstr "" #: ../../source/ref-changelog.md:330 msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in " -"favour of a new argument `transport`. `start_client(transport=\"rest\")` " -"will yield the same behaviour as `start_client(rest=True)` did before. " -"All code should migrate to the new argument `transport`. The deprecated " -"argument `rest` will be removed in a future release." +"The (experimental) `start_client` argument `rest` was deprecated in favour " +"of a new argument `transport`. `start_client(transport=\"rest\")` will yield " +"the same behaviour as `start_client(rest=True)` did before. All code should " +"migrate to the new argument `transport`. The deprecated argument `rest` will " +"be removed in a future release." msgstr "" #: ../../source/ref-changelog.md:332 msgid "" -"**Add a new gRPC option** " -"([#2197](https://github.com/adap/flower/pull/2197))" +"**Add a new gRPC option** ([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" #: ../../source/ref-changelog.md:334 msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" -" option set to 0 by default. This prevents the clients from sending " -"keepalive pings when there is no outstanding stream." +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls` " +"option set to 0 by default. This prevents the clients from sending keepalive " +"pings when there is no outstanding stream." msgstr "" #: ../../source/ref-changelog.md:336 msgid "" -"**Improve example notebooks** " -"([#2005](https://github.com/adap/flower/pull/2005))" +"**Improve example notebooks** ([#2005](https://github.com/adap/flower/" +"pull/2005))" msgstr "" #: ../../source/ref-changelog.md:338 @@ -14925,36 +14554,31 @@ msgstr "" #: ../../source/ref-changelog.md:340 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"[#1873](https://github.com/adap/flower/pull/1873), [#1981](https://github." +"com/adap/flower/pull/1981), [#1988](https://github.com/adap/flower/" +"pull/1988), [#1984](https://github.com/adap/flower/pull/1984), [#1982]" +"(https://github.com/adap/flower/pull/1982), [#2112](https://github.com/adap/" +"flower/pull/2112), [#2144](https://github.com/adap/flower/pull/2144), [#2174]" +"(https://github.com/adap/flower/pull/2174), [#2225](https://github.com/adap/" +"flower/pull/2225), [#2183](https://github.com/adap/flower/pull/2183))" msgstr "" #: ../../source/ref-changelog.md:342 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A" -" major upgrade is that all code examples now have a `requirements.txt` " -"(in addition to `pyproject.toml`)." +"compatibility of TensorFlow examples, and code examples for simulation. A " +"major upgrade is that all code examples now have a `requirements.txt` (in " +"addition to `pyproject.toml`)." msgstr "" #: ../../source/ref-changelog.md:344 msgid "" -"**General improvements** " -"([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" +"**General improvements** ([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), [#1884](https://github." +"com/adap/flower/pull/1884), [#1837](https://github.com/adap/flower/" +"pull/1837), [#1477](https://github.com/adap/flower/pull/1477), [#2171]" +"(https://github.com/adap/flower/pull/2171))" msgstr "" #: ../../source/ref-changelog.md:352 @@ -14964,110 +14588,103 @@ msgstr "" #: ../../source/ref-changelog.md:358 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" +"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " +"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " +"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " +"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" #: ../../source/ref-changelog.md:362 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " -"example)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and example)** " +"([#1694](https://github.com/adap/flower/pull/1694), [#1709](https://github." +"com/adap/flower/pull/1709), [#1715](https://github.com/adap/flower/" +"pull/1715), [#1717](https://github.com/adap/flower/pull/1717), [#1763]" +"(https://github.com/adap/flower/pull/1763), [#1795](https://github.com/adap/" +"flower/pull/1795))" msgstr "" #: ../../source/ref-changelog.md:364 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" -" " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" and a [code example](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart) that demonstrates the usage of this new strategy in " -"an XGBoost project." +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg` " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/" +"strategy/fedxgb_nn_avg.py), and a [code example](https://github.com/adap/" +"flower/tree/main/examples/xgboost-quickstart) that demonstrates the usage of " +"this new strategy in an XGBoost project." msgstr "" #: ../../source/ref-changelog.md:366 msgid "" -"**Introduce iOS SDK (preview)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**Introduce iOS SDK (preview)** ([#1621](https://github.com/adap/flower/" +"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" msgstr "" #: ../../source/ref-changelog.md:368 msgid "" -"This is a major update for anyone wanting to implement Federated Learning" -" on iOS mobile devices. We now have a swift iOS SDK present under " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" that will facilitate greatly the app creating process. To showcase its " -"use, the [iOS " +"This is a major update for anyone wanting to implement Federated Learning on " +"iOS mobile devices. We now have a swift iOS SDK present under [src/swift/" +"flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) that will " +"facilitate greatly the app creating process. To showcase its use, the [iOS " "example](https://github.com/adap/flower/tree/main/examples/ios) has also " "been updated!" msgstr "" #: ../../source/ref-changelog.md:370 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** " -"([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" +"**Introduce new \"What is Federated Learning?\" tutorial** ([#1657](https://" +"github.com/adap/flower/pull/1657), [#1721](https://github.com/adap/flower/" +"pull/1721))" msgstr "" #: ../../source/ref-changelog.md:372 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html) in our documentation explains the basics" -" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" -" Learning to start their journey with Flower. Forward it to anyone who's " +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-what-" +"is-federated-learning.html) in our documentation explains the basics of " +"Fedetated Learning. It enables anyone who's unfamiliar with Federated " +"Learning to start their journey with Flower. Forward it to anyone who's " "interested in Federated Learning!" msgstr "" #: ../../source/ref-changelog.md:374 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" +"**Introduce new Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" +"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." +"com/adap/flower/pull/1679))" msgstr "" #: ../../source/ref-changelog.md:376 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated" -" Optimization in Heterogeneous Networks (Li et al., " -"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," -" which aims at making convergence more robust in heterogeneous settings." +"This new baseline replicates the MNIST+CNN task from the paper [Federated " +"Optimization in Heterogeneous Networks (Li et al., 2018)](https://arxiv.org/" +"abs/1812.06127). It uses the `FedProx` strategy, which aims at making " +"convergence more robust in heterogeneous settings." msgstr "" #: ../../source/ref-changelog.md:378 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"**Introduce new Flower Baseline: FedAvg FEMNIST** ([#1655](https://github." +"com/adap/flower/pull/1655))" msgstr "" #: ../../source/ref-changelog.md:380 msgid "" -"This new baseline replicates an experiment evaluating the performance of " -"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " -"Benchmark for Federated Settings (Caldas et al., " -"2018)](https://arxiv.org/abs/1812.01097)." +"This new baseline replicates an experiment evaluating the performance of the " +"FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A Benchmark " +"for Federated Settings (Caldas et al., 2018)](https://arxiv.org/" +"abs/1812.01097)." msgstr "" #: ../../source/ref-changelog.md:382 msgid "" -"**Introduce (experimental) REST API** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" +"**Introduce (experimental) REST API** ([#1594](https://github.com/adap/" +"flower/pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" +"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" +"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" +"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" +"flower/pull/1733))" msgstr "" #: ../../source/ref-changelog.md:384 @@ -15085,132 +14702,112 @@ msgstr "" #: ../../source/ref-changelog.md:388 msgid "" -"**Improve the (experimental) Driver API** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**Improve the (experimental) Driver API** ([#1663](https://github.com/adap/" +"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" +"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" +"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" +"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" +"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" +"(https://github.com/adap/flower/pull/1794))" msgstr "" #: ../../source/ref-changelog.md:390 msgid "" -"The Driver API is still an experimental feature, but this release " -"introduces some major upgrades. One of the main improvements is the " -"introduction of an SQLite database to store server state on disk (instead" -" of in-memory). Another improvement is that tasks (instructions or " -"results) that have been delivered will now be deleted. This greatly " -"improves the memory efficiency of a long-running Flower server." +"The Driver API is still an experimental feature, but this release introduces " +"some major upgrades. One of the main improvements is the introduction of an " +"SQLite database to store server state on disk (instead of in-memory). " +"Another improvement is that tasks (instructions or results) that have been " +"delivered will now be deleted. This greatly improves the memory efficiency " +"of a long-running Flower server." msgstr "" #: ../../source/ref-changelog.md:392 msgid "" -"**Fix spilling issues related to Ray during simulations** " -"([#1698](https://github.com/adap/flower/pull/1698))" +"**Fix spilling issues related to Ray during simulations** ([#1698](https://" +"github.com/adap/flower/pull/1698))" msgstr "" #: ../../source/ref-changelog.md:394 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts" -" of data that would make the training unable to continue. This is now " -"fixed! 🎉" +"While running long simulations, `ray` was sometimes spilling huge amounts of " +"data that would make the training unable to continue. This is now fixed! 🎉" msgstr "" #: ../../source/ref-changelog.md:396 msgid "" -"**Add new example using** `TabNet` **and Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"**Add new example using** `TabNet` **and Flower** ([#1725](https://github." +"com/adap/flower/pull/1725))" msgstr "" #: ../../source/ref-changelog.md:398 msgid "" -"TabNet is a powerful and flexible framework for training machine learning" -" models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" -"/quickstart-tabnet)." +"TabNet is a powerful and flexible framework for training machine learning " +"models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples/" +"quickstart-tabnet)." msgstr "" #: ../../source/ref-changelog.md:400 msgid "" -"**Add new how-to guide for monitoring simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" +"**Add new how-to guide for monitoring simulations** ([#1649](https://github." +"com/adap/flower/pull/1649))" msgstr "" #: ../../source/ref-changelog.md:402 msgid "" -"We now have a documentation guide to help users monitor their performance" -" during simulations." +"We now have a documentation guide to help users monitor their performance " +"during simulations." msgstr "" #: ../../source/ref-changelog.md:404 msgid "" -"**Add training metrics to** `History` **object during simulations** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**Add training metrics to** `History` **object during simulations** ([#1696]" +"(https://github.com/adap/flower/pull/1696))" msgstr "" #: ../../source/ref-changelog.md:406 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training " -"metrics, but previous releases did not save the results in the `History` " -"object. This is now the case!" +"The `fit_metrics_aggregation_fn` can be used to aggregate training metrics, " +"but previous releases did not save the results in the `History` object. This " +"is now the case!" msgstr "" #: ../../source/ref-changelog.md:408 msgid "" -"**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" +"**General improvements** ([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), [#1647](https://github." +"com/adap/flower/pull/1647), [#1471](https://github.com/adap/flower/" +"pull/1471), [#1648](https://github.com/adap/flower/pull/1648), [#1651]" +"(https://github.com/adap/flower/pull/1651), [#1652](https://github.com/adap/" +"flower/pull/1652), [#1653](https://github.com/adap/flower/pull/1653), [#1659]" +"(https://github.com/adap/flower/pull/1659), [#1665](https://github.com/adap/" +"flower/pull/1665), [#1670](https://github.com/adap/flower/pull/1670), [#1672]" +"(https://github.com/adap/flower/pull/1672), [#1677](https://github.com/adap/" +"flower/pull/1677), [#1684](https://github.com/adap/flower/pull/1684), [#1683]" +"(https://github.com/adap/flower/pull/1683), [#1686](https://github.com/adap/" +"flower/pull/1686), [#1682](https://github.com/adap/flower/pull/1682), [#1685]" +"(https://github.com/adap/flower/pull/1685), [#1692](https://github.com/adap/" +"flower/pull/1692), [#1705](https://github.com/adap/flower/pull/1705), [#1708]" +"(https://github.com/adap/flower/pull/1708), [#1711](https://github.com/adap/" +"flower/pull/1711), [#1713](https://github.com/adap/flower/pull/1713), [#1714]" +"(https://github.com/adap/flower/pull/1714), [#1718](https://github.com/adap/" +"flower/pull/1718), [#1716](https://github.com/adap/flower/pull/1716), [#1723]" +"(https://github.com/adap/flower/pull/1723), [#1735](https://github.com/adap/" +"flower/pull/1735), [#1678](https://github.com/adap/flower/pull/1678), [#1750]" +"(https://github.com/adap/flower/pull/1750), [#1753](https://github.com/adap/" +"flower/pull/1753), [#1736](https://github.com/adap/flower/pull/1736), [#1766]" +"(https://github.com/adap/flower/pull/1766), [#1760](https://github.com/adap/" +"flower/pull/1760), [#1775](https://github.com/adap/flower/pull/1775), [#1776]" +"(https://github.com/adap/flower/pull/1776), [#1777](https://github.com/adap/" +"flower/pull/1777), [#1779](https://github.com/adap/flower/pull/1779), [#1784]" +"(https://github.com/adap/flower/pull/1784), [#1773](https://github.com/adap/" +"flower/pull/1773), [#1755](https://github.com/adap/flower/pull/1755), [#1789]" +"(https://github.com/adap/flower/pull/1789), [#1788](https://github.com/adap/" +"flower/pull/1788), [#1798](https://github.com/adap/flower/pull/1798), [#1799]" +"(https://github.com/adap/flower/pull/1799), [#1739](https://github.com/adap/" +"flower/pull/1739), [#1800](https://github.com/adap/flower/pull/1800), [#1804]" +"(https://github.com/adap/flower/pull/1804), [#1805](https://github.com/adap/" +"flower/pull/1805))" msgstr "" #: ../../source/ref-changelog.md:416 @@ -15219,8 +14816,8 @@ msgstr "" #: ../../source/ref-changelog.md:422 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " +"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" #: ../../source/ref-changelog.md:426 @@ -15231,24 +14828,24 @@ msgstr "" #: ../../source/ref-changelog.md:428 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be " -"used to identify which workload a task belongs to. It also supports a new" -" `group_id` that can be used, for example, to indicate the current " -"training round. Both the `workload_id` and `group_id` enable client nodes" -" to decide whether they want to handle a task or not." +"The (experimental) Driver API now supports a `workload_id` that can be used " +"to identify which workload a task belongs to. It also supports a new " +"`group_id` that can be used, for example, to indicate the current training " +"round. Both the `workload_id` and `group_id` enable client nodes to decide " +"whether they want to handle a task or not." msgstr "" #: ../../source/ref-changelog.md:430 msgid "" -"**Make Driver API and Fleet API address configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Make Driver API and Fleet API address configurable** ([#1637](https://" +"github.com/adap/flower/pull/1637))" msgstr "" #: ../../source/ref-changelog.md:432 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) " -"can now configure the server address of both Driver API (via `--driver-" -"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +"The (experimental) long-running Flower server (Driver API and Fleet API) can " +"now configure the server address of both Driver API (via `--driver-api-" +"address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" #: ../../source/ref-changelog.md:434 @@ -15263,55 +14860,51 @@ msgstr "" #: ../../source/ref-changelog.md:438 msgid "" -"**Add new example of Federated Learning using fastai and Flower** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"**Add new example of Federated Learning using fastai and Flower** ([#1598]" +"(https://github.com/adap/flower/pull/1598))" msgstr "" #: ../../source/ref-changelog.md:440 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" -"/quickstart-fastai)." +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples/" +"quickstart-fastai)." msgstr "" #: ../../source/ref-changelog.md:442 msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" -" versions of Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest " +"versions of Android** ([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" #: ../../source/ref-changelog.md:444 msgid "" -"The Android code example has received a substantial update: the project " -"is compatible with Flower 1.0 (and later), the UI received a full " -"refresh, and the project is updated to be compatible with newer Android " -"tooling." +"The Android code example has received a substantial update: the project is " +"compatible with Flower 1.0 (and later), the UI received a full refresh, and " +"the project is updated to be compatible with newer Android tooling." msgstr "" #: ../../source/ref-changelog.md:446 msgid "" -"**Add new `FedProx` strategy** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"**Add new `FedProx` strategy** ([#1619](https://github.com/adap/flower/" +"pull/1619))" msgstr "" #: ../../source/ref-changelog.md:448 msgid "" -"This " -"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" is almost identical to " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" but helps users replicate what is described in this " -"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " -"parameter called `proximal_mu` to regularize the local models with " -"respect to the global models." +"This [strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/" +"strategy/fedprox.py) is almost identical to [`FedAvg`](https://github.com/" +"adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py), but helps " +"users replicate what is described in this [paper](https://arxiv.org/" +"abs/1812.06127). It essentially adds a parameter called `proximal_mu` to " +"regularize the local models with respect to the global models." msgstr "" #: ../../source/ref-changelog.md:450 msgid "" -"**Add new metrics to telemetry events** " -"([#1640](https://github.com/adap/flower/pull/1640))" +"**Add new metrics to telemetry events** ([#1640](https://github.com/adap/" +"flower/pull/1640))" msgstr "" #: ../../source/ref-changelog.md:452 @@ -15322,87 +14915,73 @@ msgstr "" #: ../../source/ref-changelog.md:454 msgid "" -"**Add new custom strategy tutorial section** " -"[#1623](https://github.com/adap/flower/pull/1623)" +"**Add new custom strategy tutorial section** [#1623](https://github.com/adap/" +"flower/pull/1623)" msgstr "" #: ../../source/ref-changelog.md:456 msgid "" -"The Flower tutorial now has a new section that covers implementing a " -"custom strategy from scratch: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers implementing a custom " +"strategy from scratch: [Open in Colab](https://colab.research.google.com/" +"github/adap/flower/blob/main/doc/source/tutorial-build-a-strategy-from-" +"scratch-pytorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:458 msgid "" -"**Add new custom serialization tutorial section** " -"([#1622](https://github.com/adap/flower/pull/1622))" +"**Add new custom serialization tutorial section** ([#1622](https://github." +"com/adap/flower/pull/1622))" msgstr "" #: ../../source/ref-changelog.md:460 msgid "" -"The Flower tutorial now has a new section that covers custom " -"serialization: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers custom serialization: " +"[Open in Colab](https://colab.research.google.com/github/adap/flower/blob/" +"main/doc/source/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:462 msgid "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github.com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" +"**General improvements** ([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), [#1636](https://github." +"com/adap/flower/pull/1636), [#1635](https://github.com/adap/flower/" +"pull/1635), [#1633](https://github.com/adap/flower/pull/1633), [#1632]" +"(https://github.com/adap/flower/pull/1632), [#1631](https://github.com/adap/" +"flower/pull/1631), [#1630](https://github.com/adap/flower/pull/1630), [#1627]" +"(https://github.com/adap/flower/pull/1627), [#1593](https://github.com/adap/" +"flower/pull/1593), [#1616](https://github.com/adap/flower/pull/1616), [#1615]" +"(https://github.com/adap/flower/pull/1615), [#1607](https://github.com/adap/" +"flower/pull/1607), [#1609](https://github.com/adap/flower/pull/1609), [#1608]" +"(https://github.com/adap/flower/pull/1608), [#1603](https://github.com/adap/" +"flower/pull/1603), [#1590](https://github.com/adap/flower/pull/1590), [#1580]" +"(https://github.com/adap/flower/pull/1580), [#1599](https://github.com/adap/" +"flower/pull/1599), [#1600](https://github.com/adap/flower/pull/1600), [#1601]" +"(https://github.com/adap/flower/pull/1601), [#1597](https://github.com/adap/" +"flower/pull/1597), [#1595](https://github.com/adap/flower/pull/1595), [#1591]" +"(https://github.com/adap/flower/pull/1591), [#1588](https://github.com/adap/" +"flower/pull/1588), [#1589](https://github.com/adap/flower/pull/1589), [#1587]" +"(https://github.com/adap/flower/pull/1587), [#1573](https://github.com/adap/" +"flower/pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" +"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" +"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" +"(https://github.com/adap/flower/pull/1586))" msgstr "" #: ../../source/ref-changelog.md:466 msgid "" -"**Updated documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" +"**Updated documentation** ([#1629](https://github.com/adap/flower/" +"pull/1629), [#1628](https://github.com/adap/flower/pull/1628), [#1620]" +"(https://github.com/adap/flower/pull/1620), [#1618](https://github.com/adap/" +"flower/pull/1618), [#1617](https://github.com/adap/flower/pull/1617), [#1613]" +"(https://github.com/adap/flower/pull/1613), [#1614](https://github.com/adap/" +"flower/pull/1614))" msgstr "" #: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 msgid "" -"As usual, the documentation has improved quite a bit. It is another step " -"in our effort to make the Flower documentation the best documentation of " -"any project. Stay tuned and as always, feel free to provide feedback!" +"As usual, the documentation has improved quite a bit. It is another step in " +"our effort to make the Flower documentation the best documentation of any " +"project. Stay tuned and as always, feel free to provide feedback!" msgstr "" #: ../../source/ref-changelog.md:474 @@ -15411,15 +14990,14 @@ msgstr "" #: ../../source/ref-changelog.md:480 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " +"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" #: ../../source/ref-changelog.md:484 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"**Introduce new Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/" +"adap/flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" msgstr "" #: ../../source/ref-changelog.md:486 @@ -15428,207 +15006,195 @@ msgid "" "implementations useful especially to FL newcomers. They will typically " "revisit well known papers from the literature, and be suitable for " "integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in " -"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" +"deepen your knowledge of FL in general. Today's release is the first in this " +"series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-pack-" +"fedavg-mnist-cnn/)" msgstr "" #: ../../source/ref-changelog.md:488 msgid "" -"**Improve GPU support in simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" +"**Improve GPU support in simulations** ([#1555](https://github.com/adap/" +"flower/pull/1555))" msgstr "" #: ../../source/ref-changelog.md:490 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" -" to improve GPU support. The update includes some of the hard-earned " -"lessons from scaling simulations in GPU cluster environments. New " -"defaults make running GPU-based simulations substantially more robust." +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated to " +"improve GPU support. The update includes some of the hard-earned lessons " +"from scaling simulations in GPU cluster environments. New defaults make " +"running GPU-based simulations substantially more robust." msgstr "" #: ../../source/ref-changelog.md:492 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" +"**Improve GPU support in Jupyter Notebook tutorials** ([#1527](https://" +"github.com/adap/flower/pull/1527), [#1558](https://github.com/adap/flower/" +"pull/1558))" msgstr "" #: ../../source/ref-changelog.md:494 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to " -"use on GPU instances. We listened and made improvements to all of our " -"Jupyter notebooks! Check out the updated notebooks here:" +"Some users reported that Jupyter Notebooks have not always been easy to use " +"on GPU instances. We listened and made improvements to all of our Jupyter " +"notebooks! Check out the updated notebooks here:" msgstr "" #: ../../source/ref-changelog.md:496 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework" -"/tutorial-get-started-with-flower-pytorch.html)" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework/" +"tutorial-get-started-with-flower-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:497 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework" -"/tutorial-use-a-federated-learning-strategy-pytorch.html)" +"[Strategies in Federated Learning](https://flower.ai/docs/framework/tutorial-" +"use-a-federated-learning-strategy-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:498 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" -"-strategy-from-scratch-pytorch.html)" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a-" +"strategy-from-scratch-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:499 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" -"customize-the-client-pytorch.html)" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" +"the-client-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:501 msgid "" -"**Introduce optional telemetry** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" +"**Introduce optional telemetry** ([#1533](https://github.com/adap/flower/" +"pull/1533), [#1544](https://github.com/adap/flower/pull/1544), [#1584]" +"(https://github.com/adap/flower/pull/1584))" msgstr "" #: ../../source/ref-changelog.md:503 msgid "" -"After a [request for " -"feedback](https://github.com/adap/flower/issues/1534) from the community," -" the Flower open-source project introduces optional collection of " -"*anonymous* usage metrics to make well-informed decisions to improve " -"Flower. Doing this enables the Flower team to understand how Flower is " -"used and what challenges users might face." +"After a [request for feedback](https://github.com/adap/flower/issues/1534) " +"from the community, the Flower open-source project introduces optional " +"collection of *anonymous* usage metrics to make well-informed decisions to " +"improve Flower. Doing this enables the Flower team to understand how Flower " +"is used and what challenges users might face." msgstr "" #: ../../source/ref-changelog.md:505 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users who do not want to share anonymous usage metrics. " -"[Read more.](https://flower.ai/docs/telemetry.html)." +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users who do not want to share anonymous usage metrics. [Read more.]" +"(https://flower.ai/docs/telemetry.html)." msgstr "" #: ../../source/ref-changelog.md:507 msgid "" -"**Introduce (experimental) Driver API** " -"([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**Introduce (experimental) Driver API** ([#1520](https://github.com/adap/" +"flower/pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" +"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" +"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" +"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" +"flower/pull/1567))" msgstr "" #: ../../source/ref-changelog.md:509 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API" -" will be the abstraction that many upcoming features will be built on - " -"and you can start building those things now, too." +"Analytics applications. Phew, that's a lot! Going forward, the Driver API " +"will be the abstraction that many upcoming features will be built on - and " +"you can start building those things now, too." msgstr "" #: ../../source/ref-changelog.md:511 msgid "" -"The Driver API also enables a new execution mode in which the server runs" -" indefinitely. Multiple individual workloads can run concurrently and " -"start and stop their execution independent of the server. This is " -"especially useful for users who want to deploy Flower in production." +"The Driver API also enables a new execution mode in which the server runs " +"indefinitely. Multiple individual workloads can run concurrently and start " +"and stop their execution independent of the server. This is especially " +"useful for users who want to deploy Flower in production." msgstr "" #: ../../source/ref-changelog.md:513 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward " -"to you feedback!" +"To learn more, check out the `mt-pytorch` code example. We look forward to " +"you feedback!" msgstr "" #: ../../source/ref-changelog.md:515 msgid "" -"Please note: *The Driver API is still experimental and will likely change" -" significantly over time.*" +"Please note: *The Driver API is still experimental and will likely change " +"significantly over time.*" msgstr "" #: ../../source/ref-changelog.md:517 msgid "" -"**Add new Federated Analytics with Pandas example** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"**Add new Federated Analytics with Pandas example** ([#1469](https://github." +"com/adap/flower/pull/1469), [#1535](https://github.com/adap/flower/" +"pull/1535))" msgstr "" #: ../../source/ref-changelog.md:519 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics" -" with Pandas and Flower. You can find it here: [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." +"A new code example (`quickstart-pandas`) demonstrates federated analytics " +"with Pandas and Flower. You can find it here: [quickstart-pandas](https://" +"github.com/adap/flower/tree/main/examples/quickstart-pandas)." msgstr "" #: ../../source/ref-changelog.md:521 msgid "" -"**Add new strategies: Krum and MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"**Add new strategies: Krum and MultiKrum** ([#1481](https://github.com/adap/" +"flower/pull/1481))" msgstr "" #: ../../source/ref-changelog.md:523 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum " -"and MultiKrum in their workloads." +"contributed a new `Krum` strategy that enables users to easily use Krum and " +"MultiKrum in their workloads." msgstr "" #: ../../source/ref-changelog.md:525 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"**Update C++ example to be compatible with Flower v1.2.0** ([#1495](https://" +"github.com/adap/flower/pull/1495))" msgstr "" #: ../../source/ref-changelog.md:527 msgid "" -"The C++ code example has received a substantial update to make it " -"compatible with the latest version of Flower." +"The C++ code example has received a substantial update to make it compatible " +"with the latest version of Flower." msgstr "" #: ../../source/ref-changelog.md:529 msgid "" -"**General improvements** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**General improvements** ([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), [#1506](https://github." +"com/adap/flower/pull/1506), [#1514](https://github.com/adap/flower/" +"pull/1514), [#1522](https://github.com/adap/flower/pull/1522), [#1523]" +"(https://github.com/adap/flower/pull/1523), [#1526](https://github.com/adap/" +"flower/pull/1526), [#1528](https://github.com/adap/flower/pull/1528), [#1547]" +"(https://github.com/adap/flower/pull/1547), [#1549](https://github.com/adap/" +"flower/pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" +"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" +"flower/pull/1566))" msgstr "" #: ../../source/ref-changelog.md:533 msgid "" -"**Updated documentation** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" +"**Updated documentation** ([#1494](https://github.com/adap/flower/" +"pull/1494), [#1496](https://github.com/adap/flower/pull/1496), [#1500]" +"(https://github.com/adap/flower/pull/1500), [#1503](https://github.com/adap/" +"flower/pull/1503), [#1505](https://github.com/adap/flower/pull/1505), [#1524]" +"(https://github.com/adap/flower/pull/1524), [#1518](https://github.com/adap/" +"flower/pull/1518), [#1519](https://github.com/adap/flower/pull/1519), [#1515]" +"(https://github.com/adap/flower/pull/1515))" msgstr "" #: ../../source/ref-changelog.md:537 msgid "" -"One highlight is the new [first time contributor " -"guide](https://flower.ai/docs/first-time-contributors.html): if you've " -"never contributed on GitHub before, this is the perfect place to start!" +"One highlight is the new [first time contributor guide](https://flower.ai/" +"docs/first-time-contributors.html): if you've never contributed on GitHub " +"before, this is the perfect place to start!" msgstr "" #: ../../source/ref-changelog.md:543 @@ -15645,110 +15211,106 @@ msgstr "" msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " +"`edogab33`" msgstr "" #: ../../source/ref-changelog.md:553 msgid "" -"**Introduce Differential Privacy wrappers (preview)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"**Introduce Differential Privacy wrappers (preview)** ([#1357](https://" +"github.com/adap/flower/pull/1357), [#1460](https://github.com/adap/flower/" +"pull/1460))" msgstr "" #: ../../source/ref-changelog.md:555 msgid "" -"The first (experimental) preview of pluggable Differential Privacy " -"wrappers enables easy configuration and usage of differential privacy " -"(DP). The pluggable DP wrappers enable framework-agnostic **and** " -"strategy-agnostic usage of both client-side DP and server-side DP. Head " -"over to the Flower docs, a new explainer goes into more detail." +"The first (experimental) preview of pluggable Differential Privacy wrappers " +"enables easy configuration and usage of differential privacy (DP). The " +"pluggable DP wrappers enable framework-agnostic **and** strategy-agnostic " +"usage of both client-side DP and server-side DP. Head over to the Flower " +"docs, a new explainer goes into more detail." msgstr "" #: ../../source/ref-changelog.md:557 msgid "" -"**New iOS CoreML code example** " -"([#1289](https://github.com/adap/flower/pull/1289))" +"**New iOS CoreML code example** ([#1289](https://github.com/adap/flower/" +"pull/1289))" msgstr "" #: ../../source/ref-changelog.md:559 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can " -"be built for iOS. The code example contains both Flower iOS SDK " -"components that can be used for many tasks, and one task example running " -"on CoreML." +"Flower goes iOS! A massive new code example shows how Flower clients can be " +"built for iOS. The code example contains both Flower iOS SDK components that " +"can be used for many tasks, and one task example running on CoreML." msgstr "" #: ../../source/ref-changelog.md:561 msgid "" -"**New FedMedian strategy** " -"([#1461](https://github.com/adap/flower/pull/1461))" +"**New FedMedian strategy** ([#1461](https://github.com/adap/flower/" +"pull/1461))" msgstr "" #: ../../source/ref-changelog.md:563 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by " -"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"The new `FedMedian` strategy implements Federated Median (FedMedian) by [Yin " +"et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" #: ../../source/ref-changelog.md:565 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** " -"([#1493](https://github.com/adap/flower/pull/1493))" +"**Log** `Client` **exceptions in Virtual Client Engine** ([#1493](https://" +"github.com/adap/flower/pull/1493))" msgstr "" #: ../../source/ref-changelog.md:567 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default " -"and not just exposed to the configured `Strategy` (via the `failures` " -"argument)." +"All `Client` exceptions happening in the VCE are now logged by default and " +"not just exposed to the configured `Strategy` (via the `failures` argument)." msgstr "" #: ../../source/ref-changelog.md:569 msgid "" -"**Improve Virtual Client Engine internals** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" +"**Improve Virtual Client Engine internals** ([#1401](https://github.com/adap/" +"flower/pull/1401), [#1453](https://github.com/adap/flower/pull/1453))" msgstr "" #: ../../source/ref-changelog.md:571 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE " -"now uses Ray 2.0 under the hood, the value type of the `client_resources`" -" dictionary changed to `float` to allow fractions of resources to be " +"Some internals of the Virtual Client Engine have been revamped. The VCE now " +"uses Ray 2.0 under the hood, the value type of the `client_resources` " +"dictionary changed to `float` to allow fractions of resources to be " "allocated." msgstr "" #: ../../source/ref-changelog.md:573 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual Client " +"Engine**" msgstr "" #: ../../source/ref-changelog.md:575 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and" -" `NumPyClient`) methods." +"The Virtual Client Engine now has full support for optional `Client` (and " +"`NumPyClient`) methods." msgstr "" #: ../../source/ref-changelog.md:577 msgid "" -"**Provide type information to packages using** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"**Provide type information to packages using** `flwr` ([#1377](https://" +"github.com/adap/flower/pull/1377))" msgstr "" #: ../../source/ref-changelog.md:579 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that " -"the package is typed. This enables typing support for projects or " -"packages that use `flwr` by enabling them to improve their code using " -"static type checkers like `mypy`." +"The package `flwr` is now bundled with a `py.typed` file indicating that the " +"package is typed. This enables typing support for projects or packages that " +"use `flwr` by enabling them to improve their code using static type checkers " +"like `mypy`." msgstr "" #: ../../source/ref-changelog.md:581 msgid "" -"**Updated code example** " -"([#1344](https://github.com/adap/flower/pull/1344), " +"**Updated code example** ([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" @@ -15760,24 +15322,18 @@ msgstr "" #: ../../source/ref-changelog.md:585 msgid "" -"**Updated documentation** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +"**Updated documentation** ([#1355](https://github.com/adap/flower/" +"pull/1355), [#1558](https://github.com/adap/flower/pull/1558), [#1379]" +"(https://github.com/adap/flower/pull/1379), [#1380](https://github.com/adap/" +"flower/pull/1380), [#1381](https://github.com/adap/flower/pull/1381), [#1332]" +"(https://github.com/adap/flower/pull/1332), [#1391](https://github.com/adap/" +"flower/pull/1391), [#1403](https://github.com/adap/flower/pull/1403), [#1364]" +"(https://github.com/adap/flower/pull/1364), [#1409](https://github.com/adap/" +"flower/pull/1409), [#1419](https://github.com/adap/flower/pull/1419), [#1444]" +"(https://github.com/adap/flower/pull/1444), [#1448](https://github.com/adap/" +"flower/pull/1448), [#1417](https://github.com/adap/flower/pull/1417), [#1449]" +"(https://github.com/adap/flower/pull/1449), [#1465](https://github.com/adap/" +"flower/pull/1465), [#1467](https://github.com/adap/flower/pull/1467))" msgstr "" #: ../../source/ref-changelog.md:587 @@ -15788,47 +15344,45 @@ msgstr "" #: ../../source/ref-changelog.md:589 msgid "" -"**Restructured documentation** " -"([#1387](https://github.com/adap/flower/pull/1387))" +"**Restructured documentation** ([#1387](https://github.com/adap/flower/" +"pull/1387))" msgstr "" #: ../../source/ref-changelog.md:591 msgid "" -"The documentation has been restructured to make it easier to navigate. " -"This is just the first step in a larger effort to make the Flower " -"documentation the best documentation of any project ever. Stay tuned!" +"The documentation has been restructured to make it easier to navigate. This " +"is just the first step in a larger effort to make the Flower documentation " +"the best documentation of any project ever. Stay tuned!" msgstr "" #: ../../source/ref-changelog.md:593 msgid "" -"**Open in Colab button** " -"([#1389](https://github.com/adap/flower/pull/1389))" +"**Open in Colab button** ([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" #: ../../source/ref-changelog.md:595 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a " -"new `Open in Colab` button. No need to install anything on your local " -"machine, you can now use and learn about Flower in your browser, it's " -"only a single click away." +"The four parts of the Flower Federated Learning Tutorial now come with a new " +"`Open in Colab` button. No need to install anything on your local machine, " +"you can now use and learn about Flower in your browser, it's only a single " +"click away." msgstr "" #: ../../source/ref-changelog.md:597 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), [#1472](https://github." +"com/adap/flower/pull/1472), [#1473](https://github.com/adap/flower/" +"pull/1473), [#1474](https://github.com/adap/flower/pull/1474), [#1475]" +"(https://github.com/adap/flower/pull/1475))" msgstr "" #: ../../source/ref-changelog.md:599 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved " -"(many small changes and fixes)." +"`NumPyClient`. The existing parts one and two have also been improved (many " +"small changes and fixes)." msgstr "" #: ../../source/ref-changelog.md:605 @@ -15853,93 +15407,79 @@ msgstr "" #: ../../source/ref-changelog.md:612 msgid "" -"Tons of small API cleanups resulting in a more coherent developer " -"experience" +"Tons of small API cleanups resulting in a more coherent developer experience" msgstr "" #: ../../source/ref-changelog.md:616 msgid "" "We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +"made Flower 1.0 possible (in reverse [GitHub Contributors](https://github." +"com/adap/flower/graphs/contributors) order):" msgstr "" #: ../../source/ref-changelog.md:618 msgid "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." +"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" +"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" +"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" +"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." +"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" +"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." +"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." +"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" +"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" +"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" +"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" +"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" +"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." +"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" +"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" +"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" +"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" +"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" +"tanertopal), [@danieljanes](https://github.com/danieljanes)." msgstr "" #: ../../source/ref-changelog.md:622 msgid "" -"**All arguments must be passed as keyword arguments** " -"([#1338](https://github.com/adap/flower/pull/1338))" +"**All arguments must be passed as keyword arguments** ([#1338](https://" +"github.com/adap/flower/pull/1338))" msgstr "" #: ../../source/ref-changelog.md:624 msgid "" -"Pass all arguments as keyword arguments, positional arguments are not " -"longer supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " -"for each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"Pass all arguments as keyword arguments, positional arguments are not longer " +"supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword for " +"each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())`)." msgstr "" #: ../../source/ref-changelog.md:626 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" +"**and** `start_simulation` ([#1317](https://github.com/adap/flower/" +"pull/1317))" msgstr "" #: ../../source/ref-changelog.md:628 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " -"600.0}`, `start_server` and `start_simulation` now expect a configuration" -" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" -" arguments that as the previous config dict, but it makes writing type-" -"safe code easier and the default parameters values more transparent." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": 600.0}" +"`, `start_server` and `start_simulation` now expect a configuration object " +"of type `flwr.server.ServerConfig`. `ServerConfig` takes the same arguments " +"that as the previous config dict, but it makes writing type-safe code easier " +"and the default parameters values more transparent." msgstr "" #: ../../source/ref-changelog.md:630 msgid "" -"**Rename built-in strategy parameters for clarity** " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Rename built-in strategy parameters for clarity** ([#1334](https://github." +"com/adap/flower/pull/1334))" msgstr "" #: ../../source/ref-changelog.md:632 @@ -15962,17 +15502,17 @@ msgstr "" #: ../../source/ref-changelog.md:638 msgid "" -"**Update default arguments of built-in strategies** " -"([#1278](https://github.com/adap/flower/pull/1278))" +"**Update default arguments of built-in strategies** ([#1278](https://github." +"com/adap/flower/pull/1278))" msgstr "" #: ../../source/ref-changelog.md:640 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently " -"available clients for training and evaluation. Projects that relied on " -"the previous default values can get the previous behaviour by " -"initializing the strategy in the following way:" +"`fraction_evaluate=1.0`, which means they select *all* currently available " +"clients for training and evaluation. Projects that relied on the previous " +"default values can get the previous behaviour by initializing the strategy " +"in the following way:" msgstr "" #: ../../source/ref-changelog.md:642 @@ -15981,14 +15521,14 @@ msgstr "" #: ../../source/ref-changelog.md:644 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Add** `server_round` **to** `Strategy.evaluate` ([#1334](https://github." +"com/adap/flower/pull/1334))" msgstr "" #: ../../source/ref-changelog.md:646 msgid "" -"The `Strategy` method `evaluate` now receives the current round of " -"federated learning/evaluation as the first parameter." +"The `Strategy` method `evaluate` now receives the current round of federated " +"learning/evaluation as the first parameter." msgstr "" #: ../../source/ref-changelog.md:648 @@ -16001,39 +15541,40 @@ msgstr "" msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), " -"and (3) a config dictionary (`config`)." +"(`server_round`), (2) the model parameters to evaluate (`parameters`), and " +"(3) a config dictionary (`config`)." msgstr "" #: ../../source/ref-changelog.md:652 msgid "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**Rename** `rnd` **to** `server_round` ([#1321](https://github.com/adap/" +"flower/pull/1321))" msgstr "" #: ../../source/ref-changelog.md:654 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. " -"To improve reaability and avoid confusion with *random*, this parameter " -"has been renamed from `rnd` to `server_round`." +"current round of federated learning/evaluation as their first parameter. To " +"improve reaability and avoid confusion with *random*, this parameter has " +"been renamed from `rnd` to `server_round`." msgstr "" #: ../../source/ref-changelog.md:656 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"**Move** `flwr.dataset` **to** `flwr_baselines` ([#1273](https://github.com/" +"adap/flower/pull/1273))" msgstr "" #: ../../source/ref-changelog.md:658 -msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." +msgid "" +"The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "" #: ../../source/ref-changelog.md:660 msgid "" -"**Remove experimental strategies** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Remove experimental strategies** ([#1280](https://github.com/adap/flower/" +"pull/1280))" msgstr "" #: ../../source/ref-changelog.md:662 @@ -16044,9 +15585,8 @@ msgstr "" #: ../../source/ref-changelog.md:664 msgid "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Rename** `Weights` **to** `NDArrays` ([#1258](https://github.com/adap/" +"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" msgstr "" #: ../../source/ref-changelog.md:666 @@ -16057,21 +15597,21 @@ msgstr "" #: ../../source/ref-changelog.md:668 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Remove antiquated** `force_final_distributed_eval` **from** `start_server` " +"([#1258](https://github.com/adap/flower/pull/1258), [#1259](https://github." +"com/adap/flower/pull/1259))" msgstr "" #: ../../source/ref-changelog.md:670 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been" -" a historic artefact, in this release it is finally gone for good." +"The `start_server` parameter `force_final_distributed_eval` has long been a " +"historic artefact, in this release it is finally gone for good." msgstr "" #: ../../source/ref-changelog.md:672 msgid "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Make** `get_parameters` **configurable** ([#1242](https://github.com/adap/" +"flower/pull/1242))" msgstr "" #: ../../source/ref-changelog.md:674 @@ -16089,64 +15629,62 @@ msgstr "" #: ../../source/ref-changelog.md:678 msgid "" "The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the " -"consistency between `start_simulation` and `start_server` and makes " -"transitioning between the two easier." +"`config` instead of the `num_rounds` integer. This improves the consistency " +"between `start_simulation` and `start_server` and makes transitioning " +"between the two easier." msgstr "" #: ../../source/ref-changelog.md:682 msgid "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" #: ../../source/ref-changelog.md:684 msgid "" -"The previous Flower release introduced experimental support for Python " -"3.10, this release declares Python 3.10 support as stable." +"The previous Flower release introduced experimental support for Python 3.10, " +"this release declares Python 3.10 support as stable." msgstr "" #: ../../source/ref-changelog.md:686 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** ([#1260]" +"(https://github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/" +"flower/pull/1277))" msgstr "" #: ../../source/ref-changelog.md:688 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that" -" implement, for example, only `fit`, but no other method. No need to " +"`fit`, and `evaluate` are all optional. This enables writing clients that " +"implement, for example, only `fit`, but no other method. No need to " "implement `evaluate` when using centralized evaluation!" msgstr "" #: ../../source/ref-changelog.md:690 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**Enable passing a** `Server` **instance to** `start_simulation` ([#1281]" +"(https://github.com/adap/flower/pull/1281))" msgstr "" #: ../../source/ref-changelog.md:692 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server`" -" instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the" -" Virtual Client Engine." +"Similar to `start_server`, `start_simulation` now accepts a full `Server` " +"instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the " +"Virtual Client Engine." msgstr "" #: ../../source/ref-changelog.md:694 msgid "" -"**Update code examples** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**Update code examples** ([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), [#1282](https://github." +"com/adap/flower/pull/1282))" msgstr "" #: ../../source/ref-changelog.md:696 msgid "" -"Many code examples received small or even large maintenance updates, " -"among them are" +"Many code examples received small or even large maintenance updates, among " +"them are" msgstr "" #: ../../source/ref-changelog.md:698 @@ -16175,8 +15713,8 @@ msgstr "" #: ../../source/ref-changelog.md:705 msgid "" -"**Remove the obsolete simulation example** " -"([#1328](https://github.com/adap/flower/pull/1328))" +"**Remove the obsolete simulation example** ([#1328](https://github.com/adap/" +"flower/pull/1328))" msgstr "" #: ../../source/ref-changelog.md:707 @@ -16188,27 +15726,24 @@ msgstr "" #: ../../source/ref-changelog.md:709 msgid "" -"**Update documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"**Update documentation** ([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), [#1251](https://github." +"com/adap/flower/pull/1251), [#1257](https://github.com/adap/flower/" +"pull/1257), [#1267](https://github.com/adap/flower/pull/1267), [#1268]" +"(https://github.com/adap/flower/pull/1268), [#1300](https://github.com/adap/" +"flower/pull/1300), [#1304](https://github.com/adap/flower/pull/1304), [#1305]" +"(https://github.com/adap/flower/pull/1305), [#1307](https://github.com/adap/" +"flower/pull/1307))" msgstr "" #: ../../source/ref-changelog.md:711 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the " -"`flwr.common` module in the API reference, includes support for markdown-" -"based documentation, migrates the changelog from `.rst` to `.md`, and " -"fixes a number of smaller details!" +"deprecated library, updates documentation dependencies, includes the `flwr." +"common` module in the API reference, includes support for markdown-based " +"documentation, migrates the changelog from `.rst` to `.md`, and fixes a " +"number of smaller details!" msgstr "" #: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 @@ -16218,30 +15753,28 @@ msgstr "" #: ../../source/ref-changelog.md:715 msgid "" -"Add round number to fit and evaluate log messages " -"([#1266](https://github.com/adap/flower/pull/1266))" +"Add round number to fit and evaluate log messages ([#1266](https://github." +"com/adap/flower/pull/1266))" msgstr "" #: ../../source/ref-changelog.md:716 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example " -"([#847](https://github.com/adap/flower/pull/847))" +"Add secure gRPC connection to the `advanced_tensorflow` code example ([#847]" +"(https://github.com/adap/flower/pull/847))" msgstr "" #: ../../source/ref-changelog.md:717 msgid "" -"Update developer tooling " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"Update developer tooling ([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), [#1301](https://github." +"com/adap/flower/pull/1301), [#1310](https://github.com/adap/flower/" +"pull/1310))" msgstr "" #: ../../source/ref-changelog.md:718 msgid "" -"Rename ProtoBuf messages to improve consistency " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " +"Rename ProtoBuf messages to improve consistency ([#1214](https://github.com/" +"adap/flower/pull/1214), [#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" @@ -16251,123 +15784,120 @@ msgstr "" #: ../../source/ref-changelog.md:724 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** ([#919](https://" +"github.com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" +"pull/1127), [#914](https://github.com/adap/flower/pull/914))" msgstr "" #: ../../source/ref-changelog.md:726 msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " -"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " -"With this first preview release we're also inviting the community to " -"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" -"contribute-baselines.html)." +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how to " +"use [Flower Baselines](https://flower.ai/docs/using-baselines.html). With " +"this first preview release we're also inviting the community to [contribute " +"their own baselines](https://flower.ai/docs/baselines/how-to-contribute-" +"baselines.html)." msgstr "" #: ../../source/ref-changelog.md:728 msgid "" -"**C++ client SDK (preview) and code example** " -"([#1111](https://github.com/adap/flower/pull/1111))" +"**C++ client SDK (preview) and code example** ([#1111](https://github.com/" +"adap/flower/pull/1111))" msgstr "" #: ../../source/ref-changelog.md:730 msgid "" -"Preview support for Flower clients written in C++. The C++ preview " -"includes a Flower client SDK and a quickstart code example that " -"demonstrates a simple C++ client using the SDK." +"Preview support for Flower clients written in C++. The C++ preview includes " +"a Flower client SDK and a quickstart code example that demonstrates a simple " +"C++ client using the SDK." msgstr "" #: ../../source/ref-changelog.md:732 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"**Add experimental support for Python 3.10 and Python 3.11** ([#1135]" +"(https://github.com/adap/flower/pull/1135))" msgstr "" #: ../../source/ref-changelog.md:734 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due" -" to be released in October. This Flower release adds experimental support" -" for both Python versions." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due to " +"be released in October. This Flower release adds experimental support for " +"both Python versions." msgstr "" #: ../../source/ref-changelog.md:736 msgid "" -"**Aggregate custom metrics through user-provided functions** " -"([#1144](https://github.com/adap/flower/pull/1144))" +"**Aggregate custom metrics through user-provided functions** ([#1144]" +"(https://github.com/adap/flower/pull/1144))" msgstr "" #: ../../source/ref-changelog.md:738 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" -" customize the strategy. Built-in strategies support two new arguments, " +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to " +"customize the strategy. Built-in strategies support two new arguments, " "`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " "allow passing custom metric aggregation functions." msgstr "" #: ../../source/ref-changelog.md:740 msgid "" -"**User-configurable round timeout** " -"([#1162](https://github.com/adap/flower/pull/1162))" +"**User-configurable round timeout** ([#1162](https://github.com/adap/flower/" +"pull/1162))" msgstr "" #: ../../source/ref-changelog.md:742 msgid "" "A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary " -"contains a `round_timeout` key (with a `float` value in seconds), the " -"server will wait *at least* `round_timeout` seconds before it closes the " -"connection." +"`start_server` and `start_simulation`. If the `config` dictionary contains a " +"`round_timeout` key (with a `float` value in seconds), the server will wait " +"*at least* `round_timeout` seconds before it closes the connection." msgstr "" #: ../../source/ref-changelog.md:744 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used " -"at the same time in all built-in strategies** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"**Enable both federated evaluation and centralized evaluation to be used at " +"the same time in all built-in strategies** ([#1091](https://github.com/adap/" +"flower/pull/1091))" msgstr "" #: ../../source/ref-changelog.md:746 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., " -"client-side) and centralized evaluation (i.e., server-side) in the same " -"round. Federated evaluation can be disabled by setting `fraction_eval` to" -" `0.0`." +"Built-in strategies can now perform both federated evaluation (i.e., client-" +"side) and centralized evaluation (i.e., server-side) in the same round. " +"Federated evaluation can be disabled by setting `fraction_eval` to `0.0`." msgstr "" #: ../../source/ref-changelog.md:748 msgid "" -"**Two new Jupyter Notebook tutorials** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"**Two new Jupyter Notebook tutorials** ([#1141](https://github.com/adap/" +"flower/pull/1141))" msgstr "" #: ../../source/ref-changelog.md:750 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " -"basic and intermediate Flower features:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain basic " +"and intermediate Flower features:" msgstr "" #: ../../source/ref-changelog.md:752 msgid "" -"*An Introduction to Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"*An Introduction to Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-1-Intro-to-" +"FL-PyTorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:754 msgid "" -"*Using Strategies in Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"*Using Strategies in Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-2-" +"Strategies-in-FL-PyTorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:756 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** ([#1076]" +"(https://github.com/adap/flower/pull/1076))" msgstr "" #: ../../source/ref-changelog.md:758 @@ -16378,8 +15908,8 @@ msgstr "" #: ../../source/ref-changelog.md:760 msgid "" -"**New advanced PyTorch code example** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"**New advanced PyTorch code example** ([#1007](https://github.com/adap/" +"flower/pull/1007))" msgstr "" #: ../../source/ref-changelog.md:762 @@ -16390,8 +15920,7 @@ msgstr "" #: ../../source/ref-changelog.md:764 msgid "" -"**New JAX code example** " -"([#906](https://github.com/adap/flower/pull/906), " +"**New JAX code example** ([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" @@ -16415,41 +15944,40 @@ msgstr "" #: ../../source/ref-changelog.md:772 msgid "" -"New documentation for [implementing " -"strategies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"New documentation for [implementing strategies](https://flower.ai/docs/" +"framework/how-to-implement-strategies.html) ([#1097](https://github.com/adap/" +"flower/pull/1097), [#1175](https://github.com/adap/flower/pull/1175))" msgstr "" #: ../../source/ref-changelog.md:773 msgid "" -"New mobile-friendly documentation theme " -"([#1174](https://github.com/adap/flower/pull/1174))" +"New mobile-friendly documentation theme ([#1174](https://github.com/adap/" +"flower/pull/1174))" msgstr "" #: ../../source/ref-changelog.md:774 msgid "" "Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"compatible releases (`>=1.9.2,<1.12.0`) ([#1205](https://github.com/adap/" +"flower/pull/1205))" msgstr "" #: ../../source/ref-changelog.md:778 msgid "" -"**Remove deprecated support for Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" +"**Remove deprecated support for Python 3.6** ([#871](https://github.com/adap/" +"flower/pull/871))" msgstr "" #: ../../source/ref-changelog.md:779 msgid "" -"**Remove deprecated KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" +"**Remove deprecated KerasClient** ([#857](https://github.com/adap/flower/" +"pull/857))" msgstr "" #: ../../source/ref-changelog.md:780 msgid "" -"**Remove deprecated no-op extra installs** " -"([#973](https://github.com/adap/flower/pull/973))" +"**Remove deprecated no-op extra installs** ([#973](https://github.com/adap/" +"flower/pull/973))" msgstr "" #: ../../source/ref-changelog.md:781 @@ -16460,20 +15988,20 @@ msgstr "" #: ../../source/ref-changelog.md:782 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** ([#1107]" +"(https://github.com/adap/flower/pull/1107))" msgstr "" #: ../../source/ref-changelog.md:783 msgid "" -"**Remove deprecated DefaultStrategy strategy** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated DefaultStrategy strategy** ([#1142](https://github.com/" +"adap/flower/pull/1142))" msgstr "" #: ../../source/ref-changelog.md:784 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated support for eval_fn accuracy return value** ([#1142]" +"(https://github.com/adap/flower/pull/1142))" msgstr "" #: ../../source/ref-changelog.md:785 @@ -16489,156 +16017,152 @@ msgstr "" #: ../../source/ref-changelog.md:791 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), [#872]" +"(https://github.com/adap/flower/pull/872), [#833](https://github.com/adap/" +"flower/pull/833), [#1036](https://github.com/adap/flower/pull/1036))" msgstr "" #: ../../source/ref-changelog.md:793 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) " -"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"Simulations (using the Virtual Client Engine through `start_simulation`) now " +"work more smoothly on Jupyter Notebooks (incl. Google Colab) after " "installing Flower with the `simulation` extra (`pip install " "flwr[simulation]`)." msgstr "" #: ../../source/ref-changelog.md:795 msgid "" -"**New Jupyter Notebook code example** " -"([#833](https://github.com/adap/flower/pull/833))" +"**New Jupyter Notebook code example** ([#833](https://github.com/adap/flower/" +"pull/833))" msgstr "" #: ../../source/ref-changelog.md:797 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower " -"simulations using the Virtual Client Engine through Jupyter Notebook " -"(incl. Google Colab)." +"A new code example (`quickstart_simulation`) demonstrates Flower simulations " +"using the Virtual Client Engine through Jupyter Notebook (incl. Google " +"Colab)." msgstr "" #: ../../source/ref-changelog.md:799 msgid "" -"**Client properties (feature preview)** " -"([#795](https://github.com/adap/flower/pull/795))" +"**Client properties (feature preview)** ([#795](https://github.com/adap/" +"flower/pull/795))" msgstr "" #: ../../source/ref-changelog.md:801 msgid "" -"Clients can implement a new method `get_properties` to enable server-side" -" strategies to query client properties." +"Clients can implement a new method `get_properties` to enable server-side " +"strategies to query client properties." msgstr "" #: ../../source/ref-changelog.md:803 msgid "" -"**Experimental Android support with TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" +"**Experimental Android support with TFLite** ([#865](https://github.com/adap/" +"flower/pull/865))" msgstr "" #: ../../source/ref-changelog.md:805 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has " -"become a lot easier." +"client platforms and with this release, using Flower on Android has become a " +"lot easier." msgstr "" #: ../../source/ref-changelog.md:807 msgid "" -"The example uses TFLite on the client side, along with a new " -"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " -"still experimental, but they are a first step towards a fully-fledged " -"Android SDK and a unified `FedAvg` implementation that integrated the new" -" functionality from `FedAvgAndroid`." +"The example uses TFLite on the client side, along with a new `FedAvgAndroid` " +"strategy. The Android client and `FedAvgAndroid` are still experimental, but " +"they are a first step towards a fully-fledged Android SDK and a unified " +"`FedAvg` implementation that integrated the new functionality from " +"`FedAvgAndroid`." msgstr "" #: ../../source/ref-changelog.md:809 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default " -"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" +"**Make gRPC keepalive time user-configurable and decrease default keepalive " +"time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" #: ../../source/ref-changelog.md:811 msgid "" "The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, " -"Microsoft Azure). Users can configure the keepalive time to customize the" -" gRPC stack based on specific requirements." +"compatibility of Flower with more cloud environments (for example, Microsoft " +"Azure). Users can configure the keepalive time to customize the gRPC stack " +"based on specific requirements." msgstr "" #: ../../source/ref-changelog.md:813 msgid "" -"**New differential privacy example using Opacus and PyTorch** " -"([#805](https://github.com/adap/flower/pull/805))" +"**New differential privacy example using Opacus and PyTorch** ([#805]" +"(https://github.com/adap/flower/pull/805))" msgstr "" #: ../../source/ref-changelog.md:815 msgid "" -"A new code example (`opacus`) demonstrates differentially-private " -"federated learning with Opacus, PyTorch, and Flower." +"A new code example (`opacus`) demonstrates differentially-private federated " +"learning with Opacus, PyTorch, and Flower." msgstr "" #: ../../source/ref-changelog.md:817 msgid "" -"**New Hugging Face Transformers code example** " -"([#863](https://github.com/adap/flower/pull/863))" +"**New Hugging Face Transformers code example** ([#863](https://github.com/" +"adap/flower/pull/863))" msgstr "" #: ../../source/ref-changelog.md:819 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of " -"Hugging Face Transformers with Flower." +"A new code example (`quickstart_huggingface`) demonstrates usage of Hugging " +"Face Transformers with Flower." msgstr "" #: ../../source/ref-changelog.md:821 msgid "" -"**New MLCube code example** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"**New MLCube code example** ([#779](https://github.com/adap/flower/" +"pull/779), [#1034](https://github.com/adap/flower/pull/1034), [#1065]" +"(https://github.com/adap/flower/pull/1065), [#1090](https://github.com/adap/" +"flower/pull/1090))" msgstr "" #: ../../source/ref-changelog.md:823 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " -"with Flower." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube with " +"Flower." msgstr "" #: ../../source/ref-changelog.md:825 msgid "" -"**SSL-enabled server and client** " -"([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"**SSL-enabled server and client** ([#842](https://github.com/adap/flower/" +"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" +"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" +"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" +"github.com/adap/flower/pull/994))" msgstr "" #: ../../source/ref-changelog.md:827 msgid "" -"SSL enables secure encrypted connections between clients and servers. " -"This release open-sources the Flower secure gRPC implementation to make " -"encrypted communication channels accessible to all Flower users." +"SSL enables secure encrypted connections between clients and servers. This " +"release open-sources the Flower secure gRPC implementation to make encrypted " +"communication channels accessible to all Flower users." msgstr "" #: ../../source/ref-changelog.md:829 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** ([#885](https://" +"github.com/adap/flower/pull/885), [#895](https://github.com/adap/flower/" +"pull/895))" msgstr "" #: ../../source/ref-changelog.md:831 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive " -"Federated Optimization paper." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive Federated " +"Optimization paper." msgstr "" #: ../../source/ref-changelog.md:833 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** " -"([#860](https://github.com/adap/flower/pull/860))" +"**Initialize** `start_simulation` **with a list of client IDs** ([#860]" +"(https://github.com/adap/flower/pull/860))" msgstr "" #: ../../source/ref-changelog.md:835 @@ -16652,38 +16176,38 @@ msgstr "" #: ../../source/ref-changelog.md:839 msgid "" -"Update `num_examples` calculation in PyTorch code examples in " -"([#909](https://github.com/adap/flower/pull/909))" +"Update `num_examples` calculation in PyTorch code examples in ([#909]" +"(https://github.com/adap/flower/pull/909))" msgstr "" #: ../../source/ref-changelog.md:840 msgid "" -"Expose Flower version through `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"Expose Flower version through `flwr.__version__` ([#952](https://github.com/" +"adap/flower/pull/952))" msgstr "" #: ../../source/ref-changelog.md:841 msgid "" -"`start_server` in `app.py` now returns a `History` object containing " -"metrics from training ([#974](https://github.com/adap/flower/pull/974))" +"`start_server` in `app.py` now returns a `History` object containing metrics " +"from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" #: ../../source/ref-changelog.md:842 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable ([#978]" +"(https://github.com/adap/flower/pull/978))" msgstr "" #: ../../source/ref-changelog.md:843 msgid "" -"Increase sleep time after server start to three seconds in all code " -"examples ([#1086](https://github.com/adap/flower/pull/1086))" +"Increase sleep time after server start to three seconds in all code examples " +"([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" #: ../../source/ref-changelog.md:844 msgid "" -"Added a new FAQ section to the documentation " -"([#948](https://github.com/adap/flower/pull/948))" +"Added a new FAQ section to the documentation ([#948](https://github.com/adap/" +"flower/pull/948))" msgstr "" #: ../../source/ref-changelog.md:845 @@ -16703,8 +16227,8 @@ msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " "builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " -"an upcoming release." +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in an " +"upcoming release." msgstr "" #: ../../source/ref-changelog.md:853 @@ -16713,34 +16237,32 @@ msgstr "" #: ../../source/ref-changelog.md:857 msgid "" -"**Experimental virtual client engine** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"**Experimental virtual client engine** ([#781](https://github.com/adap/" +"flower/pull/781) [#790](https://github.com/adap/flower/pull/790) [#791]" +"(https://github.com/adap/flower/pull/791))" msgstr "" #: ../../source/ref-changelog.md:859 msgid "" -"One of Flower's goals is to enable research at scale. This release " -"enables a first (experimental) peek at a major new feature, codenamed the" -" virtual client engine. Virtual clients enable simulations that scale to " -"a (very) large number of clients on a single machine or compute cluster. " -"The easiest way to test the new functionality is to look at the two new " -"code examples called `quickstart_simulation` and `simulation_pytorch`." +"One of Flower's goals is to enable research at scale. This release enables a " +"first (experimental) peek at a major new feature, codenamed the virtual " +"client engine. Virtual clients enable simulations that scale to a (very) " +"large number of clients on a single machine or compute cluster. The easiest " +"way to test the new functionality is to look at the two new code examples " +"called `quickstart_simulation` and `simulation_pytorch`." msgstr "" #: ../../source/ref-changelog.md:861 msgid "" -"The feature is still experimental, so there's no stability guarantee for " -"the API. It's also not quite ready for prime time and comes with a few " -"known caveats. However, those who are curious are encouraged to try it " -"out and share their thoughts." +"The feature is still experimental, so there's no stability guarantee for the " +"API. It's also not quite ready for prime time and comes with a few known " +"caveats. However, those who are curious are encouraged to try it out and " +"share their thoughts." msgstr "" #: ../../source/ref-changelog.md:863 msgid "" -"**New built-in strategies** " -"([#828](https://github.com/adap/flower/pull/828) " +"**New built-in strategies** ([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" @@ -16758,101 +16280,99 @@ msgstr "" #: ../../source/ref-changelog.md:868 msgid "" -"**New PyTorch Lightning code example** " -"([#617](https://github.com/adap/flower/pull/617))" +"**New PyTorch Lightning code example** ([#617](https://github.com/adap/" +"flower/pull/617))" msgstr "" #: ../../source/ref-changelog.md:870 msgid "" -"**New Variational Auto-Encoder code example** " -"([#752](https://github.com/adap/flower/pull/752))" +"**New Variational Auto-Encoder code example** ([#752](https://github.com/" +"adap/flower/pull/752))" msgstr "" #: ../../source/ref-changelog.md:872 msgid "" -"**New scikit-learn code example** " -"([#748](https://github.com/adap/flower/pull/748))" +"**New scikit-learn code example** ([#748](https://github.com/adap/flower/" +"pull/748))" msgstr "" #: ../../source/ref-changelog.md:874 msgid "" -"**New experimental TensorBoard strategy** " -"([#789](https://github.com/adap/flower/pull/789))" +"**New experimental TensorBoard strategy** ([#789](https://github.com/adap/" +"flower/pull/789))" msgstr "" #: ../../source/ref-changelog.md:878 msgid "" -"Improved advanced TensorFlow code example " -"([#769](https://github.com/adap/flower/pull/769))" +"Improved advanced TensorFlow code example ([#769](https://github.com/adap/" +"flower/pull/769))" msgstr "" #: ../../source/ref-changelog.md:879 msgid "" -"Warning when `min_available_clients` is misconfigured " -"([#830](https://github.com/adap/flower/pull/830))" +"Warning when `min_available_clients` is misconfigured ([#830](https://github." +"com/adap/flower/pull/830))" msgstr "" #: ../../source/ref-changelog.md:880 msgid "" -"Improved gRPC server docs " -"([#841](https://github.com/adap/flower/pull/841))" +"Improved gRPC server docs ([#841](https://github.com/adap/flower/pull/841))" msgstr "" #: ../../source/ref-changelog.md:881 msgid "" -"Improved error message in `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" +"Improved error message in `NumPyClient` ([#851](https://github.com/adap/" +"flower/pull/851))" msgstr "" #: ../../source/ref-changelog.md:882 msgid "" -"Improved PyTorch quickstart code example " -"([#852](https://github.com/adap/flower/pull/852))" +"Improved PyTorch quickstart code example ([#852](https://github.com/adap/" +"flower/pull/852))" msgstr "" #: ../../source/ref-changelog.md:886 msgid "" -"**Disabled final distributed evaluation** " -"([#800](https://github.com/adap/flower/pull/800))" +"**Disabled final distributed evaluation** ([#800](https://github.com/adap/" +"flower/pull/800))" msgstr "" #: ../../source/ref-changelog.md:888 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on" -" all connected clients, which is often not required (e.g., when using " -"server-side evaluation). The prior behaviour can be enabled by passing " +"Prior behaviour was to perform a final round of distributed evaluation on " +"all connected clients, which is often not required (e.g., when using server-" +"side evaluation). The prior behaviour can be enabled by passing " "`force_final_distributed_eval=True` to `start_server`." msgstr "" #: ../../source/ref-changelog.md:890 msgid "" -"**Renamed q-FedAvg strategy** " -"([#802](https://github.com/adap/flower/pull/802))" +"**Renamed q-FedAvg strategy** ([#802](https://github.com/adap/flower/" +"pull/802))" msgstr "" #: ../../source/ref-changelog.md:892 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " -"the notation given in the original paper (q-FFL is the optimization " -"objective, q-FedAvg is the proposed solver). Note the original (now " -"deprecated) `QffedAvg` class is still available for compatibility reasons" -" (it will be removed in a future release)." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect the " +"notation given in the original paper (q-FFL is the optimization objective, q-" +"FedAvg is the proposed solver). Note the original (now deprecated) " +"`QffedAvg` class is still available for compatibility reasons (it will be " +"removed in a future release)." msgstr "" #: ../../source/ref-changelog.md:894 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/pull/791))" msgstr "" #: ../../source/ref-changelog.md:896 msgid "" -"This example has been replaced by a new example. The new example is based" -" on the experimental virtual client engine, which will become the new " -"default way of doing most types of large-scale simulations in Flower. The" -" existing example was kept for reference purposes, but it might be " -"removed in the future." +"This example has been replaced by a new example. The new example is based on " +"the experimental virtual client engine, which will become the new default " +"way of doing most types of large-scale simulations in Flower. The existing " +"example was kept for reference purposes, but it might be removed in the " +"future." msgstr "" #: ../../source/ref-changelog.md:898 @@ -16861,8 +16381,7 @@ msgstr "" #: ../../source/ref-changelog.md:902 msgid "" -"**New built-in strategies** " -"([#549](https://github.com/adap/flower/pull/549))" +"**New built-in strategies** ([#549](https://github.com/adap/flower/pull/549))" msgstr "" #: ../../source/ref-changelog.md:904 @@ -16871,8 +16390,8 @@ msgstr "" #: ../../source/ref-changelog.md:907 msgid "" -"**Custom metrics for server and strategies** " -"([#717](https://github.com/adap/flower/pull/717))" +"**Custom metrics for server and strategies** ([#717](https://github.com/adap/" +"flower/pull/717))" msgstr "" #: ../../source/ref-changelog.md:909 @@ -16886,20 +16405,19 @@ msgstr "" #: ../../source/ref-changelog.md:911 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are" -" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " -"they enable evaluation functions passed to built-in strategies (via " -"`eval_fn`) to return more than two evaluation metrics. Strategies can " -"even return *aggregated* metrics dictionaries for the server to keep " -"track of." +"Custom metric dictionaries are now used in two user-facing APIs: they are " +"returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and they " +"enable evaluation functions passed to built-in strategies (via `eval_fn`) to " +"return more than two evaluation metrics. Strategies can even return " +"*aggregated* metrics dictionaries for the server to keep track of." msgstr "" #: ../../source/ref-changelog.md:913 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate" -" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"returning an empty `{}`), server-side evaluation functions should migrate " +"from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" #: ../../source/ref-changelog.md:915 @@ -16910,25 +16428,24 @@ msgstr "" #: ../../source/ref-changelog.md:917 msgid "" -"**Migration warnings for deprecated functionality** " -"([#690](https://github.com/adap/flower/pull/690))" +"**Migration warnings for deprecated functionality** ([#690](https://github." +"com/adap/flower/pull/690))" msgstr "" #: ../../source/ref-changelog.md:919 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces " -"detailed warning messages if usage of deprecated APIs is detected. The " -"new warning messages often provide details on how to migrate to more " -"recent APIs, thus easing the transition from one release to another." +"maintaining compatibility with legacy APIs. This release introduces detailed " +"warning messages if usage of deprecated APIs is detected. The new warning " +"messages often provide details on how to migrate to more recent APIs, thus " +"easing the transition from one release to another." msgstr "" #: ../../source/ref-changelog.md:921 msgid "" -"Improved docs and docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +"Improved docs and docstrings ([#691](https://github.com/adap/flower/" +"pull/691) [#692](https://github.com/adap/flower/pull/692) [#713](https://" +"github.com/adap/flower/pull/713))" msgstr "" #: ../../source/ref-changelog.md:923 @@ -16938,43 +16455,39 @@ msgstr "" #: ../../source/ref-changelog.md:925 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"([#696](https://github.com/adap/flower/pull/696) [#702](https://github.com/" +"adap/flower/pull/702) [#705](https://github.com/adap/flower/pull/705))" msgstr "" #: ../../source/ref-changelog.md:929 msgid "" -"**Serialization-agnostic server** " -"([#721](https://github.com/adap/flower/pull/721))" +"**Serialization-agnostic server** ([#721](https://github.com/adap/flower/" +"pull/721))" msgstr "" #: ../../source/ref-changelog.md:931 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of " -"class `Weights` (which represents parameters as deserialized NumPy " -"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " -"`Parameters` objects are fully serialization-agnostic and represents " -"parameters as byte arrays, the `tensor_type` attributes indicates how " -"these byte arrays should be interpreted (e.g., for " -"serialization/deserialization)." +"The Flower server is now fully serialization-agnostic. Prior usage of class " +"`Weights` (which represents parameters as deserialized NumPy ndarrays) was " +"replaced by class `Parameters` (e.g., in `Strategy`). `Parameters` objects " +"are fully serialization-agnostic and represents parameters as byte arrays, " +"the `tensor_type` attributes indicates how these byte arrays should be " +"interpreted (e.g., for serialization/deserialization)." msgstr "" #: ../../source/ref-changelog.md:933 msgid "" -"Built-in strategies implement this approach by handling serialization and" -" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"Built-in strategies implement this approach by handling serialization and " +"deserialization to/from `Weights` internally. Custom/3rd-party Strategy " "implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR " -"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" -" easily migrate to the new format." +"definitions. Strategy authors can consult PR [#721](https://github.com/adap/" +"flower/pull/721) to see how strategies can easily migrate to the new format." msgstr "" #: ../../source/ref-changelog.md:935 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use " -"`flwr.server.Server.evaluate_round` instead " -"([#717](https://github.com/adap/flower/pull/717))" +"Deprecated `flwr.server.Server.evaluate`, use `flwr.server.Server." +"evaluate_round` instead ([#717](https://github.com/adap/flower/pull/717))" msgstr "" #: ../../source/ref-changelog.md:937 @@ -16983,8 +16496,8 @@ msgstr "" #: ../../source/ref-changelog.md:941 msgid "" -"**Server-side parameter initialization** " -"([#658](https://github.com/adap/flower/pull/658))" +"**Server-side parameter initialization** ([#658](https://github.com/adap/" +"flower/pull/658))" msgstr "" #: ../../source/ref-changelog.md:943 @@ -16997,9 +16510,9 @@ msgstr "" #: ../../source/ref-changelog.md:945 msgid "" "Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies " -"will provide these initial parameters to the server on startup and then " -"delete them to free the memory afterwards." +"`initial_parameters` to set the initial parameters. Built-in strategies will " +"provide these initial parameters to the server on startup and then delete " +"them to free the memory afterwards." msgstr "" #: ../../source/ref-changelog.md:964 @@ -17016,8 +16529,8 @@ msgstr "" #: ../../source/ref-changelog.md:968 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " -"`flwr.server.strategy.FedAvg`, which is equivalent)" +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to `flwr.server." +"strategy.FedAvg`, which is equivalent)" msgstr "" #: ../../source/ref-changelog.md:970 @@ -17027,35 +16540,33 @@ msgstr "" #: ../../source/ref-changelog.md:974 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"([#610](https://github.com/adap/flower/pull/610) [#572](https://github.com/" +"adap/flower/pull/572) [#633](https://github.com/adap/flower/pull/633))" msgstr "" #: ../../source/ref-changelog.md:976 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to " -"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " -"This means one can return almost arbitrary values from `fit`/`evaluate` " -"and make use of them on the server side!" +"Clients can now return an additional dictionary mapping `str` keys to values " +"of the following types: `bool`, `bytes`, `float`, `int`, `str`. This means " +"one can return almost arbitrary values from `fit`/`evaluate` and make use of " +"them on the server side!" msgstr "" #: ../../source/ref-changelog.md:978 msgid "" -"This improvement also allowed for more consistent return types between " -"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " -"dict)` representing the loss, number of examples, and a dictionary " -"holding arbitrary problem-specific values like accuracy." +"This improvement also allowed for more consistent return types between `fit` " +"and `evaluate`: `evaluate` should now return a tuple `(float, int, dict)` " +"representing the loss, number of examples, and a dictionary holding " +"arbitrary problem-specific values like accuracy." msgstr "" #: ../../source/ref-changelog.md:980 msgid "" -"In case you wondered: this feature is compatible with existing projects, " -"the additional dictionary return value is optional. New code should " -"however migrate to the new return types to be compatible with upcoming " -"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " -"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " -"details." +"In case you wondered: this feature is compatible with existing projects, the " +"additional dictionary return value is optional. New code should however " +"migrate to the new return types to be compatible with upcoming Flower " +"releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, `evaluate`: " +"`float, int, Dict[str, Scalar]`). See the example below for details." msgstr "" #: ../../source/ref-changelog.md:982 @@ -17066,23 +16577,23 @@ msgstr "" #: ../../source/ref-changelog.md:997 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Generalized** `config` **argument in** `Client.fit` **and** `Client." +"evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" #: ../../source/ref-changelog.md:999 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means " -"that dictionary values were expected to be strings. The new release " -"generalizes this to enable values of the following types: `bool`, " -"`bytes`, `float`, `int`, `str`." +"The `config` argument used to be of type `Dict[str, str]`, which means that " +"dictionary values were expected to be strings. The new release generalizes " +"this to enable values of the following types: `bool`, `bytes`, `float`, " +"`int`, `str`." msgstr "" #: ../../source/ref-changelog.md:1001 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" -"side and `int(config[\"epochs\"])` on the client side!" +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-side " +"and `int(config[\"epochs\"])` on the client side!" msgstr "" #: ../../source/ref-changelog.md:1003 @@ -17097,8 +16608,8 @@ msgstr "" #: ../../source/ref-changelog.md:1024 msgid "" -"New example: PyTorch From Centralized To Federated " -"([#549](https://github.com/adap/flower/pull/549))" +"New example: PyTorch From Centralized To Federated ([#549](https://github." +"com/adap/flower/pull/549))" msgstr "" #: ../../source/ref-changelog.md:1025 @@ -17106,7 +16617,8 @@ msgid "Improved documentation" msgstr "" #: ../../source/ref-changelog.md:1026 -msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +msgid "" +"New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" #: ../../source/ref-changelog.md:1027 @@ -17115,14 +16627,14 @@ msgstr "" #: ../../source/ref-changelog.md:1028 msgid "" -"Updated examples documentation " -"([#549](https://github.com/adap/flower/pull/549))" +"Updated examples documentation ([#549](https://github.com/adap/flower/" +"pull/549))" msgstr "" #: ../../source/ref-changelog.md:1029 msgid "" -"Removed obsolete documentation " -"([#548](https://github.com/adap/flower/pull/548))" +"Removed obsolete documentation ([#548](https://github.com/adap/flower/" +"pull/548))" msgstr "" #: ../../source/ref-changelog.md:1031 @@ -17131,10 +16643,9 @@ msgstr "" #: ../../source/ref-changelog.md:1033 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the" -" clients is now handled in `flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." +"`Server.fit` does not disconnect clients when finished, disconnecting the " +"clients is now handled in `flwr.server.start_server` ([#553](https://github." +"com/adap/flower/pull/553) [#540](https://github.com/adap/flower/issues/540))." msgstr "" #: ../../source/ref-changelog.md:1035 @@ -17147,23 +16658,22 @@ msgstr "" #: ../../source/ref-changelog.md:1039 msgid "" -"Added an example for embedded devices " -"([#507](https://github.com/adap/flower/pull/507))" +"Added an example for embedded devices ([#507](https://github.com/adap/flower/" +"pull/507))" msgstr "" #: ../../source/ref-changelog.md:1040 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +"Added a new NumPyClient (in addition to the existing KerasClient) ([#504]" +"(https://github.com/adap/flower/pull/504) [#508](https://github.com/adap/" +"flower/pull/508))" msgstr "" #: ../../source/ref-changelog.md:1041 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into " -"the top-level `examples` directory " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +"Deprecated `flwr_example` package and started to migrate examples into the " +"top-level `examples` directory ([#494](https://github.com/adap/flower/" +"pull/494) [#512](https://github.com/adap/flower/pull/512))" msgstr "" #: ../../source/ref-changelog.md:1043 @@ -17176,12 +16686,11 @@ msgstr "" #: ../../source/ref-changelog.md:1047 msgid "" -"Renamed strategy methods " -"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " -"Flower's public APIs. Other public methods/functions (e.g., every method " -"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " -"which is why we're removing it from the four methods in Strategy. To " -"migrate rename the following `Strategy` methods accordingly:" +"Renamed strategy methods ([#486](https://github.com/adap/flower/pull/486)) " +"to unify the naming of Flower's public APIs. Other public methods/functions " +"(e.g., every method in `Client`, but also `Strategy.evaluate`) do not use " +"the `on_` prefix, which is why we're removing it from the four methods in " +"Strategy. To migrate rename the following `Strategy` methods accordingly:" msgstr "" #: ../../source/ref-changelog.md:1048 @@ -17202,33 +16711,32 @@ msgstr "" #: ../../source/ref-changelog.md:1055 msgid "" -"Deprecated `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). To migrate use " -"`FedAvg` instead." +"Deprecated `DefaultStrategy` ([#479](https://github.com/adap/flower/" +"pull/479)). To migrate use `FedAvg` instead." msgstr "" #: ../../source/ref-changelog.md:1056 msgid "" -"Simplified examples and baselines " -"([#484](https://github.com/adap/flower/pull/484))." +"Simplified examples and baselines ([#484](https://github.com/adap/flower/" +"pull/484))." msgstr "" #: ../../source/ref-changelog.md:1057 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface " -"([#483](https://github.com/adap/flower/pull/483))." +"Removed presently unused `on_conclude_round` from strategy interface ([#483]" +"(https://github.com/adap/flower/pull/483))." msgstr "" #: ../../source/ref-changelog.md:1058 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"Set minimal Python version to 3.6.1 instead of 3.6.9 ([#471](https://github." +"com/adap/flower/pull/471))." msgstr "" #: ../../source/ref-changelog.md:1059 msgid "" -"Improved `Strategy` docstrings " -"([#470](https://github.com/adap/flower/pull/470))." +"Improved `Strategy` docstrings ([#470](https://github.com/adap/flower/" +"pull/470))." msgstr "" #: ../../source/ref-example-projects.rst:2 @@ -17237,11 +16745,11 @@ msgstr "" #: ../../source/ref-example-projects.rst:4 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate " -"how Flower can be used to federate different kinds of existing machine " -"learning pipelines, usually leveraging popular machine learning " -"frameworks such as `PyTorch `_ or `TensorFlow " -"`_." +"Flower comes with a number of usage examples. The examples demonstrate how " +"Flower can be used to federate different kinds of existing machine learning " +"pipelines, usually leveraging popular machine learning frameworks such as " +"`PyTorch `_ or `TensorFlow `_." msgstr "" #: ../../source/ref-example-projects.rst:10 @@ -17252,25 +16760,25 @@ msgstr "" #: ../../source/ref-example-projects.rst:14 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image " -"classification with MobileNetV2:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image classification " +"with MobileNetV2:" msgstr "" #: ../../source/ref-example-projects.rst:17 msgid "" -"`Quickstart TensorFlow (Code) " -"`_" +"`Quickstart TensorFlow (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:18 -msgid ":doc:`Quickstart TensorFlow (Tutorial) `" +msgid "" +":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" #: ../../source/ref-example-projects.rst:19 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" #: ../../source/ref-example-projects.rst:23 @@ -17280,14 +16788,14 @@ msgstr "" #: ../../source/ref-example-projects.rst:25 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a" -" simple Convolutional Neural Network:" +"The PyTorch quickstart example shows CIFAR-10 image classification with a " +"simple Convolutional Neural Network:" msgstr "" #: ../../source/ref-example-projects.rst:28 msgid "" -"`Quickstart PyTorch (Code) " -"`_" +"`Quickstart PyTorch (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:29 @@ -17306,9 +16814,8 @@ msgstr "" #: ../../source/ref-example-projects.rst:37 msgid "" -"`PyTorch: From Centralized To Federated (Code) " -"`_" +"`PyTorch: From Centralized To Federated (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:38 @@ -17329,14 +16836,15 @@ msgstr "" #: ../../source/ref-example-projects.rst:46 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:47 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) `_" msgstr "" #: ../../source/ref-faq.rst:4 @@ -17351,22 +16859,20 @@ msgstr "" #: ../../source/ref-faq.rst:8 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to" -" make it work even better on Colab. Here's a quickstart example:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to " +"make it work even better on Colab. Here's a quickstart example:" msgstr "" #: ../../source/ref-faq.rst:10 msgid "" -"`Flower simulation PyTorch " -"`_" +"`Flower simulation PyTorch `_" msgstr "" #: ../../source/ref-faq.rst:11 msgid "" -"`Flower simulation TensorFlow/Keras " -"`_" +"`Flower simulation TensorFlow/Keras `_" msgstr "" #: ../../source/ref-faq.rst @@ -17376,26 +16882,28 @@ msgstr "" #: ../../source/ref-faq.rst:15 msgid "" "Find the `blog post about federated learning on embedded device here " -"`_" -" and the corresponding `GitHub code example " -"`_." +"`_ " +"and the corresponding `GitHub code example `_." msgstr "" #: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgid "" +":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr "" #: ../../source/ref-faq.rst:19 msgid "" -"Yes, it does. Please take a look at our `blog post " -"`_ or check out the code examples:" +"Yes, it does. Please take a look at our `blog post `_ or " +"check out the code examples:" msgstr "" #: ../../source/ref-faq.rst:21 msgid "" -"`Android Kotlin example `_" +"`Android Kotlin example `_" msgstr "" #: ../../source/ref-faq.rst:22 @@ -17414,33 +16922,33 @@ msgstr "" #: ../../source/ref-faq.rst:28 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" #: ../../source/ref-faq.rst:29 msgid "" -"`Flower meets Nevermined YouTube video " -"`_." +"`Flower meets Nevermined YouTube video `_." msgstr "" #: ../../source/ref-faq.rst:30 msgid "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." msgstr "" #: ../../source/ref-faq.rst:31 msgid "" "`Flower meets Talan blog post `_ ." +"learning-same-mask-different-faces-imen-ayari/?" +"trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ ." msgstr "" #: ../../source/ref-faq.rst:32 msgid "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"`Flower meets Talan GitHub Repository `_ ." msgstr "" #: ../../source/ref-telemetry.md:1 @@ -17449,17 +16957,16 @@ msgstr "" #: ../../source/ref-telemetry.md:3 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to " -"make well-informed decisions to improve Flower. Doing this enables the " -"Flower team to understand how Flower is used and what challenges users " -"might face." +"The Flower open-source project collects **anonymous** usage metrics to make " +"well-informed decisions to improve Flower. Doing this enables the Flower " +"team to understand how Flower is used and what challenges users might face." msgstr "" #: ../../source/ref-telemetry.md:5 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users that do not want to share anonymous usage metrics." +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users that do not want to share anonymous usage metrics." msgstr "" #: ../../source/ref-telemetry.md:7 @@ -17467,35 +16974,34 @@ msgid "Principles" msgstr "" #: ../../source/ref-telemetry.md:9 -msgid "We follow strong principles guarding anonymous usage metrics collection:" +msgid "" +"We follow strong principles guarding anonymous usage metrics collection:" msgstr "" #: ../../source/ref-telemetry.md:11 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to " -"learn “[How to opt-out](#how-to-opt-out)”." +"**Optional:** You will always be able to disable telemetry; read on to learn " +"“[How to opt-out](#how-to-opt-out)”." msgstr "" #: ../../source/ref-telemetry.md:12 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not " -"contain any personally identifiable information (PII). See “[Collected " -"metrics](#collected-metrics)” to understand what metrics are being " -"reported." +"**Anonymous:** The reported usage metrics are anonymous and do not contain " +"any personally identifiable information (PII). See “[Collected metrics]" +"(#collected-metrics)” to understand what metrics are being reported." msgstr "" #: ../../source/ref-telemetry.md:13 msgid "" "**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-" -"to-inspect-what-is-being-reported)”" +"reported; see the section “[How to inspect what is being reported](#how-to-" +"inspect-what-is-being-reported)”" msgstr "" #: ../../source/ref-telemetry.md:14 msgid "" -"**Open for feedback:** You can always reach out to us if you have " -"feedback; see the section “[How to contact us](#how-to-contact-us)” for " -"details." +"**Open for feedback:** You can always reach out to us if you have feedback; " +"see the section “[How to contact us](#how-to-contact-us)” for details." msgstr "" #: ../../source/ref-telemetry.md:16 @@ -17512,9 +17018,9 @@ msgstr "" #: ../../source/ref-telemetry.md:24 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," -" `.bashrc` (or whatever configuration file applies to your environment) " -"to disable Flower telemetry permanently." +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `." +"bashrc` (or whatever configuration file applies to your environment) to " +"disable Flower telemetry permanently." msgstr "" #: ../../source/ref-telemetry.md:26 @@ -17527,10 +17033,10 @@ msgstr "" #: ../../source/ref-telemetry.md:30 msgid "" -"**Flower version.** Understand which versions of Flower are currently " -"being used. This helps us to decide whether we should invest effort into " -"releasing a patch version for an older version of Flower or instead use " -"the bandwidth to build new features." +"**Flower version.** Understand which versions of Flower are currently being " +"used. This helps us to decide whether we should invest effort into releasing " +"a patch version for an older version of Flower or instead use the bandwidth " +"to build new features." msgstr "" #: ../../source/ref-telemetry.md:32 @@ -17549,15 +17055,15 @@ msgstr "" #: ../../source/ref-telemetry.md:36 msgid "" -"**Hardware properties.** Understanding the hardware environment that " -"Flower is being used in helps to decide whether we should, for example, " -"put more effort into supporting low-resource environments." +"**Hardware properties.** Understanding the hardware environment that Flower " +"is being used in helps to decide whether we should, for example, put more " +"effort into supporting low-resource environments." msgstr "" #: ../../source/ref-telemetry.md:38 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables " -"us to understand how heavily certain features are being used and better " +"**Execution mode.** Knowing what execution mode Flower starts in enables us " +"to understand how heavily certain features are being used and better " "prioritize based on that." msgstr "" @@ -17565,37 +17071,34 @@ msgstr "" msgid "" "**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " "time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete " -"them." +"types not only start Flower workloads but also successfully complete them." msgstr "" #: ../../source/ref-telemetry.md:42 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in " -"`~/.flwr/source` the first time a telemetry event is generated. The " -"source ID is important to identify whether an issue is recurring or " -"whether an issue is triggered by multiple clusters running concurrently " -"(which often happens in simulation). For example, if a device runs " -"multiple workloads at the same time, and this results in an issue, then, " -"in order to reproduce the issue, multiple workloads must be started at " -"the same time." +"**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/" +"source` the first time a telemetry event is generated. The source ID is " +"important to identify whether an issue is recurring or whether an issue is " +"triggered by multiple clusters running concurrently (which often happens in " +"simulation). For example, if a device runs multiple workloads at the same " +"time, and this results in an issue, then, in order to reproduce the issue, " +"multiple workloads must be started at the same time." msgstr "" #: ../../source/ref-telemetry.md:44 msgid "" -"You may delete the source ID at any time. If you wish for all events " -"logged under a specific source ID to be deleted, you can send a deletion " -"request mentioning the source ID to `telemetry@flower.ai`. All events " -"related to that source ID will then be permanently deleted." +"You may delete the source ID at any time. If you wish for all events logged " +"under a specific source ID to be deleted, you can send a deletion request " +"mentioning the source ID to `telemetry@flower.ai`. All events related to " +"that source ID will then be permanently deleted." msgstr "" #: ../../source/ref-telemetry.md:46 msgid "" -"We will not collect any personally identifiable information. If you think" -" any of the metrics collected could be misused in any way, please [get in" -" touch with us](#how-to-contact-us). We will update this page to reflect " -"any changes to the metrics collected and publish changes in the " -"changelog." +"We will not collect any personally identifiable information. If you think " +"any of the metrics collected could be misused in any way, please [get in " +"touch with us](#how-to-contact-us). We will update this page to reflect any " +"changes to the metrics collected and publish changes in the changelog." msgstr "" #: ../../source/ref-telemetry.md:48 @@ -17612,17 +17115,17 @@ msgstr "" #: ../../source/ref-telemetry.md:52 msgid "" "We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information" -" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " -"is disabled by default. You may use logging independently from " +"metrics are reported. You can view all the reported telemetry information by " +"setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is " +"disabled by default. You may use logging independently from " "`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " "without sending any metrics." msgstr "" #: ../../source/ref-telemetry.md:58 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics," -" use both environment variables:" +"The inspect Flower telemetry without sending any anonymous usage metrics, " +"use both environment variables:" msgstr "" #: ../../source/ref-telemetry.md:64 @@ -17639,8 +17142,8 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android " -"app using Flower." +"Read this Federated Learning quickstart tutorial for creating an Android app " +"using Flower." msgstr "" #: ../../source/tutorial-quickstart-android.rst:5 @@ -17649,21 +17152,19 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"Let's build a federated learning system using TFLite and Flower on " -"Android!" +"Let's build a federated learning system using TFLite and Flower on Android!" msgstr "" #: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn " -"more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with FastAI to train a vision model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"FastAI to train a vision model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:5 @@ -17676,15 +17177,14 @@ msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower " -"with HuggingFace Transformers in order to fine-tune an LLM." +"Check out this Federating Learning quickstart tutorial for using Flower with " +"HuggingFace Transformers in order to fine-tune an LLM." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:5 @@ -17693,17 +17193,17 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Let's build a federated learning system using Hugging Face Transformers " -"and Flower!" +"Let's build a federated learning system using Hugging Face Transformers and " +"Flower!" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"We will leverage Hugging Face to federate the training of language models" -" over multiple clients using Flower. More specifically, we will fine-tune" -" a pre-trained Transformer model (distilBERT) for sequence classification" -" over a dataset of IMDB ratings. The end goal is to detect if a movie " -"rating is positive or negative." +"We will leverage Hugging Face to federate the training of language models " +"over multiple clients using Flower. More specifically, we will fine-tune a " +"pre-trained Transformer model (distilBERT) for sequence classification over " +"a dataset of IMDB ratings. The end goal is to detect if a movie rating is " +"positive or negative." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:18 @@ -17713,9 +17213,8 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:20 msgid "" "To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " -":code:`torch`, and :code:`transformers`. This can be done using " -":code:`pip`:" +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, " +"and :code:`transformers`. This can be done using :code:`pip`:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:30 @@ -17739,9 +17238,9 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"Once we have a way of creating our trainloader and testloader, we can " -"take care of the training and testing. This is very similar to any " -":code:`PyTorch` training or testing loop:" +"Once we have a way of creating our trainloader and testloader, we can take " +"care of the training and testing. This is very similar to any :code:" +"`PyTorch` training or testing loop:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:121 @@ -17750,8 +17249,8 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT" -" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"To create the model itself, we will just load the pre-trained distillBERT " +"model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:136 @@ -17765,18 +17264,17 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" "To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " -"This is very easy, as our model is a standard :code:`PyTorch` model:" +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). This " +"is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" "The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the " -"server to send its parameters to the client. Finally, the :code:`fit` " -"function trains the model locally for the client, and the " -":code:`evaluate` function tests the model locally and returns the " -"relevant metrics." +"parameters. Inversely, the :code:`set_parameters` function allows the server " +"to send its parameters to the client. Finally, the :code:`fit` function " +"trains the model locally for the client, and the :code:`evaluate` function " +"tests the model locally and returns the relevant metrics." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:175 @@ -17785,19 +17283,19 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Now that we have a way to instantiate clients, we need to create our " -"server in order to aggregate the results. Using Flower, this can be done " -"very easily by first choosing a strategy (here, we are using " -":code:`FedAvg`, which will define the global weights as the average of " -"all the clients' weights at each round) and then using the " -":code:`flwr.server.start_server` function:" +"Now that we have a way to instantiate clients, we need to create our server " +"in order to aggregate the results. Using Flower, this can be done very " +"easily by first choosing a strategy (here, we are using :code:`FedAvg`, " +"which will define the global weights as the average of all the clients' " +"weights at each round) and then using the :code:`flwr.server.start_server` " +"function:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"The :code:`weighted_average` function is there to provide a way to " -"aggregate the metrics distributed amongst the clients (basically this " -"allows us to display a nice average accuracy and loss for every round)." +"The :code:`weighted_average` function is there to provide a way to aggregate " +"the metrics distributed amongst the clients (basically this allows us to " +"display a nice average accuracy and loss for every round)." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:209 @@ -17816,22 +17314,22 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:223 msgid "" -"If you want to check out everything put together, you should check out " -"the `full code example `_ ." +"If you want to check out everything put together, you should check out the " +"`full code example `_ ." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Of course, this is a very basic example, and a lot can be added or " -"modified, it was just to showcase how simply we could federate a Hugging " -"Face workflow using Flower." +"Of course, this is a very basic example, and a lot can be added or modified, " +"it was just to showcase how simply we could federate a Hugging Face workflow " +"using Flower." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very" -" well used :code:`TensorFlow`." +"Note that in this example we used :code:`PyTorch`, but we could have very " +"well used :code:`TensorFlow`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:-1 @@ -17846,38 +17344,38 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST " -"using Flower and CoreML on iOS devices." +"In this tutorial we will learn how to train a Neural Network on MNIST using " +"Flower and CoreML on iOS devices." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:12 msgid "" "First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv" -" `. For the Flower client " +"create a virtual environment and run everything within a :doc:`virtualenv " +"`. For the Flower client " "implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that" -" all have the same model." +"Our example consists of one Python *server* and two iPhone *clients* that " +"all have the same model." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"*Clients* are responsible for generating individual weight updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:21 msgid "" "Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You" -" can do this by using pip:" +"setup our Flower server environment. We first need to install Flower. You " +"can do this by using pip:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:27 @@ -17895,21 +17393,20 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:36 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and " -"MNIST as our dataset. For simplicity reasons we will use the complete " -"Flower client with CoreML, that has been implemented and stored inside " -"the Swift SDK. The client implementation can be seen below:" +"distributed training using CoreML as our local training pipeline and MNIST " +"as our dataset. For simplicity reasons we will use the complete Flower " +"client with CoreML, that has been implemented and stored inside the Swift " +"SDK. The client implementation can be seen below:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a" -" dependency in your project. For our application, we will store the logic" -" of our app in :code:`FLiOSModel.swift` and the UI elements in " -":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" -" in this quickstart. Please refer to the `full code example " -"`_ to learn more " -"about the app." +"Let's create a new application project in Xcode and add :code:`flwr` as a " +"dependency in your project. For our application, we will store the logic of " +"our app in :code:`FLiOSModel.swift` and the UI elements in :code:" +"`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift` in this " +"quickstart. Please refer to the `full code example `_ to learn more about the app." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:75 @@ -17919,22 +17416,21 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:83 msgid "" "Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS " -"device. We need to pass the url to access mlmodel and run CoreML machine " -"learning processes, it can be retrieved by calling the function " -":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " -"into :code:`MLBatchProvider` object. The preprocessing is done inside " -":code:`DataLoader.swift`." +"will be bundled inside the application during deployment to your iOS device. " +"We need to pass the url to access mlmodel and run CoreML machine learning " +"processes, it can be retrieved by calling the function :code:`Bundle.main." +"url`. For the MNIST dataset, we need to preprocess it into :code:" +"`MLBatchProvider` object. The preprocessing is done inside :code:`DataLoader." +"swift`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:99 msgid "" -"Since CoreML does not allow the model parameters to be seen before " -"training, and accessing the model parameters during or after the training" -" can only be done by specifying the layer name, we need to know this " -"information beforehand, through looking at the model specification, which" -" are written as proto files. The implementation can be seen in " -":code:`MLModelInspect`." +"Since CoreML does not allow the model parameters to be seen before training, " +"and accessing the model parameters during or after the training can only be " +"done by specifying the layer name, we need to know this information " +"beforehand, through looking at the model specification, which are written as " +"proto files. The implementation can be seen in :code:`MLModelInspect`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:102 @@ -17945,18 +17441,18 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"Then start the Flower gRPC client and start communicating to the server " -"by passing our Flower client to the function :code:`startFlwrGRPC`." +"Then start the Flower gRPC client and start communicating to the server by " +"passing our Flower client to the function :code:`startFlwrGRPC`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:124 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " -"The attribute :code:`hostname` and :code:`port` tells the client which " -"server to connect to. This can be done by entering the hostname and port " -"in the application before clicking the start button to start the " -"federated learning process." +"That's it for the client. We only have to implement :code:`Client` or call " +"the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. The " +"attribute :code:`hostname` and :code:`port` tells the client which server to " +"connect to. This can be done by entering the hostname and port in the " +"application before clicking the start button to start the federated learning " +"process." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:129 @@ -17972,8 +17468,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" "For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named " -":code:`server.py`, import Flower and start the server:" +"configuration possibilities at their default values. In a file named :code:" +"`server.py`, import Flower and start the server:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:142 @@ -17989,32 +17485,31 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" "With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and " -"multiple clients. We therefore have to start the server first:" +"federated learning in action. FL systems usually have a server and multiple " +"clients. We therefore have to start the server first:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Build and run the client through your Xcode, one through Xcode" -" Simulator and the other by deploying it to your iPhone. To see more " -"about how to deploy your app to iPhone or Simulator visit `here " -"`_." +"Once the server is running we can start the clients in different terminals. " +"Build and run the client through your Xcode, one through Xcode Simulator and " +"the other by deploying it to your iPhone. To see more about how to deploy " +"your app to iPhone or Simulator visit `here `_." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:156 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code " -"`_ for this " -"example can be found in :code:`examples/ios`." +"learning system in your ios device. The full `source code `_ for this example can be found in :" +"code:`examples/ios`." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Jax to train a linear regression model on a scikit-learn dataset." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Jax to train a linear regression model on a scikit-learn dataset." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:5 @@ -18023,8 +17518,8 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Pandas to perform Federated Analytics." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Pandas to perform Federated Analytics." msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:5 @@ -18037,45 +17532,44 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch to train a CNN model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch to train a CNN model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural " -"Network on CIFAR10 using Flower and PyTorch." +"In this tutorial we will learn how to train a Convolutional Neural Network " +"on CIFAR10 using Flower and PyTorch." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:15 #: ../../source/tutorial-quickstart-xgboost.rst:39 msgid "" "First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"everything within a :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:17 #: ../../source/tutorial-quickstart-scikitlearn.rst:14 msgid "" -"Our example consists of one *server* and two *clients* all having the " -"same model." +"Our example consists of one *server* and two *clients* all having the same " +"model." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:19 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:23 @@ -18086,16 +17580,15 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go " -"ahead and install PyTorch and the **torchvision** library:" +"Since we want to use PyTorch to solve a computer vision task, let's go ahead " +"and install PyTorch and the **torchvision** library:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:39 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on PyTorch's `Deep Learning " -"with PyTorch " +"distributed training with two clients and one server. Our training procedure " +"and network architecture are based on PyTorch's `Deep Learning with PyTorch " "`_." msgstr "" @@ -18112,33 +17605,33 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" "We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " -"the training and test data that are then normalized." +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads the " +"training and test data that are then normalized." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset " -"is done by looping over the dataset, measure the corresponding loss and " +"Define the loss and optimizer with PyTorch. The training of the dataset is " +"done by looping over the dataset, measure the corresponding loss and " "optimize it." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"Define then the validation of the machine learning network. We loop over" -" the test set and measure the loss and accuracy of the test set." +"Define then the validation of the machine learning network. We loop over " +"the test set and measure the loss and accuracy of the test set." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:113 msgid "" -"After defining the training and testing of a PyTorch machine learning " -"model, we use the functions for the Flower clients." +"After defining the training and testing of a PyTorch machine learning model, " +"we use the functions for the Flower clients." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " -"Minute Blitz':" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 Minute " +"Blitz':" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:142 @@ -18150,20 +17643,19 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:144 #: ../../source/tutorial-quickstart-tensorflow.rst:54 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to train the neural network we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to train the neural network we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"PyTorch. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:156 @@ -18179,8 +17671,7 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:158 #: ../../source/tutorial-quickstart-scikitlearn.rst:121 msgid "" -"update the local model weights with the parameters received from the " -"server" +"update the local model weights with the parameters received from the server" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:160 @@ -18210,22 +17701,22 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:189 #: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add " -"one line to actually run this client:" +"We can now create an instance of our class :code:`CifarClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:196 #: ../../source/tutorial-quickstart-tensorflow.rst:90 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " -"the client which server to connect to. In our case we can run the server " -"and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"[::]:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"[::]:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we point " +"the client at." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:226 @@ -18233,8 +17724,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:122 #: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Open a new terminal and start the first client:" +"Once the server is running we can start the clients in different terminals. " +"Open a new terminal and start the first client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:233 @@ -18248,24 +17739,22 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:252 #: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Each client will have its own dataset. You should now see how the " -"training does in the very first terminal (the one that started the " -"server):" +"Each client will have its own dataset. You should now see how the training " +"does in the very first terminal (the one that started the server):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-pytorch`." +"learning system. The full `source code `_ for this example can be found " +"in :code:`examples/quickstart-pytorch`." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch Lightning to train an Auto Encoder model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch Lightning to train an Auto Encoder model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 @@ -18274,21 +17763,20 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 msgid "" -"Let's build a horizontal federated learning system using PyTorch " -"Lightning and Flower!" +"Let's build a horizontal federated learning system using PyTorch Lightning " +"and Flower!" msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with scikit-learn to train a linear regression model." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"scikit-learn to train a linear regression model." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:5 @@ -18297,24 +17785,23 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic " -"Regression` model on MNIST using Flower and scikit-learn." +"In this tutorial, we will learn how to train a :code:`Logistic Regression` " +"model on MNIST using Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:12 msgid "" -"It is recommended to create a virtual environment and run everything " -"within this :doc:`virtualenv `." +"It is recommended to create a virtual environment and run everything within " +"this :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"*Clients* are responsible for generating individual model parameter " -"updates for the model based on their local datasets. These updates are " -"then sent to the *server* which will aggregate them to produce an updated" -" global model. Finally, the *server* sends this improved version of the " -"model back to each *client*. A complete cycle of parameters updates is " -"called a *round*." +"*Clients* are responsible for generating individual model parameter updates " +"for the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce an updated global model. " +"Finally, the *server* sends this improved version of the model back to each " +"*client*. A complete cycle of parameters updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:20 @@ -18335,10 +17822,10 @@ msgstr "" msgid "" "Now that we have all our dependencies installed, let's run a simple " "distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that" -" we need for our federated learning setup within :code:`utils.py`. The " -":code:`utils.py` contains different functions defining all the machine " -"learning basics:" +"setting up the client and server, we will define all functionalities that we " +"need for our federated learning setup within :code:`utils.py`. The :code:" +"`utils.py` contains different functions defining all the machine learning " +"basics:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:45 @@ -18367,46 +17854,44 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:52 msgid "" -"Please check out :code:`utils.py` `here " -"`_ for more details. The pre-defined functions are used in" -" the :code:`client.py` and imported. The :code:`client.py` also requires " -"to import several packages such as Flower and scikit-learn:" +"Please check out :code:`utils.py` `here `_ for more details. The pre-" +"defined functions are used in the :code:`client.py` and imported. The :code:" +"`client.py` also requires to import several packages such as Flower and " +"scikit-learn:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"Prior to local training, we need to load the MNIST dataset, a popular " -"image classification dataset of handwritten digits for machine learning, " -"and partition the dataset for FL. This can be conveniently achieved using" -" `Flower Datasets `_. The " -":code:`FederatedDataset.load_partition()` method loads the partitioned " -"training set for each partition ID defined in the :code:`--partition-id` " -"argument." +"Prior to local training, we need to load the MNIST dataset, a popular image " +"classification dataset of handwritten digits for machine learning, and " +"partition the dataset for FL. This can be conveniently achieved using " +"`Flower Datasets `_. The :code:" +"`FederatedDataset.load_partition()` method loads the partitioned training " +"set for each partition ID defined in the :code:`--partition-id` argument." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" -"Next, the logistic regression model is defined and initialized with " -":code:`utils.set_initial_params()`." +"Next, the logistic regression model is defined and initialized with :code:" +"`utils.set_initial_params()`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to fit the logistic regression we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to fit the logistic regression we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " -"means defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"scikit-learn. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:122 @@ -18419,28 +17904,28 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:153 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add " -"one line to actually run this client:" +"We can now create an instance of our class :code:`MnistClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:160 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" -" the client which server to connect to. In our case we can run the server" -" and the client on the same machine, therefore we use " -":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we pass to the client." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we pass to " +"the client." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:169 msgid "" "The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import " -"again all required libraries such as Flower and scikit-learn." +"evaluation function for the server-side evaluation. First, we import again " +"all required libraries such as Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:172 @@ -18449,46 +17934,44 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:185 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and" -" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"The number of federated learning rounds is set in :code:`fit_round()` and " +"the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " "function is called after each federated learning round and gives you " -"information about loss and accuracy. Note that we also make use of Flower" -" Datasets here to load the test split of the MNIST dataset for server-" -"side evaluation." +"information about loss and accuracy. Note that we also make use of Flower " +"Datasets here to load the test split of the MNIST dataset for server-side " +"evaluation." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"The :code:`main` contains the server-side parameter initialization " -":code:`utils.set_initial_params()` as well as the aggregation strategy " -":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " -"federated averaging (or FedAvg), with two clients and evaluation after " -"each federated learning round. The server can be started with the command" -" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +"The :code:`main` contains the server-side parameter initialization :code:" +"`utils.set_initial_params()` as well as the aggregation strategy :code:`fl." +"server.strategy:FedAvg()`. The strategy is the default one, federated " +"averaging (or FedAvg), with two clients and evaluation after each federated " +"learning round. The server can be started with the command :code:`fl.server." +"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." +"server.ServerConfig(num_rounds=3))`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:232 msgid "" "With both client and server ready, we can now run everything and see " "federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server " -"first:" +"server and multiple clients. We, therefore, have to start the server first:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:286 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples/sklearn-logreg-" -"mnist`." +"learning system. The full `source code `_ for this example can be found in :code:" +"`examples/sklearn-logreg-mnist`." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with TensorFlow to train a MobilNetV2 model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"TensorFlow to train a MobilNetV2 model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:5 @@ -18505,8 +17988,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install" -" TF as well:" +"Since we want to use the Keras API of TensorFlow (TF), we have to install TF " +"as well:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:31 @@ -18515,25 +17998,24 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image" -" classification dataset for machine learning. The call to " -":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " -"it locally, and then returns the entire training and test set as NumPy " -"ndarrays." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image " +"classification dataset for machine learning. The call to :code:`tf.keras." +"datasets.cifar10.load_data()` downloads CIFAR10, caches it locally, and then " +"returns the entire training and test set as NumPy ndarrays." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use " -"MobilNetV2 with 10 output classes:" +"Next, we need a model. For the purpose of this tutorial, we use MobilNetV2 " +"with 10 output classes:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses Keras. The :code:`NumPyClient` interface defines three " -"methods which can be implemented in the following way:" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"Keras. The :code:`NumPyClient` interface defines three methods which can be " +"implemented in the following way:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:135 @@ -18542,23 +18024,22 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"You should now see how the training does in the very first terminal (the " -"one that started the server):" +"You should now see how the training does in the very first terminal (the one " +"that started the server):" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this can be found in :code:`examples" -"/quickstart-tensorflow/client.py`." +"learning system. The full `source code `_ for this can be found in :" +"code:`examples/quickstart-tensorflow/client.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with XGBoost to train classification models on trees." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"XGBoost to train classification models on trees." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:5 @@ -18572,18 +18053,17 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" "EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that " -"maximises the computational boundaries for boosted tree methods. It's " -"primarily designed to enhance both the performance and computational " -"speed of machine learning models. In XGBoost, trees are constructed " -"concurrently, unlike the sequential approach taken by GBDT." +"implementation of gradient-boosted decision tree (**GBDT**), that maximises " +"the computational boundaries for boosted tree methods. It's primarily " +"designed to enhance both the performance and computational speed of machine " +"learning models. In XGBoost, trees are constructed concurrently, unlike the " +"sequential approach taken by GBDT." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" "Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning " -"techniques." +"training examples, XGBoost surpasses the results of deep learning techniques." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:23 @@ -18593,30 +18073,30 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" "Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems " -"for specialised applications, like survival analysis and financial fraud " +"there's an increasing requirement to implement federated XGBoost systems for " +"specialised applications, like survival analysis and financial fraud " "detection." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"Federated learning ensures that raw data remains on the local device, " -"making it an attractive approach for sensitive domains where data " -"security and privacy are paramount. Given the robustness and efficiency " -"of XGBoost, combining it with federated learning offers a promising " -"solution for these specific challenges." +"Federated learning ensures that raw data remains on the local device, making " +"it an attractive approach for sensitive domains where data security and " +"privacy are paramount. Given the robustness and efficiency of XGBoost, " +"combining it with federated learning offers a promising solution for these " +"specific challenges." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" "In this tutorial we will learn how to train a federated XGBoost model on " "HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart " -"`_)" -" with two *clients* and one *server* to demonstrate how federated XGBoost" -" works, and then we dive into a more complex example (`full code xgboost-" -"comprehensive `_) to run various experiments." +"example (`full code xgboost-quickstart `_) with two *clients* and one *server* to " +"demonstrate how federated XGBoost works, and then we dive into a more " +"complex example (`full code xgboost-comprehensive `_) to run various " +"experiments." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:37 @@ -18637,16 +18117,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. Now that we have all our " -"dependencies installed, let's run a simple distributed training with two " -"clients and one server." +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. Now that we have all our dependencies " +"installed, let's run a simple distributed training with two clients and one " +"server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:60 msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower " -"Datasets and other related functions:" +"In a file called :code:`client.py`, import xgboost, Flower, Flower Datasets " +"and other related functions:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:87 @@ -18655,15 +18135,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower" -" Datasets and conduct data partitioning for FL:" +"Prior to local training, we require loading the HIGGS dataset from Flower " +"Datasets and conduct data partitioning for FL:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" "In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " -"the partition for the given client based on :code:`node_id`:" +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load the " +"partition for the given client based on :code:`node_id`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:121 @@ -18674,8 +18154,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"The functions of :code:`train_test_split` and " -":code:`transform_dataset_to_dmatrix` are defined as below:" +"The functions of :code:`train_test_split` and :code:" +"`transform_dataset_to_dmatrix` are defined as below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:158 @@ -18684,10 +18164,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"The :code:`num_local_round` represents the number of iterations for local" -" tree boost. We use CPU for the training in default. One can shift it to " -"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " -"evaluation metric." +"The :code:`num_local_round` represents the number of iterations for local " +"tree boost. We use CPU for the training in default. One can shift it to GPU " +"by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as evaluation " +"metric." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:181 @@ -18696,86 +18176,85 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"After loading the dataset we define the Flower client. We follow the " -"general rule to define :code:`XgbClient` class inherited from " -":code:`fl.client.Client`." +"After loading the dataset we define the Flower client. We follow the general " +"rule to define :code:`XgbClient` class inherited from :code:`fl.client." +"Client`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" "The :code:`self.bst` is used to keep the Booster objects that remain " "consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures" -" for training." +"integrated in earlier rounds and maintain other essential data structures " +"for training." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:196 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and " -":code:`evaluate` methods insides :code:`XgbClient` class as follows." +"Then, we override :code:`get_parameters`, :code:`fit` and :code:`evaluate` " +"methods insides :code:`XgbClient` class as follows." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" "Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use " -":code:`get_parameters` and :code:`set_parameters` to initialise model " -"parameters for XGBoost. As a result, let's return an empty tensor in " -":code:`get_parameters` when it is called by the server at the first " -"round." +"specified random weights. In this case, we do not use :code:`get_parameters` " +"and :code:`set_parameters` to initialise model parameters for XGBoost. As a " +"result, let's return an empty tensor in :code:`get_parameters` when it is " +"called by the server at the first round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " -"up the first set of trees. the returned Booster object and config are " -"stored in :code:`self.bst` and :code:`self.config`, respectively. From " -"the second round, we load the global model sent from server to " -":code:`self.bst`, and then update model weights on local training data " -"with function :code:`local_boost` as follows:" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build up " +"the first set of trees. the returned Booster object and config are stored " +"in :code:`self.bst` and :code:`self.config`, respectively. From the second " +"round, we load the global model sent from server to :code:`self.bst`, and " +"then update model weights on local training data with function :code:" +"`local_boost` as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"Given :code:`num_local_round`, we update trees by calling " -":code:`self.bst.update` method. After training, the last " -":code:`N=num_local_round` trees will be extracted to send to the server." +"Given :code:`num_local_round`, we update trees by calling :code:`self.bst." +"update` method. After training, the last :code:`N=num_local_round` trees " +"will be extracted to send to the server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " -"conduct evaluation on valid set. The AUC value will be returned." +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to conduct " +"evaluation on valid set. The AUC value will be returned." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one" -" line to actually run this client:" +"Now, we can create an instance of our class :code:`XgbClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"That's it for the client. We only have to implement :code:`Client`and " -"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " -"tells the client which server to connect to. In our case we can run the " -"server and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client`and call :" +"code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` tells the " +"client which server to connect to. In our case we can run the server and the " +"client on the same machine, therefore we use :code:`\"[::]:8080\"`. If we " +"run a truly federated workload with the server and clients running on " +"different machines, all that needs to change is the :code:`server_address` " +"we point the client at." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" "These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version" -" of the model back to each *client* to finish a complete FL round." +"produce a better model. Finally, the *server* sends this improved version of " +"the model back to each *client* to finish a complete FL round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from " -":code:`flwr.server.strategy`." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from :" +"code:`flwr.server.strategy`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:316 @@ -18784,9 +18263,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"We use two clients for this example. An " -":code:`evaluate_metrics_aggregation` function is defined to collect and " -"wighted average the AUC values from clients." +"We use two clients for this example. An :code:`evaluate_metrics_aggregation` " +"function is defined to collect and wighted average the AUC values from " +"clients." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:342 @@ -18799,16 +18278,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"You must be curious about how bagging aggregation works. Let's look into " -"the details." +"You must be curious about how bagging aggregation works. Let's look into the " +"details." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " -":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." -" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " -"and :code:`evaluate` methods as follows:" +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define :code:" +"`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`. Then, we " +"override the :code:`aggregate_fit`, :code:`aggregate_evaluate` and :code:" +"`evaluate` methods as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:454 @@ -18820,10 +18299,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" "In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling " -":code:`_get_tree_nums`. Then, the fetched information will be aggregated." -" After that, the trees (containing model weights) are aggregated to " -"generate a new tree model." +"parallel trees for the current and previous model by calling :code:" +"`_get_tree_nums`. Then, the fetched information will be aggregated. After " +"that, the trees (containing model weights) are aggregated to generate a new " +"tree model." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:518 @@ -18839,16 +18318,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" "Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in " -":code:`metrics_distributed`. One can see that the average AUC increases " -"over FL rounds." +"XGBoost system. The AUC values can be checked in :code:" +"`metrics_distributed`. One can see that the average AUC increases over FL " +"rounds." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"The full `source code `_ for this example can be found in :code:`examples" -"/xgboost-quickstart`." +"The full `source code `_ for this example can be found in :code:`examples/" +"xgboost-quickstart`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:594 @@ -18857,15 +18336,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:596 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time" -" to run some more comprehensive experiments by customising the " -"experimental settings. In the xgboost-comprehensive example (`full code " -"`_), we provide more options to define various experimental" -" setups, including aggregation strategies, data partitioning and " -"centralised/distributed evaluation. We also support :doc:`Flower " -"simulation ` making it easy to simulate large " -"client cohorts in a resource-aware manner. Let's take a look!" +"Now that you have known how federated XGBoost work with Flower, it's time to " +"run some more comprehensive experiments by customising the experimental " +"settings. In the xgboost-comprehensive example (`full code `_), we provide " +"more options to define various experimental setups, including aggregation " +"strategies, data partitioning and centralised/distributed evaluation. We " +"also support :doc:`Flower simulation ` making it " +"easy to simulate large client cohorts in a resource-aware manner. Let's take " +"a look!" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:603 @@ -18874,41 +18353,40 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, " -"which performs FL in a client-by-client fashion. Instead of aggregating " -"multiple clients, there is only one single client participating in the " -"training per round in the cyclic training scenario. The trained local " -"XGBoost trees will be passed to the next client as an initialised model " -"for next round's boosting." +"In addition to bagging aggregation, we offer a cyclic training scheme, which " +"performs FL in a client-by-client fashion. Instead of aggregating multiple " +"clients, there is only one single client participating in the training per " +"round in the cyclic training scenario. The trained local XGBoost trees will " +"be passed to the next client as an initialised model for next round's " +"boosting." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"To do this, we first customise a :code:`ClientManager` in " -":code:`server_utils.py`:" +"To do this, we first customise a :code:`ClientManager` in :code:" +"`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"The customised :code:`ClientManager` samples all available clients in " -"each FL round based on the order of connection to the server. Then, we " -"define a new strategy :code:`FedXgbCyclic` in " -":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " -"select only one client in given round and pass the received model to next" -" client." +"The customised :code:`ClientManager` samples all available clients in each " +"FL round based on the order of connection to the server. Then, we define a " +"new strategy :code:`FedXgbCyclic` in :code:`flwr.server.strategy." +"fedxgb_cyclic.py`, in order to sequentially select only one client in given " +"round and pass the received model to next client." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" "Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model" -" by overriding :code:`aggregate_fit`." +"Instead, we just make a copy of the received client model as global model by " +"overriding :code:`aggregate_fit`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" -" methods ensure the clients to be sequentially selected given FL round:" +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate` " +"methods ensure the clients to be sequentially selected given FL round:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:757 @@ -18917,11 +18395,11 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" -" to instantiate the data partitioner based on the given " -":code:`num_partitions` and :code:`partitioner_type`. Currently, we " -"provide four supported partitioner type to simulate the uniformity/non-" -"uniformity in data quantity (uniform, linear, square, exponential)." +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner` to " +"instantiate the data partitioner based on the given :code:`num_partitions` " +"and :code:`partitioner_type`. Currently, we provide four supported " +"partitioner type to simulate the uniformity/non-uniformity in data quantity " +"(uniform, linear, square, exponential)." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:790 @@ -18930,23 +18408,23 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:792 msgid "" -"To facilitate centralised evaluation, we define a function in " -":code:`server_utils.py`:" +"To facilitate centralised evaluation, we define a function in :code:" +"`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"This function returns a evaluation function which instantiates a " -":code:`Booster` object and loads the global model weights to it. The " -"evaluation is conducted by calling :code:`eval_set()` method, and the " -"tested AUC value is reported." +"This function returns a evaluation function which instantiates a :code:" +"`Booster` object and loads the global model weights to it. The evaluation is " +"conducted by calling :code:`eval_set()` method, and the tested AUC value is " +"reported." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:827 msgid "" -"As for distributed evaluation on the clients, it's same as the quick-" -"start example by overriding the :code:`evaluate()` method insides the " -":code:`XgbClient` class in :code:`client_utils.py`." +"As for distributed evaluation on the clients, it's same as the quick-start " +"example by overriding the :code:`evaluate()` method insides the :code:" +"`XgbClient` class in :code:`client_utils.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:831 @@ -18956,21 +18434,21 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a" -" single machine or a cluster of machines." +"capabilities of Flower to simulate federated XGBoost training on either a " +"single machine or a cluster of machines." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"After importing all required packages, we define a :code:`main()` " -"function to perform the simulation process:" +"After importing all required packages, we define a :code:`main()` function " +"to perform the simulation process:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" "We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, " -"the clients won't need to pre-process their partitions again." +"processed data is stored in a :code:`list`. After the simulation begins, the " +"clients won't need to pre-process their partitions again." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:924 @@ -18979,8 +18457,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"After that, we start the simulation by calling " -":code:`fl.simulation.start_simulation`:" +"After that, we start the simulation by calling :code:`fl.simulation." +"start_simulation`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:995 @@ -18995,18 +18473,18 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1040 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server " -"and simulation, allowing users to specify different experimental " -"settings. Let's first see the sever side:" +"In :code:`utils.py`, we define the arguments parsers for clients, server and " +"simulation, allowing users to specify different experimental settings. Let's " +"first see the sever side:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1086 msgid "" "This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and" -" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" -" will do centralised evaluation and all functionalities for client " -"evaluation will be disabled." +"clients / FL rounds / participating clients / clients for evaluation, and " +"evaluation fashion. Note that with :code:`--centralised-eval`, the sever " +"will do centralised evaluation and all functionalities for client evaluation " +"will be disabled." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1090 @@ -19015,11 +18493,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1144 msgid "" -"This defines various options for client data partitioning. Besides, " -"clients also have an option to conduct evaluation on centralised test set" -" by setting :code:`--centralised-eval`, as well as an option to perform " -"scaled learning rate based on the number of clients by setting :code" -":`--scaled-lr`." +"This defines various options for client data partitioning. Besides, clients " +"also have an option to conduct evaluation on centralised test set by " +"setting :code:`--centralised-eval`, as well as an option to perform scaled " +"learning rate based on the number of clients by setting :code:`--scaled-lr`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1148 @@ -19036,9 +18513,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1231 msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 " -"clients with exponential distribution for 50 rounds, we first start the " -"server as below:" +"To run a centralised evaluated experiment with bagging strategy on 5 clients " +"with exponential distribution for 50 rounds, we first start the server as " +"below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1238 @@ -19051,9 +18528,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1250 msgid "" -"The full `code `_ for this comprehensive example can be found in" -" :code:`examples/xgboost-comprehensive`." +"The full `code `_ for this comprehensive example can be found in :code:" +"`examples/xgboost-comprehensive`." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 @@ -19064,19 +18541,18 @@ msgstr "" msgid "" "Welcome to the third part of the Flower federated learning tutorial. In " "previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies " -"can be used to customize the execution on both the server and the clients" -" (`part 2 `__)." +"PyTorch and Flower (`part 1 `__) and we learned how strategies can be " +"used to customize the execution on both the server and the clients (`part 2 " +"`__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"In this notebook, we'll continue to customize the federated learning " -"system we built previously by creating a custom version of FedAvg (again," -" using `Flower `__ and `PyTorch " -"`__)." +"In this notebook, we'll continue to customize the federated learning system " +"we built previously by creating a custom version of FedAvg (again, using " +"`Flower `__ and `PyTorch `__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 @@ -19084,11 +18560,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the Flower community on Slack to connect, ask questions, and get help: " -"`Join Slack `__ 🌼 We'd love to hear from " -"you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"Flower community on Slack to connect, ask questions, and get help: `Join " +"Slack `__ 🌼 We'd love to hear from you in the " +"``#introductions`` channel! And if anything is unclear, head over to the " +"``#questions`` channel." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 @@ -19134,14 +18610,14 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " -"GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware acclerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 @@ -19153,11 +18629,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``. We introduce a new parameter" -" ``num_clients`` which allows us to call ``load_datasets`` with different" -" numbers of clients." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``. We introduce a new parameter " +"``num_clients`` which allows us to call ``load_datasets`` with different " +"numbers of clients." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 @@ -19170,8 +18646,8 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"Let's continue with the usual model definition (including " -"``set_parameters`` and ``get_parameters``), training and test functions:" +"Let's continue with the usual model definition (including ``set_parameters`` " +"and ``get_parameters``), training and test functions:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 @@ -19182,10 +18658,10 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"To implement the Flower client, we (again) create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " -"``cid`` to the client and use it log additional details:" +"To implement the Flower client, we (again) create a subclass of ``flwr." +"client.NumPyClient`` and implement the three methods ``get_parameters``, " +"``fit``, and ``evaluate``. Here, we also pass the ``cid`` to the client and " +"use it log additional details:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 @@ -19198,11 +18674,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher" -" learning rate (potentially also other hyperparameters) to the optimizer " -"of a fraction of the clients. We will keep the sampling of the clients as" -" it is in ``FedAvg`` and then change the configuration dictionary (one of" -" the ``FitIns`` attributes)." +"Let’s overwrite the ``configure_fit`` method such that it passes a higher " +"learning rate (potentially also other hyperparameters) to the optimizer of a " +"fraction of the clients. We will keep the sampling of the clients as it is " +"in ``FedAvg`` and then change the configuration dictionary (one of the " +"``FitIns`` attributes)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 @@ -19219,13 +18695,13 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom" -" strategy enables granular control over client node configuration, result" -" aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``." -" To make custom strategies even more powerful, you can pass custom " -"functions to the constructor of your new class (``__init__``) and then " -"call these functions whenever needed." +"In this notebook, we’ve seen how to implement a custom strategy. A custom " +"strategy enables granular control over client node configuration, result " +"aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``. To " +"make custom strategies even more powerful, you can pass custom functions to " +"the constructor of your new class (``__init__``) and then call these " +"functions whenever needed." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 @@ -19234,8 +18710,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"Before you continue, make sure to join the Flower community on Slack: " -"`Join Slack `__" +"Before you continue, make sure to join the Flower community on Slack: `Join " +"Slack `__" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 @@ -19244,16 +18720,15 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd " -"also love to hear who you are in ``#introductions``!" +"There's a dedicated ``#questions`` channel if you need help, but we'd also " +"love to hear who you are in ``#introductions``!" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 " -"`__ introduces ``Client``, the flexible API underlying " -"``NumPyClient``." +"The `Flower Federated Learning Tutorial - Part 4 `__ introduces " +"``Client``, the flexible API underlying ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 @@ -19262,26 +18737,26 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In " -"the previous parts of this tutorial, we introduced federated learning " -"with PyTorch and Flower (`part 1 `__), we learned how " -"strategies can be used to customize the execution on both the server and " -"the clients (`part 2 `__), and we built our own " -"custom strategy from scratch (`part 3 `__)." +"Welcome to the fourth part of the Flower federated learning tutorial. In the " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__), we learned how strategies can be used " +"to customize the execution on both the server and the clients (`part 2 " +"`__), and we built our own custom strategy from scratch (`part " +"3 `__)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new " -"baseclass for building clients, simply named ``Client``. In previous " -"parts of this tutorial, we've based our client on ``NumPyClient``, a " -"convenience class which makes it easy to work with machine learning " -"libraries that have good NumPy interoperability. With ``Client``, we gain" -" a lot of flexibility that we didn't have before, but we'll also have to " -"do a few things the we didn't have to do before." +"In this notebook, we revisit ``NumPyClient`` and introduce a new baseclass " +"for building clients, simply named ``Client``. In previous parts of this " +"tutorial, we've based our client on ``NumPyClient``, a convenience class " +"which makes it easy to work with machine learning libraries that have good " +"NumPy interoperability. With ``Client``, we gain a lot of flexibility that " +"we didn't have before, but we'll also have to do a few things the we didn't " +"have to do before." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 @@ -19297,9 +18772,9 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 @@ -19308,10 +18783,10 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"So far, we've implemented our client by subclassing " -"``flwr.client.NumPyClient``. The three methods we implemented are " -"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " -"creation of instances of this class in a function called ``client_fn``:" +"So far, we've implemented our client by subclassing ``flwr.client." +"NumPyClient``. The three methods we implemented are ``get_parameters``, " +"``fit``, and ``evaluate``. Finally, we wrap the creation of instances of " +"this class in a function called ``client_fn``:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 @@ -19333,25 +18808,24 @@ msgid "" "Let's dive a little bit deeper and discuss how Flower executes this " "simulation. Whenever a client is selected to do some work, " "``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and " -"the data)." +"instance of our ``FlowerNumPyClient`` (along with loading the model and the " +"data)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" "But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " -"makes it look like a subclass of ``flwr.client.Client``, not " -"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " -"know how to handle ``NumPyClient``'s, it only knows how to handle " -"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " -"top of ``Client``." +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to makes " +"it look like a subclass of ``flwr.client.Client``, not ``flwr.client." +"NumPyClient``. In fact, the Flower core framework doesn't know how to handle " +"``NumPyClient``'s, it only knows how to handle ``Client``'s. ``NumPyClient`` " +"is just a convenience abstraction built on top of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on " -"top of ``Client``." +"Instead of building on top of ``NumPyClient``, we can directly build on top " +"of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 @@ -19360,14 +18834,13 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 msgid "" -"Let's try to do the same thing using ``Client`` instead of " -"``NumPyClient``." +"Let's try to do the same thing using ``Client`` instead of ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta " -"make sure our new ``Client``-based client works, right?" +"Before we discuss the code in more detail, let's try to run it! Gotta make " +"sure our new ``Client``-based client works, right?" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 @@ -19378,40 +18851,40 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"First of all, it's more code. But why? The difference comes from the fact " +"that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the network, " +"it eventually needs to turn these parameters into ``bytes``. Turning " +"parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " "serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." +"``ndarray``'s) is called deserialization. Flower needs to do both: it needs " +"to serialize parameters on the server-side and send them to the client, the " +"client needs to deserialize them to use them for local training, and then " +"serialize the updated parameters again to send them back to the server, " +"which (finally!) deserializes them again in order to aggregate them with the " +"updates received from other clients." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" "The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It " -"can do so because it expects you to return parameters as NumPy ndarray's," -" and it knows how to handle these. This makes working with machine " -"learning libraries that have good NumPy support (most of them) a breeze." +"NumPyClient takes care of serialization and deserialization for you. It can " +"do so because it expects you to return parameters as NumPy ndarray's, and it " +"knows how to handle these. This makes working with machine learning " +"libraries that have good NumPy support (most of them) a breeze." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"In terms of API, there's one major difference: all methods in Client take " +"exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return exactly " +"one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " "``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return " +"values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These ``*Ins`` " +"and ``*Res`` objects in ``Client`` wrap all the individual values you're " +"used to from ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 @@ -19428,17 +18901,16 @@ msgstr "" msgid "" "But first what is serialization? Serialization is just the process of " "converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an " -"object. This is very useful for network communication. Indeed, without " +"deserialization is the process of converting raw bytes back into an object. " +"This is very useful for network communication. Indeed, without " "serialization, you could not just a Python object through the internet." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 msgid "" -"Federated Learning relies heavily on internet communication for training " -"by sending Python objects back and forth between the clients and the " -"server. This means that serialization is an essential part of Federated " -"Learning." +"Federated Learning relies heavily on internet communication for training by " +"sending Python objects back and forth between the clients and the server. " +"This means that serialization is an essential part of Federated Learning." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 @@ -19458,15 +18930,15 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"This is where the real serialization/deserialization will happen, " -"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"This is where the real serialization/deserialization will happen, especially " +"in ``ndarray_to_sparse_bytes`` for serialization and " "``sparse_bytes_to_ndarray`` for deserialization." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert " -"our arrays." +"Note that we imported the ``scipy.sparse`` library in order to convert our " +"arrays." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 @@ -19475,30 +18947,28 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " -"will just have to call our custom functions in our " -"``flwr.client.Client``." +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we will " +"just have to call our custom functions in our ``flwr.client.Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 msgid "" "Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` " -"defined above." +"from our network using our custom ``ndarrays_to_sparse_parameters`` defined " +"above." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" "In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we " -"need to serialize our local results with " -"``ndarrays_to_sparse_parameters``." +"server using our custom ``sparse_parameters_to_ndarrays`` and then we need " +"to serialize our local results with ``ndarrays_to_sparse_parameters``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters " -"with our custom function." +"In ``evaluate``, we will only need to deserialize the global parameters with " +"our custom function." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 @@ -19507,11 +18977,10 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change " -"the serialization and deserialization here, we only need to reimplement " -"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" -" functions of the strategy will be inherited from the super class " -"``FedAvg``." +"For this example, we will just use ``FedAvg`` as a strategy. To change the " +"serialization and deserialization here, we only need to reimplement the " +"``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other " +"functions of the strategy will be inherited from the super class ``FedAvg``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 @@ -19536,19 +19005,19 @@ msgstr "" msgid "" "In this part of the tutorial, we've seen how we can build clients by " "subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine " -"learning libraries that have good NumPy interoperability. ``Client`` is a" -" more flexible abstraction that allows us to do things that are not " -"possible in ``NumPyClient``. In order to do so, it requires us to handle " -"parameter serialization and deserialization ourselves." +"convenience abstraction that makes it easier to work with machine learning " +"libraries that have good NumPy interoperability. ``Client`` is a more " +"flexible abstraction that allows us to do things that are not possible in " +"``NumPyClient``. In order to do so, it requires us to handle parameter " +"serialization and deserialization ourselves." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"This is the final part of the Flower tutorial (for now!), " -"congratulations! You're now well equipped to understand the rest of the " -"documentation. There are many topics we didn't cover in the tutorial, we " -"recommend the following resources:" +"This is the final part of the Flower tutorial (for now!), congratulations! " +"You're now well equipped to understand the rest of the documentation. There " +"are many topics we didn't cover in the tutorial, we recommend the following " +"resources:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 @@ -19557,20 +19026,20 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"`Check out Flower Code Examples " -"`__" +"`Check out Flower Code Examples `__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"`Use Flower Baselines for your research " -"`__" +"`Use Flower Baselines for your research `__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"`Watch Flower Summit 2023 videos `__" +"`Watch Flower Summit 2023 videos `__" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 @@ -19585,10 +19054,9 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 msgid "" "In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In " -"part 1, we use PyTorch for the model training pipeline and data loading. " -"In part 2, we continue to federate the PyTorch-based pipeline using " -"Flower." +"`Flower Datasets `__ and PyTorch. In part " +"1, we use PyTorch for the model training pipeline and data loading. In part " +"2, we continue to federate the PyTorch-based pipeline using Flower." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 @@ -19605,20 +19073,19 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 msgid "" "Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " -"(``flwr``):" +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower (``flwr``):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" -" GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware accelerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 @@ -19627,51 +19094,50 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 msgid "" -"Federated learning can be applied to many different types of tasks across" -" different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular " -"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " -"distinguish between images from ten different classes: 'airplane', " -"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " -"'truck'." +"Federated learning can be applied to many different types of tasks across " +"different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular CIFAR-10 " +"dataset. CIFAR-10 can be used to train image classifiers that distinguish " +"between images from ten different classes: 'airplane', 'automobile', 'bird', " +"'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and 'truck'." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" "We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the" -" original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely " -"for experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the " -"data is naturally partitioned)." +"called the \"cross-silo\" setting in federated learning) by splitting the " +"original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely for " +"experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the data " +"is naturally partitioned)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 msgid "" -"Each organization will act as a client in the federated learning system. " -"So having ten organizations participate in a federation means having ten " +"Each organization will act as a client in the federated learning system. So " +"having ten organizations participate in a federation means having ten " "clients connected to the federated learning server." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 msgid "" "Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training " -"and test set for each edge device and wrap each of them into a PyTorch " +"datasets`` that partitions the CIFAR-10. We will create small training and " +"test set for each edge device and wrap each of them into a PyTorch " "``DataLoader``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 msgid "" "We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten " -"different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4000 training examples and 1000 validation examples. There's also a " -"single ``testloader`` (we did not split the test set). Again, this is " -"only necessary for building research or educational systems, actual " -"federated learning systems have their data naturally distributed across " -"multiple partitions." +"(``trainloaders`` and ``valloaders``) representing the data of ten different " +"organizations. Each ``trainloader``/``valloader`` pair contains 4000 " +"training examples and 1000 validation examples. There's also a single " +"``testloader`` (we did not split the test set). Again, this is only " +"necessary for building research or educational systems, actual federated " +"learning systems have their data naturally distributed across multiple " +"partitions." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 @@ -19685,8 +19151,8 @@ msgid "" "The output above shows a random batch of images from the first " "``trainloader`` in our list of ten ``trainloaders``. It also prints the " "labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another " -"batch of images." +"we've seen above). If you run the cell again, you should see another batch " +"of images." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 @@ -19699,8 +19165,8 @@ msgid "" "network. This introduction assumes basic familiarity with PyTorch, so it " "doesn't cover the PyTorch-related aspects in full detail. If you want to " "dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ " -"`__." +"MINUTE BLITZ `__." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 @@ -19709,9 +19175,9 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"We use the simple CNN described in the `PyTorch tutorial " -"`__:" +"We use the simple CNN described in the `PyTorch tutorial `__:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 @@ -19725,20 +19191,19 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" "We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train " -"the model on the dataset of one of our organizations " -"(``trainloaders[0]``). This simulates the reality of most machine " -"learning projects today: each organization has their own data and trains " -"models only on this internal data:" +"training function, and a test function. Let's put them together to train the " +"model on the dataset of one of our organizations (``trainloaders[0]``). This " +"simulates the reality of most machine learning projects today: each " +"organization has their own data and trains models only on this internal data:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " -"in a test set accuracy of about 41%, which is not good, but at the same " -"time, it doesn't really matter for the purposes of this tutorial. The " -"intent was just to show a simplistic centralized training pipeline that " -"sets the stage for what comes next - federated learning!" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result in " +"a test set accuracy of about 41%, which is not good, but at the same time, " +"it doesn't really matter for the purposes of this tutorial. The intent was " +"just to show a simplistic centralized training pipeline that sets the stage " +"for what comes next - federated learning!" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 @@ -19747,11 +19212,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was " -"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." -" Next, we'll simulate a situation where we have multiple datasets in " -"multiple organizations and where we train a model over these " -"organizations using federated learning." +"Step 1 demonstrated a simple centralized training pipeline. All data was in " +"one place (i.e., a single ``trainloader`` and a single ``valloader``). Next, " +"we'll simulate a situation where we have multiple datasets in multiple " +"organizations and where we train a model over these organizations using " +"federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 @@ -19760,30 +19225,29 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"In federated learning, the server sends the global model parameters to " -"the client, and the client updates the local model with the parameters " -"received from the server. It then trains the model on the local data " -"(which changes the model parameters locally) and sends the " -"updated/changed model parameters back to the server (or, alternatively, " -"it sends just the gradients back to the server, not the full model " -"parameters)." +"In federated learning, the server sends the global model parameters to the " +"client, and the client updates the local model with the parameters received " +"from the server. It then trains the model on the local data (which changes " +"the model parameters locally) and sends the updated/changed model parameters " +"back to the server (or, alternatively, it sends just the gradients back to " +"the server, not the full model parameters)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" "We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the" -" local model: ``set_parameters`` and ``get_parameters``. The following " -"two functions do just that for the PyTorch model above." +"received from the server and to get the updated model parameters from the " +"local model: ``set_parameters`` and ``get_parameters``. The following two " +"functions do just that for the PyTorch model above." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 msgid "" -"The details of how this works are not really important here (feel free to" -" consult the PyTorch documentation if you want to learn more). In " -"essence, we use ``state_dict`` to access PyTorch model parameter tensors." -" The parameter tensors are then converted to/from a list of NumPy " -"ndarray's (which Flower knows how to serialize/deserialize):" +"The details of how this works are not really important here (feel free to " +"consult the PyTorch documentation if you want to learn more). In essence, we " +"use ``state_dict`` to access PyTorch model parameter tensors. The parameter " +"tensors are then converted to/from a list of NumPy ndarray's (which Flower " +"knows how to serialize/deserialize):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 @@ -19792,19 +19256,18 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"With that out of the way, let's move on to the interesting part. " -"Federated learning systems consist of a server and multiple clients. In " -"Flower, we create clients by implementing subclasses of " -"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " -"``NumPyClient`` in this tutorial because it is easier to implement and " -"requires us to write less boilerplate." +"With that out of the way, let's move on to the interesting part. Federated " +"learning systems consist of a server and multiple clients. In Flower, we " +"create clients by implementing subclasses of ``flwr.client.Client`` or " +"``flwr.client.NumPyClient``. We use ``NumPyClient`` in this tutorial because " +"it is easier to implement and requires us to write less boilerplate." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"To implement the Flower client, we create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``:" +"To implement the Flower client, we create a subclass of ``flwr.client." +"NumPyClient`` and implement the three methods ``get_parameters``, ``fit``, " +"and ``evaluate``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 @@ -19814,15 +19277,14 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" "``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters " -"to the server" +"parameters on the local data, and return the (updated) model parameters to " +"the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the " -"model parameters on the local data, and return the evaluation result to " -"the server" +"``evaluate``: Receive model parameters from the server, evaluate the model " +"parameters on the local data, and return the evaluation result to the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 @@ -19835,16 +19297,15 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" "Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." +"performed and allows Flower to call the local training/evaluation through " +"``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a " +"*single client* in our federated learning system. Federated learning systems " +"have multiple clients (otherwise, there's not much to federate), so each " +"client will be represented by its own instance of ``FlowerClient``. If we " +"have, for example, three clients in our workload, then we'd have three " +"instances of ``FlowerClient``. Flower calls ``FlowerClient.fit`` on the " +"respective instance when the server selects a particular client for training " +"(and ``FlowerClient.evaluate`` for evaluation)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 @@ -19853,13 +19314,13 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In this notebook, we want to simulate a federated learning system with 10" -" clients on a single machine. This means that the server and all 10 " -"clients will live on a single machine and share resources such as CPU, " -"GPU, and memory. Having 10 clients would mean having 10 instances of " -"``FlowerClient`` in memory. Doing this on a single machine can quickly " -"exhaust the available memory resources, even if only a subset of these " -"clients participates in a single round of federated learning." +"In this notebook, we want to simulate a federated learning system with 10 " +"clients on a single machine. This means that the server and all 10 clients " +"will live on a single machine and share resources such as CPU, GPU, and " +"memory. Having 10 clients would mean having 10 instances of ``FlowerClient`` " +"in memory. Doing this on a single machine can quickly exhaust the available " +"memory resources, even if only a subset of these clients participates in a " +"single round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 @@ -19868,14 +19329,14 @@ msgid "" "multiple machines, Flower, therefore, provides special simulation " "capabilities that create ``FlowerClient`` instances only when they are " "actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" +"framework to create clients when necessary, we need to implement a function " +"called ``client_fn`` that creates a ``FlowerClient`` instance on demand. " +"Flower calls ``client_fn`` whenever it needs an instance of one particular " +"client to call ``fit`` or ``evaluate`` (those instances are usually " +"discarded after use, so they should not keep any local state). Clients are " +"identified by a client ID, or short ``cid``. The ``cid`` can be used, for " +"example, to load different local data partitions for different clients, as " +"can be seen below:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 @@ -19884,31 +19345,31 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"We now have the class ``FlowerClient`` which defines client-side " -"training/evaluation and ``client_fn`` which allows Flower to create " -"``FlowerClient`` instances whenever it needs to call ``fit`` or " -"``evaluate`` on one particular client. The last step is to start the " -"actual simulation using ``flwr.simulation.start_simulation``." +"We now have the class ``FlowerClient`` which defines client-side training/" +"evaluation and ``client_fn`` which allows Flower to create ``FlowerClient`` " +"instances whenever it needs to call ``fit`` or ``evaluate`` on one " +"particular client. The last step is to start the actual simulation using " +"``flwr.simulation.start_simulation``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 msgid "" "The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the " -"number of clients to simulate (``num_clients``), the number of federated " -"learning rounds (``num_rounds``), and the strategy. The strategy " -"encapsulates the federated learning approach/algorithm, for example, " -"*Federated Averaging* (FedAvg)." +"them the ``client_fn`` used to create ``FlowerClient`` instances, the number " +"of clients to simulate (``num_clients``), the number of federated learning " +"rounds (``num_rounds``), and the strategy. The strategy encapsulates the " +"federated learning approach/algorithm, for example, *Federated Averaging* " +"(FedAvg)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" "Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated" -" learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last " -"step is the actual call to ``start_simulation`` which - you guessed it - " -"starts the simulation:" +"strategy implementations to customize nearly all aspects of the federated " +"learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last step " +"is the actual call to ``start_simulation`` which - you guessed it - starts " +"the simulation:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 @@ -19922,20 +19383,20 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 #, python-format msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 " -"clients (``num_clients=10``). Flower then goes ahead an asks the " -"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " -"select 100% of the available clients (``fraction_fit=1.0``), so it goes " -"ahead and selects 10 random clients (i.e., 100% of 10)." +"When we call ``start_simulation``, we tell Flower that there are 10 clients " +"(``num_clients=10``). Flower then goes ahead an asks the ``FedAvg`` strategy " +"to select clients. ``FedAvg`` knows that it should select 100% of the " +"available clients (``fraction_fit=1.0``), so it goes ahead and selects 10 " +"random clients (i.e., 100% of 10)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 msgid "" -"Flower then asks the selected 10 clients to train the model. When the " -"server receives the model parameter updates from the clients, it hands " -"those updates over to the strategy (*FedAvg*) for aggregation. The " -"strategy aggregates those updates and returns the new global model, which" -" then gets used in the next round of federated learning." +"Flower then asks the selected 10 clients to train the model. When the server " +"receives the model parameter updates from the clients, it hands those " +"updates over to the strategy (*FedAvg*) for aggregation. The strategy " +"aggregates those updates and returns the new global model, which then gets " +"used in the next round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 @@ -19944,28 +19405,27 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` " -"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"You may have noticed that all metrics except for ``losses_distributed`` are " +"empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 msgid "" -"Flower can automatically aggregate losses returned by individual clients," -" but it cannot do the same for metrics in the generic metrics dictionary " -"(the one with the ``accuracy`` key). Metrics dictionaries can contain " -"very different kinds of metrics and even key/value pairs that are not " -"metrics at all, so the framework does not (and can not) know how to " -"handle these automatically." +"Flower can automatically aggregate losses returned by individual clients, " +"but it cannot do the same for metrics in the generic metrics dictionary (the " +"one with the ``accuracy`` key). Metrics dictionaries can contain very " +"different kinds of metrics and even key/value pairs that are not metrics at " +"all, so the framework does not (and can not) know how to handle these " +"automatically." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 msgid "" -"As users, we need to tell the framework how to handle/aggregate these " -"custom metrics, and we do so by passing metric aggregation functions to " -"the strategy. The strategy will then call these functions whenever it " -"receives fit or evaluate metrics from clients. The two possible functions" -" are ``fit_metrics_aggregation_fn`` and " -"``evaluate_metrics_aggregation_fn``." +"As users, we need to tell the framework how to handle/aggregate these custom " +"metrics, and we do so by passing metric aggregation functions to the " +"strategy. The strategy will then call these functions whenever it receives " +"fit or evaluate metrics from clients. The two possible functions are " +"``fit_metrics_aggregation_fn`` and ``evaluate_metrics_aggregation_fn``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 @@ -19983,17 +19443,17 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 msgid "" "We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom" -" evaluation metrics and calculates a single ``accuracy`` metric across " -"all clients on the server side." +"evaluation. It uses the ``weighted_average`` function to aggregate custom " +"evaluation metrics and calculates a single ``accuracy`` metric across all " +"clients on the server side." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 msgid "" "The other two categories of metrics (``losses_centralized`` and " "``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial " -"will cover centralized evaluation." +"centralized evaluation is being used. Part two of the Flower tutorial will " +"cover centralized evaluation." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 @@ -20003,28 +19463,28 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 msgid "" -"Congratulations, you just trained a convolutional neural network, " -"federated over 10 clients! With that, you understand the basics of " -"federated learning with Flower. The same approach you've seen can be used" -" with other machine learning frameworks (not just PyTorch) and tasks (not" -" just CIFAR-10 images classification), for example NLP with Hugging Face " -"Transformers or speech with SpeechBrain." +"Congratulations, you just trained a convolutional neural network, federated " +"over 10 clients! With that, you understand the basics of federated learning " +"with Flower. The same approach you've seen can be used with other machine " +"learning frameworks (not just PyTorch) and tasks (not just CIFAR-10 images " +"classification), for example NLP with Hugging Face Transformers or speech " +"with SpeechBrain." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. " -"Want to customize your strategy? Initialize parameters on the server " -"side? Or evaluate the aggregated model on the server side? We'll cover " -"all this and more in the next tutorial." +"In the next notebook, we're going to cover some more advanced concepts. Want " +"to customize your strategy? Initialize parameters on the server side? Or " +"evaluate the aggregated model on the server side? We'll cover all this and " +"more in the next tutorial." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 " -"`__ goes into more depth about strategies and all " -"the advanced things you can build with them." +"The `Flower Federated Learning Tutorial - Part 2 `__ goes " +"into more depth about strategies and all the advanced things you can build " +"with them." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 @@ -20034,16 +19494,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 msgid "" "Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and" -" Flower (`part 1 `__)." +"parts of this tutorial, we introduced federated learning with PyTorch and " +"Flower (`part 1 `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 msgid "" -"In this notebook, we'll begin to customize the federated learning system " -"we built in the introductory notebook (again, using `Flower " -"`__ and `PyTorch `__)." +"In this notebook, we'll begin to customize the federated learning system we " +"built in the introductory notebook (again, using `Flower `__ and `PyTorch `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 @@ -20057,8 +19517,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 msgid "" "So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of " -"new features." +"introductory notebook. With that, we're ready to introduce a number of new " +"features." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 @@ -20067,16 +19527,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 msgid "" -"Flower, by default, initializes the global model by asking one random " -"client for the initial parameters. In many cases, we want more control " -"over parameter initialization though. Flower therefore allows you to " -"directly pass the initial parameters to the Strategy:" +"Flower, by default, initializes the global model by asking one random client " +"for the initial parameters. In many cases, we want more control over " +"parameter initialization though. Flower therefore allows you to directly " +"pass the initial parameters to the Strategy:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" -" from asking one of the clients for the initial parameters. If we look " +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower " +"from asking one of the clients for the initial parameters. If we look " "closely, we can see that the logs do not show any calls to the " "``FlowerClient.get_parameters`` method." msgstr "" @@ -20087,17 +19547,17 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number " -"of arguments, amongst them the ``client_fn`` used to create " -"``FlowerClient`` instances, the number of clients to simulate " -"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +"We've seen the function ``start_simulation`` before. It accepts a number of " +"arguments, amongst them the ``client_fn`` used to create ``FlowerClient`` " +"instances, the number of clients to simulate ``num_clients``, the number of " +"rounds ``num_rounds``, and the strategy." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 msgid "" "The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " -"strategy this time:" +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different strategy " +"this time:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 @@ -20106,9 +19566,9 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the " -"client-side. Client-side and server-side evaluation are similar in some " -"ways, but different in others." +"Flower can evaluate the aggregated model on the server-side or on the client-" +"side. Client-side and server-side evaluation are similar in some ways, but " +"different in others." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 @@ -20116,33 +19576,33 @@ msgid "" "**Centralized Evaluation** (or *server-side evaluation*) is conceptually " "simple: it works the same way that evaluation in centralized machine " "learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly " -"aggregated model after each round of training without having to send the " -"model to clients. We're also fortunate in the sense that our entire " -"evaluation dataset is available at all times." +"evaluation purposes, then that's great. We can evaluate the newly aggregated " +"model after each round of training without having to send the model to " +"clients. We're also fortunate in the sense that our entire evaluation " +"dataset is available at all times." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, " -"but also more powerful: it doesn't require a centralized dataset and " -"allows us to evaluate models over a larger set of data, which often " -"yields more realistic evaluation results. In fact, many scenarios require" -" us to use **Federated Evaluation** if we want to get representative " -"evaluation results at all. But this power comes at a cost: once we start " -"to evaluate on the client side, we should be aware that our evaluation " -"dataset can change over consecutive rounds of learning if those clients " -"are not always available. Moreover, the dataset held by each client can " -"also change over consecutive rounds. This can lead to evaluation results " -"that are not stable, so even if we would not change the model, we'd see " -"our evaluation results fluctuate over consecutive rounds." +"**Federated Evaluation** (or *client-side evaluation*) is more complex, but " +"also more powerful: it doesn't require a centralized dataset and allows us " +"to evaluate models over a larger set of data, which often yields more " +"realistic evaluation results. In fact, many scenarios require us to use " +"**Federated Evaluation** if we want to get representative evaluation results " +"at all. But this power comes at a cost: once we start to evaluate on the " +"client side, we should be aware that our evaluation dataset can change over " +"consecutive rounds of learning if those clients are not always available. " +"Moreover, the dataset held by each client can also change over consecutive " +"rounds. This can lead to evaluation results that are not stable, so even if " +"we would not change the model, we'd see our evaluation results fluctuate " +"over consecutive rounds." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 msgid "" "We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " -"how we can evaluate aggregated model parameters on the server-side:" +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see how " +"we can evaluate aggregated model parameters on the server-side:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 @@ -20151,50 +19611,48 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 msgid "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" +"In some situations, we want to configure client-side execution (training, " +"evaluation) from the server-side. One example for that is the server asking " +"the clients to train for a certain number of local epochs. Flower provides a " +"way to send configuration values from the server to the clients using a " +"dictionary. Let's look at an example where the clients receive values from " +"the server through the ``config`` parameter in ``fit`` (``config`` is also " +"available in ``evaluate``). The ``fit`` method receives the configuration " +"dictionary through the ``config`` parameter and can then read values from " +"this dictionary. In this example, it reads ``server_round`` and " +"``local_epochs`` and uses those values to improve the logging and configure " +"the number of local training epochs:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 msgid "" -"So how can we send this config dictionary from server to clients? The " -"built-in Flower Strategies provide way to do this, and it works similarly" -" to the way server-side evaluation works. We provide a function to the " -"strategy, and the strategy calls this function for every round of " -"federated learning:" +"So how can we send this config dictionary from server to clients? The built-" +"in Flower Strategies provide way to do this, and it works similarly to the " +"way server-side evaluation works. We provide a function to the strategy, and " +"the strategy calls this function for every round of federated learning:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before " -"starting the simulation:" +"Next, we'll just pass this function to the FedAvg strategy before starting " +"the simulation:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 msgid "" -"As we can see, the client logs now include the current round of federated" -" learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second" -" round of federated learning, and then for two epochs during the third " -"round." +"As we can see, the client logs now include the current round of federated " +"learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second " +"round of federated learning, and then for two epochs during the third round." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 msgid "" "Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " -"used this concept throughout this notebook without mentioning it " -"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" -" key/value pair as the third return value in ``evaluate``." +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and used " +"this concept throughout this notebook without mentioning it explicitly: our " +"``FlowerClient`` returns a dictionary containing a custom key/value pair as " +"the third return value in ``evaluate``." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 @@ -20211,14 +19669,13 @@ msgstr "" #, python-format msgid "" "We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is " -"quite small, we should probably train the model a bit longer, so we " -"configure the clients to perform 3 local training epochs. We should also " -"adjust the fraction of clients selected for training during each round " -"(we don't want all 1000 clients participating in every round), so we " -"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " -"available clients (so 50 clients) will be selected for training each " -"round:" +"examples. Given that the number of training examples on each client is quite " +"small, we should probably train the model a bit longer, so we configure the " +"clients to perform 3 local training epochs. We should also adjust the " +"fraction of clients selected for training during each round (we don't want " +"all 1000 clients participating in every round), so we adjust " +"``fraction_fit`` to ``0.05``, which means that only 5% of available clients " +"(so 50 clients) will be selected for training each round:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 @@ -20231,19 +19688,18 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 msgid "" -"In the later sections, we've seen how we can communicate arbitrary values" -" between server and clients to fully customize client-side execution. " -"With that capability, we built a large-scale Federated Learning " -"simulation using the Flower Virtual Client Engine and ran an experiment " -"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +"In the later sections, we've seen how we can communicate arbitrary values " +"between server and clients to fully customize client-side execution. With " +"that capability, we built a large-scale Federated Learning simulation using " +"the Flower Virtual Client Engine and ran an experiment involving 1000 " +"clients in the same workload - all in a Jupyter Notebook!" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 " -"`__ shows how to build a fully custom ``Strategy`` from " -"scratch." +"The `Flower Federated Learning Tutorial - Part 3 `__ shows how " +"to build a fully custom ``Strategy`` from scratch." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 @@ -20254,24 +19710,24 @@ msgstr "" msgid "" "In this tutorial, you will learn what federated learning is, build your " "first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated " -"learning systems that approach the current state of the art in the field." +"parts of the tutorial, you will be able to build advanced federated learning " +"systems that approach the current state of the art in the field." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " -"federated learning. Only a basic understanding of data science and Python" -" programming is assumed." +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with federated " +"learning. Only a basic understanding of data science and Python programming " +"is assumed." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the open-source Flower community on Slack to connect, ask questions, and " -"get help: `Join Slack `__ 🌼 We'd love to " -"hear from you in the ``#introductions`` channel! And if anything is " -"unclear, head over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"open-source Flower community on Slack to connect, ask questions, and get " +"help: `Join Slack `__ 🌼 We'd love to hear " +"from you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 @@ -20280,15 +19736,15 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how " -"most machine learning works today." +"Before we begin to discuss federated learning, let us quickly recap how most " +"machine learning works today." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 msgid "" -"In machine learning, we have a model, and we have data. The model could " -"be a neural network (as depicted here), or something else, like classical" -" linear regression." +"In machine learning, we have a model, and we have data. The model could be a " +"neural network (as depicted here), or something else, like classical linear " +"regression." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 @@ -20301,9 +19757,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 msgid "" -"We train the model using the data to perform a useful task. A task could " -"be to detect objects in images, transcribe an audio recording, or play a " -"game like Go." +"We train the model using the data to perform a useful task. A task could be " +"to detect objects in images, transcribe an audio recording, or play a game " +"like Go." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 @@ -20316,8 +19772,8 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 msgid "" -"Now, in practice, the training data we work with doesn't originate on the" -" machine we train the model on. It gets created somewhere else." +"Now, in practice, the training data we work with doesn't originate on the " +"machine we train the model on. It gets created somewhere else." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 @@ -20338,9 +19794,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 msgid "" "What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running" -" the same app. But it could also be several organizations, all generating" -" data for the same task." +"just one place, it's many places. It could be several devices all running " +"the same app. But it could also be several organizations, all generating " +"data for the same task." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 @@ -20353,10 +19809,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 msgid "" -"So to use machine learning, or any kind of data analysis, the approach " -"that has been used in the past was to collect all data on a central " -"server. This server can be somewhere in a data center, or somewhere in " -"the cloud." +"So to use machine learning, or any kind of data analysis, the approach that " +"has been used in the past was to collect all data on a central server. This " +"server can be somewhere in a data center, or somewhere in the cloud." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 @@ -20388,10 +19843,10 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 msgid "" -"The classic machine learning approach we've just seen can be used in some" -" cases. Great examples include categorizing holiday photos, or analyzing " -"web traffic. Cases, where all the data is naturally available on a " -"centralized server." +"The classic machine learning approach we've just seen can be used in some " +"cases. Great examples include categorizing holiday photos, or analyzing web " +"traffic. Cases, where all the data is naturally available on a centralized " +"server." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 @@ -20404,9 +19859,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 msgid "" -"But the approach can not be used in many other cases. Cases, where the " -"data is not available on a centralized server, or cases where the data " -"available on one server is not enough to train a good model." +"But the approach can not be used in many other cases. Cases, where the data " +"is not available on a centralized server, or cases where the data available " +"on one server is not enough to train a good model." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 @@ -20419,9 +19874,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 msgid "" -"There are many reasons why the classic centralized machine learning " -"approach does not work for a large number of highly important real-world " -"use cases. Those reasons include:" +"There are many reasons why the classic centralized machine learning approach " +"does not work for a large number of highly important real-world use cases. " +"Those reasons include:" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 @@ -20431,32 +19886,32 @@ msgid "" "(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " "(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " "protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own " -"users' data for artificial intelligence training because those users live" -" in different parts of the world, and their data is governed by different" -" data protection regulations." +"sometimes even prevent single organizations from combining their own users' " +"data for artificial intelligence training because those users live in " +"different parts of the world, and their data is governed by different data " +"protection regulations." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 msgid "" -"**User preference**: In addition to regulation, there are use cases where" -" users just expect that no data leaves their device, ever. If you type " -"your passwords and credit card info into the digital keyboard of your " -"phone, you don't expect those passwords to end up on the server of the " -"company that developed that keyboard, do you? In fact, that use case was " -"the reason federated learning was invented in the first place." +"**User preference**: In addition to regulation, there are use cases where " +"users just expect that no data leaves their device, ever. If you type your " +"passwords and credit card info into the digital keyboard of your phone, you " +"don't expect those passwords to end up on the server of the company that " +"developed that keyboard, do you? In fact, that use case was the reason " +"federated learning was invented in the first place." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data " -"volume that it is neither feasible nor economic to collect all the data " -"(due to, for example, bandwidth or communication efficiency). Think about" -" a national rail service with hundreds of train stations across the " -"country. If each of these train stations is outfitted with a number of " -"security cameras, the volume of raw on-device data they produce requires " -"incredibly powerful and exceedingly expensive infrastructure to process " -"and store. And most of the data isn't even useful." +"**Data volume**: Some sensors, like cameras, produce such a high data volume " +"that it is neither feasible nor economic to collect all the data (due to, " +"for example, bandwidth or communication efficiency). Think about a national " +"rail service with hundreds of train stations across the country. If each of " +"these train stations is outfitted with a number of security cameras, the " +"volume of raw on-device data they produce requires incredibly powerful and " +"exceedingly expensive infrastructure to process and store. And most of the " +"data isn't even useful." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 @@ -20471,8 +19926,7 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 msgid "" -"Financial information from different organizations to detect financial " -"fraud" +"Financial information from different organizations to detect financial fraud" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 @@ -20485,13 +19939,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 msgid "" -"The popularity of privacy-enhancing systems like the `Brave " -"`__ browser or the `Signal `__ " -"messenger shows that users care about privacy. In fact, they choose the " -"privacy-enhancing version over other alternatives, if such an alternative" -" exists. But what can we do to apply machine learning and data science to" -" these cases to utilize private data? After all, these are all areas that" -" would benefit significantly from recent advances in AI." +"The popularity of privacy-enhancing systems like the `Brave `__ browser or the `Signal `__ messenger shows " +"that users care about privacy. In fact, they choose the privacy-enhancing " +"version over other alternatives, if such an alternative exists. But what can " +"we do to apply machine learning and data science to these cases to utilize " +"private data? After all, these are all areas that would benefit " +"significantly from recent advances in AI." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 @@ -20501,9 +19955,8 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 msgid "" "Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead " -"of moving the data to the training. Here's the single-sentence " -"explanation:" +"learning on distributed data by moving the training to the data, instead of " +"moving the data to the training. Here's the single-sentence explanation:" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 @@ -20516,22 +19969,22 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 msgid "" -"By doing so, it enables us to use machine learning (and other data " -"science approaches) in areas where it wasn't possible before. We can now " -"train excellent medical AI models by enabling different hospitals to work" -" together. We can solve financial fraud by training AI models on the data" -" of different financial institutions. We can build novel privacy-" -"enhancing applications (such as secure messaging) that have better built-" -"in AI than their non-privacy-enhancing alternatives. And those are just a" -" few of the examples that come to mind. As we deploy federated learning, " -"we discover more and more areas that can suddenly be reinvented because " -"they now have access to vast amounts of previously inaccessible data." +"By doing so, it enables us to use machine learning (and other data science " +"approaches) in areas where it wasn't possible before. We can now train " +"excellent medical AI models by enabling different hospitals to work " +"together. We can solve financial fraud by training AI models on the data of " +"different financial institutions. We can build novel privacy-enhancing " +"applications (such as secure messaging) that have better built-in AI than " +"their non-privacy-enhancing alternatives. And those are just a few of the " +"examples that come to mind. As we deploy federated learning, we discover " +"more and more areas that can suddenly be reinvented because they now have " +"access to vast amounts of previously inaccessible data." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 msgid "" -"So how does federated learning work, exactly? Let's start with an " -"intuitive explanation." +"So how does federated learning work, exactly? Let's start with an intuitive " +"explanation." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 @@ -20544,9 +19997,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 msgid "" -"We start by initializing the model on the server. This is exactly the " -"same in classic centralized learning: we initialize the model parameters," -" either randomly or from a previously saved checkpoint." +"We start by initializing the model on the server. This is exactly the same " +"in classic centralized learning: we initialize the model parameters, either " +"randomly or from a previously saved checkpoint." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 @@ -20559,18 +20012,18 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client" -" nodes)" +"Step 1: Send model to a number of connected organizations/devices (client " +"nodes)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 msgid "" "Next, we send the parameters of the global model to the connected client " "nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts " -"their local training using the same model parameters. We often use only a" -" few of the connected nodes instead of all nodes. The reason for this is " -"that selecting more and more client nodes has diminishing returns." +"organizations). This is to ensure that each participating node starts their " +"local training using the same model parameters. We often use only a few of " +"the connected nodes instead of all nodes. The reason for this is that " +"selecting more and more client nodes has diminishing returns." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 @@ -20583,18 +20036,18 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 msgid "" -"Step 2: Train model locally on the data of each organization/device " -"(client node)" +"Step 2: Train model locally on the data of each organization/device (client " +"node)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 msgid "" -"Now that all (selected) client nodes have the latest version of the " -"global model parameters, they start the local training. They use their " -"own local dataset to train their own local model. They don't train the " -"model until full convergence, but they only train for a little while. " -"This could be as little as one epoch on the local data, or even just a " -"few steps (mini-batches)." +"Now that all (selected) client nodes have the latest version of the global " +"model parameters, they start the local training. They use their own local " +"dataset to train their own local model. They don't train the model until " +"full convergence, but they only train for a little while. This could be as " +"little as one epoch on the local data, or even just a few steps (mini-" +"batches)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 @@ -20611,13 +20064,12 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 msgid "" -"After local training, each client node has a slightly different version " -"of the model parameters they originally received. The parameters are all " +"After local training, each client node has a slightly different version of " +"the model parameters they originally received. The parameters are all " "different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the " -"server. The model updates they send can either be the full model " -"parameters or just the gradients that were accumulated during local " -"training." +"dataset. The client nodes then send those model updates back to the server. " +"The model updates they send can either be the full model parameters or just " +"the gradients that were accumulated during local training." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 @@ -20635,27 +20087,26 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 msgid "" "The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of " -"the original global model, each trained on the local data of one client. " -"But didn't we want to have one model that contains the learnings from the" -" data of all 100 client nodes?" +"selected 100 client nodes, it now has 100 slightly different versions of the " +"original global model, each trained on the local data of one client. But " +"didn't we want to have one model that contains the learnings from the data " +"of all 100 client nodes?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 msgid "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." +"In order to get one single model, we have to combine all the model updates " +"we received from the client nodes. This process is called *aggregation*, and " +"there are many different ways to do it. The most basic way to do it is " +"called *Federated Averaging* (`McMahan et al., 2016 `__), often abbreviated as *FedAvg*. *FedAvg* takes the 100 " +"model updates and, as the name suggests, averages them. To be more precise, " +"it takes the *weighted average* of the model updates, weighted by the number " +"of examples each client used for training. The weighting is important to " +"make sure that each data example has the same \"influence\" on the resulting " +"global model. If one client has 10 examples, and another client has 100 " +"examples, then - without weighting - each of the 10 examples would influence " +"the global model ten times as much as each of the 100 examples." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 @@ -20673,41 +20124,39 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 msgid "" "Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step " -"1), the client nodes train on their local data (step 2), they send their " -"updated models to the server (step 3), and the server then aggregates the" -" model updates to get a new version of the global model (step 4)." +"global model parameters get sent to the participating client nodes (step 1), " +"the client nodes train on their local data (step 2), they send their updated " +"models to the server (step 3), and the server then aggregates the model " +"updates to get a new version of the global model (step 4)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 msgid "" -"During a single round, each client node that participates in that " -"iteration only trains for a little while. This means that after the " -"aggregation step (step 4), we have a model that has been trained on all " -"the data of all participating client nodes, but only for a little while. " -"We then have to repeat this training process over and over again to " -"eventually arrive at a fully trained model that performs well across the " -"data of all client nodes." +"During a single round, each client node that participates in that iteration " +"only trains for a little while. This means that after the aggregation step " +"(step 4), we have a model that has been trained on all the data of all " +"participating client nodes, but only for a little while. We then have to " +"repeat this training process over and over again to eventually arrive at a " +"fully trained model that performs well across the data of all client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 msgid "" "Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning" -" in a nutshell. In later parts of this tutorial, we will go into more " -"detail. Interesting questions include: How can we select the best client " -"nodes that should participate in the next round? What's the best way to " -"aggregate model updates? How can we handle failing client nodes " -"(stragglers)?" +"There's a lot more to discuss, of course, but that was federated learning in " +"a nutshell. In later parts of this tutorial, we will go into more detail. " +"Interesting questions include: How can we select the best client nodes that " +"should participate in the next round? What's the best way to aggregate model " +"updates? How can we handle failing client nodes (stragglers)?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 msgid "" -"Just like we can train a model on the decentralized data of different " -"client nodes, we can also evaluate the model on that data to receive " -"valuable metrics. This is called federated evaluation, sometimes " -"abbreviated as FE. In fact, federated evaluation is an integral part of " -"most federated learning systems." +"Just like we can train a model on the decentralized data of different client " +"nodes, we can also evaluate the model on that data to receive valuable " +"metrics. This is called federated evaluation, sometimes abbreviated as FE. " +"In fact, federated evaluation is an integral part of most federated learning " +"systems." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 @@ -20716,25 +20165,24 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 msgid "" -"In many cases, machine learning isn't necessary to derive value from " -"data. Data analysis can yield valuable insights, but again, there's often" -" not enough data to get a clear answer. What's the average age at which " -"people develop a certain type of health condition? Federated analytics " -"enables such queries over multiple client nodes. It is usually used in " -"conjunction with other privacy-enhancing technologies like secure " -"aggregation to prevent the server from seeing the results submitted by " -"individual client nodes." +"In many cases, machine learning isn't necessary to derive value from data. " +"Data analysis can yield valuable insights, but again, there's often not " +"enough data to get a clear answer. What's the average age at which people " +"develop a certain type of health condition? Federated analytics enables such " +"queries over multiple client nodes. It is usually used in conjunction with " +"other privacy-enhancing technologies like secure aggregation to prevent the " +"server from seeing the results submitted by individual client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 msgid "" "Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and " -"sharing statistical data, ensuring the privacy of individual " -"participants. DP achieves this by adding statistical noise to the model " -"updates, ensuring any individual participants’ information cannot be " -"distinguished or re-identified. This technique can be considered an " -"optimization that provides a quantifiable privacy protection measure." +"Learning. It is a privacy-preserving method used when analyzing and sharing " +"statistical data, ensuring the privacy of individual participants. DP " +"achieves this by adding statistical noise to the model updates, ensuring any " +"individual participants’ information cannot be distinguished or re-" +"identified. This technique can be considered an optimization that provides a " +"quantifiable privacy protection measure." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 @@ -20743,13 +20191,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 msgid "" -"Federated learning, federated evaluation, and federated analytics require" -" infrastructure to move machine learning models back and forth, train and" -" evaluate them on local data, and then aggregate the updated models. " -"Flower provides the infrastructure to do exactly that in an easy, " -"scalable, and secure way. In short, Flower presents a unified approach to" -" federated learning, analytics, and evaluation. It allows the user to " -"federate any workload, any ML framework, and any programming language." +"Federated learning, federated evaluation, and federated analytics require " +"infrastructure to move machine learning models back and forth, train and " +"evaluate them on local data, and then aggregate the updated models. Flower " +"provides the infrastructure to do exactly that in an easy, scalable, and " +"secure way. In short, Flower presents a unified approach to federated " +"learning, analytics, and evaluation. It allows the user to federate any " +"workload, any ML framework, and any programming language." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 @@ -20758,548 +20206,25 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal" -" computer, roomba, and phone)" +"Flower federated learning server and client nodes (car, scooter, personal " +"computer, roomba, and phone)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 msgid "" -"Congratulations, you just learned the basics of federated learning and " -"how it relates to the classic (centralized) machine learning!" +"Congratulations, you just learned the basics of federated learning and how " +"it relates to the classic (centralized) machine learning!" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 msgid "" -"In the next part of this tutorial, we are going to build a first " -"federated learning system with Flower." +"In the next part of this tutorial, we are going to build a first federated " +"learning system with Flower." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 msgid "" -"The `Flower Federated Learning Tutorial - Part 1 " -"`__ shows how to build a simple federated learning system " -"with PyTorch and Flower." -msgstr "" - -#~ msgid "" -#~ "If you want to use your own " -#~ "base image instead of the official " -#~ "Flower base image, all you need to" -#~ " do is set the ``BASE_REPOSITORY``, " -#~ "``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build " -#~ "arguments. .. code-block:: bash" -#~ msgstr "" - -#~ msgid "$ cd src/docker/superlink/ $ docker build \\" -#~ msgstr "" - -#~ msgid "" -#~ "--build-arg BASE_REPOSITORY=flwr_base \\ " -#~ "--build-arg PYTHON_VERSION=3.11 \\ --build-" -#~ "arg UBUNTU_VERSION=ubuntu22.04 \\ --build-arg" -#~ " FLWR_VERSION=1.8.0 \\ -t flwr_superlink:0.1.0" -#~ " ." -#~ msgstr "" - -#~ msgid "" -#~ "It is important to follow the " -#~ "instructions described in comments. For " -#~ "instance, in order to not break " -#~ "how our changelog system works, you " -#~ "should read the information above the" -#~ " ``Changelog entry`` section carefully. You" -#~ " can also checkout some examples and" -#~ " details in the :ref:`changelogentry` " -#~ "appendix." -#~ msgstr "" - -#~ msgid "Open a PR (as shown above)" -#~ msgstr "" - -#~ msgid "How to write a good PR title" -#~ msgstr "" - -#~ msgid "" -#~ "A well-crafted PR title helps team" -#~ " members quickly understand the purpose " -#~ "and scope of the changes being " -#~ "proposed. Here's a guide to help " -#~ "you write a good GitHub PR title:" -#~ msgstr "" - -#~ msgid "" -#~ "1. Be Clear and Concise: Provide a" -#~ " clear summary of the changes in " -#~ "a concise manner. 1. Use Actionable " -#~ "Verbs: Start with verbs like \"Add,\"" -#~ " \"Update,\" or \"Fix\" to indicate " -#~ "the purpose. 1. Include Relevant " -#~ "Information: Mention the affected feature " -#~ "or module for context. 1. Keep it" -#~ " Short: Avoid lengthy titles for easy" -#~ " readability. 1. Use Proper Capitalization" -#~ " and Punctuation: Follow grammar rules " -#~ "for clarity." -#~ msgstr "" - -#~ msgid "" -#~ "Let's start with a few examples " -#~ "for titles that should be avoided " -#~ "because they do not provide meaningful" -#~ " information:" -#~ msgstr "" - -#~ msgid "Implement Algorithm" -#~ msgstr "" - -#~ msgid "Database" -#~ msgstr "" - -#~ msgid "Add my_new_file.py to codebase" -#~ msgstr "" - -#~ msgid "Improve code in module" -#~ msgstr "" - -#~ msgid "Change SomeModule" -#~ msgstr "" - -#~ msgid "" -#~ "Here are a few positive examples " -#~ "which provide helpful information without " -#~ "repeating how they do it, as that" -#~ " is already visible in the \"Files" -#~ " changed\" section of the PR:" -#~ msgstr "" - -#~ msgid "Update docs banner to mention Flower Summit 2023" -#~ msgstr "" - -#~ msgid "Remove unnecessary XGBoost dependency" -#~ msgstr "" - -#~ msgid "Remove redundant attributes in strategies subclassing FedAvg" -#~ msgstr "" - -#~ msgid "" -#~ "Add CI job to deploy the staging" -#~ " system when the ``main`` branch " -#~ "changes" -#~ msgstr "" - -#~ msgid "" -#~ "Add new amazing library which will " -#~ "be used to improve the simulation " -#~ "engine" -#~ msgstr "" - -#~ msgid "Changelog entry" -#~ msgstr "" - -#~ msgid "" -#~ "When opening a new PR, inside its" -#~ " description, there should be a " -#~ "``Changelog entry`` header." -#~ msgstr "" - -#~ msgid "" -#~ "Above this header you should see " -#~ "the following comment that explains how" -#~ " to write your changelog entry:" -#~ msgstr "" - -#~ msgid "" -#~ "Inside the following 'Changelog entry' " -#~ "section, you should put the description" -#~ " of your changes that will be " -#~ "added to the changelog alongside your" -#~ " PR title." -#~ msgstr "" - -#~ msgid "" -#~ "If the section is completely empty " -#~ "(without any token) or non-existent, " -#~ "the changelog will just contain the " -#~ "title of the PR for the changelog" -#~ " entry, without any description." -#~ msgstr "" - -#~ msgid "" -#~ "If the section contains some text " -#~ "other than tokens, it will use it" -#~ " to add a description to the " -#~ "change." -#~ msgstr "" - -#~ msgid "" -#~ "If the section contains one of the" -#~ " following tokens it will ignore any" -#~ " other text and put the PR " -#~ "under the corresponding section of the" -#~ " changelog:" -#~ msgstr "" - -#~ msgid " is for classifying a PR as a general improvement." -#~ msgstr "" - -#~ msgid " is to not add the PR to the changelog" -#~ msgstr "" - -#~ msgid " is to add a general baselines change to the PR" -#~ msgstr "" - -#~ msgid " is to add a general examples change to the PR" -#~ msgstr "" - -#~ msgid " is to add a general sdk change to the PR" -#~ msgstr "" - -#~ msgid " is to add a general simulations change to the PR" -#~ msgstr "" - -#~ msgid "Note that only one token should be used." -#~ msgstr "" - -#~ msgid "" -#~ "Its content must have a specific " -#~ "format. We will break down what " -#~ "each possibility does:" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains nothing or doesn't exist, " -#~ "the following text will be added " -#~ "to the changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains a description (and no " -#~ "token), the following text will be " -#~ "added to the changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, nothing will change" -#~ " in the changelog." -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, the following text" -#~ " will be added to the changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, the following " -#~ "text will be added to the " -#~ "changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, the following " -#~ "text will be added to the " -#~ "changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, the following text " -#~ "will be added to the changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "If the ``### Changelog entry`` section" -#~ " contains ````, the following " -#~ "text will be added to the " -#~ "changelog::" -#~ msgstr "" - -#~ msgid "" -#~ "Note that only one token must be" -#~ " provided, otherwise, only the first " -#~ "action (in the order listed above), " -#~ "will be performed." -#~ msgstr "" - -#~ msgid "" -#~ "We recommend you to check out the" -#~ " complete `code example " -#~ "`_ demonstrating federated " -#~ "learning with Flower in an authenticated" -#~ " setting." -#~ msgstr "" - -#~ msgid "Let's break down the :code:`--require-client-authentication` flag:" -#~ msgstr "" - -#~ msgid "" -#~ "The first argument is a path to" -#~ " a CSV file storing all known " -#~ "node public keys. You need to " -#~ "store all known node public keys " -#~ "that are allowed to participate in " -#~ "a federation in one CSV file " -#~ "(:code:`.csv`)." -#~ msgstr "" - -#~ msgid "" -#~ "The second and third arguments are " -#~ "paths to the server's private and " -#~ "public keys. For development purposes, " -#~ "you can generate a private and " -#~ "public key pair using :code:`ssh-keygen" -#~ " -t ecdsa -b 384`." -#~ msgstr "" - -#~ msgid "" -#~ "The :code:`--authentication-keys` flag expects" -#~ " two arguments: a path to the " -#~ "node's private key file and a path" -#~ " to the node's public key file. " -#~ "For development purposes, you can " -#~ "generate a private and public key " -#~ "pair using :code:`ssh-keygen -t ecdsa" -#~ " -b 384`." -#~ msgstr "" - -#~ msgid "" -#~ "The simplest way to get started " -#~ "with Flower is by using the " -#~ "pre-made Docker images, which you can" -#~ " find on `Docker Hub " -#~ "`_." -#~ msgstr "" - -#~ msgid "" -#~ "The ``--insecure`` flag enables insecure " -#~ "communication (using HTTP, not HTTPS) " -#~ "and should only be used for " -#~ "testing purposes. We strongly recommend " -#~ "enabling `SSL `_ when " -#~ "deploying to a production environment." -#~ msgstr "" - -#~ msgid "" -#~ "If you want to persist the state" -#~ " of the SuperLink on your host " -#~ "system, all you need to do is " -#~ "specify a path where you want to" -#~ " save the file on your host " -#~ "system and a name for the database" -#~ " file. In the example below, we " -#~ "tell Docker via the flag ``-v`` to" -#~ " mount the user's home directory " -#~ "(``~/`` on your host) into the " -#~ "``/app/`` directory of the container. " -#~ "Furthermore, we use the flag " -#~ "``--database`` to specify the name of" -#~ " the database file." -#~ msgstr "" - -#~ msgid "" -#~ "For testing purposes, you can generate" -#~ " your own self-signed certificates. " -#~ "The `Enable SSL connections " -#~ "`_ page contains " -#~ "a section that will guide you " -#~ "through the process." -#~ msgstr "" - -#~ msgid "" -#~ "Assuming all files we need are in" -#~ " the local ``certificates`` directory, we" -#~ " can use the flag ``-v`` to " -#~ "mount the local directory into the " -#~ "``/app/`` directory of the container. " -#~ "This allows the SuperLink to access " -#~ "the files within the container. Finally," -#~ " we pass the names of the " -#~ "certificates to the SuperLink with the" -#~ " ``--certificates`` flag." -#~ msgstr "" - -#~ msgid "" -#~ "The SuperNode Docker image currently " -#~ "works only with the 1.9.0-nightly " -#~ "release. A stable version will be " -#~ "available when Flower 1.9.0 (stable) " -#~ "gets released (ETA: May). A SuperNode" -#~ " nightly image must be paired with" -#~ " the corresponding SuperLink nightly image" -#~ " released on the same day. To " -#~ "ensure the versions are in sync, " -#~ "using the concrete tag, e.g., " -#~ "``1.9.0.dev20240501`` instead of ``nightly`` " -#~ "is recommended." -#~ msgstr "" - -#~ msgid "" -#~ "We will use the ``app-pytorch`` " -#~ "example, which you can find in the" -#~ " Flower repository, to illustrate how " -#~ "you can dockerize your client-app." -#~ msgstr "" - -#~ msgid "" -#~ "Before we can start, we need to" -#~ " meet a few prerequisites in our " -#~ "local development environment. You can " -#~ "skip the first part if you want" -#~ " to run your client-app instead " -#~ "of the ``app-pytorch`` example." -#~ msgstr "" - -#~ msgid "" -#~ "First, we need to create a " -#~ "Dockerfile in the directory where the" -#~ " ``ClientApp`` code is located. If " -#~ "you use the ``app-pytorch`` example, " -#~ "create a new file called ``Dockerfile``" -#~ " in ``examples/app-pytorch``." -#~ msgstr "" - -#~ msgid "" -#~ "The ``Dockerfile`` contains the instructions" -#~ " that assemble the SuperNode image." -#~ msgstr "" - -#~ msgid "" -#~ "In the first two lines, we " -#~ "instruct Docker to use the SuperNode " -#~ "image tagged ``nightly`` as a base " -#~ "image and set our working directory " -#~ "to ``/app``. The following instructions " -#~ "will now be executed in the " -#~ "``/app`` directory. Next, we install the" -#~ " ``ClientApp`` dependencies by copying the" -#~ " ``requirements.txt`` file into the image" -#~ " and run ``pip install``. In the " -#~ "last two lines, we copy the " -#~ "``ClientApp`` code (``client.py`` and " -#~ "``task.py``) into the image and set " -#~ "the entry point to ``flower-client-" -#~ "app``." -#~ msgstr "" - -#~ msgid "" -#~ "Next, we build the SuperNode Docker " -#~ "image by running the following command" -#~ " in the directory where Dockerfile " -#~ "and client-app code are located." -#~ msgstr "" - -#~ msgid "" -#~ "``client:app``: The object reference of " -#~ "the ``ClientApp`` (``:``)." -#~ msgstr "" - -#~ msgid "" -#~ "It points to the ``ClientApp`` that " -#~ "will be run inside the SuperNode " -#~ "container." -#~ msgstr "" - -#~ msgid "" -#~ "Assuming the certificate already exists " -#~ "locally, we can use the flag " -#~ "``-v`` to mount the local certificate" -#~ " into the container's ``/app/`` directory." -#~ " This allows the SuperNode to access" -#~ " the certificate within the container. " -#~ "Use the ``--certificates`` flag when " -#~ "starting the container." -#~ msgstr "" - -#~ msgid "" -#~ "If you want to use a different " -#~ "version of Flower, for example Flower" -#~ " nightly, you can do so by " -#~ "changing the tag. All available versions" -#~ " are on `Docker Hub " -#~ "`_." -#~ msgstr "" - -#~ msgid "" -#~ "Run |runsimcli_link|_ in CLI and point" -#~ " to the ``server_app`` / ``client_app`` " -#~ "object in the code instead of " -#~ "executing the Python script. Here's an" -#~ " example (assuming the ``server_app`` and" -#~ " ``client_app`` objects are in a " -#~ "``sim.py`` module):" -#~ msgstr "" - -#~ msgid "start\\_driver" -#~ msgstr "" - -#~ msgid "run\\_simulation\\_from\\_cli" -#~ msgstr "" - -#~ msgid "" -#~ "We now have a list of ten " -#~ "training sets and ten validation sets" -#~ " (``trainloaders`` and ``valloaders``) " -#~ "representing the data of ten different" -#~ " organizations. Each ``trainloader``/``valloader`` " -#~ "pair contains 4500 training examples and" -#~ " 500 validation examples. There's also " -#~ "a single ``testloader`` (we did not " -#~ "split the test set). Again, this " -#~ "is only necessary for building research" -#~ " or educational systems, actual federated" -#~ " learning systems have their data " -#~ "naturally distributed across multiple " -#~ "partitions." -#~ msgstr "" - -#~ msgid "|191c6b8b5e1d46f99de4872746afa8af|" -#~ msgstr "" - -#~ msgid "|21b83f3feb024a049617190555a13549|" -#~ msgstr "" - -#~ msgid "|0dd15b4df7e3422f88aaf74cb401bfa7|" -#~ msgstr "" - -#~ msgid "|60e16f6be7354ca793444e01aa7adf25|" -#~ msgstr "" - -#~ msgid "|a7032acbd65948a8beef8bccbbb9b83a|" -#~ msgstr "" - -#~ msgid "|dd0e05706e584ee29e07cd39e6af5498|" -#~ msgstr "" - -#~ msgid "|2a2031018a1c4f81a69ea16df4947bd0|" -#~ msgstr "" - -#~ msgid "|5e841497933340d3b5c2efbf37e3e6a6|" -#~ msgstr "" - -#~ msgid "|19687aecbc3a485da999b66fe2051005|" -#~ msgstr "" - -#~ msgid "|32ef0bbade4d4500b7be97cf62405661|" -#~ msgstr "" - -#~ msgid "|9d57ed324b304a698263f5a983a56a6b|" -#~ msgstr "" - -#~ msgid "|d41510e6781c4bf18c234c6bfb8d4937|" -#~ msgstr "" - -#~ msgid "|a0198a7ebbfb4b9289e7312711cbc967|" -#~ msgstr "" - -#~ msgid "|2c13f726c8c843fc8aae997bf906125b|" -#~ msgstr "" +"The `Flower Federated Learning Tutorial - Part 1 `__ shows how to " +"build a simple federated learning system with PyTorch and Flower." +msgstr "" From c21c913bb248325dbbb91c47c1094a6bf9f8343b Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Tue, 11 Jun 2024 11:53:23 +0200 Subject: [PATCH 056/124] feat(datasets) Add label count utils (#3551) --- datasets/flwr_datasets/metrics/__init__.py | 4 +- datasets/flwr_datasets/metrics/utils.py | 199 +++++++++++++++++- datasets/flwr_datasets/metrics/utils_test.py | 130 +++++++++++- .../visualization/label_distribution.py | 73 ++----- 4 files changed, 333 insertions(+), 73 deletions(-) diff --git a/datasets/flwr_datasets/metrics/__init__.py b/datasets/flwr_datasets/metrics/__init__.py index 807860b5b7b8..e82cb3088822 100644 --- a/datasets/flwr_datasets/metrics/__init__.py +++ b/datasets/flwr_datasets/metrics/__init__.py @@ -15,9 +15,9 @@ """Metrics package.""" -from flwr_datasets.metrics.utils import compute_counts, compute_frequency +from flwr_datasets.metrics.utils import compute_counts, compute_frequencies __all__ = [ "compute_counts", - "compute_frequency", + "compute_frequencies", ] diff --git a/datasets/flwr_datasets/metrics/utils.py b/datasets/flwr_datasets/metrics/utils.py index a11e7193fbde..8f78b2fd4c32 100644 --- a/datasets/flwr_datasets/metrics/utils.py +++ b/datasets/flwr_datasets/metrics/utils.py @@ -15,12 +15,197 @@ """Utils for metrics computation.""" -from typing import List, Union +import warnings +from typing import List, Optional, Union import pandas as pd +from flwr_datasets.partitioner import Partitioner + def compute_counts( + partitioner: Partitioner, + column_name: str, + verbose_names: bool = False, + max_num_partitions: Optional[int] = None, +) -> pd.DataFrame: + """Compute the counts of unique values in a given column in the partitions. + + Take into account all possible labels in dataset when computing count for each + partition (assign 0 as the size when there are no values for a label in the + partition). + + Parameters + ---------- + partitioner : Partitioner + Partitioner with an assigned dataset. + column_name : str + Column name identifying label based on which the count will be calculated. + verbose_names : bool + Whether to use verbose versions of the values in the column specified by + `column_name`. The verbose values are possible to extract if the column is a + feature of type `ClassLabel`. + max_num_partitions : Optional[int] + The maximum number of partitions that will be used. If greater than the + total number of partitions in a partitioner, it won't have an effect. If left + as None, then all partitions will be used. + + Returns + ------- + dataframe: pd.DataFrame + DataFrame where the row index represent the partition id and the column index + represent the unique values found in column specified by `column_name` + (e.g. represeting the labels). The value of the dataframe.loc[i, j] represents + the count of the label j, in the partition of index i. + + Examples + -------- + Generate DataFrame with label counts resulting from DirichletPartitioner on cifar10 + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.metrics import compute_counts + >>> + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=0.3, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner = fds.partitioners["train"] + >>> counts_dataframe = compute_counts( + >>> partitioner=partitioner, + >>> column_name="label" + >>> ) + """ + if column_name not in partitioner.dataset.column_names: + raise ValueError( + f"The specified 'column_name': '{column_name}' is not present in the " + f"dataset. The dataset contains columns {partitioner.dataset.column_names}." + ) + + if max_num_partitions is None: + max_num_partitions = partitioner.num_partitions + else: + max_num_partitions = min(max_num_partitions, partitioner.num_partitions) + assert isinstance(max_num_partitions, int) + partition = partitioner.load_partition(0) + + try: + # Unique labels are needed to represent the correct count of each class + # (some of the classes can have zero samples that's why this + # adjustment is needed) + unique_labels = partition.features[column_name].str2int( + partition.features[column_name].names + ) + except AttributeError: # If the column_name is not formally a Label + unique_labels = partitioner.dataset.unique(column_name) + + partition_id_to_label_absolute_size = {} + for partition_id in range(max_num_partitions): + partition = partitioner.load_partition(partition_id) + partition_id_to_label_absolute_size[partition_id] = _compute_counts( + partition[column_name], unique_labels + ) + + dataframe = pd.DataFrame.from_dict( + partition_id_to_label_absolute_size, orient="index" + ) + dataframe.index.name = "Partition ID" + + if verbose_names: + # Adjust the column name values of the dataframe + current_labels = dataframe.columns + try: + legend_names = partitioner.dataset.features[column_name].int2str( + [int(v) for v in current_labels] + ) + dataframe.columns = legend_names + except AttributeError: + warnings.warn( + "The verbose names can not be established. " + "The column specified by 'column_name' needs to be of type " + "'ClassLabel' to create a verbose names. " + "The available names will used.", + stacklevel=1, + ) + return dataframe + + +def compute_frequencies( + partitioner: Partitioner, + column_name: str, + verbose_names: bool = False, + max_num_partitions: Optional[int] = None, +) -> pd.DataFrame: + """Compute the frequencies of unique values in a given column in the partitions. + + The frequencies sum up to 1 for a given partition id. This function takes into + account all possible labels in the dataset when computing the count for each + partition (assign 0 as the size when there are no values for a label in the + partition). + + Parameters + ---------- + partitioner : Partitioner + Partitioner with an assigned dataset. + column_name : str + Column name identifying label based on which the count will be calculated. + verbose_names : bool + Whether to use verbose versions of the values in the column specified by + `column_name`. The verbose value are possible to extract if the column is a + feature of type `ClassLabel`. + max_num_partitions : Optional[int] + The maximum number of partitions that will be used. If greater than the + total number of partitions in a partitioner, it won't have an effect. If left + as None, then all partitions will be used. + + Returns + ------- + dataframe: pd.DataFrame + DataFrame where the row index represent the partition id and the column index + represent the unique values found in column specified by `column_name` + (e.g. represeting the labels). The value of the dataframe.loc[i, j] represnt + the ratio of the label j to the total number of sample of in partition i. + + Examples + -------- + Generate DataFrame with label counts resulting from DirichletPartitioner on cifar10 + + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> from flwr_datasets.metrics import compute_frequencies + >>> + >>> fds = FederatedDataset( + >>> dataset="cifar10", + >>> partitioners={ + >>> "train": DirichletPartitioner( + >>> num_partitions=20, + >>> partition_by="label", + >>> alpha=0.3, + >>> min_partition_size=0, + >>> ), + >>> }, + >>> ) + >>> partitioner = fds.partitioners["train"] + >>> counts_dataframe = compute_frequencies( + >>> partitioner=partitioner, + >>> column_name="label" + >>> ) + """ + dataframe = compute_counts( + partitioner, column_name, verbose_names, max_num_partitions + ) + dataframe = dataframe.div(dataframe.sum(axis=1), axis=0) + return dataframe + + +def _compute_counts( labels: Union[List[int], List[str]], unique_labels: Union[List[int], List[str]] ) -> pd.Series: """Compute the count of labels when taking into account all possible labels. @@ -51,7 +236,7 @@ def compute_counts( return label_counts_with_zeros -def compute_frequency( +def _compute_frequencies( labels: Union[List[int], List[str]], unique_labels: Union[List[int], List[str]] ) -> pd.Series: """Compute the distribution of labels when taking into account all possible labels. @@ -70,9 +255,9 @@ def compute_frequency( ------- The pd.Series with label as indices and probabilities as values. """ - counts = compute_counts(labels, unique_labels) + counts = _compute_counts(labels, unique_labels) if len(labels) == 0: - counts = counts.astype(float) - return counts - counts = counts.divide(len(labels)) - return counts + frequencies = counts.astype(float) + return frequencies + frequencies = counts.divide(len(labels)) + return frequencies diff --git a/datasets/flwr_datasets/metrics/utils_test.py b/datasets/flwr_datasets/metrics/utils_test.py index 687aa67dbde6..9e0f3acdf805 100644 --- a/datasets/flwr_datasets/metrics/utils_test.py +++ b/datasets/flwr_datasets/metrics/utils_test.py @@ -19,12 +19,124 @@ import unittest import pandas as pd -from parameterized import parameterized +from parameterized import parameterized, parameterized_class -from flwr_datasets.metrics.utils import compute_counts, compute_frequency +import datasets +from datasets import ClassLabel +from flwr_datasets.metrics.utils import ( + _compute_counts, + _compute_frequencies, + compute_counts, + compute_frequencies, +) +from flwr_datasets.partitioner import IidPartitioner -class TestMetricsUtils(unittest.TestCase): +@parameterized_class( + ("dataset", "result"), + [ + ( + datasets.Dataset.from_dict({"feature": list(range(10)), "label": [0] * 10}), + pd.DataFrame([[5], [5]], index=pd.Index([0, 1], name="Partition ID")), + ), + ( + datasets.Dataset.from_dict( + {"feature": list(range(10)), "label": [0] * 5 + [1] * 5} + ), + pd.DataFrame([[5, 0], [0, 5]], index=pd.Index([0, 1], name="Partition ID")), + ), + ( + datasets.Dataset.from_dict( + {"feature": list(range(10)), "label": [0, 0, 0, 1, 1] + [1, 1, 1, 1, 2]} + ), + pd.DataFrame( + [[3, 2, 0], [0, 4, 1]], index=pd.Index([0, 1], name="Partition ID") + ), + ), + ], +) +class TestPublicMetricsUtils(unittest.TestCase): + """Test metrics utils.""" + + dataset: datasets.Dataset + result: pd.DataFrame + + def test_compute_counts(self) -> None: + """Test if the counts are computed correctly.""" + iid_partitioner = IidPartitioner(num_partitions=2) + iid_partitioner.dataset = self.dataset + count = compute_counts(iid_partitioner, column_name="label") + pd.testing.assert_frame_equal(count, self.result) + + def test_compute_frequencies(self) -> None: + """Test if the frequencies are computed correctly.""" + iid_partitioner = IidPartitioner(num_partitions=2) + iid_partitioner.dataset = self.dataset + frequencies = compute_frequencies(iid_partitioner, column_name="label") + result = self.result.div(self.result.sum(axis=1), axis=0) + pd.testing.assert_frame_equal(frequencies, result) + + def test_compute_counts_with_verbose_label(self) -> None: + """Test if the counts are computed correctly.""" + iid_partitioner = IidPartitioner(num_partitions=2) + dataset = self.dataset + new_col_names = [ + str(col_id) for col_id in range(len(self.dataset.unique("label"))) + ] + dataset = dataset.cast_column( + "label", + ClassLabel( + num_classes=len(self.dataset.unique("label")), names=new_col_names + ), + ) + iid_partitioner.dataset = dataset + result = self.result.copy() + result.columns = new_col_names + count = compute_counts(iid_partitioner, column_name="label", verbose_names=True) + pd.testing.assert_frame_equal(count, result) + + def test_compute_frequencies_with_verbose_label(self) -> None: + """Test if the frequencies are computed correctly.""" + iid_partitioner = IidPartitioner(num_partitions=2) + dataset = self.dataset + new_col_names = [ + str(col_id) for col_id in range(len(self.dataset.unique("label"))) + ] + dataset = dataset.cast_column( + "label", + ClassLabel( + num_classes=len(self.dataset.unique("label")), names=new_col_names + ), + ) + iid_partitioner.dataset = dataset + result = self.result.copy() + result.columns = new_col_names + result = result.div(result.sum(axis=1), axis=0) + frequencies = compute_frequencies( + iid_partitioner, column_name="label", verbose_names=True + ) + pd.testing.assert_frame_equal(frequencies, result) + + def test_compute_count_with_smaller_max_partitions(self) -> None: + """Test is compute_count works when the max_partitions None: + """Test is compute_count works when the max_partitions>total partitions.""" + iid_partitioner = IidPartitioner(num_partitions=2) + iid_partitioner.dataset = self.dataset + count = compute_counts( + iid_partitioner, column_name="label", max_num_partitions=3 + ) + pd.testing.assert_frame_equal(count, self.result) + + +class TestPrivateMetricsUtils(unittest.TestCase): """Test metrics utils.""" @parameterized.expand( # type: ignore @@ -34,9 +146,9 @@ class TestMetricsUtils(unittest.TestCase): ([1, 1, 2], [1, 2, 3, 4], pd.Series([2, 1, 0, 0], index=[1, 2, 3, 4])), ] ) - def test_compute_counts(self, labels, unique_labels, expected) -> None: + def test__compute_counts(self, labels, unique_labels, expected) -> None: """Test if the counts are computed correctly.""" - result = compute_counts(labels, unique_labels) + result = _compute_counts(labels, unique_labels) pd.testing.assert_series_equal(result, expected) @parameterized.expand( # type: ignore @@ -56,7 +168,7 @@ def test_compute_counts(self, labels, unique_labels, expected) -> None: ) def test_compute_distribution(self, labels, unique_labels, expected) -> None: """Test if the distributions are computed correctly.""" - result = compute_frequency(labels, unique_labels) + result = _compute_frequencies(labels, unique_labels) pd.testing.assert_series_equal(result, expected, atol=0.001) @parameterized.expand( # type: ignore @@ -67,7 +179,7 @@ def test_compute_distribution(self, labels, unique_labels, expected) -> None: ) def test_distribution_sum_to_one(self, labels, unique_labels) -> None: """Test if distributions sum up to one.""" - result = compute_frequency(labels, unique_labels) + result = _compute_frequencies(labels, unique_labels) self.assertAlmostEqual(result.sum(), 1.0) def test_compute_counts_non_unique_labels(self) -> None: @@ -75,14 +187,14 @@ def test_compute_counts_non_unique_labels(self) -> None: labels = [1, 2, 3] unique_labels = [1, 2, 2, 3] with self.assertRaises(ValueError): - compute_counts(labels, unique_labels) + _compute_counts(labels, unique_labels) def test_compute_distribution_non_unique_labels(self) -> None: """Test if not having the unique labels raises ValueError.""" labels = [1, 1, 2, 3] unique_labels = [1, 1, 2, 3] with self.assertRaises(ValueError): - compute_frequency(labels, unique_labels) + _compute_frequencies(labels, unique_labels) if __name__ == "__main__": diff --git a/datasets/flwr_datasets/visualization/label_distribution.py b/datasets/flwr_datasets/visualization/label_distribution.py index f959fbd856ee..940b0e8f91bd 100644 --- a/datasets/flwr_datasets/visualization/label_distribution.py +++ b/datasets/flwr_datasets/visualization/label_distribution.py @@ -15,7 +15,6 @@ """Label distribution plotting.""" -import warnings from typing import Any, Dict, Optional, Tuple, Union import matplotlib.colors as mcolors @@ -23,7 +22,7 @@ from matplotlib.axes import Axes from matplotlib.figure import Figure -from flwr_datasets.metrics import compute_counts +from flwr_datasets.metrics.utils import compute_counts, compute_frequencies from flwr_datasets.partitioner import Partitioner from flwr_datasets.visualization.bar_plot import _plot_bar from flwr_datasets.visualization.heatmap_plot import _plot_heatmap @@ -81,7 +80,9 @@ def plot_label_distributions( Title for the legend. If None, the defaults will be takes based on the type of plot. verbose_labels : bool - Whether to use verbose versions of the labels. + Whether to use verbose versions of the labels. These values are used as columns + of the returned dataframe and as labels on the legend in a bar plot and columns/ + rows ticks in a heatmap plot. plot_kwargs: Optional[Dict[str, Any]] Any key value pair that can be passed to a plot function that are not supported directly. In case of the parameter doubling (e.g. specifying cmap here too) the @@ -192,60 +193,22 @@ def plot_label_distributions( """ _validate_parameters(plot_type, size_unit, partition_id_axis) - if label_name not in partitioner.dataset.column_names: - raise ValueError( - f"The specified 'label_name': '{label_name}' is not present in the " - f"dataset. The dataset contains columns {partitioner.dataset.column_names}." + dataframe = pd.DataFrame() + if size_unit == "absolute": + dataframe = compute_counts( + partitioner=partitioner, + column_name=label_name, + verbose_names=verbose_labels, + max_num_partitions=max_num_partitions, ) - - if max_num_partitions is None: - max_num_partitions = partitioner.num_partitions - else: - max_num_partitions = min(max_num_partitions, partitioner.num_partitions) - assert isinstance(max_num_partitions, int) - partitions = [partitioner.load_partition(i) for i in range(max_num_partitions)] - - partition = partitions[0] - try: - # Unique labels are needed to represent the correct count of each class - # (some of the classes can have zero samples that's why this - # adjustment is needed) - unique_labels = partition.features[label_name].str2int( - partition.features[label_name].names + elif size_unit == "percent": + dataframe = compute_frequencies( + partitioner=partitioner, + column_name=label_name, + verbose_names=verbose_labels, + max_num_partitions=max_num_partitions, ) - except AttributeError: # If the label_name is not formally a Label - unique_labels = partitioner.dataset.unique(label_name) - - partition_id_to_label_absolute_size = { - pid: compute_counts(partition[label_name], unique_labels) - for pid, partition in enumerate(partitions) - } - - dataframe = pd.DataFrame.from_dict( - partition_id_to_label_absolute_size, orient="index" - ) - dataframe.index.name = "Partition ID" - - if size_unit == "percent": - dataframe = dataframe.div(dataframe.sum(axis=1), axis=0) * 100.0 - - if verbose_labels: - # Adjust the column name values of the dataframe - # (these values are used for as labels in bar plot and columns/rows ticks - # in heatmap) - current_labels = dataframe.columns - try: - legend_names = partition.features[label_name].int2str( - [int(v) for v in current_labels] - ) - dataframe.columns = legend_names - except AttributeError: - warnings.warn( - "The verbose label names can not be established. " - "The column specified by 'label_name' needs to be of type " - "'ClassLabel'", - stacklevel=1, - ) + dataframe = dataframe * 100.0 if plot_type == "bar": axis = _plot_bar( From 408d8820ba89b02fe938eafd1f6c50bacd0b41cf Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Wed, 12 Jun 2024 12:56:00 +0200 Subject: [PATCH 057/124] feat(framework) Add `flwr install` command (#3258) Co-authored-by: Heng Pan Co-authored-by: Taner Topal Co-authored-by: Javier --- src/py/flwr/cli/app.py | 2 + src/py/flwr/cli/build.py | 17 +-- src/py/flwr/cli/config_utils.py | 15 ++- src/py/flwr/cli/install.py | 196 +++++++++++++++++++++++++++++++ src/py/flwr/cli/utils.py | 14 +++ src/py/flwr/common/object_ref.py | 22 ++-- 6 files changed, 238 insertions(+), 28 deletions(-) create mode 100644 src/py/flwr/cli/install.py diff --git a/src/py/flwr/cli/app.py b/src/py/flwr/cli/app.py index e1417f1267ac..477b990bf1da 100644 --- a/src/py/flwr/cli/app.py +++ b/src/py/flwr/cli/app.py @@ -18,6 +18,7 @@ from .build import build from .example import example +from .install import install from .new import new from .run import run @@ -34,6 +35,7 @@ app.command()(example) app.command()(run) app.command()(build) +app.command()(install) if __name__ == "__main__": app() diff --git a/src/py/flwr/cli/build.py b/src/py/flwr/cli/build.py index ca7ab8686c5c..d279a8d11bc2 100644 --- a/src/py/flwr/cli/build.py +++ b/src/py/flwr/cli/build.py @@ -14,7 +14,6 @@ # ============================================================================== """Flower command line interface `build` command.""" -import hashlib import os import zipfile from pathlib import Path @@ -25,7 +24,7 @@ from typing_extensions import Annotated from .config_utils import load_and_validate -from .utils import is_valid_project_name +from .utils import get_sha256_hash, is_valid_project_name # pylint: disable=too-many-locals @@ -115,7 +114,7 @@ def build( fab_file.write(file_path, archive_path) # Calculate file info - sha256_hash = _get_sha256_hash(file_path) + sha256_hash = get_sha256_hash(file_path) file_size_bits = os.path.getsize(file_path) * 8 # size in bits list_file_content += f"{archive_path},{sha256_hash},{file_size_bits}\n" @@ -127,18 +126,6 @@ def build( ) -def _get_sha256_hash(file_path: Path) -> str: - """Calculate the SHA-256 hash of a file.""" - sha256 = hashlib.sha256() - with open(file_path, "rb") as f: - while True: - data = f.read(65536) # Read in 64kB blocks - if not data: - break - sha256.update(data) - return sha256.hexdigest() - - def _load_gitignore(directory: Path) -> pathspec.PathSpec: """Load and parse .gitignore file, returning a pathspec.""" gitignore_path = directory / ".gitignore" diff --git a/src/py/flwr/cli/config_utils.py b/src/py/flwr/cli/config_utils.py index d943d87e3812..ec67fefda0d2 100644 --- a/src/py/flwr/cli/config_utils.py +++ b/src/py/flwr/cli/config_utils.py @@ -24,6 +24,7 @@ def load_and_validate( path: Optional[Path] = None, + check_module: bool = True, ) -> Tuple[Optional[Dict[str, Any]], List[str], List[str]]: """Load and validate pyproject.toml as dict. @@ -42,7 +43,7 @@ def load_and_validate( ] return (None, errors, []) - is_valid, errors, warnings = validate(config) + is_valid, errors, warnings = validate(config, check_module) if not is_valid: return (None, errors, warnings) @@ -102,7 +103,9 @@ def validate_fields(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]] return len(errors) == 0, errors, warnings -def validate(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]: +def validate( + config: Dict[str, Any], check_module: bool = True +) -> Tuple[bool, List[str], List[str]]: """Validate pyproject.toml.""" is_valid, errors, warnings = validate_fields(config) @@ -110,12 +113,16 @@ def validate(config: Dict[str, Any]) -> Tuple[bool, List[str], List[str]]: return False, errors, warnings # Validate serverapp - is_valid, reason = object_ref.validate(config["flower"]["components"]["serverapp"]) + is_valid, reason = object_ref.validate( + config["flower"]["components"]["serverapp"], check_module + ) if not is_valid and isinstance(reason, str): return False, [reason], [] # Validate clientapp - is_valid, reason = object_ref.validate(config["flower"]["components"]["clientapp"]) + is_valid, reason = object_ref.validate( + config["flower"]["components"]["clientapp"], check_module + ) if not is_valid and isinstance(reason, str): return False, [reason], [] diff --git a/src/py/flwr/cli/install.py b/src/py/flwr/cli/install.py new file mode 100644 index 000000000000..e6ce9fe1a69a --- /dev/null +++ b/src/py/flwr/cli/install.py @@ -0,0 +1,196 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Flower command line interface `install` command.""" + + +import os +import shutil +import tempfile +import zipfile +from pathlib import Path +from typing import Optional + +import typer +from typing_extensions import Annotated + +from .config_utils import load_and_validate +from .utils import get_sha256_hash + + +def install( + source: Annotated[ + Optional[Path], + typer.Argument(metavar="source", help="The source FAB file to install."), + ] = None, + flwr_dir: Annotated[ + Optional[Path], + typer.Option(help="The desired install path."), + ] = None, +) -> None: + """Install a Flower App Bundle. + + It can be ran with a single FAB file argument: + + ``flwr install ./target_project.fab`` + + The target install directory can be specified with ``--flwr-dir``: + + ``flwr install ./target_project.fab --flwr-dir ./docs/flwr`` + + This will install ``target_project`` to ``./docs/flwr/``. By default, + ``flwr-dir`` is equal to: + + - ``$FLWR_HOME/`` if ``$FLWR_HOME`` is defined + - ``$XDG_DATA_HOME/.flwr/`` if ``$XDG_DATA_HOME`` is defined + - ``$HOME/.flwr/`` in all other cases + """ + if source is None: + source = Path(typer.prompt("Enter the source FAB file")) + + source = source.resolve() + if not source.exists() or not source.is_file(): + typer.secho( + f"❌ The source {source} does not exist or is not a file.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + if source.suffix != ".fab": + typer.secho( + f"❌ The source {source} is not a `.fab` file.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + install_from_fab(source, flwr_dir) + + +def install_from_fab( + fab_file: Path, flwr_dir: Optional[Path], skip_prompt: bool = False +) -> None: + """Install from a FAB file after extracting and validating.""" + with tempfile.TemporaryDirectory() as tmpdir: + with zipfile.ZipFile(fab_file, "r") as zipf: + zipf.extractall(tmpdir) + tmpdir_path = Path(tmpdir) + info_dir = tmpdir_path / ".info" + if not info_dir.exists(): + typer.secho( + "❌ FAB file has incorrect format.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + content_file = info_dir / "CONTENT" + + if not content_file.exists() or not _verify_hashes( + content_file.read_text(), tmpdir_path + ): + typer.secho( + "❌ File hashes couldn't be verified.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + shutil.rmtree(info_dir) + + validate_and_install(tmpdir_path, fab_file.stem, flwr_dir, skip_prompt) + + +def validate_and_install( + project_dir: Path, + fab_name: str, + flwr_dir: Optional[Path], + skip_prompt: bool = False, +) -> None: + """Validate TOML files and install the project to the desired directory.""" + config, _, _ = load_and_validate(project_dir / "pyproject.toml", check_module=False) + + if config is None: + typer.secho( + "❌ Invalid config inside FAB file.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + publisher = config["flower"]["publisher"] + project_name = config["project"]["name"] + version = config["project"]["version"] + + if fab_name != f"{publisher}.{project_name}.{version.replace('.', '-')}": + typer.secho( + "❌ FAB file has incorrect name. The file name must follow the format " + "`...fab`.", + fg=typer.colors.RED, + bold=True, + ) + raise typer.Exit(code=1) + + install_dir: Path = ( + ( + Path( + os.getenv( + "FLWR_HOME", + f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", + ) + ) + if not flwr_dir + else flwr_dir + ) + / "apps" + / publisher + / project_name + / version + ) + if install_dir.exists() and not skip_prompt: + if not typer.confirm( + typer.style( + f"\n💬 {project_name} version {version} is already installed, " + "do you want to reinstall it?", + fg=typer.colors.MAGENTA, + bold=True, + ) + ): + return + + install_dir.mkdir(parents=True, exist_ok=True) + + # Move contents from source directory + for item in project_dir.iterdir(): + if item.is_dir(): + shutil.copytree(item, install_dir / item.name, dirs_exist_ok=True) + else: + shutil.copy2(item, install_dir / item.name) + + typer.secho( + f"🎊 Successfully installed {project_name} to {install_dir}.", + fg=typer.colors.GREEN, + bold=True, + ) + + +def _verify_hashes(list_content: str, tmpdir: Path) -> bool: + """Verify file hashes based on the LIST content.""" + for line in list_content.strip().split("\n"): + rel_path, hash_expected, _ = line.split(",") + file_path = tmpdir / rel_path + if not file_path.exists() or get_sha256_hash(file_path) != hash_expected: + return False + return True diff --git a/src/py/flwr/cli/utils.py b/src/py/flwr/cli/utils.py index 6460b770b184..2f5a8831fa7c 100644 --- a/src/py/flwr/cli/utils.py +++ b/src/py/flwr/cli/utils.py @@ -14,7 +14,9 @@ # ============================================================================== """Flower command line interface utils.""" +import hashlib import re +from pathlib import Path from typing import Callable, List, Optional, cast import typer @@ -122,3 +124,15 @@ def sanitize_project_name(name: str) -> str: sanitized_name = sanitized_name[1:] return sanitized_name + + +def get_sha256_hash(file_path: Path) -> str: + """Calculate the SHA-256 hash of a file.""" + sha256 = hashlib.sha256() + with open(file_path, "rb") as f: + while True: + data = f.read(65536) # Read in 64kB blocks + if not data: + break + sha256.update(data) + return sha256.hexdigest() diff --git a/src/py/flwr/common/object_ref.py b/src/py/flwr/common/object_ref.py index 4660f07e24a4..b56c69a4f36b 100644 --- a/src/py/flwr/common/object_ref.py +++ b/src/py/flwr/common/object_ref.py @@ -30,6 +30,7 @@ def validate( module_attribute_str: str, + check_module: bool = True, ) -> Tuple[bool, Optional[str]]: """Validate object reference. @@ -56,15 +57,18 @@ def validate( f"Missing attribute in {module_attribute_str}{OBJECT_REF_HELP_STR}", ) - # Load module - module = find_spec(module_str) - if module and module.origin: - if not _find_attribute_in_module(module.origin, attributes_str): - return ( - False, - f"Unable to find attribute {attributes_str} in module {module_str}" - f"{OBJECT_REF_HELP_STR}", - ) + if check_module: + # Load module + module = find_spec(module_str) + if module and module.origin: + if not _find_attribute_in_module(module.origin, attributes_str): + return ( + False, + f"Unable to find attribute {attributes_str} in module {module_str}" + f"{OBJECT_REF_HELP_STR}", + ) + return (True, None) + else: return (True, None) return ( From e54a33bdbb96dfbec7abcf844aa3157e5480ee9c Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Wed, 12 Jun 2024 14:54:02 +0100 Subject: [PATCH 058/124] feat(framework) Add `GetRun` rpc to the Driver servicer (#3578) --- src/proto/flwr/proto/driver.proto | 4 ++ src/proto/flwr/proto/fleet.proto | 10 +-- src/proto/flwr/proto/run.proto | 26 ++++++++ .../grpc_rere_client/client_interceptor.py | 2 +- .../client_interceptor_test.py | 3 +- .../client/grpc_rere_client/connection.py | 3 +- src/py/flwr/client/rest_client/connection.py | 3 +- src/py/flwr/proto/driver_pb2.py | 39 ++++++------ src/py/flwr/proto/driver_pb2_grpc.py | 35 +++++++++++ src/py/flwr/proto/driver_pb2_grpc.pyi | 14 +++++ src/py/flwr/proto/fleet_pb2.py | 61 +++++++++---------- src/py/flwr/proto/fleet_pb2.pyi | 42 ------------- src/py/flwr/proto/fleet_pb2_grpc.py | 13 ++-- src/py/flwr/proto/fleet_pb2_grpc.pyi | 9 +-- src/py/flwr/proto/run_pb2.py | 30 +++++++++ src/py/flwr/proto/run_pb2.pyi | 52 ++++++++++++++++ src/py/flwr/proto/run_pb2_grpc.py | 4 ++ src/py/flwr/proto/run_pb2_grpc.pyi | 4 ++ .../superlink/driver/driver_servicer.py | 7 +++ .../fleet/grpc_rere/fleet_servicer.py | 3 +- .../fleet/grpc_rere/server_interceptor.py | 3 +- .../grpc_rere/server_interceptor_test.py | 3 +- .../fleet/message_handler/message_handler.py | 8 ++- .../superlink/fleet/rest_rere/rest_api.py | 2 +- src/py/flwr_tool/protoc_test.py | 2 +- 25 files changed, 251 insertions(+), 131 deletions(-) create mode 100644 src/proto/flwr/proto/run.proto create mode 100644 src/py/flwr/proto/run_pb2.py create mode 100644 src/py/flwr/proto/run_pb2.pyi create mode 100644 src/py/flwr/proto/run_pb2_grpc.py create mode 100644 src/py/flwr/proto/run_pb2_grpc.pyi diff --git a/src/proto/flwr/proto/driver.proto b/src/proto/flwr/proto/driver.proto index 54e6b6b41b68..edbd5d91bb5b 100644 --- a/src/proto/flwr/proto/driver.proto +++ b/src/proto/flwr/proto/driver.proto @@ -19,6 +19,7 @@ package flwr.proto; import "flwr/proto/node.proto"; import "flwr/proto/task.proto"; +import "flwr/proto/run.proto"; service Driver { // Request run_id @@ -32,6 +33,9 @@ service Driver { // Get task results rpc PullTaskRes(PullTaskResRequest) returns (PullTaskResResponse) {} + + // Get run details + rpc GetRun(GetRunRequest) returns (GetRunResponse) {} } // CreateRun diff --git a/src/proto/flwr/proto/fleet.proto b/src/proto/flwr/proto/fleet.proto index df6b5843023d..24f60bb3d825 100644 --- a/src/proto/flwr/proto/fleet.proto +++ b/src/proto/flwr/proto/fleet.proto @@ -19,6 +19,7 @@ package flwr.proto; import "flwr/proto/node.proto"; import "flwr/proto/task.proto"; +import "flwr/proto/run.proto"; service Fleet { rpc CreateNode(CreateNodeRequest) returns (CreateNodeResponse) {} @@ -70,13 +71,4 @@ message PushTaskResResponse { map results = 2; } -// GetRun messages -message Run { - sint64 run_id = 1; - string fab_id = 2; - string fab_version = 3; -} -message GetRunRequest { sint64 run_id = 1; } -message GetRunResponse { Run run = 1; } - message Reconnect { uint64 reconnect = 1; } diff --git a/src/proto/flwr/proto/run.proto b/src/proto/flwr/proto/run.proto new file mode 100644 index 000000000000..76a7fd91532f --- /dev/null +++ b/src/proto/flwr/proto/run.proto @@ -0,0 +1,26 @@ +// Copyright 2024 Flower Labs GmbH. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================== + +syntax = "proto3"; + +package flwr.proto; + +message Run { + sint64 run_id = 1; + string fab_id = 2; + string fab_version = 3; +} +message GetRunRequest { sint64 run_id = 1; } +message GetRunResponse { Run run = 1; } diff --git a/src/py/flwr/client/grpc_rere_client/client_interceptor.py b/src/py/flwr/client/grpc_rere_client/client_interceptor.py index 8bc55878971d..d2dded8a73d9 100644 --- a/src/py/flwr/client/grpc_rere_client/client_interceptor.py +++ b/src/py/flwr/client/grpc_rere_client/client_interceptor.py @@ -31,11 +31,11 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611 CreateNodeRequest, DeleteNodeRequest, - GetRunRequest, PingRequest, PullTaskInsRequest, PushTaskResRequest, ) +from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611 _PUBLIC_KEY_HEADER = "public-key" _AUTH_TOKEN_HEADER = "auth-token" diff --git a/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py b/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py index 487361a06026..cc35ffef46db 100644 --- a/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py +++ b/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py @@ -41,13 +41,12 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PullTaskInsRequest, PullTaskInsResponse, PushTaskResRequest, PushTaskResResponse, ) +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from .client_interceptor import _AUTH_TOKEN_HEADER, _PUBLIC_KEY_HEADER, Request diff --git a/src/py/flwr/client/grpc_rere_client/connection.py b/src/py/flwr/client/grpc_rere_client/connection.py index 9579d5830165..52d0cc58b2bb 100644 --- a/src/py/flwr/client/grpc_rere_client/connection.py +++ b/src/py/flwr/client/grpc_rere_client/connection.py @@ -44,8 +44,6 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611 CreateNodeRequest, DeleteNodeRequest, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -53,6 +51,7 @@ ) from flwr.proto.fleet_pb2_grpc import FleetStub # pylint: disable=E0611 from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611 from .client_interceptor import AuthenticateClientInterceptor diff --git a/src/py/flwr/client/rest_client/connection.py b/src/py/flwr/client/rest_client/connection.py index da8fbd351ab1..7383eae3d22b 100644 --- a/src/py/flwr/client/rest_client/connection.py +++ b/src/py/flwr/client/rest_client/connection.py @@ -46,8 +46,6 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -56,6 +54,7 @@ PushTaskResResponse, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611 try: diff --git a/src/py/flwr/proto/driver_pb2.py b/src/py/flwr/proto/driver_pb2.py index b0caae58ff6f..a2458b445563 100644 --- a/src/py/flwr/proto/driver_pb2.py +++ b/src/py/flwr/proto/driver_pb2.py @@ -14,31 +14,32 @@ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2 from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2 +from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"7\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"!\n\x0fGetNodesRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"3\n\x10GetNodesResponse\x12\x1f\n\x05nodes\x18\x01 \x03(\x0b\x32\x10.flwr.proto.Node\"@\n\x12PushTaskInsRequest\x12*\n\rtask_ins_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"\'\n\x13PushTaskInsResponse\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"F\n\x12PullTaskResRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"A\n\x13PullTaskResResponse\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes2\xc1\x02\n\x06\x44river\x12J\n\tCreateRun\x12\x1c.flwr.proto.CreateRunRequest\x1a\x1d.flwr.proto.CreateRunResponse\"\x00\x12G\n\x08GetNodes\x12\x1b.flwr.proto.GetNodesRequest\x1a\x1c.flwr.proto.GetNodesResponse\"\x00\x12P\n\x0bPushTaskIns\x12\x1e.flwr.proto.PushTaskInsRequest\x1a\x1f.flwr.proto.PushTaskInsResponse\"\x00\x12P\n\x0bPullTaskRes\x12\x1e.flwr.proto.PullTaskResRequest\x1a\x1f.flwr.proto.PullTaskResResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x17\x66lwr/proto/driver.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\"7\n\x10\x43reateRunRequest\x12\x0e\n\x06\x66\x61\x62_id\x18\x01 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x02 \x01(\t\"#\n\x11\x43reateRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"!\n\x0fGetNodesRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"3\n\x10GetNodesResponse\x12\x1f\n\x05nodes\x18\x01 \x03(\x0b\x32\x10.flwr.proto.Node\"@\n\x12PushTaskInsRequest\x12*\n\rtask_ins_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"\'\n\x13PushTaskInsResponse\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"F\n\x12PullTaskResRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"A\n\x13PullTaskResResponse\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes2\x84\x03\n\x06\x44river\x12J\n\tCreateRun\x12\x1c.flwr.proto.CreateRunRequest\x1a\x1d.flwr.proto.CreateRunResponse\"\x00\x12G\n\x08GetNodes\x12\x1b.flwr.proto.GetNodesRequest\x1a\x1c.flwr.proto.GetNodesResponse\"\x00\x12P\n\x0bPushTaskIns\x12\x1e.flwr.proto.PushTaskInsRequest\x1a\x1f.flwr.proto.PushTaskInsResponse\"\x00\x12P\n\x0bPullTaskRes\x12\x1e.flwr.proto.PullTaskResRequest\x1a\x1f.flwr.proto.PullTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.driver_pb2', _globals) if _descriptor._USE_C_DESCRIPTORS == False: DESCRIPTOR._options = None - _globals['_CREATERUNREQUEST']._serialized_start=85 - _globals['_CREATERUNREQUEST']._serialized_end=140 - _globals['_CREATERUNRESPONSE']._serialized_start=142 - _globals['_CREATERUNRESPONSE']._serialized_end=177 - _globals['_GETNODESREQUEST']._serialized_start=179 - _globals['_GETNODESREQUEST']._serialized_end=212 - _globals['_GETNODESRESPONSE']._serialized_start=214 - _globals['_GETNODESRESPONSE']._serialized_end=265 - _globals['_PUSHTASKINSREQUEST']._serialized_start=267 - _globals['_PUSHTASKINSREQUEST']._serialized_end=331 - _globals['_PUSHTASKINSRESPONSE']._serialized_start=333 - _globals['_PUSHTASKINSRESPONSE']._serialized_end=372 - _globals['_PULLTASKRESREQUEST']._serialized_start=374 - _globals['_PULLTASKRESREQUEST']._serialized_end=444 - _globals['_PULLTASKRESRESPONSE']._serialized_start=446 - _globals['_PULLTASKRESRESPONSE']._serialized_end=511 - _globals['_DRIVER']._serialized_start=514 - _globals['_DRIVER']._serialized_end=835 + _globals['_CREATERUNREQUEST']._serialized_start=107 + _globals['_CREATERUNREQUEST']._serialized_end=162 + _globals['_CREATERUNRESPONSE']._serialized_start=164 + _globals['_CREATERUNRESPONSE']._serialized_end=199 + _globals['_GETNODESREQUEST']._serialized_start=201 + _globals['_GETNODESREQUEST']._serialized_end=234 + _globals['_GETNODESRESPONSE']._serialized_start=236 + _globals['_GETNODESRESPONSE']._serialized_end=287 + _globals['_PUSHTASKINSREQUEST']._serialized_start=289 + _globals['_PUSHTASKINSREQUEST']._serialized_end=353 + _globals['_PUSHTASKINSRESPONSE']._serialized_start=355 + _globals['_PUSHTASKINSRESPONSE']._serialized_end=394 + _globals['_PULLTASKRESREQUEST']._serialized_start=396 + _globals['_PULLTASKRESREQUEST']._serialized_end=466 + _globals['_PULLTASKRESRESPONSE']._serialized_start=468 + _globals['_PULLTASKRESRESPONSE']._serialized_end=533 + _globals['_DRIVER']._serialized_start=536 + _globals['_DRIVER']._serialized_end=924 # @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/driver_pb2_grpc.py b/src/py/flwr/proto/driver_pb2_grpc.py index ac6815023ebd..2cd3ebe62a63 100644 --- a/src/py/flwr/proto/driver_pb2_grpc.py +++ b/src/py/flwr/proto/driver_pb2_grpc.py @@ -3,6 +3,7 @@ import grpc from flwr.proto import driver_pb2 as flwr_dot_proto_dot_driver__pb2 +from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2 class DriverStub(object): @@ -34,6 +35,11 @@ def __init__(self, channel): request_serializer=flwr_dot_proto_dot_driver__pb2.PullTaskResRequest.SerializeToString, response_deserializer=flwr_dot_proto_dot_driver__pb2.PullTaskResResponse.FromString, ) + self.GetRun = channel.unary_unary( + '/flwr.proto.Driver/GetRun', + request_serializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString, + response_deserializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString, + ) class DriverServicer(object): @@ -67,6 +73,13 @@ def PullTaskRes(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def GetRun(self, request, context): + """Get run details + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_DriverServicer_to_server(servicer, server): rpc_method_handlers = { @@ -90,6 +103,11 @@ def add_DriverServicer_to_server(servicer, server): request_deserializer=flwr_dot_proto_dot_driver__pb2.PullTaskResRequest.FromString, response_serializer=flwr_dot_proto_dot_driver__pb2.PullTaskResResponse.SerializeToString, ), + 'GetRun': grpc.unary_unary_rpc_method_handler( + servicer.GetRun, + request_deserializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.FromString, + response_serializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'flwr.proto.Driver', rpc_method_handlers) @@ -167,3 +185,20 @@ def PullTaskRes(request, flwr_dot_proto_dot_driver__pb2.PullTaskResResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def GetRun(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/flwr.proto.Driver/GetRun', + flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString, + flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/driver_pb2_grpc.pyi b/src/py/flwr/proto/driver_pb2_grpc.pyi index 43cf45f39b25..4ff09db588ca 100644 --- a/src/py/flwr/proto/driver_pb2_grpc.pyi +++ b/src/py/flwr/proto/driver_pb2_grpc.pyi @@ -4,6 +4,7 @@ isort:skip_file """ import abc import flwr.proto.driver_pb2 +import flwr.proto.run_pb2 import grpc class DriverStub: @@ -28,6 +29,11 @@ class DriverStub: flwr.proto.driver_pb2.PullTaskResResponse] """Get task results""" + GetRun: grpc.UnaryUnaryMultiCallable[ + flwr.proto.run_pb2.GetRunRequest, + flwr.proto.run_pb2.GetRunResponse] + """Get run details""" + class DriverServicer(metaclass=abc.ABCMeta): @abc.abstractmethod @@ -62,5 +68,13 @@ class DriverServicer(metaclass=abc.ABCMeta): """Get task results""" pass + @abc.abstractmethod + def GetRun(self, + request: flwr.proto.run_pb2.GetRunRequest, + context: grpc.ServicerContext, + ) -> flwr.proto.run_pb2.GetRunResponse: + """Get run details""" + pass + def add_DriverServicer_to_server(servicer: DriverServicer, server: grpc.Server) -> None: ... diff --git a/src/py/flwr/proto/fleet_pb2.py b/src/py/flwr/proto/fleet_pb2.py index 42f3292d910d..9763b71fed2f 100644 --- a/src/py/flwr/proto/fleet_pb2.py +++ b/src/py/flwr/proto/fleet_pb2.py @@ -14,9 +14,10 @@ from flwr.proto import node_pb2 as flwr_dot_proto_dot_node__pb2 from flwr.proto import task_pb2 as flwr_dot_proto_dot_task__pb2 +from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2 -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\":\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\"\x1f\n\rGetRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Run\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xc9\x03\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x16\x66lwr/proto/fleet.proto\x12\nflwr.proto\x1a\x15\x66lwr/proto/node.proto\x1a\x15\x66lwr/proto/task.proto\x1a\x14\x66lwr/proto/run.proto\"*\n\x11\x43reateNodeRequest\x12\x15\n\rping_interval\x18\x01 \x01(\x01\"4\n\x12\x43reateNodeResponse\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"3\n\x11\x44\x65leteNodeRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\"\x14\n\x12\x44\x65leteNodeResponse\"D\n\x0bPingRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x15\n\rping_interval\x18\x02 \x01(\x01\"\x1f\n\x0cPingResponse\x12\x0f\n\x07success\x18\x01 \x01(\x08\"F\n\x12PullTaskInsRequest\x12\x1e\n\x04node\x18\x01 \x01(\x0b\x32\x10.flwr.proto.Node\x12\x10\n\x08task_ids\x18\x02 \x03(\t\"k\n\x13PullTaskInsResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12*\n\rtask_ins_list\x18\x02 \x03(\x0b\x32\x13.flwr.proto.TaskIns\"@\n\x12PushTaskResRequest\x12*\n\rtask_res_list\x18\x01 \x03(\x0b\x32\x13.flwr.proto.TaskRes\"\xae\x01\n\x13PushTaskResResponse\x12(\n\treconnect\x18\x01 \x01(\x0b\x32\x15.flwr.proto.Reconnect\x12=\n\x07results\x18\x02 \x03(\x0b\x32,.flwr.proto.PushTaskResResponse.ResultsEntry\x1a.\n\x0cResultsEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\r:\x02\x38\x01\"\x1e\n\tReconnect\x12\x11\n\treconnect\x18\x01 \x01(\x04\x32\xc9\x03\n\x05\x46leet\x12M\n\nCreateNode\x12\x1d.flwr.proto.CreateNodeRequest\x1a\x1e.flwr.proto.CreateNodeResponse\"\x00\x12M\n\nDeleteNode\x12\x1d.flwr.proto.DeleteNodeRequest\x1a\x1e.flwr.proto.DeleteNodeResponse\"\x00\x12;\n\x04Ping\x12\x17.flwr.proto.PingRequest\x1a\x18.flwr.proto.PingResponse\"\x00\x12P\n\x0bPullTaskIns\x12\x1e.flwr.proto.PullTaskInsRequest\x1a\x1f.flwr.proto.PullTaskInsResponse\"\x00\x12P\n\x0bPushTaskRes\x12\x1e.flwr.proto.PushTaskResRequest\x1a\x1f.flwr.proto.PushTaskResResponse\"\x00\x12\x41\n\x06GetRun\x12\x19.flwr.proto.GetRunRequest\x1a\x1a.flwr.proto.GetRunResponse\"\x00\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -25,36 +26,30 @@ DESCRIPTOR._options = None _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._options = None _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_options = b'8\001' - _globals['_CREATENODEREQUEST']._serialized_start=84 - _globals['_CREATENODEREQUEST']._serialized_end=126 - _globals['_CREATENODERESPONSE']._serialized_start=128 - _globals['_CREATENODERESPONSE']._serialized_end=180 - _globals['_DELETENODEREQUEST']._serialized_start=182 - _globals['_DELETENODEREQUEST']._serialized_end=233 - _globals['_DELETENODERESPONSE']._serialized_start=235 - _globals['_DELETENODERESPONSE']._serialized_end=255 - _globals['_PINGREQUEST']._serialized_start=257 - _globals['_PINGREQUEST']._serialized_end=325 - _globals['_PINGRESPONSE']._serialized_start=327 - _globals['_PINGRESPONSE']._serialized_end=358 - _globals['_PULLTASKINSREQUEST']._serialized_start=360 - _globals['_PULLTASKINSREQUEST']._serialized_end=430 - _globals['_PULLTASKINSRESPONSE']._serialized_start=432 - _globals['_PULLTASKINSRESPONSE']._serialized_end=539 - _globals['_PUSHTASKRESREQUEST']._serialized_start=541 - _globals['_PUSHTASKRESREQUEST']._serialized_end=605 - _globals['_PUSHTASKRESRESPONSE']._serialized_start=608 - _globals['_PUSHTASKRESRESPONSE']._serialized_end=782 - _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_start=736 - _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_end=782 - _globals['_RUN']._serialized_start=784 - _globals['_RUN']._serialized_end=842 - _globals['_GETRUNREQUEST']._serialized_start=844 - _globals['_GETRUNREQUEST']._serialized_end=875 - _globals['_GETRUNRESPONSE']._serialized_start=877 - _globals['_GETRUNRESPONSE']._serialized_end=923 - _globals['_RECONNECT']._serialized_start=925 - _globals['_RECONNECT']._serialized_end=955 - _globals['_FLEET']._serialized_start=958 - _globals['_FLEET']._serialized_end=1415 + _globals['_CREATENODEREQUEST']._serialized_start=106 + _globals['_CREATENODEREQUEST']._serialized_end=148 + _globals['_CREATENODERESPONSE']._serialized_start=150 + _globals['_CREATENODERESPONSE']._serialized_end=202 + _globals['_DELETENODEREQUEST']._serialized_start=204 + _globals['_DELETENODEREQUEST']._serialized_end=255 + _globals['_DELETENODERESPONSE']._serialized_start=257 + _globals['_DELETENODERESPONSE']._serialized_end=277 + _globals['_PINGREQUEST']._serialized_start=279 + _globals['_PINGREQUEST']._serialized_end=347 + _globals['_PINGRESPONSE']._serialized_start=349 + _globals['_PINGRESPONSE']._serialized_end=380 + _globals['_PULLTASKINSREQUEST']._serialized_start=382 + _globals['_PULLTASKINSREQUEST']._serialized_end=452 + _globals['_PULLTASKINSRESPONSE']._serialized_start=454 + _globals['_PULLTASKINSRESPONSE']._serialized_end=561 + _globals['_PUSHTASKRESREQUEST']._serialized_start=563 + _globals['_PUSHTASKRESREQUEST']._serialized_end=627 + _globals['_PUSHTASKRESRESPONSE']._serialized_start=630 + _globals['_PUSHTASKRESRESPONSE']._serialized_end=804 + _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_start=758 + _globals['_PUSHTASKRESRESPONSE_RESULTSENTRY']._serialized_end=804 + _globals['_RECONNECT']._serialized_start=806 + _globals['_RECONNECT']._serialized_end=836 + _globals['_FLEET']._serialized_start=839 + _globals['_FLEET']._serialized_end=1296 # @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/fleet_pb2.pyi b/src/py/flwr/proto/fleet_pb2.pyi index a6f38b703e76..5989f45c5c60 100644 --- a/src/py/flwr/proto/fleet_pb2.pyi +++ b/src/py/flwr/proto/fleet_pb2.pyi @@ -164,48 +164,6 @@ class PushTaskResResponse(google.protobuf.message.Message): def ClearField(self, field_name: typing_extensions.Literal["reconnect",b"reconnect","results",b"results"]) -> None: ... global___PushTaskResResponse = PushTaskResResponse -class Run(google.protobuf.message.Message): - """GetRun messages""" - DESCRIPTOR: google.protobuf.descriptor.Descriptor - RUN_ID_FIELD_NUMBER: builtins.int - FAB_ID_FIELD_NUMBER: builtins.int - FAB_VERSION_FIELD_NUMBER: builtins.int - run_id: builtins.int - fab_id: typing.Text - fab_version: typing.Text - def __init__(self, - *, - run_id: builtins.int = ..., - fab_id: typing.Text = ..., - fab_version: typing.Text = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["fab_id",b"fab_id","fab_version",b"fab_version","run_id",b"run_id"]) -> None: ... -global___Run = Run - -class GetRunRequest(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - RUN_ID_FIELD_NUMBER: builtins.int - run_id: builtins.int - def __init__(self, - *, - run_id: builtins.int = ..., - ) -> None: ... - def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ... -global___GetRunRequest = GetRunRequest - -class GetRunResponse(google.protobuf.message.Message): - DESCRIPTOR: google.protobuf.descriptor.Descriptor - RUN_FIELD_NUMBER: builtins.int - @property - def run(self) -> global___Run: ... - def __init__(self, - *, - run: typing.Optional[global___Run] = ..., - ) -> None: ... - def HasField(self, field_name: typing_extensions.Literal["run",b"run"]) -> builtins.bool: ... - def ClearField(self, field_name: typing_extensions.Literal["run",b"run"]) -> None: ... -global___GetRunResponse = GetRunResponse - class Reconnect(google.protobuf.message.Message): DESCRIPTOR: google.protobuf.descriptor.Descriptor RECONNECT_FIELD_NUMBER: builtins.int diff --git a/src/py/flwr/proto/fleet_pb2_grpc.py b/src/py/flwr/proto/fleet_pb2_grpc.py index 16757eaed381..e0b0fbc50460 100644 --- a/src/py/flwr/proto/fleet_pb2_grpc.py +++ b/src/py/flwr/proto/fleet_pb2_grpc.py @@ -3,6 +3,7 @@ import grpc from flwr.proto import fleet_pb2 as flwr_dot_proto_dot_fleet__pb2 +from flwr.proto import run_pb2 as flwr_dot_proto_dot_run__pb2 class FleetStub(object): @@ -41,8 +42,8 @@ def __init__(self, channel): ) self.GetRun = channel.unary_unary( '/flwr.proto.Fleet/GetRun', - request_serializer=flwr_dot_proto_dot_fleet__pb2.GetRunRequest.SerializeToString, - response_deserializer=flwr_dot_proto_dot_fleet__pb2.GetRunResponse.FromString, + request_serializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString, + response_deserializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString, ) @@ -121,8 +122,8 @@ def add_FleetServicer_to_server(servicer, server): ), 'GetRun': grpc.unary_unary_rpc_method_handler( servicer.GetRun, - request_deserializer=flwr_dot_proto_dot_fleet__pb2.GetRunRequest.FromString, - response_serializer=flwr_dot_proto_dot_fleet__pb2.GetRunResponse.SerializeToString, + request_deserializer=flwr_dot_proto_dot_run__pb2.GetRunRequest.FromString, + response_serializer=flwr_dot_proto_dot_run__pb2.GetRunResponse.SerializeToString, ), } generic_handler = grpc.method_handlers_generic_handler( @@ -231,7 +232,7 @@ def GetRun(request, timeout=None, metadata=None): return grpc.experimental.unary_unary(request, target, '/flwr.proto.Fleet/GetRun', - flwr_dot_proto_dot_fleet__pb2.GetRunRequest.SerializeToString, - flwr_dot_proto_dot_fleet__pb2.GetRunResponse.FromString, + flwr_dot_proto_dot_run__pb2.GetRunRequest.SerializeToString, + flwr_dot_proto_dot_run__pb2.GetRunResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/fleet_pb2_grpc.pyi b/src/py/flwr/proto/fleet_pb2_grpc.pyi index f275cd149d69..1c0ab862d45c 100644 --- a/src/py/flwr/proto/fleet_pb2_grpc.pyi +++ b/src/py/flwr/proto/fleet_pb2_grpc.pyi @@ -4,6 +4,7 @@ isort:skip_file """ import abc import flwr.proto.fleet_pb2 +import flwr.proto.run_pb2 import grpc class FleetStub: @@ -37,8 +38,8 @@ class FleetStub: """ GetRun: grpc.UnaryUnaryMultiCallable[ - flwr.proto.fleet_pb2.GetRunRequest, - flwr.proto.fleet_pb2.GetRunResponse] + flwr.proto.run_pb2.GetRunRequest, + flwr.proto.run_pb2.GetRunResponse] class FleetServicer(metaclass=abc.ABCMeta): @@ -84,9 +85,9 @@ class FleetServicer(metaclass=abc.ABCMeta): @abc.abstractmethod def GetRun(self, - request: flwr.proto.fleet_pb2.GetRunRequest, + request: flwr.proto.run_pb2.GetRunRequest, context: grpc.ServicerContext, - ) -> flwr.proto.fleet_pb2.GetRunResponse: ... + ) -> flwr.proto.run_pb2.GetRunResponse: ... def add_FleetServicer_to_server(servicer: FleetServicer, server: grpc.Server) -> None: ... diff --git a/src/py/flwr/proto/run_pb2.py b/src/py/flwr/proto/run_pb2.py new file mode 100644 index 000000000000..13f06e7169aa --- /dev/null +++ b/src/py/flwr/proto/run_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: flwr/proto/run.proto +# Protobuf Python Version: 4.25.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/run.proto\x12\nflwr.proto\":\n\x03Run\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\x12\x0e\n\x06\x66\x61\x62_id\x18\x02 \x01(\t\x12\x13\n\x0b\x66\x61\x62_version\x18\x03 \x01(\t\"\x1f\n\rGetRunRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\".\n\x0eGetRunResponse\x12\x1c\n\x03run\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Runb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.run_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_RUN']._serialized_start=36 + _globals['_RUN']._serialized_end=94 + _globals['_GETRUNREQUEST']._serialized_start=96 + _globals['_GETRUNREQUEST']._serialized_end=127 + _globals['_GETRUNRESPONSE']._serialized_start=129 + _globals['_GETRUNRESPONSE']._serialized_end=175 +# @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/run_pb2.pyi b/src/py/flwr/proto/run_pb2.pyi new file mode 100644 index 000000000000..401d27855a41 --- /dev/null +++ b/src/py/flwr/proto/run_pb2.pyi @@ -0,0 +1,52 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing +import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class Run(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RUN_ID_FIELD_NUMBER: builtins.int + FAB_ID_FIELD_NUMBER: builtins.int + FAB_VERSION_FIELD_NUMBER: builtins.int + run_id: builtins.int + fab_id: typing.Text + fab_version: typing.Text + def __init__(self, + *, + run_id: builtins.int = ..., + fab_id: typing.Text = ..., + fab_version: typing.Text = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["fab_id",b"fab_id","fab_version",b"fab_version","run_id",b"run_id"]) -> None: ... +global___Run = Run + +class GetRunRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RUN_ID_FIELD_NUMBER: builtins.int + run_id: builtins.int + def __init__(self, + *, + run_id: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ... +global___GetRunRequest = GetRunRequest + +class GetRunResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RUN_FIELD_NUMBER: builtins.int + @property + def run(self) -> global___Run: ... + def __init__(self, + *, + run: typing.Optional[global___Run] = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["run",b"run"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["run",b"run"]) -> None: ... +global___GetRunResponse = GetRunResponse diff --git a/src/py/flwr/proto/run_pb2_grpc.py b/src/py/flwr/proto/run_pb2_grpc.py new file mode 100644 index 000000000000..2daafffebfc8 --- /dev/null +++ b/src/py/flwr/proto/run_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/src/py/flwr/proto/run_pb2_grpc.pyi b/src/py/flwr/proto/run_pb2_grpc.pyi new file mode 100644 index 000000000000..f3a5a087ef5d --- /dev/null +++ b/src/py/flwr/proto/run_pb2_grpc.pyi @@ -0,0 +1,4 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" diff --git a/src/py/flwr/server/superlink/driver/driver_servicer.py b/src/py/flwr/server/superlink/driver/driver_servicer.py index ce2d9d68d8ca..e808616af778 100644 --- a/src/py/flwr/server/superlink/driver/driver_servicer.py +++ b/src/py/flwr/server/superlink/driver/driver_servicer.py @@ -35,6 +35,7 @@ PushTaskInsResponse, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611 from flwr.server.superlink.state import State, StateFactory from flwr.server.utils.validator import validate_task_ins_or_res @@ -129,6 +130,12 @@ def on_rpc_done() -> None: context.set_code(grpc.StatusCode.OK) return PullTaskResResponse(task_res_list=task_res_list) + def GetRun( + self, request: GetRunRequest, context: grpc.ServicerContext + ) -> GetRunResponse: + """Get run information.""" + raise NotImplementedError + def _raise_if(validation_error: bool, detail: str) -> None: if validation_error: diff --git a/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py b/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py index 03a2ec064213..13e024eb31e4 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +++ b/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py @@ -26,8 +26,6 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -35,6 +33,7 @@ PushTaskResRequest, PushTaskResResponse, ) +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.server.superlink.fleet.message_handler import message_handler from flwr.server.superlink.state import StateFactory diff --git a/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py b/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py index 6a302679a235..21e9c44907cd 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py +++ b/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor.py @@ -34,8 +34,6 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -44,6 +42,7 @@ PushTaskResResponse, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.server.superlink.state import State _PUBLIC_KEY_HEADER = "public-key" diff --git a/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor_test.py b/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor_test.py index c4c71e5a8188..01499102b7d8 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor_test.py +++ b/src/py/flwr/server/superlink/fleet/grpc_rere/server_interceptor_test.py @@ -32,8 +32,6 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -42,6 +40,7 @@ PushTaskResResponse, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.proto.task_pb2 import Task, TaskRes # pylint: disable=E0611 from flwr.server.app import ADDRESS_FLEET_API_GRPC_RERE, _run_fleet_api_grpc_rere from flwr.server.superlink.state.state_factory import StateFactory diff --git a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py index 83b005a4cb8e..4c796502436b 100644 --- a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +++ b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py @@ -24,8 +24,6 @@ CreateNodeResponse, DeleteNodeRequest, DeleteNodeResponse, - GetRunRequest, - GetRunResponse, PingRequest, PingResponse, PullTaskInsRequest, @@ -33,9 +31,13 @@ PushTaskResRequest, PushTaskResResponse, Reconnect, - Run, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import ( # pylint: disable=E0611 + GetRunRequest, + GetRunResponse, + Run, +) from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611 from flwr.server.superlink.state import State diff --git a/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py b/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py index 8ac7c6cfc613..c7ff496d39bf 100644 --- a/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +++ b/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py @@ -21,11 +21,11 @@ from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611 CreateNodeRequest, DeleteNodeRequest, - GetRunRequest, PingRequest, PullTaskInsRequest, PushTaskResRequest, ) +from flwr.proto.run_pb2 import GetRunRequest # pylint: disable=E0611 from flwr.server.superlink.fleet.message_handler import message_handler from flwr.server.superlink.state import State diff --git a/src/py/flwr_tool/protoc_test.py b/src/py/flwr_tool/protoc_test.py index 8dcf4c6474d6..6aec4251c384 100644 --- a/src/py/flwr_tool/protoc_test.py +++ b/src/py/flwr_tool/protoc_test.py @@ -28,4 +28,4 @@ def test_directories() -> None: def test_proto_file_count() -> None: """Test if the correct number of proto files were captured by the glob.""" - assert len(PROTO_FILES) == 8 + assert len(PROTO_FILES) == 9 From 742e49886753b613c577b2117e4acab7be9da9f3 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Wed, 12 Jun 2024 16:04:47 +0200 Subject: [PATCH 059/124] break(framework) Remove `flower-driver-api` and `flower-fleet-api` (#3418) Co-authored-by: jafermarq Co-authored-by: Daniel J. Beutel --- pyproject.toml | 2 - src/py/flwr/server/__init__.py | 4 - src/py/flwr/server/app.py | 169 +-------------------------------- 3 files changed, 1 insertion(+), 174 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a1a21a6b94cf..62e17aeb5281 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,8 +53,6 @@ exclude = [ [tool.poetry.scripts] flwr = "flwr.cli.app:app" -flower-driver-api = "flwr.server:run_driver_api" -flower-fleet-api = "flwr.server:run_fleet_api" flower-superlink = "flwr.server:run_superlink" flower-supernode = "flwr.client:run_supernode" flower-client-app = "flwr.client:run_client_app" diff --git a/src/py/flwr/server/__init__.py b/src/py/flwr/server/__init__.py index 875f66c43d03..19c6034bcaa1 100644 --- a/src/py/flwr/server/__init__.py +++ b/src/py/flwr/server/__init__.py @@ -17,8 +17,6 @@ from . import strategy from . import workflow as workflow -from .app import run_driver_api as run_driver_api -from .app import run_fleet_api as run_fleet_api from .app import run_superlink as run_superlink from .app import start_server as start_server from .client_manager import ClientManager as ClientManager @@ -36,8 +34,6 @@ "Driver", "History", "LegacyContext", - "run_driver_api", - "run_fleet_api", "run_server_app", "run_superlink", "Server", diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index c050c983134b..cbb18b602fcd 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -40,7 +40,7 @@ TRANSPORT_TYPE_REST, ) from flwr.common.exit_handlers import register_exit_handlers -from flwr.common.logger import log, warn_deprecated_feature +from flwr.common.logger import log from flwr.common.secure_aggregation.crypto.symmetric_encryption import ( private_key_to_bytes, public_key_to_bytes, @@ -190,139 +190,6 @@ def start_server( # pylint: disable=too-many-arguments,too-many-locals return hist -def run_driver_api() -> None: - """Run Flower server (Driver API).""" - log(INFO, "Starting Flower server (Driver API)") - # Running `flower-driver-api` is deprecated - warn_deprecated_feature("flower-driver-api") - log(WARN, "Use `flower-superlink` instead") - event(EventType.RUN_DRIVER_API_ENTER) - args = _parse_args_run_driver_api().parse_args() - - # Parse IP address - parsed_address = parse_address(args.driver_api_address) - if not parsed_address: - sys.exit(f"Driver IP address ({args.driver_api_address}) cannot be parsed.") - host, port, is_v6 = parsed_address - address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" - - # Obtain certificates - certificates = _try_obtain_certificates(args) - - # Initialize StateFactory - state_factory = StateFactory(args.database) - - # Start server - grpc_server: grpc.Server = run_driver_api_grpc( - address=address, - state_factory=state_factory, - certificates=certificates, - ) - - # Graceful shutdown - register_exit_handlers( - event_type=EventType.RUN_DRIVER_API_LEAVE, - grpc_servers=[grpc_server], - bckg_threads=[], - ) - - # Block - grpc_server.wait_for_termination() - - -# pylint: disable=too-many-locals -def run_fleet_api() -> None: - """Run Flower server (Fleet API).""" - log(INFO, "Starting Flower server (Fleet API)") - # Running `flower-fleet-api` is deprecated - warn_deprecated_feature("flower-fleet-api") - log(WARN, "Use `flower-superlink` instead") - event(EventType.RUN_FLEET_API_ENTER) - args = _parse_args_run_fleet_api().parse_args() - - # Obtain certificates - certificates = _try_obtain_certificates(args) - - # Initialize StateFactory - state_factory = StateFactory(args.database) - - grpc_servers = [] - bckg_threads = [] - - address_arg = args.fleet_api_address - parsed_address = parse_address(address_arg) - if not parsed_address: - sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") - host, port, is_v6 = parsed_address - address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" - - num_workers = args.fleet_api_num_workers - if num_workers != 1: - log( - WARN, - "The Fleet API currently supports only 1 worker. " - "You have specified %d workers. " - "Support for multiple workers will be added in future releases. " - "Proceeding with a single worker.", - args.fleet_api_num_workers, - ) - num_workers = 1 - - # Start Fleet API - if args.fleet_api_type == TRANSPORT_TYPE_REST: - if ( - importlib.util.find_spec("requests") - and importlib.util.find_spec("starlette") - and importlib.util.find_spec("uvicorn") - ) is None: - sys.exit(MISSING_EXTRA_REST) - - _, ssl_certfile, ssl_keyfile = ( - certificates if certificates is not None else (None, None, None) - ) - fleet_thread = threading.Thread( - target=_run_fleet_api_rest, - args=( - host, - port, - ssl_keyfile, - ssl_certfile, - state_factory, - num_workers, - ), - ) - fleet_thread.start() - bckg_threads.append(fleet_thread) - elif args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE: - address_arg = args.grpc_rere_fleet_api_address - parsed_address = parse_address(address_arg) - if not parsed_address: - sys.exit(f"Fleet IP address ({address_arg}) cannot be parsed.") - host, port, is_v6 = parsed_address - address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" - fleet_server = _run_fleet_api_grpc_rere( - address=address, - state_factory=state_factory, - certificates=certificates, - ) - grpc_servers.append(fleet_server) - else: - raise ValueError(f"Unknown fleet_api_type: {args.fleet_api_type}") - - # Graceful shutdown - register_exit_handlers( - event_type=EventType.RUN_FLEET_API_LEAVE, - grpc_servers=grpc_servers, - bckg_threads=bckg_threads, - ) - - # Block - if len(grpc_servers) > 0: - grpc_servers[0].wait_for_termination() - elif len(bckg_threads) > 0: - bckg_threads[0].join() - - # pylint: disable=too-many-branches, too-many-locals, too-many-statements def run_superlink() -> None: """Run Flower SuperLink (Driver API and Fleet API).""" @@ -661,40 +528,6 @@ def _run_fleet_api_rest( ) -def _parse_args_run_driver_api() -> argparse.ArgumentParser: - """Parse command line arguments for Driver API.""" - parser = argparse.ArgumentParser( - description="Start a Flower Driver API server. " - "This server will be responsible for " - "receiving TaskIns from the Driver script and " - "sending them to the Fleet API. Once the client nodes " - "are done, they will send the TaskRes back to this Driver API server (through" - " the Fleet API) which will then send them back to the Driver script.", - ) - - _add_args_common(parser=parser) - _add_args_driver_api(parser=parser) - - return parser - - -def _parse_args_run_fleet_api() -> argparse.ArgumentParser: - """Parse command line arguments for Fleet API.""" - parser = argparse.ArgumentParser( - description="Start a Flower Fleet API server." - "This server will be responsible for " - "sending TaskIns (received from the Driver API) to the client nodes " - "and of receiving TaskRes sent back from those same client nodes once " - "they are done. Then, this Fleet API server can send those " - "TaskRes back to the Driver API.", - ) - - _add_args_common(parser=parser) - _add_args_fleet_api(parser=parser) - - return parser - - def _parse_args_run_superlink() -> argparse.ArgumentParser: """Parse command line arguments for both Driver API and Fleet API.""" parser = argparse.ArgumentParser( From 910c1f1784fac4497d055ee86c786bc6b2af7efb Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 12:52:43 +0200 Subject: [PATCH 060/124] feat(framework:skip) Allow `flwr install` to work with `bytes` (#3546) --- src/py/flwr/cli/install.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/py/flwr/cli/install.py b/src/py/flwr/cli/install.py index e6ce9fe1a69a..d6d2ee55a47a 100644 --- a/src/py/flwr/cli/install.py +++ b/src/py/flwr/cli/install.py @@ -19,8 +19,9 @@ import shutil import tempfile import zipfile +from io import BytesIO from pathlib import Path -from typing import Optional +from typing import IO, Optional, Union import typer from typing_extensions import Annotated @@ -80,11 +81,24 @@ def install( def install_from_fab( - fab_file: Path, flwr_dir: Optional[Path], skip_prompt: bool = False + fab_file: Union[Path, bytes], + flwr_dir: Optional[Path], + skip_prompt: bool = False, ) -> None: """Install from a FAB file after extracting and validating.""" + fab_file_archive: Union[Path, IO[bytes]] + fab_name: Optional[str] + if isinstance(fab_file, bytes): + fab_file_archive = BytesIO(fab_file) + fab_name = None + elif isinstance(fab_file, Path): + fab_file_archive = fab_file + fab_name = fab_file.stem + else: + raise ValueError("fab_file must be either a Path or bytes") + with tempfile.TemporaryDirectory() as tmpdir: - with zipfile.ZipFile(fab_file, "r") as zipf: + with zipfile.ZipFile(fab_file_archive, "r") as zipf: zipf.extractall(tmpdir) tmpdir_path = Path(tmpdir) info_dir = tmpdir_path / ".info" @@ -110,12 +124,12 @@ def install_from_fab( shutil.rmtree(info_dir) - validate_and_install(tmpdir_path, fab_file.stem, flwr_dir, skip_prompt) + validate_and_install(tmpdir_path, fab_name, flwr_dir, skip_prompt) def validate_and_install( project_dir: Path, - fab_name: str, + fab_name: Optional[str], flwr_dir: Optional[Path], skip_prompt: bool = False, ) -> None: @@ -134,7 +148,10 @@ def validate_and_install( project_name = config["project"]["name"] version = config["project"]["version"] - if fab_name != f"{publisher}.{project_name}.{version.replace('.', '-')}": + if ( + fab_name + and fab_name != f"{publisher}.{project_name}.{version.replace('.', '-')}" + ): typer.secho( "❌ FAB file has incorrect name. The file name must follow the format " "`...fab`.", From 80191fe736b85ba6175edd1382b60bd2d17a1ec8 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 13 Jun 2024 13:54:54 +0200 Subject: [PATCH 061/124] docs(*:skip) Fix chown command (#3595) --- doc/source/how-to-run-flower-using-docker.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index cffcd18129b5..54079968d417 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -86,7 +86,7 @@ container. Furthermore, we use the flag ``--database`` to specify the name of th .. code-block:: bash $ mkdir state - $ sudo chmod -R 49999:49999 state + $ sudo chown -R 49999:49999 state $ docker run --rm \ -p 9091:9091 -p 9092:9092 --volume ./state/:/app/state flwr/superlink:1.8.0 \ --insecure \ From 8fc4287c27be3435e02e797617c857b46c00379d Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 13 Jun 2024 16:32:23 +0100 Subject: [PATCH 062/124] feat(framework) Implement `run_supernode` (#3353) --- src/py/flwr/client/app.py | 28 +++-- src/py/flwr/client/supernode/app.py | 184 ++++++++++++++++++++++------ 2 files changed, 164 insertions(+), 48 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index 7294600288aa..cdb7b25cbf6b 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -19,7 +19,7 @@ import time from dataclasses import dataclass from logging import DEBUG, ERROR, INFO, WARN -from typing import Callable, ContextManager, Optional, Tuple, Type, Union +from typing import Callable, ContextManager, Dict, Optional, Tuple, Type, Union from cryptography.hazmat.primitives.asymmetric import ec from grpc import RpcError @@ -177,7 +177,7 @@ class `flwr.client.Client` (default: None) def _start_client_internal( *, server_address: str, - load_client_app_fn: Optional[Callable[[], ClientApp]] = None, + load_client_app_fn: Optional[Callable[[str, str], ClientApp]] = None, client_fn: Optional[ClientFn] = None, client: Optional[Client] = None, grpc_max_message_length: int = GRPC_MAX_MESSAGE_LENGTH, @@ -252,7 +252,7 @@ def single_client_factory( client_fn = single_client_factory - def _load_client_app() -> ClientApp: + def _load_client_app(_1: str, _2: str) -> ClientApp: return ClientApp(client_fn=client_fn) load_client_app_fn = _load_client_app @@ -308,6 +308,8 @@ def _on_backoff(retry_state: RetryState) -> None: ) node_state = NodeState() + # run_id -> (fab_id, fab_version) + run_info: Dict[int, Tuple[str, str]] = {} while not app_state_tracker.interrupt: sleep_duration: int = 0 @@ -319,7 +321,6 @@ def _on_backoff(retry_state: RetryState) -> None: root_certificates, authentication_keys, ) as conn: - # pylint: disable-next=W0612 receive, send, create_node, delete_node, get_run = conn # Register node @@ -356,13 +357,20 @@ def _on_backoff(retry_state: RetryState) -> None: send(out_message) break + # Get run info + run_id = message.metadata.run_id + if run_id not in run_info: + if get_run is not None: + run_info[run_id] = get_run(run_id) + # If get_run is None, i.e., in grpc-bidi mode + else: + run_info[run_id] = ("", "") + # Register context for this run - node_state.register_context(run_id=message.metadata.run_id) + node_state.register_context(run_id=run_id) # Retrieve context for this run - context = node_state.retrieve_context( - run_id=message.metadata.run_id - ) + context = node_state.retrieve_context(run_id=run_id) # Create an error reply message that will never be used to prevent # the used-before-assignment linting error @@ -373,7 +381,7 @@ def _on_backoff(retry_state: RetryState) -> None: # Handle app loading and task message try: # Load ClientApp instance - client_app: ClientApp = load_client_app_fn() + client_app: ClientApp = load_client_app_fn(*run_info[run_id]) # Execute ClientApp reply_message = client_app(message=message, context=context) @@ -411,7 +419,7 @@ def _on_backoff(retry_state: RetryState) -> None: else: # No exception, update node state node_state.update_context( - run_id=message.metadata.run_id, + run_id=run_id, context=context, ) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 336cd818d718..9ec9695fb51e 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -15,11 +15,13 @@ """Flower SuperNode.""" import argparse +import os import sys from logging import DEBUG, INFO, WARN from pathlib import Path from typing import Callable, Optional, Tuple +import tomli from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import ( @@ -27,6 +29,7 @@ load_ssh_public_key, ) +from flwr.cli.config_utils import validate_fields from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import EventType, event from flwr.common.exit_handlers import register_exit_handlers @@ -44,11 +47,23 @@ def run_supernode() -> None: event(EventType.RUN_SUPERNODE_ENTER) - _ = _parse_args_run_supernode().parse_args() + args = _parse_args_run_supernode().parse_args() - log( - DEBUG, - "Flower SuperNode starting...", + _warn_deprecated_server_arg(args) + + root_certificates = _get_certificates(args) + load_fn = _get_load_client_app_fn(args, multi_app=True) + authentication_keys = _try_setup_client_authentication(args) + + _start_client_internal( + server_address=args.server, + load_client_app_fn=load_fn, + transport="rest" if args.rest else "grpc-rere", + root_certificates=root_certificates, + insecure=args.insecure, + authentication_keys=authentication_keys, + max_retries=args.max_retries, + max_wait_time=args.max_wait_time, ) # Graceful shutdown @@ -65,6 +80,27 @@ def run_client_app() -> None: args = _parse_args_run_client_app().parse_args() + _warn_deprecated_server_arg(args) + + root_certificates = _get_certificates(args) + load_fn = _get_load_client_app_fn(args, multi_app=False) + authentication_keys = _try_setup_client_authentication(args) + + _start_client_internal( + server_address=args.superlink, + load_client_app_fn=load_fn, + transport="rest" if args.rest else "grpc-rere", + root_certificates=root_certificates, + insecure=args.insecure, + authentication_keys=authentication_keys, + max_retries=args.max_retries, + max_wait_time=args.max_wait_time, + ) + register_exit_handlers(event_type=EventType.RUN_CLIENT_APP_LEAVE) + + +def _warn_deprecated_server_arg(args: argparse.Namespace) -> None: + """Warn about the deprecated argument `--server`.""" if args.server != ADDRESS_FLEET_API_GRPC_RERE: warn = "Passing flag --server is deprecated. Use --superlink instead." warn_deprecated_feature(warn) @@ -82,27 +118,6 @@ def run_client_app() -> None: else: args.superlink = args.server - root_certificates = _get_certificates(args) - log( - DEBUG, - "Flower will load ClientApp `%s`", - getattr(args, "client-app"), - ) - load_fn = _get_load_client_app_fn(args) - authentication_keys = _try_setup_client_authentication(args) - - _start_client_internal( - server_address=args.superlink, - load_client_app_fn=load_fn, - transport="rest" if args.rest else "grpc-rere", - root_certificates=root_certificates, - insecure=args.insecure, - authentication_keys=authentication_keys, - max_retries=args.max_retries, - max_wait_time=args.max_wait_time, - ) - register_exit_handlers(event_type=EventType.RUN_CLIENT_APP_LEAVE) - def _get_certificates(args: argparse.Namespace) -> Optional[bytes]: """Load certificates if specified in args.""" @@ -140,24 +155,117 @@ def _get_certificates(args: argparse.Namespace) -> Optional[bytes]: def _get_load_client_app_fn( - args: argparse.Namespace, -) -> Callable[[], ClientApp]: - """Get the load_client_app_fn function.""" - client_app_dir = args.dir - if client_app_dir is not None: - sys.path.insert(0, client_app_dir) + args: argparse.Namespace, multi_app: bool +) -> Callable[[str, str], ClientApp]: + """Get the load_client_app_fn function. + + If `multi_app` is True, this function loads the specified ClientApp + based on `fab_id` and `fab_version`. If `fab_id` is empty, a default + ClientApp will be loaded. + + If `multi_app` is False, it ignores `fab_id` and `fab_version` and + loads a default ClientApp. + """ + # Find the Flower directory containing Flower Apps (only for multi-app) + flwr_dir = Path("") + if "flwr_dir" in args: + if args.flwr_dir is None: + flwr_dir = Path( + os.getenv( + "FLWR_HOME", + f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", + ) + ) + else: + flwr_dir = Path(args.flwr_dir) + + sys.path.insert(0, str(flwr_dir)) - app_ref: str = getattr(args, "client-app") - valid, error_msg = validate(app_ref) - if not valid and error_msg: - raise LoadClientAppError(error_msg) from None + default_app_ref: str = getattr(args, "client-app") - def _load() -> ClientApp: - client_app = load_app(app_ref, LoadClientAppError) + if not multi_app: + log( + DEBUG, + "Flower SuperNode will load and validate ClientApp `%s`", + getattr(args, "client-app"), + ) + valid, error_msg = validate(default_app_ref) + if not valid and error_msg: + raise LoadClientAppError(error_msg) from None + + def _load(fab_id: str, fab_version: str) -> ClientApp: + # If multi-app feature is disabled + if not multi_app: + # Set sys.path + sys.path[0] = args.dir + + # Set app reference + client_app_ref = default_app_ref + # If multi-app feature is enabled but the fab id is not specified + elif fab_id == "": + if default_app_ref == "": + raise LoadClientAppError( + "Invalid FAB ID: The FAB ID is empty.", + ) from None + + log(WARN, "FAB ID is not provided; the default ClientApp will be loaded.") + # Set sys.path + sys.path[0] = args.dir + + # Set app reference + client_app_ref = default_app_ref + # If multi-app feature is enabled + else: + # Check the fab_id + if fab_id.count("/") != 1: + raise LoadClientAppError( + f"Invalid FAB ID: {fab_id}", + ) from None + username, project_name = fab_id.split("/") + + # Locate the directory + project_dir = flwr_dir / "apps" / username / project_name / fab_version + + # Check if the directory exists + if not project_dir.exists(): + raise LoadClientAppError( + f"Invalid Flower App directory: {project_dir}", + ) from None + + # Load pyproject.toml file + toml_path = project_dir / "pyproject.toml" + if not os.path.isfile(toml_path): + raise LoadClientAppError( + f"Cannot find pyproject.toml in {project_dir}", + ) from None + with open(toml_path, encoding="utf-8") as toml_file: + config = tomli.loads(toml_file.read()) + + # Validate pyproject.toml fields + is_valid, errors, _ = validate_fields(config) + if not is_valid: + error_msg = "\n".join([f" - {error}" for error in errors]) + raise LoadClientAppError( + f"Invalid pyproject.toml:\n{error_msg}", + ) from None + + # Set sys.path + sys.path[0] = str(project_dir) + + # Set app reference + client_app_ref = config["flower"]["components"]["clientapp"] + + # Load ClientApp + log( + DEBUG, + "Loading ClientApp `%s`", + client_app_ref, + ) + client_app = load_app(client_app_ref, LoadClientAppError) if not isinstance(client_app, ClientApp): raise LoadClientAppError( - f"Attribute {app_ref} is not of type {ClientApp}", + f"Attribute {client_app_ref} is not of type {ClientApp}", ) from None return client_app From 18658f52d3a3504286f4f06b12fa8a3d94bd26d4 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Thu, 13 Jun 2024 18:12:39 +0200 Subject: [PATCH 063/124] docs(framework) Add latest Hosted Weblate translation updates (#3586) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Yan Gao Co-authored-by: 박태현 --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 113 +- .../zh_Hans/LC_MESSAGES/framework-docs.po | 1168 ++++++++++++++--- 2 files changed, 1059 insertions(+), 222 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 68440f928f08..2d106db01fd5 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-28 11:47+0200\n" -"PO-Revision-Date: 2024-06-11 06:22+0000\n" +"PO-Revision-Date: 2024-06-13 16:07+0000\n" "Last-Translator: 박태현 \n" "Language-Team: Korean \n" @@ -621,16 +621,20 @@ msgid "" "means that you can seamlessly switch your entire development environment " "just by connecting to a different container." msgstr "" +"작업 공간 파일은 로컬 파일 시스템에서 마운트되거나 컨테이너에 복사 또는 " +"클론됩니다. 확장 프로그램은 컨테이너 내부에 설치되고 실행되며, 도구, 플랫폼 " +"및 파일 시스템에 완전한 접근 권한을 갖습니다. 이는 다른 컨테이너에 연결하는 " +"것만으로 전체 개발 환경을 원활하게 전환할 수 있음을 의미합니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 msgid "" "Source: `Official VSCode documentation `_" -msgstr "" +msgstr "출처 : 공식 VSCode 문서" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 msgid "Getting started" -msgstr "" +msgstr "시작하기" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 msgid "" @@ -641,6 +645,12 @@ msgid "" "your command line. Additionally, install the `VSCode Containers Extension " "`_." msgstr "" +"`Dockerfile`을 설정하고 구성하는 것과 개발 컨테이너 구성은 약간 복잡할 수 " +"있습니다. 다행히도, 이를 직접 할 필요는 없습니다. 일반적으로 시스템에 `" +"Docker `_를 설치하고 커맨드 " +"라인에서 사용할 수 있는지 확인하는 것으로 충분합니다. 추가로 `VSCode " +"Containers Extension `" +"_을 설치하세요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" @@ -651,36 +661,46 @@ msgid "" "left corner of your VSCode window and select the option *(Re)Open Folder in " "Container*." msgstr "" +"이제 준비가 완료되었습니다. VSCode를 시작하면 컨테이너 환경에서 실행할지를 " +"묻고, 확인하면 자동으로 컨테이너를 빌드하고 사용할 것입니다. VSCode에 " +"수동으로 개발 컨테이너를 사용하도록 지시하려면, 확장을 설치한 후, VSCode " +"창의 왼쪽 하단에 있는 초록색 부을 클릭하고 *(Re)Open Folder in Container* " +"옵션을 선택하세요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" "In some cases your setup might be more involved. For those cases consult the " "following sources:" -msgstr "" +msgstr "경우에 따라 설정이 더 복잡할 수도 있습니다. 이러한 경우에는 다음 소스를 " +"참조하세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 msgid "" "`Developing inside a Container `_" msgstr "" +"`컨테이너 내부 개발`_" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 msgid "" "`Remote development in Containers `_" msgstr "" +"`컨테이너 원격 개발`_" #: ../../source/contributor-how-to-install-development-versions.rst:2 msgid "Install development versions" -msgstr "" +msgstr "개발 버전 설치하기" #: ../../source/contributor-how-to-install-development-versions.rst:5 msgid "Install development versions of Flower" -msgstr "" +msgstr "Flower 개발 버전 설치하기" #: ../../source/contributor-how-to-install-development-versions.rst:8 msgid "Using Poetry (recommended)" -msgstr "" +msgstr "Poetry 사용하기(권장)" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" @@ -688,50 +708,62 @@ msgid "" "``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." "lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" +"PyPI에서 ``flwr`` 사전 릴리스 설치하기: ``pyproject.toml``에서 ``flwr``의 " +"dependency를 업데이트한 다음, 재설치하세요(``poetry 설치``이전에 ``poetry." +"lock`` (``rm poetry.lock``)를 제거하는 것을 잊지 마세요)." #: ../../source/contributor-how-to-install-development-versions.rst:12 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (without " "extras)" msgstr "" +"``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:13 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true, extras = " "[\"simulation\"] }`` (with extras)" msgstr "" +"``flwr = { version = \"1.0.0a0\", allow-prereleases = true, extras = [" +"\"simulation\"] }`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" "Install ``flwr`` from a local copy of the Flower source code via ``pyproject." "toml``:" -msgstr "" +msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 설치:" #: ../../source/contributor-how-to-install-development-versions.rst:17 msgid "``flwr = { path = \"../../\", develop = true }`` (without extras)" -msgstr "" +msgstr "``flwr = { path = \"../../\", develop = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" "``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " "(with extras)" msgstr "" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` (" +"extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:20 msgid "Install ``flwr`` from a local wheel file via ``pyproject.toml``:" -msgstr "" +msgstr "``pyproject.toml``을 통해 로컬 wheel file에서 ``flwr``을 설치하세요:" #: ../../source/contributor-how-to-install-development-versions.rst:22 msgid "" "``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " "extras)" msgstr "" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (extras " +"제외)" #: ../../source/contributor-how-to-install-development-versions.rst:23 msgid "" "``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\", extras = " "[\"simulation\"] }`` (with extras)" msgstr "" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\", extras = [" +"\"simulation\"] }`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:25 msgid "" @@ -739,101 +771,120 @@ msgid "" "Dependency Specification `_" msgstr "" +"자세한 내용은 Poetry 문서를 참고하세요: `Poetry Dependency Specification " +"`_" #: ../../source/contributor-how-to-install-development-versions.rst:28 msgid "Using pip (recommended on Colab)" -msgstr "" +msgstr "pip 사용하기(Colab에서 권장)" #: ../../source/contributor-how-to-install-development-versions.rst:30 msgid "Install a ``flwr`` pre-release from PyPI:" -msgstr "" +msgstr "PyPI에서 ``flwr`` 사전 릴리스를 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:32 msgid "``pip install -U --pre flwr`` (without extras)" -msgstr "" +msgstr "``pip install -U --pre flwr`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:33 msgid "``pip install -U --pre flwr[simulation]`` (with extras)" -msgstr "" +msgstr "``pip install -U --pre flwr[simulation]`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:35 msgid "" "Python packages can be installed from git repositories. Use one of the " "following commands to install the Flower directly from GitHub." msgstr "" +"Python 패키지는 git 저장소에서 설치할 수 있습니다. 다음 명령어 중 하나를 " +"사용하여 GitHub에서 직접 Flower를 설치하세요." #: ../../source/contributor-how-to-install-development-versions.rst:37 msgid "Install ``flwr`` from the default GitHub branch (``main``):" -msgstr "" +msgstr "기본 GitHub branch (``main``)에서 ``flwr`` 를 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" "``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" -msgstr "" +msgstr "``pip install flwr@git+https://github.com/adap/flower.git`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:40 msgid "" "``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` " "(with extras)" msgstr "" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` (" +"extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:42 msgid "Install ``flwr`` from a specific GitHub branch (``branch-name``):" -msgstr "" +msgstr "특정 GitHub branch (``branch-name``)에서 ``flwr``설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:44 msgid "" "``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " "(without extras)" msgstr "" +"``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` (" +"extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" "``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" "name`` (with extras)" msgstr "" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" +"name`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:49 msgid "Open Jupyter Notebooks on Google Colab" -msgstr "" +msgstr "Google Colab에서 Jupyter Notebooks 열기" #: ../../source/contributor-how-to-install-development-versions.rst:51 msgid "" "Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" "pytorch.ipynb``:" msgstr "" +"``doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb``" +"notebook을 엽니다:" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" "https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" "tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" "Open a development version of the same notebook from branch `branch-name` by " "changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" +"``main``을 ``branch-name``(``blob`` 바로 뒤)으로 변경하여 동일한 notebook의 " +"개발 버전을 브랜치 `branch-name`에서 엽니다 :" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" "https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" "source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:59 msgid "Install a `whl` on Google Colab:" -msgstr "" +msgstr "Google Colab에서 `whl` 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" "In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " "to session storage``" -msgstr "" +msgstr "왼쪽의 수직 아이콘 그리드에서 ``Files`` > ``Upload to session storage``를 " +"선택하세요" #: ../../source/contributor-how-to-install-development-versions.rst:62 msgid "Upload the whl (e.g., ``flwr-1.8.0-py3-none-any.whl``)" -msgstr "" +msgstr "whl (예:``flwr-1.8.0-py3-none-any.whl``)을 업로드하세요" #: ../../source/contributor-how-to-install-development-versions.rst:63 msgid "" @@ -841,26 +892,31 @@ msgid "" "to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " "torchvision matplotlib``" msgstr "" +"``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``를 ``!pip " +"install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch torchvision " +"matplotlib``로 바꾸세요" #: ../../source/contributor-how-to-release-flower.rst:2 msgid "Release Flower" -msgstr "" +msgstr "Flower 릴리즈 하기" #: ../../source/contributor-how-to-release-flower.rst:4 msgid "" "This document describes the current release process. It may or may not " "change in the future." -msgstr "" +msgstr "이 문서는 현재 릴리즈 과정을 설명합니다. 이는 앞으로 변경될 수도 있습니다." #: ../../source/contributor-how-to-release-flower.rst:7 msgid "During the release" -msgstr "" +msgstr "릴리즈 동안에" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" "The version number of a release is stated in ``pyproject.toml``. To release " "a new version of Flower, the following things need to happen (in that order):" msgstr "" +"릴리즈의 버전 번호는 ``pyproject.toml``에 명시되어 있습니다. Flower의 새 " +"버전을 릴리즈하려면 다음 작업이 순서대로 수행되어야 합니다:" #: ../../source/contributor-how-to-release-flower.rst:11 msgid "" @@ -868,6 +924,9 @@ msgid "" "order to add every new change to the changelog (feel free to make manual " "changes to the changelog afterwards until it looks good)." msgstr "" +"모든 새로운 변경 사항을 변경 로그에 추가하기 위해``python3 src/py/flwr_tool/" +"update_changelog.py ``을 실행합니다 (변경 로그가 만족스러워질 " +"때까지 수동으로 변경해도 됩니다)." #: ../../source/contributor-how-to-release-flower.rst:12 msgid "" @@ -878,6 +937,12 @@ msgid "" "and current date, and it will add a thanking message for the contributors. " "Open a pull request with those changes." msgstr "" +"모든 변경 사항으로 변경 로그가 업데이트되면,``./dev/prepare-release-" +"changelog.sh v``을 실행합니다. 여기서 ````은 " +"``pyproject.toml``에 명시된 버전 번호입니다 (앞에 ``v``가 추가된 것을 " +"주의하세요). 이 명령어는 변경 로그의 ``Unreleased``헤더를 해당 버전과 현재 " +"날짜로 교체하고, 기여자들에게 감사 메시지가 추가됩니다. 이러한 변경 사항으로 " +"pull request합니다." #: ../../source/contributor-how-to-release-flower.rst:13 msgid "" diff --git a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po index 47be2dfda762..7ca5b00176fb 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po @@ -8,15 +8,16 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-28 11:47+0200\n" -"PO-Revision-Date: 2024-05-10 06:59+0000\n" +"PO-Revision-Date: 2024-06-12 10:09+0000\n" "Last-Translator: Yan Gao \n" +"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" -"Language-Team: Chinese (Simplified) \n" -"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -295,8 +296,9 @@ msgid "``FLWR_PACKAGE``" msgstr "``FLWR_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:103 +#, fuzzy msgid "The PyPI package to install." -msgstr "" +msgstr "要安装的 PyPI 软件包。" #: ../../source/contributor-how-to-build-docker-images.rst:104 #, fuzzy @@ -1118,12 +1120,16 @@ msgstr "" "3.10 `_或更高版本。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 +#, fuzzy msgid "" "Due to a known incompatibility with `ray " "`_, we currently recommend utilizing at " "most `Python 3.11 `_ for running Flower " "simulations." msgstr "" +"由于已知与 `ray `_ 不兼容," +"我们目前建议最多使用 `Python 3.11 `_ 运行 " +"Flower 仿真。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 #, fuzzy @@ -1738,11 +1744,14 @@ msgid "" msgstr "在这个例子中,你可以看到请求将我分叉的版本库中的分支 ``doc-fixes`` 合并到 Flower 版本库中的分支 ``main``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 +#, fuzzy msgid "" "The title should be changed to adhere to the :ref:`pr_title_format` " "guidelines, otherwise it won't be possible to merge the PR. So in this " "case, a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" +"应该修改标题以符合 :ref:`pr_title_format` 准则,否则将无法合并 " +"PR。因此,在这种情况下,正确的标题可能是 ``docs(framework:skip)修复错字``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" @@ -1753,8 +1762,9 @@ msgid "" msgstr "中间的输入框供您描述 PR 的作用,并将其与现有问题联系起来。我们在此放置了注释(一旦 PR 打开,注释将不会显示),以指导您完成整个过程。" #: ../../source/contributor-tutorial-contribute-on-github.rst:199 +#, fuzzy msgid "It is important to follow the instructions described in comments." -msgstr "" +msgstr "请务必遵守注释中的说明。" #: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" @@ -1989,10 +1999,12 @@ msgid "Push the changes to your fork" msgstr "将更改推送到分叉" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 +#, fuzzy msgid "" "Open a PR (as shown above) with title ``docs(framework) Update how-to " "guide title``" -msgstr "" +msgstr "打开一个 PR(如上图所示),标题为\"`docs(framework) Update how-to guide " +"title```\"。" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" @@ -2033,20 +2045,24 @@ msgid "Appendix" msgstr "附录" #: ../../source/contributor-tutorial-contribute-on-github.rst:327 +#, fuzzy msgid "PR title format" -msgstr "" +msgstr "PR 标题格式" #: ../../source/contributor-tutorial-contribute-on-github.rst:329 +#, fuzzy msgid "We enforce the following PR title format:" -msgstr "" +msgstr "我们执行以下 PR 标题格式:" #: ../../source/contributor-tutorial-contribute-on-github.rst:335 +#, fuzzy msgid "" "(or ``(:skip) `` to ignore the PR in the " "changelog)" -msgstr "" +msgstr "(或 ``(:skip) `` 忽略更新日志中的 PR)。" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 +#, fuzzy msgid "" "Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " "break}``, ```` should be in ``{framework, baselines, datasets, " @@ -2054,6 +2070,10 @@ msgid "" "':skip' flag to be used}``, and ```` starts with a capitalised " "verb in the imperative mood." msgstr "" +"其中 ```` 需要使用 ``{ci, fix, feat, docs, refactor, break}``, " +"```` 应该使用 ``{framework, baselines, datasets, examples, 或者 '*' " +"当修改多个项目时需要使用 ':skip'标记}``, 并且 ```` " +"应该以一个大写的动词开始。" #: ../../source/contributor-tutorial-contribute-on-github.rst:341 #, fuzzy @@ -2061,16 +2081,19 @@ msgid "Valid examples:" msgstr "实例" #: ../../source/contributor-tutorial-contribute-on-github.rst:343 +#, fuzzy msgid "``feat(framework) Add flwr build CLI command``" -msgstr "" +msgstr "`feat(框架) 添加 flwr build CLI 命令```" #: ../../source/contributor-tutorial-contribute-on-github.rst:344 +#, fuzzy msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" -msgstr "" +msgstr "``refactor(examples:skip) Improve quickstart-pytorch logging``." #: ../../source/contributor-tutorial-contribute-on-github.rst:345 +#, fuzzy msgid "``ci(*:skip) Enforce PR title format``" -msgstr "" +msgstr "`ci(*:skip)执行 PR 标题格式``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:347 #, fuzzy @@ -2078,30 +2101,38 @@ msgid "Invalid examples:" msgstr "模拟示例" #: ../../source/contributor-tutorial-contribute-on-github.rst:349 +#, fuzzy msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" -msgstr "" +msgstr "`feat(框架): 添加 flwr build CLI 命令``(额外的``:``)" #: ../../source/contributor-tutorial-contribute-on-github.rst:350 +#, fuzzy msgid "" "``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " "``*``)" -msgstr "" +msgstr "`feat(*)添加flwr构建CLI命令``(缺少``skip``标志和``*``)。" #: ../../source/contributor-tutorial-contribute-on-github.rst:351 +#, fuzzy msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" -msgstr "" +msgstr "`feat(skip)添加flwr构建CLI命令``(缺少```)。" #: ../../source/contributor-tutorial-contribute-on-github.rst:352 +#, fuzzy msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" -msgstr "" +msgstr "`feat(framework)添加 flwr 构建 CLI 命令``(非大写动词)" #: ../../source/contributor-tutorial-contribute-on-github.rst:353 +#, fuzzy msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" -msgstr "" +msgstr "feat(框架) 添加 flwr 构建 CLI 命令。" #: ../../source/contributor-tutorial-contribute-on-github.rst:354 +#, fuzzy msgid "``Add flwr build CLI command.`` (missing ``()``)" msgstr "" +"``添加 flwr build CLI 命令.``(缺少``()``) ``Add flwr build " +"CLI command.`` (missing ``()``)" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 msgid "Get started as a contributor" @@ -2264,49 +2295,62 @@ msgid "Run Linters and Tests" msgstr "运行分类器和测试" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:106 +#, fuzzy msgid "Add a pre-commit hook" -msgstr "" +msgstr "添加预先提交钩子" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 +#, fuzzy msgid "" "Developers may integrate a pre-commit hook into their workflow utilizing " "the `pre-commit `_ library. The pre-" "commit hook is configured to execute two primary operations: " "``./dev/format.sh`` and ``./dev/test.sh`` scripts." msgstr "" +"开发人员可利用 `pre-commit `_ " +"库将预提交钩子集成到工作流程中。预提交钩子被配置为执行两个主要操作: `./dev/" +"format.sh`` 和 ``./dev/test.sh`` 脚本。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 +#, fuzzy msgid "There are multiple ways developers can use this:" -msgstr "" +msgstr "开发人员可以通过多种方式使用它:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 +#, fuzzy msgid "Install the pre-commit hook to your local git directory by simply running:" -msgstr "" +msgstr "在本地 git 目录中安装预提交钩子,只需运行" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 +#, fuzzy msgid "" "Each ``git commit`` will trigger the execution of formatting and " "linting/test scripts." -msgstr "" +msgstr "每次 \"git 提交 \"都会触发格式化和内核/测试脚本的执行。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 +#, fuzzy msgid "" "If in a hurry, bypass the hook using ``--no-verify`` with the ``git " "commit`` command. ::" -msgstr "" +msgstr "如果赶时间,可使用 ``--no-verify`` 和 ``git commit` 命令绕过钩子:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 +#, fuzzy msgid "" "For developers who prefer not to install the hook permanently, it is " "possible to execute a one-time check prior to committing changes by using" " the following command:" -msgstr "" +msgstr "对于不想永久安装钩子的开发人员,可以使用以下命令在提交更改之前执行一次性检查" +":" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 +#, fuzzy msgid "" "This executes the formatting and linting checks/tests on all the files " "without modifying the default behavior of ``git commit``." -msgstr "" +msgstr "这将在不修改 ``git commit`` " +"默认行为的情况下对所有文件执行格式化和词排检查/测试。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 msgid "Run Github Actions (CI) locally" @@ -4068,36 +4112,45 @@ msgid "" msgstr "然后,服务器可以使用定制的策略来汇总这些字典中提供的指标:" #: ../../source/how-to-authenticate-supernodes.rst:2 +#, fuzzy msgid "Authenticate SuperNodes" -msgstr "" +msgstr "验证超级节点" #: ../../source/how-to-authenticate-supernodes.rst:4 +#, fuzzy msgid "" "Flower has built-in support for authenticated SuperNodes that you can use" " to verify the identities of each SuperNode connecting to a SuperLink. " "Flower node authentication works similar to how GitHub SSH authentication" " works:" msgstr "" +"Flower 内置了对经过身份验证的超级节点的支持,您可以用它来验证连接到超级链接的" +"每个超级节点的身份。Flower 节点身份验证的工作方式与 GitHub SSH " +"身份验证的工作方式类似:" #: ../../source/how-to-authenticate-supernodes.rst:7 +#, fuzzy msgid "SuperLink (server) stores a list of known (client) node public keys" -msgstr "" +msgstr "超级链接(服务器)存储已知(客户端)节点公钥列表" #: ../../source/how-to-authenticate-supernodes.rst:8 +#, fuzzy msgid "" "Using ECDH, both SuperNode and SuperLink independently derive a shared " "secret" -msgstr "" +msgstr "使用 ECDH,超级节点和超级链路可独立生成共享秘密" #: ../../source/how-to-authenticate-supernodes.rst:9 +#, fuzzy msgid "" "Shared secret is used to compute the HMAC value of the message sent from " "SuperNode to SuperLink as a token" -msgstr "" +msgstr "共享秘密用于计算作为令牌从超级节点发送到超级链接的信息的 HMAC 值" #: ../../source/how-to-authenticate-supernodes.rst:10 +#, fuzzy msgid "SuperLink verifies the token" -msgstr "" +msgstr "超级链接验证令牌" #: ../../source/how-to-authenticate-supernodes.rst:12 #, fuzzy @@ -4111,22 +4164,26 @@ msgstr "" "`_了解更多信息。" #: ../../source/how-to-authenticate-supernodes.rst:15 +#, fuzzy msgid "" "This guide covers a preview feature that might change in future versions " "of Flower." -msgstr "" +msgstr "本指南涵盖的预览功能可能会在 Flower 的未来版本中有所改变。" #: ../../source/how-to-authenticate-supernodes.rst:18 +#, fuzzy msgid "" "For increased security, node authentication can only be used when " "encrypted connections (SSL/TLS) are enabled." -msgstr "" +msgstr "为提高安全性,只有启用加密连接(SSL/TLS)时才能使用节点验证。" #: ../../source/how-to-authenticate-supernodes.rst:21 +#, fuzzy msgid "Enable node authentication in :code:`SuperLink`" -msgstr "" +msgstr "在 :code:`SuperLink` 中启用节点验证" #: ../../source/how-to-authenticate-supernodes.rst:23 +#, fuzzy msgid "" "To enable node authentication, first you need to configure SSL/TLS " "connections to secure the SuperLink<>SuperNode communication. You can " @@ -4137,36 +4194,56 @@ msgid "" ":code:`SuperNode` that has both secure connections and node " "authentication enabled:" msgstr "" +"要启用节点验证,首先需要配置 SSL/TLS 连接,以确保 SuperLink<>SuperNode " +"通信的安全。您可以在 `_ 找到完整的指南。配置安全连接后,您就可以在长期运行的 " +"Flower :code:`SuperLink`中启用客户端身份验证。" +"使用以下终端命令启动一个同时启用了安全连接和节点验证的 Flower " +":code:`SuperNode`:" #: ../../source/how-to-authenticate-supernodes.rst:36 +#, fuzzy msgid "Let's break down the authentication flags:" -msgstr "" +msgstr "让我们来分析一下身份验证标志:" #: ../../source/how-to-authenticate-supernodes.rst:38 +#, fuzzy msgid "" "The first flag :code:`--auth-list-public-keys` expects a path to a CSV " "file storing all known node public keys. You need to store all known node" " public keys that are allowed to participate in a federation in one CSV " "file (:code:`.csv`)." msgstr "" +"第一个标志 :code:`--auth-list-public-keys`(密码:`--auth-list-public-keys`)" +"需要一个 CSV 文件路径,该文件存储了所有已知节点的公钥。您需要在一个 CSV " +"文件(:code:`.csv`)中存储所有允许参与联盟的已知节点公钥。" #: ../../source/how-to-authenticate-supernodes.rst:40 +#, fuzzy msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " "example, refer to our code sample, which contains a CSV file with two " "known node public keys." msgstr "" +"存储已知节点公开密钥的有效 CSV 文件应以 OpenSSH " +"格式列出密钥,以逗号分隔,不含任何注释。有关示例,请参阅我们的代码示例," +"其中包含一个包含两个已知节点公钥的 CSV 文件。" #: ../../source/how-to-authenticate-supernodes.rst:42 +#, fuzzy msgid "" "The second and third flags :code:`--auth-superlink-private-key` and :code" ":`--auth-superlink-public-key` expect paths to the server's private and " "public keys. For development purposes, you can generate a private and " "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" +"第二和第三个标记 :code:`--auth-superlink-private-key` 和 :code:`--auth-" +"superlink-public-key` 希望指向服务器私钥和公钥的路径。出于开发目的," +"您可以使用 :code:`ssh-keygen -t ecdsa -b 384` 生成一对私钥和公钥。" #: ../../source/how-to-authenticate-supernodes.rst:45 +#, fuzzy msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " "adding known node public keys to the SuperLink. To change the set of " @@ -4174,20 +4251,29 @@ msgid "" "start the server again. Support for dynamically changing the set of known" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" +"在 Flower 1.9 中,超级链接不支持动态删除、编辑或添加已知节点公钥。要更改已知" +"节点集,您需要关闭服务器,编辑 CSV 文件,然后重新启动服务器。" +"动态更改已知节点集的支持已列入 Flower 1.10(预计发布时间:6 月)的路线图。" #: ../../source/how-to-authenticate-supernodes.rst:51 +#, fuzzy msgid "Enable node authentication in :code:`SuperNode`" -msgstr "" +msgstr "在 :code:`SuperNode` 中启用节点验证" #: ../../source/how-to-authenticate-supernodes.rst:53 +#, fuzzy msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " "easily enable node authentication in the long-running Flower client " "(:code:`SuperNode`). Use the following terminal command to start an " "authenticated :code:`SuperNode`:" msgstr "" +"与长期运行的 Flower 服务器(:code:`SuperLink`)类似,您也可以在长期运行的 " +"Flower 客户端(:code:`SuperNode`)中轻松启用节点身份验证。" +"使用以下终端命令启动已验证的 :code:`SuperNode`:" #: ../../source/how-to-authenticate-supernodes.rst:64 +#, fuzzy msgid "" "The :code:`--auth-supernode-private-key` flag expects a path to the " "node's private key file and the :code:`--auth-supernode-public-key` flag " @@ -4195,12 +4281,17 @@ msgid "" "you can generate a private and public key pair using :code:`ssh-keygen -t" " ecdsa -b 384`." msgstr "" +":code:`--auth-supernode-private-key`标志需要节点私钥文件的路径,:code:`-auth-" +"supernode-public-key`标志需要节点公钥文件的路径。出于开发目的,可以使用 :code" +":`ssh-keygen -t ecdsa -b 384` 生成一对私钥和公钥。" #: ../../source/how-to-authenticate-supernodes.rst:68 +#, fuzzy msgid "Security notice" -msgstr "" +msgstr "安全通知" #: ../../source/how-to-authenticate-supernodes.rst:70 +#, fuzzy msgid "" "The system's security relies on the credentials of the SuperLink and each" " SuperNode. Therefore, it is imperative to safeguard and safely store the" @@ -4210,6 +4301,9 @@ msgid "" "communication is done in a secure manner, using trusted communication " "methods." msgstr "" +"系统的安全性依赖于超级链接和每个超级节点的凭证。因此,必须保护和安全存储凭证" +",以避免公钥基础设施 (PKI) 假冒攻击等安全风险。节点验证机制还涉及人机交互,因" +"此请确保使用可信的通信方法,以安全的方式进行所有通信。" #: ../../source/how-to-authenticate-supernodes.rst:75 #: ../../source/how-to-enable-ssl-connections.rst:65 @@ -4219,12 +4313,16 @@ msgid "Conclusion" msgstr "总结" #: ../../source/how-to-authenticate-supernodes.rst:77 +#, fuzzy msgid "" "You should now have learned how to start a long-running Flower server " "(:code:`SuperLink`) and client (:code:`SuperNode`) with node " "authentication enabled. You should also know the significance of the " "private key and store it safely to minimize security risks." msgstr "" +"现在,您应该已经学会了如何启动长期运行的 Flower 服务器(:code:`SuperLink`)和" +"客户端(:code:`SuperNode`)并启用节点身份验证。您还应该知道私钥的重要性,并将" +"其安全存储,以尽量减少安全风险。" #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" @@ -5312,12 +5410,16 @@ msgstr "" "`安装后步骤 `_进行操作。" #: ../../source/how-to-run-flower-using-docker.rst:26 +#, fuzzy msgid "" "To ensure optimal performance and compatibility, the SuperLink, SuperNode" " and ServerApp image must have the same version when running together. " "This guarantees seamless integration and avoids potential conflicts or " "issues that may arise from using different versions." msgstr "" +"为确保最佳性能和兼容性,SuperLink、SuperNode 和 ServerApp 映像在一起运行时必" +"须具有相同的版本。这可确保无缝集成,并避免因使用不同版本而可能产生的潜在冲突" +"或问题。" #: ../../source/how-to-run-flower-using-docker.rst:31 #, fuzzy @@ -5467,12 +5569,14 @@ msgid "Flower SuperNode" msgstr "Flower 服务器" #: ../../source/how-to-run-flower-using-docker.rst:115 +#, fuzzy msgid "" "The SuperNode Docker image comes with a pre-installed version of Flower " "and serves as a base for building your own SuperNode image." -msgstr "" +msgstr "超级节点 Docker 镜像预装了 Flower 版本,可作为构建自己的超级节点镜像的基础。" #: ../../source/how-to-run-flower-using-docker.rst:120 +#, fuzzy msgid "" "The SuperNode Docker image currently works only with the 1.9.0-nightly " "release. A stable version will be available when Flower 1.9.0 (stable) " @@ -5481,12 +5585,19 @@ msgid "" "same day. To ensure the versions are in sync, using the concrete tag, " "e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" +"超级节点 Docker 映像目前仅适用于 1.9.0-nightly 版本。稳定版将在 Flower 1.9." +"0(稳定版)发布时推出(预计发布时间:5 月)。超级节点夜间镜像必须与同一天发布" +"的相应超级链接和服务器应用程序夜间镜像配对。为确保版本同步,建议使用具体标签" +",例如``1.9.0.dev20240501``,而不是``nightly``。" #: ../../source/how-to-run-flower-using-docker.rst:126 +#, fuzzy msgid "" "We will use the ``quickstart-pytorch`` example, which you can find in the" " Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" +"我们将使用 \"quickstart-pytorch\"(快速启动-pytorch)示例来说明如何对 " +"ClientApp 进行 docker 化。" #: ../../source/how-to-run-flower-using-docker.rst:134 #, fuzzy @@ -5502,43 +5613,58 @@ msgid "Clone the Flower repository." msgstr "**叉花仓库**" #: ../../source/how-to-run-flower-using-docker.rst:152 +#, fuzzy msgid "Creating a SuperNode Dockerfile" -msgstr "" +msgstr "创建超级节点 Dockerfile" #: ../../source/how-to-run-flower-using-docker.rst:154 #: ../../source/how-to-run-flower-using-docker.rst:289 +#, fuzzy msgid "Let's assume the following project layout:" -msgstr "" +msgstr "假设项目布局如下" #: ../../source/how-to-run-flower-using-docker.rst:163 +#, fuzzy msgid "" "First, we need to create a ``requirements.txt`` file in the directory " "where the ``ClientApp`` code is located. In the file, we list all the " "dependencies that the ClientApp requires." msgstr "" +"首先,我们需要在 ``ClientApp`` 代码所在的目录中创建一个 ``requirements.txt`` " +"文件。在该文件中,我们列出了 ClientApp 需要的所有依赖项。" #: ../../source/how-to-run-flower-using-docker.rst:175 +#, fuzzy msgid "" "Note that `flwr `__ is already installed " "in the ``flwr/supernode`` base image, so you only need to include other " "package dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" +"请注意,`flwr `__ 已经安装在`flwr/" +"supernode``基础镜像中,因此只需在`requirements." +"txt``中包含其他依赖包,如`torch``、`tensorflow`等。" #: ../../source/how-to-run-flower-using-docker.rst:179 +#, fuzzy msgid "" "Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " "example, create a new file called ``Dockerfile.supernode`` in ``examples" "/quickstart-pytorch``." msgstr "" +"接下来,我们创建一个 Dockerfile。如果使用 ``quickstart-pytorch`` 示例,请在 " +"``examples/quickstart-pytorch`` 中创建一个名为 ``Dockerfile.supernode`` " +"的新文件。" #: ../../source/how-to-run-flower-using-docker.rst:182 +#, fuzzy msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." -msgstr "" +msgstr "Dockerfile.supernode \"包含组装超级节点映像的指令。" #: ../../source/how-to-run-flower-using-docker.rst:196 +#, fuzzy msgid "" "In the first two lines, we instruct Docker to use the SuperNode image " "tagged ``nightly`` as a base image and set our working directory to " @@ -5550,6 +5676,13 @@ msgid "" "``client:app``. The argument is the object reference of the ClientApp " "(``:``) that will be run inside the ClientApp." msgstr "" +"在前两行中,我们指示 Docker 使用标记为 ``nightly`` 的 SuperNode " +"镜像作为基础镜像,并将工作目录设置为 ``/app``。下面的指令将在 ``/app`` " +"目录中执行。接下来,我们通过将 ``requirements.txt`` 文件复制到映像中并运行 ``" +"pip install`` 来安装 ClientApp 依赖项。最后两行,我们将 ``client.py`` " +"模块复制到映像中,并将入口点设置为 ``flower-client-app``,参数为 " +"``client:app``。参数是将在 ClientApp 内运行的 ClientApp " +"的对象引用(``<模块>:<属性>``)。" #: ../../source/how-to-run-flower-using-docker.rst:205 #, fuzzy @@ -5557,17 +5690,22 @@ msgid "Building the SuperNode Docker image" msgstr "启动服务器" #: ../../source/how-to-run-flower-using-docker.rst:207 +#, fuzzy msgid "" "Next, we build the SuperNode Docker image by running the following " "command in the directory where Dockerfile and ClientApp code are located." -msgstr "" +msgstr "接下来,我们在 Dockerfile 和 ClientApp 代码所在的目录下运行以下命令,构建 " +"SuperNode Docker 映像。" #: ../../source/how-to-run-flower-using-docker.rst:214 +#, fuzzy msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" +"我们将图像命名为 ``flwr_supernode``,标签为 ``0.0." +"1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" #: ../../source/how-to-run-flower-using-docker.rst:219 #, fuzzy @@ -5575,64 +5713,79 @@ msgid "Running the SuperNode Docker image" msgstr "启动服务器" #: ../../source/how-to-run-flower-using-docker.rst:221 +#, fuzzy msgid "Now that we have built the SuperNode image, we can finally run it." -msgstr "" +msgstr "现在,我们已经构建了超级节点镜像,终于可以运行它了。" #: ../../source/how-to-run-flower-using-docker.rst:229 #: ../../source/how-to-run-flower-using-docker.rst:345 +#, fuzzy msgid "Let's break down each part of this command:" -msgstr "" +msgstr "让我们来分析一下这条命令的各个部分:" #: ../../source/how-to-run-flower-using-docker.rst:231 #: ../../source/how-to-run-flower-using-docker.rst:347 +#, fuzzy msgid "``docker run``: This is the command to run a new Docker container." -msgstr "" +msgstr "`docker run``: 这是运行新 Docker 容器的命令。" #: ../../source/how-to-run-flower-using-docker.rst:232 #: ../../source/how-to-run-flower-using-docker.rst:348 +#, fuzzy msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." -msgstr "" +msgstr "`-rm``: 该选项指定容器停止时应自动移除。" #: ../../source/how-to-run-flower-using-docker.rst:233 +#, fuzzy msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." -msgstr "" +msgstr "flwr_supernode:0.0.1``: 要使用的 Docker 映像的名称和标记。" #: ../../source/how-to-run-flower-using-docker.rst:234 #: ../../source/how-to-run-flower-using-docker.rst:350 +#, fuzzy msgid "``--insecure``: This option enables insecure communication." -msgstr "" +msgstr "不安全\": 该选项启用不安全通信。" #: ../../source/how-to-run-flower-using-docker.rst +#, fuzzy msgid "" "``--server 192.168.1.100:9092``: This option specifies the address of the" " SuperLinks Fleet" -msgstr "" +msgstr "``--server 192.168.1.100:9092``: 该选项指定超级链接舰队的地址" #: ../../source/how-to-run-flower-using-docker.rst +#, fuzzy msgid "API to connect to. Remember to update it with your SuperLink IP." -msgstr "" +msgstr "要连接的 API。记住用您的超级链接 IP 更新它。" #: ../../source/how-to-run-flower-using-docker.rst:248 +#, fuzzy msgid "" "To test running Flower locally, you can create a `bridge network " "`__, use the ``--network`` argument and pass the " "name of the Docker network to run your SuperNodes." msgstr "" +"要测试在本地运行 Flower,可以创建一个 \"桥接网络 `__\"," +"使用\"--网络 \"参数并传递 Docker 网络的名称,以运行超级节点。" #: ../../source/how-to-run-flower-using-docker.rst:252 +#, fuzzy msgid "" "Any argument that comes after the tag is passed to the Flower SuperNode " "binary. To see all available flags that the SuperNode supports, run:" -msgstr "" +msgstr "标记后的任何参数都将传递给 Flower " +"超级节点二进制文件。要查看超级节点支持的所有可用标记,请运行" #: ../../source/how-to-run-flower-using-docker.rst:262 +#, fuzzy msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your SuperNode container." -msgstr "" +msgstr "要启用 SSL,我们需要将 PEM 编码的根证书挂载到 SuperNode 容器中。" #: ../../source/how-to-run-flower-using-docker.rst:264 #, fuzzy @@ -5652,44 +5805,58 @@ msgid "Flower ServerApp" msgstr "Flower 服务器。" #: ../../source/how-to-run-flower-using-docker.rst:277 +#, fuzzy msgid "" "The procedure for building and running a ServerApp image is almost " "identical to the SuperNode image." -msgstr "" +msgstr "构建和运行 ServerApp 映像的程序与 SuperNode 映像几乎完全相同。" #: ../../source/how-to-run-flower-using-docker.rst:279 +#, fuzzy msgid "" "Similar to the SuperNode image, the ServerApp Docker image comes with a " "pre-installed version of Flower and serves as a base for building your " "own ServerApp image." msgstr "" +"与 SuperNode 映像类似,ServerApp Docker 映像也预装了 Flower 版本," +"可作为构建自己的 ServerApp 映像的基础。" #: ../../source/how-to-run-flower-using-docker.rst:282 +#, fuzzy msgid "" "We will use the same ``quickstart-pytorch`` example as we do in the " "Flower SuperNode section. If you have not already done so, please follow " "the `SuperNode Prerequisites`_ before proceeding." msgstr "" +"我们将使用与 \"Flower SuperNode \"部分相同的 \"quickstart-pytorch \"示例" +"。如果您还没有这样做,请在继续之前遵循 \"SuperNode 先决条件\"。" #: ../../source/how-to-run-flower-using-docker.rst:287 +#, fuzzy msgid "Creating a ServerApp Dockerfile" -msgstr "" +msgstr "创建 ServerApp Dockerfile" #: ../../source/how-to-run-flower-using-docker.rst:298 +#, fuzzy msgid "" "First, we need to create a Dockerfile in the directory where the " "``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " "example, create a new file called ``Dockerfile.serverapp`` in ``examples" "/quickstart-pytorch``." msgstr "" +"首先,我们需要在 ``ServerApp`` 代码所在的目录中创建一个 Dockerfile。如果使用 " +"``quickstart-pytorch`` 示例,请在 ``examples/quickstart-pytorch`` " +"中创建一个名为 ``Dockerfile.serverapp`` 的新文件。" #: ../../source/how-to-run-flower-using-docker.rst:302 +#, fuzzy msgid "" "The ``Dockerfile.serverapp`` contains the instructions that assemble the " "ServerApp image." -msgstr "" +msgstr "Dockerfile.serverapp \"包含组装 ServerApp 镜像的说明。" #: ../../source/how-to-run-flower-using-docker.rst:313 +#, fuzzy msgid "" "In the first two lines, we instruct Docker to use the ServerApp image " "tagged ``1.8.0`` as a base image and set our working directory to " @@ -5700,6 +5867,11 @@ msgid "" "ServerApp (``:``) that will be run inside the " "ServerApp container." msgstr "" +"在前两行中,我们指示 Docker 使用标记为 ``1.8.0`` 的 ServerApp " +"镜像作为基础镜像,并将工作目录设置为 ``/app``。下面的指令将在 ``/app`` " +"目录中执行。在最后两行中,我们将 ``server.py`` 模块复制到映像中," +"并将入口点设置为 ``flower-server-app``,参数为 ``server:app``。参数是将在 " +"ServerApp 容器内运行的 ServerApp 的对象引用(``<模块>:<属性>``)。" #: ../../source/how-to-run-flower-using-docker.rst:321 #, fuzzy @@ -5707,17 +5879,22 @@ msgid "Building the ServerApp Docker image" msgstr "启动服务器" #: ../../source/how-to-run-flower-using-docker.rst:323 +#, fuzzy msgid "" "Next, we build the ServerApp Docker image by running the following " "command in the directory where Dockerfile and ServerApp code are located." -msgstr "" +msgstr "接下来,我们在 Dockerfile 和 ServerApp 代码所在的目录下运行以下命令,构建 " +"ServerApp Docker 镜像。" #: ../../source/how-to-run-flower-using-docker.rst:330 +#, fuzzy msgid "" "We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" +"我们给图片命名为 ``flwr_serverapp``,标签为 ``0.0." +"1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" #: ../../source/how-to-run-flower-using-docker.rst:335 #, fuzzy @@ -5725,32 +5902,42 @@ msgid "Running the ServerApp Docker image" msgstr "启动服务器" #: ../../source/how-to-run-flower-using-docker.rst:337 +#, fuzzy msgid "Now that we have built the ServerApp image, we can finally run it." -msgstr "" +msgstr "现在我们已经构建了 ServerApp 镜像,终于可以运行它了。" #: ../../source/how-to-run-flower-using-docker.rst:349 +#, fuzzy msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." -msgstr "" +msgstr "flwr_serverapp:0.0.1``: 要使用的 Docker 映像的名称和标记。" #: ../../source/how-to-run-flower-using-docker.rst +#, fuzzy msgid "" "``--server 192.168.1.100:9091``: This option specifies the address of the" " SuperLinks Driver" -msgstr "" +msgstr "``--server 192.168.1.100:9091``: 此选项指定超级链接驱动程序的地址" #: ../../source/how-to-run-flower-using-docker.rst:363 +#, fuzzy msgid "" "To test running Flower locally, you can create a `bridge network " "`__, use the ``--network`` argument and pass the " "name of the Docker network to run your ServerApps." msgstr "" +"要测试在本地运行 Flower,可以创建一个 ``bridge network `___,使用 ``--network`` 参数并传递 Docker 网络的名称,以运行 " +"ServerApps。" #: ../../source/how-to-run-flower-using-docker.rst:367 +#, fuzzy msgid "" "Any argument that comes after the tag is passed to the Flower ServerApp " "binary. To see all available flags that the ServerApp supports, run:" -msgstr "" +msgstr "标记后的任何参数都将传递给 Flower ServerApp 二进制文件。要查看 ServerApp " +"支持的所有可用标记,请运行" #: ../../source/how-to-run-flower-using-docker.rst:377 #, fuzzy @@ -6715,6 +6902,7 @@ msgid "Upgrade to Flower Next" msgstr "升级至 Flower 1.0" #: ../../source/how-to-upgrade-to-flower-next.rst:4 +#, fuzzy msgid "" "Welcome to the migration guide for updating Flower to Flower Next! " "Whether you're a seasoned user or just getting started, this guide will " @@ -6722,18 +6910,27 @@ msgid "" " latest features and improvements in Flower Next, starting from version " "1.8." msgstr "" +"欢迎阅读从 Flower 升级到 Flower Next 的迁移指南!" +"无论您是经验丰富的用户还是刚刚开始使用 " +"Flower,本指南都将帮助您顺利过渡现有设置,以利用 Flower Next 从 1.8 " +"版开始的最新功能和改进。" #: ../../source/how-to-upgrade-to-flower-next.rst:9 +#, fuzzy msgid "" "This guide shows how to reuse pre-``1.8`` Flower code with minimum code " "changes by using the *compatibility layer* in Flower Next. In another " "guide, we will show how to run Flower Next end-to-end with pure Flower " "Next APIs." msgstr "" +"本指南展示了如何通过使用 Flower Next 中的*可兼容层*,以最小的代码改动重用```1" +".8```前的 Flower 代码。在另一个指南中,我们将介绍如何使用纯 Flower Next API " +"端到端运行 Flower Next。" #: ../../source/how-to-upgrade-to-flower-next.rst:13 +#, fuzzy msgid "Let's dive in!" -msgstr "" +msgstr "让我们深入了解一下!" #: ../../source/how-to-upgrade-to-flower-next.rst:48 #, fuzzy @@ -6748,14 +6945,16 @@ msgid "or if you need Flower Next with simulation:" msgstr "启动 Flower 模拟" #: ../../source/how-to-upgrade-to-flower-next.rst:61 +#, fuzzy msgid "" "Ensure you set the following version constraint in your " "``requirements.txt``" -msgstr "" +msgstr "确保在 ``requirements.txt`` 中设置了以下版本限制" #: ../../source/how-to-upgrade-to-flower-next.rst:71 +#, fuzzy msgid "or ``pyproject.toml``:" -msgstr "" +msgstr "或 ``pyproject.toml```:" #: ../../source/how-to-upgrade-to-flower-next.rst:82 #, fuzzy @@ -6780,6 +6979,7 @@ msgid "" msgstr "将 ``pyproject.toml`` 中的次要版本增加一个。" #: ../../source/how-to-upgrade-to-flower-next.rst:102 +#, fuzzy msgid "" "In Flower Next, the *infrastructure* and *application layers* have been " "decoupled. Instead of starting a client in code via ``start_client()``, " @@ -6791,6 +6991,12 @@ msgid "" "to run your project both in the traditional way and in the Flower Next " "way:" msgstr "" +"在 Flower Next 中,*基础架构层*和*应用层*已经解耦。你不再需要在代码中通过``st" +"art_client()``启动客户端,而是创建一个|clientapp_link|_,然后通过命令行启动它" +"。无需通过``start_server()``在代码中启动服务器,而是创建一个 |serverapp_link|" +"_ 并通过命令行启动它。服务器和客户端的长期运行组件被称为超级链接(SuperLink)" +"和超级节点(SuperNode)。以下是无需手动更新的非破坏性更改," +"可让您以传统方式和 Flower Next 方式运行项目:" #: ../../source/how-to-upgrade-to-flower-next.rst:109 #, fuzzy @@ -6798,10 +7004,12 @@ msgid "|clientapp_link|_" msgstr "客户端" #: ../../source/how-to-upgrade-to-flower-next.rst:110 +#, fuzzy msgid "" "Wrap your existing client with |clientapp_link|_ instead of launching it " "via |startclient_link|_. Here's an example:" -msgstr "" +msgstr "用 |clientapp_link|_ 封装现有客户端,而不是通过 |startclient_link|_ " +"启动。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:132 #, fuzzy @@ -6809,35 +7017,45 @@ msgid "|serverapp_link|_" msgstr "服务器" #: ../../source/how-to-upgrade-to-flower-next.rst:133 +#, fuzzy msgid "" "Wrap your existing strategy with |serverapp_link|_ instead of starting " "the server via |startserver_link|_. Here's an example:" -msgstr "" +msgstr "用 |serverapp_link|_ 包住现有策略,而不是通过 |startserver_link|_ " +"启动服务器。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:154 +#, fuzzy msgid "Deployment" -msgstr "" +msgstr "调配" #: ../../source/how-to-upgrade-to-flower-next.rst:155 +#, fuzzy msgid "" "Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " "in sequence, |flowernext_clientapp_link|_ (2x) and " "|flowernext_serverapp_link|_. There is no need to execute `client.py` and" " `server.py` as Python scripts." msgstr "" +"在依次运行 |flowernext_clientapp_link|_ (2x) 和 |flowernext_serverapp_link|_ " +"之前,使用 |flowernext_superlink_link|_ 运行 ``SuperLink`` 。无需将 |client." +"py` 和 `server.py` 作为 Python 脚本执行。" #: ../../source/how-to-upgrade-to-flower-next.rst:158 +#, fuzzy msgid "" "Here's an example to start the server without HTTPS (only for " "prototyping):" -msgstr "" +msgstr "下面是一个在不使用 HTTPS 的情况下启动服务器的示例(仅用于原型开发):" #: ../../source/how-to-upgrade-to-flower-next.rst:174 +#, fuzzy msgid "" "Here's another example to start with HTTPS. Use the ``--certificates`` " "command line argument to pass paths to (CA certificate, server " "certificate, and server private key)." -msgstr "" +msgstr "下面是另一个使用 HTTPS 的示例。使用 ``--certificates`` 命令行参数传递路径(" +"CA 证书、服务器证书和服务器私钥)。" #: ../../source/how-to-upgrade-to-flower-next.rst:201 #, fuzzy @@ -6845,36 +7063,48 @@ msgid "Simulation in CLI" msgstr "运行模拟" #: ../../source/how-to-upgrade-to-flower-next.rst:202 +#, fuzzy msgid "" "Wrap your existing client and strategy with |clientapp_link|_ and " "|serverapp_link|_, respectively. There is no need to use |startsim_link|_" " anymore. Here's an example:" msgstr "" +"分别用 |clientapp_link|_ 和 |serverapp_link|_ 封装现有的客户端和策略。" +"无需再使用 |startsim_link|_。下面是一个示例:" #: ../../source/how-to-upgrade-to-flower-next.rst:232 +#, fuzzy msgid "" "Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " "``client_app`` object in the code instead of executing the Python script." " Here's an example (assuming the ``server_app`` and ``client_app`` " "objects are in a ``sim.py`` module):" msgstr "" +"在 CLI 中运行 |flower_simulation_link|_ 并指向代码中的 ``server_app`` " +"/``client_app`` 对象,而不是执行 Python 脚本。下面是一个示例(假定 " +"`server_app`` 和 `client_app`` 对象位于 `sim.py`` 模块中):" #: ../../source/how-to-upgrade-to-flower-next.rst:249 +#, fuzzy msgid "" "Set default resources for each |clientapp_link|_ using the ``--backend-" "config`` command line argument instead of setting the " "``client_resources`` argument in |startsim_link|_. Here's an example:" msgstr "" +"使用 ``--backend-config`` 命令行参数为每个 |clientapp_link|_ 设置默认资源," +"而不是在 |startsim_link|_ 中设置 ``client_resources`` 参数。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:275 +#, fuzzy msgid "Simulation in a Notebook" -msgstr "" +msgstr "笔记本中的模拟" #: ../../source/how-to-upgrade-to-flower-next.rst:276 +#, fuzzy msgid "" "Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " "an example:" -msgstr "" +msgstr "在笔记本中运行 |runsim_link|_,而不是 |startsim_link|_。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:319 #, fuzzy @@ -6897,15 +7127,18 @@ msgid "Important" msgstr "重要变更:" #: ../../source/how-to-upgrade-to-flower-next.rst:328 +#, fuzzy msgid "" "As we continuously enhance Flower Next at a rapid pace, we'll be " "periodically updating this guide. Please feel free to share any feedback " "with us!" -msgstr "" +msgstr "随着 Flower Next " +"的不断快速改进,我们将定期更新本指南。如有任何反馈,请随时与我们分享!" #: ../../source/how-to-upgrade-to-flower-next.rst:334 +#, fuzzy msgid "Happy migrating! 🚀" -msgstr "" +msgstr "移民愉快!🚀" #: ../../source/how-to-use-built-in-mods.rst:2 #, fuzzy @@ -9316,8 +9549,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.encode:1 of +#, fuzzy msgid "Encode the string using the codec registered for encoding." -msgstr "" +msgstr "使用注册的编码解码器对字符串进行编码。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9328,8 +9562,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.replace:1 of +#, fuzzy msgid "Return a copy with all occurrences of substring old replaced by new." -msgstr "" +msgstr "返回用 new 替换子串 old 的所有出现次数的副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9340,10 +9575,11 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of +#, fuzzy msgid "" "Return a list of the substrings in the string, using sep as the separator" " string." -msgstr "" +msgstr "使用 sep 作为分隔符,返回字符串中的子字符串列表。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9359,8 +9595,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.join:1 of +#, fuzzy msgid "Concatenate any number of strings." -msgstr "" +msgstr "连接任意数量的字符串。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9369,8 +9606,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.capitalize:1 of +#, fuzzy msgid "Return a capitalized version of the string." -msgstr "" +msgstr "返回字符串的大写版本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9379,8 +9617,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.casefold:1 of +#, fuzzy msgid "Return a version of the string suitable for caseless comparisons." -msgstr "" +msgstr "返回适合无例比较的字符串版本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9389,8 +9628,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.title:1 of +#, fuzzy msgid "Return a version of the string where each word is titlecased." -msgstr "" +msgstr "返回字符串的版本,其中每个单词都使用了标题大小写。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9413,10 +9653,11 @@ msgid "" msgstr ":py:obj:`Context `\\ \\(state\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "" "Return the number of non-overlapping occurrences of substring sub in " "string S[start:end]." -msgstr "" +msgstr "返回子字符串 sub 在字符串 S[start:end] 中非重叠出现的次数。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9427,8 +9668,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.expandtabs:1 of +#, fuzzy msgid "Return a copy where all tab characters are expanded using spaces." -msgstr "" +msgstr "返回使用空格扩展所有制表符的副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9438,10 +9680,11 @@ msgid "" msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "" "Return the lowest index in S where substring sub is found, such that sub " "is contained within S[start:end]." -msgstr "" +msgstr "返回在 S 中找到子串 sub 的最低索引,且 sub 包含在 S[start:end] 中。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9450,8 +9693,9 @@ msgstr ":py:obj:`partition_id `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.partition:1 flwr.common.EventType.rpartition:1 of +#, fuzzy msgid "Partition the string into three parts using the given separator." -msgstr "" +msgstr "使用给定的分隔符将字符串分为三部分。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9469,8 +9713,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.ljust:1 of +#, fuzzy msgid "Return a left-justified string of length width." -msgstr "" +msgstr "返回长度为 width 的左对齐字符串。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9479,8 +9724,9 @@ msgstr ":py:obj:`now `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.lower:1 of +#, fuzzy msgid "Return a copy of the string converted to lowercase." -msgstr "" +msgstr "返回转换为小写的字符串副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9489,8 +9735,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.lstrip:1 of +#, fuzzy msgid "Return a copy of the string with leading whitespace removed." -msgstr "" +msgstr "返回去掉前导空白的字符串副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9500,10 +9747,11 @@ msgid "" msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "" "Return the highest index in S where substring sub is found, such that sub" " is contained within S[start:end]." -msgstr "" +msgstr "返回在 S 中找到子串 sub 的最高索引,且 sub 包含在 S[start:end] 中。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9521,8 +9769,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rjust:1 of +#, fuzzy msgid "Return a right-justified string of length width." -msgstr "" +msgstr "返回长度为 width 的右对齐字符串。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9531,8 +9780,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rstrip:1 of +#, fuzzy msgid "Return a copy of the string with trailing whitespace removed." -msgstr "" +msgstr "返回去掉尾部空白的字符串副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9548,8 +9798,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.splitlines:1 of +#, fuzzy msgid "Return a list of the lines in the string, breaking at line boundaries." -msgstr "" +msgstr "返回字符串中的行列表,以行为分界线。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9558,8 +9809,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.strip:1 of +#, fuzzy msgid "Return a copy of the string with leading and trailing whitespace removed." -msgstr "" +msgstr "返回去掉前导和尾部空白的字符串副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9568,10 +9820,11 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.swapcase:1 of +#, fuzzy msgid "" "Convert uppercase characters to lowercase and lowercase characters to " "uppercase." -msgstr "" +msgstr "将大写字母转换为小写字母,将小写字母转换为大写字母。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9580,8 +9833,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.translate:1 of +#, fuzzy msgid "Replace each character in the string using the given translation table." -msgstr "" +msgstr "使用给定的翻译表替换字符串中的每个字符。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9590,8 +9844,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.upper:1 of +#, fuzzy msgid "Return a copy of the string converted to uppercase." -msgstr "" +msgstr "返回转换为大写字符串的副本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9601,8 +9856,9 @@ msgid "" msgstr ":py:obj:`Status `\\ \\(code\\, message\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "Return True if S starts with the specified prefix, False otherwise." -msgstr "" +msgstr "如果 S 以指定前缀开头,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9612,8 +9868,9 @@ msgid "" msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "Return True if S ends with the specified suffix, False otherwise." -msgstr "" +msgstr "如果 S 以指定后缀结束,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9624,8 +9881,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.removeprefix:1 of +#, fuzzy msgid "Return a str with the given prefix string removed if present." -msgstr "" +msgstr "返回一个字符串,如果存在,则去掉给定的前缀字符串。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9636,8 +9894,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.removesuffix:1 of +#, fuzzy msgid "Return a str with the given suffix string removed if present." -msgstr "" +msgstr "返回一个字符串,如果存在给定的后缀字符串,则将其删除。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9646,8 +9905,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isascii:1 of +#, fuzzy msgid "Return True if all characters in the string are ASCII, False otherwise." -msgstr "" +msgstr "如果字符串中的所有字符都是 ASCII 码,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9656,8 +9916,9 @@ msgstr ":py:obj:`now `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.islower:1 of +#, fuzzy msgid "Return True if the string is a lowercase string, False otherwise." -msgstr "" +msgstr "如果字符串是小写字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9666,8 +9927,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isupper:1 of +#, fuzzy msgid "Return True if the string is an uppercase string, False otherwise." -msgstr "" +msgstr "如果字符串是大写字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9676,8 +9938,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.istitle:1 of +#, fuzzy msgid "Return True if the string is a title-cased string, False otherwise." -msgstr "" +msgstr "如果字符串是带标题的字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9686,8 +9949,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isspace:1 of +#, fuzzy msgid "Return True if the string is a whitespace string, False otherwise." -msgstr "" +msgstr "如果字符串是空白字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9696,8 +9960,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isdecimal:1 of +#, fuzzy msgid "Return True if the string is a decimal string, False otherwise." -msgstr "" +msgstr "如果字符串是十进制字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9706,8 +9971,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isdigit:1 of +#, fuzzy msgid "Return True if the string is a digit string, False otherwise." -msgstr "" +msgstr "如果字符串是数字字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9716,8 +9982,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isnumeric:1 of +#, fuzzy msgid "Return True if the string is a numeric string, False otherwise." -msgstr "" +msgstr "如果字符串是数字字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9726,8 +9993,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isalpha:1 of +#, fuzzy msgid "Return True if the string is an alphabetic string, False otherwise." -msgstr "" +msgstr "如果字符串是字母字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9736,8 +10004,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isalnum:1 of +#, fuzzy msgid "Return True if the string is an alpha-numeric string, False otherwise." -msgstr "" +msgstr "如果字符串是字母数字字符串,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9746,8 +10015,9 @@ msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isidentifier:1 of +#, fuzzy msgid "Return True if the string is a valid Python identifier, False otherwise." -msgstr "" +msgstr "如果字符串是有效的 Python 标识符,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9756,8 +10026,9 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isprintable:1 of +#, fuzzy msgid "Return True if the string is printable, False otherwise." -msgstr "" +msgstr "如果字符串可打印,则返回 True,否则返回 False。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9766,10 +10037,11 @@ msgstr ":py:obj:`PING `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.zfill:1 of +#, fuzzy msgid "" "Pad a numeric string with zeros on the left, to fill a field of the given" " width." -msgstr "" +msgstr "在数字字符串左侧填充零,以填满给定宽度的字段。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9781,8 +10053,9 @@ msgstr "" "\\*\\*kwargs\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "Return a formatted version of S, using substitutions from args and kwargs." -msgstr "" +msgstr "使用 args 和 kwargs 的替换,返回 S 的格式化版本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9790,8 +10063,9 @@ msgid ":py:obj:`format_map `\\ \\(mapping\\)" msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 +#, fuzzy msgid "Return a formatted version of S, using substitutions from mapping." -msgstr "" +msgstr "使用映射中的替换,返回 S 的格式化版本。" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #, fuzzy @@ -9800,8 +10074,9 @@ msgstr ":py:obj:`TRAIN `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.maketrans:1 of +#, fuzzy msgid "Return a translation table usable for str.translate()." -msgstr "" +msgstr "返回可用于 str.translate() 的翻译表。" #: flwr.common.EventType.capitalize:1::1 of #, fuzzy @@ -9975,30 +10250,36 @@ msgstr "" "`\\" #: flwr.common.EventType.capitalize:3 of +#, fuzzy msgid "" "More specifically, make the first character have upper case and the rest " "lower case." -msgstr "" +msgstr "更具体地说,让第一个字符大写,其余字符小写。" #: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 #: flwr.common.EventType.rjust:3 of +#, fuzzy msgid "Padding is done using the specified fill character (default is a space)." -msgstr "" +msgstr "使用指定的填充字符(默认为空格)进行填充。" #: flwr.common.EventType.count:1 of +#, fuzzy msgid "" "Return the number of non-overlapping occurrences of substring sub in " "string S[start:end]. Optional arguments start and end are interpreted as" " in slice notation." -msgstr "" +msgstr "返回子串 sub 在字符串 S[start:end] 中非重叠出现的次数。 可选参数 start 和 " +"end 按切分符号解释。" #: flwr.common.EventType.encode:3 of +#, fuzzy msgid "encoding" -msgstr "" +msgstr "编码" #: flwr.common.EventType.encode:4 of +#, fuzzy msgid "The encoding in which to encode the string." -msgstr "" +msgstr "字符串的编码。" #: flwr.common.EventType.encode:9 of #, fuzzy @@ -10006,6 +10287,7 @@ msgid "errors" msgstr "错误" #: flwr.common.EventType.encode:6 of +#, fuzzy msgid "" "The error handling scheme to use for encoding errors. The default is " "'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " @@ -10013,134 +10295,177 @@ msgid "" "as any other name registered with codecs.register_error that can handle " "UnicodeEncodeErrors." msgstr "" +"编码错误的错误处理方案。默认值为 \"strict\",即编码错误会引发 " +"UnicodeEncodeError。 其他可能的值包括 \"ignore\"、\"replace \"和 " +"\"xmlcharrefreplace\",以及通过 codecs.register_error 注册的、可处理 " +"UnicodeEncodeErrror 的其他名称。" #: flwr.common.EventType.endswith:1 of +#, fuzzy msgid "" "Return True if S ends with the specified suffix, False otherwise. With " "optional start, test S beginning at that position. With optional end, " "stop comparing S at that position. suffix can also be a tuple of strings " "to try." msgstr "" +"如果 S 以指定后缀结束,则返回 True,否则返回 False。如果起始位置可选," +"则从该位置开始测试 S。如果使用可选的 end,则在该位置停止比较 " +"S。后缀也可以是要尝试的字符串元组。" #: flwr.common.EventType.expandtabs:3 of +#, fuzzy msgid "If tabsize is not given, a tab size of 8 characters is assumed." -msgstr "" +msgstr "如果未给出制表符大小,则假定制表符大小为 8 个字符。" #: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of +#, fuzzy msgid "" "Return the lowest index in S where substring sub is found, such that sub " "is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" +"返回在 S 中找到子串 sub 的最低索引,即 sub 包含在 S[start:end] 中。 可选参数 " +"start 和 end 按切分符号解释。" #: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of +#, fuzzy msgid "Return -1 on failure." -msgstr "" +msgstr "失败时返回-1。" #: flwr.common.EventType.format:1 of +#, fuzzy msgid "" "Return a formatted version of S, using substitutions from args and " "kwargs. The substitutions are identified by braces ('{' and '}')." -msgstr "" +msgstr "使用来自 args 和 kwargs 的替换,返回 S " +"的格式化版本。替换用大括号('{'和'}')标识。" #: flwr.common.EventType.format_map:1 of +#, fuzzy msgid "" "Return a formatted version of S, using substitutions from mapping. The " "substitutions are identified by braces ('{' and '}')." -msgstr "" +msgstr "使用映射中的替换,返回 S 的格式化版本。替换用大括号('{'和'}')标识。" #: flwr.common.EventType.index:5 flwr.common.EventType.rindex:5 of +#, fuzzy msgid "Raises ValueError when the substring is not found." -msgstr "" +msgstr "如果未找到子串,则引发 ValueError。" #: flwr.common.EventType.isalnum:3 of +#, fuzzy msgid "" "A string is alpha-numeric if all characters in the string are alpha-" "numeric and there is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是字母数字,且字符串中至少有一个字符,则该字符串为字" +"母数字字符串。" #: flwr.common.EventType.isalpha:3 of +#, fuzzy msgid "" "A string is alphabetic if all characters in the string are alphabetic and" " there is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是字母,并且字符串中至少有一个字符,那么该字符串就是" +"字母字符串。" #: flwr.common.EventType.isascii:3 of +#, fuzzy msgid "" "ASCII characters have code points in the range U+0000-U+007F. Empty " "string is ASCII too." -msgstr "" +msgstr "ASCII 字符的码位范围为 U+0000-U+007F。空字符串也是 ASCII 字符。" #: flwr.common.EventType.isdecimal:3 of +#, fuzzy msgid "" "A string is a decimal string if all characters in the string are decimal " "and there is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是十进制,并且字符串中至少有一个字符是十进制,那么该" +"字符串就是十进制字符串。" #: flwr.common.EventType.isdigit:3 of +#, fuzzy msgid "" "A string is a digit string if all characters in the string are digits and" " there is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是数字,并且字符串中至少有一个字符,那么该字符串就是" +"数字字符串。" #: flwr.common.EventType.isidentifier:3 of +#, fuzzy msgid "" "Call keyword.iskeyword(s) to test whether string s is a reserved " "identifier, such as \"def\" or \"class\"." -msgstr "" +msgstr "调用 keyword.iskeyword(s) 测试字符串 s 是否为保留标识符,如 \"def \"或 " +"\"class\"。" #: flwr.common.EventType.islower:3 of +#, fuzzy msgid "" "A string is lowercase if all cased characters in the string are lowercase" " and there is at least one cased character in the string." -msgstr "" +msgstr "如果字符串中的所有大小写字符都是小写,且字符串中至少有一个大小写字符,则该字" +"符串为小写字符串。" #: flwr.common.EventType.isnumeric:3 of +#, fuzzy msgid "" "A string is numeric if all characters in the string are numeric and there" " is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是数字,且字符串中至少有一个字符,则该字符串为数字字" +"符串。" #: flwr.common.EventType.isprintable:3 of +#, fuzzy msgid "" "A string is printable if all of its characters are considered printable " "in repr() or if it is empty." -msgstr "" +msgstr "如果字符串的所有字符在 repr() " +"中都被认为是可打印的,或者字符串为空,那么该字符串就是可打印的。" #: flwr.common.EventType.isspace:3 of +#, fuzzy msgid "" "A string is whitespace if all characters in the string are whitespace and" " there is at least one character in the string." -msgstr "" +msgstr "如果字符串中的所有字符都是空格,且字符串中至少有一个字符,则该字符串为空格。" #: flwr.common.EventType.istitle:3 of +#, fuzzy msgid "" "In a title-cased string, upper- and title-case characters may only follow" " uncased characters and lowercase characters only cased ones." -msgstr "" +msgstr "在标题大小写字符串中,大写和标题大小写字符只能跟在无大小写字符之后,小写字符" +"只能跟在有大小写字符之后。" #: flwr.common.EventType.isupper:3 of +#, fuzzy msgid "" "A string is uppercase if all cased characters in the string are uppercase" " and there is at least one cased character in the string." -msgstr "" +msgstr "如果字符串中所有带大小写的字符都是大写,并且字符串中至少有一个带大小写的字符" +",则该字符串为大写字符串。" #: flwr.common.EventType.join:3 of +#, fuzzy msgid "" "The string whose method is called is inserted in between each given " "string. The result is returned as a new string." -msgstr "" +msgstr "方法被调用的字符串会被插入每个给定的字符串之间。结果将以新字符串的形式返回。" #: flwr.common.EventType.join:6 of +#, fuzzy msgid "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" -msgstr "" +msgstr "示例:'.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" #: flwr.common.EventType.lstrip:3 flwr.common.EventType.rstrip:3 #: flwr.common.EventType.strip:3 of +#, fuzzy msgid "If chars is given and not None, remove characters in chars instead." -msgstr "" +msgstr "如果给定的是 chars 而不是 None,则删除 chars 中的字符。" #: flwr.common.EventType.maketrans:3 of +#, fuzzy msgid "" "If there is only one argument, it must be a dictionary mapping Unicode " "ordinals (integers) or characters to Unicode ordinals, strings or None. " @@ -10150,32 +10475,43 @@ msgid "" "same position in y. If there is a third argument, it must be a string, " "whose characters will be mapped to None in the result." msgstr "" +"如果只有一个参数,则必须是一个将 Unicode 序号(整数)或字符映射到 Unicode " +"序号、字符串或 None 的字典。字符键将被转换为序号。如果有两个参数,它们必须是" +"长度相等的字符串,在生成的字典中,x 中的每个字符将被映射到 y " +"中相同位置的字符。" #: flwr.common.EventType.partition:3 of +#, fuzzy msgid "" "This will search for the separator in the string. If the separator is " "found, returns a 3-tuple containing the part before the separator, the " "separator itself, and the part after it." -msgstr "" +msgstr "它会在字符串中搜索分隔符。 如果找到分隔符,则返回一个包含分隔符前部分、" +"分隔符本身和分隔符后部分的 3 元组。" #: flwr.common.EventType.partition:7 of +#, fuzzy msgid "" "If the separator is not found, returns a 3-tuple containing the original " "string and two empty strings." -msgstr "" +msgstr "如果找不到分隔符,则返回一个包含原始字符串和两个空字符串的 3 元组。" #: flwr.common.EventType.removeprefix:3 of +#, fuzzy msgid "" "If the string starts with the prefix string, return string[len(prefix):]." " Otherwise, return a copy of the original string." -msgstr "" +msgstr "如果字符串以前缀字符串开始,则返回 " +"string[len(prefix):]。否则,返回原始字符串的副本。" #: flwr.common.EventType.removesuffix:3 of +#, fuzzy msgid "" "If the string ends with the suffix string and that suffix is not empty, " "return string[:-len(suffix)]. Otherwise, return a copy of the original " "string." -msgstr "" +msgstr "如果字符串以后缀字符串结尾,且后缀不为空,则返回 " +"string[:-len(suffix)]。否则,返回原始字符串的副本。" #: flwr.common.EventType.replace:5 of #, fuzzy @@ -10183,92 +10519,115 @@ msgid "count" msgstr "背景" #: flwr.common.EventType.replace:4 of +#, fuzzy msgid "" "Maximum number of occurrences to replace. -1 (the default value) means " "replace all occurrences." -msgstr "" +msgstr "要替换的最大出现次数。-1(默认值)表示替换所有出现次数。" #: flwr.common.EventType.replace:7 of +#, fuzzy msgid "" "If the optional argument count is given, only the first count occurrences" " are replaced." -msgstr "" +msgstr "如果给出可选参数 count,则只替换第一个计数出现的次数。" #: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of +#, fuzzy msgid "" "Return the highest index in S where substring sub is found, such that sub" " is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" +"返回在 S 中找到子串 sub 且 sub 包含在 S[start:end] 中的最高索引。 可选参数 " +"start 和 end 按切分符号解释。" #: flwr.common.EventType.rpartition:3 of +#, fuzzy msgid "" "This will search for the separator in the string, starting at the end. If" " the separator is found, returns a 3-tuple containing the part before the" " separator, the separator itself, and the part after it." -msgstr "" +msgstr "它会从字符串的末尾开始搜索分隔符。如果找到分隔符,则返回一个包含分隔符前部分" +"、分隔符本身和分隔符后部分的 3 元组。" #: flwr.common.EventType.rpartition:7 of +#, fuzzy msgid "" "If the separator is not found, returns a 3-tuple containing two empty " "strings and the original string." -msgstr "" +msgstr "如果找不到分隔符,则返回一个包含两个空字符串和原始字符串的 3 元组。" #: flwr.common.EventType.rsplit:7 flwr.common.EventType.split:7 of +#, fuzzy msgid "sep" -msgstr "" +msgstr "sep" #: flwr.common.EventType.rsplit:4 flwr.common.EventType.split:4 of +#, fuzzy msgid "The separator used to split the string." -msgstr "" +msgstr "用于分割字符串的分隔符。" #: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of +#, fuzzy msgid "" "When set to None (the default value), will split on any whitespace " "character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" " empty strings from the result." msgstr "" +"当设置为 \"无\"(默认值)时,将对任何空白字符(包括 \\n" +" \\r \\t \\f 和空格)进行分割,并从结果中剔除空字符串。" #: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of +#, fuzzy msgid "maxsplit" -msgstr "" +msgstr "最大分割" #: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of +#, fuzzy msgid "" "Maximum number of splits (starting from the left). -1 (the default value)" " means no limit." -msgstr "" +msgstr "最大分割次数(从左边开始)。-1(默认值)表示没有限制。" #: flwr.common.EventType.rsplit:13 of +#, fuzzy msgid "Splitting starts at the end of the string and works to the front." -msgstr "" +msgstr "从琴弦末端开始分弦,一直到琴弦前端。" #: flwr.common.EventType.split:13 of +#, fuzzy msgid "" "Note, str.split() is mainly useful for data that has been intentionally " "delimited. With natural text that includes punctuation, consider using " "the regular expression module." -msgstr "" +msgstr "注意,str.split() 主要适用于有意分隔的数据。 " +"对于包含标点符号的自然文本,可以考虑使用正则表达式模块。" #: flwr.common.EventType.splitlines:3 of +#, fuzzy msgid "" "Line breaks are not included in the resulting list unless keepends is " "given and true." -msgstr "" +msgstr "除非指定 keepends 为 true,否则换行符不会包含在生成的列表中。" #: flwr.common.EventType.startswith:1 of +#, fuzzy msgid "" "Return True if S starts with the specified prefix, False otherwise. With " "optional start, test S beginning at that position. With optional end, " "stop comparing S at that position. prefix can also be a tuple of strings " "to try." msgstr "" +"如果 S 以指定的前缀开始,则返回 True,否则返回 False。如果选择 start," +"则从该位置开始测试 S。如果使用可选的 end,则在该位置停止比较 S。" #: flwr.common.EventType.title:3 of +#, fuzzy msgid "" "More specifically, words start with uppercased characters and all " "remaining cased characters have lower case." -msgstr "" +msgstr "更具体地说,单词以大写字母开头,其余所有大小写字符均为小写。" #: flwr.common.EventType.translate:5 of #, fuzzy @@ -10276,21 +10635,26 @@ msgid "table" msgstr "数据库" #: flwr.common.EventType.translate:4 of +#, fuzzy msgid "" "Translation table, which must be a mapping of Unicode ordinals to Unicode" " ordinals, strings, or None." -msgstr "" +msgstr "翻译表,必须是 Unicode 序号到 Unicode 序号、字符串或无的映射。" #: flwr.common.EventType.translate:7 of +#, fuzzy msgid "" "The table must implement lookup/indexing via __getitem__, for instance a " "dictionary or list. If this operation raises LookupError, the character " "is left untouched. Characters mapped to None are deleted." msgstr "" +"表必须通过 __getitem__ 实现查找/索引,例如字典或列表。 如果该操作引发 " +"LookupError,该字符将保持不变。 映射为 None 的字符将被删除。" #: flwr.common.EventType.zfill:3 of +#, fuzzy msgid "The string is never truncated." -msgstr "" +msgstr "字符串不会被截断。" #: ../../source/ref-api/flwr.common.FitIns.rst:2 #, fuzzy @@ -10492,25 +10856,32 @@ msgstr "遇到的错误。" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of +#, fuzzy msgid "" "Time-to-live for this message in seconds. If unset, it will be set based " "on the remaining time for the received message before it expires. This " "follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " "msg.meta.created_at)" msgstr "" +"该信息的有效时间(秒)。如果未设置,则将根据收到的信息过期前的剩余时间来设置" +"。其计算公式为:ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta." +"created_at)" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of +#, fuzzy msgid "" "Time-to-live for this message in seconds. If unset, it will be set based " "on the remaining time for the received message before it expires. This " "follows the equation:" -msgstr "" +msgstr "该信息的有效时间(秒)。如果未设置,则将根据接收到的信息过期前的剩余时间来设" +"置。其计算公式如下" #: flwr.common.message.Message.create_error_reply:9 #: flwr.common.message.Message.create_reply:13 of +#, fuzzy msgid "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" -msgstr "" +msgstr "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" #: flwr.common.message.Message.create_reply:3 of #, fuzzy @@ -10631,8 +11002,9 @@ msgstr ":py:obj:`ttl `\\" #: flwr.common.Metadata.created_at:1 #: flwr.common.Metadata.created_at:1::1 of +#, fuzzy msgid "Unix timestamp when the message was created." -msgstr "" +msgstr "创建信息时的 Unix 时间戳。" #: flwr.common.Metadata.created_at:1::1 of #, fuzzy @@ -15720,8 +16092,9 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.unmask_stage:1 #: of +#, fuzzy msgid "Execute the 'unmask' stage." -msgstr "" +msgstr "执行 \"解除屏蔽 \"阶段。" #: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:2 #, fuzzy @@ -15729,12 +16102,16 @@ msgid "SecAggWorkflow" msgstr "工作流程" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of +#, fuzzy msgid "" "Bases: " ":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" +"基础: :py:class:`~flwr.server.workflow.secure_aggregation." +"secaggplus_workflow.SecAggPlusWorkflow`." #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of +#, fuzzy msgid "" "The SecAgg protocol ensures the secure summation of integer vectors owned" " by multiple parties, without accessing any individual integer vector. " @@ -15748,27 +16125,40 @@ msgid "" "('parameters') from the client's `FitRes`. The server then aggregates " "these contributions to compute the weighted average of model parameters." msgstr "" +"SecAgg 协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向量" +"。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持私" +"密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保护" +"隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * params]\"" +",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " +"\"FitRes \"中的模型参数(\"parameters\"" +")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of +#, fuzzy msgid "" "The protocol involves four main stages: - 'setup': Send SecAgg " "configuration to clients and collect their public keys. - 'share keys': " "Broadcast public keys among clients and collect encrypted secret" msgstr "" +"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg 配置并收集它们的公钥。-" +" 共享密钥\": 在客户端之间广播公钥并收集加密密钥。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of +#, fuzzy msgid "" "Each client's private key is split into N shares under the SecAgg " "protocol, where N is the number of selected clients." -msgstr "" +msgstr "根据 SecAgg 协议,每个客户的私人密钥被分成 N 份,其中 N 是所选客户的数量。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of +#, fuzzy msgid "" "Generally, higher `reconstruction_threshold` means better privacy " "guarantees but less tolerance to dropouts." -msgstr "" +msgstr "一般来说,\"重建阈值 \"越高,隐私保证就越好,但对丢包的容忍度就越低。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of +#, fuzzy msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " @@ -15776,45 +16166,62 @@ msgid "" "setting the security threshold relative to the number of selected " "clients." msgstr "" +"当 `reconstruction_threshold` 为浮点数时,它被解释为重建私钥所需的所有选定客" +"户端数量的比例。此功能可根据所选客户端的数量灵活设置安全阈值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of +#, fuzzy msgid "" "`reconstruction_threshold`, and the quantization parameters " "(`clipping_range`, `quantization_range`, `modulus_range`) play critical " "roles in balancing privacy, robustness, and efficiency within the SecAgg " "protocol." msgstr "" +"重构阈值 \"和量化参数(\"裁剪范围\"、\"量化范围\"、\"模量范围\")在 SecAgg " +"协议中平衡隐私性、鲁棒性和效率方面起着至关重要的作用。" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`collect_masked_vectors_stage " "`\\ " "\\(driver\\, ...\\)" msgstr "" +":py:obj:`collect_masked_vectors_stage `\\(driver\\, ...\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`setup_stage `\\" " \\(driver\\, context\\, state\\)" msgstr "" +":py:obj:`setup_stage `\\(" +"driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`share_keys_stage " "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" +"py:obj:`share_keys_stage `\\(driver\\, context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of +#, fuzzy msgid "" ":py:obj:`unmask_stage " "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" +":py:obj:`unmask_stage `\\ " +"\\(driver\\, context\\, state\\)" #: ../../source/ref-api/flwr.simulation.rst:2 #, fuzzy @@ -15822,10 +16229,13 @@ msgid "simulation" msgstr "运行模拟" #: ../../source/ref-api/flwr.simulation.rst:18::1 +#, fuzzy msgid "" ":py:obj:`start_simulation `\\ \\(\\*\\," " client\\_fn\\[\\, ...\\]\\)" msgstr "" +":py:obj:`start_simulation `\\ \\(\\*\\, " +"client\\_fn\\[\\, ...\\]\\)" #: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.app.start_simulation:1 of @@ -15833,15 +16243,19 @@ msgid "Start a Ray-based Flower simulation server." msgstr "启动基于 Ray 的Flower模拟服务器。" #: ../../source/ref-api/flwr.simulation.rst:18::1 +#, fuzzy msgid "" ":py:obj:`run_simulation `\\ " "\\(server\\_app\\, client\\_app\\, ...\\)" msgstr "" +":py:obj:`run_simulation `\\ \\(server\\_app\\" +", client\\_app\\, ...\\)" #: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.run_simulation.run_simulation:1 of +#, fuzzy msgid "Run a Flower App using the Simulation Engine." -msgstr "" +msgstr "使用模拟引擎运行花朵应用程序。" #: ../../source/ref-api/flwr.simulation.run_simulation.rst:2 #, fuzzy @@ -15849,36 +16263,46 @@ msgid "run\\_simulation" msgstr "运行模拟" #: flwr.simulation.run_simulation.run_simulation:3 of +#, fuzzy msgid "" "The `ServerApp` to be executed. It will send messages to different " "`ClientApp` instances running on different (virtual) SuperNodes." -msgstr "" +msgstr "要执行的 `ServerApp`。它将向运行在不同(虚拟)超级节点上的不同 " +"`ClientApp`实例发送消息。" #: flwr.simulation.run_simulation.run_simulation:6 of +#, fuzzy msgid "" "The `ClientApp` to be executed by each of the SuperNodes. It will receive" " messages sent by the `ServerApp`." -msgstr "" +msgstr "由每个超级节点执行的 `ClientApp`。它将接收由 `ServerApp` 发送的信息。" #: flwr.simulation.run_simulation.run_simulation:9 of +#, fuzzy msgid "" "Number of nodes that run a ClientApp. They can be sampled by a Driver in " "the ServerApp and receive a Message describing what the ClientApp should " "perform." -msgstr "" +msgstr "运行 ClientApp 的节点数。它们可被 ServerApp 中的驱动程序采样,并接收描述 " +"ClientApp 应执行的操作的信息。" #: flwr.simulation.run_simulation.run_simulation:13 of +#, fuzzy msgid "A simulation backend that runs `ClientApp`s." -msgstr "" +msgstr "运行 \"客户端应用程序 \"的模拟后台。" #: flwr.simulation.run_simulation.run_simulation:15 of +#, fuzzy msgid "" "'A dictionary, e.g {\"\": , \"\": } to " "configure a backend. Values supported in are those included by " "`flwr.common.typing.ConfigsRecordValues`." msgstr "" +"字典,例如 {\"\": , \"\": } 来配置后端。 " +"中支持的值是 `flwr.common.typing.ConfigsRecordValues`中包含的值。" #: flwr.simulation.run_simulation.run_simulation:19 of +#, fuzzy msgid "" "A boolean to indicate whether to enable GPU growth on the main thread. " "This is desirable if you make use of a TensorFlow model on your " @@ -15888,12 +16312,20 @@ msgid "" "`tf.config.experimental.set_memory_growth()` works in the TensorFlow " "documentation: https://www.tensorflow.org/api/stable." msgstr "" +"布尔值,用于指示是否在主线程上启用 GPU 增长。如果您在 \"ServerApp \"上使用 " +"TensorFlow 模型,同时让 \"ClientApp \"在同一 GPU " +"上运行,则最好启用此选项。如果不启用此功能,您可能会遇到内存不足的错误,因为 " +"TensorFlow 默认会分配所有 GPU 内存。有关 `tf.config.experimental." +"set_memory_growth()` 如何工作的更多信息,请参阅 TensorFlow 文档:https://www." +"tensorflow.org/api/stable。" #: flwr.simulation.run_simulation.run_simulation:26 of +#, fuzzy msgid "" "When diabled, only INFO, WARNING and ERROR log messages will be shown. If" " enabled, DEBUG-level logs will be displayed." -msgstr "" +msgstr "启用后,将只显示 INFO、WARNING 和 ERROR 日志信息。启用后,将显示 DEBUG " +"级日志。" #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 #, fuzzy @@ -16109,6 +16541,7 @@ msgstr "" "TOKEN_v1.5.0-->" #: ../../source/ref-changelog.md:21 +#, fuzzy msgid "" "**Introduce Flower Next high-level API (stable)** " "([#3002](https://github.com/adap/flower/pull/3002), " @@ -16137,8 +16570,27 @@ msgid "" "[#3195](https://github.com/adap/flower/pull/3195), " "[#3197](https://github.com/adap/flower/pull/3197))" msgstr "" +"**介绍 Flower Next 高级应用程序接口(稳定版)** ([#3002](https://github.com/" +"adap/flower/pull/3002), [#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), [#3173](https://github." +"com/adap/flower/pull/3173), [#3174](https://github.com/adap/flower/pull/3174)" +", [#2923](https://github.com/adap/flower/pull/2923), [#2691](https://github." +"com/adap/flower/pull/2691), [#3079](https://github.com/adap/flower/pull/3079)" +", [#2961](https://github.com/adap/flower/pull/2961), [#2924](https://github." +"com/adap/flower/pull/2924), [#3166](https://github.com/adap/flower/pull/3166)" +", [#3031](https://github.com/adap/flower/pull/3031), [#3057](https://github." +"com/adap/flower/pull/3057), [#3000](https://github.com/adap/flower/pull/3000)" +", [#3113](https://github.com/adap/flower/pull/3113), [#2957](https://github." +"com/adap/flower/pull/2957), [#3183](https://github.com/adap/flower/pull/3183)" +", [#3180](https://github.com/adap/flower/pull/3180), [#3035](https://github." +"com/adap/flower/pull/3035), [#3189](https://github.com/adap/flower/pull/3189)" +", [#3185](https://github.com/adap/flower/pull/3185), [#3190](https://github." +"com/adap/flower/pull/3190), [#3191](https://github.com/adap/flower/pull/3191)" +", [#3195](https://github.com/adap/flower/pull/3195), [#3197](https://github." +"com/adap/flower/pull/3197))" #: ../../source/ref-changelog.md:23 +#, fuzzy msgid "" "The Flower Next high-level API is stable! Flower Next is the future of " "Flower - all new features (like Flower Mods) will be built on top of it. " @@ -16151,6 +16603,13 @@ msgid "" " line of code. The best part? It's fully compatible with existing Flower " "projects that use `Strategy`, `NumPyClient` & co." msgstr "" +"Flower Next 高级应用程序接口已经稳定!Flower Next 是 Flower 的未来 - " +"所有新功能(如 Flower Mods)都将构建在它之上。您可以使用 `ServerApp` 和 " +"`ClientApp` 开始将现有项目迁移到 Flower Next(请查看 `quickstart-pytorch` 或 " +"`quickstart-tensorflow` ,详细的迁移指南将在不久后发布)。Flower Next 允许您" +"同时运行多个项目(我们称之为多重运行),并在模拟环境或部署环境中执行同一项目" +",而无需更改任何代码。最棒的是什么?它与使用 `Strategy`、`NumPyClient` " +"等的现有 Flower 项目完全兼容。" #: ../../source/ref-changelog.md:25 #, fuzzy @@ -16165,6 +16624,7 @@ msgstr "" "[#2493](https://github.com/adap/flower/pull/2493))" #: ../../source/ref-changelog.md:27 +#, fuzzy msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " "`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " @@ -16180,6 +16640,15 @@ msgid "" "metrics, stateful computations on the client node and implementations of " "custom SMPC protocols, to name just a few." msgstr "" +"除了使用 \"Strategy\"、\"NumPyClient \"等的 Flower Next 高级应用程序接口外," +"Flower 1.8 还提供了新的 Flower Next 低级应用程序接口的预览版。低级应用程序接" +"口允许通过向/从客户端节点发送/接收单个消息,对学习过程的各个方面进行细粒度控" +"制。新的 \"ServerApp \"支持注册一个自定义的 \"main \"函数" +",允许为异步FL、循环训练或联合分析等方法编写自定义训练循环。新的 \"ClientApp " +"\"支持注册 \"训练\"、\"评估 \"和 \"查询 \"函数,这些函数可以访问从 " +"\"ServerApp \"接收到的原始信息。新的抽象(如 \"RecordSet\"、\"Message \"和 " +"\"Context\")进一步支持发送多个模型、多套配置值和指标、" +"客户端节点上的有状态计算以及自定义 SMPC 协议的实现等。" #: ../../source/ref-changelog.md:29 #, fuzzy @@ -16194,6 +16663,7 @@ msgstr "" "[#2248](https://github.com/adap/flower/pull/2248))" #: ../../source/ref-changelog.md:31 +#, fuzzy msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " "edit or handle them directly. Mods can be used to develop pluggable " @@ -16204,6 +16674,11 @@ msgid "" "SecAgg+. The Flower Mods API is released as a preview, but researchers " "can already use it to experiment with arbirtrary SMPC protocols." msgstr "" +"Flower Modifiers(我们称之为 Mods)可以拦截信息,并直接对其进行分析、编辑或处" +"理。修改器可用于开发可在不同项目中使用的可插拔模块。Flower 1.8 已经包含了记录" +"信息大小、通过网络发送的参数数量、固定剪切和自适应剪切的差分隐私、" +"本地差分隐私以及安全聚合协议 SecAgg 和 SecAgg+ 的 Mods。Flower Mods API " +"作为预览版发布,但研究人员已经可以用它来试验任意的 SMPC 协议。" #: ../../source/ref-changelog.md:33 #, fuzzy @@ -16225,6 +16700,7 @@ msgstr "" "[#1475](https://github.com/adap/flower/pull/1475)))" #: ../../source/ref-changelog.md:35 +#, fuzzy msgid "" "We are introducing LLM FlowerTune, an introductory example that " "demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " @@ -16233,6 +16709,12 @@ msgid "" "Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" "-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" +"我们将介绍 LLM FlowerTune,这是一个介绍性示例,演示了在 Alpaca-GPT4 " +"数据集上对预先训练好的 Llama2 模型进行联合 LLM " +"微调。该示例可轻松调整以使用不同的模型和/或数据集。请阅读我们的博文 [LLM " +"FlowerTune: Federated LLM Fine-tuning with Flower](https://flower.ai/blog/" +"2024-03-14-llm-flowertune-federated-llm-finetuning-with-flower/) " +"了解更多详情。" #: ../../source/ref-changelog.md:37 #, fuzzy @@ -16256,6 +16738,7 @@ msgstr "" "[#994](https://github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:39 +#, fuzzy msgid "" "Built-in Differential Privacy is here! Flower supports both central and " "local differential privacy (DP). Central DP can be configured with either" @@ -16267,6 +16750,13 @@ msgid "" "the new Differential Privacy components](https://flower.ai/docs/framework" "/how-to-use-differential-privacy.html) in Flower." msgstr "" +"内置差分保密功能!Flower 支持中央和本地差分保密 " +"(DP)。中央差分隐私可配置为固定或自适应剪切。剪切可以发生在服务器端或客户端。" +"本地 DP " +"在客户端进行剪切和噪声处理。新的文档页面[解释差分隐私方法](https://flower.ai/" +"docs/framework/explanation-differential-privacy.html) " +"和新的操作指南[如何使用新的差分隐私组件](https://flower.ai/docs/framework/" +"how-to-use-differential-privacy.html) 介绍了 Flower 的使用方法。" #: ../../source/ref-changelog.md:41 #, fuzzy @@ -16281,6 +16771,7 @@ msgstr "" "[#2248](https://github.com/adap/flower/pull/2248))" #: ../../source/ref-changelog.md:43 +#, fuzzy msgid "" "Built-in Secure Aggregation is here! Flower now supports different secure" " aggregation protocols out-of-the-box. The best part? You can add secure " @@ -16292,6 +16783,12 @@ msgid "" "combine Federated Learning, Differential Privacy and Secure Aggregation " "in the same project." msgstr "" +"内置安全聚合功能!Flower " +"现在支持不同的安全聚合协议。最棒的是什么?只需几行代码," +"您就可以将安全聚合添加到 Flower 项目中。在这个初始版本中,我们包含了对 " +"SecAgg 和 SecAgg+ 的支持,但更多协议将很快实现。我们还将添加详细的文档," +"解释安全聚合以及如何在 Flower 中使用它。您可以查看新的代码示例,了解如何使用 " +"Flower 在同一项目中轻松结合联合学习、差分隐私和安全聚合。" #: ../../source/ref-changelog.md:45 #, fuzzy @@ -16315,10 +16812,12 @@ msgstr "" "[#2171](https://github.com/adap/flower/pull/2171))" #: ../../source/ref-changelog.md:47 +#, fuzzy msgid "" "A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" " and then running them using the Simulation Engine (`flwr run`)." -msgstr "" +msgstr "新的 `flwr` CLI 命令允许创建新的 Flower 项目(`flwr " +"new`),然后使用仿真引擎运行它们(`flwr run`)。" #: ../../source/ref-changelog.md:49 #, fuzzy @@ -16344,11 +16843,14 @@ msgstr "" "[#1733](https://github.com/adap/flower/pull/1733))" #: ../../source/ref-changelog.md:51 +#, fuzzy msgid "" "The Flower Simulation Engine can now run Flower Next projects. For " "notebook environments, there's also a new `run_simulation` function that " "can run `ServerApp` and `ClientApp`." msgstr "" +"Flower 模拟引擎现在可以运行 Flower Next 项目。对于笔记本环境,还有一个新的 " +"`run_simulation` 函数,可以运行 `ServerApp` 和 `ClientApp`。" #: ../../source/ref-changelog.md:53 #, fuzzy @@ -16358,6 +16860,7 @@ msgid "" msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" #: ../../source/ref-changelog.md:55 +#, fuzzy msgid "" "A SuperNode will now try to reconnect indefinitely to the SuperLink in " "case of connection errors. The arguments `--max-retries` and `--max-wait-" @@ -16367,6 +16870,10 @@ msgid "" "wait-time` defines the time before the SuperNode gives up trying to " "reconnect to the SuperLink." msgstr "" +"如果出现连接错误,超级节点现在会尝试无限期地重新连接超级链接。现在可以向 " +"`flower-client-app` 命令传递参数 `-ax-retries` 和 `-max-wait-time`。" +"最大重试次数 \"将定义客户端在放弃重新连接超级链接之前的重试次数,而 " +"\"最大等待时间 \"则定义超级节点放弃重新连接超级链接之前的等待时间。" #: ../../source/ref-changelog.md:57 #, fuzzy @@ -16384,12 +16891,16 @@ msgstr "" "[#1679](https://github.com/adap/flower/pull/1679)" #: ../../source/ref-changelog.md:59 +#, fuzzy msgid "" "There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " "baseline. Several other baselined have been updated as well." msgstr "" +"有一条新的 [FedStar](https://flower.ai/docs/baselines/fedstar.html) " +"基准线。其他几条基准线也已更新。" #: ../../source/ref-changelog.md:61 +#, fuzzy msgid "" "**Improve documentation and translations** " "([#3050](https://github.com/adap/flower/pull/3050), " @@ -16409,13 +16920,29 @@ msgid "" "[#2990](https://github.com/adap/flower/pull/2990), " "[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" +"**改进文件和翻译** ([#3050](https://github.com/adap/flower/pull/3050), " +"[#3044](https://github.com/adap/flower/pull/3044), [#3043](https://github." +"com/adap/flower/pull/3043), [#2986](https://github.com/adap/flower/pull/2986)" +", [#3041](https://github.com/adap/flower/pull/3041), [#3046](https://github." +"com/adap/flower/pull/3046), [#3042](https://github.com/adap/flower/pull/3042)" +", [#2978](https://github.com/adap/flower/pull/2978), [#2952](https://github." +"com/adap/flower/pull/2952), [#3167](https://github.com/adap/flower/pull/3167)" +", [#2953](https://github.com/adap/flower/pull/2953), [#3045](https://github." +"com/adap/flower/pull/3045), [#2654](https://github.com/adap/flower/pull/2654)" +", [#3082](https://github.com/adap/flower/pull/3082), [#2990](https://github." +"com/adap/flower/pull/2990), [#2989](https://github.com/adap/flower/pull/" +"2989))" #: ../../source/ref-changelog.md:63 +#, fuzzy msgid "" "As usual, we merged many smaller and larger improvements to the " "documentation. A special thank you goes to [Sebastian van der " "Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" +"像往常一样,我们合并了许多对文档的较大和较小的改进。特别要感谢 [Sebastian " +"van der Voort](https://github.com/svdvoort),他为我们带来了一份重要的文档 " +"PR!" #: ../../source/ref-changelog.md:65 #, fuzzy @@ -16444,6 +16971,7 @@ msgstr "" "[#1515](https://github.com/adap/flower/pull/1515))" #: ../../source/ref-changelog.md:67 +#, fuzzy msgid "" "Two new examples show federated training of a Vision Transformer (ViT) " "and federated learning in a medical context using the popular MONAI " @@ -16451,8 +16979,13 @@ msgid "" " new Flower Next `ServerApp` and `ClientApp`. Many other examples " "received considerable updates as well." msgstr "" +"两个新示例展示了视觉转换器(ViT)的联合训练,以及使用流行的 MONAI " +"库在医疗环境中进行的联合学习。quickstart-pytorch \"和 \"quickstart-" +"tensorflow \"展示了新的 Flower Next \"ServerApp \"和 \"ClientApp\"" +"。许多其他示例也得到了大量更新。" #: ../../source/ref-changelog.md:69 +#, fuzzy msgid "" "**General improvements** " "([#3171](https://github.com/adap/flower/pull/3171), " @@ -16529,6 +17062,56 @@ msgid "" "[#2955](https://github.com/adap/flower/pull/2955), " "[#2954](https://github.com/adap/flower/pull/2954))" msgstr "" +"**一般改进**([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), [3003](https://github.com/" +"adap/flower/pull/3003), [3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), [3085](https://github.com/" +"adap/flower/pull/3085), [3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), [2991](https://github.com/" +"adap/flower/pull/2991), [2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), [3086](https://github.com/" +"adap/flower/pull/3086), [2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), [2941](https://github.com/" +"adap/flower/pull/2941), [2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), [2973](https://github.com/" +"adap/flower/pull/2973), [2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), [3040](https://github.com/" +"adap/flower/pull/3040), [3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), [2902](https://github.com/" +"adap/flower/pull/2902), [2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), [3132](https://github.com/" +"adap/flower/pull/3132), [3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), [3064](https://github.com/" +"adap/flower/pull/3064), [3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), [3178](https://github.com/" +"adap/flower/pull/3178), [2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), [3091](https://github.com/" +"adap/flower/pull/3091), [3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), [3013](https://github.com/" +"adap/flower/pull/3013), [3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), [3068](https://github.com/" +"adap/flower/pull/3068), [2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), [2984](https://github.com/" +"adap/flower/pull/2984), [2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), [3143](https://github.com/" +"adap/flower/pull/3143), [2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), [2927](https://github.com/" +"adap/flower/pull/2927), [2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), [2912](https://github.com/" +"adap/flower/pull/2912), [3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), [2922](https://github.com/" +"adap/flower/pull/2922), [2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), [3179](https://github.com/" +"adap/flower/pull/3179), [3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), [3187](https://github.com/" +"adap/flower/pull/3187), [2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), [3144](https://github.com/" +"adap/flower/pull/3144), [3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), [#2836](https://github." +"com/adap/flower/pull/2836), [#2929](https://github.com/adap/flower/pull/2929)" +", [#2943](https://github.com/adap/flower/pull/2943), [#2955](https://github." +"com/adap/flower/pull/2955), [#2954](https://github.com/adap/flower/pull/" +"2954))" #: ../../source/ref-changelog.md:75 #, fuzzy @@ -16568,6 +17151,7 @@ msgstr "" "[#2435](https://github.com/adap/flower/pull/2435))" #: ../../source/ref-changelog.md:87 +#, fuzzy msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " @@ -16579,6 +17163,12 @@ msgid "" "different rounds of execution to enable stateful computations in a " "unified way across simulation and deployment." msgstr "" +"客户端 \"和 \"NumPyClient \"的子类现在可以存储保留在客户端上的本地状态" +"。让我们先从亮点开始:这一新功能与模拟客户端(通过 " +"`start_simulation`)和网络客户端(通过 `start_client`)兼容。这也是 `Context`" +" 和 `RecordSet` 等新抽象的首次预览。客户端可以通过 `state.RecordSet` 访问 " +"`RecordSet` 类型的状态: RecordSet = self.context.state`。对该 `RecordSet` " +"的更改会在不同轮执行中保留,以便在模拟和部署中以统一的方式进行有状态计算。" #: ../../source/ref-changelog.md:89 #, fuzzy @@ -16588,6 +17178,7 @@ msgid "" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" #: ../../source/ref-changelog.md:91 +#, fuzzy msgid "" "Flower is faster than ever. All `FedAvg`-derived strategies now use in-" "place aggregation to reduce memory consumption. The Flower client " @@ -16595,6 +17186,9 @@ msgid "" "which results in significant speedups, especially when the client-side " "training time is short." msgstr "" +"Flower 的速度比以往更快。所有源于 `FedAvg` " +"的策略现在都使用就地聚合,以减少内存消耗。Flower 客户端序列化/解序列化已从头" +"开始重写,从而显著提高了速度,尤其是在客户端训练时间较短的情况下。" #: ../../source/ref-changelog.md:93 #, fuzzy @@ -16606,11 +17200,14 @@ msgstr "" "([#1598](https://github.com/adap/flower/pull/1598))" #: ../../source/ref-changelog.md:95 +#, fuzzy msgid "" "Flower has official support for federated learning using [Apple " "MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " "example." msgstr "" +"通过新的 `quickstart-mlx` 代码示例,Flower 正式支持使用 [Apple MLX](https" +"://ml-explore.github.io/mlx)的联合学习。" #: ../../source/ref-changelog.md:97 #, fuzzy @@ -16623,6 +17220,7 @@ msgstr "" "[#1764](https://github.com/adap/flower/pull/1764))" #: ../../source/ref-changelog.md:99 +#, fuzzy msgid "" "A new strategy called `FedXgbCyclic` supports a client-by-client style of" " training (often called cyclic). The `xgboost-comprehensive` code example" @@ -16630,6 +17228,10 @@ msgid "" "comprehensive` now also supports simulation mode. With this, Flower " "offers best-in-class XGBoost support." msgstr "" +"名为 `FedXgbCyclic` 的新策略支持逐个客户端的训练风格(通常称为循环" +")。xgboost-comprehensive \"代码示例展示了如何在一个完整的项目中使用它" +"。除此之外,`xgboost-comprehensive` 现在还支持模拟模式。由此,Flower " +"提供了同类最佳的 XGBoost 支持。" #: ../../source/ref-changelog.md:101 #, fuzzy @@ -16639,10 +17241,12 @@ msgid "" msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" #: ../../source/ref-changelog.md:103 +#, fuzzy msgid "" "Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " "ensure better support for users using more recent Python versions." -msgstr "" +msgstr "框架测试现在可在 Python 3.8、3.9、3.10 和 3.11 上运行。这将确保为使用最新 " +"Python 版本的用户提供更好的支持。" #: ../../source/ref-changelog.md:105 #, fuzzy @@ -16654,10 +17258,11 @@ msgstr "" "([#2283](https://github.com/adap/flower/pull/2283))" #: ../../source/ref-changelog.md:107 +#, fuzzy msgid "" "The `grpcio` and `protobuf` dependencies were updated to their latest " "versions for improved security and performance." -msgstr "" +msgstr "为提高安全性和性能,\"grpcio \"和 \"protobuf \"依赖项已更新至最新版本。" #: ../../source/ref-changelog.md:109 #, fuzzy @@ -16681,12 +17286,16 @@ msgstr "" "[#994](https://github.com/adap/flower/pull/994))" #: ../../source/ref-changelog.md:111 +#, fuzzy msgid "" "The Flower server can now be run using an official Docker image. A new " "how-to guide explains [how to run Flower using " "Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" "docker.html). An official Flower client Docker image will follow." msgstr "" +"现在可以使用官方 Docker 映像运行 Flower 服务器了。新的操作指南介绍了 [" +"如何使用 Docker 运行 Flower](https://flower.ai/docs/framework/how-to-run-" +"flower-using-docker.html)。Flower 客户端 Docker 官方镜像将随后发布。" #: ../../source/ref-changelog.md:113 #, fuzzy @@ -16726,10 +17335,12 @@ msgstr "" "[#1310](https://github.com/adap/flower/pull/1310)" #: ../../source/ref-changelog.md:121 +#, fuzzy msgid "" "Several code examples were updated to use [Flower " "Datasets](https://flower.ai/docs/datasets/)." -msgstr "" +msgstr "更新了多个代码示例,以使用 [Flower Datasets](https://flower.ai/docs/datasets/" +") 。" #: ../../source/ref-changelog.md:123 #, fuzzy @@ -16757,8 +17368,9 @@ msgstr "" "[#1794](https://github.com/adap/flower/pull/1794))" #: ../../source/ref-changelog.md:125 +#, fuzzy msgid "Many Flower code examples received substantial updates." -msgstr "" +msgstr "许多 \"Flower \"代码示例得到了大幅更新。" #: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 msgid "**Update Flower Baselines**" @@ -16818,6 +17430,7 @@ msgstr "" "[#1614](https://github.com/adap/flower/pull/1614)))" #: ../../source/ref-changelog.md:138 +#, fuzzy msgid "" "**Improved testing and development infrastructure** " "([#2797](https://github.com/adap/flower/pull/2797), " @@ -16850,12 +17463,34 @@ msgid "" "[#2661](https://github.com/adap/flower/pull/2661), " "[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" +"**改进测试和开发基础设施** ([#2797](https://github.com/adap/flower/pull/2797)" +", [#2676](https://github.com/adap/flower/pull/2676), [#2644](https://github." +"com/adap/flower/pull/2644), [#2656](https://github.com/adap/flower/pull/2656)" +", [#2848](https://github.com/adap/flower/pull/2848), [#2675](https://github." +"com/adap/flower/pull/2675), [#2735](https://github.com/adap/flower/pull/2735)" +", [#2767](https://github.com/adap/flower/pull/2767), [#2732](https://github." +"com/adap/flower/pull/2732), [#2744](https://github.com/adap/flower/pull/2744)" +", [#2681](https://github.com/adap/flower/pull/2681), [#2699](https://github." +"com/adap/flower/pull/2699), [#2745](https://github.com/adap/flower/pull/2745)" +", [#2734](https://github.com/adap/flower/pull/2734), [#2731](https://github." +"com/adap/flower/pull/2731), [#2652](https://github.com/adap/flower/pull/2652)" +", [#2720](https://github.com/adap/flower/pull/2720), [#2721](https://github." +"com/adap/flower/pull/2721), [#2717](https://github.com/adap/flower/pull/2717)" +", [#2864](https://github.com/adap/flower/pull/2864), [#2694](https://github." +"com/adap/flower/pull/2694), [#2709](https://github.com/adap/flower/pull/2709)" +", [#2658](https://github.com/adap/flower/pull/2658), [#2796](https://github." +"com/adap/flower/pull/2796), [#2692](https://github.com/adap/flower/pull/2692)" +", [#2657](https://github.com/adap/flower/pull/2657), [#2813](https://github." +"com/adap/flower/pull/2813), [#2661](https://github.com/adap/flower/pull/2661)" +", [#2398](https://github.com/adap/flower/pull/2398))" #: ../../source/ref-changelog.md:140 +#, fuzzy msgid "" "The Flower testing and development infrastructure has received " "substantial updates. This makes Flower 1.7 the most tested release ever." -msgstr "" +msgstr "Flower 测试和开发基础架构已得到大幅更新。这使得 Flower 1.7 " +"成为有史以来经过最多测试的版本。" #: ../../source/ref-changelog.md:142 #, fuzzy @@ -16894,6 +17529,7 @@ msgstr "" "[#2183](https://github.com/adap/flower/pull/2183))" #: ../../source/ref-changelog.md:144 +#, fuzzy msgid "" "**General improvements** " "([#2803](https://github.com/adap/flower/pull/2803), " @@ -16933,6 +17569,31 @@ msgid "" "[#2672](https://github.com/adap/flower/pull/2672), " "[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" +"**一般改进** ([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." +"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/pull/2690)" +", [#2889](https://github.com/adap/flower/pull/2889), [#2874](https://github." +"com/adap/flower/pull/2874), [#2819](https://github.com/adap/flower/pull/2819)" +", [#2689](https://github.com/adap/flower/pull/2689), [#2457](https://github." +"com/adap/flower/pull/2457), [#2870](https://github.com/adap/flower/pull/2870)" +", [#2669](https://github.com/adap/flower/pull/2669), [#2876](https://github." +"com/adap/flower/pull/2876), [#2885](https://github.com/adap/flower/pull/2885)" +", [#2858](https://github.com/adap/flower/pull/2858), [#2867](https://github." +"com/adap/flower/pull/2867), [#2351](https://github.com/adap/flower/pull/2351)" +", [#2886](https://github.com/adap/flower/pull/2886), [#2860](https://github." +"com/adap/flower/pull/2860), [#2828](https://github.com/adap/flower/pull/2828)" +", [#2869](https://github.com/adap/flower/pull/2869), [#2875](https://github." +"com/adap/flower/pull/2875), [#2733](https://github.com/adap/flower/pull/2733)" +", [#2488](https://github.com/adap/flower/pull/2488), [#2646](https://github." +"com/adap/flower/pull/2646), [#2879](https://github.com/adap/flower/pull/2879)" +", [#2821](https://github.com/adap/flower/pull/2821), [#2855](https://github." +"com/adap/flower/pull/2855), [#2800](https://github.com/adap/flower/pull/2800)" +", [#2807](https://github.com/adap/flower/pull/2807), [#2801](https://github." +"com/adap/flower/pull/2801), [#2804](https://github.com/adap/flower/pull/2804)" +", [#2851](https://github.com/adap/flower/pull/2851), [#2787](https://github." +"com/adap/flower/pull/2787), [#2852](https://github.com/adap/flower/pull/2852)" +", [#2672](https://github.com/adap/flower/pull/2672), [#2759](https://github." +"com/adap/flower/pull/2759))" #: ../../source/ref-changelog.md:148 #, fuzzy @@ -16945,6 +17606,7 @@ msgstr "" "[#2508](https://github.com/adap/flower/pull/2508))" #: ../../source/ref-changelog.md:150 +#, fuzzy msgid "" "Until now, clients of type `NumPyClient` needed to be started via " "`start_numpy_client`. In our efforts to consolidate framework APIs, we " @@ -16954,6 +17616,11 @@ msgid "" "object to `start_client`. The examples and the documentation have been " "updated accordingly." msgstr "" +"到目前为止,\"NumPyClient \"类型的客户端需要通过 \"start_numpy_client \"启动" +"。为了整合框架 API,我们引入了一些变化,现在所有客户端类型都应通过 " +"`start_client` 启动。要继续使用 `NumPyClient` 客户端,只需首先调用 `." +"to_client()` 方法,然后将返回的 `Client` 对象传递给 " +"`start_client`。示例和文档已相应更新。" #: ../../source/ref-changelog.md:152 #, fuzzy @@ -16963,11 +17630,13 @@ msgid "" msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" #: ../../source/ref-changelog.md:154 +#, fuzzy msgid "" "Legacy DP wrapper classes are deprecated, but still functional. This is " "in preparation for an all-new pluggable version of differential privacy " "support in Flower." -msgstr "" +msgstr "传统的 DP 封装类已废弃,但仍可正常使用。这是为 Flower " +"中的全新可插拔差分隐私支持版本做准备。" #: ../../source/ref-changelog.md:156 #, fuzzy @@ -16998,11 +17667,14 @@ msgstr "" "[#2615](https://github.com/adap/flower/pull/2615))" #: ../../source/ref-changelog.md:162 +#, fuzzy msgid "" "Experimental fields `sa`, `legacy_server_message` and " "`legacy_client_message` were removed from `Task` message. The removed " "fields are superseded by the new `RecordSet` abstraction." msgstr "" +"从 `Task` 消息中删除了试验性字段 `sa`、 `legacy_server_message` 和 " +"`legacy_client_message`。删除的字段已被新的 `RecordSet` 抽象所取代。" #: ../../source/ref-changelog.md:164 #, fuzzy @@ -17012,11 +17684,14 @@ msgid "" msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" #: ../../source/ref-changelog.md:166 +#, fuzzy msgid "" "The development of the MXNet fremework has ended and the project is now " "[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " "examples won't receive updates." msgstr "" +"MXNet fremework 的开发工作已经结束,该项目现已[归档于 GitHub](https://github." +"com/apache/mxnet)。现有的 MXNet 示例不会收到更新。" #: ../../source/ref-changelog.md:168 #, fuzzy @@ -17024,6 +17699,7 @@ msgid "v1.6.0 (2023-11-28)" msgstr "v1.4.0 (2023-04-21)" #: ../../source/ref-changelog.md:174 +#, fuzzy msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " @@ -17032,6 +17708,12 @@ msgid "" "`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " "`cnxdeveloper`, `k3nfalt` " msgstr "" +"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, `" +"Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel Mota`" +", `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, `Navin " +"Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " +"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " +"`k3nfalt` " #: ../../source/ref-changelog.md:178 msgid "" @@ -17061,10 +17743,13 @@ msgstr "" "[#1567](https://github.com/adap/flower/pull/1567))" #: ../../source/ref-changelog.md:182 +#, fuzzy msgid "" "We have added a new `xgboost-quickstart` example alongside a new " "`xgboost-comprehensive` example that goes more in-depth." msgstr "" +"我们添加了一个新的 \"xgboost-quickstart \"示例和一个新的 \"xgboost-" +"comprehensive \"示例,后者更加深入。" #: ../../source/ref-changelog.md:184 #, fuzzy @@ -17074,12 +17759,16 @@ msgid "" msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" #: ../../source/ref-changelog.md:186 +#, fuzzy msgid "" "We had many questions about Vertical Federated Learning using Flower, so " "we decided to add an simple example for it on the [Titanic " "dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " "tutorial (in the README)." msgstr "" +"我们收到了许多关于使用 Flower 进行垂直联合学习的问题,因此我们决定在 [" +"Titanic 数据集](https://www.kaggle.com/competitions/titanic/data) " +"上添加一个简单的示例,并附上教程(在 README 中)。" #: ../../source/ref-changelog.md:188 msgid "" @@ -17138,6 +17827,7 @@ msgstr "" "[#2400](https://github.com/adap/flower/pull/2400)" #: ../../source/ref-changelog.md:202 +#, fuzzy msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " "passing `--certificates`, but users can enable `--insecure` to use HTTP " @@ -17146,13 +17836,21 @@ msgid "" "an HTTPS-enabled server or requires opt-out via passing `--insecure` to " "enable insecure HTTP connections." msgstr "" +"Flower 默认使用 HTTPS。新的 \"flower-server \"需要通过\"--证书\"," +"但用户可以启用\"--不安全 \"来使用 HTTP 进行原型开发。这同样适用于 `flower-" +"client`,它可以使用用户提供的凭证或 gRPC 绑定证书连接到支持 HTTPS 的服务器," +"也可以通过传递 `--insecure`来启用不安全的 HTTP 连接。" #: ../../source/ref-changelog.md:204 +#, fuzzy msgid "" "For backward compatibility, `start_client()` and `start_numpy_client()` " "will still start in insecure mode by default. In a future release, " "insecure connections will require user opt-in by passing `insecure=True`." msgstr "" +"为了向后兼容,`start_client()` 和 `start_numpy_client()` " +"默认仍以不安全模式启动。在未来的版本中,不安全连接将需要用户通过传递 " +"`insecure=True` 进行选择。" #: ../../source/ref-changelog.md:206 msgid "" @@ -17355,6 +18053,7 @@ msgstr "" "[#1475](https://github.com/adap/flower/pull/1475)))" #: ../../source/ref-changelog.md:254 +#, fuzzy msgid "" "**General improvements** " "([#2309](https://github.com/adap/flower/pull/2309), " @@ -17385,6 +18084,25 @@ msgid "" "[#2553](https://github.com/adap/flower/pull/2553), " "[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" +"**一般改进** ([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." +"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/pull/2316)" +", [#2317](https://github.com/adap/flower/pull/2317), [#2349](https://github." +"com/adap/flower/pull/2349), [#2360](https://github.com/adap/flower/pull/2360)" +", [#2402](https://github.com/adap/flower/pull/2402), [#2446](https://github." +"com/adap/flower/pull/2446), [#2561](https://github.com/adap/flower/pull/2561)" +", [#2273](https://github.com/adap/flower/pull/2273), [#2267](https://github." +"com/adap/flower/pull/2267), [#2274](https://github.com/adap/flower/pull/2274)" +", [#2275](https://github.com/adap/flower/pull/2275), [#2432](https://github." +"com/adap/flower/pull/2432), [#2251](https://github.com/adap/flower/pull/2251)" +", [#2321](https://github.com/adap/flower/pull/2321), [#1936](https://github." +"com/adap/flower/pull/1936), [#2408](https://github.com/adap/flower/pull/2408)" +", [#2413](https://github.com/adap/flower/pull/2413), [#2401](https://github." +"com/adap/flower/pull/2401), [#2531](https://github.com/adap/flower/pull/2531)" +", [#2534](https://github.com/adap/flower/pull/2534), [#2535](https://github." +"com/adap/flower/pull/2535), [#2521](https://github.com/adap/flower/pull/2521)" +", [#2553](https://github.com/adap/flower/pull/2553), [#2596](https://github." +"com/adap/flower/pull/2596))" #: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 #: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 @@ -22077,6 +22795,7 @@ msgstr "" "还需要导入几个软件包,如 Flower 和 scikit-learn:" #: ../../source/tutorial-quickstart-scikitlearn.rst:67 +#, fuzzy msgid "" "Prior to local training, we need to load the MNIST dataset, a popular " "image classification dataset of handwritten digits for machine learning, " @@ -22086,6 +22805,11 @@ msgid "" "training set for each partition ID defined in the :code:`--partition-id` " "argument." msgstr "" +"在本地训练之前,我们需要加载 MNIST " +"数据集(一个用于机器学习的流行手写数字图像分类数据集),并对数据集进行 FL " +"分区。使用 \"Flower Datasets `" +"_\"可以方便地实现这一点。:code:`FederatedDataset.load_partition()` 方法为 " +":code:`--partition-id` 参数中定义的每个分区 ID 加载分区训练集。" #: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" @@ -22667,6 +23391,7 @@ msgid "Cyclic training" msgstr "集中式训练" #: ../../source/tutorial-quickstart-xgboost.rst:605 +#, fuzzy msgid "" "In addition to bagging aggregation, we offer a cyclic training scheme, " "which performs FL in a client-by-client fashion. Instead of aggregating " @@ -22675,14 +23400,20 @@ msgid "" "XGBoost trees will be passed to the next client as an initialised model " "for next round's boosting." msgstr "" +"除了袋式聚合,我们还提供了一种循环训练方案,它以逐个客户端的方式执行 FL。在循" +"环训练方案中,每轮只有一个客户端参与训练,而不是多个客户端聚合在一起。" +"训练好的本地 XGBoost 树将传递给下一个客户端,作为下一轮提升的初始化模型。" #: ../../source/tutorial-quickstart-xgboost.rst:609 +#, fuzzy msgid "" "To do this, we first customise a :code:`ClientManager` in " ":code:`server_utils.py`:" -msgstr "" +msgstr "为此,我们首先要在 :code:`server_utils.py` 中自定义一个 " +":code:`ClientManager`:" #: ../../source/tutorial-quickstart-xgboost.rst:649 +#, fuzzy msgid "" "The customised :code:`ClientManager` samples all available clients in " "each FL round based on the order of connection to the server. Then, we " @@ -22691,19 +23422,29 @@ msgid "" "select only one client in given round and pass the received model to next" " client." msgstr "" +"定制的 :code:`ClientManager` 会根据连接服务器的顺序,在每轮 FL " +"中对所有可用客户端进行采样。然后,我们在 :code:`flwr.server.strategy." +"fedxgb_cyclic.py`\"中定义了一个新策略 :code:`FedXgbCyclic`,以便在给定回合中" +"按顺序只选择一个客户端,并将接收到的模型传递给下一个客户端。" #: ../../source/tutorial-quickstart-xgboost.rst:690 +#, fuzzy msgid "" "Unlike the original :code:`FedAvg`, we don't perform aggregation here. " "Instead, we just make a copy of the received client model as global model" " by overriding :code:`aggregate_fit`." msgstr "" +"与最初的 :code:`FedAvg` 不同,我们在这里不执行聚合。相反,我们只是通过覆盖 " +":code:`aggregate_fit` 将接收到的客户端模型复制为全局模型。" #: ../../source/tutorial-quickstart-xgboost.rst:693 +#, fuzzy msgid "" "Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" " methods ensure the clients to be sequentially selected given FL round:" msgstr "" +"此外,定制的 :code:`configure_fit` 和 :code:`configure_evaluate` " +"方法可确保在 FL 轮中按顺序选择客户:" #: ../../source/tutorial-quickstart-xgboost.rst:757 msgid "Customised data partitioning" @@ -22758,40 +23499,51 @@ msgid "Flower simulation" msgstr "运行模拟" #: ../../source/tutorial-quickstart-xgboost.rst:832 +#, fuzzy msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " "capabilities of Flower to simulate federated XGBoost training on either a" " single machine or a cluster of machines." msgstr "" +"我们还提供了一个示例代码(:code:`sim.py`),用于使用 Flower " +"的模拟功能在单台机器或机器集群上模拟联合 XGBoost 训练。" #: ../../source/tutorial-quickstart-xgboost.rst:866 +#, fuzzy msgid "" "After importing all required packages, we define a :code:`main()` " "function to perform the simulation process:" -msgstr "" +msgstr "导入所有需要的软件包后,我们定义了一个 :code:`main()` 函数来执行模拟程序:" #: ../../source/tutorial-quickstart-xgboost.rst:921 +#, fuzzy msgid "" "We first load the dataset and perform data partitioning, and the pre-" "processed data is stored in a :code:`list`. After the simulation begins, " "the clients won't need to pre-process their partitions again." -msgstr "" +msgstr "我们首先加载数据集并执行数据分区,预处理后的数据存储在 :code:`list` " +"中。模拟开始后,客户端就不需要再预处理分区了。" #: ../../source/tutorial-quickstart-xgboost.rst:924 +#, fuzzy msgid "Then, we define the strategies and other hyper-parameters:" -msgstr "" +msgstr "然后,我们定义策略和其他超参数:" #: ../../source/tutorial-quickstart-xgboost.rst:975 +#, fuzzy msgid "" "After that, we start the simulation by calling " ":code:`fl.simulation.start_simulation`:" -msgstr "" +msgstr "然后,我们调用 :code:`fl.simulation.start_simulation` 开始模拟:" #: ../../source/tutorial-quickstart-xgboost.rst:995 +#, fuzzy msgid "" "One of key parameters for :code:`start_simulation` is :code:`client_fn` " "which returns a function to construct a client. We define it as follows:" msgstr "" +":code:`start_simulation` 的一个关键参数是 " +":code:`client_fn`,它返回一个用于构建客户端的函数。我们将其定义如下:" #: ../../source/tutorial-quickstart-xgboost.rst:1038 msgid "Arguments parser" @@ -22832,12 +23584,14 @@ msgid "" msgstr "这定义了客户端数据分区的各种选项。此外,通过设置 :code:`-centralised-eval`,客户端还可以选择在集中测试集上进行评估。" #: ../../source/tutorial-quickstart-xgboost.rst:1148 +#, fuzzy msgid "We also have an argument parser for simulation:" -msgstr "" +msgstr "我们还有一个用于模拟的参数解析器:" #: ../../source/tutorial-quickstart-xgboost.rst:1226 +#, fuzzy msgid "This integrates all arguments for both client and server sides." -msgstr "" +msgstr "这整合了客户端和服务器端的所有参数。" #: ../../source/tutorial-quickstart-xgboost.rst:1229 msgid "Example commands" @@ -22856,8 +23610,9 @@ msgid "Then, on each client terminal, we start the clients:" msgstr "然后,我们在每个客户终端上启动客户机:" #: ../../source/tutorial-quickstart-xgboost.rst:1244 +#, fuzzy msgid "To run the same experiment with Flower simulation:" -msgstr "" +msgstr "运行与 Flower 模拟相同的实验:" #: ../../source/tutorial-quickstart-xgboost.rst:1250 #, fuzzy @@ -23562,12 +24317,16 @@ msgid "" msgstr "每个组织都将充当联邦学习系统中的客户端。因此,有十个组织参与联邦学习,就意味着有十个客户端连接到联邦学习服务器:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 +#, fuzzy msgid "" "Let's now create the Federated Dataset abstraction that from ``flwr-" "datasets`` that partitions the CIFAR-10. We will create small training " "and test set for each edge device and wrap each of them into a PyTorch " "``DataLoader``:" msgstr "" +"现在,让我们从 ``flwr-datasets`` 中创建 Federated Dataset 抽象,以分割 " +"CIFAR-10。我们将为每个边缘设备创建小型训练集和测试集,并将它们分别封装到 " +"PyTorch ``DataLoader`` 中:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 #, fuzzy @@ -24310,8 +25069,9 @@ msgid "" msgstr "在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可以是其他东西,比如经典的线性回归。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 +#, fuzzy msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" -msgstr "" +msgstr "|d8bf04f23d9b46d8a23cc6f4887d7873|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 msgid "Model and data" @@ -24325,8 +25085,9 @@ msgid "" msgstr "我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转录音频或玩围棋等游戏。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 +#, fuzzy msgid "|5aa1711387d74d0f8b9c499e1a51627e|" -msgstr "" +msgstr "|5aa1711387d74d0f8b9c499e1a51627e|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 msgid "Train model using data" @@ -24346,8 +25107,9 @@ msgid "" msgstr "它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键盘输入的接收,或者智能扬声器上某人试着唱的歌。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 +#, fuzzy msgid "|2bc8e069228d4873804061ff4a95048c|" -msgstr "" +msgstr "|2bc8e069228d4873804061ff4a95048c|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 msgid "Data on a phone" @@ -24364,8 +25126,9 @@ msgstr "" "\"通常不只是一个地方,而是很多地方。它可能是多个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 +#, fuzzy msgid "|c258488766324dc9a6807f0e7c4fd5f4|" -msgstr "" +msgstr "|c258488766324dc9a6807f0e7c4fd5f4|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 msgid "Data is on many devices" @@ -24380,8 +25143,9 @@ msgid "" msgstr "因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 +#, fuzzy msgid "|d5f962c3f4ec48529efda980868c14b0|" -msgstr "" +msgstr "|d5f962c3f4ec48529efda980868c14b0|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 msgid "Central data collection" @@ -24395,8 +25159,9 @@ msgid "" msgstr "一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模型。这就是我们基本上一直依赖的机器学习方法。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 +#, fuzzy msgid "|a5eccea18d4c43a68b54b65043cabef8|" -msgstr "" +msgstr "|a5eccea18d4c43a68b54b65043cabef8|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 msgid "Central model training" @@ -24415,8 +25180,9 @@ msgid "" msgstr "我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 +#, fuzzy msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" -msgstr "" +msgstr "|f17662f7df2d42f68cac70a1fdeda8a7|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 msgid "Centralized possible" @@ -24430,8 +25196,9 @@ msgid "" msgstr "但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器上的数据不足以训练出一个好的模型。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 +#, fuzzy msgid "|241fc906441a4f038c625a19d30d01b2|" -msgstr "" +msgstr "|241fc906441a4f038c625a19d30d01b2|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 msgid "Centralized impossible" @@ -24578,8 +25345,9 @@ msgid "" msgstr "我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前保存的检查点初始化模型参数。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 +#, fuzzy msgid "|0aa5aa05810b44b6a835cecce28f3137|" -msgstr "" +msgstr "|0aa5aa05810b44b6a835cecce28f3137|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 msgid "Initialize global model" @@ -24602,8 +25370,9 @@ msgid "" msgstr "接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户端节点会导致收益递减。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 +#, fuzzy msgid "|c742940dd4bf4de09d8d0d5e8d179638|" -msgstr "" +msgstr "|c742940dd4bf4de09d8d0d5e8d179638|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 msgid "Send global model" @@ -24628,8 +25397,9 @@ msgstr "" "(mini-batches)。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 +#, fuzzy msgid "|1f169ab4601a47e1a226f1628f4ebddb|" -msgstr "" +msgstr "|1f169ab4601a47e1a226f1628f4ebddb|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 msgid "Train on local data" @@ -24651,8 +25421,9 @@ msgid "" msgstr "经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同,是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练过程中积累的梯度。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 +#, fuzzy msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" -msgstr "" +msgstr "|12cfa9cde14440ecb8c8f6c1d7185bec|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 msgid "Send model updates" @@ -24697,8 +25468,9 @@ msgstr "" " 100 个示例的 10 倍。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 +#, fuzzy msgid "|72939caf6e294b0986fee6dde96614d7|" -msgstr "" +msgstr "|72939caf6e294b0986fee6dde96614d7|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 msgid "Aggregate model updates" @@ -24804,8 +25576,9 @@ msgstr "" "为联邦学习、分析和评估提供了一种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 +#, fuzzy msgid "|83a8daee45da4a98b8d6f24ae098fc50|" -msgstr "" +msgstr "|83a8daee45da4a98b8d6f24ae098fc50|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" @@ -26925,4 +27698,3 @@ msgstr "" #~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" - From 3ecf7518229d36c14da1057277189ba27d637b25 Mon Sep 17 00:00:00 2001 From: Daniel Nata Nugraha Date: Thu, 13 Jun 2024 18:42:46 +0200 Subject: [PATCH 064/124] refactor(framework) Refactor IP address format in SuperLink (#3583) --- src/py/flwr/server/app.py | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index cbb18b602fcd..1574ec46f968 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -200,15 +200,7 @@ def run_superlink() -> None: args = _parse_args_run_superlink().parse_args() # Parse IP address - parsed_driver_address = parse_address(args.driver_api_address) - if not parsed_driver_address: - sys.exit(f"Driver IP address ({args.driver_api_address}) cannot be parsed.") - driver_host, driver_port, driver_is_v6 = parsed_driver_address - driver_address = ( - f"[{driver_host}]:{driver_port}" - if driver_is_v6 - else f"{driver_host}:{driver_port}" - ) + driver_address, _, _ = _format_address(args.driver_api_address) # Obtain certificates certificates = _try_obtain_certificates(args) @@ -231,13 +223,8 @@ def run_superlink() -> None: if args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE else ADDRESS_FLEET_API_REST ) - parsed_fleet_address = parse_address(args.fleet_api_address) - if not parsed_fleet_address: - sys.exit(f"Fleet IP address ({args.fleet_api_address}) cannot be parsed.") - fleet_host, fleet_port, fleet_is_v6 = parsed_fleet_address - fleet_address = ( - f"[{fleet_host}]:{fleet_port}" if fleet_is_v6 else f"{fleet_host}:{fleet_port}" - ) + + fleet_address, host, port = _format_address(args.fleet_api_address) num_workers = args.fleet_api_num_workers if num_workers != 1: @@ -267,8 +254,8 @@ def run_superlink() -> None: fleet_thread = threading.Thread( target=_run_fleet_api_rest, args=( - fleet_host, - fleet_port, + host, + port, ssl_keyfile, ssl_certfile, state_factory, @@ -325,6 +312,16 @@ def run_superlink() -> None: driver_server.wait_for_termination(timeout=1) +def _format_address(address: str) -> Tuple[str, str, int]: + parsed_address = parse_address(address) + if not parsed_address: + sys.exit( + f"Address ({address}) cannot be parsed (expected: URL or IPv4 or IPv6)." + ) + host, port, is_v6 = parsed_address + return (f"[{host}]:{port}" if is_v6 else f"{host}:{port}", host, port) + + def _try_setup_client_authentication( args: argparse.Namespace, certificates: Optional[Tuple[bytes, bytes, bytes]], From a44f92e80a0ebf9494394e6c93de2c1743b272c6 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 19:34:53 +0200 Subject: [PATCH 065/124] feat(framework:skip) Add get_fab_metadata function (#3553) --- src/py/flwr/cli/config_utils.py | 56 +++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/py/flwr/cli/config_utils.py b/src/py/flwr/cli/config_utils.py index ec67fefda0d2..2f1acbca03d6 100644 --- a/src/py/flwr/cli/config_utils.py +++ b/src/py/flwr/cli/config_utils.py @@ -14,14 +14,56 @@ # ============================================================================== """Utility to validate the `pyproject.toml` file.""" +import zipfile +from io import BytesIO from pathlib import Path -from typing import Any, Dict, List, Optional, Tuple +from typing import IO, Any, Dict, List, Optional, Tuple, Union import tomli from flwr.common import object_ref +def get_fab_metadata(fab_file: Union[Path, bytes]) -> Tuple[str, str]: + """Extract the fab_id and the fab_version from a FAB file or path. + + Parameters + ---------- + fab_file : Union[Path, bytes] + The Flower App Bundle file to validate and extract the metadata from. + It can either be a path to the file or the file itself as bytes. + + Returns + ------- + Tuple[str, str] + The `fab_version` and `fab_id` of the given Flower App Bundle. + """ + fab_file_archive: Union[Path, IO[bytes]] + if isinstance(fab_file, bytes): + fab_file_archive = BytesIO(fab_file) + elif isinstance(fab_file, Path): + fab_file_archive = fab_file + else: + raise ValueError("fab_file must be either a Path or bytes") + + with zipfile.ZipFile(fab_file_archive, "r") as zipf: + with zipf.open("pyproject.toml") as file: + toml_content = file.read().decode("utf-8") + + conf = load_from_string(toml_content) + if conf is None: + raise ValueError("Invalid TOML content in pyproject.toml") + + is_valid, errors, _ = validate(conf) + if not is_valid: + raise ValueError(errors) + + return ( + conf["project"]["version"], + f"{conf['flower']['publisher']}/{conf['project']['name']}", + ) + + def load_and_validate( path: Optional[Path] = None, check_module: bool = True, @@ -63,8 +105,7 @@ def load(path: Optional[Path] = None) -> Optional[Dict[str, Any]]: return None with toml_path.open(encoding="utf-8") as toml_file: - data = tomli.loads(toml_file.read()) - return data + return load_from_string(toml_file.read()) # pylint: disable=too-many-branches @@ -128,3 +169,12 @@ def validate( return False, [reason], [] return True, [], [] + + +def load_from_string(toml_content: str) -> Optional[Dict[str, Any]]: + """Load TOML content from a string and return as dict.""" + try: + data = tomli.loads(toml_content) + return data + except tomli.TOMLDecodeError: + return None From be73dc50d1c22870dfa6eb722be33d27d6a1f613 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 21:13:54 +0200 Subject: [PATCH 066/124] refactor(framework:skip) Add return types to certain CLI functions (#3601) --- src/py/flwr/cli/build.py | 4 +++- src/py/flwr/cli/install.py | 14 ++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/py/flwr/cli/build.py b/src/py/flwr/cli/build.py index d279a8d11bc2..2981eacf925d 100644 --- a/src/py/flwr/cli/build.py +++ b/src/py/flwr/cli/build.py @@ -33,7 +33,7 @@ def build( Optional[Path], typer.Option(help="The Flower project directory to bundle into a FAB"), ] = None, -) -> None: +) -> str: """Build a Flower project into a Flower App Bundle (FAB). You can run `flwr build` without any argument to bundle the current directory: @@ -125,6 +125,8 @@ def build( f"🎊 Successfully built {fab_filename}.", fg=typer.colors.GREEN, bold=True ) + return fab_filename + def _load_gitignore(directory: Path) -> pathspec.PathSpec: """Load and parse .gitignore file, returning a pathspec.""" diff --git a/src/py/flwr/cli/install.py b/src/py/flwr/cli/install.py index d6d2ee55a47a..d953c650f3ac 100644 --- a/src/py/flwr/cli/install.py +++ b/src/py/flwr/cli/install.py @@ -84,7 +84,7 @@ def install_from_fab( fab_file: Union[Path, bytes], flwr_dir: Optional[Path], skip_prompt: bool = False, -) -> None: +) -> Path: """Install from a FAB file after extracting and validating.""" fab_file_archive: Union[Path, IO[bytes]] fab_name: Optional[str] @@ -124,7 +124,11 @@ def install_from_fab( shutil.rmtree(info_dir) - validate_and_install(tmpdir_path, fab_name, flwr_dir, skip_prompt) + installed_path = validate_and_install( + tmpdir_path, fab_name, flwr_dir, skip_prompt + ) + + return installed_path def validate_and_install( @@ -132,7 +136,7 @@ def validate_and_install( fab_name: Optional[str], flwr_dir: Optional[Path], skip_prompt: bool = False, -) -> None: +) -> Path: """Validate TOML files and install the project to the desired directory.""" config, _, _ = load_and_validate(project_dir / "pyproject.toml", check_module=False) @@ -185,7 +189,7 @@ def validate_and_install( bold=True, ) ): - return + return install_dir install_dir.mkdir(parents=True, exist_ok=True) @@ -202,6 +206,8 @@ def validate_and_install( bold=True, ) + return install_dir + def _verify_hashes(list_content: str, tmpdir: Path) -> bool: """Verify file hashes based on the LIST content.""" From c16cd7503465f9d13e98173a160bbef03bc1e666 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 21:32:30 +0200 Subject: [PATCH 067/124] refactor(framework:skip) Add function to get flwr dir (#3600) --- src/py/flwr/cli/install.py | 14 +++----------- src/py/flwr/client/supernode/app.py | 11 +++-------- src/py/flwr/common/config.py | 28 ++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 19 deletions(-) create mode 100644 src/py/flwr/common/config.py diff --git a/src/py/flwr/cli/install.py b/src/py/flwr/cli/install.py index d953c650f3ac..de9227bee450 100644 --- a/src/py/flwr/cli/install.py +++ b/src/py/flwr/cli/install.py @@ -15,7 +15,6 @@ """Flower command line interface `install` command.""" -import os import shutil import tempfile import zipfile @@ -26,6 +25,8 @@ import typer from typing_extensions import Annotated +from flwr.common.config import get_flwr_dir + from .config_utils import load_and_validate from .utils import get_sha256_hash @@ -165,16 +166,7 @@ def validate_and_install( raise typer.Exit(code=1) install_dir: Path = ( - ( - Path( - os.getenv( - "FLWR_HOME", - f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", - ) - ) - if not flwr_dir - else flwr_dir - ) + (get_flwr_dir() if not flwr_dir else flwr_dir) / "apps" / publisher / project_name diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 9ec9695fb51e..ddc547ad371b 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -15,7 +15,6 @@ """Flower SuperNode.""" import argparse -import os import sys from logging import DEBUG, INFO, WARN from pathlib import Path @@ -32,6 +31,7 @@ from flwr.cli.config_utils import validate_fields from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import EventType, event +from flwr.common.config import get_flwr_dir from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log, warn_deprecated_feature from flwr.common.object_ref import load_app, validate @@ -170,12 +170,7 @@ def _get_load_client_app_fn( flwr_dir = Path("") if "flwr_dir" in args: if args.flwr_dir is None: - flwr_dir = Path( - os.getenv( - "FLWR_HOME", - f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", - ) - ) + flwr_dir = get_flwr_dir() else: flwr_dir = Path(args.flwr_dir) @@ -234,7 +229,7 @@ def _load(fab_id: str, fab_version: str) -> ClientApp: # Load pyproject.toml file toml_path = project_dir / "pyproject.toml" - if not os.path.isfile(toml_path): + if not toml_path.is_file(): raise LoadClientAppError( f"Cannot find pyproject.toml in {project_dir}", ) from None diff --git a/src/py/flwr/common/config.py b/src/py/flwr/common/config.py new file mode 100644 index 000000000000..2c5b5962e7bd --- /dev/null +++ b/src/py/flwr/common/config.py @@ -0,0 +1,28 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Provide functions for managing global Flower config.""" + +import os +from pathlib import Path + + +def get_flwr_dir() -> Path: + """Return the Flower home directory based on env variables.""" + return Path( + os.getenv( + "FLWR_HOME", + f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", + ) + ) From bdb9269d68d452e96339324bf3e5dfffdc4a0270 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 22:28:51 +0200 Subject: [PATCH 068/124] feat(framework) Add proto files for SuperExec service (#3602) --- src/proto/flwr/proto/exec.proto | 26 +++++++++++ src/py/flwr/proto/exec_pb2.py | 30 +++++++++++++ src/py/flwr/proto/exec_pb2.pyi | 32 ++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.py | 67 +++++++++++++++++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.pyi | 27 ++++++++++++ src/py/flwr_tool/protoc_test.py | 2 +- 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/proto/flwr/proto/exec.proto create mode 100644 src/py/flwr/proto/exec_pb2.py create mode 100644 src/py/flwr/proto/exec_pb2.pyi create mode 100644 src/py/flwr/proto/exec_pb2_grpc.py create mode 100644 src/py/flwr/proto/exec_pb2_grpc.pyi diff --git a/src/proto/flwr/proto/exec.proto b/src/proto/flwr/proto/exec.proto new file mode 100644 index 000000000000..05885c9ceed3 --- /dev/null +++ b/src/proto/flwr/proto/exec.proto @@ -0,0 +1,26 @@ +// Copyright 2024 Flower Labs GmbH. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================== + +syntax = "proto3"; + +package flwr.proto; + +service Exec { + // Start run upon request + rpc StartRun(StartRunRequest) returns (StartRunResponse) {} +} + +message StartRunRequest { bytes fab_file = 1; } +message StartRunResponse { sint64 run_id = 1; } diff --git a/src/py/flwr/proto/exec_pb2.py b/src/py/flwr/proto/exec_pb2.py new file mode 100644 index 000000000000..a1d1f24af7d0 --- /dev/null +++ b/src/py/flwr/proto/exec_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: flwr/proto/exec.proto +# Protobuf Python Version: 4.25.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\"#\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\x32O\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x62\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.exec_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_STARTRUNREQUEST']._serialized_start=37 + _globals['_STARTRUNREQUEST']._serialized_end=72 + _globals['_STARTRUNRESPONSE']._serialized_start=74 + _globals['_STARTRUNRESPONSE']._serialized_end=108 + _globals['_EXEC']._serialized_start=110 + _globals['_EXEC']._serialized_end=189 +# @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/exec_pb2.pyi b/src/py/flwr/proto/exec_pb2.pyi new file mode 100644 index 000000000000..8a0122062dcf --- /dev/null +++ b/src/py/flwr/proto/exec_pb2.pyi @@ -0,0 +1,32 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class StartRunRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + FAB_FILE_FIELD_NUMBER: builtins.int + fab_file: builtins.bytes + def __init__(self, + *, + fab_file: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["fab_file",b"fab_file"]) -> None: ... +global___StartRunRequest = StartRunRequest + +class StartRunResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RUN_ID_FIELD_NUMBER: builtins.int + run_id: builtins.int + def __init__(self, + *, + run_id: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ... +global___StartRunResponse = StartRunResponse diff --git a/src/py/flwr/proto/exec_pb2_grpc.py b/src/py/flwr/proto/exec_pb2_grpc.py new file mode 100644 index 000000000000..349148eb9926 --- /dev/null +++ b/src/py/flwr/proto/exec_pb2_grpc.py @@ -0,0 +1,67 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +from flwr.proto import exec_pb2 as flwr_dot_proto_dot_exec__pb2 + + +class ExecStub(object): + """Missing associated documentation comment in .proto file.""" + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.StartRun = channel.unary_unary( + '/flwr.proto.Exec/StartRun', + request_serializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString, + response_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString, + ) + + +class ExecServicer(object): + """Missing associated documentation comment in .proto file.""" + + def StartRun(self, request, context): + """Start run upon request + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_ExecServicer_to_server(servicer, server): + rpc_method_handlers = { + 'StartRun': grpc.unary_unary_rpc_method_handler( + servicer.StartRun, + request_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.FromString, + response_serializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'flwr.proto.Exec', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Exec(object): + """Missing associated documentation comment in .proto file.""" + + @staticmethod + def StartRun(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/flwr.proto.Exec/StartRun', + flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString, + flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/exec_pb2_grpc.pyi b/src/py/flwr/proto/exec_pb2_grpc.pyi new file mode 100644 index 000000000000..6cab594babd9 --- /dev/null +++ b/src/py/flwr/proto/exec_pb2_grpc.pyi @@ -0,0 +1,27 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import abc +import flwr.proto.exec_pb2 +import grpc + +class ExecStub: + def __init__(self, channel: grpc.Channel) -> None: ... + StartRun: grpc.UnaryUnaryMultiCallable[ + flwr.proto.exec_pb2.StartRunRequest, + flwr.proto.exec_pb2.StartRunResponse] + """Start run upon request""" + + +class ExecServicer(metaclass=abc.ABCMeta): + @abc.abstractmethod + def StartRun(self, + request: flwr.proto.exec_pb2.StartRunRequest, + context: grpc.ServicerContext, + ) -> flwr.proto.exec_pb2.StartRunResponse: + """Start run upon request""" + pass + + +def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ... diff --git a/src/py/flwr_tool/protoc_test.py b/src/py/flwr_tool/protoc_test.py index 6aec4251c384..0c43ed0b0811 100644 --- a/src/py/flwr_tool/protoc_test.py +++ b/src/py/flwr_tool/protoc_test.py @@ -28,4 +28,4 @@ def test_directories() -> None: def test_proto_file_count() -> None: """Test if the correct number of proto files were captured by the glob.""" - assert len(PROTO_FILES) == 9 + assert len(PROTO_FILES) == 10 From bd39b303f8cf35dcdef6c572670ead3c3fe9f881 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 22:35:14 +0200 Subject: [PATCH 069/124] feat(framework) Add SuperExec binary (#3603) --- pyproject.toml | 1 + src/py/flwr/superexec/__init__.py | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/py/flwr/superexec/__init__.py diff --git a/pyproject.toml b/pyproject.toml index 62e17aeb5281..2dd592050468 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -54,6 +54,7 @@ exclude = [ [tool.poetry.scripts] flwr = "flwr.cli.app:app" flower-superlink = "flwr.server:run_superlink" +flower-superexec = "flwr.superexec:run_superexec" flower-supernode = "flwr.client:run_supernode" flower-client-app = "flwr.client:run_client_app" flower-server-app = "flwr.server:run_server_app" diff --git a/src/py/flwr/superexec/__init__.py b/src/py/flwr/superexec/__init__.py new file mode 100644 index 000000000000..9395b3b51efd --- /dev/null +++ b/src/py/flwr/superexec/__init__.py @@ -0,0 +1,19 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Fower SuperExec package.""" + + +def run_superexec() -> None: + """Empty stub.""" From b0fc4b820d0aee89274aff68e74c704b171e0f68 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 13 Jun 2024 22:45:24 +0200 Subject: [PATCH 070/124] feat(framework) Add SuperExec constants (#3604) --- src/py/flwr/common/constant.py | 2 ++ src/py/flwr/common/telemetry.py | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/py/flwr/common/constant.py b/src/py/flwr/common/constant.py index b6d39b6e8932..0722ab7d167e 100644 --- a/src/py/flwr/common/constant.py +++ b/src/py/flwr/common/constant.py @@ -36,6 +36,8 @@ TRANSPORT_TYPE_VCE, ] +SUPEREXEC_DEFAULT_ADDRESS = "0.0.0.0:9093" + # Constants for ping PING_DEFAULT_INTERVAL = 30 PING_CALL_TIMEOUT = 5 diff --git a/src/py/flwr/common/telemetry.py b/src/py/flwr/common/telemetry.py index 41fe1508e652..eeb255e8d6eb 100644 --- a/src/py/flwr/common/telemetry.py +++ b/src/py/flwr/common/telemetry.py @@ -164,6 +164,10 @@ def _generate_next_value_(name: str, start: int, count: int, last_values: List[A RUN_SUPERNODE_ENTER = auto() RUN_SUPERNODE_LEAVE = auto() + # SuperExec + RUN_SUPEREXEC_ENTER = auto() + RUN_SUPEREXEC_LEAVE = auto() + # Use the ThreadPoolExecutor with max_workers=1 to have a queue # and also ensure that telemetry calls are not blocking. From abc3789daa502bd5a230943216e646f216c331ef Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Fri, 14 Jun 2024 10:11:28 +0200 Subject: [PATCH 071/124] fix(datasets) Limit the datasets versions (#3607) --- datasets/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/datasets/pyproject.toml b/datasets/pyproject.toml index f874d4f0ce51..56cf3038f4ef 100644 --- a/datasets/pyproject.toml +++ b/datasets/pyproject.toml @@ -54,7 +54,7 @@ exclude = [ [tool.poetry.dependencies] python = "^3.8" numpy = "^1.21.0" -datasets = "^2.14.6" +datasets = ">=2.14.6 <2.20.0" pillow = { version = ">=6.2.1", optional = true } soundfile = { version = ">=0.12.1", optional = true } librosa = { version = ">=0.10.0.post2", optional = true } From dc15282107d0191b5f5239aa3166b3743b0d5bc1 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Fri, 14 Jun 2024 10:31:56 +0200 Subject: [PATCH 072/124] feat(*:skip) Add retry loop when installing flwr (#3588) Signed-off-by: Robert Steiner --- .github/workflows/_docker-build.yml | 35 +++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/.github/workflows/_docker-build.yml b/.github/workflows/_docker-build.yml index 3508b1a7b3f6..b8ddd355eb8e 100644 --- a/.github/workflows/_docker-build.yml +++ b/.github/workflows/_docker-build.yml @@ -60,8 +60,24 @@ jobs: hash = hashlib.sha256('''${{ inputs.namespace-repository }} ${{ inputs.file-dir }} ${{ inputs.build-args }}'''.encode()) + # Adds two spaces to the line breaks to ensure proper indentation + # when passing the multi-line string to the wretry.action. + # Without it, the multi-line string is passed like this: + # + # build-args: | + # ARG1= + # ARG2= + # ARG3= + # + # This causes the Docker action to interpret ARG2 and ARG3 as keys instead + # of values ​​of the multi-line string. + build_args = '''${{ inputs.build-args }}'''.replace("\n", "\n ") + with open(os.environ['GITHUB_OUTPUT'], 'a') as fh: print(f"id={hash.hexdigest()}", file=fh) + print("build-args< Date: Fri, 14 Jun 2024 11:02:03 +0200 Subject: [PATCH 073/124] feat(framework) Add SuperExec to flwr run CLI (#3605) --- src/py/flwr/cli/run/run.py | 39 +++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/py/flwr/cli/run/run.py b/src/py/flwr/cli/run/run.py index dbaf7feb3500..3ac9966a1107 100644 --- a/src/py/flwr/cli/run/run.py +++ b/src/py/flwr/cli/run/run.py @@ -16,12 +16,18 @@ import sys from enum import Enum +from logging import DEBUG from typing import Optional import typer from typing_extensions import Annotated from flwr.cli import config_utils +from flwr.common.constant import SUPEREXEC_DEFAULT_ADDRESS +from flwr.common.grpc import GRPC_MAX_MESSAGE_LENGTH, create_channel +from flwr.common.logger import log +from flwr.proto.exec_pb2 import StartRunRequest # pylint: disable=E0611 +from flwr.proto.exec_pb2_grpc import ExecStub from flwr.simulation.run_simulation import _run_simulation @@ -31,20 +37,32 @@ class Engine(str, Enum): SIMULATION = "simulation" +# pylint: disable-next=too-many-locals def run( engine: Annotated[ Optional[Engine], typer.Option(case_sensitive=False, help="The ML framework to use"), ] = None, + use_superexec: Annotated[ + bool, + typer.Option( + case_sensitive=False, help="Use this flag to use the new SuperExec API" + ), + ] = False, ) -> None: """Run Flower project.""" + if use_superexec: + _start_superexec_run() + return + typer.secho("Loading project configuration... ", fg=typer.colors.BLUE) config, errors, warnings = config_utils.load_and_validate() if config is None: typer.secho( - "Project configuration could not be loaded.\npyproject.toml is invalid:\n" + "Project configuration could not be loaded.\n" + "pyproject.toml is invalid:\n" + "\n".join([f"- {line}" for line in errors]), fg=typer.colors.RED, bold=True, @@ -82,3 +100,22 @@ def run( fg=typer.colors.RED, bold=True, ) + + +def _start_superexec_run() -> None: + def on_channel_state_change(channel_connectivity: str) -> None: + """Log channel connectivity.""" + log(DEBUG, channel_connectivity) + + channel = create_channel( + server_address=SUPEREXEC_DEFAULT_ADDRESS, + insecure=True, + root_certificates=None, + max_message_length=GRPC_MAX_MESSAGE_LENGTH, + interceptors=None, + ) + channel.subscribe(on_channel_state_change) + stub = ExecStub(channel) + + req = StartRunRequest() + stub.StartRun(req) From 32508010af0d678b555209396ee55f56fcbc8c2a Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Fri, 14 Jun 2024 13:39:13 +0200 Subject: [PATCH 074/124] feat(framework) Add SuperExec servicer (#3606) --- src/py/flwr/superexec/exec_grpc.py | 51 +++++++++++++++++++ src/py/flwr/superexec/exec_servicer.py | 54 +++++++++++++++++++++ src/py/flwr/superexec/exec_servicer_test.py | 52 ++++++++++++++++++++ src/py/flwr/superexec/executor.py | 54 +++++++++++++++++++++ 4 files changed, 211 insertions(+) create mode 100644 src/py/flwr/superexec/exec_grpc.py create mode 100644 src/py/flwr/superexec/exec_servicer.py create mode 100644 src/py/flwr/superexec/exec_servicer_test.py create mode 100644 src/py/flwr/superexec/executor.py diff --git a/src/py/flwr/superexec/exec_grpc.py b/src/py/flwr/superexec/exec_grpc.py new file mode 100644 index 000000000000..127d5615dd84 --- /dev/null +++ b/src/py/flwr/superexec/exec_grpc.py @@ -0,0 +1,51 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""SuperExec gRPC API.""" + +from logging import INFO +from typing import Optional, Tuple + +import grpc + +from flwr.common import GRPC_MAX_MESSAGE_LENGTH +from flwr.common.logger import log +from flwr.proto.exec_pb2_grpc import add_ExecServicer_to_server +from flwr.server.superlink.fleet.grpc_bidi.grpc_server import generic_create_grpc_server + +from .exec_servicer import ExecServicer +from .executor import Executor + + +def run_superexec_api_grpc( + address: str, + executor: Executor, + certificates: Optional[Tuple[bytes, bytes, bytes]], +) -> grpc.Server: + """Run SuperExec API (gRPC, request-response).""" + exec_servicer: grpc.Server = ExecServicer( + executor=executor, + ) + superexec_add_servicer_to_server_fn = add_ExecServicer_to_server + superexec_grpc_server = generic_create_grpc_server( + servicer_and_add_fn=(exec_servicer, superexec_add_servicer_to_server_fn), + server_address=address, + max_message_length=GRPC_MAX_MESSAGE_LENGTH, + certificates=certificates, + ) + + log(INFO, "Flower ECE: Starting SuperExec API (gRPC-rere) on %s", address) + superexec_grpc_server.start() + + return superexec_grpc_server diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py new file mode 100644 index 000000000000..aa8172c18704 --- /dev/null +++ b/src/py/flwr/superexec/exec_servicer.py @@ -0,0 +1,54 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""SuperExec API servicer.""" + + +from logging import ERROR, INFO +from typing import Dict + +import grpc + +from flwr.common.logger import log +from flwr.proto import exec_pb2_grpc # pylint: disable=E0611 +from flwr.proto.exec_pb2 import ( # pylint: disable=E0611 + StartRunRequest, + StartRunResponse, +) + +from .executor import Executor, RunTracker + + +class ExecServicer(exec_pb2_grpc.ExecServicer): + """SuperExec API servicer.""" + + def __init__(self, executor: Executor) -> None: + self.executor = executor + self.runs: Dict[int, RunTracker] = {} + + def StartRun( + self, request: StartRunRequest, context: grpc.ServicerContext + ) -> StartRunResponse: + """Create run ID.""" + log(INFO, "ExecServicer.StartRun") + + run = self.executor.start_run(request.fab_file) + + if run is None: + log(ERROR, "Executor failed to start run") + return StartRunResponse() + + self.runs[run.run_id] = run + + return StartRunResponse(run_id=run.run_id) diff --git a/src/py/flwr/superexec/exec_servicer_test.py b/src/py/flwr/superexec/exec_servicer_test.py new file mode 100644 index 000000000000..41f67b74c48b --- /dev/null +++ b/src/py/flwr/superexec/exec_servicer_test.py @@ -0,0 +1,52 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Test the SuperExec API servicer.""" + + +import subprocess +from unittest.mock import MagicMock + +from flwr.proto.exec_pb2 import StartRunRequest # pylint: disable=E0611 + +from .exec_servicer import ExecServicer + + +def test_start_run() -> None: + """Test StartRun method of ExecServicer.""" + run_res = MagicMock() + run_res.run_id = 10 + with subprocess.Popen( + ["echo", "success"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True, + ) as proc: + run_res.proc = proc + + executor = MagicMock() + executor.start_run = lambda _: run_res + + context_mock = MagicMock() + + request = StartRunRequest() + request.fab_file = b"test" + + # Create a instance of FlowerServiceServicer + servicer = ExecServicer(executor=executor) + + # Execute + response = servicer.StartRun(request, context_mock) + + assert response.run_id == 10 diff --git a/src/py/flwr/superexec/executor.py b/src/py/flwr/superexec/executor.py new file mode 100644 index 000000000000..f85ac4c157fc --- /dev/null +++ b/src/py/flwr/superexec/executor.py @@ -0,0 +1,54 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Execute and monitor a Flower run.""" + +from abc import ABC, abstractmethod +from dataclasses import dataclass +from subprocess import Popen +from typing import Optional + + +@dataclass +class RunTracker: + """Track a Flower run (composed of a run_id and the associated process).""" + + run_id: int + proc: Popen # type: ignore + + +class Executor(ABC): + """Execute and monitor a Flower run.""" + + @abstractmethod + def start_run( + self, + fab_file: bytes, + ) -> Optional[RunTracker]: + """Start a run using the given Flower FAB ID and version. + + This method creates a new run on the SuperLink, returns its run_id + and also starts the run execution. + + Parameters + ---------- + fab_file : bytes + The Flower App Bundle file bytes. + + Returns + ------- + run_id : Optional[RunTracker] + The run_id and the associated process of the run created by the SuperLink, + or `None` if it fails. + """ From 0be59583e2d39f18d552cc039f1f0601099939f4 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Fri, 14 Jun 2024 14:13:03 +0200 Subject: [PATCH 075/124] feat(framework) Add initial `SuperExec` service (#3555) Co-authored-by: Daniel J. Beutel --- src/py/flwr/superexec/__init__.py | 8 +- src/py/flwr/superexec/app.py | 178 ++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+), 3 deletions(-) create mode 100644 src/py/flwr/superexec/app.py diff --git a/src/py/flwr/superexec/__init__.py b/src/py/flwr/superexec/__init__.py index 9395b3b51efd..a510c41f4182 100644 --- a/src/py/flwr/superexec/__init__.py +++ b/src/py/flwr/superexec/__init__.py @@ -12,8 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================== -"""Fower SuperExec package.""" +"""Flower SuperExec service.""" +from .app import run_superexec as run_superexec -def run_superexec() -> None: - """Empty stub.""" +__all__ = [ + "run_superexec", +] diff --git a/src/py/flwr/superexec/app.py b/src/py/flwr/superexec/app.py new file mode 100644 index 000000000000..e1cb4f609e9c --- /dev/null +++ b/src/py/flwr/superexec/app.py @@ -0,0 +1,178 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Flower SuperExec app.""" + +import argparse +import sys +from logging import INFO, WARN +from pathlib import Path +from typing import Optional, Tuple + +import grpc + +from flwr.common import EventType, event, log +from flwr.common.address import parse_address +from flwr.common.constant import SUPEREXEC_DEFAULT_ADDRESS +from flwr.common.exit_handlers import register_exit_handlers +from flwr.common.object_ref import load_app, validate + +from .exec_grpc import run_superexec_api_grpc +from .executor import Executor + + +def run_superexec() -> None: + """Run Flower SuperExec.""" + log(INFO, "Starting Flower SuperExec") + + event(EventType.RUN_SUPEREXEC_ENTER) + + args = _parse_args_run_superexec().parse_args() + + # Parse IP address + parsed_address = parse_address(args.address) + if not parsed_address: + sys.exit(f"SuperExec IP address ({args.address}) cannot be parsed.") + host, port, is_v6 = parsed_address + address = f"[{host}]:{port}" if is_v6 else f"{host}:{port}" + + # Obtain certificates + certificates = _try_obtain_certificates(args) + + # Start SuperExec API + superexec_server: grpc.Server = run_superexec_api_grpc( + address=address, + executor=_load_executor(args), + certificates=certificates, + ) + + grpc_servers = [superexec_server] + + # Graceful shutdown + register_exit_handlers( + event_type=EventType.RUN_SUPEREXEC_LEAVE, + grpc_servers=grpc_servers, + bckg_threads=None, + ) + + superexec_server.wait_for_termination() + + +def _parse_args_run_superexec() -> argparse.ArgumentParser: + """Parse command line arguments for SuperExec.""" + parser = argparse.ArgumentParser( + description="Start a Flower SuperExec", + ) + parser.add_argument( + "executor", + help="For example: `deployment:exec` or `project.package.module:wrapper.exec`.", + ) + parser.add_argument( + "--address", + help="SuperExec (gRPC) server address (IPv4, IPv6, or a domain name)", + default=SUPEREXEC_DEFAULT_ADDRESS, + ) + parser.add_argument( + "--executor-dir", + help="The directory for the executor.", + default=".", + ) + parser.add_argument( + "--insecure", + action="store_true", + help="Run the SuperExec without HTTPS, regardless of whether certificate " + "paths are provided. By default, the server runs with HTTPS enabled. " + "Use this flag only if you understand the risks.", + ) + parser.add_argument( + "--ssl-certfile", + help="SuperExec server SSL certificate file (as a path str) " + "to create a secure connection.", + type=str, + default=None, + ) + parser.add_argument( + "--ssl-keyfile", + help="SuperExec server SSL private key file (as a path str) " + "to create a secure connection.", + type=str, + ) + parser.add_argument( + "--ssl-ca-certfile", + help="SuperExec server SSL CA certificate file (as a path str) " + "to create a secure connection.", + type=str, + ) + return parser + + +def _try_obtain_certificates( + args: argparse.Namespace, +) -> Optional[Tuple[bytes, bytes, bytes]]: + # Obtain certificates + if args.insecure: + log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.") + return None + # Check if certificates are provided + if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile: + if not Path.is_file(args.ssl_ca_certfile): + sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.") + if not Path.is_file(args.ssl_certfile): + sys.exit("Path argument `--ssl-certfile` does not point to a file.") + if not Path.is_file(args.ssl_keyfile): + sys.exit("Path argument `--ssl-keyfile` does not point to a file.") + certificates = ( + Path(args.ssl_ca_certfile).read_bytes(), # CA certificate + Path(args.ssl_certfile).read_bytes(), # server certificate + Path(args.ssl_keyfile).read_bytes(), # server private key + ) + return certificates + if args.ssl_certfile or args.ssl_keyfile or args.ssl_ca_certfile: + sys.exit( + "You need to provide valid file paths to `--ssl-certfile`, " + "`--ssl-keyfile`, and `—-ssl-ca-certfile` to create a secure " + "connection in SuperExec server (gRPC-rere)." + ) + sys.exit( + "Certificates are required unless running in insecure mode. " + "Please provide certificate paths to `--ssl-certfile`, " + "`--ssl-keyfile`, and `—-ssl-ca-certfile` or run the server " + "in insecure mode using '--insecure' if you understand the risks." + ) + + +def _load_executor( + args: argparse.Namespace, +) -> Executor: + """Get the executor plugin.""" + if args.executor_dir is not None: + sys.path.insert(0, args.executor_dir) + + executor_ref: str = args.executor + valid, error_msg = validate(executor_ref) + if not valid and error_msg: + raise LoadExecutorError(error_msg) from None + + executor = load_app(executor_ref, LoadExecutorError) + + if not isinstance(executor, Executor): + raise LoadExecutorError( + f"Attribute {executor_ref} is not of type {Executor}", + ) from None + + return executor + + +class LoadExecutorError(Exception): + """Error when trying to load `Executor`.""" From 6a7fc7d494fabcdd3d7e3f79818afcba2d82b6d4 Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 14 Jun 2024 14:33:19 +0200 Subject: [PATCH 076/124] feat(framework) Enable setting `run_id` when starting simulation (#3576) --- src/py/flwr/simulation/run_simulation.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index 2dbeef1a261c..3532c5a4e877 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -53,6 +53,7 @@ def run_simulation_from_cli() -> None: backend_name=args.backend, backend_config=backend_config_dict, app_dir=args.app_dir, + run_id=args.run_id, enable_tf_gpu_growth=args.enable_tf_gpu_growth, verbose_logging=args.verbose, ) @@ -168,6 +169,13 @@ def server_th_with_start_checks( # type: ignore return serverapp_th +def _init_run_id(driver: InMemoryDriver, state: StateFactory, run_id: int) -> None: + """Create a run with a given `run_id`.""" + log(DEBUG, "Pre-registering run with id %s", run_id) + state.state().run_ids[run_id] = ("", "") # type: ignore + driver.run_id = run_id + + # pylint: disable=too-many-locals def _main_loop( num_supernodes: int, @@ -175,6 +183,7 @@ def _main_loop( backend_config_stream: str, app_dir: str, enable_tf_gpu_growth: bool, + run_id: Optional[int] = None, client_app: Optional[ClientApp] = None, client_app_attr: Optional[str] = None, server_app: Optional[ServerApp] = None, @@ -195,6 +204,9 @@ def _main_loop( # Initialize Driver driver = InMemoryDriver(state_factory) + if run_id: + _init_run_id(driver, state_factory, run_id) + # Get and run ServerApp thread serverapp_th = run_serverapp_th( server_app_attr=server_app_attr, @@ -244,6 +256,7 @@ def _run_simulation( client_app_attr: Optional[str] = None, server_app_attr: Optional[str] = None, app_dir: str = "", + run_id: Optional[int] = None, enable_tf_gpu_growth: bool = False, verbose_logging: bool = False, ) -> None: @@ -283,6 +296,9 @@ def _run_simulation( Add specified directory to the PYTHONPATH and load `ClientApp` from there. (Default: current working directory.) + run_id : Optional[int] + An integer specifying the ID of the run started when running this function. + enable_tf_gpu_growth : bool (default: False) A boolean to indicate whether to enable GPU growth on the main thread. This is desirable if you make use of a TensorFlow model on your `ServerApp` while @@ -322,6 +338,7 @@ def _run_simulation( backend_config_stream, app_dir, enable_tf_gpu_growth, + run_id, client_app, client_app_attr, server_app, @@ -413,5 +430,10 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser: "ClientApp and ServerApp from there." " Default: current working directory.", ) + parser.add_argument( + "--run-id", + type=int, + help="Sets the ID of the run started by the Simulation Engine.", + ) return parser From 19d063efd6716b9d8708290c0562026ac03083dd Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Fri, 14 Jun 2024 14:39:53 +0200 Subject: [PATCH 077/124] fix(framework:skip) Skip module checking for metadata extraction (#3608) --- src/py/flwr/cli/config_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/cli/config_utils.py b/src/py/flwr/cli/config_utils.py index 2f1acbca03d6..d06a1d6dba96 100644 --- a/src/py/flwr/cli/config_utils.py +++ b/src/py/flwr/cli/config_utils.py @@ -54,7 +54,7 @@ def get_fab_metadata(fab_file: Union[Path, bytes]) -> Tuple[str, str]: if conf is None: raise ValueError("Invalid TOML content in pyproject.toml") - is_valid, errors, _ = validate(conf) + is_valid, errors, _ = validate(conf, check_module=False) if not is_valid: raise ValueError(errors) From 2bfd47a478dd50ee21170873421cd57706261dbd Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Sun, 16 Jun 2024 15:50:51 +0200 Subject: [PATCH 078/124] docs(framework:skip) Use correct description for CLI arg (#3614) --- src/py/flwr/cli/run/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/cli/run/run.py b/src/py/flwr/cli/run/run.py index 3ac9966a1107..7577d9efbd8c 100644 --- a/src/py/flwr/cli/run/run.py +++ b/src/py/flwr/cli/run/run.py @@ -41,7 +41,7 @@ class Engine(str, Enum): def run( engine: Annotated[ Optional[Engine], - typer.Option(case_sensitive=False, help="The ML framework to use"), + typer.Option(case_sensitive=False, help="The execution engine to run the app"), ] = None, use_superexec: Annotated[ bool, From b658ba7e7af034d0267c54191086683f7288822d Mon Sep 17 00:00:00 2001 From: Taner Topal Date: Sun, 16 Jun 2024 21:59:23 +0200 Subject: [PATCH 079/124] feat(framework) Add new proto definitions for FABs (#3618) --- src/proto/flwr/proto/fab.proto | 15 ++++++++ src/py/flwr/proto/fab_pb2.py | 30 ++++++++++++++++ src/py/flwr/proto/fab_pb2.pyi | 56 ++++++++++++++++++++++++++++++ src/py/flwr/proto/fab_pb2_grpc.py | 4 +++ src/py/flwr/proto/fab_pb2_grpc.pyi | 4 +++ src/py/flwr_tool/protoc_test.py | 2 +- 6 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 src/proto/flwr/proto/fab.proto create mode 100644 src/py/flwr/proto/fab_pb2.py create mode 100644 src/py/flwr/proto/fab_pb2.pyi create mode 100644 src/py/flwr/proto/fab_pb2_grpc.py create mode 100644 src/py/flwr/proto/fab_pb2_grpc.pyi diff --git a/src/proto/flwr/proto/fab.proto b/src/proto/flwr/proto/fab.proto new file mode 100644 index 000000000000..1e796a59c82a --- /dev/null +++ b/src/proto/flwr/proto/fab.proto @@ -0,0 +1,15 @@ +syntax = "proto3"; + +package flwr.proto; + +message Fab { + // This field is the hash of the data field. It is used to identify the data. + // The hash is calculated using the SHA-256 algorithm and is represented as a + // hex string (sha256hex). + string hash = 1; + // This field contains the fab file contents a one bytes blob. + bytes content = 2; +} + +message GetFabRequest { string hash = 1; } +message GetFabResponse { Fab fab = 1; } diff --git a/src/py/flwr/proto/fab_pb2.py b/src/py/flwr/proto/fab_pb2.py new file mode 100644 index 000000000000..c146a1635597 --- /dev/null +++ b/src/py/flwr/proto/fab_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: flwr/proto/fab.proto +# Protobuf Python Version: 4.25.0 +"""Generated protocol buffer code.""" +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +from google.protobuf.internal import builder as _builder +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14\x66lwr/proto/fab.proto\x12\nflwr.proto\"$\n\x03\x46\x61\x62\x12\x0c\n\x04hash\x18\x01 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x02 \x01(\x0c\"\x1d\n\rGetFabRequest\x12\x0c\n\x04hash\x18\x01 \x01(\t\".\n\x0eGetFabResponse\x12\x1c\n\x03\x66\x61\x62\x18\x01 \x01(\x0b\x32\x0f.flwr.proto.Fabb\x06proto3') + +_globals = globals() +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'flwr.proto.fab_pb2', _globals) +if _descriptor._USE_C_DESCRIPTORS == False: + DESCRIPTOR._options = None + _globals['_FAB']._serialized_start=36 + _globals['_FAB']._serialized_end=72 + _globals['_GETFABREQUEST']._serialized_start=74 + _globals['_GETFABREQUEST']._serialized_end=103 + _globals['_GETFABRESPONSE']._serialized_start=105 + _globals['_GETFABRESPONSE']._serialized_end=151 +# @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/fab_pb2.pyi b/src/py/flwr/proto/fab_pb2.pyi new file mode 100644 index 000000000000..dafc217d0ce2 --- /dev/null +++ b/src/py/flwr/proto/fab_pb2.pyi @@ -0,0 +1,56 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" +import builtins +import google.protobuf.descriptor +import google.protobuf.message +import typing +import typing_extensions + +DESCRIPTOR: google.protobuf.descriptor.FileDescriptor + +class Fab(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + HASH_FIELD_NUMBER: builtins.int + CONTENT_FIELD_NUMBER: builtins.int + hash: typing.Text + """This field is the hash of the data field. It is used to identify the data. + The hash is calculated using the SHA-256 algorithm and is represented as a + hex string (sha256hex). + """ + + content: builtins.bytes + """This field contains the fab file contents a one bytes blob.""" + + def __init__(self, + *, + hash: typing.Text = ..., + content: builtins.bytes = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["content",b"content","hash",b"hash"]) -> None: ... +global___Fab = Fab + +class GetFabRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + HASH_FIELD_NUMBER: builtins.int + hash: typing.Text + def __init__(self, + *, + hash: typing.Text = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["hash",b"hash"]) -> None: ... +global___GetFabRequest = GetFabRequest + +class GetFabResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + FAB_FIELD_NUMBER: builtins.int + @property + def fab(self) -> global___Fab: ... + def __init__(self, + *, + fab: typing.Optional[global___Fab] = ..., + ) -> None: ... + def HasField(self, field_name: typing_extensions.Literal["fab",b"fab"]) -> builtins.bool: ... + def ClearField(self, field_name: typing_extensions.Literal["fab",b"fab"]) -> None: ... +global___GetFabResponse = GetFabResponse diff --git a/src/py/flwr/proto/fab_pb2_grpc.py b/src/py/flwr/proto/fab_pb2_grpc.py new file mode 100644 index 000000000000..2daafffebfc8 --- /dev/null +++ b/src/py/flwr/proto/fab_pb2_grpc.py @@ -0,0 +1,4 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + diff --git a/src/py/flwr/proto/fab_pb2_grpc.pyi b/src/py/flwr/proto/fab_pb2_grpc.pyi new file mode 100644 index 000000000000..f3a5a087ef5d --- /dev/null +++ b/src/py/flwr/proto/fab_pb2_grpc.pyi @@ -0,0 +1,4 @@ +""" +@generated by mypy-protobuf. Do not edit manually! +isort:skip_file +""" diff --git a/src/py/flwr_tool/protoc_test.py b/src/py/flwr_tool/protoc_test.py index 0c43ed0b0811..6ba7daa0efea 100644 --- a/src/py/flwr_tool/protoc_test.py +++ b/src/py/flwr_tool/protoc_test.py @@ -28,4 +28,4 @@ def test_directories() -> None: def test_proto_file_count() -> None: """Test if the correct number of proto files were captured by the glob.""" - assert len(PROTO_FILES) == 10 + assert len(PROTO_FILES) == 11 From 41a673b60a48d94c52cf7d62cdf966dff5eea228 Mon Sep 17 00:00:00 2001 From: Javier Date: Sun, 16 Jun 2024 23:47:24 +0200 Subject: [PATCH 080/124] fix(framework) Pass superlink address when starting supernode (#3621) --- src/py/flwr/client/supernode/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index ddc547ad371b..4ed3027547ab 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -56,7 +56,7 @@ def run_supernode() -> None: authentication_keys = _try_setup_client_authentication(args) _start_client_internal( - server_address=args.server, + server_address=args.superlink, load_client_app_fn=load_fn, transport="rest" if args.rest else "grpc-rere", root_certificates=root_certificates, From 5d1cb0e6baa5dca4a3a0fd902ac414b1aa74a5e8 Mon Sep 17 00:00:00 2001 From: MarcelRoesberg <66379010+MarcelRoesberg@users.noreply.github.com> Date: Mon, 17 Jun 2024 13:12:18 +0200 Subject: [PATCH 081/124] fix(examples:skip) Fix typo in one example (#3628) --- examples/vertical-fl/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/vertical-fl/README.md b/examples/vertical-fl/README.md index d8c599d617c4..ba8228a059f9 100644 --- a/examples/vertical-fl/README.md +++ b/examples/vertical-fl/README.md @@ -459,7 +459,7 @@ evaluate function are bogus, as they won't be used on the server side. The `client_fn` we will use in our `start_simulation` function to generate our 3 clients will be very basic: -```pyhton3 +```python3 partitions, label = get_partitions_and_label() def client_fn(cid): From dc3d4eea34751cb78dc762c56459e5f7c80fe8fa Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Mon, 17 Jun 2024 16:07:36 +0200 Subject: [PATCH 082/124] docs(framework) Add latest Hosted Weblate translation updates (#3617) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 박태현 --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 2d106db01fd5..9333ce670e93 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-05-28 11:47+0200\n" -"PO-Revision-Date: 2024-06-13 16:07+0000\n" +"PO-Revision-Date: 2024-06-16 09:09+0000\n" "Last-Translator: 박태현 \n" "Language-Team: Korean \n" @@ -301,8 +301,8 @@ msgid "" "The following example creates a SuperLink image with the official Flower " "base image py3.11-ubuntu22.04 and Flower 1.8.0:" msgstr "" -"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base 이미지" -"로 SuperLink 이미지를 만듭니다:" +"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base " +"이미지로 SuperLink 이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" @@ -731,7 +731,8 @@ msgstr "" msgid "" "Install ``flwr`` from a local copy of the Flower source code via ``pyproject." "toml``:" -msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 설치:" +msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 " +"설치하세요:" #: ../../source/contributor-how-to-install-development-versions.rst:17 msgid "``flwr = { path = \"../../\", develop = true }`` (without extras)" @@ -817,7 +818,7 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:42 msgid "Install ``flwr`` from a specific GitHub branch (``branch-name``):" -msgstr "특정 GitHub branch (``branch-name``)에서 ``flwr``설치하기:" +msgstr "특정 GitHub branch (``branch-name``)에서 ``flwr`` 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:44 msgid "" From b8e5b502016b745feb0cee2fef02a4996372e5d7 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Mon, 17 Jun 2024 21:53:25 +0100 Subject: [PATCH 083/124] refactor(framework:skip) Use absolute paths when setting `sys.path` and replace `os.path.abspath` with `pathlib.Path.absolute` (#3610) --- src/py/flwr/client/supernode/app.py | 17 ++++++++++------- src/py/flwr/server/run_serverapp.py | 2 +- .../flwr/server/superlink/fleet/vce/vce_api.py | 2 ++ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 4ed3027547ab..d1d2bc197ce9 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -174,7 +174,7 @@ def _get_load_client_app_fn( else: flwr_dir = Path(args.flwr_dir) - sys.path.insert(0, str(flwr_dir)) + sys.path.insert(0, str(flwr_dir.absolute())) default_app_ref: str = getattr(args, "client-app") @@ -191,8 +191,8 @@ def _get_load_client_app_fn( def _load(fab_id: str, fab_version: str) -> ClientApp: # If multi-app feature is disabled if not multi_app: - # Set sys.path - sys.path[0] = args.dir + # Get sys path to be inserted + sys_path = Path(args.dir).absolute() # Set app reference client_app_ref = default_app_ref @@ -204,8 +204,8 @@ def _load(fab_id: str, fab_version: str) -> ClientApp: ) from None log(WARN, "FAB ID is not provided; the default ClientApp will be loaded.") - # Set sys.path - sys.path[0] = args.dir + # Get sys path to be inserted + sys_path = Path(args.dir).absolute() # Set app reference client_app_ref = default_app_ref @@ -244,12 +244,15 @@ def _load(fab_id: str, fab_version: str) -> ClientApp: f"Invalid pyproject.toml:\n{error_msg}", ) from None - # Set sys.path - sys.path[0] = str(project_dir) + # Get sys path to be inserted + sys_path = Path(project_dir).absolute() # Set app reference client_app_ref = config["flower"]["components"]["clientapp"] + # Set sys.path + sys.path.insert(0, str(sys_path)) + # Load ClientApp log( DEBUG, diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index 0879dd6054d0..fd0214a040bc 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -45,7 +45,7 @@ def run( ) if server_app_dir is not None: - sys.path.insert(0, server_app_dir) + sys.path.insert(0, str(Path(server_app_dir).absolute())) # Load ServerApp if needed def _load() -> ServerApp: diff --git a/src/py/flwr/server/superlink/fleet/vce/vce_api.py b/src/py/flwr/server/superlink/fleet/vce/vce_api.py index cc3e85b28097..dcd37aba09c0 100644 --- a/src/py/flwr/server/superlink/fleet/vce/vce_api.py +++ b/src/py/flwr/server/superlink/fleet/vce/vce_api.py @@ -20,6 +20,7 @@ import time import traceback from logging import DEBUG, ERROR, INFO, WARN +from pathlib import Path from typing import Callable, Dict, List, Optional from flwr.client.client_app import ClientApp, ClientAppException, LoadClientAppError @@ -274,6 +275,7 @@ def start_vce( # Use mapping constructed externally. This also means nodes # have previously being registered. nodes_mapping = existing_nodes_mapping + app_dir = str(Path(app_dir).absolute()) if not state_factory: log(INFO, "A StateFactory was not supplied to the SimulationEngine.") From 77031b1078c81aebe509ffe891c44abeed34538f Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Mon, 17 Jun 2024 21:58:47 +0100 Subject: [PATCH 084/124] refactor(framework:skip) Add `get_project_dir` and `get_project_config` (#3612) --- src/py/flwr/client/supernode/app.py | 43 +++++---------------------- src/py/flwr/common/config.py | 45 ++++++++++++++++++++++++++++- src/py/flwr/common/constant.py | 5 ++++ 3 files changed, 56 insertions(+), 37 deletions(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index d1d2bc197ce9..97951f2a3279 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -20,7 +20,6 @@ from pathlib import Path from typing import Callable, Optional, Tuple -import tomli from cryptography.exceptions import UnsupportedAlgorithm from cryptography.hazmat.primitives.asymmetric import ec from cryptography.hazmat.primitives.serialization import ( @@ -28,10 +27,9 @@ load_ssh_public_key, ) -from flwr.cli.config_utils import validate_fields from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import EventType, event -from flwr.common.config import get_flwr_dir +from flwr.common.config import get_flwr_dir, get_project_config, get_project_dir from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log, warn_deprecated_feature from flwr.common.object_ref import load_app, validate @@ -172,7 +170,7 @@ def _get_load_client_app_fn( if args.flwr_dir is None: flwr_dir = get_flwr_dir() else: - flwr_dir = Path(args.flwr_dir) + flwr_dir = Path(args.flwr_dir).absolute() sys.path.insert(0, str(flwr_dir.absolute())) @@ -211,38 +209,11 @@ def _load(fab_id: str, fab_version: str) -> ClientApp: client_app_ref = default_app_ref # If multi-app feature is enabled else: - # Check the fab_id - if fab_id.count("/") != 1: - raise LoadClientAppError( - f"Invalid FAB ID: {fab_id}", - ) from None - username, project_name = fab_id.split("/") - - # Locate the directory - project_dir = flwr_dir / "apps" / username / project_name / fab_version - - # Check if the directory exists - if not project_dir.exists(): - raise LoadClientAppError( - f"Invalid Flower App directory: {project_dir}", - ) from None - - # Load pyproject.toml file - toml_path = project_dir / "pyproject.toml" - if not toml_path.is_file(): - raise LoadClientAppError( - f"Cannot find pyproject.toml in {project_dir}", - ) from None - with open(toml_path, encoding="utf-8") as toml_file: - config = tomli.loads(toml_file.read()) - - # Validate pyproject.toml fields - is_valid, errors, _ = validate_fields(config) - if not is_valid: - error_msg = "\n".join([f" - {error}" for error in errors]) - raise LoadClientAppError( - f"Invalid pyproject.toml:\n{error_msg}", - ) from None + try: + project_dir = get_project_dir(fab_id, fab_version, flwr_dir) + config = get_project_config(project_dir) + except Exception as e: + raise LoadClientAppError("Failed to load ClientApp") from e # Get sys path to be inserted sys_path = Path(project_dir).absolute() diff --git a/src/py/flwr/common/config.py b/src/py/flwr/common/config.py index 2c5b5962e7bd..95bf8ce31c45 100644 --- a/src/py/flwr/common/config.py +++ b/src/py/flwr/common/config.py @@ -16,13 +16,56 @@ import os from pathlib import Path +from typing import Any, Dict, Optional, Union + +import tomli + +from flwr.cli.config_utils import validate_fields +from flwr.common.constant import APP_DIR, FAB_CONFIG_FILE, FLWR_HOME def get_flwr_dir() -> Path: """Return the Flower home directory based on env variables.""" return Path( os.getenv( - "FLWR_HOME", + FLWR_HOME, f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", ) ) + + +def get_project_dir( + fab_id: str, fab_version: str, flwr_dir: Optional[Union[str, Path]] = None +) -> Path: + """Return the project directory based on the given fab_id and fab_version.""" + # Check the fab_id + if fab_id.count("/") != 1: + raise ValueError( + f"Invalid FAB ID: {fab_id}", + ) + publisher, project_name = fab_id.split("/") + if flwr_dir is None: + flwr_dir = get_flwr_dir() + return Path(flwr_dir) / APP_DIR / publisher / project_name / fab_version + + +def get_project_config(project_dir: Union[str, Path]) -> Dict[str, Any]: + """Return pyproject.toml in the given project directory.""" + # Load pyproject.toml file + toml_path = Path(project_dir) / FAB_CONFIG_FILE + if not toml_path.is_file(): + raise FileNotFoundError( + f"Cannot find {FAB_CONFIG_FILE} in {project_dir}", + ) + with toml_path.open(encoding="utf-8") as toml_file: + config = tomli.loads(toml_file.read()) + + # Validate pyproject.toml fields + is_valid, errors, _ = validate_fields(config) + if not is_valid: + error_msg = "\n".join([f" - {error}" for error in errors]) + raise ValueError( + f"Invalid {FAB_CONFIG_FILE}:\n{error_msg}", + ) + + return config diff --git a/src/py/flwr/common/constant.py b/src/py/flwr/common/constant.py index 0722ab7d167e..1548694858fe 100644 --- a/src/py/flwr/common/constant.py +++ b/src/py/flwr/common/constant.py @@ -45,6 +45,11 @@ PING_RANDOM_RANGE = (-0.1, 0.1) PING_MAX_INTERVAL = 1e300 +# Constants for FAB +APP_DIR = "apps" +FAB_CONFIG_FILE = "pyproject.toml" +FLWR_HOME = "FLWR_HOME" + class MessageType: """Message type.""" From 8ea769cbbe7376be2dd54d1ceaa500cee84f0c87 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Mon, 17 Jun 2024 23:05:36 +0200 Subject: [PATCH 085/124] docs(framework) Update translation text (#3631) --- doc/locales/fr/LC_MESSAGES/framework-docs.po | 3283 ++-- doc/locales/ko/LC_MESSAGES/framework-docs.po | 13496 +++++++++------- .../pt_BR/LC_MESSAGES/framework-docs.po | 3086 ++-- .../zh_Hans/LC_MESSAGES/framework-docs.po | 4100 +++-- 4 files changed, 14305 insertions(+), 9660 deletions(-) diff --git a/doc/locales/fr/LC_MESSAGES/framework-docs.po b/doc/locales/fr/LC_MESSAGES/framework-docs.po index 67edf687bbbe..6624d91f9e64 100644 --- a/doc/locales/fr/LC_MESSAGES/framework-docs.po +++ b/doc/locales/fr/LC_MESSAGES/framework-docs.po @@ -3,7 +3,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower Docs\n" "Report-Msgid-Bugs-To: EMAIL@ADDRESS\n" -"POT-Creation-Date: 2024-05-28 11:47+0200\n" +"POT-Creation-Date: 2024-06-17 16:09+0200\n" "PO-Revision-Date: 2023-09-05 17:54+0000\n" "Last-Translator: Charles Beauville \n" "Language: fr\n" @@ -61,248 +61,248 @@ msgstr "" msgid "" "Flower provides pre-made docker images on `Docker Hub " "`_ that include all necessary dependencies" -" for running the SuperLink. You can also build your own custom docker " -"images from scratch with a different version of Python or Ubuntu if that " -"is what you need. In this guide, we will explain what images exist and " -"how to build them locally." +" for running the SuperLink, SuperNode or ServerApp. You can also build " +"your own custom docker images from scratch with a different version of " +"Python or Linux distribution (Ubuntu/Alpine) if that is what you need. In" +" this guide, we will explain what images exist and how to build them " +"locally." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:9 +#: ../../source/contributor-how-to-build-docker-images.rst:10 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:11 +#: ../../source/contributor-how-to-build-docker-images.rst:12 #, fuzzy msgid "Clone the flower repository." msgstr "**Fourche le dépôt de Flower**" -#: ../../source/contributor-how-to-build-docker-images.rst:17 -#: ../../source/how-to-run-flower-using-docker.rst:144 +#: ../../source/contributor-how-to-build-docker-images.rst:18 +#: ../../source/how-to-run-flower-using-docker.rst:165 msgid "Verify the Docker daemon is running." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:19 -#: ../../source/how-to-run-flower-using-docker.rst:146 +#: ../../source/contributor-how-to-build-docker-images.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:167 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:23 -msgid "" -"Currently, Flower provides two images, a ``base`` image and a " -"``superlink`` image. The base image, as the name suggests, contains basic" -" dependencies that the SuperLink needs. This includes system " -"dependencies, Python and Python tools. The SuperLink image is based on " -"the base image, but it additionally installs the SuperLink using ``pip``." -msgstr "" - -#: ../../source/contributor-how-to-build-docker-images.rst:28 +#: ../../source/contributor-how-to-build-docker-images.rst:25 msgid "" "The build instructions that assemble the images are located in the " "respective Dockerfiles. You can find them in the subdirectories of " "``src/docker``." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:31 +#: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" -"Both, base and SuperLink image are configured via build arguments. " -"Through build arguments, we can make our build more flexible. For " -"example, in the base image, we can specify the version of Python to " -"install using the ``PYTHON_VERSION`` build argument. Some of the build " -"arguments have default values, others must be specified when building the" -" image. All available build arguments for each image are listed in one of" -" the tables below." +"Flower Docker images are configured via build arguments. Through build " +"arguments, we can make the creation of images more flexible. For example," +" in the base image, we can specify the version of Python to install using" +" the ``PYTHON_VERSION`` build argument. Some of the build arguments have " +"default values, others must be specified when building the image. All " +"available build arguments for each image are listed in one of the tables " +"below." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:38 +#: ../../source/contributor-how-to-build-docker-images.rst:35 #, fuzzy msgid "Building the base image" msgstr "Chargement des données" -#: ../../source/contributor-how-to-build-docker-images.rst:44 -#: ../../source/contributor-how-to-build-docker-images.rst:86 +#: ../../source/contributor-how-to-build-docker-images.rst:41 +#: ../../source/contributor-how-to-build-docker-images.rst:98 #, fuzzy msgid "Build argument" msgstr "Amélioration de la documentation" -#: ../../source/contributor-how-to-build-docker-images.rst:45 -#: ../../source/contributor-how-to-build-docker-images.rst:87 +#: ../../source/contributor-how-to-build-docker-images.rst:42 +#: ../../source/contributor-how-to-build-docker-images.rst:99 #, fuzzy msgid "Description" msgstr "Dépréciations" -#: ../../source/contributor-how-to-build-docker-images.rst:46 -#: ../../source/contributor-how-to-build-docker-images.rst:88 +#: ../../source/contributor-how-to-build-docker-images.rst:43 +#: ../../source/contributor-how-to-build-docker-images.rst:100 #, fuzzy msgid "Required" msgstr "Changements nécessaires" -#: ../../source/contributor-how-to-build-docker-images.rst:47 -#: ../../source/contributor-how-to-build-docker-images.rst:89 +#: ../../source/contributor-how-to-build-docker-images.rst:44 +#: ../../source/contributor-how-to-build-docker-images.rst:101 #, fuzzy msgid "Example" msgstr "Exemples de PyTorch" -#: ../../source/contributor-how-to-build-docker-images.rst:48 -#: ../../source/contributor-how-to-build-docker-images.rst:94 -#, fuzzy -msgid "``PYTHON_VERSION``" -msgstr "Version Python" - -#: ../../source/contributor-how-to-build-docker-images.rst:49 -msgid "Version of ``python`` to be installed." +#: ../../source/contributor-how-to-build-docker-images.rst:45 +msgid "``DISTRO``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:50 -#: ../../source/contributor-how-to-build-docker-images.rst:54 -#: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:108 +#: ../../source/contributor-how-to-build-docker-images.rst:46 #, fuzzy -msgid "Yes" -msgstr "Types" +msgid "The Linux distribution to use as the base image." +msgstr "Chargement des données" +#: ../../source/contributor-how-to-build-docker-images.rst:47 #: ../../source/contributor-how-to-build-docker-images.rst:51 +#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:71 +#: ../../source/contributor-how-to-build-docker-images.rst:104 #, fuzzy -msgid "``3.11``" -msgstr "1.0.0rc1" +msgid "No" +msgstr "Aucun" -#: ../../source/contributor-how-to-build-docker-images.rst:52 -msgid "``PIP_VERSION``" +#: ../../source/contributor-how-to-build-docker-images.rst:48 +msgid "``ubuntu``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:53 -msgid "Version of ``pip`` to be installed." +#: ../../source/contributor-how-to-build-docker-images.rst:49 +#, fuzzy +msgid "``DISTRO_VERSION``" +msgstr "Version Python" + +#: ../../source/contributor-how-to-build-docker-images.rst:50 +msgid "Version of the Linux distribution." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:52 #, fuzzy -msgid "``23.0.1``" +msgid "``22.04``" msgstr "1.0.0rc1" +#: ../../source/contributor-how-to-build-docker-images.rst:53 +#, fuzzy +msgid "``PYTHON_VERSION``" +msgstr "Version Python" + +#: ../../source/contributor-how-to-build-docker-images.rst:54 +msgid "Version of ``python`` to be installed." +msgstr "" + #: ../../source/contributor-how-to-build-docker-images.rst:56 -msgid "``SETUPTOOLS_VERSION``" +msgid "``3.11`` or ``3.11.1``" msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:57 -msgid "Version of ``setuptools`` to be installed." +msgid "``PIP_VERSION``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:58 +msgid "Version of ``pip`` to be installed." msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:63 +#: ../../source/contributor-how-to-build-docker-images.rst:67 +#: ../../source/contributor-how-to-build-docker-images.rst:108 #, fuzzy -msgid "``69.0.2``" -msgstr "``1.0.0b0``" +msgid "Yes" +msgstr "Types" #: ../../source/contributor-how-to-build-docker-images.rst:60 -#: ../../source/contributor-how-to-build-docker-images.rst:98 -msgid "``UBUNTU_VERSION``" -msgstr "" +#, fuzzy +msgid "``23.0.1``" +msgstr "1.0.0rc1" #: ../../source/contributor-how-to-build-docker-images.rst:61 -msgid "Version of the official Ubuntu Docker image." +msgid "``SETUPTOOLS_VERSION``" msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:62 -msgid "Defaults to ``22.04``." +msgid "Version of ``setuptools`` to be installed." msgstr "" +#: ../../source/contributor-how-to-build-docker-images.rst:64 +#, fuzzy +msgid "``69.0.2``" +msgstr "``1.0.0b0``" + #: ../../source/contributor-how-to-build-docker-images.rst:65 -msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1" -" and setuptools 69.0.2:" +msgid "``FLWR_VERSION``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:76 -msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +#: ../../source/contributor-how-to-build-docker-images.rst:66 +msgid "Version of Flower to be installed." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:80 +#: ../../source/contributor-how-to-build-docker-images.rst:68 #, fuzzy -msgid "Building the SuperLink image" -msgstr "Démarrer le serveur" +msgid "``1.8.0``" +msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-build-docker-images.rst:90 -msgid "``BASE_REPOSITORY``" +#: ../../source/contributor-how-to-build-docker-images.rst:69 +msgid "``FLWR_PACKAGE``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:91 -msgid "The repository name of the base image." +#: ../../source/contributor-how-to-build-docker-images.rst:70 +msgid "The Flower package to be installed." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:92 -msgid "Defaults to ``flwr/base``." +#: ../../source/contributor-how-to-build-docker-images.rst:72 +msgid "``flwr`` or ``flwr-nightly``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:95 -#, fuzzy -msgid "The Python version of the base image." -msgstr "Évaluer la réponse d'un client." +#: ../../source/contributor-how-to-build-docker-images.rst:75 +msgid "" +"The following example creates a base Ubuntu/Alpine image with Python " +"3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:96 -msgid "Defaults to ``py3.11``." +#: ../../source/contributor-how-to-build-docker-images.rst:88 +msgid "" +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " +"the build arguments as well as the name and tag can be adapted to your " +"needs. These values serve as examples only." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:99 +#: ../../source/contributor-how-to-build-docker-images.rst:92 #, fuzzy -msgid "The Ubuntu version of the base image." -msgstr "Chargement des données" - -#: ../../source/contributor-how-to-build-docker-images.rst:100 -msgid "Defaults to ``ubuntu22.04``." -msgstr "" +msgid "Building the SuperLink/SuperNode or ServerApp image" +msgstr "Démarrer le serveur" #: ../../source/contributor-how-to-build-docker-images.rst:102 -msgid "``FLWR_PACKAGE``" +msgid "``BASE_REPOSITORY``" msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:103 -msgid "The PyPI package to install." +msgid "The repository name of the base image." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:104 -#, fuzzy -msgid "Defaults to ``flwr``." -msgstr "Flux de travail" +#: ../../source/contributor-how-to-build-docker-images.rst:105 +msgid "``flwr/base``" +msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:106 -msgid "``FLWR_VERSION``" +msgid "``BASE_IMAGE``" msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:107 -msgid "Version of Flower to be installed." -msgstr "" - -#: ../../source/contributor-how-to-build-docker-images.rst:109 #, fuzzy -msgid "``1.8.0``" -msgstr "``1.0.0b0``" +msgid "The Tag of the Flower base image." +msgstr "Chargement des données" -#: ../../source/contributor-how-to-build-docker-images.rst:112 -msgid "" -"The following example creates a SuperLink image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.8.0:" +#: ../../source/contributor-how-to-build-docker-images.rst:109 +msgid "``1.8.0-py3.10-ubuntu22.04``" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:122 +#: ../../source/contributor-how-to-build-docker-images.rst:111 msgid "" -"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " -"that the build arguments as well as the name and tag can be adapted to " -"your needs. These values serve as examples only." +"The following example creates a SuperLink/SuperNode or ServerApp image " +"with the official Flower base image:" msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:125 +#: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" "If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." +"base image, all you need to do is set the ``BASE_REPOSITORY`` build " +"argument." msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:138 +#: ../../source/contributor-how-to-build-docker-images.rst:133 msgid "After creating the image, we can test whether the image is working:" msgstr "" @@ -414,146 +414,6 @@ msgid "" " on our `GitHub repo `_." msgstr "" -#: ../../source/contributor-how-to-create-new-messages.rst:2 -msgid "Creating New Messages" -msgstr "Création de nouveaux messages" - -#: ../../source/contributor-how-to-create-new-messages.rst:4 -msgid "" -"This is a simple guide for creating a new type of message between the " -"server and clients in Flower." -msgstr "" -"Voici un guide simple pour créer un nouveau type de message entre le " -"serveur et les clients dans Flower." - -#: ../../source/contributor-how-to-create-new-messages.rst:6 -msgid "" -"Let's suppose we have the following example functions in " -":code:`server.py` and :code:`numpy_client.py`..." -msgstr "" -"Supposons que nous ayons les fonctions suivantes dans :code:`server.py` " -"et :code:`numpy_client.py`..." - -#: ../../source/contributor-how-to-create-new-messages.rst:8 -msgid "Server's side:" -msgstr "Côté serveur :" - -#: ../../source/contributor-how-to-create-new-messages.rst:17 -msgid "Client's side:" -msgstr "Côté client :" - -#: ../../source/contributor-how-to-create-new-messages.rst:26 -msgid "" -"Let's now see what we need to implement in order to get this simple " -"function between the server and client to work!" -msgstr "" -"Voyons maintenant ce que nous devons mettre en œuvre pour que cette " -"simple fonction entre le serveur et le client fonctionne !" - -#: ../../source/contributor-how-to-create-new-messages.rst:30 -msgid "Message Types for Protocol Buffers" -msgstr "Types de messages pour les tampons de protocole" - -#: ../../source/contributor-how-to-create-new-messages.rst:32 -#, fuzzy -msgid "" -"The first thing we need to do is to define a message type for the RPC " -"system in :code:`transport.proto`. Note that we have to do it for both " -"the request and response messages. For more details on the syntax of " -"proto3, please see the `official documentation `_." -msgstr "" -"La première chose à faire est de définir un type de message pour le " -"système RPC dans :code:`transport.proto`. Notez que nous devons le faire " -"à la fois pour les messages de demande et de réponse. Pour plus de " -"détails sur la syntaxe de proto3, veuillez consulter la `documentation " -"officielle `_." - -#: ../../source/contributor-how-to-create-new-messages.rst:35 -msgid "Within the :code:`ServerMessage` block:" -msgstr "Dans le bloc :code:`ServerMessage` :" - -#: ../../source/contributor-how-to-create-new-messages.rst:52 -msgid "Within the ClientMessage block:" -msgstr "Dans le bloc ClientMessage :" - -#: ../../source/contributor-how-to-create-new-messages.rst:70 -msgid "" -"Make sure to also add a field of the newly created message type in " -":code:`oneof msg`." -msgstr "" -"Veille à ajouter également un champ du type de message nouvellement créé " -"dans :code:`oneof msg`." - -#: ../../source/contributor-how-to-create-new-messages.rst:72 -msgid "Once that is done, we will compile the file with:" -msgstr "Une fois que c'est fait, nous compilerons le fichier avec :" - -#: ../../source/contributor-how-to-create-new-messages.rst:78 -msgid "If it compiles successfully, you should see the following message:" -msgstr "S'il se compile avec succès, tu devrais voir le message suivant :" - -#: ../../source/contributor-how-to-create-new-messages.rst:87 -msgid "Serialization and Deserialization Functions" -msgstr "Fonctions de sérialisation et de désérialisation" - -#: ../../source/contributor-how-to-create-new-messages.rst:89 -msgid "" -"Our next step is to add functions to serialize and deserialize Python " -"datatypes to or from our defined RPC message types. You should add these " -"functions in :code:`serde.py`." -msgstr "" -"La prochaine étape consiste à ajouter des fonctions pour sérialiser et " -"désérialiser les types de données Python vers ou à partir des types de " -"messages RPC définis. Tu dois ajouter ces fonctions dans " -":code:`serde.py`." - -#: ../../source/contributor-how-to-create-new-messages.rst:91 -msgid "The four functions:" -msgstr "Les quatre fonctions :" - -#: ../../source/contributor-how-to-create-new-messages.rst:112 -msgid "Sending the Message from the Server" -msgstr "Envoi du message à partir du serveur" - -#: ../../source/contributor-how-to-create-new-messages.rst:114 -msgid "" -"Now write the request function in your Client Proxy class (e.g., " -":code:`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "" -"Écris maintenant la fonction de demande dans ta classe Client Proxy (par " -"exemple, :code:`grpc_client_proxy.py`) en utilisant les fonctions serde " -"que tu viens de créer :" - -#: ../../source/contributor-how-to-create-new-messages.rst:128 -msgid "Receiving the Message by the Client" -msgstr "Réception du message par le client" - -#: ../../source/contributor-how-to-create-new-messages.rst:130 -msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the " -"field of your message and call the :code:`example_response` function. " -"Remember to use the serde functions!" -msgstr "" -"Dernière étape ! Modifie le code dans :code:`message_handler.py` pour " -"vérifier le champ de ton message et appeler la fonction " -":code:`example_response`. N'oublie pas d'utiliser les fonctions serde !" - -#: ../../source/contributor-how-to-create-new-messages.rst:132 -msgid "Within the handle function:" -msgstr "Dans le cadre de la fonction de poignée :" - -#: ../../source/contributor-how-to-create-new-messages.rst:139 -msgid "And add a new function:" -msgstr "Et ajoute une nouvelle fonction :" - -#: ../../source/contributor-how-to-create-new-messages.rst:149 -msgid "Hopefully, when you run your program you will get the intended result!" -msgstr "" -"Avec un peu de chance, lorsque tu exécuteras ton programme, tu obtiendras" -" le résultat escompté !" - #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" msgstr "Utiliser les conteneurs VS Code Remote" @@ -961,29 +821,79 @@ msgstr "" msgid "Check the draft release on GitHub, and if everything is good, publish it." msgstr "" +#: ../../source/contributor-how-to-release-flower.rst:15 +#, fuzzy +msgid "Trigger the CI for building the Docker images." +msgstr "Démarrer le serveur" + #: ../../source/contributor-how-to-release-flower.rst:17 +msgid "" +"To trigger the workflow, a collaborator must create a " +"``workflow_dispatch`` event in the GitHub CI. This can be done either " +"through the UI or via the GitHub CLI. The event requires only one input, " +"the Flower version, to be released." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:21 +#, fuzzy +msgid "**Via the UI**" +msgstr "**Review the PR**" + +#: ../../source/contributor-how-to-release-flower.rst:23 +msgid "" +"Go to the ``Build docker images`` workflow `page " +"`_." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:24 +msgid "" +"Click on the ``Run workflow`` button and type the new version of Flower " +"in the ``Version of Flower`` input field." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:25 +msgid "Click on the **green** ``Run workflow`` button." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:29 +msgid "**Via the GitHub CI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:31 +msgid "" +"Make sure you are logged in via ``gh auth login`` and that the current " +"working directory is the root of the Flower repository." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:32 +msgid "" +"Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" +"version=``." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" msgstr "Après la publication" -#: ../../source/contributor-how-to-release-flower.rst:19 +#: ../../source/contributor-how-to-release-flower.rst:37 msgid "Create a pull request which contains the following changes:" msgstr "Crée une demande de pull qui contient les modifications suivantes :" -#: ../../source/contributor-how-to-release-flower.rst:21 +#: ../../source/contributor-how-to-release-flower.rst:39 msgid "Increase the minor version in ``pyproject.toml`` by one." msgstr "Augmente la version mineure de ``pyproject.toml`` d'une unité." -#: ../../source/contributor-how-to-release-flower.rst:22 +#: ../../source/contributor-how-to-release-flower.rst:40 msgid "Update all files which contain the current version number if necessary." msgstr "" "Mets à jour tous les fichiers qui contiennent le numéro de version actuel" " si nécessaire." -#: ../../source/contributor-how-to-release-flower.rst:23 +#: ../../source/contributor-how-to-release-flower.rst:41 msgid "Add a new ``Unreleased`` section in ``changelog.md``." msgstr "Ajoute une nouvelle section ``Unreleased`` dans ``changelog.md``." -#: ../../source/contributor-how-to-release-flower.rst:25 +#: ../../source/contributor-how-to-release-flower.rst:43 msgid "" "Merge the pull request on the same day (i.e., before a new nightly " "release gets published to PyPI)." @@ -991,15 +901,15 @@ msgstr "" "Fusionne la pull request le jour même (c'est-à-dire avant qu'une nouvelle" " version nightly ne soit publiée sur PyPI)." -#: ../../source/contributor-how-to-release-flower.rst:28 +#: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" msgstr "Publier une pré-version" -#: ../../source/contributor-how-to-release-flower.rst:31 +#: ../../source/contributor-how-to-release-flower.rst:49 msgid "Pre-release naming" msgstr "Nom de la pré-version" -#: ../../source/contributor-how-to-release-flower.rst:33 +#: ../../source/contributor-how-to-release-flower.rst:51 msgid "" "PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" " MUST use one of the following naming patterns:" @@ -1008,39 +918,39 @@ msgstr "" "Les préversions DOIVENT utiliser l'un des modèles de dénomination " "suivants :" -#: ../../source/contributor-how-to-release-flower.rst:35 +#: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" msgstr "Alpha : ``MAJOR.MINOR.PATCHaN``" -#: ../../source/contributor-how-to-release-flower.rst:36 +#: ../../source/contributor-how-to-release-flower.rst:54 msgid "Beta: ``MAJOR.MINOR.PATCHbN``" msgstr "Bêta : ``MAJOR.MINOR.PATCHbN``" -#: ../../source/contributor-how-to-release-flower.rst:37 +#: ../../source/contributor-how-to-release-flower.rst:55 msgid "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" msgstr "Candidat à la publication (RC) : ``MAJOR.MINOR.PATCHrcN``" -#: ../../source/contributor-how-to-release-flower.rst:39 +#: ../../source/contributor-how-to-release-flower.rst:57 msgid "Examples include:" msgstr "Voici quelques exemples :" -#: ../../source/contributor-how-to-release-flower.rst:41 +#: ../../source/contributor-how-to-release-flower.rst:59 msgid "``1.0.0a0``" msgstr "``1.0.0a0``" -#: ../../source/contributor-how-to-release-flower.rst:42 +#: ../../source/contributor-how-to-release-flower.rst:60 msgid "``1.0.0b0``" msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-release-flower.rst:43 +#: ../../source/contributor-how-to-release-flower.rst:61 msgid "``1.0.0rc0``" msgstr "``1.0.0rc0``" -#: ../../source/contributor-how-to-release-flower.rst:44 +#: ../../source/contributor-how-to-release-flower.rst:62 msgid "``1.0.0rc1``" msgstr "1.0.0rc1" -#: ../../source/contributor-how-to-release-flower.rst:46 +#: ../../source/contributor-how-to-release-flower.rst:64 msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" @@ -1048,11 +958,11 @@ msgstr "" "Ceci est conforme au PEP-440 et aux recommandations de l'Autorité de " "l'emballage Python (PyPA) :" -#: ../../source/contributor-how-to-release-flower.rst:49 +#: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" msgstr "`PEP-440 `_" -#: ../../source/contributor-how-to-release-flower.rst:50 +#: ../../source/contributor-how-to-release-flower.rst:68 msgid "" "`PyPA Choosing a versioning scheme " "`_" -#: ../../source/contributor-how-to-release-flower.rst:52 +#: ../../source/contributor-how-to-release-flower.rst:70 msgid "" "Note that the approach defined by PyPA is not compatible with SemVer " "2.0.0 spec, for details consult the `Semantic Versioning Specification " @@ -1074,17 +984,17 @@ msgstr "" "Versioning Specification `_ (en particulier le point 11 sur la préséance)." -#: ../../source/contributor-how-to-release-flower.rst:55 +#: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" msgstr "Classification avant publication" -#: ../../source/contributor-how-to-release-flower.rst:57 +#: ../../source/contributor-how-to-release-flower.rst:75 msgid "Should the next pre-release be called alpha, beta, or release candidate?" msgstr "" "La prochaine préversion doit-elle être appelée alpha, bêta ou release " "candidate ?" -#: ../../source/contributor-how-to-release-flower.rst:59 +#: ../../source/contributor-how-to-release-flower.rst:77 msgid "" "RC: feature complete, no known issues (apart from issues that are " "classified as \"won't fix\" for the next stable release) - if no issues " @@ -1095,11 +1005,11 @@ msgstr "" "version stable) - si aucun problème n'apparaît, cette version deviendra " "la prochaine version stable" -#: ../../source/contributor-how-to-release-flower.rst:60 +#: ../../source/contributor-how-to-release-flower.rst:78 msgid "Beta: feature complete, allowed to have known issues" msgstr "Bêta : fonctionnalité complète, autorisée à avoir des problèmes connus" -#: ../../source/contributor-how-to-release-flower.rst:61 +#: ../../source/contributor-how-to-release-flower.rst:79 msgid "Alpha: not feature complete, allowed to have known issues" msgstr "" "Alpha : les fonctionnalités ne sont pas complètes, les problèmes connus " @@ -2310,7 +2220,7 @@ msgid "Get started as a contributor" msgstr "Devenez un·e contributeur·ice" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 -#: ../../source/how-to-run-flower-using-docker.rst:132 +#: ../../source/how-to-run-flower-using-docker.rst:153 msgid "Prerequisites" msgstr "Prérequis" @@ -4606,11 +4516,11 @@ msgid "" "authentication enabled:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:36 +#: ../../source/how-to-authenticate-supernodes.rst:38 msgid "Let's break down the authentication flags:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:38 +#: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" "The first flag :code:`--auth-list-public-keys` expects a path to a CSV " "file storing all known node public keys. You need to store all known node" @@ -4618,7 +4528,7 @@ msgid "" "file (:code:`.csv`)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:40 +#: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " @@ -4626,7 +4536,7 @@ msgid "" "known node public keys." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:42 +#: ../../source/how-to-authenticate-supernodes.rst:44 msgid "" "The second and third flags :code:`--auth-superlink-private-key` and :code" ":`--auth-superlink-public-key` expect paths to the server's private and " @@ -4634,7 +4544,7 @@ msgid "" "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:45 +#: ../../source/how-to-authenticate-supernodes.rst:47 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " "adding known node public keys to the SuperLink. To change the set of " @@ -4643,11 +4553,11 @@ msgid "" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:51 +#: ../../source/how-to-authenticate-supernodes.rst:53 msgid "Enable node authentication in :code:`SuperNode`" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:53 +#: ../../source/how-to-authenticate-supernodes.rst:55 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " "easily enable node authentication in the long-running Flower client " @@ -4655,7 +4565,7 @@ msgid "" "authenticated :code:`SuperNode`:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:64 +#: ../../source/how-to-authenticate-supernodes.rst:66 msgid "" "The :code:`--auth-supernode-private-key` flag expects a path to the " "node's private key file and the :code:`--auth-supernode-public-key` flag " @@ -4664,11 +4574,11 @@ msgid "" " ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:68 +#: ../../source/how-to-authenticate-supernodes.rst:70 msgid "Security notice" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:70 +#: ../../source/how-to-authenticate-supernodes.rst:72 msgid "" "The system's security relies on the credentials of the SuperLink and each" " SuperNode. Therefore, it is imperative to safeguard and safely store the" @@ -4679,14 +4589,14 @@ msgid "" "methods." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:75 -#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:68 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" msgstr "Conclusion" -#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-authenticate-supernodes.rst:79 msgid "" "You should now have learned how to start a long-running Flower server " "(:code:`SuperLink`) and client (:code:`SuperNode`) with node " @@ -5059,19 +4969,19 @@ msgstr "" "Nous allons maintenant montrer comment écrire un client qui utilise les " "scripts générés précédemment :" -#: ../../source/how-to-enable-ssl-connections.rst:47 +#: ../../source/how-to-enable-ssl-connections.rst:50 msgid "" "When providing certificates, the server expects a tuple of three " "certificates paths: CA certificate, server certificate and server private" " key." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:51 +#: ../../source/how-to-enable-ssl-connections.rst:54 #, fuzzy msgid "Client (SuperNode)" msgstr "Codes d'état du client." -#: ../../source/how-to-enable-ssl-connections.rst:53 +#: ../../source/how-to-enable-ssl-connections.rst:56 #, fuzzy msgid "" "Use the following terminal command to start a client (SuperNode) that " @@ -5080,7 +4990,7 @@ msgstr "" "Nous allons maintenant montrer comment écrire un client qui utilise les " "scripts générés précédemment :" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:64 #, fuzzy msgid "" "When setting :code:`root_certificates`, the client expects a file path to" @@ -5091,7 +5001,7 @@ msgstr "" "utilisons à nouveau :code:`Path` pour simplifier la lecture de ces " "certificats sous forme de chaînes d'octets." -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:70 #, fuzzy msgid "" "You should now have learned how to generate self-signed certificates " @@ -5102,12 +5012,12 @@ msgstr "" "à l'aide du script donné, à démarrer un serveur compatible SSL et à " "demander à un client d'établir une connexion sécurisée avec lui." -#: ../../source/how-to-enable-ssl-connections.rst:72 +#: ../../source/how-to-enable-ssl-connections.rst:75 #, fuzzy msgid "Additional resources" msgstr "Ressources supplémentaires" -#: ../../source/how-to-enable-ssl-connections.rst:74 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" @@ -5115,11 +5025,11 @@ msgstr "" "Ces sources supplémentaires peuvent être pertinentes si tu souhaites " "approfondir le sujet des certificats :" -#: ../../source/how-to-enable-ssl-connections.rst:76 +#: ../../source/how-to-enable-ssl-connections.rst:79 msgid "`Let's Encrypt `_" msgstr "`Let's Encrypt `_" -#: ../../source/how-to-enable-ssl-connections.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" msgstr "`certbot `_" @@ -5961,14 +5871,15 @@ msgstr "" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`__." +"`__. Supported architectures include " +"``amd64`` and ``arm64v8``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:7 +#: ../../source/how-to-run-flower-using-docker.rst:8 msgid "Before you start, make sure that the Docker daemon is running:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:14 +#: ../../source/how-to-run-flower-using-docker.rst:15 msgid "" "If you do not see the version of Docker but instead get an error saying " "that the command was not found, you will need to install Docker first. " @@ -5976,7 +5887,7 @@ msgid "" "docker/>`_." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:21 msgid "" "On Linux, Docker commands require ``sudo`` privilege. If you want to " "avoid using ``sudo``, you can follow the `Post-installation steps " @@ -5984,7 +5895,7 @@ msgid "" "official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:26 +#: ../../source/how-to-run-flower-using-docker.rst:27 msgid "" "To ensure optimal performance and compatibility, the SuperLink, SuperNode" " and ServerApp image must have the same version when running together. " @@ -5992,28 +5903,28 @@ msgid "" "issues that may arise from using different versions." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:31 +#: ../../source/how-to-run-flower-using-docker.rst:32 #, fuzzy msgid "Flower SuperLink" msgstr "flower-superlink" -#: ../../source/how-to-run-flower-using-docker.rst:34 +#: ../../source/how-to-run-flower-using-docker.rst:35 #, fuzzy msgid "Quickstart" msgstr "Démarrage rapide de JAX" -#: ../../source/how-to-run-flower-using-docker.rst:36 +#: ../../source/how-to-run-flower-using-docker.rst:37 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:42 +#: ../../source/how-to-run-flower-using-docker.rst:43 msgid "" "The command pulls the Docker image with the tag ``1.8.0`` from Docker " "Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " "The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:49 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " @@ -6021,7 +5932,7 @@ msgid "" "system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:52 +#: ../../source/how-to-run-flower-using-docker.rst:53 msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " @@ -6031,9 +5942,9 @@ msgid "" " flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:59 -#: ../../source/how-to-run-flower-using-docker.rst:238 -#: ../../source/how-to-run-flower-using-docker.rst:354 +#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:259 +#: ../../source/how-to-run-flower-using-docker.rst:376 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " @@ -6042,49 +5953,60 @@ msgid "" "deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:64 +#: ../../source/how-to-run-flower-using-docker.rst:65 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:71 +#: ../../source/how-to-run-flower-using-docker.rst:72 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:73 +#: ../../source/how-to-run-flower-using-docker.rst:74 msgid "" "If you want to persist the state of the SuperLink on your host system, " -"all you need to do is specify a path where you want to save the file on " -"your host system and a name for the database file. In the example below, " -"we tell Docker via the flag ``--volume`` to mount the user's home " -"directory (``~/`` on your host) into the ``/app/`` directory of the " -"container. Furthermore, we use the flag ``--database`` to specify the " -"name of the database file." +"all you need to do is specify a directory where you want to save the file" +" on your host system and a name for the database file. By default, the " +"SuperLink container runs with a non-root user called ``app`` with the " +"user ID ``49999``. It is recommended to create new directory and change " +"the user ID of the directory to ``49999`` to ensure the mounted directory" +" has the proper permissions. If you later want to delete the directory, " +"you can change the user ID back to the current user ID by running ``sudo " +"chown -R $USER:$(id -gn) state``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:82 +msgid "" +"In the example below, we create a new directory, change the user ID and " +"tell Docker via the flag ``--volume`` to mount the local ``state`` " +"directory into the ``/app/state`` directory of the container. " +"Furthermore, we use the flag ``--database`` to specify the name of the " +"database file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:86 +#: ../../source/how-to-run-flower-using-docker.rst:95 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, " -"the SuperLink tries to restore the state from the file. To start the " +"``state`` directory on your host system. If the file already exists, the " +"SuperLink tries to restore the state from the file. To start the " "SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:91 -#: ../../source/how-to-run-flower-using-docker.rst:260 -#: ../../source/how-to-run-flower-using-docker.rst:375 +#: ../../source/how-to-run-flower-using-docker.rst:100 +#: ../../source/how-to-run-flower-using-docker.rst:281 +#: ../../source/how-to-run-flower-using-docker.rst:397 #, fuzzy msgid "Enabling SSL for secure connections" msgstr "Collecte centralisée des données" -#: ../../source/how-to-run-flower-using-docker.rst:93 +#: ../../source/how-to-run-flower-using-docker.rst:102 msgid "" "To enable SSL, you will need a PEM-encoded root certificate, a PEM-" "encoded private key and a PEM-encoded certificate chain." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:97 +#: ../../source/how-to-run-flower-using-docker.rst:106 msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `__ is already installed " "in the ``flwr/supernode`` base image, so you only need to include other " @@ -6164,20 +6098,20 @@ msgid "" "``tensorflow``, etc." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:179 +#: ../../source/how-to-run-flower-using-docker.rst:200 msgid "" "Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " "example, create a new file called ``Dockerfile.supernode`` in ``examples" "/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:182 +#: ../../source/how-to-run-flower-using-docker.rst:203 msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:196 +#: ../../source/how-to-run-flower-using-docker.rst:217 msgid "" "In the first two lines, we instruct Docker to use the SuperNode image " "tagged ``nightly`` as a base image and set our working directory to " @@ -6190,70 +6124,70 @@ msgid "" "(``:``) that will be run inside the ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:205 +#: ../../source/how-to-run-flower-using-docker.rst:226 #, fuzzy msgid "Building the SuperNode Docker image" msgstr "Démarrer le serveur" -#: ../../source/how-to-run-flower-using-docker.rst:207 +#: ../../source/how-to-run-flower-using-docker.rst:228 msgid "" "Next, we build the SuperNode Docker image by running the following " "command in the directory where Dockerfile and ClientApp code are located." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:214 +#: ../../source/how-to-run-flower-using-docker.rst:235 msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:219 +#: ../../source/how-to-run-flower-using-docker.rst:240 #, fuzzy msgid "Running the SuperNode Docker image" msgstr "Démarrer le serveur" -#: ../../source/how-to-run-flower-using-docker.rst:221 +#: ../../source/how-to-run-flower-using-docker.rst:242 msgid "Now that we have built the SuperNode image, we can finally run it." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:229 -#: ../../source/how-to-run-flower-using-docker.rst:345 +#: ../../source/how-to-run-flower-using-docker.rst:250 +#: ../../source/how-to-run-flower-using-docker.rst:367 msgid "Let's break down each part of this command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:231 -#: ../../source/how-to-run-flower-using-docker.rst:347 +#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:369 msgid "``docker run``: This is the command to run a new Docker container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:232 -#: ../../source/how-to-run-flower-using-docker.rst:348 +#: ../../source/how-to-run-flower-using-docker.rst:253 +#: ../../source/how-to-run-flower-using-docker.rst:370 msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:233 +#: ../../source/how-to-run-flower-using-docker.rst:254 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:234 -#: ../../source/how-to-run-flower-using-docker.rst:350 +#: ../../source/how-to-run-flower-using-docker.rst:255 +#: ../../source/how-to-run-flower-using-docker.rst:372 msgid "``--insecure``: This option enables insecure communication." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the" -" SuperLinks Fleet" +"``--superlink 192.168.1.100:9092``: This option specifies the address of " +"the SuperLinks Fleet" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "API to connect to. Remember to update it with your SuperLink IP." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:248 +#: ../../source/how-to-run-flower-using-docker.rst:269 msgid "" "To test running Flower locally, you can create a `bridge network " "`__." +" `Docker Hub `__." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:400 +#: ../../source/how-to-run-flower-using-docker.rst:460 msgid "Pinning a Docker image to a specific version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:402 +#: ../../source/how-to-run-flower-using-docker.rst:462 msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " @@ -6432,22 +6404,22 @@ msgid "" "instead of the tag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:407 +#: ../../source/how-to-run-flower-using-docker.rst:467 msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:414 +#: ../../source/how-to-run-flower-using-docker.rst:474 msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:423 +#: ../../source/how-to-run-flower-using-docker.rst:483 #, fuzzy msgid "Setting environment variables" msgstr "Mise en place de l'environnement de codage" -#: ../../source/how-to-run-flower-using-docker.rst:425 +#: ../../source/how-to-run-flower-using-docker.rst:485 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." @@ -7433,9 +7405,10 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" -"Here's another example to start with HTTPS. Use the ``--certificates`` " -"command line argument to pass paths to (CA certificate, server " -"certificate, and server private key)." +"Here's another example to start with HTTPS. Use the ``--ssl-ca-" +"certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line " +"options to pass paths to (CA certificate, server certificate, and server " +"private key)." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:201 @@ -7958,12 +7931,12 @@ msgstr "Configuration du contributeur" msgid "Contributor how-to guides" msgstr "Guide pour les contributeurs" -#: ../../source/index.rst:173 +#: ../../source/index.rst:172 #, fuzzy msgid "Contributor explanations" msgstr "Explications" -#: ../../source/index.rst:179 +#: ../../source/index.rst:178 #, fuzzy msgid "Contributor references" msgstr "Configuration du contributeur" @@ -8141,7 +8114,8 @@ msgstr "flower-driver-api" msgid "flwr" msgstr "Fleur" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 +#: ../../source/ref-api/flwr.client.rst:45 ../../source/ref-api/flwr.rst:25 +#: ../../source/ref-api/flwr.server.rst:49 msgid "Modules" msgstr "" @@ -8167,7 +8141,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr "" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:38::1 flwr.server:1 #: flwr.server.server.Server:1 of #, fuzzy msgid "Flower server." @@ -8186,6 +8160,7 @@ msgstr "Simulation de moniteur" msgid "client" msgstr "client" +#: ../../source/ref-api/flwr.client.mod.rst:13 #: ../../source/ref-api/flwr.client.rst:13 #: ../../source/ref-api/flwr.common.rst:13 #: ../../source/ref-api/flwr.server.rst:13 @@ -8237,9 +8212,10 @@ msgstr "" msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:30 #: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:28 +#: ../../source/ref-api/flwr.server.rst:26 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" @@ -8275,6 +8251,16 @@ msgstr "" msgid "Abstract base class for Flower clients using NumPy." msgstr "" +#: ../../source/ref-api/flwr.client.rst:52::1 +#, fuzzy +msgid ":py:obj:`flwr.client.mod `\\" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.client.rst:52::1 flwr.client.mod:1 of +#, fuzzy +msgid "Flower Built-in Mods." +msgstr "Client de Flower" + #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 @@ -8285,6 +8271,7 @@ msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 #: ../../source/ref-api/flwr.client.NumPyClient.rst:15 +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:15 #: ../../source/ref-api/flwr.common.Array.rst:15 #: ../../source/ref-api/flwr.common.ClientMessage.rst:15 #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:15 @@ -8463,6 +8450,7 @@ msgstr "" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters #: flwr.client.client.Client.get_properties +#: flwr.client.mod.localdp_mod.LocalDpMod #: flwr.client.numpy_client.NumPyClient.evaluate #: flwr.client.numpy_client.NumPyClient.fit #: flwr.client.numpy_client.NumPyClient.get_parameters @@ -8617,10 +8605,11 @@ msgstr "" msgid "ClientApp" msgstr "client" -#: flwr.client.client_app.ClientApp:1 flwr.common.constant.MessageType:1 -#: flwr.common.constant.MessageTypeLegacy:1 flwr.common.context.Context:1 -#: flwr.common.message.Error:1 flwr.common.message.Message:1 -#: flwr.common.message.Metadata:1 flwr.common.record.parametersrecord.Array:1 +#: flwr.client.client_app.ClientApp:1 flwr.client.mod.localdp_mod.LocalDpMod:1 +#: flwr.common.constant.MessageType:1 flwr.common.constant.MessageTypeLegacy:1 +#: flwr.common.context.Context:1 flwr.common.message.Error:1 +#: flwr.common.message.Message:1 flwr.common.message.Metadata:1 +#: flwr.common.record.parametersrecord.Array:1 #: flwr.common.record.recordset.RecordSet:1 flwr.common.typing.ClientMessage:1 #: flwr.common.typing.DisconnectRes:1 flwr.common.typing.EvaluateIns:1 #: flwr.common.typing.EvaluateRes:1 flwr.common.typing.FitIns:1 @@ -8641,7 +8630,8 @@ msgstr "" #: flwr.client.client_app.ClientApp:4 #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 -#: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 +#: flwr.client.client_app.ClientApp.train:4 +#: flwr.client.mod.localdp_mod.LocalDpMod:22 flwr.server.app.start_server:41 #: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 @@ -8865,6 +8855,239 @@ msgid "" "arbitrary property values back to the server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:2 +msgid "mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`adaptiveclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:1 of +#, fuzzy +msgid "Client-side adaptive clipping modifier." +msgstr "Logique côté client" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`fixedclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:1 of +#, fuzzy +msgid "Client-side fixed clipping modifier." +msgstr "Logique côté client" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" +msgstr "serveur.stratégie.Stratégie" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.utils.make_ffn:1 of +msgid "." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " +"call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secagg_mod.secagg_mod:1 of +msgid "Handle incoming message and return results, following the SecAgg protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secaggplus_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secaggplus_mod.secaggplus_mod:1 of +msgid "" +"Handle incoming message and return results, following the SecAgg+ " +"protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`message_size_mod `\\ \\(msg\\," +" ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.message_size_mod:1 of +msgid "Message size mod." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`parameters_size_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.parameters_size_mod:1 of +#, fuzzy +msgid "Parameters size mod." +msgstr "Paramètres du modèle." + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +msgid "" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\," +" sensitivity\\, ...\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +#: flwr.client.mod.localdp_mod.LocalDpMod:1 of +#, fuzzy +msgid "Modifier for local differential privacy." +msgstr "Confidentialité différentielle" + +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:2 +msgid "LocalDpMod" +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:3 of +msgid "" +"This mod clips the client model updates and adds noise to the params " +"before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:12 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:10 +#: flwr.client.mod.localdp_mod.LocalDpMod:6 of +msgid "It operates on messages of type `MessageType.TRAIN`." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:8 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +msgid "The value of the clipping norm." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:10 of +msgid "The sensitivity of the client model." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:12 of +msgid "" +"The privacy budget. Smaller value of epsilon indicates a higher level of " +"privacy protection." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:15 of +msgid "" +"The failure probability. The probability that the privacy mechanism fails" +" to provide the desired level of privacy. A smaller value of delta " +"indicates a stricter privacy guarantee." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:23 of +msgid "Create an instance of the local DP mod and add it to the client-side mods:" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.adaptiveclipping_mod.rst:2 +msgid "adaptiveclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy " +"wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:6 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:6 of +msgid "The wrapper sends the clipping_norm value to the client." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:8 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:8 of +msgid "This mod clips the client model updates before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:10 of +msgid "" +"It also sends KEY_NORM_BIT to the server for computing the new clipping " +"value." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:15 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:13 +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +#, fuzzy +msgid "Notes" +msgstr "Aucun" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:16 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:14 of +msgid "Consider the order of mods when using multiple." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:18 of +msgid "Typically, adaptiveclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.fixedclipping_mod.rst:2 +msgid "fixedclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideFixedClipping server-side strategy wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:16 of +msgid "Typically, fixedclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.make_ffn.rst:2 +msgid "make\\_ffn" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.message_size_mod.rst:2 +msgid "message\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.message_size_mod:3 of +msgid "This mod logs the size in bytes of the message being transmited." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.parameters_size_mod.rst:2 +#, fuzzy +msgid "parameters\\_size\\_mod" +msgstr "Paramètres du modèle." + +#: flwr.client.mod.comms_mods.parameters_size_mod:3 of +msgid "" +"This mod logs the number of parameters transmitted in the message as well" +" as their size in bytes." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secagg_mod.rst:2 +msgid "secagg\\_mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secaggplus_mod.rst:2 +#, fuzzy +msgid "secaggplus\\_mod" +msgstr "Flux de travail" + #: ../../source/ref-api/flwr.client.run_client_app.rst:2 msgid "run\\_client\\_app" msgstr "" @@ -10263,6 +10486,20 @@ msgid "" "`\\" msgstr "serveur.stratégie.Stratégie" +#: flwr.common.EventType.capitalize:1::1 of +#, fuzzy +msgid "" +":py:obj:`RUN_SUPEREXEC_ENTER " +"`\\" +msgstr "serveur.stratégie.Stratégie" + +#: flwr.common.EventType.capitalize:1::1 of +#, fuzzy +msgid "" +":py:obj:`RUN_SUPEREXEC_LEAVE " +"`\\" +msgstr "serveur.stratégie.Stratégie" + #: flwr.common.EventType.capitalize:3 of msgid "" "More specifically, make the first character have upper case and the rest " @@ -11164,116 +11401,96 @@ msgstr "" msgid "server" msgstr "serveur" -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_driver_api `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_driver_api:1 of -#, fuzzy -msgid "Run Flower server (Driver API)." -msgstr "flower-driver-api" - -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_fleet_api:1 of -#, fuzzy -msgid "Run Flower server (Fleet API)." -msgstr "flower-fleet-api" - -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid ":py:obj:`run_server_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.run_serverapp.run_server_app:1 of #, fuzzy msgid "Run Flower server app." msgstr "Serveur de Flower" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.run_superlink:1 of #, fuzzy msgid "Run Flower SuperLink (Driver API and Fleet API)." msgstr "flower-fleet-api" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.start_server:1 of msgid "Start a Flower server using the gRPC transport layer." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.ClientManager:1 of msgid "Abstract base class for managing Flower clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid ":py:obj:`Driver `\\ \\(\\)" msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.driver.driver.Driver:1 of msgid "Abstract base Driver class for the Driver API." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`History `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.history.History:1 of msgid "History class for training and/or evaluation metrics collection." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of msgid "Legacy Context." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " "strategy\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " "strategy\\, ...\\]\\)" msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_app.ServerApp:1 of #, fuzzy msgid "Flower ServerApp." msgstr "Serveur de Flower" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," @@ -11283,37 +11500,37 @@ msgstr "" "config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " "...)``" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_config.ServerConfig:1 of #, fuzzy msgid "Flower server config." msgstr "Serveur de Flower" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.SimpleClientManager:1 of msgid "Provides a pool of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #, fuzzy msgid ":py:obj:`flwr.server.strategy `\\" msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.strategy:1 of msgid "Contains the strategy abstraction and different implementations." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #, fuzzy msgid ":py:obj:`flwr.server.workflow `\\" msgstr "serveur.stratégie.Stratégie" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.workflow:1 of #, fuzzy msgid "Workflows." @@ -11570,14 +11787,6 @@ msgstr "" msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -#, fuzzy -msgid "Notes" -msgstr "Aucun" - #: flwr.server.driver.driver.Driver.send_and_receive:19 of msgid "" "This method uses `push_messages` to send the messages and `pull_messages`" @@ -12987,12 +13196,6 @@ msgid "" "value of 1.0 or higher is recommended for strong privacy." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -msgid "The value of the clipping norm." -msgstr "" - #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 #: of msgid "" @@ -13283,7 +13486,7 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:905 +#: ../../source/ref-changelog.md:997 msgid "FedAdagrad" msgstr "FedAdagrad" @@ -15155,55 +15358,21 @@ msgstr "Changelog" #: ../../source/ref-changelog.md:3 #, fuzzy -msgid "Unreleased" -msgstr "Inédit" - -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 -#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 -#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 -#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 -#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 -#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 -#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 -#: ../../source/ref-changelog.md:1022 -msgid "What's new?" -msgstr "Quoi de neuf ?" - -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 -#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 -#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 -#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 -#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 -#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 -#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 -msgid "Incompatible changes" -msgstr "Changements incompatibles" - -#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 -#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 -#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 -#: ../../source/ref-changelog.md:603 -msgid "None" -msgstr "Aucun" - -#: ../../source/ref-changelog.md:11 -#, fuzzy -msgid "v1.8.0 (2024-04-03)" +msgid "v1.9.0 (2024-06-10)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 -#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 -#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 -#: ../../source/ref-changelog.md:614 +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:169 ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:362 ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:510 ../../source/ref-changelog.md:568 +#: ../../source/ref-changelog.md:637 ../../source/ref-changelog.md:706 msgid "Thanks to our contributors" msgstr "Merci à nos contributeurs" -#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 -#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 -#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 -#: ../../source/ref-changelog.md:478 +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:171 ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:364 ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:512 ../../source/ref-changelog.md:570 msgid "" "We would like to give our special thanks to all the contributors who made" " the new version of Flower possible (in `git shortlog` order):" @@ -15212,60 +15381,647 @@ msgstr "" "ont rendu possible la nouvelle version de Flower (dans l'ordre `git " "shortlog`) :" -#: ../../source/ref-changelog.md:17 +#: ../../source/ref-changelog.md:9 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " -"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " -"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " -"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " -"`tabdar-khan` " +"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. " +"Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`," +" `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " msgstr "" -#: ../../source/ref-changelog.md:21 +#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:175 ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:368 ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:516 ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:643 ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:814 ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:947 ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:1031 ../../source/ref-changelog.md:1064 +#: ../../source/ref-changelog.md:1114 +msgid "What's new?" +msgstr "Quoi de neuf ?" + +#: ../../source/ref-changelog.md:13 +#, fuzzy +msgid "" +"**Introduce built-in authentication (preview)** " +"([#2946](https://github.com/adap/flower/pull/2946), " +"[#3388](https://github.com/adap/flower/pull/3388), " +"[#2948](https://github.com/adap/flower/pull/2948), " +"[#2917](https://github.com/adap/flower/pull/2917), " +"[#3386](https://github.com/adap/flower/pull/3386), " +"[#3308](https://github.com/adap/flower/pull/3308), " +"[#3001](https://github.com/adap/flower/pull/3001), " +"[#3409](https://github.com/adap/flower/pull/3409), " +"[#2999](https://github.com/adap/flower/pull/2999), " +"[#2979](https://github.com/adap/flower/pull/2979), " +"[#3389](https://github.com/adap/flower/pull/3389), " +"[#3503](https://github.com/adap/flower/pull/3503), " +"[#3366](https://github.com/adap/flower/pull/3366), " +"[#3357](https://github.com/adap/flower/pull/3357))" +msgstr "" +"**Documentation mise à jour** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" + +#: ../../source/ref-changelog.md:15 msgid "" -"**Introduce Flower Next high-level API (stable)** " -"([#3002](https://github.com/adap/flower/pull/3002), " -"[#2934](https://github.com/adap/flower/pull/2934), " -"[#2958](https://github.com/adap/flower/pull/2958), " -"[#3173](https://github.com/adap/flower/pull/3173), " -"[#3174](https://github.com/adap/flower/pull/3174), " -"[#2923](https://github.com/adap/flower/pull/2923), " -"[#2691](https://github.com/adap/flower/pull/2691), " -"[#3079](https://github.com/adap/flower/pull/3079), " -"[#2961](https://github.com/adap/flower/pull/2961), " -"[#2924](https://github.com/adap/flower/pull/2924), " -"[#3166](https://github.com/adap/flower/pull/3166), " -"[#3031](https://github.com/adap/flower/pull/3031), " -"[#3057](https://github.com/adap/flower/pull/3057), " -"[#3000](https://github.com/adap/flower/pull/3000), " -"[#3113](https://github.com/adap/flower/pull/3113), " -"[#2957](https://github.com/adap/flower/pull/2957), " -"[#3183](https://github.com/adap/flower/pull/3183), " -"[#3180](https://github.com/adap/flower/pull/3180), " -"[#3035](https://github.com/adap/flower/pull/3035), " -"[#3189](https://github.com/adap/flower/pull/3189), " -"[#3185](https://github.com/adap/flower/pull/3185), " -"[#3190](https://github.com/adap/flower/pull/3190), " -"[#3191](https://github.com/adap/flower/pull/3191), " -"[#3195](https://github.com/adap/flower/pull/3195), " -"[#3197](https://github.com/adap/flower/pull/3197))" +"Flower 1.9 introduces the first build-in version of client node " +"authentication. In previous releases, users often wrote glue code to " +"connect Flower to external authentication systems. With this release, the" +" SuperLink can authenticate SuperNodes using a built-in authentication " +"system. A new [how-to guide](https://flower.ai/docs/framework/how-to-" +"authenticate-supernodes.html) and a new [code " +"example](https://github.com/adap/flower/tree/main/examples/flower-" +"authentication) help you to get started." msgstr "" -#: ../../source/ref-changelog.md:23 +#: ../../source/ref-changelog.md:17 msgid "" -"The Flower Next high-level API is stable! Flower Next is the future of " -"Flower - all new features (like Flower Mods) will be built on top of it. " -"You can start to migrate your existing projects to Flower Next by using " -"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " -"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." -" Flower Next allows you to run multiple projects concurrently (we call " +"This is the first preview release of the Flower-native authentication " +"system. Many additional features are on the roadmap for upcoming Flower " +"releases - stay tuned." +msgstr "" + +#: ../../source/ref-changelog.md:19 +#, fuzzy +msgid "" +"**Introduce end-to-end Docker support** " +"([#3483](https://github.com/adap/flower/pull/3483), " +"[#3266](https://github.com/adap/flower/pull/3266), " +"[#3390](https://github.com/adap/flower/pull/3390), " +"[#3283](https://github.com/adap/flower/pull/3283), " +"[#3285](https://github.com/adap/flower/pull/3285), " +"[#3391](https://github.com/adap/flower/pull/3391), " +"[#3403](https://github.com/adap/flower/pull/3403), " +"[#3458](https://github.com/adap/flower/pull/3458), " +"[#3533](https://github.com/adap/flower/pull/3533), " +"[#3453](https://github.com/adap/flower/pull/3453), " +"[#3486](https://github.com/adap/flower/pull/3486), " +"[#3290](https://github.com/adap/flower/pull/3290))" +msgstr "" +"**Introduire l'API REST (expérimentale)** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" + +#: ../../source/ref-changelog.md:21 +msgid "" +"Full Flower Next Docker support is here! With the release of Flower 1.9, " +"Flower provides stable Docker images for the Flower SuperLink, the Flower" +" SuperNode, and the Flower `ServerApp`. This set of images enables you to" +" run all Flower components in Docker. Check out the new [how-to " +"guide](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html) to get stated." +msgstr "" + +#: ../../source/ref-changelog.md:23 +#, fuzzy +msgid "" +"**Re-architect Flower Next simulation engine** " +"([#3307](https://github.com/adap/flower/pull/3307), " +"[#3355](https://github.com/adap/flower/pull/3355), " +"[#3272](https://github.com/adap/flower/pull/3272), " +"[#3273](https://github.com/adap/flower/pull/3273), " +"[#3417](https://github.com/adap/flower/pull/3417), " +"[#3281](https://github.com/adap/flower/pull/3281), " +"[#3343](https://github.com/adap/flower/pull/3343), " +"[#3326](https://github.com/adap/flower/pull/3326))" +msgstr "" +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" + +#: ../../source/ref-changelog.md:25 +msgid "" +"Flower Next simulations now use a new in-memory `Driver` that improves " +"the reliability of simulations, especially in notebook environments. This" +" is a significant step towards a complete overhaul of the Flower Next " +"simulation architecture." +msgstr "" + +#: ../../source/ref-changelog.md:27 +#, fuzzy +msgid "" +"**Upgrade simulation engine** " +"([#3354](https://github.com/adap/flower/pull/3354), " +"[#3378](https://github.com/adap/flower/pull/3378), " +"[#3262](https://github.com/adap/flower/pull/3262), " +"[#3435](https://github.com/adap/flower/pull/3435), " +"[#3501](https://github.com/adap/flower/pull/3501), " +"[#3482](https://github.com/adap/flower/pull/3482), " +"[#3494](https://github.com/adap/flower/pull/3494))" +msgstr "" +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" + +#: ../../source/ref-changelog.md:29 +msgid "" +"The Flower Next simulation engine comes with improved and configurable " +"logging. The Ray-based simulation backend in Flower 1.9 was updated to " +"use Ray 2.10." +msgstr "" + +#: ../../source/ref-changelog.md:31 +#, fuzzy +msgid "" +"**Introduce FedPFT baseline** " +"([#3268](https://github.com/adap/flower/pull/3268))" +msgstr "" +"**Ajouter une nouvelle stratégie `FedProx`** " +"([#1619](https://github.com/adap/flower/pull/1619))" + +#: ../../source/ref-changelog.md:33 +msgid "" +"FedPFT allows you to perform one-shot Federated Learning by leveraging " +"widely available foundational models, dramatically reducing communication" +" costs while delivering high performing models. This is work led by Mahdi" +" Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " +"details in their paper: \"Parametric Feature Transfer: One-shot Federated" +" Learning with Foundation Models\" " +"([arxiv](https://arxiv.org/abs/2402.01862))" +msgstr "" + +#: ../../source/ref-changelog.md:35 +#, fuzzy +msgid "" +"**Launch additional** `flwr new` **templates for Apple MLX, Hugging Face " +"Transformers, scikit-learn and TensorFlow** " +"([#3291](https://github.com/adap/flower/pull/3291), " +"[#3139](https://github.com/adap/flower/pull/3139), " +"[#3284](https://github.com/adap/flower/pull/3284), " +"[#3251](https://github.com/adap/flower/pull/3251), " +"[#3376](https://github.com/adap/flower/pull/3376), " +"[#3287](https://github.com/adap/flower/pull/3287))" +msgstr "" +"**Nouvel exemple de code MLCube** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" + +#: ../../source/ref-changelog.md:37 +msgid "" +"The `flwr` CLI's `flwr new` command is starting to become everone's " +"favorite way of creating new Flower projects. This release introduces " +"additional `flwr new` templates for Apple MLX, Hugging Face Transformers," +" scikit-learn and TensorFlow. In addition to that, existing templates " +"also received updates." +msgstr "" + +#: ../../source/ref-changelog.md:39 +#, fuzzy +msgid "" +"**Refine** `RecordSet` **API** " +"([#3209](https://github.com/adap/flower/pull/3209), " +"[#3331](https://github.com/adap/flower/pull/3331), " +"[#3334](https://github.com/adap/flower/pull/3334), " +"[#3335](https://github.com/adap/flower/pull/3335), " +"[#3375](https://github.com/adap/flower/pull/3375), " +"[#3368](https://github.com/adap/flower/pull/3368))" +msgstr "" +"**Mise à jour de la documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" + +#: ../../source/ref-changelog.md:41 +msgid "" +"`RecordSet` is part of the Flower Next low-level API preview release. In " +"Flower 1.9, `RecordSet` received a number of usability improvements that " +"make it easier to build `RecordSet`-based `ServerApp`s and `ClientApp`s." +msgstr "" + +#: ../../source/ref-changelog.md:43 +#, fuzzy +msgid "" +"**Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), " +"[#3430](https://github.com/adap/flower/pull/3430), " +"[#3461](https://github.com/adap/flower/pull/3461), " +"[#3360](https://github.com/adap/flower/pull/3360), " +"[#3433](https://github.com/adap/flower/pull/3433))" +msgstr "" +"Mettre à jour les outils de développement " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" + +#: ../../source/ref-changelog.md:45 +msgid "" +"Logs received a substantial update. Not only are logs now much nicer to " +"look at, but they are also more configurable." +msgstr "" + +#: ../../source/ref-changelog.md:47 +#, fuzzy +msgid "" +"**Improve reliability** " +"([#3564](https://github.com/adap/flower/pull/3564), " +"[#3561](https://github.com/adap/flower/pull/3561), " +"[#3566](https://github.com/adap/flower/pull/3566), " +"[#3462](https://github.com/adap/flower/pull/3462), " +"[#3225](https://github.com/adap/flower/pull/3225), " +"[#3514](https://github.com/adap/flower/pull/3514), " +"[#3535](https://github.com/adap/flower/pull/3535), " +"[#3372](https://github.com/adap/flower/pull/3372))" +msgstr "" +"**Tutoriel amélioré** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" + +#: ../../source/ref-changelog.md:49 +msgid "" +"Flower 1.9 includes reliability improvements across many parts of the " +"system. One example is a much improved SuperNode shutdown procedure." +msgstr "" + +#: ../../source/ref-changelog.md:51 +#, fuzzy +msgid "" +"**Update Swift and C++ SDKs** " +"([#3321](https://github.com/adap/flower/pull/3321), " +"[#2763](https://github.com/adap/flower/pull/2763))" +msgstr "" +"**Exemple de code mis à jour** " +"([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" + +#: ../../source/ref-changelog.md:53 +msgid "" +"In the C++ SDK, communication-related code is now separate from main " +"client logic. A new abstract class `Communicator` has been introduced " +"alongside a gRPC implementation of it." +msgstr "" + +#: ../../source/ref-changelog.md:55 +msgid "" +"**Improve testing, tooling and CI/CD infrastructure** " +"([#3294](https://github.com/adap/flower/pull/3294), " +"[#3282](https://github.com/adap/flower/pull/3282), " +"[#3311](https://github.com/adap/flower/pull/3311), " +"[#2878](https://github.com/adap/flower/pull/2878), " +"[#3333](https://github.com/adap/flower/pull/3333), " +"[#3255](https://github.com/adap/flower/pull/3255), " +"[#3349](https://github.com/adap/flower/pull/3349), " +"[#3400](https://github.com/adap/flower/pull/3400), " +"[#3401](https://github.com/adap/flower/pull/3401), " +"[#3399](https://github.com/adap/flower/pull/3399), " +"[#3346](https://github.com/adap/flower/pull/3346), " +"[#3398](https://github.com/adap/flower/pull/3398), " +"[#3397](https://github.com/adap/flower/pull/3397), " +"[#3347](https://github.com/adap/flower/pull/3347), " +"[#3502](https://github.com/adap/flower/pull/3502), " +"[#3387](https://github.com/adap/flower/pull/3387), " +"[#3542](https://github.com/adap/flower/pull/3542), " +"[#3396](https://github.com/adap/flower/pull/3396), " +"[#3496](https://github.com/adap/flower/pull/3496), " +"[#3465](https://github.com/adap/flower/pull/3465), " +"[#3473](https://github.com/adap/flower/pull/3473), " +"[#3484](https://github.com/adap/flower/pull/3484), " +"[#3521](https://github.com/adap/flower/pull/3521), " +"[#3363](https://github.com/adap/flower/pull/3363), " +"[#3497](https://github.com/adap/flower/pull/3497), " +"[#3464](https://github.com/adap/flower/pull/3464), " +"[#3495](https://github.com/adap/flower/pull/3495), " +"[#3478](https://github.com/adap/flower/pull/3478), " +"[#3271](https://github.com/adap/flower/pull/3271))" +msgstr "" + +#: ../../source/ref-changelog.md:57 +msgid "" +"As always, the Flower tooling, testing, and CI/CD infrastructure has " +"received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:59 +msgid "" +"**Improve documentation** " +"([#3530](https://github.com/adap/flower/pull/3530), " +"[#3539](https://github.com/adap/flower/pull/3539), " +"[#3425](https://github.com/adap/flower/pull/3425), " +"[#3520](https://github.com/adap/flower/pull/3520), " +"[#3286](https://github.com/adap/flower/pull/3286), " +"[#3516](https://github.com/adap/flower/pull/3516), " +"[#3523](https://github.com/adap/flower/pull/3523), " +"[#3545](https://github.com/adap/flower/pull/3545), " +"[#3498](https://github.com/adap/flower/pull/3498), " +"[#3439](https://github.com/adap/flower/pull/3439), " +"[#3440](https://github.com/adap/flower/pull/3440), " +"[#3382](https://github.com/adap/flower/pull/3382), " +"[#3559](https://github.com/adap/flower/pull/3559), " +"[#3432](https://github.com/adap/flower/pull/3432), " +"[#3278](https://github.com/adap/flower/pull/3278), " +"[#3371](https://github.com/adap/flower/pull/3371), " +"[#3519](https://github.com/adap/flower/pull/3519), " +"[#3267](https://github.com/adap/flower/pull/3267), " +"[#3204](https://github.com/adap/flower/pull/3204), " +"[#3274](https://github.com/adap/flower/pull/3274))" +msgstr "" + +#: ../../source/ref-changelog.md:61 +msgid "" +"As always, the Flower documentation has received many updates. Notable " +"new pages include:" +msgstr "" + +#: ../../source/ref-changelog.md:63 +msgid "" +"[How-to upgrate to Flower Next (Flower Next migration " +"guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-" +"next.html)" +msgstr "" + +#: ../../source/ref-changelog.md:65 +msgid "" +"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-" +"run-flower-using-docker.html)" +msgstr "" + +#: ../../source/ref-changelog.md:67 +msgid "" +"[Flower Mods reference](https://flower.ai/docs/framework/ref-" +"api/flwr.client.mod.html#module-flwr.client.mod)" +msgstr "" + +#: ../../source/ref-changelog.md:69 +#, fuzzy +msgid "" +"**General updates to Flower Examples** " +"([#3205](https://github.com/adap/flower/pull/3205), " +"[#3226](https://github.com/adap/flower/pull/3226), " +"[#3211](https://github.com/adap/flower/pull/3211), " +"[#3252](https://github.com/adap/flower/pull/3252), " +"[#3427](https://github.com/adap/flower/pull/3427), " +"[#3410](https://github.com/adap/flower/pull/3410), " +"[#3426](https://github.com/adap/flower/pull/3426), " +"[#3228](https://github.com/adap/flower/pull/3228), " +"[#3342](https://github.com/adap/flower/pull/3342), " +"[#3200](https://github.com/adap/flower/pull/3200), " +"[#3202](https://github.com/adap/flower/pull/3202), " +"[#3394](https://github.com/adap/flower/pull/3394), " +"[#3488](https://github.com/adap/flower/pull/3488), " +"[#3329](https://github.com/adap/flower/pull/3329), " +"[#3526](https://github.com/adap/flower/pull/3526), " +"[#3392](https://github.com/adap/flower/pull/3392), " +"[#3474](https://github.com/adap/flower/pull/3474), " +"[#3269](https://github.com/adap/flower/pull/3269))" +msgstr "" +"**Mise à jour de la documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" + +#: ../../source/ref-changelog.md:71 +msgid "As always, Flower code examples have received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:73 +msgid "" +"**General improvements** " +"([#3532](https://github.com/adap/flower/pull/3532), " +"[#3318](https://github.com/adap/flower/pull/3318), " +"[#3565](https://github.com/adap/flower/pull/3565), " +"[#3296](https://github.com/adap/flower/pull/3296), " +"[#3305](https://github.com/adap/flower/pull/3305), " +"[#3246](https://github.com/adap/flower/pull/3246), " +"[#3224](https://github.com/adap/flower/pull/3224), " +"[#3475](https://github.com/adap/flower/pull/3475), " +"[#3297](https://github.com/adap/flower/pull/3297), " +"[#3317](https://github.com/adap/flower/pull/3317), " +"[#3429](https://github.com/adap/flower/pull/3429), " +"[#3196](https://github.com/adap/flower/pull/3196), " +"[#3534](https://github.com/adap/flower/pull/3534), " +"[#3240](https://github.com/adap/flower/pull/3240), " +"[#3365](https://github.com/adap/flower/pull/3365), " +"[#3407](https://github.com/adap/flower/pull/3407), " +"[#3563](https://github.com/adap/flower/pull/3563), " +"[#3344](https://github.com/adap/flower/pull/3344), " +"[#3330](https://github.com/adap/flower/pull/3330), " +"[#3436](https://github.com/adap/flower/pull/3436), " +"[#3300](https://github.com/adap/flower/pull/3300), " +"[#3327](https://github.com/adap/flower/pull/3327), " +"[#3254](https://github.com/adap/flower/pull/3254), " +"[#3253](https://github.com/adap/flower/pull/3253), " +"[#3419](https://github.com/adap/flower/pull/3419), " +"[#3289](https://github.com/adap/flower/pull/3289), " +"[#3208](https://github.com/adap/flower/pull/3208), " +"[#3245](https://github.com/adap/flower/pull/3245), " +"[#3319](https://github.com/adap/flower/pull/3319), " +"[#3203](https://github.com/adap/flower/pull/3203), " +"[#3423](https://github.com/adap/flower/pull/3423), " +"[#3352](https://github.com/adap/flower/pull/3352), " +"[#3292](https://github.com/adap/flower/pull/3292), " +"[#3261](https://github.com/adap/flower/pull/3261))" +msgstr "" + +#: ../../source/ref-changelog.md:75 ../../source/ref-changelog.md:1058 +msgid "Deprecations" +msgstr "Dépréciations" + +#: ../../source/ref-changelog.md:77 +#, fuzzy +msgid "**Deprecate Python 3.8 support**" +msgstr "**Créer le PR**" + +#: ../../source/ref-changelog.md:79 +msgid "" +"Python 3.8 will stop receiving security fixes in [October " +"2024](https://devguide.python.org/versions/). Support for Python 3.8 is " +"now deprecated and will be removed in an upcoming release." +msgstr "" + +#: ../../source/ref-changelog.md:81 +#, fuzzy +msgid "" +"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-" +"api` ([#3416](https://github.com/adap/flower/pull/3416), " +"[#3420](https://github.com/adap/flower/pull/3420))" +msgstr "" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" + +#: ../../source/ref-changelog.md:83 +msgid "" +"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api`" +" and `flower-fleet-api`. Both commands will be removed in an upcoming " +"release. Use `flower-superlink` instead." +msgstr "" + +#: ../../source/ref-changelog.md:85 +#, fuzzy +msgid "" +"**Deprecate** `--server` **in favor of** `--superlink` " +"([#3518](https://github.com/adap/flower/pull/3518))" +msgstr "" +"**Autoriser le passage d'une **instance `Server` à** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" + +#: ../../source/ref-changelog.md:87 +msgid "" +"The commands `flower-server-app` and `flower-client-app` should use " +"`--superlink` instead of the now deprecated `--server`. Support for " +"`--server` will be removed in a future release." +msgstr "" + +#: ../../source/ref-changelog.md:89 ../../source/ref-changelog.md:163 +#: ../../source/ref-changelog.md:238 ../../source/ref-changelog.md:350 +#: ../../source/ref-changelog.md:440 ../../source/ref-changelog.md:504 +#: ../../source/ref-changelog.md:562 ../../source/ref-changelog.md:631 +#: ../../source/ref-changelog.md:693 ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:868 ../../source/ref-changelog.md:939 +#: ../../source/ref-changelog.md:976 ../../source/ref-changelog.md:1019 +msgid "Incompatible changes" +msgstr "Changements incompatibles" + +#: ../../source/ref-changelog.md:91 +msgid "" +"**Replace** `flower-superlink` **CLI option** `--certificates` **with** " +"`--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` " +"([#3512](https://github.com/adap/flower/pull/3512), " +"[#3408](https://github.com/adap/flower/pull/3408))" +msgstr "" + +#: ../../source/ref-changelog.md:93 +msgid "" +"SSL-related `flower-superlink` CLI arguments were restructured in an " +"incompatible way. Instead of passing a single `--certificates` flag with " +"three values, you now need to pass three flags (`--ssl-ca-certfile`, " +"`--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the " +"[SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-" +"connections.html) documentation page for details." +msgstr "" + +#: ../../source/ref-changelog.md:95 +#, fuzzy +msgid "" +"**Remove SuperLink** `--vce` **option** " +"([#3513](https://github.com/adap/flower/pull/3513))" +msgstr "" +"**Documentation restructurée** " +"([#1387](https://github.com/adap/flower/pull/1387))" + +#: ../../source/ref-changelog.md:97 +msgid "" +"Instead of separately starting a SuperLink and a `ServerApp` for " +"simulation, simulations must now be started using the single `flower-" +"simulation` command." +msgstr "" + +#: ../../source/ref-changelog.md:99 +#, fuzzy +msgid "" +"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** " +"([#3527](https://github.com/adap/flower/pull/3527))" +msgstr "" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" + +#: ../../source/ref-changelog.md:101 +msgid "" +"To simplify the usage of `flower-superlink`, previously separate sets of " +"CLI options for gRPC and REST were merged into one unified set of " +"options. Consult the [Flower CLI reference " +"documentation](https://flower.ai/docs/framework/ref-api-cli.html) for " +"details." +msgstr "" + +#: ../../source/ref-changelog.md:103 +#, fuzzy +msgid "v1.8.0 (2024-04-03)" +msgstr "v1.3.0 (2023-02-06)" + +#: ../../source/ref-changelog.md:109 +msgid "" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " +msgstr "" + +#: ../../source/ref-changelog.md:113 +msgid "" +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" +msgstr "" + +#: ../../source/ref-changelog.md:115 +msgid "" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " "this multi-run) and execute the same project in either simulation " "environments or deployment environments without having to change a single" " line of code. The best part? It's fully compatible with existing Flower " "projects that use `Strategy`, `NumPyClient` & co." msgstr "" -#: ../../source/ref-changelog.md:25 +#: ../../source/ref-changelog.md:117 #, fuzzy msgid "" "**Introduce Flower Next low-level API (preview)** " @@ -15278,7 +16034,7 @@ msgstr "" "[#1286](https://github.com/adap/flower/pull/1286), " "[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:27 +#: ../../source/ref-changelog.md:119 msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " "`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " @@ -15295,7 +16051,7 @@ msgid "" "custom SMPC protocols, to name just a few." msgstr "" -#: ../../source/ref-changelog.md:29 +#: ../../source/ref-changelog.md:121 #, fuzzy msgid "" "**Introduce Flower Mods (preview)** " @@ -15308,7 +16064,7 @@ msgstr "" "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:31 +#: ../../source/ref-changelog.md:123 msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " "edit or handle them directly. Mods can be used to develop pluggable " @@ -15320,7 +16076,7 @@ msgid "" "can already use it to experiment with arbirtrary SMPC protocols." msgstr "" -#: ../../source/ref-changelog.md:33 +#: ../../source/ref-changelog.md:125 #, fuzzy msgid "" "**Fine-tune LLMs with LLM FlowerTune** " @@ -15339,7 +16095,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:35 +#: ../../source/ref-changelog.md:127 msgid "" "We are introducing LLM FlowerTune, an introductory example that " "demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " @@ -15349,7 +16105,7 @@ msgid "" "-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -#: ../../source/ref-changelog.md:37 +#: ../../source/ref-changelog.md:129 #, fuzzy msgid "" "**Introduce built-in Differential Privacy (preview)** " @@ -15370,7 +16126,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:39 +#: ../../source/ref-changelog.md:131 msgid "" "Built-in Differential Privacy is here! Flower supports both central and " "local differential privacy (DP). Central DP can be configured with either" @@ -15383,7 +16139,7 @@ msgid "" "/how-to-use-differential-privacy.html) in Flower." msgstr "" -#: ../../source/ref-changelog.md:41 +#: ../../source/ref-changelog.md:133 #, fuzzy msgid "" "**Introduce built-in Secure Aggregation (preview)** " @@ -15396,7 +16152,7 @@ msgstr "" "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:43 +#: ../../source/ref-changelog.md:135 msgid "" "Built-in Secure Aggregation is here! Flower now supports different secure" " aggregation protocols out-of-the-box. The best part? You can add secure " @@ -15409,7 +16165,7 @@ msgid "" "in the same project." msgstr "" -#: ../../source/ref-changelog.md:45 +#: ../../source/ref-changelog.md:137 #, fuzzy msgid "" "**Introduce** `flwr` **CLI (preview)** " @@ -15432,13 +16188,13 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:47 +#: ../../source/ref-changelog.md:139 msgid "" "A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" " and then running them using the Simulation Engine (`flwr run`)." msgstr "" -#: ../../source/ref-changelog.md:49 +#: ../../source/ref-changelog.md:141 #, fuzzy msgid "" "**Introduce Flower Next Simulation Engine** " @@ -15462,14 +16218,14 @@ msgstr "" "[#1770](https://github.com/adap/flower/pull/1770), " "[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:51 +#: ../../source/ref-changelog.md:143 msgid "" "The Flower Simulation Engine can now run Flower Next projects. For " "notebook environments, there's also a new `run_simulation` function that " "can run `ServerApp` and `ClientApp`." msgstr "" -#: ../../source/ref-changelog.md:53 +#: ../../source/ref-changelog.md:145 #, fuzzy msgid "" "**Handle SuperNode connection errors** " @@ -15478,7 +16234,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:55 +#: ../../source/ref-changelog.md:147 msgid "" "A SuperNode will now try to reconnect indefinitely to the SuperLink in " "case of connection errors. The arguments `--max-retries` and `--max-wait-" @@ -15489,7 +16245,7 @@ msgid "" "reconnect to the SuperLink." msgstr "" -#: ../../source/ref-changelog.md:57 +#: ../../source/ref-changelog.md:149 #, fuzzy msgid "" "**General updates to Flower Baselines** " @@ -15504,13 +16260,13 @@ msgstr "" "[#1681](https://github.com/adap/flower/pull/1681), " "[#1679](https://github.com/adap/flower/pull/1679))" -#: ../../source/ref-changelog.md:59 +#: ../../source/ref-changelog.md:151 msgid "" "There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " "baseline. Several other baselined have been updated as well." msgstr "" -#: ../../source/ref-changelog.md:61 +#: ../../source/ref-changelog.md:153 msgid "" "**Improve documentation and translations** " "([#3050](https://github.com/adap/flower/pull/3050), " @@ -15531,14 +16287,14 @@ msgid "" "[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" -#: ../../source/ref-changelog.md:63 +#: ../../source/ref-changelog.md:155 msgid "" "As usual, we merged many smaller and larger improvements to the " "documentation. A special thank you goes to [Sebastian van der " "Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" -#: ../../source/ref-changelog.md:65 +#: ../../source/ref-changelog.md:157 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -15565,7 +16321,7 @@ msgstr "" "[#1519](https://github.com/adap/flower/pull/1519), " "[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:67 +#: ../../source/ref-changelog.md:159 msgid "" "Two new examples show federated training of a Vision Transformer (ViT) " "and federated learning in a medical context using the popular MONAI " @@ -15574,7 +16330,7 @@ msgid "" "received considerable updates as well." msgstr "" -#: ../../source/ref-changelog.md:69 +#: ../../source/ref-changelog.md:161 msgid "" "**General improvements** " "([#3171](https://github.com/adap/flower/pull/3171), " @@ -15652,12 +16408,18 @@ msgid "" "[#2954](https://github.com/adap/flower/pull/2954))" msgstr "" -#: ../../source/ref-changelog.md:75 +#: ../../source/ref-changelog.md:165 ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:506 ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:633 ../../source/ref-changelog.md:695 +msgid "None" +msgstr "Aucun" + +#: ../../source/ref-changelog.md:167 #, fuzzy msgid "v1.7.0 (2024-02-05)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:81 +#: ../../source/ref-changelog.md:173 msgid "" "`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " "Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " @@ -15667,7 +16429,7 @@ msgid "" "Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" -#: ../../source/ref-changelog.md:85 +#: ../../source/ref-changelog.md:177 #, fuzzy msgid "" "**Introduce stateful clients (experimental)** " @@ -15684,7 +16446,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:87 +#: ../../source/ref-changelog.md:179 msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " @@ -15697,7 +16459,7 @@ msgid "" "unified way across simulation and deployment." msgstr "" -#: ../../source/ref-changelog.md:89 +#: ../../source/ref-changelog.md:181 #, fuzzy msgid "" "**Improve performance** " @@ -15706,7 +16468,7 @@ msgstr "" "**Supprimer les stratégies expérimentales** " "([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:91 +#: ../../source/ref-changelog.md:183 msgid "" "Flower is faster than ever. All `FedAvg`-derived strategies now use in-" "place aggregation to reduce memory consumption. The Flower client " @@ -15715,7 +16477,7 @@ msgid "" "training time is short." msgstr "" -#: ../../source/ref-changelog.md:93 +#: ../../source/ref-changelog.md:185 #, fuzzy msgid "" "**Support Federated Learning with Apple MLX and Flower** " @@ -15724,14 +16486,14 @@ msgstr "" "**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " "Flower** ([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:95 +#: ../../source/ref-changelog.md:187 msgid "" "Flower has official support for federated learning using [Apple " "MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " "example." msgstr "" -#: ../../source/ref-changelog.md:97 +#: ../../source/ref-changelog.md:189 #, fuzzy msgid "" "**Introduce new XGBoost cyclic strategy** " @@ -15742,7 +16504,7 @@ msgstr "" "([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:99 +#: ../../source/ref-changelog.md:191 msgid "" "A new strategy called `FedXgbCyclic` supports a client-by-client style of" " training (often called cyclic). The `xgboost-comprehensive` code example" @@ -15751,7 +16513,7 @@ msgid "" "offers best-in-class XGBoost support." msgstr "" -#: ../../source/ref-changelog.md:101 +#: ../../source/ref-changelog.md:193 #, fuzzy msgid "" "**Support Python 3.11** " @@ -15760,13 +16522,13 @@ msgstr "" "**Support Python 3.10** " "([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:103 +#: ../../source/ref-changelog.md:195 msgid "" "Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " "ensure better support for users using more recent Python versions." msgstr "" -#: ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:197 #, fuzzy msgid "" "**Update gRPC and ProtoBuf dependencies** " @@ -15775,13 +16537,13 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:199 msgid "" "The `grpcio` and `protobuf` dependencies were updated to their latest " "versions for improved security and performance." msgstr "" -#: ../../source/ref-changelog.md:109 +#: ../../source/ref-changelog.md:201 #, fuzzy msgid "" "**Introduce Docker image for Flower server** " @@ -15802,7 +16564,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:203 msgid "" "The Flower server can now be run using an official Docker image. A new " "how-to guide explains [how to run Flower using " @@ -15810,7 +16572,7 @@ msgid "" "docker.html). An official Flower client Docker image will follow." msgstr "" -#: ../../source/ref-changelog.md:113 +#: ../../source/ref-changelog.md:205 #, fuzzy msgid "" "**Introduce** `flower-via-docker-compose` **example** " @@ -15819,7 +16581,7 @@ msgstr "" "**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " "FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:115 +#: ../../source/ref-changelog.md:207 #, fuzzy msgid "" "**Introduce** `quickstart-sklearn-tabular` **example** " @@ -15828,7 +16590,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:117 +#: ../../source/ref-changelog.md:209 #, fuzzy msgid "" "**Introduce** `custom-metrics` **example** " @@ -15837,7 +16599,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:119 +#: ../../source/ref-changelog.md:211 #, fuzzy msgid "" "**Update code examples to use Flower Datasets** " @@ -15852,13 +16614,13 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:121 +#: ../../source/ref-changelog.md:213 msgid "" "Several code examples were updated to use [Flower " "Datasets](https://flower.ai/docs/datasets/)." msgstr "" -#: ../../source/ref-changelog.md:123 +#: ../../source/ref-changelog.md:215 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -15884,16 +16646,16 @@ msgstr "" "[#1662](https://github.com/adap/flower/pull/1662), " "[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:125 +#: ../../source/ref-changelog.md:217 msgid "Many Flower code examples received substantial updates." msgstr "" -#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 +#: ../../source/ref-changelog.md:219 ../../source/ref-changelog.md:312 #, fuzzy msgid "**Update Flower Baselines**" msgstr "Demande pour une nouvelle Flower Baseline" -#: ../../source/ref-changelog.md:129 +#: ../../source/ref-changelog.md:221 #, fuzzy msgid "" "HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " @@ -15903,38 +16665,38 @@ msgstr "" "([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:130 +#: ../../source/ref-changelog.md:222 #, fuzzy msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "" "Amélioration de la documentation sur le serveur gRPC " "([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:131 +#: ../../source/ref-changelog.md:223 #, fuzzy msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:132 +#: ../../source/ref-changelog.md:224 #, fuzzy msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:133 +#: ../../source/ref-changelog.md:225 #, fuzzy msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:134 +#: ../../source/ref-changelog.md:226 #, fuzzy msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" msgstr "" "**Renommé stratégie q-FedAvg** " "([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-changelog.md:136 +#: ../../source/ref-changelog.md:228 #, fuzzy msgid "" "**Improve documentation** " @@ -15954,7 +16716,7 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:138 +#: ../../source/ref-changelog.md:230 msgid "" "**Improved testing and development infrastructure** " "([#2797](https://github.com/adap/flower/pull/2797), " @@ -15988,13 +16750,13 @@ msgid "" "[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" -#: ../../source/ref-changelog.md:140 +#: ../../source/ref-changelog.md:232 msgid "" "The Flower testing and development infrastructure has received " "substantial updates. This makes Flower 1.7 the most tested release ever." msgstr "" -#: ../../source/ref-changelog.md:142 +#: ../../source/ref-changelog.md:234 msgid "" "**Update dependencies** " "([#2753](https://github.com/adap/flower/pull/2753), " @@ -16018,7 +16780,7 @@ msgid "" "[#2789](https://github.com/adap/flower/pull/2789))" msgstr "" -#: ../../source/ref-changelog.md:144 +#: ../../source/ref-changelog.md:236 msgid "" "**General improvements** " "([#2803](https://github.com/adap/flower/pull/2803), " @@ -16059,7 +16821,7 @@ msgid "" "[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" -#: ../../source/ref-changelog.md:148 +#: ../../source/ref-changelog.md:240 #, fuzzy msgid "" "**Deprecate** `start_numpy_client` " @@ -16070,7 +16832,7 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:150 +#: ../../source/ref-changelog.md:242 msgid "" "Until now, clients of type `NumPyClient` needed to be started via " "`start_numpy_client`. In our efforts to consolidate framework APIs, we " @@ -16081,7 +16843,7 @@ msgid "" "updated accordingly." msgstr "" -#: ../../source/ref-changelog.md:152 +#: ../../source/ref-changelog.md:244 #, fuzzy msgid "" "**Deprecate legacy DP wrappers** " @@ -16090,14 +16852,14 @@ msgstr "" "**Supprimez KerasClient** " "([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:154 +#: ../../source/ref-changelog.md:246 msgid "" "Legacy DP wrapper classes are deprecated, but still functional. This is " "in preparation for an all-new pluggable version of differential privacy " "support in Flower." msgstr "" -#: ../../source/ref-changelog.md:156 +#: ../../source/ref-changelog.md:248 #, fuzzy msgid "" "**Make optional arg** `--callable` **in** `flower-client` **a required " @@ -16106,7 +16868,7 @@ msgstr "" "**Log** `Client` **exceptions dans le moteur de client virtuel** " "([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:158 +#: ../../source/ref-changelog.md:250 #, fuzzy msgid "" "**Rename** `certificates` **to** `root_certificates` **in** `Driver` " @@ -16115,7 +16877,7 @@ msgstr "" "**Rename** `rnd` **to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:160 +#: ../../source/ref-changelog.md:252 #, fuzzy msgid "" "**Drop experimental** `Task` **fields** " @@ -16126,14 +16888,14 @@ msgstr "" "([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:162 +#: ../../source/ref-changelog.md:254 msgid "" "Experimental fields `sa`, `legacy_server_message` and " "`legacy_client_message` were removed from `Task` message. The removed " "fields are superseded by the new `RecordSet` abstraction." msgstr "" -#: ../../source/ref-changelog.md:164 +#: ../../source/ref-changelog.md:256 #, fuzzy msgid "" "**Retire MXNet examples** " @@ -16142,19 +16904,19 @@ msgstr "" "**Nouvel exemple de code scikit-learn** " "([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:166 +#: ../../source/ref-changelog.md:258 msgid "" "The development of the MXNet fremework has ended and the project is now " "[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " "examples won't receive updates." msgstr "" -#: ../../source/ref-changelog.md:168 +#: ../../source/ref-changelog.md:260 #, fuzzy msgid "v1.6.0 (2023-11-28)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:174 +#: ../../source/ref-changelog.md:266 msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " @@ -16164,7 +16926,7 @@ msgid "" "`cnxdeveloper`, `k3nfalt` " msgstr "" -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:270 #, fuzzy msgid "" "**Add experimental support for Python 3.12** " @@ -16173,7 +16935,7 @@ msgstr "" "**Ajouter la prise en charge expérimentale de Python 3.10 et Python " "3.11** ([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:180 +#: ../../source/ref-changelog.md:272 #, fuzzy msgid "" "**Add new XGBoost examples** " @@ -16192,13 +16954,13 @@ msgstr "" "[#1551](https://github.com/adap/flower/pull/1551), " "[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:274 msgid "" "We have added a new `xgboost-quickstart` example alongside a new " "`xgboost-comprehensive` example that goes more in-depth." msgstr "" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:276 #, fuzzy msgid "" "**Add Vertical FL example** " @@ -16207,7 +16969,7 @@ msgstr "" "**Nouvel exemple de code CoreML pour iOS** " "([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:278 msgid "" "We had many questions about Vertical Federated Learning using Flower, so " "we decided to add an simple example for it on the [Titanic " @@ -16215,7 +16977,7 @@ msgid "" "tutorial (in the README)." msgstr "" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:280 #, fuzzy msgid "" "**Support custom** `ClientManager` **in** `start_driver()` " @@ -16225,7 +16987,7 @@ msgstr "" "paramètre de `start_simulation` " "([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:190 +#: ../../source/ref-changelog.md:282 #, fuzzy msgid "" "**Update REST API to support create and delete nodes** " @@ -16234,7 +16996,7 @@ msgstr "" "**Nouvelle stratégie expérimentale TensorBoard** " "([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:192 +#: ../../source/ref-changelog.md:284 #, fuzzy msgid "" "**Update the Android SDK** " @@ -16243,11 +17005,11 @@ msgstr "" "**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " "FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:194 +#: ../../source/ref-changelog.md:286 msgid "Add gRPC request-response capability to the Android SDK." msgstr "" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:288 #, fuzzy msgid "" "**Update the C++ SDK** " @@ -16262,11 +17024,11 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:198 +#: ../../source/ref-changelog.md:290 msgid "Add gRPC request-response capability to the C++ SDK." msgstr "" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:292 #, fuzzy msgid "" "**Make HTTPS the new default** " @@ -16277,7 +17039,7 @@ msgstr "" "([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:294 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " "passing `--certificates`, but users can enable `--insecure` to use HTTP " @@ -16287,14 +17049,14 @@ msgid "" "enable insecure HTTP connections." msgstr "" -#: ../../source/ref-changelog.md:204 +#: ../../source/ref-changelog.md:296 msgid "" "For backward compatibility, `start_client()` and `start_numpy_client()` " "will still start in insecure mode by default. In a future release, " "insecure connections will require user opt-in by passing `insecure=True`." msgstr "" -#: ../../source/ref-changelog.md:206 +#: ../../source/ref-changelog.md:298 #, fuzzy msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " @@ -16306,7 +17068,7 @@ msgstr "" "[#1286](https://github.com/adap/flower/pull/1286), " "[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:208 +#: ../../source/ref-changelog.md:300 msgid "" "Using the `client_fn`, Flower clients can interchangeably run as " "standalone processes (i.e. via `start_client`) or in simulation (i.e. via" @@ -16315,7 +17077,7 @@ msgid "" "convert a `NumPyClient` to a `Client`." msgstr "" -#: ../../source/ref-changelog.md:210 +#: ../../source/ref-changelog.md:302 #, fuzzy msgid "" "**Add new** `Bulyan` **strategy** " @@ -16326,7 +17088,7 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:212 +#: ../../source/ref-changelog.md:304 #, fuzzy msgid "" "The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " @@ -16336,7 +17098,7 @@ msgstr "" "(FedMedian) par [Yin et al., 2018] " "(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:306 #, fuzzy msgid "" "**Add new** `XGB Bagging` **strategy** " @@ -16345,7 +17107,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 +#: ../../source/ref-changelog.md:308 ../../source/ref-changelog.md:310 #, fuzzy msgid "" "**Introduce `WorkloadState`** " @@ -16356,7 +17118,7 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:222 +#: ../../source/ref-changelog.md:314 #, fuzzy msgid "" "FedProx ([#2210](https://github.com/adap/flower/pull/2210), " @@ -16368,7 +17130,7 @@ msgstr "" "[#1286](https://github.com/adap/flower/pull/1286), " "[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-changelog.md:316 #, fuzzy msgid "" "Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " @@ -16378,7 +17140,7 @@ msgstr "" "([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:226 +#: ../../source/ref-changelog.md:318 #, fuzzy msgid "" "FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " @@ -16388,7 +17150,7 @@ msgstr "" "([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-changelog.md:320 #, fuzzy msgid "" "TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " @@ -16398,48 +17160,48 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:230 +#: ../../source/ref-changelog.md:322 #, fuzzy msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:232 +#: ../../source/ref-changelog.md:324 #, fuzzy msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "" "Amélioration de la documentation sur le serveur gRPC " "([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:234 +#: ../../source/ref-changelog.md:326 #, fuzzy msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:236 +#: ../../source/ref-changelog.md:328 #, fuzzy msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:238 +#: ../../source/ref-changelog.md:330 #, fuzzy msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:240 +#: ../../source/ref-changelog.md:332 #, fuzzy msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:242 +#: ../../source/ref-changelog.md:334 #, fuzzy msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:244 +#: ../../source/ref-changelog.md:336 #, fuzzy msgid "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " @@ -16449,7 +17211,7 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:246 +#: ../../source/ref-changelog.md:338 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -16465,7 +17227,7 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:248 +#: ../../source/ref-changelog.md:340 #, fuzzy msgid "" "**General updates to Flower Baselines** " @@ -16498,7 +17260,7 @@ msgstr "" "[#1564](https://github.com/adap/flower/pull/1564), " "[#1566](https://github.com/adap/flower/pull/1566))" -#: ../../source/ref-changelog.md:250 +#: ../../source/ref-changelog.md:342 #, fuzzy msgid "" "**General updates to the simulation engine** " @@ -16513,7 +17275,7 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:252 +#: ../../source/ref-changelog.md:344 #, fuzzy msgid "" "**General updates to Flower SDKs** " @@ -16532,7 +17294,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:254 +#: ../../source/ref-changelog.md:346 msgid "" "**General improvements** " "([#2309](https://github.com/adap/flower/pull/2309), " @@ -16564,15 +17326,15 @@ msgid "" "[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" -#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 -#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 -#: ../../source/ref-changelog.md:531 +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:502 ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:623 msgid "Flower received many improvements under the hood, too many to list here." msgstr "" "Flower a reçu de nombreuses améliorations sous le capot, trop nombreuses " "pour être énumérées ici." -#: ../../source/ref-changelog.md:260 +#: ../../source/ref-changelog.md:352 #, fuzzy msgid "" "**Remove support for Python 3.7** " @@ -16589,13 +17351,13 @@ msgstr "" "[#1065](https://github.com/adap/flower/pull/1065), " "[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:354 msgid "" "Python 3.7 support was deprecated in Flower 1.5, and this release removes" " support. Flower now requires Python 3.8." msgstr "" -#: ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:356 #, fuzzy msgid "" "**Remove experimental argument** `rest` **from** `start_client` " @@ -16604,19 +17366,19 @@ msgstr "" "**Supprimer les stratégies expérimentales** " "([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:266 +#: ../../source/ref-changelog.md:358 msgid "" "The (still experimental) argument `rest` was removed from `start_client` " "and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " "experimental REST API instead." msgstr "" -#: ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:360 #, fuzzy msgid "v1.5.0 (2023-08-31)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:274 +#: ../../source/ref-changelog.md:366 msgid "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -16625,7 +17387,7 @@ msgid "" "TOKEN_v1.5.0-->" msgstr "" -#: ../../source/ref-changelog.md:278 +#: ../../source/ref-changelog.md:370 #, fuzzy msgid "" "**Introduce new simulation engine** " @@ -16638,7 +17400,7 @@ msgstr "" "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:280 +#: ../../source/ref-changelog.md:372 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " "remains fully backwards compatible. It offers much improved stability and" @@ -16647,7 +17409,7 @@ msgid "" "only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -#: ../../source/ref-changelog.md:282 +#: ../../source/ref-changelog.md:374 msgid "" "Comprehensive documentation includes a new [how-to run " "simulations](https://flower.ai/docs/framework/how-to-run-" @@ -16658,7 +17420,7 @@ msgid "" "series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" -#: ../../source/ref-changelog.md:284 +#: ../../source/ref-changelog.md:376 msgid "" "**Restructure Flower Docs** " "([#1824](https://github.com/adap/flower/pull/1824), " @@ -16690,7 +17452,7 @@ msgid "" "[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" -#: ../../source/ref-changelog.md:286 +#: ../../source/ref-changelog.md:378 msgid "" "Much effort went into a completely restructured Flower docs experience. " "The documentation on [flower.ai/docs](https://flower.ai/docs) is now " @@ -16698,7 +17460,7 @@ msgid "" "Flower iOS SDK, and code example projects." msgstr "" -#: ../../source/ref-changelog.md:288 +#: ../../source/ref-changelog.md:380 #, fuzzy msgid "" "**Introduce Flower Swift SDK** " @@ -16709,14 +17471,14 @@ msgstr "" "([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:290 +#: ../../source/ref-changelog.md:382 msgid "" "This is the first preview release of the Flower Swift SDK. Flower support" " on iOS is improving, and alongside the Swift SDK and code example, there" " is now also an iOS quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:384 #, fuzzy msgid "" "**Introduce Flower Android SDK** " @@ -16725,14 +17487,14 @@ msgstr "" "**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " "FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:294 +#: ../../source/ref-changelog.md:386 msgid "" "This is the first preview release of the Flower Kotlin SDK. Flower " "support on Android is improving, and alongside the Kotlin SDK and code " "example, there is now also an Android quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:388 #, fuzzy msgid "" "**Introduce new end-to-end testing infrastructure** " @@ -16765,24 +17527,24 @@ msgstr "" "[#1662](https://github.com/adap/flower/pull/1662), " "[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:390 msgid "" "A new testing infrastructure ensures that new changes stay compatible " "with existing framework integrations or strategies." msgstr "" -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:392 #, fuzzy msgid "**Deprecate Python 3.7**" msgstr "**Créer le PR**" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:394 msgid "" "Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" " Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:396 #, fuzzy msgid "" "**Add new** `FedTrimmedAvg` **strategy** " @@ -16793,7 +17555,7 @@ msgstr "" "([#1469](https://github.com/adap/flower/pull/1469), " "[#1535](https://github.com/adap/flower/pull/1535))" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:398 #, fuzzy msgid "" "The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " @@ -16803,7 +17565,7 @@ msgstr "" "(FedMedian) par [Yin et al., 2018] " "(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:400 #, fuzzy msgid "" "**Introduce start_driver** " @@ -16812,7 +17574,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:402 msgid "" "In addition to `start_server` and using the raw Driver API, there is a " "new `start_driver` function that allows for running `start_server` " @@ -16821,7 +17583,7 @@ msgid "" "`start_driver`." msgstr "" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:404 #, fuzzy msgid "" "**Add parameter aggregation to** `mt-pytorch` **code example** " @@ -16830,7 +17592,7 @@ msgstr "" "**Nouvel exemple de code PyTorch avancé** " "([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:406 msgid "" "The `mt-pytorch` example shows how to aggregate parameters when writing a" " driver script. The included `driver.py` and `server.py` have been " @@ -16838,7 +17600,7 @@ msgid "" "building server-side logic." msgstr "" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:408 #, fuzzy msgid "" "**Migrate experimental REST API to Starlette** " @@ -16847,14 +17609,14 @@ msgstr "" "**Nouvelle stratégie expérimentale TensorBoard** " "([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:410 msgid "" "The (experimental) REST API used to be implemented in " "[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" " use [Starlette](https://www.starlette.io/) directly." msgstr "" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:412 #, fuzzy msgid "" "Please note: The REST request-response API is still experimental and will" @@ -16863,7 +17625,7 @@ msgstr "" "Remarque : l'API REST est encore expérimentale et est susceptible de " "changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:414 #, fuzzy msgid "" "**Introduce experimental gRPC request-response API** " @@ -16874,14 +17636,14 @@ msgstr "" "([#1357](https://github.com/adap/flower/pull/1357), " "[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:416 msgid "" "In addition to the existing gRPC API (based on bidirectional streaming) " "and the experimental REST API, there is now a new gRPC API that uses a " "request-response model to communicate with client nodes." msgstr "" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:418 #, fuzzy msgid "" "Please note: The gRPC request-response API is still experimental and will" @@ -16890,7 +17652,7 @@ msgstr "" "Remarque : l'API REST est encore expérimentale et est susceptible de " "changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:420 #, fuzzy msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " @@ -16900,7 +17662,7 @@ msgstr "" "**Initialise** `start_simulation` **avec une liste d'ID de clients** " "([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:422 msgid "" "The (experimental) `start_client` argument `rest` was deprecated in " "favour of a new argument `transport`. `start_client(transport=\"rest\")` " @@ -16909,7 +17671,7 @@ msgid "" "argument `rest` will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:424 #, fuzzy msgid "" "**Add a new gRPC option** " @@ -16918,14 +17680,14 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:426 msgid "" "We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" " option set to 0 by default. This prevents the clients from sending " "keepalive pings when there is no outstanding stream." msgstr "" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:428 #, fuzzy msgid "" "**Improve example notebooks** " @@ -16934,12 +17696,12 @@ msgstr "" "**Supprimer les stratégies expérimentales** " "([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:430 #, fuzzy msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "Bienvenue au tutoriel sur l'apprentissage fédéré de la fleur !" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:432 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " "[#1873](https://github.com/adap/flower/pull/1873), " @@ -16954,7 +17716,7 @@ msgid "" "[#2183](https://github.com/adap/flower/pull/2183))" msgstr "" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:434 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " @@ -16963,7 +17725,7 @@ msgid "" "(in addition to `pyproject.toml`)." msgstr "" -#: ../../source/ref-changelog.md:344 +#: ../../source/ref-changelog.md:436 #, fuzzy msgid "" "**General improvements** " @@ -16983,11 +17745,11 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:352 +#: ../../source/ref-changelog.md:444 msgid "v1.4.0 (2023-04-21)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:358 +#: ../../source/ref-changelog.md:450 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " @@ -17003,7 +17765,7 @@ msgstr "" "Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " "`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:454 msgid "" "**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " "example)** ([#1694](https://github.com/adap/flower/pull/1694), " @@ -17021,7 +17783,7 @@ msgstr "" "[#1763](https://github.com/adap/flower/pull/1763), " "[#1795](https://github.com/adap/flower/pull/1795))" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:456 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " "gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" @@ -17038,7 +17800,7 @@ msgstr "" "qui démontre l'utilisation de cette nouvelle stratégie dans un projet " "XGBoost." -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:458 msgid "" "**Introduce iOS SDK (preview)** " "([#1621](https://github.com/adap/flower/pull/1621), " @@ -17048,7 +17810,7 @@ msgstr "" "([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:460 msgid "" "This is a major update for anyone wanting to implement Federated Learning" " on iOS mobile devices. We now have a swift iOS SDK present under " @@ -17067,7 +17829,7 @@ msgstr "" "iOS](https://github.com/adap/flower/tree/main/examples/ios) a également " "été mis à jour !" -#: ../../source/ref-changelog.md:370 +#: ../../source/ref-changelog.md:462 msgid "" "**Introduce new \"What is Federated Learning?\" tutorial** " "([#1657](https://github.com/adap/flower/pull/1657), " @@ -17077,7 +17839,7 @@ msgstr "" " \"** ([#1657](https://github.com/adap/flower/pull/1657), " "[#1721](https://github.com/adap/flower/pull/1721))" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:464 #, fuzzy msgid "" "A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" @@ -17093,7 +17855,7 @@ msgstr "" " voyage avec Flower. Fais-le suivre à tous ceux qui s'intéressent à " "l'apprentissage fédéré !" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:466 msgid "" "**Introduce new Flower Baseline: FedProx MNIST** " "([#1513](https://github.com/adap/flower/pull/1513), " @@ -17107,7 +17869,7 @@ msgstr "" "[#1681](https://github.com/adap/flower/pull/1681), " "[#1679](https://github.com/adap/flower/pull/1679))" -#: ../../source/ref-changelog.md:376 +#: ../../source/ref-changelog.md:468 msgid "" "This new baseline replicates the MNIST+CNN task from the paper [Federated" " Optimization in Heterogeneous Networks (Li et al., " @@ -17120,7 +17882,7 @@ msgstr "" "qui vise à rendre la convergence plus robuste dans des contextes " "hétérogènes." -#: ../../source/ref-changelog.md:378 +#: ../../source/ref-changelog.md:470 msgid "" "**Introduce new Flower Baseline: FedAvg FEMNIST** " "([#1655](https://github.com/adap/flower/pull/1655))" @@ -17128,7 +17890,7 @@ msgstr "" "**Introduire une nouvelle ligne de base pour les fleurs : FedAvg " "FEMNIST** ([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:380 +#: ../../source/ref-changelog.md:472 msgid "" "This new baseline replicates an experiment evaluating the performance of " "the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " @@ -17140,7 +17902,7 @@ msgstr "" " l'article [LEAF : A Benchmark for Federated Settings (Caldas et al., " "2018)] (https://arxiv.org/abs/1812.01097)." -#: ../../source/ref-changelog.md:382 +#: ../../source/ref-changelog.md:474 msgid "" "**Introduce (experimental) REST API** " "([#1594](https://github.com/adap/flower/pull/1594), " @@ -17160,7 +17922,7 @@ msgstr "" "[#1770](https://github.com/adap/flower/pull/1770), " "[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:384 +#: ../../source/ref-changelog.md:476 msgid "" "A new REST API has been introduced as an alternative to the gRPC-based " "communication stack. In this initial version, the REST API only supports " @@ -17170,7 +17932,7 @@ msgstr "" "communication basée sur gRPC. Dans cette version initiale, l'API REST ne " "prend en charge que les clients anonymes." -#: ../../source/ref-changelog.md:386 +#: ../../source/ref-changelog.md:478 msgid "" "Please note: The REST API is still experimental and will likely change " "significantly over time." @@ -17178,7 +17940,7 @@ msgstr "" "Remarque : l'API REST est encore expérimentale et est susceptible de " "changer de manière significative au fil du temps." -#: ../../source/ref-changelog.md:388 +#: ../../source/ref-changelog.md:480 msgid "" "**Improve the (experimental) Driver API** " "([#1663](https://github.com/adap/flower/pull/1663), " @@ -17202,7 +17964,7 @@ msgstr "" "[#1662](https://github.com/adap/flower/pull/1662), " "[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:482 msgid "" "The Driver API is still an experimental feature, but this release " "introduces some major upgrades. One of the main improvements is the " @@ -17220,7 +17982,7 @@ msgstr "" "considérablement l'efficacité de la mémoire d'un serveur Flower " "fonctionnant depuis longtemps." -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:484 msgid "" "**Fix spilling issues related to Ray during simulations** " "([#1698](https://github.com/adap/flower/pull/1698))" @@ -17228,7 +17990,7 @@ msgstr "" "**Répare les problèmes de déversement liés à Ray pendant les " "simulations** ([#1698](https://github.com/adap/flower/pull/1698))" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:486 #, fuzzy msgid "" "While running long simulations, `ray` was sometimes spilling huge amounts" @@ -17239,7 +18001,7 @@ msgstr "" "d'énormes quantités de données qui rendaient l'entraînement incapable de " "continuer. ce problème est maintenant corrigé ! 🎉" -#: ../../source/ref-changelog.md:396 +#: ../../source/ref-changelog.md:488 msgid "" "**Add new example using** `TabNet` **and Flower** " "([#1725](https://github.com/adap/flower/pull/1725))" @@ -17247,7 +18009,7 @@ msgstr "" "**Ajouter un nouvel exemple utilisant** `TabNet` **et Flower** " "([#1725](https://github.com/adap/flower/pull/1725))" -#: ../../source/ref-changelog.md:398 +#: ../../source/ref-changelog.md:490 msgid "" "TabNet is a powerful and flexible framework for training machine learning" " models on tabular data. We now have a federated example using Flower: " @@ -17260,7 +18022,7 @@ msgstr "" "tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" "tabnet)." -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:492 msgid "" "**Add new how-to guide for monitoring simulations** " "([#1649](https://github.com/adap/flower/pull/1649))" @@ -17268,7 +18030,7 @@ msgstr "" "**Ajouter un nouveau guide pratique pour le suivi des simulations** " "([#1649](https://github.com/adap/flower/pull/1649))" -#: ../../source/ref-changelog.md:402 +#: ../../source/ref-changelog.md:494 msgid "" "We now have a documentation guide to help users monitor their performance" " during simulations." @@ -17276,7 +18038,7 @@ msgstr "" "Nous avons maintenant un guide de documentation pour aider les " "utilisateurs à surveiller leurs performances pendant les simulations." -#: ../../source/ref-changelog.md:404 +#: ../../source/ref-changelog.md:496 msgid "" "**Add training metrics to** `History` **object during simulations** " "([#1696](https://github.com/adap/flower/pull/1696))" @@ -17284,7 +18046,7 @@ msgstr "" "**Ajouter des mesures de formation à** `History` **objet pendant les " "simulations** ([#1696](https://github.com/adap/flower/pull/1696))" -#: ../../source/ref-changelog.md:406 +#: ../../source/ref-changelog.md:498 msgid "" "The `fit_metrics_aggregation_fn` can be used to aggregate training " "metrics, but previous releases did not save the results in the `History` " @@ -17295,7 +18057,7 @@ msgstr "" "n'enregistraient pas les résultats dans l'objet `History`. c'est " "désormais le cas !" -#: ../../source/ref-changelog.md:408 +#: ../../source/ref-changelog.md:500 msgid "" "**General improvements** " "([#1659](https://github.com/adap/flower/pull/1659), " @@ -17370,11 +18132,11 @@ msgstr "" "[#1692](https://github.com/adap/flower/pull/1692), " "[#1705](https://github.com/ada" -#: ../../source/ref-changelog.md:416 +#: ../../source/ref-changelog.md:508 msgid "v1.3.0 (2023-02-06)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:422 +#: ../../source/ref-changelog.md:514 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" @@ -17382,7 +18144,7 @@ msgstr "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" -#: ../../source/ref-changelog.md:426 +#: ../../source/ref-changelog.md:518 msgid "" "**Add support for** `workload_id` **and** `group_id` **in Driver API** " "([#1595](https://github.com/adap/flower/pull/1595))" @@ -17390,7 +18152,7 @@ msgstr "" "**Ajouter la prise en charge de** `workload_id` **et** `group_id` **dans " "l'API du pilote** ([#1595](https://github.com/adap/flower/pull/1595))" -#: ../../source/ref-changelog.md:428 +#: ../../source/ref-changelog.md:520 msgid "" "The (experimental) Driver API now supports a `workload_id` that can be " "used to identify which workload a task belongs to. It also supports a new" @@ -17405,7 +18167,7 @@ msgstr "" "en cours. Le `workload_id` et le `group_id` permettent tous deux aux " "nœuds clients de décider s'ils veulent traiter une tâche ou non." -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:522 msgid "" "**Make Driver API and Fleet API address configurable** " "([#1637](https://github.com/adap/flower/pull/1637))" @@ -17414,7 +18176,7 @@ msgstr "" "flotte soit configurable** " "([#1637](https://github.com/adap/flower/pull/1637))" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:524 msgid "" "The (experimental) long-running Flower server (Driver API and Fleet API) " "can now configure the server address of both Driver API (via `--driver-" @@ -17425,7 +18187,7 @@ msgstr "" "`--driver-api-address`) et de Fleet API (via `--fleet-api-address`) lors " "de son démarrage :" -#: ../../source/ref-changelog.md:434 +#: ../../source/ref-changelog.md:526 #, fuzzy msgid "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " @@ -17434,11 +18196,11 @@ msgstr "" "``flower-superlink --driver-api-address \"0.0.0.0:8081\" --fleet-api-" "address \"0.0.0.0:8086\" ``" -#: ../../source/ref-changelog.md:436 +#: ../../source/ref-changelog.md:528 msgid "Both IPv4 and IPv6 addresses are supported." msgstr "Les adresses IPv4 et IPv6 sont toutes deux prises en charge." -#: ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:530 msgid "" "**Add new example of Federated Learning using fastai and Flower** " "([#1598](https://github.com/adap/flower/pull/1598))" @@ -17446,7 +18208,7 @@ msgstr "" "**Ajouter un nouvel exemple d'apprentissage fédéré utilisant fastai et " "Flower** ([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:440 +#: ../../source/ref-changelog.md:532 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " @@ -17459,7 +18221,7 @@ msgstr "" "fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" "fastai)." -#: ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:534 msgid "" "**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" " versions of Android** " @@ -17469,7 +18231,7 @@ msgstr "" "dernières versions d'Android** " "([#1603](https://github.com/adap/flower/pull/1603))" -#: ../../source/ref-changelog.md:444 +#: ../../source/ref-changelog.md:536 #, fuzzy msgid "" "The Android code example has received a substantial update: the project " @@ -17483,7 +18245,7 @@ msgstr "" "est mis à jour pour être compatible avec les outils Android les plus " "récents." -#: ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:538 msgid "" "**Add new `FedProx` strategy** " "([#1619](https://github.com/adap/flower/pull/1619))" @@ -17491,7 +18253,7 @@ msgstr "" "**Ajouter une nouvelle stratégie `FedProx`** " "([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:540 msgid "" "This " "[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" @@ -17511,7 +18273,7 @@ msgstr "" "un paramètre appelé `proximal_mu` pour régulariser les modèles locaux par" " rapport aux modèles globaux." -#: ../../source/ref-changelog.md:450 +#: ../../source/ref-changelog.md:542 msgid "" "**Add new metrics to telemetry events** " "([#1640](https://github.com/adap/flower/pull/1640))" @@ -17519,7 +18281,7 @@ msgstr "" "**Ajouter de nouvelles métriques aux événements de télémétrie** " "([#1640](https://github.com/adap/flower/pull/1640))" -#: ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:544 msgid "" "An updated event structure allows, for example, the clustering of events " "within the same workload." @@ -17527,7 +18289,7 @@ msgstr "" "Une structure d'événements mise à jour permet, par exemple, de regrouper " "des événements au sein d'une même charge de travail." -#: ../../source/ref-changelog.md:454 +#: ../../source/ref-changelog.md:546 msgid "" "**Add new custom strategy tutorial section** " "[#1623](https://github.com/adap/flower/pull/1623)" @@ -17535,7 +18297,7 @@ msgstr "" "**Ajouter une nouvelle section de tutoriel sur les stratégies " "personnalisées** [#1623](https://github.com/adap/flower/pull/1623)" -#: ../../source/ref-changelog.md:456 +#: ../../source/ref-changelog.md:548 #, fuzzy msgid "" "The Flower tutorial now has a new section that covers implementing a " @@ -17549,7 +18311,7 @@ msgstr "" "Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-3-Building-a" "-Strategy-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:458 +#: ../../source/ref-changelog.md:550 msgid "" "**Add new custom serialization tutorial section** " "([#1622](https://github.com/adap/flower/pull/1622))" @@ -17557,7 +18319,7 @@ msgstr "" "**Ajouter une nouvelle section de tutoriel sur la sérialisation " "personnalisée** ([#1622](https://github.com/adap/flower/pull/1622))" -#: ../../source/ref-changelog.md:460 +#: ../../source/ref-changelog.md:552 #, fuzzy msgid "" "The Flower tutorial now has a new section that covers custom " @@ -17570,7 +18332,7 @@ msgstr "" "Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source/tutorial/Flower-4" "-Client-and-NumPyClient-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:462 +#: ../../source/ref-changelog.md:554 msgid "" "**General improvements** " "([#1638](https://github.com/adap/flower/pull/1638), " @@ -17629,7 +18391,7 @@ msgstr "" "[#1599](https://github.com/adap/flower/pull/1599), " "[#1600](https://github.com/ada" -#: ../../source/ref-changelog.md:466 +#: ../../source/ref-changelog.md:558 msgid "" "**Updated documentation** " "([#1629](https://github.com/adap/flower/pull/1629), " @@ -17649,7 +18411,7 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614))" -#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 +#: ../../source/ref-changelog.md:560 ../../source/ref-changelog.md:627 msgid "" "As usual, the documentation has improved quite a bit. It is another step " "in our effort to make the Flower documentation the best documentation of " @@ -17660,11 +18422,11 @@ msgstr "" " meilleure documentation de tout projet. Reste à l'écoute et comme " "toujours, n'hésite pas à nous faire part de tes commentaires !" -#: ../../source/ref-changelog.md:474 +#: ../../source/ref-changelog.md:566 msgid "v1.2.0 (2023-01-13)" msgstr "v1.2.0 (2023-01-13)" -#: ../../source/ref-changelog.md:480 +#: ../../source/ref-changelog.md:572 msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." " Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" @@ -17672,7 +18434,7 @@ msgstr "" "adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " "Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" -#: ../../source/ref-changelog.md:484 +#: ../../source/ref-changelog.md:576 msgid "" "**Introduce new Flower Baseline: FedAvg MNIST** " "([#1497](https://github.com/adap/flower/pull/1497), " @@ -17682,7 +18444,7 @@ msgstr "" "([#1497](https://github.com/adap/flower/pull/1497), " "[#1552](https://github.com/adap/flower/pull/1552))" -#: ../../source/ref-changelog.md:486 +#: ../../source/ref-changelog.md:578 msgid "" "Over the coming weeks, we will be releasing a number of new reference " "implementations useful especially to FL newcomers. They will typically " @@ -17702,7 +18464,7 @@ msgstr "" "suite.](https://flower.ai/blog/2023-01-12-fl-starter-pack-fedavg-mnist-" "cnn/)" -#: ../../source/ref-changelog.md:488 +#: ../../source/ref-changelog.md:580 msgid "" "**Improve GPU support in simulations** " "([#1555](https://github.com/adap/flower/pull/1555))" @@ -17710,7 +18472,7 @@ msgstr "" "**Améliorer la prise en charge des GPU dans les simulations** " "([#1555](https://github.com/adap/flower/pull/1555))" -#: ../../source/ref-changelog.md:490 +#: ../../source/ref-changelog.md:582 msgid "" "The Ray-based Virtual Client Engine (`start_simulation`) has been updated" " to improve GPU support. The update includes some of the hard-earned " @@ -17724,7 +18486,7 @@ msgstr "" "paramètres par défaut rendent l'exécution des simulations basées sur les " "GPU beaucoup plus robuste." -#: ../../source/ref-changelog.md:492 +#: ../../source/ref-changelog.md:584 msgid "" "**Improve GPU support in Jupyter Notebook tutorials** " "([#1527](https://github.com/adap/flower/pull/1527), " @@ -17734,7 +18496,7 @@ msgstr "" "Notebook** ([#1527](https://github.com/adap/flower/pull/1527), " "[#1558](https://github.com/adap/flower/pull/1558))" -#: ../../source/ref-changelog.md:494 +#: ../../source/ref-changelog.md:586 msgid "" "Some users reported that Jupyter Notebooks have not always been easy to " "use on GPU instances. We listened and made improvements to all of our " @@ -17745,7 +18507,7 @@ msgstr "" "écoutés et avons apporté des améliorations à tous nos carnets Jupyter ! " "Découvre les carnets mis à jour ici :" -#: ../../source/ref-changelog.md:496 +#: ../../source/ref-changelog.md:588 #, fuzzy msgid "" "[An Introduction to Federated Learning](https://flower.ai/docs/framework" @@ -17754,7 +18516,7 @@ msgstr "" "[Une introduction à l'apprentissage fédéré] " "(https://flower.ai/docs/tutorial/Flower-1-Intro-to-FL-PyTorch.html)" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:589 #, fuzzy msgid "" "[Strategies in Federated Learning](https://flower.ai/docs/framework" @@ -17763,7 +18525,7 @@ msgstr "" "[Stratégies d'apprentissage fédéré] " "(https://flower.ai/docs/tutorial/Flower-2-Strategies-in-FL-PyTorch.html)" -#: ../../source/ref-changelog.md:498 +#: ../../source/ref-changelog.md:590 #, fuzzy msgid "" "[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" @@ -17773,7 +18535,7 @@ msgstr "" "(https://flower.ai/docs/tutorial/Flower-3-Building-a-Strategy-" "PyTorch.html)" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:591 #, fuzzy msgid "" "[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" @@ -17782,7 +18544,7 @@ msgstr "" "[Client et NumPyClient] (https://flower.ai/docs/tutorial/Flower-4-Client-" "and-NumPyClient-PyTorch.html)" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:593 msgid "" "**Introduce optional telemetry** " "([#1533](https://github.com/adap/flower/pull/1533), " @@ -17794,7 +18556,7 @@ msgstr "" "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584))" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:595 msgid "" "After a [request for " "feedback](https://github.com/adap/flower/issues/1534) from the community," @@ -17811,7 +18573,7 @@ msgstr "" "comment Flower est utilisé et quels sont les défis auxquels les " "utilisateurs peuvent être confrontés." -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:597 #, fuzzy msgid "" "**Flower is a friendly framework for collaborative AI and data science.**" @@ -17825,7 +18587,7 @@ msgstr "" "souhaitent pas partager des métriques d'utilisation anonymes.[Lire la " "suite.](https://flower.ai/docs/telemetry.html)." -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:599 msgid "" "**Introduce (experimental) Driver API** " "([#1520](https://github.com/adap/flower/pull/1520), " @@ -17844,7 +18606,7 @@ msgstr "" "[#1551](https://github.com/adap/flower/pull/1551), " "[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:601 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " @@ -17859,7 +18621,7 @@ msgstr "" "laquelle de nombreuses fonctionnalités à venir seront construites - et tu" " peux commencer à construire ces choses dès maintenant, aussi." -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:603 msgid "" "The Driver API also enables a new execution mode in which the server runs" " indefinitely. Multiple individual workloads can run concurrently and " @@ -17872,7 +18634,7 @@ msgstr "" "leur exécution indépendamment du serveur. Ceci est particulièrement utile" " pour les utilisateurs qui souhaitent déployer Flower en production." -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:605 msgid "" "To learn more, check out the `mt-pytorch` code example. We look forward " "to you feedback!" @@ -17880,7 +18642,7 @@ msgstr "" "Pour en savoir plus, consulte l'exemple de code `mt-pytorch`. Nous " "attendons tes commentaires avec impatience !" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:607 msgid "" "Please note: *The Driver API is still experimental and will likely change" " significantly over time.*" @@ -17888,7 +18650,7 @@ msgstr "" "Remarque : *L'API du pilote est encore expérimentale et est susceptible " "de changer de manière significative au fil du temps.*" -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:609 msgid "" "**Add new Federated Analytics with Pandas example** " "([#1469](https://github.com/adap/flower/pull/1469), " @@ -17898,7 +18660,7 @@ msgstr "" "([#1469](https://github.com/adap/flower/pull/1469), " "[#1535](https://github.com/adap/flower/pull/1535))" -#: ../../source/ref-changelog.md:519 +#: ../../source/ref-changelog.md:611 msgid "" "A new code example (`quickstart-pandas`) demonstrates federated analytics" " with Pandas and Flower. You can find it here: [quickstart-" @@ -17910,7 +18672,7 @@ msgstr "" "pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" "pandas)." -#: ../../source/ref-changelog.md:521 +#: ../../source/ref-changelog.md:613 msgid "" "**Add new strategies: Krum and MultiKrum** " "([#1481](https://github.com/adap/flower/pull/1481))" @@ -17918,7 +18680,7 @@ msgstr "" "**Ajouter de nouvelles stratégies : Krum et MultiKrum** " "([#1481](https://github.com/adap/flower/pull/1481))" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:615 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " "contributed a new `Krum` strategy that enables users to easily use Krum " @@ -17928,7 +18690,7 @@ msgstr "" "contribué à une nouvelle stratégie `Krum` qui permet aux utilisateurs " "d'utiliser facilement Krum et MultiKrum dans leurs charges de travail." -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:617 msgid "" "**Update C++ example to be compatible with Flower v1.2.0** " "([#1495](https://github.com/adap/flower/pull/1495))" @@ -17936,7 +18698,7 @@ msgstr "" "**Mettre à jour l'exemple C++ pour qu'il soit compatible avec Flower " "v1.2.0** ([#1495](https://github.com/adap/flower/pull/1495))" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:619 msgid "" "The C++ code example has received a substantial update to make it " "compatible with the latest version of Flower." @@ -17944,7 +18706,7 @@ msgstr "" "L'exemple de code C++ a reçu une mise à jour substantielle pour le rendre" " compatible avec la dernière version de Flower." -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:621 msgid "" "**General improvements** " "([#1491](https://github.com/adap/flower/pull/1491), " @@ -17976,7 +18738,7 @@ msgstr "" "[#1564](https://github.com/adap/flower/pull/1564), " "[#1566](https://github.com/adap/flower/pull/1566))" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:625 msgid "" "**Updated documentation** " "([#1494](https://github.com/adap/flower/pull/1494), " @@ -18000,7 +18762,7 @@ msgstr "" "[#1519](https://github.com/adap/flower/pull/1519), " "[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:537 +#: ../../source/ref-changelog.md:629 msgid "" "One highlight is the new [first time contributor " "guide](https://flower.ai/docs/first-time-contributors.html): if you've " @@ -18010,11 +18772,11 @@ msgstr "" "(https://flower.ai/docs/first-time-contributors.html) : si tu n'as jamais" " contribué sur GitHub auparavant, c'est l'endroit idéal pour commencer !" -#: ../../source/ref-changelog.md:543 +#: ../../source/ref-changelog.md:635 msgid "v1.1.0 (2022-10-31)" msgstr "v1.1.0 (2022-10-31)" -#: ../../source/ref-changelog.md:547 +#: ../../source/ref-changelog.md:639 msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" @@ -18023,7 +18785,7 @@ msgstr "" " qui ont rendu possible la nouvelle version de Flower (dans l'ordre `git " "shortlog`) :" -#: ../../source/ref-changelog.md:549 +#: ../../source/ref-changelog.md:641 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " @@ -18035,7 +18797,7 @@ msgstr "" "Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " "`danielnugraha`, `edogab33`" -#: ../../source/ref-changelog.md:553 +#: ../../source/ref-changelog.md:645 msgid "" "**Introduce Differential Privacy wrappers (preview)** " "([#1357](https://github.com/adap/flower/pull/1357), " @@ -18045,7 +18807,7 @@ msgstr "" "([#1357](https://github.com/adap/flower/pull/1357), " "[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:555 +#: ../../source/ref-changelog.md:647 msgid "" "The first (experimental) preview of pluggable Differential Privacy " "wrappers enables easy configuration and usage of differential privacy " @@ -18061,7 +18823,7 @@ msgstr "" "voir les documents de Flower, un nouvel explicatif va plus loin dans les " "détails." -#: ../../source/ref-changelog.md:557 +#: ../../source/ref-changelog.md:649 msgid "" "**New iOS CoreML code example** " "([#1289](https://github.com/adap/flower/pull/1289))" @@ -18069,7 +18831,7 @@ msgstr "" "**Nouvel exemple de code CoreML pour iOS** " "([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:559 +#: ../../source/ref-changelog.md:651 msgid "" "Flower goes iOS! A massive new code example shows how Flower clients can " "be built for iOS. The code example contains both Flower iOS SDK " @@ -18082,7 +18844,7 @@ msgstr "" "utilisés pour de nombreuses tâches, et un exemple de tâche fonctionnant " "sur CoreML." -#: ../../source/ref-changelog.md:561 +#: ../../source/ref-changelog.md:653 msgid "" "**New FedMedian strategy** " "([#1461](https://github.com/adap/flower/pull/1461))" @@ -18090,7 +18852,7 @@ msgstr "" "**Nouvelle stratégie de FedMedian** " "([#1461](https://github.com/adap/flower/pull/1461))" -#: ../../source/ref-changelog.md:563 +#: ../../source/ref-changelog.md:655 msgid "" "The new `FedMedian` strategy implements Federated Median (FedMedian) by " "[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." @@ -18099,7 +18861,7 @@ msgstr "" "(FedMedian) par [Yin et al., 2018] " "(https://arxiv.org/pdf/1803.01498v1.pdf)." -#: ../../source/ref-changelog.md:565 +#: ../../source/ref-changelog.md:657 msgid "" "**Log** `Client` **exceptions in Virtual Client Engine** " "([#1493](https://github.com/adap/flower/pull/1493))" @@ -18107,7 +18869,7 @@ msgstr "" "**Log** `Client` **exceptions dans le moteur de client virtuel** " "([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:567 +#: ../../source/ref-changelog.md:659 msgid "" "All `Client` exceptions happening in the VCE are now logged by default " "and not just exposed to the configured `Strategy` (via the `failures` " @@ -18117,7 +18879,7 @@ msgstr "" "maintenant enregistrées par défaut et ne sont pas seulement exposées à la" " `Stratégie` configurée (via l'argument `failures`)." -#: ../../source/ref-changelog.md:569 +#: ../../source/ref-changelog.md:661 msgid "" "**Improve Virtual Client Engine internals** " "([#1401](https://github.com/adap/flower/pull/1401), " @@ -18127,7 +18889,7 @@ msgstr "" "([#1401](https://github.com/adap/flower/pull/1401), " "[#1453](https://github.com/adap/flower/pull/1453))" -#: ../../source/ref-changelog.md:571 +#: ../../source/ref-changelog.md:663 msgid "" "Some internals of the Virtual Client Engine have been revamped. The VCE " "now uses Ray 2.0 under the hood, the value type of the `client_resources`" @@ -18138,7 +18900,7 @@ msgstr "" "dictionnaire `client_resources` a été remplacé par `float` pour permettre" " l'allocation de fractions de ressources." -#: ../../source/ref-changelog.md:573 +#: ../../source/ref-changelog.md:665 msgid "" "**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " "Client Engine**" @@ -18146,7 +18908,7 @@ msgstr "" "**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " "Client Engine**" -#: ../../source/ref-changelog.md:575 +#: ../../source/ref-changelog.md:667 msgid "" "The Virtual Client Engine now has full support for optional `Client` (and" " `NumPyClient`) methods." @@ -18154,7 +18916,7 @@ msgstr "" "Le moteur de client virtuel prend désormais en charge les méthodes " "optionnelles `Client` (et `NumPyClient`)." -#: ../../source/ref-changelog.md:577 +#: ../../source/ref-changelog.md:669 msgid "" "**Provide type information to packages using** `flwr` " "([#1377](https://github.com/adap/flower/pull/1377))" @@ -18162,7 +18924,7 @@ msgstr "" "**Fournir des informations de type aux paquets en utilisant** `flwr` " "([#1377](https://github.com/adap/flower/pull/1377))" -#: ../../source/ref-changelog.md:579 +#: ../../source/ref-changelog.md:671 msgid "" "The package `flwr` is now bundled with a `py.typed` file indicating that " "the package is typed. This enables typing support for projects or " @@ -18175,7 +18937,7 @@ msgstr "" "permettant d'améliorer leur code à l'aide de vérificateurs de types " "statiques comme `mypy`." -#: ../../source/ref-changelog.md:581 +#: ../../source/ref-changelog.md:673 msgid "" "**Updated code example** " "([#1344](https://github.com/adap/flower/pull/1344), " @@ -18185,7 +18947,7 @@ msgstr "" "([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:583 +#: ../../source/ref-changelog.md:675 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." @@ -18193,7 +18955,7 @@ msgstr "" "Les exemples de code couvrant scikit-learn et PyTorch Lightning ont été " "mis à jour pour fonctionner avec la dernière version de Flower." -#: ../../source/ref-changelog.md:585 +#: ../../source/ref-changelog.md:677 msgid "" "**Updated documentation** " "([#1355](https://github.com/adap/flower/pull/1355), " @@ -18233,7 +18995,7 @@ msgstr "" "[#1465](https://github.com/adap/flower/pull/1465), " "[#1467](https://github.com/adap/flower/pull/1467))" -#: ../../source/ref-changelog.md:587 +#: ../../source/ref-changelog.md:679 msgid "" "There have been so many documentation updates that it doesn't even make " "sense to list them individually." @@ -18241,7 +19003,7 @@ msgstr "" "Il y a eu tellement de mises à jour de la documentation que cela n'a même" " pas de sens de les énumérer individuellement." -#: ../../source/ref-changelog.md:589 +#: ../../source/ref-changelog.md:681 msgid "" "**Restructured documentation** " "([#1387](https://github.com/adap/flower/pull/1387))" @@ -18249,7 +19011,7 @@ msgstr "" "**Documentation restructurée** " "([#1387](https://github.com/adap/flower/pull/1387))" -#: ../../source/ref-changelog.md:591 +#: ../../source/ref-changelog.md:683 msgid "" "The documentation has been restructured to make it easier to navigate. " "This is just the first step in a larger effort to make the Flower " @@ -18259,7 +19021,7 @@ msgstr "" "n'est que la première étape d'un effort plus important visant à faire de " "la documentation de Flower la meilleure documentation de tous les projets" -#: ../../source/ref-changelog.md:593 +#: ../../source/ref-changelog.md:685 msgid "" "**Open in Colab button** " "([#1389](https://github.com/adap/flower/pull/1389))" @@ -18267,7 +19029,7 @@ msgstr "" "**Ouvrir dans le bouton Colab** " "([#1389](https://github.com/adap/flower/pull/1389))" -#: ../../source/ref-changelog.md:595 +#: ../../source/ref-changelog.md:687 msgid "" "The four parts of the Flower Federated Learning Tutorial now come with a " "new `Open in Colab` button. No need to install anything on your local " @@ -18280,7 +19042,7 @@ msgstr "" "maintenant utiliser et apprendre à connaître Flower dans ton navigateur, " "il te suffit d'un simple clic." -#: ../../source/ref-changelog.md:597 +#: ../../source/ref-changelog.md:689 msgid "" "**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," " [#1470](https://github.com/adap/flower/pull/1470), " @@ -18296,7 +19058,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475))" -#: ../../source/ref-changelog.md:599 +#: ../../source/ref-changelog.md:691 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " @@ -18309,27 +19071,27 @@ msgstr "" "existantes ont également été améliorées (beaucoup de petits changements " "et de corrections)." -#: ../../source/ref-changelog.md:605 +#: ../../source/ref-changelog.md:697 msgid "v1.0.0 (2022-07-28)" msgstr "v1.0.0 (2022-07-28)" -#: ../../source/ref-changelog.md:607 +#: ../../source/ref-changelog.md:699 msgid "Highlights" msgstr "Points forts" -#: ../../source/ref-changelog.md:609 +#: ../../source/ref-changelog.md:701 msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "Moteur de client virtuel stable** (accessible via `start_simulation`)" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:702 msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "Toutes les méthodes `Client`/`NumPyClient` sont maintenant optionnelles" -#: ../../source/ref-changelog.md:611 +#: ../../source/ref-changelog.md:703 msgid "Configurable `get_parameters`" msgstr "`get_parameters` configurable" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:704 msgid "" "Tons of small API cleanups resulting in a more coherent developer " "experience" @@ -18337,7 +19099,7 @@ msgstr "" "Des tonnes de petits nettoyages d'API résultant en une expérience plus " "cohérente pour les développeurs" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:708 msgid "" "We would like to give our **special thanks** to all the contributors who " "made Flower 1.0 possible (in reverse [GitHub " @@ -18347,7 +19109,7 @@ msgstr "" "ont rendu Flower 1.0 possible (dans l'ordre inverse de [GitHub " "Contributors](https://github.com/adap/flower/graphs/contributors)) :" -#: ../../source/ref-changelog.md:618 +#: ../../source/ref-changelog.md:710 msgid "" "[@rtaiello](https://github.com/rtaiello), " "[@g-pichler](https://github.com/g-pichler), [@rob-" @@ -18407,7 +19169,7 @@ msgstr "" "/Jueun-Park), [@architjen](https://github.com/architjen), " "[@PratikGarai](https://github.com/PratikGarai), [@mrinaald](" -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:714 msgid "" "**All arguments must be passed as keyword arguments** " "([#1338](https://github.com/adap/flower/pull/1338))" @@ -18415,7 +19177,7 @@ msgstr "" "**Tous les arguments doivent être passés comme des arguments de mot-clé**" " ([#1338](https://github.com/adap/flower/pull/1338))" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:716 #, fuzzy msgid "" "Pass all arguments as keyword arguments, positional arguments are not " @@ -18431,7 +19193,7 @@ msgstr "" "``start_client(server_address=\"127.0.0.1:8080\", " "client=FlowerClient())`)." -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:718 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " "**and** `start_simulation` " @@ -18441,7 +19203,7 @@ msgstr "" "`start_server` **et** `start_simulation` " "([#1317](https://github.com/adap/flower/pull/1317))" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:720 msgid "" "Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " "600.0}`, `start_server` and `start_simulation` now expect a configuration" @@ -18457,7 +19219,7 @@ msgstr "" "sécurisé plus facile et les valeurs des paramètres par défaut plus " "transparentes." -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:722 msgid "" "**Rename built-in strategy parameters for clarity** " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -18465,7 +19227,7 @@ msgstr "" "**Renommer les paramètres de la stratégie intégrée pour plus de clarté** " "([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:632 +#: ../../source/ref-changelog.md:724 msgid "" "The following built-in strategy parameters were renamed to improve " "readability and consistency with other API's:" @@ -18473,19 +19235,19 @@ msgstr "" "Les paramètres de stratégie intégrés suivants ont été renommés pour " "améliorer la lisibilité et la cohérence avec d'autres API :" -#: ../../source/ref-changelog.md:634 +#: ../../source/ref-changelog.md:726 msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "`fraction_eval` --> `fraction_evaluate`" -#: ../../source/ref-changelog.md:635 +#: ../../source/ref-changelog.md:727 msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "`min_eval_clients` --> `min_evaluate_clients`" -#: ../../source/ref-changelog.md:636 +#: ../../source/ref-changelog.md:728 msgid "`eval_fn` --> `evaluate_fn`" msgstr "`eval_fn` --> `evaluate_fn`" -#: ../../source/ref-changelog.md:638 +#: ../../source/ref-changelog.md:730 msgid "" "**Update default arguments of built-in strategies** " "([#1278](https://github.com/adap/flower/pull/1278))" @@ -18493,7 +19255,7 @@ msgstr "" "**Mettre à jour les arguments par défaut des stratégies intégrées** " "([#1278](https://github.com/adap/flower/pull/1278))" -#: ../../source/ref-changelog.md:640 +#: ../../source/ref-changelog.md:732 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " "`fraction_evaluate=1.0`, which means they select *all* currently " @@ -18508,11 +19270,11 @@ msgstr "" "peuvent retrouver le comportement antérieur en initialisant la stratégie " "de la manière suivante :" -#: ../../source/ref-changelog.md:642 +#: ../../source/ref-changelog.md:734 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "`stratégie = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" -#: ../../source/ref-changelog.md:644 +#: ../../source/ref-changelog.md:736 msgid "" "**Add** `server_round` **to** `Strategy.evaluate` " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -18520,7 +19282,7 @@ msgstr "" "**Ajouter** `server_round` **à** `Strategy.evaluate` " "([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:646 +#: ../../source/ref-changelog.md:738 msgid "" "The `Strategy` method `evaluate` now receives the current round of " "federated learning/evaluation as the first parameter." @@ -18528,7 +19290,7 @@ msgstr "" "La méthode `Stratégie` `évaluer` reçoit maintenant le cycle actuel " "d'apprentissage/évaluation fédéré comme premier paramètre." -#: ../../source/ref-changelog.md:648 +#: ../../source/ref-changelog.md:740 msgid "" "**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -18536,7 +19298,7 @@ msgstr "" "**Ajouter** `server_round` **et** `config` **paramètres à** `evaluate_fn`" " ([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:742 msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " @@ -18549,7 +19311,7 @@ msgstr "" " modèle à évaluer (`parameters`), et (3) un dictionnaire de configuration" " (`config`)." -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:744 msgid "" "**Rename** `rnd` **to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" @@ -18557,7 +19319,7 @@ msgstr "" "**Rename** `rnd` **to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:654 +#: ../../source/ref-changelog.md:746 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " @@ -18572,7 +19334,7 @@ msgstr "" " la fiabilité et éviter la confusion avec *random*, ce paramètre a été " "renommé de `rnd` à `server_round`." -#: ../../source/ref-changelog.md:656 +#: ../../source/ref-changelog.md:748 msgid "" "**Move** `flwr.dataset` **to** `flwr_baselines` " "([#1273](https://github.com/adap/flower/pull/1273))" @@ -18580,11 +19342,11 @@ msgstr "" "**Déplacer** `flwr.dataset` **vers** `flwr_baselines` " "([#1273](https://github.com/adap/flower/pull/1273))" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:750 msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "Le paquet expérimental `flwr.dataset` a été migré vers Flower Baselines." -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:752 msgid "" "**Remove experimental strategies** " "([#1280](https://github.com/adap/flower/pull/1280))" @@ -18592,7 +19354,7 @@ msgstr "" "**Supprimer les stratégies expérimentales** " "([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:754 msgid "" "Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " "`FedFSv1`)." @@ -18600,7 +19362,7 @@ msgstr "" "Supprimer les stratégies expérimentales non maintenues (`FastAndSlow`, " "`FedFSv0`, `FedFSv1`)." -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:756 msgid "" "**Rename** `Weights` **to** `NDArrays` " "([#1258](https://github.com/adap/flower/pull/1258), " @@ -18610,7 +19372,7 @@ msgstr "" "([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:758 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." @@ -18618,7 +19380,7 @@ msgstr "" "`flwr.common.Weights` a été renommé en `flwr.common.NDArys` pour mieux " "rendre compte de la nature de ce type." -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:760 msgid "" "**Remove antiquated** `force_final_distributed_eval` **from** " "`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " @@ -18628,7 +19390,7 @@ msgstr "" "`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:762 msgid "" "The `start_server` parameter `force_final_distributed_eval` has long been" " a historic artefact, in this release it is finally gone for good." @@ -18637,7 +19399,7 @@ msgstr "" "été un artefact historique, dans cette version il a finalement disparu " "pour de bon." -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:764 msgid "" "**Make** `get_parameters` **configurable** " "([#1242](https://github.com/adap/flower/pull/1242))" @@ -18645,7 +19407,7 @@ msgstr "" "**Make** `get_parameters` **configurable** " "([#1242](https://github.com/adap/flower/pull/1242))" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:766 msgid "" "The `get_parameters` method now accepts a configuration dictionary, just " "like `get_properties`, `fit`, and `evaluate`." @@ -18653,7 +19415,7 @@ msgstr "" "La méthode `get_parameters` accepte maintenant un dictionnaire de " "configuration, tout comme `get_properties`, `fit`, et `evaluate`." -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:768 msgid "" "**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " "**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" @@ -18662,7 +19424,7 @@ msgstr "" " `config` **paramètre** " "([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:770 msgid "" "The `start_simulation` function now accepts a configuration dictionary " "`config` instead of the `num_rounds` integer. This improves the " @@ -18674,7 +19436,7 @@ msgstr "" " cohérence entre `start_simulation` et `start_server` et facilite la " "transition entre les deux." -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:774 msgid "" "**Support Python 3.10** " "([#1320](https://github.com/adap/flower/pull/1320))" @@ -18682,7 +19444,7 @@ msgstr "" "**Support Python 3.10** " "([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:776 msgid "" "The previous Flower release introduced experimental support for Python " "3.10, this release declares Python 3.10 support as stable." @@ -18691,7 +19453,7 @@ msgstr "" "expérimentale de Python 3.10, cette version déclare la prise en charge de" " Python 3.10 comme stable." -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:778 msgid "" "**Make all** `Client` **and** `NumPyClient` **methods optional** " "([#1260](https://github.com/adap/flower/pull/1260), " @@ -18701,7 +19463,7 @@ msgstr "" "**facultatives** ([#1260](https://github.com/adap/flower/pull/1260), " "[#1277](https://github.com/adap/flower/pull/1277))" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:780 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " "`fit`, and `evaluate` are all optional. This enables writing clients that" @@ -18714,7 +19476,7 @@ msgstr "" "méthode. Pas besoin d'implémenter `evaluate` quand on utilise " "l'évaluation centralisée !" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:782 msgid "" "**Enable passing a** `Server` **instance to** `start_simulation` " "([#1281](https://github.com/adap/flower/pull/1281))" @@ -18722,7 +19484,7 @@ msgstr "" "**Autoriser le passage d'une **instance `Server` à** `start_simulation` " "([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:784 msgid "" "Similar to `start_server`, `start_simulation` now accepts a full `Server`" " instance. This enables users to heavily customize the execution of " @@ -18735,7 +19497,7 @@ msgstr "" "l'exécution, par exemple, de FL asynchrones à l'aide du moteur de client " "virtuel." -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:786 msgid "" "**Update code examples** " "([#1291](https://github.com/adap/flower/pull/1291), " @@ -18747,7 +19509,7 @@ msgstr "" "[#1286](https://github.com/adap/flower/pull/1286), " "[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:788 msgid "" "Many code examples received small or even large maintenance updates, " "among them are" @@ -18755,31 +19517,31 @@ msgstr "" "De nombreux exemples de code ont reçu de petites ou même de grandes mises" " à jour de maintenance" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:790 msgid "`scikit-learn`" msgstr "`scikit-learn`" -#: ../../source/ref-changelog.md:699 +#: ../../source/ref-changelog.md:791 msgid "`simulation_pytorch`" msgstr "`simulation_pytorch`" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:792 msgid "`quickstart_pytorch`" msgstr "`quickstart_pytorch` (démarrage rapide)" -#: ../../source/ref-changelog.md:701 +#: ../../source/ref-changelog.md:793 msgid "`quickstart_simulation`" msgstr "`quickstart_simulation`" -#: ../../source/ref-changelog.md:702 +#: ../../source/ref-changelog.md:794 msgid "`quickstart_tensorflow`" msgstr "`quickstart_tensorflow`" -#: ../../source/ref-changelog.md:703 +#: ../../source/ref-changelog.md:795 msgid "`advanced_tensorflow`" msgstr "`advanced_tensorflow` (en anglais)" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:797 msgid "" "**Remove the obsolete simulation example** " "([#1328](https://github.com/adap/flower/pull/1328))" @@ -18787,7 +19549,7 @@ msgstr "" "**Supprime l'exemple de simulation obsolète** " "([#1328](https://github.com/adap/flower/pull/1328))" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:799 msgid "" "Removes the obsolete `simulation` example and renames " "`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " @@ -18797,7 +19559,7 @@ msgstr "" "`quickstart_simulation` en `simulation_tensorflow` pour qu'il corresponde" " au nom de `simulation_pytorch`" -#: ../../source/ref-changelog.md:709 +#: ../../source/ref-changelog.md:801 msgid "" "**Update documentation** " "([#1223](https://github.com/adap/flower/pull/1223), " @@ -18823,7 +19585,7 @@ msgstr "" "[#1305](https://github.com/adap/flower/pull/1305), " "[#1307](https://github.com/adap/flower/pull/1307))" -#: ../../source/ref-changelog.md:711 +#: ../../source/ref-changelog.md:803 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " @@ -18840,12 +19602,12 @@ msgstr "" "markdown, migre le changelog de `.rst` vers `.md`, et corrige un certain " "nombre de détails plus petits !" -#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 -#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +#: ../../source/ref-changelog.md:805 ../../source/ref-changelog.md:860 +#: ../../source/ref-changelog.md:929 ../../source/ref-changelog.md:968 msgid "**Minor updates**" msgstr "**Mises à jour mineures**" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:807 msgid "" "Add round number to fit and evaluate log messages " "([#1266](https://github.com/adap/flower/pull/1266))" @@ -18853,7 +19615,7 @@ msgstr "" "Ajoute un chiffre rond pour ajuster et évaluer les messages du journal " "([#1266](https://github.com/adap/flower/pull/1266))" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:808 msgid "" "Add secure gRPC connection to the `advanced_tensorflow` code example " "([#847](https://github.com/adap/flower/pull/847))" @@ -18861,7 +19623,7 @@ msgstr "" "Ajouter une connexion gRPC sécurisée à l'exemple de code " "`advanced_tensorflow` ([#847](https://github.com/adap/flower/pull/847))" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:809 msgid "" "Update developer tooling " "([#1231](https://github.com/adap/flower/pull/1231), " @@ -18875,7 +19637,7 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310))" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:810 msgid "" "Rename ProtoBuf messages to improve consistency " "([#1214](https://github.com/adap/flower/pull/1214), " @@ -18887,11 +19649,11 @@ msgstr "" "[#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:720 +#: ../../source/ref-changelog.md:812 msgid "v0.19.0 (2022-05-18)" msgstr "v0.19.0 (2022-05-18)" -#: ../../source/ref-changelog.md:724 +#: ../../source/ref-changelog.md:816 msgid "" "**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " "([#919](https://github.com/adap/flower/pull/919), " @@ -18903,7 +19665,7 @@ msgstr "" "[#1127](https://github.com/adap/flower/pull/1127), " "[#914](https://github.com/adap/flower/pull/914))" -#: ../../source/ref-changelog.md:726 +#: ../../source/ref-changelog.md:818 #, fuzzy msgid "" "The first preview release of Flower Baselines has arrived! We're " @@ -18922,7 +19684,7 @@ msgstr "" "également la communauté à [contribuer à leurs propres lignes de " "base](https://flower.ai/docs/baselines/how-to-contribute-baselines.html)." -#: ../../source/ref-changelog.md:728 +#: ../../source/ref-changelog.md:820 msgid "" "**C++ client SDK (preview) and code example** " "([#1111](https://github.com/adap/flower/pull/1111))" @@ -18930,7 +19692,7 @@ msgstr "" "**SDK client C++ (aperçu) et exemple de code** " "([#1111](https://github.com/adap/flower/pull/1111))" -#: ../../source/ref-changelog.md:730 +#: ../../source/ref-changelog.md:822 msgid "" "Preview support for Flower clients written in C++. The C++ preview " "includes a Flower client SDK and a quickstart code example that " @@ -18940,7 +19702,7 @@ msgstr "" "code de démarrage rapide qui démontre un client C++ simple utilisant le " "SDK." -#: ../../source/ref-changelog.md:732 +#: ../../source/ref-changelog.md:824 msgid "" "**Add experimental support for Python 3.10 and Python 3.11** " "([#1135](https://github.com/adap/flower/pull/1135))" @@ -18948,7 +19710,7 @@ msgstr "" "**Ajouter la prise en charge expérimentale de Python 3.10 et Python " "3.11** ([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:734 +#: ../../source/ref-changelog.md:826 msgid "" "Python 3.10 is the latest stable release of Python and Python 3.11 is due" " to be released in October. This Flower release adds experimental support" @@ -18958,7 +19720,7 @@ msgstr "" "devrait sortir en octobre. Cette version de Flower ajoute une prise en " "charge expérimentale pour les deux versions de Python." -#: ../../source/ref-changelog.md:736 +#: ../../source/ref-changelog.md:828 msgid "" "**Aggregate custom metrics through user-provided functions** " "([#1144](https://github.com/adap/flower/pull/1144))" @@ -18966,7 +19728,7 @@ msgstr "" "**Agréger des mesures personnalisées grâce à des fonctions fournies par " "l'utilisateur** ([#1144](https://github.com/adap/flower/pull/1144))" -#: ../../source/ref-changelog.md:738 +#: ../../source/ref-changelog.md:830 msgid "" "Custom metrics (e.g., `accuracy`) can now be aggregated without having to" " customize the strategy. Built-in strategies support two new arguments, " @@ -18978,7 +19740,7 @@ msgstr "" "permettent de passer des fonctions d'agrégation de métriques " "personnalisées." -#: ../../source/ref-changelog.md:740 +#: ../../source/ref-changelog.md:832 msgid "" "**User-configurable round timeout** " "([#1162](https://github.com/adap/flower/pull/1162))" @@ -18986,7 +19748,7 @@ msgstr "" "**Temps d'attente configurable par l'utilisateur** " "([#1162](https://github.com/adap/flower/pull/1162))" -#: ../../source/ref-changelog.md:742 +#: ../../source/ref-changelog.md:834 msgid "" "A new configuration value allows the round timeout to be set for " "`start_server` and `start_simulation`. If the `config` dictionary " @@ -18998,7 +19760,7 @@ msgstr "" "valeur `float` en secondes), le serveur attendra *au moins* " "`round_timeout` secondes avant de fermer la connexion." -#: ../../source/ref-changelog.md:744 +#: ../../source/ref-changelog.md:836 msgid "" "**Enable both federated evaluation and centralized evaluation to be used " "at the same time in all built-in strategies** " @@ -19008,7 +19770,7 @@ msgstr "" "l'évaluation centralisée dans toutes les stratégies intégrées** " "([#1091](https://github.com/adap/flower/pull/1091))" -#: ../../source/ref-changelog.md:746 +#: ../../source/ref-changelog.md:838 msgid "" "Built-in strategies can now perform both federated evaluation (i.e., " "client-side) and centralized evaluation (i.e., server-side) in the same " @@ -19020,7 +19782,7 @@ msgstr "" "(c'est-à-dire côté serveur) dans le même tour. L'évaluation fédérée peut " "être désactivée en réglant `fraction_eval` sur `0.0`." -#: ../../source/ref-changelog.md:748 +#: ../../source/ref-changelog.md:840 msgid "" "**Two new Jupyter Notebook tutorials** " "([#1141](https://github.com/adap/flower/pull/1141))" @@ -19028,7 +19790,7 @@ msgstr "" "**Deux nouveaux tutoriels Jupyter Notebook** " "([#1141](https://github.com/adap/flower/pull/1141))" -#: ../../source/ref-changelog.md:750 +#: ../../source/ref-changelog.md:842 msgid "" "Two Jupyter Notebook tutorials (compatible with Google Colab) explain " "basic and intermediate Flower features:" @@ -19036,7 +19798,7 @@ msgstr "" "Deux tutoriels Jupyter Notebook (compatibles avec Google Colab) " "expliquent les fonctionnalités de base et intermédiaires de Flower :" -#: ../../source/ref-changelog.md:752 +#: ../../source/ref-changelog.md:844 msgid "" "*An Introduction to Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" @@ -19046,7 +19808,7 @@ msgstr "" "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" "-Intro-to-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:754 +#: ../../source/ref-changelog.md:846 msgid "" "*Using Strategies in Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" @@ -19056,7 +19818,7 @@ msgstr "" "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" "-Strategies-in-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:756 +#: ../../source/ref-changelog.md:848 msgid "" "**New FedAvgM strategy (Federated Averaging with Server Momentum)** " "([#1076](https://github.com/adap/flower/pull/1076))" @@ -19064,7 +19826,7 @@ msgstr "" "**Nouvelle stratégie FedAvgM (Federated Averaging with Server Momentum)**" " ([#1076](https://github.com/adap/flower/pull/1076))" -#: ../../source/ref-changelog.md:758 +#: ../../source/ref-changelog.md:850 #, fuzzy msgid "" "The new `FedAvgM` strategy implements Federated Averaging with Server " @@ -19073,7 +19835,7 @@ msgstr "" "La nouvelle stratégie `FedAvgM` met en œuvre la moyenne fédérée avec le " "momentum du serveur [Hsu et al., 2019]." -#: ../../source/ref-changelog.md:760 +#: ../../source/ref-changelog.md:852 msgid "" "**New advanced PyTorch code example** " "([#1007](https://github.com/adap/flower/pull/1007))" @@ -19081,7 +19843,7 @@ msgstr "" "**Nouvel exemple de code PyTorch avancé** " "([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:762 +#: ../../source/ref-changelog.md:854 msgid "" "A new code example (`advanced_pytorch`) demonstrates advanced Flower " "concepts with PyTorch." @@ -19089,7 +19851,7 @@ msgstr "" "Un nouvel exemple de code (`advanced_pytorch`) démontre des concepts de " "fleur avancés avec PyTorch." -#: ../../source/ref-changelog.md:764 +#: ../../source/ref-changelog.md:856 msgid "" "**New JAX code example** " "([#906](https://github.com/adap/flower/pull/906), " @@ -19099,7 +19861,7 @@ msgstr "" "([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" -#: ../../source/ref-changelog.md:766 +#: ../../source/ref-changelog.md:858 msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." @@ -19107,7 +19869,7 @@ msgstr "" "Un nouvel exemple de code (`jax_from_centralized_to_federated`) montre " "l'apprentissage fédéré avec JAX et Flower." -#: ../../source/ref-changelog.md:770 +#: ../../source/ref-changelog.md:862 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" @@ -19116,7 +19878,7 @@ msgstr "" "initialisé dans `start_simulation` " "([#1177](https://github.com/adap/flower/pull/1177))" -#: ../../source/ref-changelog.md:771 +#: ../../source/ref-changelog.md:863 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" @@ -19125,7 +19887,7 @@ msgstr "" "paramètre de `start_simulation` " "([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:864 #, fuzzy msgid "" "New documentation for [implementing " @@ -19138,7 +19900,7 @@ msgstr "" "strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " "[#1175](https://github.com/adap/flower/pull/1175))" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:865 msgid "" "New mobile-friendly documentation theme " "([#1174](https://github.com/adap/flower/pull/1174))" @@ -19146,7 +19908,7 @@ msgstr "" "Nouveau thème de documentation adapté aux mobiles " "([#1174](https://github.com/adap/flower/pull/1174))" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:866 msgid "" "Limit version range for (optional) `ray` dependency to include only " "compatible releases (`>=1.9.2,<1.12.0`) " @@ -19156,7 +19918,7 @@ msgstr "" "n'inclure que les versions compatibles (`>=1.9.2,<1.12.0`) " "([#1205](https://github.com/adap/flower/pull/1205))" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:870 msgid "" "**Remove deprecated support for Python 3.6** " "([#871](https://github.com/adap/flower/pull/871))" @@ -19164,7 +19926,7 @@ msgstr "" "**Supprime la prise en charge obsolète de Python 3.6** " "([#871](https://github.com/adap/flower/pull/871))" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:871 msgid "" "**Remove deprecated KerasClient** " "([#857](https://github.com/adap/flower/pull/857))" @@ -19172,7 +19934,7 @@ msgstr "" "**Supprimez KerasClient** " "([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:780 +#: ../../source/ref-changelog.md:872 msgid "" "**Remove deprecated no-op extra installs** " "([#973](https://github.com/adap/flower/pull/973))" @@ -19180,7 +19942,7 @@ msgstr "" "**Supprimer les installations supplémentaires no-op dépréciées** " "([#973](https://github.com/adap/flower/pull/973))" -#: ../../source/ref-changelog.md:781 +#: ../../source/ref-changelog.md:873 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" @@ -19188,7 +19950,7 @@ msgstr "" "**Supprimez les champs proto obsolètes de** `FitRes` **et** `EvaluateRes`" " ([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:782 +#: ../../source/ref-changelog.md:874 msgid "" "**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " "([#1107](https://github.com/adap/flower/pull/1107))" @@ -19196,7 +19958,7 @@ msgstr "" "**Supprime la stratégie QffedAvg (remplacée par QFedAvg)** " "([#1107](https://github.com/adap/flower/pull/1107))" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:875 msgid "" "**Remove deprecated DefaultStrategy strategy** " "([#1142](https://github.com/adap/flower/pull/1142))" @@ -19204,7 +19966,7 @@ msgstr "" "**Supprime la stratégie DefaultStrategy qui est obsolète** " "([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:784 +#: ../../source/ref-changelog.md:876 msgid "" "**Remove deprecated support for eval_fn accuracy return value** " "([#1142](https://github.com/adap/flower/pull/1142))" @@ -19212,7 +19974,7 @@ msgstr "" "**Supprimer la prise en charge obsolète de la valeur de retour de la " "précision eval_fn** ([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:877 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" @@ -19221,11 +19983,11 @@ msgstr "" " en tant que ndarrays NumPy** " "([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:787 +#: ../../source/ref-changelog.md:879 msgid "v0.18.0 (2022-02-28)" msgstr "v0.18.0 (2022-02-28)" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:883 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " "Google Colab** ([#866](https://github.com/adap/flower/pull/866), " @@ -19240,7 +20002,7 @@ msgstr "" "[#833](https://github.com/adap/flower/pull/833), " "[#1036](https://github.com/adap/flower/pull/1036))" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:885 msgid "" "Simulations (using the Virtual Client Engine through `start_simulation`) " "now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " @@ -19252,7 +20014,7 @@ msgstr "" "Notebooks Jupyter (y compris Google Colab) après avoir installé Flower " "avec l'option `simulation` (`pip install flwr[simulation]`)." -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:887 msgid "" "**New Jupyter Notebook code example** " "([#833](https://github.com/adap/flower/pull/833))" @@ -19260,7 +20022,7 @@ msgstr "" "**Nouvel exemple de code Jupyter Notebook** " "([#833](https://github.com/adap/flower/pull/833))" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:889 msgid "" "A new code example (`quickstart_simulation`) demonstrates Flower " "simulations using the Virtual Client Engine through Jupyter Notebook " @@ -19270,7 +20032,7 @@ msgstr "" "simulations de Flower en utilisant le moteur de client virtuel via " "Jupyter Notebook (y compris Google Colab)." -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:891 msgid "" "**Client properties (feature preview)** " "([#795](https://github.com/adap/flower/pull/795))" @@ -19278,7 +20040,7 @@ msgstr "" "**Propriétés du client (aperçu des fonctionnalités)** " "([#795](https://github.com/adap/flower/pull/795))" -#: ../../source/ref-changelog.md:801 +#: ../../source/ref-changelog.md:893 msgid "" "Clients can implement a new method `get_properties` to enable server-side" " strategies to query client properties." @@ -19287,7 +20049,7 @@ msgstr "" "pour permettre aux stratégies côté serveur d'interroger les propriétés du" " client." -#: ../../source/ref-changelog.md:803 +#: ../../source/ref-changelog.md:895 msgid "" "**Experimental Android support with TFLite** " "([#865](https://github.com/adap/flower/pull/865))" @@ -19295,7 +20057,7 @@ msgstr "" "**Support expérimental d'Android avec TFLite** " "([#865](https://github.com/adap/flower/pull/865))" -#: ../../source/ref-changelog.md:805 +#: ../../source/ref-changelog.md:897 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " @@ -19307,7 +20069,7 @@ msgstr "" "intégrer des plates-formes client arbitraires et avec cette version, " "l'utilisation de Flower sur Android est devenue beaucoup plus facile." -#: ../../source/ref-changelog.md:807 +#: ../../source/ref-changelog.md:899 msgid "" "The example uses TFLite on the client side, along with a new " "`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " @@ -19321,7 +20083,7 @@ msgstr "" "part entière et une implémentation unifiée de `FedAvg` intégrant la " "nouvelle fonctionnalité de `FedAvgAndroid`." -#: ../../source/ref-changelog.md:809 +#: ../../source/ref-changelog.md:901 msgid "" "**Make gRPC keepalive time user-configurable and decrease default " "keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" @@ -19330,7 +20092,7 @@ msgstr "" "diminuer le temps de garde par défaut** " "([#1069](https://github.com/adap/flower/pull/1069))" -#: ../../source/ref-changelog.md:811 +#: ../../source/ref-changelog.md:903 msgid "" "The default gRPC keepalive time has been reduced to increase the " "compatibility of Flower with more cloud environments (for example, " @@ -19343,7 +20105,7 @@ msgstr "" "de keepalive pour personnaliser la pile gRPC en fonction d'exigences " "spécifiques." -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:905 msgid "" "**New differential privacy example using Opacus and PyTorch** " "([#805](https://github.com/adap/flower/pull/805))" @@ -19351,7 +20113,7 @@ msgstr "" "**Nouvel exemple de confidentialité différentielle utilisant Opacus et " "PyTorch** ([#805](https://github.com/adap/flower/pull/805))" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:907 msgid "" "A new code example (`opacus`) demonstrates differentially-private " "federated learning with Opacus, PyTorch, and Flower." @@ -19359,7 +20121,7 @@ msgstr "" "Un nouvel exemple de code (`opacus`) démontre l'apprentissage fédéré " "différentiellement privé avec Opacus, PyTorch et Flower." -#: ../../source/ref-changelog.md:817 +#: ../../source/ref-changelog.md:909 msgid "" "**New Hugging Face Transformers code example** " "([#863](https://github.com/adap/flower/pull/863))" @@ -19367,7 +20129,7 @@ msgstr "" "**Nouvel exemple de code pour les Transformers à visage embrassant** " "([#863](https://github.com/adap/flower/pull/863))" -#: ../../source/ref-changelog.md:819 +#: ../../source/ref-changelog.md:911 msgid "" "A new code example (`quickstart_huggingface`) demonstrates usage of " "Hugging Face Transformers with Flower." @@ -19375,7 +20137,7 @@ msgstr "" "Un nouvel exemple de code (`quickstart_huggingface`) démontre " "l'utilisation des transformateurs Hugging Face avec Flower." -#: ../../source/ref-changelog.md:821 +#: ../../source/ref-changelog.md:913 msgid "" "**New MLCube code example** " "([#779](https://github.com/adap/flower/pull/779), " @@ -19389,7 +20151,7 @@ msgstr "" "[#1065](https://github.com/adap/flower/pull/1065), " "[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-changelog.md:823 +#: ../../source/ref-changelog.md:915 msgid "" "A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " "with Flower." @@ -19397,7 +20159,7 @@ msgstr "" "Un nouvel exemple de code (`quickstart_mlcube`) démontre l'utilisation de" " MLCube avec Flower." -#: ../../source/ref-changelog.md:825 +#: ../../source/ref-changelog.md:917 msgid "" "**SSL-enabled server and client** " "([#842](https://github.com/adap/flower/pull/842), " @@ -19414,7 +20176,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:827 +#: ../../source/ref-changelog.md:919 msgid "" "SSL enables secure encrypted connections between clients and servers. " "This release open-sources the Flower secure gRPC implementation to make " @@ -19425,7 +20187,7 @@ msgstr "" "l'implémentation gRPC sécurisée de Flower afin de rendre les canaux de " "communication cryptés accessibles à tous les utilisateurs de Flower." -#: ../../source/ref-changelog.md:829 +#: ../../source/ref-changelog.md:921 msgid "" "**Updated** `FedAdam` **and** `FedYogi` **strategies** " "([#885](https://github.com/adap/flower/pull/885), " @@ -19435,7 +20197,7 @@ msgstr "" "([#885](https://github.com/adap/flower/pull/885), " "[#895](https://github.com/adap/flower/pull/895))" -#: ../../source/ref-changelog.md:831 +#: ../../source/ref-changelog.md:923 msgid "" "`FedAdam` and `FedAdam` match the latest version of the Adaptive " "Federated Optimization paper." @@ -19443,7 +20205,7 @@ msgstr "" "`FedAdam` et `FedAdam` correspondent à la dernière version de l'article " "sur l'optimisation fédérée adaptative." -#: ../../source/ref-changelog.md:833 +#: ../../source/ref-changelog.md:925 msgid "" "**Initialize** `start_simulation` **with a list of client IDs** " "([#860](https://github.com/adap/flower/pull/860))" @@ -19451,7 +20213,7 @@ msgstr "" "**Initialise** `start_simulation` **avec une liste d'ID de clients** " "([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-changelog.md:835 +#: ../../source/ref-changelog.md:927 msgid "" "`start_simulation` can now be called with a list of client IDs " "(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " @@ -19465,7 +20227,7 @@ msgstr "" "être initialisé, ce qui peut faciliter le chargement de partitions de " "données qui ne sont pas accessibles par des identifiants `int`." -#: ../../source/ref-changelog.md:839 +#: ../../source/ref-changelog.md:931 msgid "" "Update `num_examples` calculation in PyTorch code examples in " "([#909](https://github.com/adap/flower/pull/909))" @@ -19473,7 +20235,7 @@ msgstr "" "Mettre à jour le calcul de `num_examples` dans les exemples de code " "PyTorch dans ([#909](https://github.com/adap/flower/pull/909))" -#: ../../source/ref-changelog.md:840 +#: ../../source/ref-changelog.md:932 msgid "" "Expose Flower version through `flwr.__version__` " "([#952](https://github.com/adap/flower/pull/952))" @@ -19481,7 +20243,7 @@ msgstr "" "Exposer la version de Flower à travers `flwr.__version__` " "([#952](https://github.com/adap/flower/pull/952))" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:933 msgid "" "`start_server` in `app.py` now returns a `History` object containing " "metrics from training ([#974](https://github.com/adap/flower/pull/974))" @@ -19490,7 +20252,7 @@ msgstr "" "contenant les métriques de l'entraînement " "([#974](https://github.com/adap/flower/pull/974))" -#: ../../source/ref-changelog.md:842 +#: ../../source/ref-changelog.md:934 msgid "" "Make `max_workers` (used by `ThreadPoolExecutor`) configurable " "([#978](https://github.com/adap/flower/pull/978))" @@ -19498,7 +20260,7 @@ msgstr "" "Rendre `max_workers` (utilisé par `ThreadPoolExecutor`) configurable " "([#978](https://github.com/adap/flower/pull/978))" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:935 msgid "" "Increase sleep time after server start to three seconds in all code " "examples ([#1086](https://github.com/adap/flower/pull/1086))" @@ -19507,7 +20269,7 @@ msgstr "" "secondes dans tous les exemples de code " "([#1086](https://github.com/adap/flower/pull/1086))" -#: ../../source/ref-changelog.md:844 +#: ../../source/ref-changelog.md:936 msgid "" "Added a new FAQ section to the documentation " "([#948](https://github.com/adap/flower/pull/948))" @@ -19515,7 +20277,7 @@ msgstr "" "Ajout d'une nouvelle section FAQ à la documentation " "([#948](https://github.com/adap/flower/pull/948))" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:937 msgid "" "And many more under-the-hood changes, library updates, documentation " "changes, and tooling improvements!" @@ -19524,7 +20286,7 @@ msgstr "" "bibliothèque, des modifications de la documentation et des améliorations " "de l'outillage !" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:941 msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" @@ -19532,7 +20294,7 @@ msgstr "" "**Supprimé** `flwr_example` **et** `flwr_experimental` **de la version " "release build** ([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:943 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " @@ -19546,11 +20308,11 @@ msgstr "" "tensorflow`, `http-logger`, `ops`) sont maintenant no-op et seront " "supprimés dans une prochaine version." -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:945 msgid "v0.17.0 (2021-09-24)" msgstr "v0.17.0 (2021-09-24)" -#: ../../source/ref-changelog.md:857 +#: ../../source/ref-changelog.md:949 msgid "" "**Experimental virtual client engine** " "([#781](https://github.com/adap/flower/pull/781) " @@ -19562,7 +20324,7 @@ msgstr "" "[#790](https://github.com/adap/flower/pull/790) " "[#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:951 msgid "" "One of Flower's goals is to enable research at scale. This release " "enables a first (experimental) peek at a major new feature, codenamed the" @@ -19580,7 +20342,7 @@ msgstr "" "fonctionnalité est de regarder les deux nouveaux exemples de code appelés" " `quickstart_simulation` et `simulation_pytorch`." -#: ../../source/ref-changelog.md:861 +#: ../../source/ref-changelog.md:953 msgid "" "The feature is still experimental, so there's no stability guarantee for " "the API. It's also not quite ready for prime time and comes with a few " @@ -19593,7 +20355,7 @@ msgstr "" " les personnes curieuses sont encouragées à l'essayer et à faire part de " "leurs réflexions." -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:955 msgid "" "**New built-in strategies** " "([#828](https://github.com/adap/flower/pull/828) " @@ -19603,7 +20365,7 @@ msgstr "" "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:957 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" @@ -19611,7 +20373,7 @@ msgstr "" "FedYogi - Stratégie d'apprentissage fédéré utilisant Yogi côté serveur. " "Mise en oeuvre basée sur https://arxiv.org/abs/2003.00295" -#: ../../source/ref-changelog.md:866 +#: ../../source/ref-changelog.md:958 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" @@ -19619,7 +20381,7 @@ msgstr "" "FedAdam - Stratégie d'apprentissage fédéré utilisant Adam côté serveur. " "Mise en œuvre basée sur https://arxiv.org/abs/2003.00295" -#: ../../source/ref-changelog.md:868 +#: ../../source/ref-changelog.md:960 msgid "" "**New PyTorch Lightning code example** " "([#617](https://github.com/adap/flower/pull/617))" @@ -19627,7 +20389,7 @@ msgstr "" "**Nouvel exemple de code PyTorch Lightning** " "([#617](https://github.com/adap/flower/pull/617))" -#: ../../source/ref-changelog.md:870 +#: ../../source/ref-changelog.md:962 msgid "" "**New Variational Auto-Encoder code example** " "([#752](https://github.com/adap/flower/pull/752))" @@ -19635,7 +20397,7 @@ msgstr "" "**Nouvel exemple de code d'autocodage variationnel** " "([#752](https://github.com/adap/flower/pull/752))" -#: ../../source/ref-changelog.md:872 +#: ../../source/ref-changelog.md:964 msgid "" "**New scikit-learn code example** " "([#748](https://github.com/adap/flower/pull/748))" @@ -19643,7 +20405,7 @@ msgstr "" "**Nouvel exemple de code scikit-learn** " "([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:874 +#: ../../source/ref-changelog.md:966 msgid "" "**New experimental TensorBoard strategy** " "([#789](https://github.com/adap/flower/pull/789))" @@ -19651,7 +20413,7 @@ msgstr "" "**Nouvelle stratégie expérimentale TensorBoard** " "([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:878 +#: ../../source/ref-changelog.md:970 msgid "" "Improved advanced TensorFlow code example " "([#769](https://github.com/adap/flower/pull/769))" @@ -19659,7 +20421,7 @@ msgstr "" "Amélioration de l'exemple de code TensorFlow avancé " "([#769](https://github.com/adap/flower/pull/769))" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:971 msgid "" "Warning when `min_available_clients` is misconfigured " "([#830](https://github.com/adap/flower/pull/830))" @@ -19667,7 +20429,7 @@ msgstr "" "Avertissement lorsque `min_available_clients` est mal configuré " "([#830](https://github.com/adap/flower/pull/830))" -#: ../../source/ref-changelog.md:880 +#: ../../source/ref-changelog.md:972 msgid "" "Improved gRPC server docs " "([#841](https://github.com/adap/flower/pull/841))" @@ -19675,7 +20437,7 @@ msgstr "" "Amélioration de la documentation sur le serveur gRPC " "([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:973 msgid "" "Improved error message in `NumPyClient` " "([#851](https://github.com/adap/flower/pull/851))" @@ -19683,7 +20445,7 @@ msgstr "" "Amélioration du message d'erreur dans `NumPyClient` " "([#851](https://github.com/adap/flower/pull/851))" -#: ../../source/ref-changelog.md:882 +#: ../../source/ref-changelog.md:974 msgid "" "Improved PyTorch quickstart code example " "([#852](https://github.com/adap/flower/pull/852))" @@ -19691,7 +20453,7 @@ msgstr "" "Exemple de code de démarrage rapide PyTorch amélioré " "([#852](https://github.com/adap/flower/pull/852))" -#: ../../source/ref-changelog.md:886 +#: ../../source/ref-changelog.md:978 msgid "" "**Disabled final distributed evaluation** " "([#800](https://github.com/adap/flower/pull/800))" @@ -19699,7 +20461,7 @@ msgstr "" "**Désactivé l'évaluation finale distribuée** " "([#800](https://github.com/adap/flower/pull/800))" -#: ../../source/ref-changelog.md:888 +#: ../../source/ref-changelog.md:980 msgid "" "Prior behaviour was to perform a final round of distributed evaluation on" " all connected clients, which is often not required (e.g., when using " @@ -19712,7 +20474,7 @@ msgstr "" "l'évaluation côté serveur). Le comportement précédent peut être activé en" " passant `force_final_distributed_eval=True` à `start_server`." -#: ../../source/ref-changelog.md:890 +#: ../../source/ref-changelog.md:982 msgid "" "**Renamed q-FedAvg strategy** " "([#802](https://github.com/adap/flower/pull/802))" @@ -19720,7 +20482,7 @@ msgstr "" "**Renommé stratégie q-FedAvg** " "([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-changelog.md:892 +#: ../../source/ref-changelog.md:984 msgid "" "The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " "the notation given in the original paper (q-FFL is the optimization " @@ -19735,7 +20497,7 @@ msgstr "" "des raisons de compatibilité (elle sera supprimée dans une prochaine " "version)." -#: ../../source/ref-changelog.md:894 +#: ../../source/ref-changelog.md:986 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " "`simulation_pytorch_legacy` " @@ -19745,7 +20507,7 @@ msgstr "" "`simulation_pytorch_legacy` " "([#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:896 +#: ../../source/ref-changelog.md:988 msgid "" "This example has been replaced by a new example. The new example is based" " on the experimental virtual client engine, which will become the new " @@ -19760,11 +20522,11 @@ msgstr "" "conservé à des fins de référence, mais il pourrait être supprimé à " "l'avenir." -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:990 msgid "v0.16.0 (2021-05-11)" msgstr "v0.16.0 (2021-05-11)" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:994 msgid "" "**New built-in strategies** " "([#549](https://github.com/adap/flower/pull/549))" @@ -19772,11 +20534,11 @@ msgstr "" "**Nouvelles stratégies intégrées** " "([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:904 +#: ../../source/ref-changelog.md:996 msgid "(abstract) FedOpt" msgstr "(résumé) FedOpt" -#: ../../source/ref-changelog.md:907 +#: ../../source/ref-changelog.md:999 msgid "" "**Custom metrics for server and strategies** " "([#717](https://github.com/adap/flower/pull/717))" @@ -19784,7 +20546,7 @@ msgstr "" "**Métriques personnalisées pour le serveur et les stratégies** " "([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/ref-changelog.md:909 +#: ../../source/ref-changelog.md:1001 msgid "" "The Flower server is now fully task-agnostic, all remaining instances of " "task-specific metrics (such as `accuracy`) have been replaced by custom " @@ -19800,7 +20562,7 @@ msgstr "" " À partir de cette version, les métriques personnalisées remplacent les " "métriques spécifiques à une tâche sur le serveur." -#: ../../source/ref-changelog.md:911 +#: ../../source/ref-changelog.md:1003 #, fuzzy msgid "" "Custom metric dictionaries are now used in two user-facing APIs: they are" @@ -19818,7 +20580,7 @@ msgstr "" "stratégies peuvent même renvoyer des dictionnaires de métriques " "*agrégées* pour que le serveur puisse en garder la trace." -#: ../../source/ref-changelog.md:913 +#: ../../source/ref-changelog.md:1005 #, fuzzy msgid "" "Strategy implementations should migrate their `aggregate_fit` and " @@ -19832,7 +20594,7 @@ msgstr "" "d'évaluation côté serveur doivent migrer de `return loss, accuracy` à " "`return loss, {\"accuracy\" : accuracy}`." -#: ../../source/ref-changelog.md:915 +#: ../../source/ref-changelog.md:1007 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." @@ -19841,7 +20603,7 @@ msgstr "" "pris en charge), la compatibilité sera supprimée dans une prochaine " "version." -#: ../../source/ref-changelog.md:917 +#: ../../source/ref-changelog.md:1009 msgid "" "**Migration warnings for deprecated functionality** " "([#690](https://github.com/adap/flower/pull/690))" @@ -19849,7 +20611,7 @@ msgstr "" "**Avertissements de migration pour les fonctionnalités obsolètes** " "([#690](https://github.com/adap/flower/pull/690))" -#: ../../source/ref-changelog.md:919 +#: ../../source/ref-changelog.md:1011 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " "maintaining compatibility with legacy APIs. This release introduces " @@ -19865,7 +20627,7 @@ msgstr "" "vers des API plus récentes, facilitant ainsi la transition d'une version " "à l'autre." -#: ../../source/ref-changelog.md:921 +#: ../../source/ref-changelog.md:1013 msgid "" "Improved docs and docstrings " "([#691](https://github.com/adap/flower/pull/691) " @@ -19877,11 +20639,11 @@ msgstr "" "[#692](https://github.com/adap/flower/pull/692) " "[#713](https://github.com/adap/flower/pull/713))" -#: ../../source/ref-changelog.md:923 +#: ../../source/ref-changelog.md:1015 msgid "MXNet example and documentation" msgstr "Exemple et documentation MXNet" -#: ../../source/ref-changelog.md:925 +#: ../../source/ref-changelog.md:1017 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " "([#696](https://github.com/adap/flower/pull/696) " @@ -19893,7 +20655,7 @@ msgstr "" "[#702](https://github.com/adap/flower/pull/702) " "[#705](https://github.com/adap/flower/pull/705))" -#: ../../source/ref-changelog.md:929 +#: ../../source/ref-changelog.md:1021 msgid "" "**Serialization-agnostic server** " "([#721](https://github.com/adap/flower/pull/721))" @@ -19901,7 +20663,7 @@ msgstr "" "**Serveur agnostique de sérialisation** " "([#721](https://github.com/adap/flower/pull/721))" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:1023 msgid "" "The Flower server is now fully serialization-agnostic. Prior usage of " "class `Weights` (which represents parameters as deserialized NumPy " @@ -19921,7 +20683,7 @@ msgstr "" "d'octets doivent être interprétés (par exemple, pour la " "sérialisation/désérialisation)." -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:1025 msgid "" "Built-in strategies implement this approach by handling serialization and" " deserialization to/from `Weights` internally. Custom/3rd-party Strategy " @@ -19938,7 +20700,7 @@ msgstr "" "[#721](https://github.com/adap/flower/pull/721) pour voir comment les " "stratégies peuvent facilement migrer vers le nouveau format." -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:1027 msgid "" "Deprecated `flwr.server.Server.evaluate`, use " "`flwr.server.Server.evaluate_round` instead " @@ -19948,11 +20710,11 @@ msgstr "" "`flwr.server.Server.evaluate_round` à la place " "([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:1029 msgid "v0.15.0 (2021-03-12)" msgstr "v0.15.0 (2021-03-12)" -#: ../../source/ref-changelog.md:941 +#: ../../source/ref-changelog.md:1033 msgid "" "**Server-side parameter initialization** " "([#658](https://github.com/adap/flower/pull/658))" @@ -19960,7 +20722,7 @@ msgstr "" "**Initialisation des paramètres côté serveur** " "([#658](https://github.com/adap/flower/pull/658))" -#: ../../source/ref-changelog.md:943 +#: ../../source/ref-changelog.md:1035 msgid "" "Model parameters can now be initialized on the server-side. Server-side " "parameter initialization works via a new `Strategy` method called " @@ -19970,7 +20732,7 @@ msgstr "" "serveur. L'initialisation des paramètres côté serveur fonctionne via une " "nouvelle méthode `Strategy` appelée `initialize_parameters`." -#: ../../source/ref-changelog.md:945 +#: ../../source/ref-changelog.md:1037 msgid "" "Built-in strategies support a new constructor argument called " "`initial_parameters` to set the initial parameters. Built-in strategies " @@ -19982,7 +20744,7 @@ msgstr "" "initiaux. Les stratégies intégrées fourniront ces paramètres initiaux au " "serveur au démarrage et les supprimeront ensuite pour libérer la mémoire." -#: ../../source/ref-changelog.md:964 +#: ../../source/ref-changelog.md:1056 msgid "" "If no initial parameters are provided to the strategy, the server will " "continue to use the current behaviour (namely, it will ask one of the " @@ -19994,11 +20756,7 @@ msgstr "" "l'un des clients connectés ses paramètres et les utilisera comme " "paramètres globaux initiaux)." -#: ../../source/ref-changelog.md:966 -msgid "Deprecations" -msgstr "Dépréciations" - -#: ../../source/ref-changelog.md:968 +#: ../../source/ref-changelog.md:1060 msgid "" "Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " "`flwr.server.strategy.FedAvg`, which is equivalent)" @@ -20006,11 +20764,11 @@ msgstr "" "Déclasser `flwr.server.strategy.DefaultStrategy` (migrer vers " "`flwr.server.strategy.FedAvg`, qui est équivalent)" -#: ../../source/ref-changelog.md:970 +#: ../../source/ref-changelog.md:1062 msgid "v0.14.0 (2021-02-18)" msgstr "v0.14.0 (2021-02-18)" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:1066 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " "([#610](https://github.com/adap/flower/pull/610) " @@ -20022,7 +20780,7 @@ msgstr "" "[#572](https://github.com/adap/flower/pull/572) " "[#633](https://github.com/adap/flower/pull/633))" -#: ../../source/ref-changelog.md:976 +#: ../../source/ref-changelog.md:1068 msgid "" "Clients can now return an additional dictionary mapping `str` keys to " "values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " @@ -20035,7 +20793,7 @@ msgstr "" "valeurs presque arbitraires de `fit`/`evaluate` et les utiliser du côté " "du serveur !" -#: ../../source/ref-changelog.md:978 +#: ../../source/ref-changelog.md:1070 msgid "" "This improvement also allowed for more consistent return types between " "`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " @@ -20048,7 +20806,7 @@ msgstr "" "d'exemples, et un dictionnaire contenant des valeurs arbitraires " "spécifiques au problème comme la précision." -#: ../../source/ref-changelog.md:980 +#: ../../source/ref-changelog.md:1072 msgid "" "In case you wondered: this feature is compatible with existing projects, " "the additional dictionary return value is optional. New code should " @@ -20065,7 +20823,7 @@ msgstr "" "Scalar]`, `evaluate` : `float, int, Dict[str, Scalar]`). Voir l'exemple " "ci-dessous pour plus de détails." -#: ../../source/ref-changelog.md:982 +#: ../../source/ref-changelog.md:1074 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" @@ -20073,7 +20831,7 @@ msgstr "" "*Exemple de code:* note les valeurs de retour du dictionnaire " "supplémentaires dans `FlwrClient.fit` et `FlwrClient.evaluate` :" -#: ../../source/ref-changelog.md:997 +#: ../../source/ref-changelog.md:1089 msgid "" "**Generalized** `config` **argument in** `Client.fit` **and** " "`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" @@ -20081,7 +20839,7 @@ msgstr "" "**Généralisé** `config` **argument dans** `Client.fit` **et** " "`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" -#: ../../source/ref-changelog.md:999 +#: ../../source/ref-changelog.md:1091 msgid "" "The `config` argument used to be of type `Dict[str, str]`, which means " "that dictionary values were expected to be strings. The new release " @@ -20093,7 +20851,7 @@ msgstr "" "nouvelle version généralise cela pour permettre les valeurs des types " "suivants : `bool`, `bytes`, `float`, `int`, `str`." -#: ../../source/ref-changelog.md:1001 +#: ../../source/ref-changelog.md:1093 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " "using the `config` dictionary. Yay, no more `str(epochs)` on the server-" @@ -20104,7 +20862,7 @@ msgstr "" "Yay, plus de `str(epochs)` du côté serveur et `int(config[\"epochs\"])` " "du côté client !" -#: ../../source/ref-changelog.md:1003 +#: ../../source/ref-changelog.md:1095 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" @@ -20112,11 +20870,11 @@ msgstr "" "*Exemple de code:* Notez que le dictionnaire `config` contient maintenant" " des valeurs autres que `str` dans `Client.fit` et `Client.evaluate` :" -#: ../../source/ref-changelog.md:1020 +#: ../../source/ref-changelog.md:1112 msgid "v0.13.0 (2021-01-08)" msgstr "v0.13.0 (2021-01-08)" -#: ../../source/ref-changelog.md:1024 +#: ../../source/ref-changelog.md:1116 msgid "" "New example: PyTorch From Centralized To Federated " "([#549](https://github.com/adap/flower/pull/549))" @@ -20124,21 +20882,21 @@ msgstr "" "Nouvel exemple : PyTorch de centralisé à fédéré " "([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:1025 +#: ../../source/ref-changelog.md:1117 msgid "Improved documentation" msgstr "Amélioration de la documentation" -#: ../../source/ref-changelog.md:1026 +#: ../../source/ref-changelog.md:1118 msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" "Nouveau thème de documentation " "([#551](https://github.com/adap/flower/pull/551))" -#: ../../source/ref-changelog.md:1027 +#: ../../source/ref-changelog.md:1119 msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "Nouvelle référence API ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:1028 +#: ../../source/ref-changelog.md:1120 msgid "" "Updated examples documentation " "([#549](https://github.com/adap/flower/pull/549))" @@ -20146,7 +20904,7 @@ msgstr "" "Mise à jour de la documentation des exemples " "([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:1029 +#: ../../source/ref-changelog.md:1121 msgid "" "Removed obsolete documentation " "([#548](https://github.com/adap/flower/pull/548))" @@ -20154,11 +20912,11 @@ msgstr "" "Suppression de la documentation obsolète " "([#548](https://github.com/adap/flower/pull/548))" -#: ../../source/ref-changelog.md:1031 +#: ../../source/ref-changelog.md:1123 msgid "Bugfix:" msgstr "Correction de bogues :" -#: ../../source/ref-changelog.md:1033 +#: ../../source/ref-changelog.md:1125 msgid "" "`Server.fit` does not disconnect clients when finished, disconnecting the" " clients is now handled in `flwr.server.start_server` " @@ -20171,15 +20929,15 @@ msgstr "" "([#553](https://github.com/adap/flower/pull/553) " "[#540](https://github.com/adap/flower/issues/540))." -#: ../../source/ref-changelog.md:1035 +#: ../../source/ref-changelog.md:1127 msgid "v0.12.0 (2020-12-07)" msgstr "v0.12.0 (2020-12-07)" -#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +#: ../../source/ref-changelog.md:1129 ../../source/ref-changelog.md:1145 msgid "Important changes:" msgstr "Changements importants :" -#: ../../source/ref-changelog.md:1039 +#: ../../source/ref-changelog.md:1131 msgid "" "Added an example for embedded devices " "([#507](https://github.com/adap/flower/pull/507))" @@ -20187,7 +20945,7 @@ msgstr "" "Ajout d'un exemple pour les périphériques embarqués " "([#507](https://github.com/adap/flower/pull/507))" -#: ../../source/ref-changelog.md:1040 +#: ../../source/ref-changelog.md:1132 msgid "" "Added a new NumPyClient (in addition to the existing KerasClient) " "([#504](https://github.com/adap/flower/pull/504) " @@ -20197,7 +20955,7 @@ msgstr "" "([#504](https://github.com/adap/flower/pull/504) " "[#508](https://github.com/adap/flower/pull/508))" -#: ../../source/ref-changelog.md:1041 +#: ../../source/ref-changelog.md:1133 msgid "" "Deprecated `flwr_example` package and started to migrate examples into " "the top-level `examples` directory " @@ -20209,15 +20967,15 @@ msgstr "" "([#494](https://github.com/adap/flower/pull/494) " "[#512](https://github.com/adap/flower/pull/512))" -#: ../../source/ref-changelog.md:1043 +#: ../../source/ref-changelog.md:1135 msgid "v0.11.0 (2020-11-30)" msgstr "v0.11.0 (2020-11-30)" -#: ../../source/ref-changelog.md:1045 +#: ../../source/ref-changelog.md:1137 msgid "Incompatible changes:" msgstr "Changements incompatibles :" -#: ../../source/ref-changelog.md:1047 +#: ../../source/ref-changelog.md:1139 msgid "" "Renamed strategy methods " "([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " @@ -20234,23 +20992,23 @@ msgstr "" "quatre méthodes de Stratégie. Pour migrer, renommez les méthodes de " "`Strategy` suivantes en conséquence :" -#: ../../source/ref-changelog.md:1048 +#: ../../source/ref-changelog.md:1140 msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "`on_configure_evaluate` => `configure_evaluate`" -#: ../../source/ref-changelog.md:1049 +#: ../../source/ref-changelog.md:1141 msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "`on_aggregate_evaluate` => `aggregate_evaluate`" -#: ../../source/ref-changelog.md:1050 +#: ../../source/ref-changelog.md:1142 msgid "`on_configure_fit` => `configure_fit`" msgstr "`on_configure_fit` => `configure_fit`" -#: ../../source/ref-changelog.md:1051 +#: ../../source/ref-changelog.md:1143 msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "`on_aggregate_fit` => `aggregate_fit`" -#: ../../source/ref-changelog.md:1055 +#: ../../source/ref-changelog.md:1147 msgid "" "Deprecated `DefaultStrategy` " "([#479](https://github.com/adap/flower/pull/479)). To migrate use " @@ -20260,7 +21018,7 @@ msgstr "" "([#479](https://github.com/adap/flower/pull/479)). Pour migrer, utilisez " "`FedAvg` à la place." -#: ../../source/ref-changelog.md:1056 +#: ../../source/ref-changelog.md:1148 msgid "" "Simplified examples and baselines " "([#484](https://github.com/adap/flower/pull/484))." @@ -20268,7 +21026,7 @@ msgstr "" "Exemples simplifiés et lignes de base " "([#484](https://github.com/adap/flower/pull/484))." -#: ../../source/ref-changelog.md:1057 +#: ../../source/ref-changelog.md:1149 msgid "" "Removed presently unused `on_conclude_round` from strategy interface " "([#483](https://github.com/adap/flower/pull/483))." @@ -20276,7 +21034,7 @@ msgstr "" "Suppression de `on_conclude_round` actuellement inutilisé de l'interface " "de stratégie ([#483](https://github.com/adap/flower/pull/483))." -#: ../../source/ref-changelog.md:1058 +#: ../../source/ref-changelog.md:1150 msgid "" "Set minimal Python version to 3.6.1 instead of 3.6.9 " "([#471](https://github.com/adap/flower/pull/471))." @@ -20284,7 +21042,7 @@ msgstr "" "Fixe la version minimale de Python à 3.6.1 au lieu de 3.6.9 " "([#471](https://github.com/adap/flower/pull/471))." -#: ../../source/ref-changelog.md:1059 +#: ../../source/ref-changelog.md:1151 msgid "" "Improved `Strategy` docstrings " "([#470](https://github.com/adap/flower/pull/470))." @@ -24495,7 +25253,7 @@ msgstr "" "chose d'autre, comme la régression linéaire classique." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgid "|93b02017c78049bbbd5ae456dcb2c91b|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 @@ -24514,7 +25272,7 @@ msgstr "" " Go." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgid "|01471150fd5144c080a176b43e92a3ff|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 @@ -24545,7 +25303,7 @@ msgstr "" "chanson." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|2bc8e069228d4873804061ff4a95048c|" +msgid "|9bc21c7dbd17444a8f070c60786e3484|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 @@ -24566,7 +25324,7 @@ msgstr "" " données pour la même tâche." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +msgid "|3047bbce54b34099ae559963d0420d79|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 @@ -24587,7 +25345,7 @@ msgstr "" "cloud." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|d5f962c3f4ec48529efda980868c14b0|" +msgid "|e9f8ce948593444fb838d2f354c7ec5d|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 @@ -24608,7 +25366,7 @@ msgstr "" "appuyés." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|a5eccea18d4c43a68b54b65043cabef8|" +msgid "|c24c1478b30e4f74839208628a842d1e|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 @@ -24633,7 +25391,7 @@ msgstr "" " sur un serveur centralisé." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgid "|1b3613d7a58847b59e1d3180802dbc09|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 @@ -24652,7 +25410,7 @@ msgstr "" "suffisantes pour former un bon modèle." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|241fc906441a4f038c625a19d30d01b2|" +msgid "|9980b5213db547d0b8024a50992b9e3f|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 @@ -24874,7 +25632,7 @@ msgstr "" "partir d'un point de contrôle précédemment sauvegardé." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|0aa5aa05810b44b6a835cecce28f3137|" +msgid "|c7afb4c92d154bfaa5e8cb9a150e17f1|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 @@ -24909,7 +25667,7 @@ msgstr "" "rendements décroissants." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +msgid "|032eb6fed6924ac387b9f13854919196|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 @@ -24942,7 +25700,7 @@ msgstr "" "données locales, ou même de quelques étapes (mini-batchs)." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +msgid "|fbf225add7fd4df5a9bf25a95597d954|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 @@ -24973,7 +25731,7 @@ msgstr "" " l'entraînement local." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgid "|7efbe3d29d8349b89594e8947e910525|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 @@ -25032,7 +25790,7 @@ msgstr "" "times as much as each of the 100 examples." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|72939caf6e294b0986fee6dde96614d7|" +msgid "|329fb3c04c744eda83bb51fa444c2266|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 @@ -25175,7 +25933,7 @@ msgstr "" "quel cadre de ML et n'importe quel langage de programmation." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +msgid "|c00bf2750bc24d229737a0fe1395f0fc|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 @@ -31213,3 +31971,414 @@ msgstr "" #~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" +#~ msgid "" +#~ "Flower provides pre-made docker images" +#~ " on `Docker Hub `_" +#~ " that include all necessary dependencies" +#~ " for running the SuperLink. You can" +#~ " also build your own custom docker" +#~ " images from scratch with a different" +#~ " version of Python or Ubuntu if " +#~ "that is what you need. In this " +#~ "guide, we will explain what images " +#~ "exist and how to build them " +#~ "locally." +#~ msgstr "" + +#~ msgid "" +#~ "Currently, Flower provides two images, a" +#~ " ``base`` image and a ``superlink`` " +#~ "image. The base image, as the name" +#~ " suggests, contains basic dependencies that" +#~ " the SuperLink needs. This includes " +#~ "system dependencies, Python and Python " +#~ "tools. The SuperLink image is based " +#~ "on the base image, but it " +#~ "additionally installs the SuperLink using " +#~ "``pip``." +#~ msgstr "" + +#~ msgid "" +#~ "Both, base and SuperLink image are " +#~ "configured via build arguments. Through " +#~ "build arguments, we can make our " +#~ "build more flexible. For example, in " +#~ "the base image, we can specify the" +#~ " version of Python to install using" +#~ " the ``PYTHON_VERSION`` build argument. " +#~ "Some of the build arguments have " +#~ "default values, others must be specified" +#~ " when building the image. All " +#~ "available build arguments for each image" +#~ " are listed in one of the " +#~ "tables below." +#~ msgstr "" + +#~ msgid "``3.11``" +#~ msgstr "1.0.0rc1" + +#~ msgid "``UBUNTU_VERSION``" +#~ msgstr "" + +#~ msgid "Version of the official Ubuntu Docker image." +#~ msgstr "" + +#~ msgid "Defaults to ``22.04``." +#~ msgstr "" + +#~ msgid "" +#~ "The following example creates a base " +#~ "image with Python 3.11.0, pip 23.0.1 " +#~ "and setuptools 69.0.2:" +#~ msgstr "" + +#~ msgid "Building the SuperLink image" +#~ msgstr "Démarrer le serveur" + +#~ msgid "Defaults to ``flwr/base``." +#~ msgstr "" + +#~ msgid "The Python version of the base image." +#~ msgstr "Évaluer la réponse d'un client." + +#~ msgid "Defaults to ``py3.11``." +#~ msgstr "" + +#~ msgid "Defaults to ``ubuntu22.04``." +#~ msgstr "" + +#~ msgid "The PyPI package to install." +#~ msgstr "" + +#~ msgid "Defaults to ``flwr``." +#~ msgstr "Flux de travail" + +#~ msgid "" +#~ "The following example creates a " +#~ "SuperLink image with the official Flower" +#~ " base image py3.11-ubuntu22.04 and Flower" +#~ " 1.8.0:" +#~ msgstr "" + +#~ msgid "" +#~ "The name of image is ``flwr_superlink``" +#~ " and the tag ``0.1.0``. Remember that" +#~ " the build arguments as well as " +#~ "the name and tag can be adapted" +#~ " to your needs. These values serve" +#~ " as examples only." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to use your own " +#~ "base image instead of the official " +#~ "Flower base image, all you need to" +#~ " do is set the ``BASE_REPOSITORY``, " +#~ "``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build " +#~ "arguments." +#~ msgstr "" + +#~ msgid "Creating New Messages" +#~ msgstr "Création de nouveaux messages" + +#~ msgid "" +#~ "This is a simple guide for " +#~ "creating a new type of message " +#~ "between the server and clients in " +#~ "Flower." +#~ msgstr "" +#~ "Voici un guide simple pour créer " +#~ "un nouveau type de message entre " +#~ "le serveur et les clients dans " +#~ "Flower." + +#~ msgid "" +#~ "Let's suppose we have the following " +#~ "example functions in :code:`server.py` and " +#~ ":code:`numpy_client.py`..." +#~ msgstr "" +#~ "Supposons que nous ayons les fonctions" +#~ " suivantes dans :code:`server.py` et " +#~ ":code:`numpy_client.py`..." + +#~ msgid "Server's side:" +#~ msgstr "Côté serveur :" + +#~ msgid "Client's side:" +#~ msgstr "Côté client :" + +#~ msgid "" +#~ "Let's now see what we need to " +#~ "implement in order to get this " +#~ "simple function between the server and" +#~ " client to work!" +#~ msgstr "" +#~ "Voyons maintenant ce que nous devons " +#~ "mettre en œuvre pour que cette " +#~ "simple fonction entre le serveur et " +#~ "le client fonctionne !" + +#~ msgid "Message Types for Protocol Buffers" +#~ msgstr "Types de messages pour les tampons de protocole" + +#~ msgid "" +#~ "The first thing we need to do " +#~ "is to define a message type for" +#~ " the RPC system in :code:`transport.proto`." +#~ " Note that we have to do it " +#~ "for both the request and response " +#~ "messages. For more details on the " +#~ "syntax of proto3, please see the " +#~ "`official documentation `_." +#~ msgstr "" +#~ "La première chose à faire est de" +#~ " définir un type de message pour " +#~ "le système RPC dans :code:`transport.proto`." +#~ " Notez que nous devons le faire " +#~ "à la fois pour les messages de " +#~ "demande et de réponse. Pour plus " +#~ "de détails sur la syntaxe de " +#~ "proto3, veuillez consulter la `documentation" +#~ " officielle `_." + +#~ msgid "Within the :code:`ServerMessage` block:" +#~ msgstr "Dans le bloc :code:`ServerMessage` :" + +#~ msgid "Within the ClientMessage block:" +#~ msgstr "Dans le bloc ClientMessage :" + +#~ msgid "" +#~ "Make sure to also add a field " +#~ "of the newly created message type " +#~ "in :code:`oneof msg`." +#~ msgstr "" +#~ "Veille à ajouter également un champ " +#~ "du type de message nouvellement créé " +#~ "dans :code:`oneof msg`." + +#~ msgid "Once that is done, we will compile the file with:" +#~ msgstr "Une fois que c'est fait, nous compilerons le fichier avec :" + +#~ msgid "If it compiles successfully, you should see the following message:" +#~ msgstr "S'il se compile avec succès, tu devrais voir le message suivant :" + +#~ msgid "Serialization and Deserialization Functions" +#~ msgstr "Fonctions de sérialisation et de désérialisation" + +#~ msgid "" +#~ "Our next step is to add functions" +#~ " to serialize and deserialize Python " +#~ "datatypes to or from our defined " +#~ "RPC message types. You should add " +#~ "these functions in :code:`serde.py`." +#~ msgstr "" +#~ "La prochaine étape consiste à ajouter" +#~ " des fonctions pour sérialiser et " +#~ "désérialiser les types de données Python" +#~ " vers ou à partir des types de" +#~ " messages RPC définis. Tu dois " +#~ "ajouter ces fonctions dans :code:`serde.py`." + +#~ msgid "The four functions:" +#~ msgstr "Les quatre fonctions :" + +#~ msgid "Sending the Message from the Server" +#~ msgstr "Envoi du message à partir du serveur" + +#~ msgid "" +#~ "Now write the request function in " +#~ "your Client Proxy class (e.g., " +#~ ":code:`grpc_client_proxy.py`) using the serde " +#~ "functions you just created:" +#~ msgstr "" +#~ "Écris maintenant la fonction de demande" +#~ " dans ta classe Client Proxy (par " +#~ "exemple, :code:`grpc_client_proxy.py`) en utilisant" +#~ " les fonctions serde que tu viens " +#~ "de créer :" + +#~ msgid "Receiving the Message by the Client" +#~ msgstr "Réception du message par le client" + +#~ msgid "" +#~ "Last step! Modify the code in " +#~ ":code:`message_handler.py` to check the field" +#~ " of your message and call the " +#~ ":code:`example_response` function. Remember to " +#~ "use the serde functions!" +#~ msgstr "" +#~ "Dernière étape ! Modifie le code " +#~ "dans :code:`message_handler.py` pour vérifier " +#~ "le champ de ton message et appeler" +#~ " la fonction :code:`example_response`. N'oublie" +#~ " pas d'utiliser les fonctions serde !" + +#~ msgid "Within the handle function:" +#~ msgstr "Dans le cadre de la fonction de poignée :" + +#~ msgid "And add a new function:" +#~ msgstr "Et ajoute une nouvelle fonction :" + +#~ msgid "Hopefully, when you run your program you will get the intended result!" +#~ msgstr "" +#~ "Avec un peu de chance, lorsque tu" +#~ " exécuteras ton programme, tu obtiendras" +#~ " le résultat escompté !" + +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to persist the state" +#~ " of the SuperLink on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``--volume``" +#~ " to mount the user's home directory" +#~ " (``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." +#~ msgstr "" + +#~ msgid "" +#~ "As soon as the SuperLink starts, " +#~ "the file ``state.db`` is created in " +#~ "the user's home directory on your " +#~ "host system. If the file already " +#~ "exists, the SuperLink tries to restore" +#~ " the state from the file. To " +#~ "start the SuperLink with an empty " +#~ "database, simply remove the ``state.db`` " +#~ "file." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``--volume`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the SuperLink to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the SuperLink with the" +#~ " ``--certificates`` flag." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9092``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Fleet" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the SuperNode to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9091``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Driver" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the ServerApp to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to use a different " +#~ "version of Flower, for example Flower" +#~ " nightly, you can do so by " +#~ "changing the tag. All available versions" +#~ " are on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "Here's another example to start with " +#~ "HTTPS. Use the ``--certificates`` command " +#~ "line argument to pass paths to (CA" +#~ " certificate, server certificate, and " +#~ "server private key)." +#~ msgstr "" + +#~ msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Driver API)." +#~ msgstr "flower-driver-api" + +#~ msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Fleet API)." +#~ msgstr "flower-fleet-api" + +#~ msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +#~ msgstr "" + +#~ msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +#~ msgstr "" + +#~ msgid "|2bc8e069228d4873804061ff4a95048c|" +#~ msgstr "" + +#~ msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +#~ msgstr "" + +#~ msgid "|d5f962c3f4ec48529efda980868c14b0|" +#~ msgstr "" + +#~ msgid "|a5eccea18d4c43a68b54b65043cabef8|" +#~ msgstr "" + +#~ msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +#~ msgstr "" + +#~ msgid "|241fc906441a4f038c625a19d30d01b2|" +#~ msgstr "" + +#~ msgid "|0aa5aa05810b44b6a835cecce28f3137|" +#~ msgstr "" + +#~ msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +#~ msgstr "" + +#~ msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +#~ msgstr "" + +#~ msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +#~ msgstr "" + +#~ msgid "|72939caf6e294b0986fee6dde96614d7|" +#~ msgstr "" + +#~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +#~ msgstr "" + diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 9333ce670e93..9c8d2f5ff19b 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -7,17 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-28 11:47+0200\n" +"POT-Creation-Date: 2024-06-17 16:09+0200\n" "PO-Revision-Date: 2024-06-16 09:09+0000\n" "Last-Translator: 박태현 \n" -"Language-Team: Korean \n" "Language: ko\n" +"Language-Team: Korean \n" +"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -30,11 +29,9 @@ msgstr "엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" -"`Flower `_ core framework architecture with Edge Client " -"Engine" -msgstr "" -"`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔" -"진" +"`Flower `_ core framework architecture with Edge " +"Client Engine" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" @@ -44,9 +41,7 @@ msgstr "가상 클라이언트 엔진" msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" -msgstr "" -"`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔" -"진" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" @@ -54,277 +49,276 @@ msgstr "동일 작업에서 가상 클라이언트 엔진과 엣지 클라이언 #: ../../source/contributor-explanation-architecture.rst:23 msgid "" -"`Flower `_ core framework architecture with both Virtual " -"Client Engine and Edge Client Engine" -msgstr "" -"`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라" -"이언트 엔진" +"`Flower `_ core framework architecture with both " +"Virtual Client Engine and Edge Client Engine" +msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라이언트 엔진" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" msgstr "Docker Flower 이미지를 Locally 구축하는 방법" #: ../../source/contributor-how-to-build-docker-images.rst:4 +#, fuzzy msgid "" -"Flower provides pre-made docker images on `Docker Hub `_ that include all necessary dependencies for running the " -"SuperLink. You can also build your own custom docker images from scratch " -"with a different version of Python or Ubuntu if that is what you need. In " -"this guide, we will explain what images exist and how to build them locally." +"Flower provides pre-made docker images on `Docker Hub " +"`_ that include all necessary dependencies" +" for running the SuperLink, SuperNode or ServerApp. You can also build " +"your own custom docker images from scratch with a different version of " +"Python or Linux distribution (Ubuntu/Alpine) if that is what you need. In" +" this guide, we will explain what images exist and how to build them " +"locally." msgstr "" -"Flower는 'Docker Hub '_에서 미리 만들어진 " -"Docker 이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 " -"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 다" -"른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 정" -"의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 이미지들과 " -"이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." +"Flower는 'Docker Hub '_에서 미리 만들어진 Docker " +"이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 ServerApp을 실행하는 데 필요한 모든 " +"dependencies를 포함합니다. 필요한 경우 다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해" +" 처음부터 사용자 정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 이미지들과 이들을 로컬에서 빌드하는 " +"방법에 대해 설명하겠습니다." -#: ../../source/contributor-how-to-build-docker-images.rst:9 +#: ../../source/contributor-how-to-build-docker-images.rst:10 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." msgstr "시작하기 전에, 로컬 개발 환경에서 몇 가지 전제 조건을 충족해야 합니다." -#: ../../source/contributor-how-to-build-docker-images.rst:11 +#: ../../source/contributor-how-to-build-docker-images.rst:12 msgid "Clone the flower repository." msgstr "Flower 리포지토리를 복제합니다." -#: ../../source/contributor-how-to-build-docker-images.rst:17 -#: ../../source/how-to-run-flower-using-docker.rst:144 +#: ../../source/contributor-how-to-build-docker-images.rst:18 +#: ../../source/how-to-run-flower-using-docker.rst:165 msgid "Verify the Docker daemon is running." msgstr "Docker 데몬이 실행 중인지 확인하십시오." -#: ../../source/contributor-how-to-build-docker-images.rst:19 -#: ../../source/how-to-run-flower-using-docker.rst:146 -msgid "" -"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." -msgstr "" -":doc:Run Flower using Docker 의 첫 번째 섹션" -"을 따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." - -#: ../../source/contributor-how-to-build-docker-images.rst:23 +#: ../../source/contributor-how-to-build-docker-images.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:167 msgid "" -"Currently, Flower provides two images, a ``base`` image and a ``superlink`` " -"image. The base image, as the name suggests, contains basic dependencies " -"that the SuperLink needs. This includes system dependencies, Python and " -"Python tools. The SuperLink image is based on the base image, but it " -"additionally installs the SuperLink using ``pip``." +"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -"현재, Flower는 \"base\" 이미지 그리고 \"superlink\" 이미지를 제공합니다. " -"base 이미지는 이름에서 알 수 있듯이 SuperLink가 필요로 하는 기본 dependencies" -"를 포함하고 있습니다. 여기에는 시스템 dependencies, Python 및 Python 도구가 " -"포함됩니다. SuperLink 이미지는 base 이미지를 기반으로 하지만 \"pip\"을 사용하" -"여 SuperLink를 추가로 설치합니다." +":doc:Run Flower using Docker 의 첫 번째 섹션을 " +"따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." -#: ../../source/contributor-how-to-build-docker-images.rst:28 +#: ../../source/contributor-how-to-build-docker-images.rst:25 msgid "" "The build instructions that assemble the images are located in the " -"respective Dockerfiles. You can find them in the subdirectories of ``src/" -"docker``." +"respective Dockerfiles. You can find them in the subdirectories of " +"``src/docker``." msgstr "" -"이미지들을 조합하는 빌드 instruction들은 해당 Dockerfile에 있습니다. \"src/" -"docker\" 의 하위 디렉토리에서 찾을 수 있습니다." +"이미지들을 조합하는 빌드 instruction들은 해당 Dockerfile에 있습니다. \"src/docker\" 의 하위 " +"디렉토리에서 찾을 수 있습니다." -#: ../../source/contributor-how-to-build-docker-images.rst:31 -msgid "" -"Both, base and SuperLink image are configured via build arguments. Through " -"build arguments, we can make our build more flexible. For example, in the " -"base image, we can specify the version of Python to install using the " -"``PYTHON_VERSION`` build argument. Some of the build arguments have default " -"values, others must be specified when building the image. All available " -"build arguments for each image are listed in one of the tables below." +#: ../../source/contributor-how-to-build-docker-images.rst:28 +#, fuzzy +msgid "" +"Flower Docker images are configured via build arguments. Through build " +"arguments, we can make the creation of images more flexible. For example," +" in the base image, we can specify the version of Python to install using" +" the ``PYTHON_VERSION`` build argument. Some of the build arguments have " +"default values, others must be specified when building the image. All " +"available build arguments for each image are listed in one of the tables " +"below." msgstr "" -"base 이미지와 SuperLink 이미지 둘 다 빌드 argument들을 통해 구성됩니다. 빌드 " -"argument들을 통해, 빌드를 더 유연하게 만들 수 있습니다. 예를 들어, base 이미" -"지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 수 있" -"습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 합니" -"다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 있습니다." +"base 이미지와 SuperLink 이미지 둘 다 빌드 argument들을 통해 구성됩니다. 빌드 argument들을 통해, 빌드를" +" 더 유연하게 만들 수 있습니다. 예를 들어, base 이미지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여" +" Python 버전을 지정할 수 있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 합니다. 각 " +"이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 있습니다." -#: ../../source/contributor-how-to-build-docker-images.rst:38 +#: ../../source/contributor-how-to-build-docker-images.rst:35 msgid "Building the base image" msgstr "base 이미지 빌드" -#: ../../source/contributor-how-to-build-docker-images.rst:44 -#: ../../source/contributor-how-to-build-docker-images.rst:86 +#: ../../source/contributor-how-to-build-docker-images.rst:41 +#: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "Build argument" msgstr "빌드 argument" -#: ../../source/contributor-how-to-build-docker-images.rst:45 -#: ../../source/contributor-how-to-build-docker-images.rst:87 +#: ../../source/contributor-how-to-build-docker-images.rst:42 +#: ../../source/contributor-how-to-build-docker-images.rst:99 msgid "Description" msgstr "설명" -#: ../../source/contributor-how-to-build-docker-images.rst:46 -#: ../../source/contributor-how-to-build-docker-images.rst:88 +#: ../../source/contributor-how-to-build-docker-images.rst:43 +#: ../../source/contributor-how-to-build-docker-images.rst:100 msgid "Required" msgstr "필수" -#: ../../source/contributor-how-to-build-docker-images.rst:47 -#: ../../source/contributor-how-to-build-docker-images.rst:89 +#: ../../source/contributor-how-to-build-docker-images.rst:44 +#: ../../source/contributor-how-to-build-docker-images.rst:101 msgid "Example" msgstr "예시" +#: ../../source/contributor-how-to-build-docker-images.rst:45 +msgid "``DISTRO``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:46 +#, fuzzy +msgid "The Linux distribution to use as the base image." +msgstr "base 이미지의 Ubuntu 버전." + +#: ../../source/contributor-how-to-build-docker-images.rst:47 +#: ../../source/contributor-how-to-build-docker-images.rst:51 +#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:71 +#: ../../source/contributor-how-to-build-docker-images.rst:104 +msgid "No" +msgstr "" + #: ../../source/contributor-how-to-build-docker-images.rst:48 -#: ../../source/contributor-how-to-build-docker-images.rst:94 -msgid "``PYTHON_VERSION``" -msgstr "``PYTHON_VERSION``" +#, fuzzy +msgid "``ubuntu``" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:49 -msgid "Version of ``python`` to be installed." -msgstr "설치 된 ``python`` 버전." +#, fuzzy +msgid "``DISTRO_VERSION``" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:50 +msgid "Version of the Linux distribution." +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:52 +#, fuzzy +msgid "``22.04``" +msgstr "``23.0.1``" + +#: ../../source/contributor-how-to-build-docker-images.rst:53 +msgid "``PYTHON_VERSION``" +msgstr "``PYTHON_VERSION``" + #: ../../source/contributor-how-to-build-docker-images.rst:54 -#: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:108 -msgid "Yes" -msgstr "예" +msgid "Version of ``python`` to be installed." +msgstr "설치 된 ``python`` 버전." -#: ../../source/contributor-how-to-build-docker-images.rst:51 -msgid "``3.11``" -msgstr "``3.11``" +#: ../../source/contributor-how-to-build-docker-images.rst:56 +msgid "``3.11`` or ``3.11.1``" +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:52 +#: ../../source/contributor-how-to-build-docker-images.rst:57 msgid "``PIP_VERSION``" msgstr "``PIP_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:53 +#: ../../source/contributor-how-to-build-docker-images.rst:58 msgid "Version of ``pip`` to be installed." msgstr "설치 된 ``pip`` 버전." -#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:63 +#: ../../source/contributor-how-to-build-docker-images.rst:67 +#: ../../source/contributor-how-to-build-docker-images.rst:108 +msgid "Yes" +msgstr "예" + +#: ../../source/contributor-how-to-build-docker-images.rst:60 msgid "``23.0.1``" msgstr "``23.0.1``" -#: ../../source/contributor-how-to-build-docker-images.rst:56 +#: ../../source/contributor-how-to-build-docker-images.rst:61 msgid "``SETUPTOOLS_VERSION``" msgstr "``SETUPTOOLS_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:57 +#: ../../source/contributor-how-to-build-docker-images.rst:62 msgid "Version of ``setuptools`` to be installed." msgstr "설치 된 ``setuptools`` 버전." -#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:64 msgid "``69.0.2``" msgstr "``69.0.2``" -#: ../../source/contributor-how-to-build-docker-images.rst:60 -#: ../../source/contributor-how-to-build-docker-images.rst:98 -msgid "``UBUNTU_VERSION``" -msgstr "``UBUNTU_VERSION``" +#: ../../source/contributor-how-to-build-docker-images.rst:65 +msgid "``FLWR_VERSION``" +msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:61 -msgid "Version of the official Ubuntu Docker image." -msgstr "공식 Ubuntu Docker 이미지 버전." +#: ../../source/contributor-how-to-build-docker-images.rst:66 +msgid "Version of Flower to be installed." +msgstr "설치 된 Flower 버전." -#: ../../source/contributor-how-to-build-docker-images.rst:62 -msgid "Defaults to ``22.04``." -msgstr "``22.04``이 기본값." +#: ../../source/contributor-how-to-build-docker-images.rst:68 +msgid "``1.8.0``" +msgstr "``1.8.0``" -#: ../../source/contributor-how-to-build-docker-images.rst:65 -msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1 " -"and setuptools 69.0.2:" +#: ../../source/contributor-how-to-build-docker-images.rst:69 +msgid "``FLWR_PACKAGE``" +msgstr "``FLWR_PACKAGE``" + +#: ../../source/contributor-how-to-build-docker-images.rst:70 +#, fuzzy +msgid "The Flower package to be installed." +msgstr "설치 할 PyPI 패키지." + +#: ../../source/contributor-how-to-build-docker-images.rst:72 +msgid "``flwr`` or ``flwr-nightly``" msgstr "" -"다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base 이" -"미지를 만듭니다:" -#: ../../source/contributor-how-to-build-docker-images.rst:76 +#: ../../source/contributor-how-to-build-docker-images.rst:75 +#, fuzzy +msgid "" +"The following example creates a base Ubuntu/Alpine image with Python " +"3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" +msgstr "다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base 이미지를 만듭니다:" + +#: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the " -"build arguments as well as the name and tag can be adapted to your needs. " -"These values serve as examples only." +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " +"the build arguments as well as the name and tag can be adapted to your " +"needs. These values serve as examples only." msgstr "" -"이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 " -"argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 뿐입" -"니다." +"이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 argument들 뿐만 아니라 이름과" +" 태그도 정할 수 있습니다. 이 값들은 예시일 뿐입니다." -#: ../../source/contributor-how-to-build-docker-images.rst:80 -msgid "Building the SuperLink image" +#: ../../source/contributor-how-to-build-docker-images.rst:92 +#, fuzzy +msgid "Building the SuperLink/SuperNode or ServerApp image" msgstr "SuperLink 이미지 빌드" -#: ../../source/contributor-how-to-build-docker-images.rst:90 +#: ../../source/contributor-how-to-build-docker-images.rst:102 msgid "``BASE_REPOSITORY``" msgstr "``BASE_REPOSITORY``" -#: ../../source/contributor-how-to-build-docker-images.rst:91 +#: ../../source/contributor-how-to-build-docker-images.rst:103 msgid "The repository name of the base image." msgstr "base 이미지의 리포지토리 이름." -#: ../../source/contributor-how-to-build-docker-images.rst:92 -msgid "Defaults to ``flwr/base``." -msgstr "``flwr/base``이 기본값." - -#: ../../source/contributor-how-to-build-docker-images.rst:95 -msgid "The Python version of the base image." -msgstr "base 이미지의 Python 버전." - -#: ../../source/contributor-how-to-build-docker-images.rst:96 -msgid "Defaults to ``py3.11``." -msgstr "``py3.11``이 기본값." - -#: ../../source/contributor-how-to-build-docker-images.rst:99 -msgid "The Ubuntu version of the base image." -msgstr "base 이미지의 Ubuntu 버전." - -#: ../../source/contributor-how-to-build-docker-images.rst:100 -msgid "Defaults to ``ubuntu22.04``." -msgstr "``ubuntu22.04``이 기본값." - -#: ../../source/contributor-how-to-build-docker-images.rst:102 -msgid "``FLWR_PACKAGE``" +#: ../../source/contributor-how-to-build-docker-images.rst:105 +#, fuzzy +msgid "``flwr/base``" msgstr "``FLWR_PACKAGE``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 -msgid "The PyPI package to install." -msgstr "설치 할 PyPI 패키지." - -#: ../../source/contributor-how-to-build-docker-images.rst:104 -msgid "Defaults to ``flwr``." -msgstr "``flwr``이 기본값." - #: ../../source/contributor-how-to-build-docker-images.rst:106 -msgid "``FLWR_VERSION``" -msgstr "``FLWR_VERSION``" +#, fuzzy +msgid "``BASE_IMAGE``" +msgstr "``BASE_REPOSITORY``" #: ../../source/contributor-how-to-build-docker-images.rst:107 -msgid "Version of Flower to be installed." -msgstr "설치 된 Flower 버전." +#, fuzzy +msgid "The Tag of the Flower base image." +msgstr "base 이미지의 리포지토리 이름." #: ../../source/contributor-how-to-build-docker-images.rst:109 -msgid "``1.8.0``" -msgstr "``1.8.0``" - -#: ../../source/contributor-how-to-build-docker-images.rst:112 -msgid "" -"The following example creates a SuperLink image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.8.0:" +msgid "``1.8.0-py3.10-ubuntu22.04``" msgstr "" -"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base " -"이미지로 SuperLink 이미지를 만듭니다:" -#: ../../source/contributor-how-to-build-docker-images.rst:122 +#: ../../source/contributor-how-to-build-docker-images.rst:111 +#, fuzzy msgid "" -"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +"The following example creates a SuperLink/SuperNode or ServerApp image " +"with the official Flower base image:" msgstr "" -"이미지의 이름은 ``flwr_superlink``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌" -"드 argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 뿐" -"입니다." +"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base 이미지로 SuperLink" +" 이미지를 만듭니다:" -#: ../../source/contributor-how-to-build-docker-images.rst:125 +#: ../../source/contributor-how-to-build-docker-images.rst:122 +#, fuzzy msgid "" -"If you want to use your own base image instead of the official Flower base " -"image, all you need to do is set the ``BASE_REPOSITORY``, ``PYTHON_VERSION`` " -"and ``UBUNTU_VERSION`` build arguments." +"If you want to use your own base image instead of the official Flower " +"base image, all you need to do is set the ``BASE_REPOSITORY`` build " +"argument." msgstr "" -"공식 Flower base 이미지 대신 자체 base 이미지를 사용 하길 원한다면, " -"``BASE_REPOSITORY``, ``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 argument들" -"을 설정해야 합니다." +"공식 Flower base 이미지 대신 자체 base 이미지를 사용 하길 원한다면, ``BASE_REPOSITORY``, " +"``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 argument들을 설정해야 합니다." -#: ../../source/contributor-how-to-build-docker-images.rst:138 +#: ../../source/contributor-how-to-build-docker-images.rst:133 msgid "After creating the image, we can test whether the image is working:" msgstr "이미지 생성 후에, 이미지가 작동하는지 테스트할 수 있습니다:" @@ -334,30 +328,29 @@ msgstr "번역 기여" #: ../../source/contributor-how-to-contribute-translations.rst:4 msgid "" -"Since `Flower 1.5 `_ we have introduced translations to our doc pages, " -"but, as you might have noticed, the translations are often imperfect. If you " -"speak languages other than English, you might be able to help us in our " -"effort to make Federated Learning accessible to as many people as possible " -"by contributing to those translations! This might also be a great " -"opportunity for those wanting to become open source contributors with little " -"prerequisites." -msgstr "" -"`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 번" -"역이 불안전한 경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 사람" -"들이 Federated Learning에 접근할 수 있도록 번역 작업에 기여함으로써 저희의 노" -"력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 기여자가 " -"되고자 하는 사람들에게 좋은 기회가 될 수도 있습니다." +"Since `Flower 1.5 `_ we have introduced translations to " +"our doc pages, but, as you might have noticed, the translations are often" +" imperfect. If you speak languages other than English, you might be able " +"to help us in our effort to make Federated Learning accessible to as many" +" people as possible by contributing to those translations! This might " +"also be a great opportunity for those wanting to become open source " +"contributors with little prerequisites." +msgstr "" +"`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 번역이 불안전한 " +"경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 사람들이 Federated Learning에 접근할 수 있도록 번역 " +"작업에 기여함으로써 저희의 노력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 기여자가 되고자 하는 사람들에게" +" 좋은 기회가 될 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" -"Our translation project is publicly available over on `Weblate `_, this where most of " -"the work will happen." +"Our translation project is publicly available over on `Weblate " +"`_, this " +"where most of the work will happen." msgstr "" -"번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." +"번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." #: ../../source/contributor-how-to-contribute-translations.rst:18 msgid "Contribute to existing languages" @@ -365,43 +358,43 @@ msgstr "기존 언어에 기여하기" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" -"The first thing you will need to do in order to contribute is to create a " -"free Weblate account on this `page `_. More information about profile settings can be found `here " +"The first thing you will need to do in order to contribute is to create a" +" free Weblate account on this `page " +"`_. More information about" +" profile settings can be found `here " "`_." msgstr "" -"기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page `_에서 무료 Weblate 계정을 만드는 것입니다. 프로필 설" -"정에 대한 자세한 정보는 `here `_를 참조하세요." +"기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page " +"`_에서 무료 Weblate 계정을 만드는 " +"것입니다. 프로필 설정에 대한 자세한 정보는 `here " +"`_를 참조하세요." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" -"Once you are signed in to Weblate, you can navigate to the `Flower Framework " -"project `_. " -"Here, you should see the different existing languages that can be found on " -"the website." +"Once you are signed in to Weblate, you can navigate to the `Flower " +"Framework project `_. Here, you should see the different existing languages" +" that can be found on the website." msgstr "" -"Weblate에 로그인한 후, `Flower Framework project `_로 이동할 수 있습니다. 여기에서 웹사이트에 " -"있는 다양한 기존 언어들을 확인할 수 있습니다." +"Weblate에 로그인한 후, `Flower Framework project " +"`_로 이동할 수 " +"있습니다. 여기에서 웹사이트에 있는 다양한 기존 언어들을 확인할 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" -"Once you have selected the language you want to contribute to, you should " -"see a similar interface to this:" +"Once you have selected the language you want to contribute to, you should" +" see a similar interface to this:" msgstr "기여하고자 하는 언어를 선택하면, 다음과 같은 인터페이스가 나타납니다:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" "The most straight forward option here is to click on the ``Translate`` " -"button on the top right (in the ``Translation status`` section). This will " -"automatically bring you to the translation interface for untranslated " -"strings." +"button on the top right (in the ``Translation status`` section). This " +"will automatically bring you to the translation interface for " +"untranslated strings." msgstr "" -"여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 " -"``Translate`` 버튼을 클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 인터" -"페이스로 자동으로 이동합니다." +"여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 ``Translate`` 버튼을 " +"클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 인터페이스로 자동으로 이동합니다." #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" @@ -409,47 +402,44 @@ msgstr "인터페이스는 다음과 같습니다:" #: ../../source/contributor-how-to-contribute-translations.rst:47 msgid "" -"You input your translation in the text box at the top and then, once you are " -"happy with it, you either press ``Save and continue`` (to save the " -"translation and go to the next untranslated string), ``Save and stay`` (to " -"save the translation and stay on the same page), ``Suggest`` (to add your " -"translation to suggestions for other users to view), or ``Skip`` (to go to " -"the next untranslated string without saving anything)." +"You input your translation in the text box at the top and then, once you " +"are happy with it, you either press ``Save and continue`` (to save the " +"translation and go to the next untranslated string), ``Save and stay`` " +"(to save the translation and stay on the same page), ``Suggest`` (to add " +"your translation to suggestions for other users to view), or ``Skip`` (to" +" go to the next untranslated string without saving anything)." msgstr "" -"번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and " -"continue``(번역을 저장하고 다음 미번역 문장으로 이동), ``Save and stay``(번역" -"을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 볼 수 있도록 " -"번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 문장으" -"로 이동) 중 하나를 선택하면 됩니다." +"번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and continue``(번역을 저장하고 다음 미번역 " +"문장으로 이동), ``Save and stay``(번역을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 " +"볼 수 있도록 번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 문장으로 이동) 중 하나를 선택하면 " +"됩니다." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" "In order to help with the translations, you can see on the bottom the " "``Nearby strings``, the ``Comments`` (from other contributors), the " "``Automatic suggestions`` (from machine translation engines), the " -"translations in ``Other languages``, and the ``History`` of translations for " -"this string." +"translations in ``Other languages``, and the ``History`` of translations " +"for this string." msgstr "" -"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``자" -"동 제안``(기계 번역의), ``다른 언어``의 번역 및 해당 문장의 번역``히스토리``" -"를 볼 수 있습니다." +"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``자동 제안``(기계 번역의), ``다른 " +"언어``의 번역 및 해당 문장의 번역``히스토리``를 볼 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" -"On the right, under the ``String information`` section, you can also click " -"the link under ``Source string location`` in order to view the source of the " -"doc file containing the string." -msgstr "" -"오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 포함" -"된 문서의 파일 소스를 볼 수도 있습니다." +"On the right, under the ``String information`` section, you can also " +"click the link under ``Source string location`` in order to view the " +"source of the doc file containing the string." +msgstr "오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 포함된 문서의 파일 소스를 볼 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" -"For more information about translating using Weblate, you can check out this " -"`in-depth guide `_." +"For more information about translating using Weblate, you can check out " +"this `in-depth guide " +"`_." msgstr "" -"Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide `_를 확인하세요." +"Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide " +"`_를 확인하세요." #: ../../source/contributor-how-to-contribute-translations.rst:67 msgid "Add new languages" @@ -457,126 +447,12 @@ msgstr "새 언어 추가" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" -"If you want to add a new language, you will first have to contact us, either " -"on `Slack `_, or by opening an issue on our " -"`GitHub repo `_." -msgstr "" -"새 언어를 추가하려면, `Slack `에 문의하거나 " -"`GitHub repo `_에서 issue에 들어가 문의 해야 " -"합니다." - -#: ../../source/contributor-how-to-create-new-messages.rst:2 -msgid "Creating New Messages" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:4 -msgid "" -"This is a simple guide for creating a new type of message between the server " -"and clients in Flower." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:6 -msgid "" -"Let's suppose we have the following example functions in :code:`server.py` " -"and :code:`numpy_client.py`..." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:8 -msgid "Server's side:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:17 -msgid "Client's side:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:26 -msgid "" -"Let's now see what we need to implement in order to get this simple function " -"between the server and client to work!" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:30 -msgid "Message Types for Protocol Buffers" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:32 -msgid "" -"The first thing we need to do is to define a message type for the RPC system " -"in :code:`transport.proto`. Note that we have to do it for both the request " -"and response messages. For more details on the syntax of proto3, please see " -"the `official documentation `_." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:35 -msgid "Within the :code:`ServerMessage` block:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:52 -msgid "Within the ClientMessage block:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:70 -msgid "" -"Make sure to also add a field of the newly created message type in :code:" -"`oneof msg`." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:72 -msgid "Once that is done, we will compile the file with:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:78 -msgid "If it compiles successfully, you should see the following message:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:87 -msgid "Serialization and Deserialization Functions" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:89 -msgid "" -"Our next step is to add functions to serialize and deserialize Python " -"datatypes to or from our defined RPC message types. You should add these " -"functions in :code:`serde.py`." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:91 -msgid "The four functions:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:112 -msgid "Sending the Message from the Server" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:114 -msgid "" -"Now write the request function in your Client Proxy class (e.g., :code:" -"`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:128 -msgid "Receiving the Message by the Client" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:130 -msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the field " -"of your message and call the :code:`example_response` function. Remember to " -"use the serde functions!" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:132 -msgid "Within the handle function:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:139 -msgid "And add a new function:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:149 -msgid "Hopefully, when you run your program you will get the intended result!" +"If you want to add a new language, you will first have to contact us, " +"either on `Slack `_, or by opening an issue" +" on our `GitHub repo `_." msgstr "" +"새 언어를 추가하려면, `Slack `에 문의하거나 `GitHub repo " +"`_에서 issue에 들어가 문의 해야 합니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" @@ -584,52 +460,49 @@ msgstr "VSCode Dev Container에서 개발" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" -"When working on the Flower framework we want to ensure that all contributors " -"use the same developer environment to format code or run tests. For this " -"purpose we are using the VSCode Remote Containers extension. What is it? " -"Read the following quote:" +"When working on the Flower framework we want to ensure that all " +"contributors use the same developer environment to format code or run " +"tests. For this purpose we are using the VSCode Remote Containers " +"extension. What is it? Read the following quote:" msgstr "" -"Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 " -"동일한 개발 환경을 사용하길 원합니다. 이를 위해 VSCode Remote Containers 확장" -"을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 읽어보세요:" +"Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 동일한 개발 환경을 사용하길 원합니다. 이를 " +"위해 VSCode Remote Containers 확장을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 " +"읽어보세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" -"The Visual Studio Code Remote - Containers extension lets you use a Docker " -"container as a fully-featured development environment. It allows you to open " -"any folder inside (or mounted into) a container and take advantage of Visual " -"Studio Code's full feature set. A :code:`devcontainer.json` file in your " -"project tells VS Code how to access (or create) a development container with " -"a well-defined tool and runtime stack. This container can be used to run an " -"application or to separate tools, libraries, or runtimes needed for working " -"with a codebase." -msgstr "" -"Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 " -"기능을 갖춘 개발 환경으로 사용할 수 있습니다. 이 확장 기능을 사용하면 컨테이" -"너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio Code의 모" -"든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer.json` 파일" -"은 잘 정의된 도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(또는 생성)" -"하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 애플리케이션을 실행하거나 코" -"드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 데 사용할 수 " -"있습니다." +"The Visual Studio Code Remote - Containers extension lets you use a " +"Docker container as a fully-featured development environment. It allows " +"you to open any folder inside (or mounted into) a container and take " +"advantage of Visual Studio Code's full feature set. A " +":code:`devcontainer.json` file in your project tells VS Code how to " +"access (or create) a development container with a well-defined tool and " +"runtime stack. This container can be used to run an application or to " +"separate tools, libraries, or runtimes needed for working with a " +"codebase." +msgstr "" +"Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 기능을 갖춘 개발 환경으로 " +"사용할 수 있습니다. 이 확장 기능을 사용하면 컨테이너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio" +" Code의 모든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer.json` 파일은 잘 정의된 " +"도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(또는 생성)하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 " +"애플리케이션을 실행하거나 코드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 데 사용할 수 있습니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" -"Workspace files are mounted from the local file system or copied or cloned " -"into the container. Extensions are installed and run inside the container, " -"where they have full access to the tools, platform, and file system. This " -"means that you can seamlessly switch your entire development environment " -"just by connecting to a different container." +"Workspace files are mounted from the local file system or copied or " +"cloned into the container. Extensions are installed and run inside the " +"container, where they have full access to the tools, platform, and file " +"system. This means that you can seamlessly switch your entire development" +" environment just by connecting to a different container." msgstr "" -"작업 공간 파일은 로컬 파일 시스템에서 마운트되거나 컨테이너에 복사 또는 " -"클론됩니다. 확장 프로그램은 컨테이너 내부에 설치되고 실행되며, 도구, 플랫폼 " -"및 파일 시스템에 완전한 접근 권한을 갖습니다. 이는 다른 컨테이너에 연결하는 " -"것만으로 전체 개발 환경을 원활하게 전환할 수 있음을 의미합니다." +"작업 공간 파일은 로컬 파일 시스템에서 마운트되거나 컨테이너에 복사 또는 클론됩니다. 확장 프로그램은 컨테이너 내부에 설치되고 " +"실행되며, 도구, 플랫폼 및 파일 시스템에 완전한 접근 권한을 갖습니다. 이는 다른 컨테이너에 연결하는 것만으로 전체 개발 환경을 " +"원활하게 전환할 수 있음을 의미합니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 msgid "" -"Source: `Official VSCode documentation `_" +"Source: `Official VSCode documentation " +"`_" msgstr "출처 : 공식 VSCode 문서" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 @@ -638,57 +511,52 @@ msgstr "시작하기" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 msgid "" -"Configuring and setting up the :code:`Dockerfile` as well the configuration " -"for the devcontainer can be a bit more involved. The good thing is you don't " -"have to do it. Usually it should be enough to install `Docker `_ on your system and ensure its available on " -"your command line. Additionally, install the `VSCode Containers Extension " -"`_." +"Configuring and setting up the :code:`Dockerfile` as well the " +"configuration for the devcontainer can be a bit more involved. The good " +"thing is you don't have to do it. Usually it should be enough to install " +"`Docker `_ on your system and " +"ensure its available on your command line. Additionally, install the " +"`VSCode Containers Extension `_." msgstr "" -"`Dockerfile`을 설정하고 구성하는 것과 개발 컨테이너 구성은 약간 복잡할 수 " -"있습니다. 다행히도, 이를 직접 할 필요는 없습니다. 일반적으로 시스템에 `" -"Docker `_를 설치하고 커맨드 " -"라인에서 사용할 수 있는지 확인하는 것으로 충분합니다. 추가로 `VSCode " -"Containers Extension `" -"_을 설치하세요." +"`Dockerfile`을 설정하고 구성하는 것과 개발 컨테이너 구성은 약간 복잡할 수 있습니다. 다행히도, 이를 직접 할 필요는 " +"없습니다. 일반적으로 시스템에 `Docker `_를 " +"설치하고 커맨드 라인에서 사용할 수 있는지 확인하는 것으로 충분합니다. 추가로 `VSCode Containers Extension " +"`_을 설치하세요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" -"Now you should be good to go. When starting VSCode, it will ask you to run " -"in the container environment and - if you confirm - automatically build the " -"container and use it. To manually instruct VSCode to use the devcontainer, " -"you can, after installing the extension, click the green area in the bottom " -"left corner of your VSCode window and select the option *(Re)Open Folder in " -"Container*." +"Now you should be good to go. When starting VSCode, it will ask you to " +"run in the container environment and - if you confirm - automatically " +"build the container and use it. To manually instruct VSCode to use the " +"devcontainer, you can, after installing the extension, click the green " +"area in the bottom left corner of your VSCode window and select the " +"option *(Re)Open Folder in Container*." msgstr "" -"이제 준비가 완료되었습니다. VSCode를 시작하면 컨테이너 환경에서 실행할지를 " -"묻고, 확인하면 자동으로 컨테이너를 빌드하고 사용할 것입니다. VSCode에 " -"수동으로 개발 컨테이너를 사용하도록 지시하려면, 확장을 설치한 후, VSCode " -"창의 왼쪽 하단에 있는 초록색 부을 클릭하고 *(Re)Open Folder in Container* " -"옵션을 선택하세요." +"이제 준비가 완료되었습니다. VSCode를 시작하면 컨테이너 환경에서 실행할지를 묻고, 확인하면 자동으로 컨테이너를 빌드하고 사용할" +" 것입니다. VSCode에 수동으로 개발 컨테이너를 사용하도록 지시하려면, 확장을 설치한 후, VSCode 창의 왼쪽 하단에 있는 " +"초록색 부을 클릭하고 *(Re)Open Folder in Container* 옵션을 선택하세요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" -"In some cases your setup might be more involved. For those cases consult the " -"following sources:" -msgstr "경우에 따라 설정이 더 복잡할 수도 있습니다. 이러한 경우에는 다음 소스를 " -"참조하세요:" +"In some cases your setup might be more involved. For those cases consult " +"the following sources:" +msgstr "경우에 따라 설정이 더 복잡할 수도 있습니다. 이러한 경우에는 다음 소스를 참조하세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 msgid "" -"`Developing inside a Container `_" +"`Developing inside a Container " +"`_" msgstr "" -"`컨테이너 내부 개발`_" +"`컨테이너 내부 개발`_" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 msgid "" -"`Remote development in Containers `_" -msgstr "" -"`컨테이너 원격 개발`_" +"`Remote development in Containers " +"`_" +msgstr "`컨테이너 원격 개발`_" #: ../../source/contributor-how-to-install-development-versions.rst:2 msgid "Install development versions" @@ -704,35 +572,33 @@ msgstr "Poetry 사용하기(권장)" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" -"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency in " -"``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." -"lock`` (``rm poetry.lock``) before running ``poetry install``)." +"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency " +"in ``pyproject.toml`` and then reinstall (don't forget to delete " +"``poetry.lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" -"PyPI에서 ``flwr`` 사전 릴리스 설치하기: ``pyproject.toml``에서 ``flwr``의 " -"dependency를 업데이트한 다음, 재설치하세요(``poetry 설치``이전에 ``poetry." -"lock`` (``rm poetry.lock``)를 제거하는 것을 잊지 마세요)." +"PyPI에서 ``flwr`` 사전 릴리스 설치하기: ``pyproject.toml``에서 ``flwr``의 dependency를 " +"업데이트한 다음, 재설치하세요(``poetry 설치``이전에 ``poetry.lock`` (``rm poetry.lock``)를 " +"제거하는 것을 잊지 마세요)." #: ../../source/contributor-how-to-install-development-versions.rst:12 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (without " "extras)" -msgstr "" -"``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (extras 제외)" +msgstr "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:13 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true, extras = " "[\"simulation\"] }`` (with extras)" msgstr "" -"``flwr = { version = \"1.0.0a0\", allow-prereleases = true, extras = [" -"\"simulation\"] }`` (extras 포함)" +"``flwr = { version = \"1.0.0a0\", allow-prereleases = true, extras = " +"[\"simulation\"] }`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" -"Install ``flwr`` from a local copy of the Flower source code via ``pyproject." -"toml``:" -msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 " -"설치하세요:" +"Install ``flwr`` from a local copy of the Flower source code via " +"``pyproject.toml``:" +msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 설치하세요:" #: ../../source/contributor-how-to-install-development-versions.rst:17 msgid "``flwr = { path = \"../../\", develop = true }`` (without extras)" @@ -740,11 +606,11 @@ msgstr "``flwr = { path = \"../../\", develop = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " -"(with extras)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " +"}`` (with extras)" msgstr "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` (" -"extras 포함)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " +"}`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:20 msgid "Install ``flwr`` from a local wheel file via ``pyproject.toml``:" @@ -752,8 +618,8 @@ msgstr "``pyproject.toml``을 통해 로컬 wheel file에서 ``flwr``을 설치 #: ../../source/contributor-how-to-install-development-versions.rst:22 msgid "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " -"extras)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without" +" extras)" msgstr "" "``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (extras " "제외)" @@ -763,8 +629,8 @@ msgid "" "``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\", extras = " "[\"simulation\"] }`` (with extras)" msgstr "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\", extras = [" -"\"simulation\"] }`` (extras 포함)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\", extras = " +"[\"simulation\"] }`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:25 msgid "" @@ -772,8 +638,8 @@ msgid "" "Dependency Specification `_" msgstr "" -"자세한 내용은 Poetry 문서를 참고하세요: `Poetry Dependency Specification " -"`_" +"자세한 내용은 Poetry 문서를 참고하세요: `Poetry Dependency Specification `_" #: ../../source/contributor-how-to-install-development-versions.rst:28 msgid "Using pip (recommended on Colab)" @@ -796,8 +662,8 @@ msgid "" "Python packages can be installed from git repositories. Use one of the " "following commands to install the Flower directly from GitHub." msgstr "" -"Python 패키지는 git 저장소에서 설치할 수 있습니다. 다음 명령어 중 하나를 " -"사용하여 GitHub에서 직접 Flower를 설치하세요." +"Python 패키지는 git 저장소에서 설치할 수 있습니다. 다음 명령어 중 하나를 사용하여 GitHub에서 직접 Flower를 " +"설치하세요." #: ../../source/contributor-how-to-install-development-versions.rst:37 msgid "Install ``flwr`` from the default GitHub branch (``main``):" @@ -805,7 +671,8 @@ msgstr "기본 GitHub branch (``main``)에서 ``flwr`` 를 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" -"``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" +"``pip install flwr@git+https://github.com/adap/flower.git`` (without " +"extras)" msgstr "``pip install flwr@git+https://github.com/adap/flower.git`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:40 @@ -813,8 +680,8 @@ msgid "" "``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` " "(with extras)" msgstr "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` (" -"extras 포함)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git`` " +"(extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:42 msgid "Install ``flwr`` from a specific GitHub branch (``branch-name``):" @@ -825,16 +692,16 @@ msgid "" "``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " "(without extras)" msgstr "" -"``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` (" -"extras 제외)" +"``pip install flwr@git+https://github.com/adap/flower.git@branch-name`` " +"(extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" -"name`` (with extras)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" +"@branch-name`` (with extras)" msgstr "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" -"name`` (extras 포함)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" +"@branch-name`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:49 msgid "Open Jupyter Notebooks on Google Colab" @@ -845,32 +712,32 @@ msgid "" "Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" "pytorch.ipynb``:" msgstr "" -"``doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb``" -"notebook을 엽니다:" +"``doc/source/tutorial-series-get-started-with-flower-" +"pytorch.ipynb``notebook을 엽니다:" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" -"tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" -"tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" -"Open a development version of the same notebook from branch `branch-name` by " -"changing ``main`` to ``branch-name`` (right after ``blob``):" +"Open a development version of the same notebook from branch `branch-name`" +" by changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" -"``main``을 ``branch-name``(``blob`` 바로 뒤)으로 변경하여 동일한 notebook의 " -"개발 버전을 브랜치 `branch-name`에서 엽니다 :" +"``main``을 ``branch-name``(``blob`` 바로 뒤)으로 변경하여 동일한 notebook의 개발 버전을 브랜치 " +"`branch-name`에서 엽니다 :" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" -"source/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-" +"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" -"source/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-" +"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:59 msgid "Install a `whl` on Google Colab:" @@ -878,10 +745,9 @@ msgstr "Google Colab에서 `whl` 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" -"In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " -"to session storage``" -msgstr "왼쪽의 수직 아이콘 그리드에서 ``Files`` > ``Upload to session storage``를 " -"선택하세요" +"In the vertical icon grid on the left hand side, select ``Files`` > " +"``Upload to session storage``" +msgstr "왼쪽의 수직 아이콘 그리드에서 ``Files`` > ``Upload to session storage``를 선택하세요" #: ../../source/contributor-how-to-install-development-versions.rst:62 msgid "Upload the whl (e.g., ``flwr-1.8.0-py3-none-any.whl``)" @@ -889,13 +755,13 @@ msgstr "whl (예:``flwr-1.8.0-py3-none-any.whl``)을 업로드하세요" #: ../../source/contributor-how-to-install-development-versions.rst:63 msgid "" -"Change ``!pip install -q 'flwr[simulation]' torch torchvision matplotlib`` " -"to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " -"torchvision matplotlib``" +"Change ``!pip install -q 'flwr[simulation]' torch torchvision " +"matplotlib`` to ``!pip install -q 'flwr-1.8.0-py3-none-" +"any.whl[simulation]' torch torchvision matplotlib``" msgstr "" -"``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``를 ``!pip " -"install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch torchvision " -"matplotlib``로 바꾸세요" +"``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``를 " +"``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " +"torchvision matplotlib``로 바꾸세요" #: ../../source/contributor-how-to-release-flower.rst:2 msgid "Release Flower" @@ -913,11 +779,12 @@ msgstr "릴리즈 동안에" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" -"The version number of a release is stated in ``pyproject.toml``. To release " -"a new version of Flower, the following things need to happen (in that order):" +"The version number of a release is stated in ``pyproject.toml``. To " +"release a new version of Flower, the following things need to happen (in " +"that order):" msgstr "" -"릴리즈의 버전 번호는 ``pyproject.toml``에 명시되어 있습니다. Flower의 새 " -"버전을 릴리즈하려면 다음 작업이 순서대로 수행되어야 합니다:" +"릴리즈의 버전 번호는 ``pyproject.toml``에 명시되어 있습니다. Flower의 새 버전을 릴리즈하려면 다음 작업이 " +"순서대로 수행되어야 합니다:" #: ../../source/contributor-how-to-release-flower.rst:11 msgid "" @@ -925,158 +792,203 @@ msgid "" "order to add every new change to the changelog (feel free to make manual " "changes to the changelog afterwards until it looks good)." msgstr "" -"모든 새로운 변경 사항을 변경 로그에 추가하기 위해``python3 src/py/flwr_tool/" -"update_changelog.py ``을 실행합니다 (변경 로그가 만족스러워질 " -"때까지 수동으로 변경해도 됩니다)." +"모든 새로운 변경 사항을 변경 로그에 추가하기 위해``python3 " +"src/py/flwr_tool/update_changelog.py ``을 실행합니다 (변경 로그가 " +"만족스러워질 때까지 수동으로 변경해도 됩니다)." #: ../../source/contributor-how-to-release-flower.rst:12 msgid "" -"Once the changelog has been updated with all the changes, run ``./dev/" -"prepare-release-changelog.sh v``, where ```` is " -"the version stated in ``pyproject.toml`` (notice the ``v`` added before it). " -"This will replace the ``Unreleased`` header of the changelog by the version " -"and current date, and it will add a thanking message for the contributors. " -"Open a pull request with those changes." +"Once the changelog has been updated with all the changes, run ``./dev" +"/prepare-release-changelog.sh v``, where ```` " +"is the version stated in ``pyproject.toml`` (notice the ``v`` added " +"before it). This will replace the ``Unreleased`` header of the changelog " +"by the version and current date, and it will add a thanking message for " +"the contributors. Open a pull request with those changes." msgstr "" -"모든 변경 사항으로 변경 로그가 업데이트되면,``./dev/prepare-release-" -"changelog.sh v``을 실행합니다. 여기서 ````은 " -"``pyproject.toml``에 명시된 버전 번호입니다 (앞에 ``v``가 추가된 것을 " -"주의하세요). 이 명령어는 변경 로그의 ``Unreleased``헤더를 해당 버전과 현재 " -"날짜로 교체하고, 기여자들에게 감사 메시지가 추가됩니다. 이러한 변경 사항으로 " -"pull request합니다." +"모든 변경 사항으로 변경 로그가 업데이트되면,``./dev/prepare-release-changelog.sh " +"v``을 실행합니다. 여기서 ````은 ``pyproject.toml``에 명시된 " +"버전 번호입니다 (앞에 ``v``가 추가된 것을 주의하세요). 이 명령어는 변경 로그의 ``Unreleased``헤더를 해당 버전과" +" 현재 날짜로 교체하고, 기여자들에게 감사 메시지가 추가됩니다. 이러한 변경 사항으로 pull request합니다." #: ../../source/contributor-how-to-release-flower.rst:13 msgid "" "Once the pull request is merged, tag the release commit with the version " -"number as soon as the PR is merged: ``git tag v`` (notice the " -"``v`` added before the version number), then ``git push --tags``. This will " -"create a draft release on GitHub containing the correct artifacts and the " -"relevant part of the changelog." +"number as soon as the PR is merged: ``git tag v`` (notice " +"the ``v`` added before the version number), then ``git push --tags``. " +"This will create a draft release on GitHub containing the correct " +"artifacts and the relevant part of the changelog." msgstr "" #: ../../source/contributor-how-to-release-flower.rst:14 -msgid "" -"Check the draft release on GitHub, and if everything is good, publish it." +msgid "Check the draft release on GitHub, and if everything is good, publish it." msgstr "" +#: ../../source/contributor-how-to-release-flower.rst:15 +#, fuzzy +msgid "Trigger the CI for building the Docker images." +msgstr "공식 Ubuntu Docker 이미지 버전." + #: ../../source/contributor-how-to-release-flower.rst:17 +msgid "" +"To trigger the workflow, a collaborator must create a " +"``workflow_dispatch`` event in the GitHub CI. This can be done either " +"through the UI or via the GitHub CLI. The event requires only one input, " +"the Flower version, to be released." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:21 +msgid "**Via the UI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:23 +msgid "" +"Go to the ``Build docker images`` workflow `page " +"`_." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:24 +msgid "" +"Click on the ``Run workflow`` button and type the new version of Flower " +"in the ``Version of Flower`` input field." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:25 +msgid "Click on the **green** ``Run workflow`` button." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:29 +msgid "**Via the GitHub CI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:31 +msgid "" +"Make sure you are logged in via ``gh auth login`` and that the current " +"working directory is the root of the Flower repository." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:32 +msgid "" +"Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" +"version=``." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:19 +#: ../../source/contributor-how-to-release-flower.rst:37 msgid "Create a pull request which contains the following changes:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:21 +#: ../../source/contributor-how-to-release-flower.rst:39 msgid "Increase the minor version in ``pyproject.toml`` by one." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:22 +#: ../../source/contributor-how-to-release-flower.rst:40 msgid "Update all files which contain the current version number if necessary." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:23 +#: ../../source/contributor-how-to-release-flower.rst:41 msgid "Add a new ``Unreleased`` section in ``changelog.md``." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:25 +#: ../../source/contributor-how-to-release-flower.rst:43 msgid "" -"Merge the pull request on the same day (i.e., before a new nightly release " -"gets published to PyPI)." +"Merge the pull request on the same day (i.e., before a new nightly " +"release gets published to PyPI)." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:28 +#: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:31 +#: ../../source/contributor-how-to-release-flower.rst:49 msgid "Pre-release naming" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:33 +#: ../../source/contributor-how-to-release-flower.rst:51 msgid "" -"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases " -"MUST use one of the following naming patterns:" +"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" +" MUST use one of the following naming patterns:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:35 +#: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:36 +#: ../../source/contributor-how-to-release-flower.rst:54 msgid "Beta: ``MAJOR.MINOR.PATCHbN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:37 +#: ../../source/contributor-how-to-release-flower.rst:55 msgid "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:39 +#: ../../source/contributor-how-to-release-flower.rst:57 msgid "Examples include:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:41 +#: ../../source/contributor-how-to-release-flower.rst:59 msgid "``1.0.0a0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:42 +#: ../../source/contributor-how-to-release-flower.rst:60 msgid "``1.0.0b0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:43 +#: ../../source/contributor-how-to-release-flower.rst:61 msgid "``1.0.0rc0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:44 +#: ../../source/contributor-how-to-release-flower.rst:62 msgid "``1.0.0rc1``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:46 +#: ../../source/contributor-how-to-release-flower.rst:64 msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:49 +#: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:50 +#: ../../source/contributor-how-to-release-flower.rst:68 msgid "" -"`PyPA Choosing a versioning scheme `_" +"`PyPA Choosing a versioning scheme " +"`_" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:52 +#: ../../source/contributor-how-to-release-flower.rst:70 msgid "" -"Note that the approach defined by PyPA is not compatible with SemVer 2.0.0 " -"spec, for details consult the `Semantic Versioning Specification `_ (specifically item 11 on " -"precedence)." +"Note that the approach defined by PyPA is not compatible with SemVer " +"2.0.0 spec, for details consult the `Semantic Versioning Specification " +"`_ (specifically item " +"11 on precedence)." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:55 +#: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:57 -msgid "" -"Should the next pre-release be called alpha, beta, or release candidate?" +#: ../../source/contributor-how-to-release-flower.rst:75 +msgid "Should the next pre-release be called alpha, beta, or release candidate?" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:59 +#: ../../source/contributor-how-to-release-flower.rst:77 msgid "" -"RC: feature complete, no known issues (apart from issues that are classified " -"as \"won't fix\" for the next stable release) - if no issues surface this " -"will become the next stable release" +"RC: feature complete, no known issues (apart from issues that are " +"classified as \"won't fix\" for the next stable release) - if no issues " +"surface this will become the next stable release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:60 +#: ../../source/contributor-how-to-release-flower.rst:78 msgid "Beta: feature complete, allowed to have known issues" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:61 +#: ../../source/contributor-how-to-release-flower.rst:79 msgid "Alpha: not feature complete, allowed to have known issues" msgstr "" @@ -1088,8 +1000,8 @@ msgstr "" msgid "" "It is recommended to run your Python setup within a virtual environment. " "This guide shows three different examples how to create a virtual " -"environment with pyenv virtualenv, poetry, or Anaconda. You can follow the " -"instructions or choose your preferred setup." +"environment with pyenv virtualenv, poetry, or Anaconda. You can follow " +"the instructions or choose your preferred setup." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 @@ -1099,15 +1011,17 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 msgid "" -"Flower requires at least `Python 3.8 `_, but " -"`Python 3.10 `_ or above is recommended." +"Flower requires at least `Python 3.8 `_, " +"but `Python 3.10 `_ or above is " +"recommended." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 msgid "" -"Due to a known incompatibility with `ray `_, " -"we currently recommend utilizing at most `Python 3.11 `_ for running Flower simulations." +"Due to a known incompatibility with `ray " +"`_, we currently recommend utilizing at " +"most `Python 3.11 `_ for running Flower " +"simulations." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 @@ -1116,10 +1030,10 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" -"One of the recommended virtual environment is `pyenv `_/`virtualenv `_. " -"Please see `Flower examples `_ for details." +"One of the recommended virtual environment is `pyenv " +"`_/`virtualenv `_. Please see `Flower examples " +"`_ for details." msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 @@ -1142,15 +1056,15 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" -"The Flower examples are based on `Poetry `_ " -"to manage dependencies. After installing Poetry you simply create a virtual " -"environment with:" +"The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " +"simply create a virtual environment with:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" -"If you open a new terminal you can activate the previously created virtual " -"environment with the following command:" +"If you open a new terminal you can activate the previously created " +"virtual environment with the following command:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 @@ -1159,10 +1073,10 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" -"If you prefer to use Anaconda for your virtual environment then install and " -"setup the `conda `_ package. After setting it up you can create a virtual " -"environment with:" +"If you prefer to use Anaconda for your virtual environment then install " +"and setup the `conda `_ package. After setting it up you can " +"create a virtual environment with:" msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:68 @@ -1175,8 +1089,8 @@ msgstr "" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" -"As soon as you created your virtual environment you clone one of the `Flower " -"examples `_." +"As soon as you created your virtual environment you clone one of the " +"`Flower examples `_." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:2 @@ -1189,17 +1103,18 @@ msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" -"The Flower documentation lives in the ``doc`` directory. The Sphinx-based " -"documentation system supports both reStructuredText (``.rst`` files) and " -"Markdown (``.md`` files)." +"The Flower documentation lives in the ``doc`` directory. The Sphinx-based" +" documentation system supports both reStructuredText (``.rst`` files) and" +" Markdown (``.md`` files)." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:10 #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 msgid "" -"Note that, in order to build the documentation locally (with ``poetry run " -"make html``, like described below), `Pandoc `_ needs to be installed on the system." +"Note that, in order to build the documentation locally (with ``poetry run" +" make html``, like described below), `Pandoc " +"`_ needs to be installed on the " +"system." msgstr "" #: ../../source/contributor-how-to-write-documentation.rst:14 @@ -1242,10 +1157,10 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" -"We welcome contributions to Flower! However, it is not always easy to know " -"where to start. We therefore put together a few recommendations on where to " -"start to increase your chances of getting your PR accepted into the Flower " -"codebase." +"We welcome contributions to Flower! However, it is not always easy to " +"know where to start. We therefore put together a few recommendations on " +"where to start to increase your chances of getting your PR accepted into " +"the Flower codebase." msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:11 @@ -1254,9 +1169,9 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" -"Until the Flower core library matures it will be easier to get PR's accepted " -"if they only touch non-core areas of the codebase. Good candidates to get " -"started are:" +"Until the Flower core library matures it will be easier to get PR's " +"accepted if they only touch non-core areas of the codebase. Good " +"candidates to get started are:" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:17 @@ -1277,23 +1192,24 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:25 msgid "" -"If you are not familiar with Flower Baselines, you should probably check-out " -"our `contributing guide for baselines `_." +"If you are not familiar with Flower Baselines, you should probably check-" +"out our `contributing guide for baselines " +"`_." msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:27 msgid "" -"You should then check out the open `issues `_ for baseline " -"requests. If you find a baseline that you'd like to work on and that has no " -"assignees, feel free to assign it to yourself and start working on it!" +"You should then check out the open `issues " +"`_" +" for baseline requests. If you find a baseline that you'd like to work on" +" and that has no assignees, feel free to assign it to yourself and start " +"working on it!" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" -"Otherwise, if you don't find a baseline you'd like to work on, be sure to " -"open a new issue with the baseline request template!" +"Otherwise, if you don't find a baseline you'd like to work on, be sure to" +" open a new issue with the baseline request template!" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:34 @@ -1303,8 +1219,8 @@ msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" "We wish we had more time to write usage examples because we believe they " -"help users to get started with building what they want to build. Here are a " -"few ideas where we'd be happy to accept a PR:" +"help users to get started with building what they want to build. Here are" +" a few ideas where we'd be happy to accept a PR:" msgstr "" #: ../../source/contributor-ref-good-first-contributions.rst:40 @@ -1325,10 +1241,10 @@ msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" -"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg protocol " -"has not been implemented yet, so its diagram and abstraction may not be " -"accurate in practice. The SecAgg protocol can be considered as a special " -"case of the SecAgg+ protocol." +"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg " +"protocol has not been implemented yet, so its diagram and abstraction may" +" not be accurate in practice. The SecAgg protocol can be considered as a " +"special case of the SecAgg+ protocol." msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 @@ -1339,15 +1255,15 @@ msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 msgid "" "In this implementation, each client will be assigned with a unique index " -"(int) for secure aggregation, and thus many python dictionaries used have " -"keys of int type rather than ClientProxy type." +"(int) for secure aggregation, and thus many python dictionaries used have" +" keys of int type rather than ClientProxy type." msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" -"The Flower server will execute and process received results in the following " -"order:" +"The Flower server will execute and process received results in the " +"following order:" msgstr "" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 @@ -1364,15 +1280,15 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" -"This guide is for people who want to get involved with Flower, but who are " -"not used to contributing to GitHub projects." +"This guide is for people who want to get involved with Flower, but who " +"are not used to contributing to GitHub projects." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:6 msgid "" -"If you're familiar with how contributing on GitHub works, you can directly " -"checkout our :doc:`getting started guide for contributors `." +"If you're familiar with how contributing on GitHub works, you can " +"directly checkout our :doc:`getting started guide for contributors " +"`." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:10 @@ -1388,15 +1304,15 @@ msgid "" "Git is a distributed version control tool. This allows for an entire " "codebase's history to be stored and every developer's machine. It is a " "software that will need to be installed on your local machine, you can " -"follow this `guide `_ to set it up." +"follow this `guide `_ to set it up." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" "GitHub, itself, is a code hosting platform for version control and " -"collaboration. It allows for everyone to collaborate and work from anywhere " -"on remote repositories." +"collaboration. It allows for everyone to collaborate and work from " +"anywhere on remote repositories." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:18 @@ -1407,10 +1323,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" -"The idea behind the generic Git and GitHub workflow boils down to this: you " -"download code from a remote repository on GitHub, make changes locally and " -"keep track of them using Git and then you upload your new history back to " -"GitHub." +"The idea behind the generic Git and GitHub workflow boils down to this: " +"you download code from a remote repository on GitHub, make changes " +"locally and keep track of them using Git and then you upload your new " +"history back to GitHub." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:32 @@ -1419,18 +1335,18 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 msgid "" -"A fork is a personal copy of a GitHub repository. To create one for Flower, " -"you must navigate to ``_ (while connected to " -"your GitHub account) and click the ``Fork`` button situated on the top right " -"of the page." +"A fork is a personal copy of a GitHub repository. To create one for " +"Flower, you must navigate to ``_ (while " +"connected to your GitHub account) and click the ``Fork`` button situated " +"on the top right of the page." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" "You can change the name if you want, but this is not necessary as this " -"version of Flower will be yours and will sit inside your own account (i.e., " -"in your own list of repositories). Once created, you should see on the top " -"left corner that you are looking at your own version of Flower." +"version of Flower will be yours and will sit inside your own account " +"(i.e., in your own list of repositories). Once created, you should see on" +" the top left corner that you are looking at your own version of Flower." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 @@ -1440,9 +1356,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" "The next step is to download the forked repository on your machine to be " -"able to make changes to it. On your forked repository page, you should first " -"click on the ``Code`` button on the right, this will give you the ability to " -"copy the HTTPS link of the repository." +"able to make changes to it. On your forked repository page, you should " +"first click on the ``Code`` button on the right, this will give you the " +"ability to copy the HTTPS link of the repository." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:41 @@ -1453,8 +1369,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "" -"This will create a ``flower/`` (or the name of your fork if you renamed it) " -"folder in the current working directory." +"This will create a ``flower/`` (or the name of your fork if you renamed " +"it) folder in the current working directory." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:66 @@ -1467,10 +1383,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" -"And here we will need to add an origin to our repository. The origin is the " -"\\ of the remote fork repository. To obtain it, we can do as " -"previously mentioned by going to our fork repository on our GitHub account " -"and copying the link." +"And here we will need to add an origin to our repository. The origin is " +"the \\ of the remote fork repository. To obtain it, we can do as " +"previously mentioned by going to our fork repository on our GitHub " +"account and copying the link." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:61 @@ -1490,16 +1406,16 @@ msgid "" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 -msgid "" -"The following diagram visually explains what we did in the previous steps:" +msgid "The following diagram visually explains what we did in the previous steps:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" -"The upstream is the GitHub remote address of the parent repository (in this " -"case Flower), i.e. the one we eventually want to contribute to and therefore " -"need an up-to-date history of. The origin is just the GitHub remote address " -"of the forked repository we created, i.e. the copy (fork) in our own account." +"The upstream is the GitHub remote address of the parent repository (in " +"this case Flower), i.e. the one we eventually want to contribute to and " +"therefore need an up-to-date history of. The origin is just the GitHub " +"remote address of the forked repository we created, i.e. the copy (fork) " +"in our own account." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:84 @@ -1515,9 +1431,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:95 msgid "" "This can be achieved by following this :doc:`getting started guide for " -"contributors ` (note that " -"you won't need to clone the repository). Once you are able to write code and " -"test it, you can finally start making changes!" +"contributors ` (note " +"that you won't need to clone the repository). Once you are able to write " +"code and test it, you can finally start making changes!" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 @@ -1526,7 +1442,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" -"Before making any changes make sure you are up-to-date with your repository:" +"Before making any changes make sure you are up-to-date with your " +"repository:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 @@ -1539,13 +1456,15 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" -"To make the history cleaner and easier to work with, it is good practice to " -"create a new branch for each feature/project that needs to be implemented." +"To make the history cleaner and easier to work with, it is good practice " +"to create a new branch for each feature/project that needs to be " +"implemented." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" -"To do so, just run the following command inside the repository's directory:" +"To do so, just run the following command inside the repository's " +"directory:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 @@ -1553,8 +1472,7 @@ msgid "**Make changes**" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 -msgid "" -"Write great code and create wonderful changes using your favorite editor!" +msgid "Write great code and create wonderful changes using your favorite editor!" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 @@ -1563,9 +1481,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" -"Don't forget to test and format your code! Otherwise your code won't be able " -"to be merged into the Flower repository. This is done so the codebase stays " -"consistent and easy to understand." +"Don't forget to test and format your code! Otherwise your code won't be " +"able to be merged into the Flower repository. This is done so the " +"codebase stays consistent and easy to understand." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:131 @@ -1578,8 +1496,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" -"Before creating a commit that will update your history, you must specify to " -"Git which files it needs to take into account." +"Before creating a commit that will update your history, you must specify " +"to Git which files it needs to take into account." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:143 @@ -1588,9 +1506,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" -"To check which files have been modified compared to the last version (last " -"commit) and to see which files are staged for commit, you can use the :code:" -"`git status` command." +"To check which files have been modified compared to the last version " +"(last commit) and to see which files are staged for commit, you can use " +"the :code:`git status` command." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:160 @@ -1605,9 +1523,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" -"The \\ is there to explain to others what the commit does. " -"It should be written in an imperative style and be concise. An example would " -"be :code:`git commit -m \"Add images to README\"`." +"The \\ is there to explain to others what the commit " +"does. It should be written in an imperative style and be concise. An " +"example would be :code:`git commit -m \"Add images to README\"`." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:171 @@ -1616,9 +1534,9 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" -"Once we have committed our changes, we have effectively updated our local " -"history, but GitHub has no way of knowing this unless we push our changes to " -"our origin's remote address:" +"Once we have committed our changes, we have effectively updated our local" +" history, but GitHub has no way of knowing this unless we push our " +"changes to our origin's remote address:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 @@ -1637,8 +1555,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" -"Once you have pushed changes, on the GitHub webpage of your repository you " -"should see the following message:" +"Once you have pushed changes, on the GitHub webpage of your repository " +"you should see the following message:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 @@ -1652,29 +1570,29 @@ msgid "" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 -msgid "" -"At the top you have an explanation of which branch will be merged where:" +msgid "At the top you have an explanation of which branch will be merged where:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" -"In this example you can see that the request is to merge the branch ``doc-" -"fixes`` from my forked repository to branch ``main`` from the Flower " -"repository." +"In this example you can see that the request is to merge the branch " +"``doc-fixes`` from my forked repository to branch ``main`` from the " +"Flower repository." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" "The title should be changed to adhere to the :ref:`pr_title_format` " -"guidelines, otherwise it won't be possible to merge the PR. So in this case, " -"a correct title might be ``docs(framework:skip) Fix typos``." +"guidelines, otherwise it won't be possible to merge the PR. So in this " +"case, a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" -"The input box in the middle is there for you to describe what your PR does " -"and to link it to existing issues. We have placed comments (that won't be " -"rendered once the PR is opened) to guide you through the process." +"The input box in the middle is there for you to describe what your PR " +"does and to link it to existing issues. We have placed comments (that " +"won't be rendered once the PR is opened) to guide you through the " +"process." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:199 @@ -1684,14 +1602,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " -"reviewers that a new PR has been opened and that they should look over it to " -"merge or to request changes." +"reviewers that a new PR has been opened and that they should look over it" +" to merge or to request changes." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" -"If your PR is not yet ready for review, and you don't want to notify anyone, " -"you have the option to create a draft pull request:" +"If your PR is not yet ready for review, and you don't want to notify " +"anyone, you have the option to create a draft pull request:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 @@ -1701,8 +1619,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " -"commits to it the same way we did before, by making changes to the branch " -"associated with the PR." +"commits to it the same way we did before, by making changes to the branch" +" associated with the PR." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:231 @@ -1711,14 +1629,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" -"Once the PR has been opened or once the draft PR has been marked as ready, a " -"review from code owners will be automatically requested:" +"Once the PR has been opened or once the draft PR has been marked as " +"ready, a review from code owners will be automatically requested:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" -"Code owners will then look into the code, ask questions, request changes or " -"validate the PR." +"Code owners will then look into the code, ask questions, request changes " +"or validate the PR." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:218 @@ -1727,8 +1645,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" -"To resolve them, just push the necessary changes to the branch associated " -"with the PR:" +"To resolve them, just push the necessary changes to the branch associated" +" with the PR:" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:226 @@ -1737,7 +1655,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" -"Once all the conversations have been resolved, you can re-request a review." +"Once all the conversations have been resolved, you can re-request a " +"review." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:251 @@ -1746,8 +1665,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" -"If all the automatic tests have passed and reviewers have no more changes to " -"request, they can approve the PR and merge it." +"If all the automatic tests have passed and reviewers have no more changes" +" to request, they can approve the PR and merge it." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:238 @@ -1770,14 +1689,14 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" -"For our documentation, we've started to use the `Diàtaxis framework `_." +"For our documentation, we've started to use the `Diàtaxis framework " +"`_." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" -"Our \"How to\" guides should have titles that continue the sentence \"How to " -"…\", for example, \"How to upgrade to Flower 1.0\"." +"Our \"How to\" guides should have titles that continue the sentence \"How" +" to …\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:263 @@ -1788,8 +1707,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" -"This issue is about changing the title of a doc from present continuous to " -"present simple." +"This issue is about changing the title of a doc from present continuous " +"to present simple." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:267 @@ -1828,8 +1747,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" -"Build the docs and `check the result `_" +"Build the docs and `check the result `_" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:283 @@ -1838,10 +1757,10 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" -"You might have noticed that the file name still reflects the old wording. If " -"we just change the file, then we break all existing links to it - it is " -"**very important** to avoid that, breaking links can harm our search engine " -"ranking." +"You might have noticed that the file name still reflects the old wording." +" If we just change the file, then we break all existing links to it - it " +"is **very important** to avoid that, breaking links can harm our search " +"engine ranking." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:288 @@ -1858,8 +1777,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" -"This will cause a redirect from ``saving-progress.html`` to ``save-progress." -"html``, old links will continue to work." +"This will cause a redirect from ``saving-progress.html`` to ``save-" +"progress.html``, old links will continue to work." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:296 @@ -1883,8 +1802,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" -"Commit the changes (commit messages are always imperative: \"Do something\", " -"in this case \"Change …\")" +"Commit the changes (commit messages are always imperative: \"Do " +"something\", in this case \"Change …\")" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:307 @@ -1893,8 +1812,8 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 msgid "" -"Open a PR (as shown above) with title ``docs(framework) Update how-to guide " -"title``" +"Open a PR (as shown above) with title ``docs(framework) Update how-to " +"guide title``" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 @@ -1916,14 +1835,15 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" -"Once you have made your first PR, and want to contribute more, be sure to " -"check out the following :" +"Once you have made your first PR, and want to contribute more, be sure to" +" check out the following :" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" -":doc:`Good first contributions `, " -"where you should particularly look into the :code:`baselines` contributions." +":doc:`Good first contributions `, where you should particularly look into the " +":code:`baselines` contributions." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:322 @@ -1941,16 +1861,17 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"(or ``(:skip) `` to ignore the PR in the changelog)" +"(or ``(:skip) `` to ignore the PR in the " +"changelog)" msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, break}``, " -"```` should be in ``{framework, baselines, datasets, examples, or " -"'*' when modifying multiple projects which requires the ':skip' flag to be " -"used}``, and ```` starts with a capitalised verb in the imperative " -"mood." +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " +"break}``, ```` should be in ``{framework, baselines, datasets, " +"examples, or '*' when modifying multiple projects which requires the " +"':skip' flag to be used}``, and ```` starts with a capitalised " +"verb in the imperative mood." msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:341 @@ -2004,7 +1925,7 @@ msgid "Get started as a contributor" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 -#: ../../source/how-to-run-flower-using-docker.rst:132 +#: ../../source/how-to-run-flower-using-docker.rst:153 msgid "Prerequisites" msgstr "" @@ -2021,15 +1942,14 @@ msgid "(Optional) `pyenv `_" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 -msgid "" -"(Optional) `pyenv-virtualenv `_" +msgid "(Optional) `pyenv-virtualenv `_" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 msgid "" "Flower uses :code:`pyproject.toml` to manage dependencies and configure " -"development tools (the ones which support it). Poetry is a build tool which " -"supports `PEP 517 `_." +"development tools (the ones which support it). Poetry is a build tool " +"which supports `PEP 517 `_." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 @@ -2050,14 +1970,14 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 msgid "" -"Install `homebrew `_. Don't forget the post-installation " -"actions to add `brew` to your PATH." +"Install `homebrew `_. Don't forget the post-" +"installation actions to add `brew` to your PATH." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 msgid "" -"Install `xz` (to install different Python versions) and `pandoc` to build " -"the docs::" +"Install `xz` (to install different Python versions) and `pandoc` to build" +" the docs::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 @@ -2066,8 +1986,8 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 msgid "" -"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all necessary " -"packages::" +"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " +"necessary packages::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 @@ -2082,31 +2002,31 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 msgid "" -"Let's create the Python environment for all-things Flower. If you wish to " -"use :code:`pyenv`, we provide two convenience scripts that you can use. If " -"you prefer using something else than :code:`pyenv`, create a new " +"Let's create the Python environment for all-things Flower. If you wish to" +" use :code:`pyenv`, we provide two convenience scripts that you can use. " +"If you prefer using something else than :code:`pyenv`, create a new " "environment, activate and skip to the last point where all packages are " "installed." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 msgid "" -"If you don't have :code:`pyenv` installed, the following script that will " -"install it, set it up, and create the virtual environment (with :code:" -"`Python 3.8.17` by default)::" +"If you don't have :code:`pyenv` installed, the following script that will" +" install it, set it up, and create the virtual environment (with " +":code:`Python 3.8.17` by default)::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 msgid "" "If you already have :code:`pyenv` installed (along with the :code:`pyenv-" -"virtualenv` plugin), you can use the following convenience script (with :" -"code:`Python 3.8.17` by default)::" +"virtualenv` plugin), you can use the following convenience script (with " +":code:`Python 3.8.17` by default)::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 msgid "" -"3. Install the Flower package in development mode (think :code:`pip install -" -"e`) along with all necessary dependencies::" +"3. Install the Flower package in development mode (think :code:`pip " +"install -e`) along with all necessary dependencies::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 @@ -2116,9 +2036,9 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" "The Flower repository contains a number of convenience scripts to make " -"recurring development tasks easier and less error-prone. See the :code:`/" -"dev` subdirectory for a full list. The following scripts are amongst the " -"most important ones:" +"recurring development tasks easier and less error-prone. See the " +":code:`/dev` subdirectory for a full list. The following scripts are " +"amongst the most important ones:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 @@ -2143,10 +2063,10 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 msgid "" -"Developers may integrate a pre-commit hook into their workflow utilizing the " -"`pre-commit `_ library. The pre-commit hook " -"is configured to execute two primary operations: ``./dev/format.sh`` and ``./" -"dev/test.sh`` scripts." +"Developers may integrate a pre-commit hook into their workflow utilizing " +"the `pre-commit `_ library. The pre-" +"commit hook is configured to execute two primary operations: " +"``./dev/format.sh`` and ``./dev/test.sh`` scripts." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 @@ -2154,27 +2074,26 @@ msgid "There are multiple ways developers can use this:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 -msgid "" -"Install the pre-commit hook to your local git directory by simply running:" +msgid "Install the pre-commit hook to your local git directory by simply running:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 msgid "" -"Each ``git commit`` will trigger the execution of formatting and linting/" -"test scripts." +"Each ``git commit`` will trigger the execution of formatting and " +"linting/test scripts." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 msgid "" -"If in a hurry, bypass the hook using ``--no-verify`` with the ``git commit`` " -"command. ::" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " +"commit`` command. ::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 msgid "" "For developers who prefer not to install the hook permanently, it is " -"possible to execute a one-time check prior to committing changes by using " -"the following command:" +"possible to execute a one-time check prior to committing changes by using" +" the following command:" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 @@ -2189,10 +2108,10 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 msgid "" -"Developers could run the full set of Github Actions workflows under their " -"local environment by using `Act `_. Please " -"refer to the installation instructions under the linked repository and run " -"the next command under Flower main cloned repository folder::" +"Developers could run the full set of Github Actions workflows under their" +" local environment by using `Act `_. " +"Please refer to the installation instructions under the linked repository" +" and run the next command under Flower main cloned repository folder::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 @@ -2207,14 +2126,14 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" -"Flower uses Poetry to build releases. The necessary command is wrapped in a " -"simple script::" +"Flower uses Poetry to build releases. The necessary command is wrapped in" +" a simple script::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" -"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in " -"the :code:`/dist` subdirectory." +"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" +" the :code:`/dist` subdirectory." msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 @@ -2223,9 +2142,9 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" -"Flower's documentation uses `Sphinx `_. There's " -"no convenience script to re-build the documentation yet, but it's pretty " -"easy::" +"Flower's documentation uses `Sphinx `_. " +"There's no convenience script to re-build the documentation yet, but it's" +" pretty easy::" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 @@ -2238,13 +2157,14 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing machine learning workload with `FedBN `_, a federated training strategy designed for non-iid data. We " -"are using PyTorch to train a Convolutional Neural Network(with Batch " -"Normalization layers) on the CIFAR-10 dataset. When applying FedBN, only few " -"changes needed compared to :doc:`Example: PyTorch - From Centralized To " -"Federated `." +"This tutorial will show you how to use Flower to build a federated " +"version of an existing machine learning workload with `FedBN " +"`_, a federated training strategy " +"designed for non-iid data. We are using PyTorch to train a Convolutional " +"Neural Network(with Batch Normalization layers) on the CIFAR-10 dataset. " +"When applying FedBN, only few changes needed compared to :doc:`Example: " +"PyTorch - From Centralized To Federated `." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 @@ -2254,10 +2174,10 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 msgid "" -"All files are revised based on :doc:`Example: PyTorch - From Centralized To " -"Federated `. The only thing " -"to do is modifying the file called :code:`cifar.py`, revised part is shown " -"below:" +"All files are revised based on :doc:`Example: PyTorch - From Centralized " +"To Federated `. The only " +"thing to do is modifying the file called :code:`cifar.py`, revised part " +"is shown below:" msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:13 @@ -2273,10 +2193,10 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 msgid "" -"So far this should all look fairly familiar if you've used PyTorch before. " -"Let's take the next step and use what we've built to create a federated " -"learning system within FedBN, the system consists of one server and two " -"clients." +"So far this should all look fairly familiar if you've used PyTorch " +"before. Let's take the next step and use what we've built to create a " +"federated learning system within FedBN, the system consists of one server" +" and two clients." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 @@ -2287,25 +2207,25 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:53 msgid "" "If you have read :doc:`Example: PyTorch - From Centralized To Federated " -"`, the following parts are " -"easy to follow, only :code:`get_parameters` and :code:`set_parameters` " -"function in :code:`client.py` needed to revise. If not, please read the :doc:" -"`Example: PyTorch - From Centralized To Federated `. first." +"`, the following parts are" +" easy to follow, only :code:`get_parameters` and :code:`set_parameters` " +"function in :code:`client.py` needed to revise. If not, please read the " +":doc:`Example: PyTorch - From Centralized To Federated `. first." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" -"Our example consists of one *server* and two *clients*. In FedBN, :code:" -"`server.py` keeps unchanged, we can start the server directly." +"Our example consists of one *server* and two *clients*. In FedBN, " +":code:`server.py` keeps unchanged, we can start the server directly." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" -"Finally, we will revise our *client* logic by changing :code:" -"`get_parameters` and :code:`set_parameters` in :code:`client.py`, we will " -"exclude batch normalization parameters from model parameter list when " -"sending to or receiving from the server." +"Finally, we will revise our *client* logic by changing " +":code:`get_parameters` and :code:`set_parameters` in :code:`client.py`, " +"we will exclude batch normalization parameters from model parameter list " +"when sending to or receiving from the server." msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 @@ -2314,9 +2234,9 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" -"in each window (make sure that the server is still running before you do so) " -"and see your (previously centralized) PyTorch project run federated learning " -"with FedBN strategy across two clients. Congratulations!" +"in each window (make sure that the server is still running before you do " +"so) and see your (previously centralized) PyTorch project run federated " +"learning with FedBN strategy across two clients. Congratulations!" msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 @@ -2328,12 +2248,13 @@ msgstr "" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" -"The full source code for this example can be found `here `_. Our " -"example is of course somewhat over-simplified because both clients load the " -"exact same dataset, which isn't realistic. You're now prepared to explore " -"this topic further. How about using different subsets of CIFAR-10 on each " -"client? How about adding more clients?" +"The full source code for this example can be found `here " +"`_. Our example is of course somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using different subsets of CIFAR-10 on each client? How about adding more" +" clients?" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:2 @@ -2343,22 +2264,23 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing JAX workload. We are using JAX to train a linear regression " -"model on a scikit-learn dataset. We will structure the example similar to " -"our `PyTorch - From Centralized To Federated `_ walkthrough. " -"First, we build a centralized training approach based on the `Linear " -"Regression with JAX `_ tutorial`. Then, we build upon the centralized " -"training code to run the training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated " +"version of an existing JAX workload. We are using JAX to train a linear " +"regression model on a scikit-learn dataset. We will structure the example" +" similar to our `PyTorch - From Centralized To Federated " +"`_ walkthrough. First, we build a centralized " +"training approach based on the `Linear Regression with JAX " +"`_" +" tutorial`. Then, we build upon the centralized training code to run the " +"training in a federated fashion." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 msgid "" -"Before we start building our JAX example, we need install the packages :code:" -"`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" +"Before we start building our JAX example, we need install the packages " +":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:18 @@ -2369,10 +2291,10 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 msgid "" -"We begin with a brief description of the centralized training code based on " -"a :code:`Linear Regression` model. If you want a more in-depth explanation " -"of what's going on then have a look at the official `JAX documentation " -"`_." +"We begin with a brief description of the centralized training code based " +"on a :code:`Linear Regression` model. If you want a more in-depth " +"explanation of what's going on then have a look at the official `JAX " +"documentation `_." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:23 @@ -2380,51 +2302,53 @@ msgstr "" msgid "" "Let's create a new file called :code:`jax_training.py` with all the " "components required for a traditional (centralized) linear regression " -"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to be " -"imported. In addition, we need to import :code:`sklearn` since we use :code:" -"`make_regression` for the dataset and :code:`train_test_split` to split the " -"dataset into a training and test set. You can see that we do not yet import " -"the :code:`flwr` package for federated learning. This will be done later." +"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to " +"be imported. In addition, we need to import :code:`sklearn` since we use " +":code:`make_regression` for the dataset and :code:`train_test_split` to " +"split the dataset into a training and test set. You can see that we do " +"not yet import the :code:`flwr` package for federated learning. This will" +" be done later." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" -"The :code:`load_data()` function loads the mentioned training and test sets." +"The :code:`load_data()` function loads the mentioned training and test " +"sets." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" -"The model architecture (a very simple :code:`Linear Regression` model) is " -"defined in :code:`load_model()`." +"The model architecture (a very simple :code:`Linear Regression` model) is" +" defined in :code:`load_model()`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 msgid "" -"We now need to define the training (function :code:`train()`), which loops " -"over the training set and measures the loss (function :code:`loss_fn()`) for " -"each batch of training examples. The loss function is separate since JAX " -"takes derivatives with a :code:`grad()` function (defined in the :code:" -"`main()` function and called in :code:`train()`)." +"We now need to define the training (function :code:`train()`), which " +"loops over the training set and measures the loss (function " +":code:`loss_fn()`) for each batch of training examples. The loss function" +" is separate since JAX takes derivatives with a :code:`grad()` function " +"(defined in the :code:`main()` function and called in :code:`train()`)." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 msgid "" -"The evaluation of the model is defined in the function :code:`evaluation()`. " -"The function takes all test examples and measures the loss of the linear " -"regression model." +"The evaluation of the model is defined in the function " +":code:`evaluation()`. The function takes all test examples and measures " +"the loss of the linear regression model." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:88 #: ../../source/tutorial-quickstart-jax.rst:94 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model using JAX. As " -"already mentioned, the :code:`jax.grad()` function is defined in :code:" -"`main()` and passed to :code:`train()`." +"evaluation we can put everything together and train our model using JAX. " +"As already mentioned, the :code:`jax.grad()` function is defined in " +":code:`main()` and passed to :code:`train()`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:105 @@ -2435,9 +2359,9 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 msgid "" -"So far this should all look fairly familiar if you've used JAX before. Let's " -"take the next step and use what we've built to create a simple federated " -"learning system consisting of one server and two clients." +"So far this should all look fairly familiar if you've used JAX before. " +"Let's take the next step and use what we've built to create a simple " +"federated learning system consisting of one server and two clients." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:115 @@ -2448,24 +2372,24 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 msgid "" -"The concept of federating an existing workload is always the same and easy " -"to understand. We have to start a *server* and then use the code in :code:" -"`jax_training.py` for the *clients* that are connected to the *server*. The " -"*server* sends model parameters to the clients. The *clients* run the " -"training and update the parameters. The updated parameters are sent back to " -"the *server*, which averages all received parameter updates. This describes " -"one round of the federated learning process, and we repeat this for multiple " -"rounds." +"The concept of federating an existing workload is always the same and " +"easy to understand. We have to start a *server* and then use the code in " +":code:`jax_training.py` for the *clients* that are connected to the " +"*server*. The *server* sends model parameters to the clients. The " +"*clients* run the training and update the parameters. The updated " +"parameters are sent back to the *server*, which averages all received " +"parameter updates. This describes one round of the federated learning " +"process, and we repeat this for multiple rounds." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:123 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" -"Our example consists of one *server* and two *clients*. Let's set up :code:" -"`server.py` first. The *server* needs to import the Flower package :code:" -"`flwr`. Next, we use the :code:`start_server` function to start a server and " -"tell it to perform three rounds of federated learning." +"Our example consists of one *server* and two *clients*. Let's set up " +":code:`server.py` first. The *server* needs to import the Flower package " +":code:`flwr`. Next, we use the :code:`start_server` function to start a " +"server and tell it to perform three rounds of federated learning." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:133 @@ -2477,24 +2401,25 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build " -"upon the previously defined JAX training in :code:`jax_training.py`. Our " -"*client* needs to import :code:`flwr`, but also :code:`jax` and :code:" -"`jaxlib` to update the parameters on our JAX model:" +"Finally, we will define our *client* logic in :code:`client.py` and build" +" upon the previously defined JAX training in :code:`jax_training.py`. Our" +" *client* needs to import :code:`flwr`, but also :code:`jax` and " +":code:`jaxlib` to update the parameters on our JAX model:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of " -"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " -"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " -"call it :code:`FlowerClient`. :code:`NumPyClient` is slightly easier to " -"implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like JAX) because it avoids some of the boilerplate that " -"would otherwise be necessary. :code:`FlowerClient` needs to implement four " -"methods, two methods for getting/setting model parameters, one method for " -"training the model, and one method for testing the model:" +"Implementing a Flower *client* basically means implementing a subclass of" +" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " +"Our implementation will be based on :code:`flwr.client.NumPyClient` and " +"we'll call it :code:`FlowerClient`. :code:`NumPyClient` is slightly " +"easier to implement than :code:`Client` if you use a framework with good " +"NumPy interoperability (like JAX) because it avoids some of the " +"boilerplate that would otherwise be necessary. :code:`FlowerClient` needs" +" to implement four methods, two methods for getting/setting model " +"parameters, one method for training the model, and one method for testing" +" the model:" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2506,7 +2431,8 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" -"set the model parameters on the local model that are received from the server" +"set the model parameters on the local model that are received from the " +"server" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2518,8 +2444,8 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" -"loop over the list of model parameters received as NumPy :code:`ndarray`'s " -"(think list of neural network layers)" +"loop over the list of model parameters received as NumPy " +":code:`ndarray`'s (think list of neural network layers)" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:163 @@ -2534,8 +2460,8 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" -"get the model parameters and return them as a list of NumPy :code:" -"`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" +"get the model parameters and return them as a list of NumPy " +":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2553,8 +2479,8 @@ msgstr "" #: ../../source/tutorial-quickstart-jax.rst:172 #: ../../source/tutorial-quickstart-jax.rst:176 msgid "" -"update the parameters of the local model with the parameters received from " -"the server" +"update the parameters of the local model with the parameters received " +"from the server" msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2590,20 +2516,21 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 msgid "" -"The challenging part is to transform the JAX model parameters from :code:" -"`DeviceArray` to :code:`NumPy ndarray` to make them compatible with " -"`NumPyClient`." +"The challenging part is to transform the JAX model parameters from " +":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" +" `NumPyClient`." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " -"use of the functions :code:`train()` and :code:`evaluate()` previously " +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" +" use of the functions :code:`train()` and :code:`evaluate()` previously " "defined in :code:`jax_training.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type annotations " -"to give you a better understanding of the data types that get passed around." +"Flower through our :code:`NumPyClient` subclass which of our already " +"defined functions to call for training and evaluation. We included type " +"annotations to give you a better understanding of the data types that get" +" passed around." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:245 @@ -2620,8 +2547,8 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:274 #: ../../source/tutorial-quickstart-jax.rst:280 msgid "" -"in each window (make sure that the server is still running before you do so) " -"and see your JAX project run federated learning across two clients. " +"in each window (make sure that the server is still running before you do " +"so) and see your JAX project run federated learning across two clients. " "Congratulations!" msgstr "" @@ -2629,16 +2556,16 @@ msgstr "" #: ../../source/tutorial-quickstart-jax.rst:285 msgid "" "The source code of this example was improved over time and can be found " -"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " +"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 msgid "" -"You're now prepared to explore this topic further. How about using a more " -"sophisticated model or using a different dataset? How about adding more " +"You're now prepared to explore this topic further. How about using a more" +" sophisticated model or using a different dataset? How about adding more " "clients?" msgstr "" @@ -2648,31 +2575,32 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated version " -"of an existing machine learning workload. We are using PyTorch to train a " -"Convolutional Neural Network on the CIFAR-10 dataset. First, we introduce " -"this machine learning task with a centralized training approach based on the " -"`Deep Learning with PyTorch `_ tutorial. Then, we build upon the centralized " -"training code to run the training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated " +"version of an existing machine learning workload. We are using PyTorch to" +" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " +"introduce this machine learning task with a centralized training approach" +" based on the `Deep Learning with PyTorch " +"`_ " +"tutorial. Then, we build upon the centralized training code to run the " +"training in a federated fashion." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"We begin with a brief description of the centralized CNN training code. If " -"you want a more in-depth explanation of what's going on then have a look at " -"the official `PyTorch tutorial `_." +"We begin with a brief description of the centralized CNN training code. " +"If you want a more in-depth explanation of what's going on then have a " +"look at the official `PyTorch tutorial " +"`_." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" "Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all " -"required packages (such as :code:`torch` and :code:`torchvision`) need to be " -"imported. You can see that we do not import any package for federated " -"learning. You can keep all these imports as they are even when we add the " -"federated learning components at a later point." +"required for a traditional (centralized) training on CIFAR-10. First, all" +" required packages (such as :code:`torch` and :code:`torchvision`) need " +"to be imported. You can see that we do not import any package for " +"federated learning. You can keep all these imports as they are even when " +"we add the federated learning components at a later point." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 @@ -2684,22 +2612,22 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test sets. " -"The :code:`transform` normalized the data after loading." +"The :code:`load_data()` function loads the CIFAR-10 training and test " +"sets. The :code:`transform` normalized the data after loading." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" -"We now need to define the training (function :code:`train()`) which loops " -"over the training set, measures the loss, backpropagates it, and then takes " -"one optimizer step for each batch of training examples." +"We now need to define the training (function :code:`train()`) which loops" +" over the training set, measures the loss, backpropagates it, and then " +"takes one optimizer step for each batch of training examples." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in the function :code:`test()`. The " -"function loops over all test samples and measures the loss of the model " -"based on the test dataset." +"The evaluation of the model is defined in the function :code:`test()`. " +"The function loops over all test samples and measures the loss of the " +"model based on the test dataset." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 @@ -2710,59 +2638,60 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far, this should all look fairly familiar if you've used PyTorch before. " -"Let's take the next step and use what we've built to create a simple " -"federated learning system consisting of one server and two clients." +"So far, this should all look fairly familiar if you've used PyTorch " +"before. Let's take the next step and use what we've built to create a " +"simple federated learning system consisting of one server and two " +"clients." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" -"The simple machine learning project discussed in the previous section trains " -"the model on a single dataset (CIFAR-10), we call this centralized learning. " -"This concept of centralized learning, as shown in the previous section, is " -"probably known to most of you, and many of you have used it previously. " -"Normally, if you'd want to run machine learning workloads in a federated " -"fashion, then you'd have to change most of your code and set everything up " -"from scratch. This can be a considerable effort." +"The simple machine learning project discussed in the previous section " +"trains the model on a single dataset (CIFAR-10), we call this centralized" +" learning. This concept of centralized learning, as shown in the previous" +" section, is probably known to most of you, and many of you have used it " +"previously. Normally, if you'd want to run machine learning workloads in " +"a federated fashion, then you'd have to change most of your code and set " +"everything up from scratch. This can be a considerable effort." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"However, with Flower you can evolve your pre-existing code into a federated " -"learning setup without the need for a major rewrite." +"However, with Flower you can evolve your pre-existing code into a " +"federated learning setup without the need for a major rewrite." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept is easy to understand. We have to start a *server* and then use " -"the code in :code:`cifar.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The *clients* " -"run the training and update the parameters. The updated parameters are sent " -"back to the *server* which averages all received parameter updates. This " -"describes one round of the federated learning process and we repeat this for " -"multiple rounds." +"The concept is easy to understand. We have to start a *server* and then " +"use the code in :code:`cifar.py` for the *clients* that are connected to " +"the *server*. The *server* sends model parameters to the clients. The " +"*clients* run the training and update the parameters. The updated " +"parameters are sent back to the *server* which averages all received " +"parameter updates. This describes one round of the federated learning " +"process and we repeat this for multiple rounds." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build " -"upon the previously defined centralized training in :code:`cifar.py`. Our " -"*client* needs to import :code:`flwr`, but also :code:`torch` to update the " -"parameters on our PyTorch model:" +"Finally, we will define our *client* logic in :code:`client.py` and build" +" upon the previously defined centralized training in :code:`cifar.py`. " +"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " +"update the parameters on our PyTorch model:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of " -"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " -"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " -"call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier to " -"implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids some " -"of the boilerplate that would otherwise be necessary. :code:`CifarClient` " -"needs to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing " -"the model:" +"Implementing a Flower *client* basically means implementing a subclass of" +" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " +"Our implementation will be based on :code:`flwr.client.NumPyClient` and " +"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" +" to implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " +"some of the boilerplate that would otherwise be necessary. " +":code:`CifarClient` needs to implement four methods, two methods for " +"getting/setting model parameters, one method for training the model, and " +"one method for testing the model:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 @@ -2779,39 +2708,40 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " -"use of the functions :code:`train()` and :code:`test()` previously defined " -"in :code:`cifar.py`. So what we really do here is we tell Flower through " -"our :code:`NumPyClient` subclass which of our already defined functions to " -"call for training and evaluation. We included type annotations to give you a " -"better understanding of the data types that get passed around." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" +" use of the functions :code:`train()` and :code:`test()` previously " +"defined in :code:`cifar.py`. So what we really do here is we tell Flower " +"through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type " +"annotations to give you a better understanding of the data types that get" +" passed around." msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" "All that's left to do it to define a function that loads both model and " -"data, creates a :code:`CifarClient`, and starts this client. You load your " -"data and model by using :code:`cifar.py`. Start :code:`CifarClient` with the " -"function :code:`fl.client.start_client()` by pointing it at the same IP " -"address we used in :code:`server.py`:" +"data, creates a :code:`CifarClient`, and starts this client. You load " +"your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " +"with the function :code:`fl.client.start_client()` by pointing it at the " +"same IP address we used in :code:`server.py`:" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" -"in each window (make sure that the server is running before you do so) and " -"see your (previously centralized) PyTorch project run federated learning " -"across two clients. Congratulations!" +"in each window (make sure that the server is running before you do so) " +"and see your (previously centralized) PyTorch project run federated " +"learning across two clients. Congratulations!" msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" "The full source code for this example: `PyTorch: From Centralized To " -"Federated (Code) `_. Our example is, of course, somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using different subsets of CIFAR-10 on each client? How about adding more " -"clients?" +"Federated (Code) `_. Our example is, of course, " +"somewhat over-simplified because both clients load the exact same " +"dataset, which isn't realistic. You're now prepared to explore this topic" +" further. How about using different subsets of CIFAR-10 on each client? " +"How about adding more clients?" msgstr "" #: ../../source/explanation-differential-privacy.rst:2 @@ -2822,18 +2752,19 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:3 msgid "" -"The information in datasets like healthcare, financial transactions, user " -"preferences, etc., is valuable and has the potential for scientific " -"breakthroughs and provides important business insights. However, such data " -"is also sensitive and there is a risk of compromising individual privacy." +"The information in datasets like healthcare, financial transactions, user" +" preferences, etc., is valuable and has the potential for scientific " +"breakthroughs and provides important business insights. However, such " +"data is also sensitive and there is a risk of compromising individual " +"privacy." msgstr "" #: ../../source/explanation-differential-privacy.rst:6 msgid "" "Traditional methods like anonymization alone would not work because of " -"attacks like Re-identification and Data Linkage. That's where differential " -"privacy comes in. It provides the possibility of analyzing data while " -"ensuring the privacy of individuals." +"attacks like Re-identification and Data Linkage. That's where " +"differential privacy comes in. It provides the possibility of analyzing " +"data while ensuring the privacy of individuals." msgstr "" #: ../../source/explanation-differential-privacy.rst:12 @@ -2842,8 +2773,8 @@ msgid "" "instance, Alice's data). Differential Privacy (DP) guarantees that any " "analysis (M), like calculating the average income, will produce nearly " "identical results for both datasets (O and O' would be similar). This " -"preserves group patterns while obscuring individual details, ensuring the " -"individual's information remains hidden in the crowd." +"preserves group patterns while obscuring individual details, ensuring the" +" individual's information remains hidden in the crowd." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2854,7 +2785,8 @@ msgstr "" msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " -"individual in the data while preserving the overall accuracy of the analysis." +"individual in the data while preserving the overall accuracy of the " +"analysis." msgstr "" #: ../../source/explanation-differential-privacy.rst:25 @@ -2865,12 +2797,12 @@ msgstr "" msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " -"algorithm. It provides an unconditional upper bound on the influence of a " -"single individual on the output of the algorithm by adding noise [1]. A " -"randomized mechanism M provides (:math:`\\epsilon`, :math:`\\delta`)-" -"differential privacy if for any two neighboring databases, D :sub:`1` and D :" -"sub:`2`, that differ in only a single record, and for all possible outputs S " -"⊆ Range(A):" +"algorithm. It provides an unconditional upper bound on the influence of a" +" single individual on the output of the algorithm by adding noise [1]. A " +"randomized mechanism M provides (:math:`\\epsilon`, " +":math:`\\delta`)-differential privacy if for any two neighboring " +"databases, D :sub:`1` and D :sub:`2`, that differ in only a single " +"record, and for all possible outputs S ⊆ Range(A):" msgstr "" #: ../../source/explanation-differential-privacy.rst:32 @@ -2884,11 +2816,11 @@ msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " "lower :math:`\\epsilon` values indicate higher levels of privacy but are " -"likely to reduce utility as well. The :math:`\\delta` parameter accounts for " -"a small probability on which the upper bound :math:`\\epsilon` does not " -"hold. The amount of noise needed to achieve differential privacy is " -"proportional to the sensitivity of the output, which measures the maximum " -"change in the output due to the inclusion or removal of a single record." +"likely to reduce utility as well. The :math:`\\delta` parameter accounts " +"for a small probability on which the upper bound :math:`\\epsilon` does " +"not hold. The amount of noise needed to achieve differential privacy is " +"proportional to the sensitivity of the output, which measures the maximum" +" change in the output due to the inclusion or removal of a single record." msgstr "" #: ../../source/explanation-differential-privacy.rst:45 @@ -2899,14 +2831,15 @@ msgstr "" msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " -"designed in a way to prevent the algorithm to learn any specific information " -"about any individual data points and subsequently prevent the model from " -"revealing sensitive information. Depending on the stage at which noise is " -"introduced, various methods exist for applying DP to machine learning " -"algorithms. One approach involves adding noise to the training data (either " -"to the features or labels), while another method entails injecting noise " -"into the gradients of the loss function during model training. Additionally, " -"such noise can be incorporated into the model's output." +"designed in a way to prevent the algorithm to learn any specific " +"information about any individual data points and subsequently prevent the" +" model from revealing sensitive information. Depending on the stage at " +"which noise is introduced, various methods exist for applying DP to " +"machine learning algorithms. One approach involves adding noise to the " +"training data (either to the features or labels), while another method " +"entails injecting noise into the gradients of the loss function during " +"model training. Additionally, such noise can be incorporated into the " +"model's output." msgstr "" #: ../../source/explanation-differential-privacy.rst:53 @@ -2918,40 +2851,40 @@ msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " "However, federated learning also introduces new privacy challenges. The " -"model updates between parties and the central server can leak information " -"about the local data. These leaks can be exploited by attacks such as " +"model updates between parties and the central server can leak information" +" about the local data. These leaks can be exploited by attacks such as " "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" #: ../../source/explanation-differential-privacy.rst:58 msgid "" -"DP can play a crucial role in federated learning to provide privacy for the " -"clients' data." +"DP can play a crucial role in federated learning to provide privacy for " +"the clients' data." msgstr "" #: ../../source/explanation-differential-privacy.rst:60 msgid "" -"Depending on the granularity of privacy provision or the location of noise " -"addition, different forms of DP exist in federated learning. In this " -"explainer, we focus on two approaches of DP utilization in federated " -"learning based on where the noise is added: at the server (also known as the " -"center) or at the client (also known as the local)." +"Depending on the granularity of privacy provision or the location of " +"noise addition, different forms of DP exist in federated learning. In " +"this explainer, we focus on two approaches of DP utilization in federated" +" learning based on where the noise is added: at the server (also known as" +" the center) or at the client (also known as the local)." msgstr "" #: ../../source/explanation-differential-privacy.rst:63 msgid "" -"**Central Differential Privacy**: DP is applied by the server and the goal " -"is to prevent the aggregated model from leaking information about each " -"client's data." +"**Central Differential Privacy**: DP is applied by the server and the " +"goal is to prevent the aggregated model from leaking information about " +"each client's data." msgstr "" #: ../../source/explanation-differential-privacy.rst:65 msgid "" "**Local Differential Privacy**: DP is applied on the client side before " -"sending any information to the server and the goal is to prevent the updates " -"that are sent to the server from leaking any information about the client's " -"data." +"sending any information to the server and the goal is to prevent the " +"updates that are sent to the server from leaking any information about " +"the client's data." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2962,24 +2895,24 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:69 msgid "" -"In this approach, which is also known as user-level DP, the central server " -"is responsible for adding noise to the globally aggregated parameters. It " -"should be noted that trust in the server is required." +"In this approach, which is also known as user-level DP, the central " +"server is responsible for adding noise to the globally aggregated " +"parameters. It should be noted that trust in the server is required." msgstr "" #: ../../source/explanation-differential-privacy.rst:76 msgid "" -"While there are various ways to implement central DP in federated learning, " -"we concentrate on the algorithms proposed by [2] and [3]. The overall " -"approach is to clip the model updates sent by the clients and add some " -"amount of noise to the aggregated model. In each iteration, a random set of " -"clients is chosen with a specific probability for training. Each client " -"performs local training on its own data. The update of each client is then " -"clipped by some value `S` (sensitivity `S`). This would limit the impact of " -"any individual client which is crucial for privacy and often beneficial for " -"robustness. A common approach to achieve this is by restricting the `L2` " -"norm of the clients' model updates, ensuring that larger updates are scaled " -"down to fit within the norm `S`." +"While there are various ways to implement central DP in federated " +"learning, we concentrate on the algorithms proposed by [2] and [3]. The " +"overall approach is to clip the model updates sent by the clients and add" +" some amount of noise to the aggregated model. In each iteration, a " +"random set of clients is chosen with a specific probability for training." +" Each client performs local training on its own data. The update of each " +"client is then clipped by some value `S` (sensitivity `S`). This would " +"limit the impact of any individual client which is crucial for privacy " +"and often beneficial for robustness. A common approach to achieve this is" +" by restricting the `L2` norm of the clients' model updates, ensuring " +"that larger updates are scaled down to fit within the norm `S`." msgstr "" #: ../../source/explanation-differential-privacy.rst:-1 @@ -2988,11 +2921,11 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:89 msgid "" -"Afterwards, the Gaussian mechanism is used to add noise in order to distort " -"the sum of all clients' updates. The amount of noise is scaled to the " -"sensitivity value to obtain a privacy guarantee. The Gaussian mechanism is " -"used with a noise sampled from `N (0, σ²)` where `σ = ( noise_scale * S ) / " -"(number of sampled clients)`." +"Afterwards, the Gaussian mechanism is used to add noise in order to " +"distort the sum of all clients' updates. The amount of noise is scaled to" +" the sensitivity value to obtain a privacy guarantee. The Gaussian " +"mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " +"noise_scale * S ) / (number of sampled clients)`." msgstr "" #: ../../source/explanation-differential-privacy.rst:94 @@ -3001,29 +2934,29 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:96 msgid "" -"There are two forms of clipping commonly used in Central DP: Fixed Clipping " -"and Adaptive Clipping." +"There are two forms of clipping commonly used in Central DP: Fixed " +"Clipping and Adaptive Clipping." msgstr "" #: ../../source/explanation-differential-privacy.rst:98 msgid "" -"**Fixed Clipping** : A predefined fix threshold is set for the magnitude of " -"clients' updates. Any update exceeding this threshold is clipped back to the " -"threshold value." +"**Fixed Clipping** : A predefined fix threshold is set for the magnitude " +"of clients' updates. Any update exceeding this threshold is clipped back " +"to the threshold value." msgstr "" #: ../../source/explanation-differential-privacy.rst:100 msgid "" -"**Adaptive Clipping** : The clipping threshold dynamically adjusts based on " -"the observed update distribution [4]. It means that the clipping value is " -"tuned during the rounds with respect to the quantile of the update norm " -"distribution." +"**Adaptive Clipping** : The clipping threshold dynamically adjusts based " +"on the observed update distribution [4]. It means that the clipping value" +" is tuned during the rounds with respect to the quantile of the update " +"norm distribution." msgstr "" #: ../../source/explanation-differential-privacy.rst:102 msgid "" -"The choice between fixed and adaptive clipping depends on various factors " -"such as privacy requirements, data distribution, model complexity, and " +"The choice between fixed and adaptive clipping depends on various factors" +" such as privacy requirements, data distribution, model complexity, and " "others." msgstr "" @@ -3036,9 +2969,9 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:107 msgid "" "In this approach, each client is responsible for performing DP. Local DP " -"avoids the need for a fully trusted aggregator, but it should be noted that " -"local DP leads to a decrease in accuracy but better privacy in comparison to " -"central DP." +"avoids the need for a fully trusted aggregator, but it should be noted " +"that local DP leads to a decrease in accuracy but better privacy in " +"comparison to central DP." msgstr "" #: ../../source/explanation-differential-privacy.rst:116 @@ -3048,16 +2981,16 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:118 msgid "" "Each client adds noise to the local updates before sending them to the " -"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering the " -"sensitivity of the local model to be ∆, Gaussian noise is applied with a " -"noise scale of σ where:" +"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " +"the sensitivity of the local model to be ∆, Gaussian noise is applied " +"with a noise scale of σ where:" msgstr "" #: ../../source/explanation-differential-privacy.rst:120 msgid "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" -"{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times " +"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" "\n" msgstr "" @@ -3084,18 +3017,18 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:135 msgid "" -"[2] McMahan et al. Learning Differentially Private Recurrent Language Models." +"[2] McMahan et al. Learning Differentially Private Recurrent Language " +"Models." msgstr "" #: ../../source/explanation-differential-privacy.rst:137 msgid "" -"[3] Geyer et al. Differentially Private Federated Learning: A Client Level " -"Perspective." +"[3] Geyer et al. Differentially Private Federated Learning: A Client " +"Level Perspective." msgstr "" #: ../../source/explanation-differential-privacy.rst:139 -msgid "" -"[4] Galen et al. Differentially Private Learning with Adaptive Clipping." +msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." msgstr "" #: ../../source/explanation-federated-evaluation.rst:2 @@ -3106,8 +3039,8 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" "There are two main approaches to evaluating models in federated learning " -"systems: centralized (or server-side) evaluation and federated (or client-" -"side) evaluation." +"systems: centralized (or server-side) evaluation and federated (or " +"client-side) evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:8 @@ -3132,10 +3065,11 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" -"The :code:`Strategy` abstraction provides a method called :code:`evaluate` " -"that can directly be used to evaluate the current global model parameters. " -"The current server implementation calls :code:`evaluate` after parameter " -"aggregation and before federated evaluation (see next paragraph)." +"The :code:`Strategy` abstraction provides a method called " +":code:`evaluate` that can directly be used to evaluate the current global" +" model parameters. The current server implementation calls " +":code:`evaluate` after parameter aggregation and before federated " +"evaluation (see next paragraph)." msgstr "" #: ../../source/explanation-federated-evaluation.rst:65 @@ -3148,8 +3082,8 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" -"Client-side evaluation happens in the :code:`Client.evaluate` method and can " -"be configured from the server side." +"Client-side evaluation happens in the :code:`Client.evaluate` method and " +"can be configured from the server side." msgstr "" #: ../../source/explanation-federated-evaluation.rst:101 @@ -3164,39 +3098,40 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:105 msgid "" -":code:`fraction_evaluate`: a :code:`float` defining the fraction of clients " -"that will be selected for evaluation. If :code:`fraction_evaluate` is set " -"to :code:`0.1` and :code:`100` clients are connected to the server, then :" -"code:`10` will be randomly selected for evaluation. If :code:" -"`fraction_evaluate` is set to :code:`0.0`, federated evaluation will be " -"disabled." +":code:`fraction_evaluate`: a :code:`float` defining the fraction of " +"clients that will be selected for evaluation. If " +":code:`fraction_evaluate` is set to :code:`0.1` and :code:`100` clients " +"are connected to the server, then :code:`10` will be randomly selected " +"for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " +"federated evaluation will be disabled." msgstr "" #: ../../source/explanation-federated-evaluation.rst:106 msgid "" -":code:`min_evaluate_clients`: an :code:`int`: the minimum number of clients " -"to be selected for evaluation. If :code:`fraction_evaluate` is set to :code:" -"`0.1`, :code:`min_evaluate_clients` is set to 20, and :code:`100` clients " -"are connected to the server, then :code:`20` clients will be selected for " -"evaluation." +":code:`min_evaluate_clients`: an :code:`int`: the minimum number of " +"clients to be selected for evaluation. If :code:`fraction_evaluate` is " +"set to :code:`0.1`, :code:`min_evaluate_clients` is set to 20, and " +":code:`100` clients are connected to the server, then :code:`20` clients " +"will be selected for evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:107 msgid "" ":code:`min_available_clients`: an :code:`int` that defines the minimum " -"number of clients which need to be connected to the server before a round of " -"federated evaluation can start. If fewer than :code:`min_available_clients` " -"are connected to the server, the server will wait until more clients are " -"connected before it continues to sample clients for evaluation." +"number of clients which need to be connected to the server before a round" +" of federated evaluation can start. If fewer than " +":code:`min_available_clients` are connected to the server, the server " +"will wait until more clients are connected before it continues to sample " +"clients for evaluation." msgstr "" #: ../../source/explanation-federated-evaluation.rst:108 msgid "" ":code:`on_evaluate_config_fn`: a function that returns a configuration " -"dictionary which will be sent to the selected clients. The function will be " -"called during each round and provides a convenient way to customize client-" -"side evaluation from the server side, for example, to configure the number " -"of validation steps performed." +"dictionary which will be sent to the selected clients. The function will " +"be called during each round and provides a convenient way to customize " +"client-side evaluation from the server side, for example, to configure " +"the number of validation steps performed." msgstr "" #: ../../source/explanation-federated-evaluation.rst:135 @@ -3205,8 +3140,9 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" -"Model parameters can also be evaluated during training. :code:`Client.fit` " -"can return arbitrary evaluation results as a dictionary:" +"Model parameters can also be evaluated during training. " +":code:`Client.fit` can return arbitrary evaluation results as a " +"dictionary:" msgstr "" #: ../../source/explanation-federated-evaluation.rst:177 @@ -3215,10 +3151,10 @@ msgstr "" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" -"For a full code example that uses both centralized and federated evaluation, " -"see the *Advanced TensorFlow Example* (the same approach can be applied to " -"workloads implemented in any other framework): https://github.com/adap/" -"flower/tree/main/examples/advanced-tensorflow" +"For a full code example that uses both centralized and federated " +"evaluation, see the *Advanced TensorFlow Example* (the same approach can " +"be applied to workloads implemented in any other framework): " +"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" msgstr "" #: ../../source/fed/0000-20200102-fed-template.md:10 @@ -3392,9 +3328,9 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" -"ensure community participants can successfully drive changes to completion " -"across one or more releases while stakeholders are adequately represented " -"throughout the process" +"ensure community participants can successfully drive changes to " +"completion across one or more releases while stakeholders are adequately " +"represented throughout the process" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 @@ -3422,54 +3358,54 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" "For far-fetching changes or features proposed to Flower, an abstraction " -"beyond a single GitHub issue or pull request is required to understand and " -"communicate upcoming changes to the project." +"beyond a single GitHub issue or pull request is required to understand " +"and communicate upcoming changes to the project." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" -"The purpose of this process is to reduce the amount of \"tribal knowledge\" " -"in our community. By moving decisions from Slack threads, video calls, and " -"hallway conversations into a well-tracked artifact, this process aims to " -"enhance communication and discoverability." +"The purpose of this process is to reduce the amount of \"tribal " +"knowledge\" in our community. By moving decisions from Slack threads, " +"video calls, and hallway conversations into a well-tracked artifact, this" +" process aims to enhance communication and discoverability." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" -"Roughly any larger, user-facing enhancement should follow the Enhancement " -"process. If an enhancement would be described in either written or verbal " -"communication to anyone besides the author or developer, then consider " -"creating an Enhancement Doc." +"Roughly any larger, user-facing enhancement should follow the Enhancement" +" process. If an enhancement would be described in either written or " +"verbal communication to anyone besides the author or developer, then " +"consider creating an Enhancement Doc." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" -"Similarly, any technical effort (refactoring, major architectural change) " -"that will impact a large section of the development community should also be " -"communicated widely. The Enhancement process is suited for this even if it " -"will have zero impact on the typical user or operator." +"Similarly, any technical effort (refactoring, major architectural change)" +" that will impact a large section of the development community should " +"also be communicated widely. The Enhancement process is suited for this " +"even if it will have zero impact on the typical user or operator." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" -"For small changes and additions, going through the Enhancement process would " -"be time-consuming and unnecessary. This includes, for example, adding new " -"Federated Learning algorithms, as these only add features without changing " -"how Flower works or is used." +"For small changes and additions, going through the Enhancement process " +"would be time-consuming and unnecessary. This includes, for example, " +"adding new Federated Learning algorithms, as these only add features " +"without changing how Flower works or is used." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " -"providing a laid-out path for implementation and are championed by members " -"of the community." +"providing a laid-out path for implementation and are championed by " +"members of the community." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" "An Enhancement is captured in a Markdown file that follows a defined " -"template and a workflow to review and store enhancement docs for reference " -"— the Enhancement Doc." +"template and a workflow to review and store enhancement docs for " +"reference — the Enhancement Doc." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:69 @@ -3521,8 +3457,8 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" -"**fed-number** (Required) The `fed-number` of the last Flower Enhancement " -"Doc + 1. With this number, it becomes easy to reference other proposals." +"**fed-number** (Required) The `fed-number` of the last Flower Enhancement" +" Doc + 1. With this number, it becomes easy to reference other proposals." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 @@ -3531,20 +3467,20 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" -"**status** (Required) The current status of the proposal. See [workflow]" -"(#workflow) for the possible states." +"**status** (Required) The current status of the proposal. See " +"[workflow](#workflow) for the possible states." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" -"**authors** (Required) A list of authors of the proposal. This is simply the " -"GitHub ID." +"**authors** (Required) A list of authors of the proposal. This is simply " +"the GitHub ID." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" -"**creation-date** (Required) The date that the proposal was first submitted " -"in a PR." +"**creation-date** (Required) The date that the proposal was first " +"submitted in a PR." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 @@ -3555,8 +3491,8 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" -"**see-also** (Optional) A list of other proposals that are relevant to this " -"one." +"**see-also** (Optional) A list of other proposals that are relevant to " +"this one." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 @@ -3564,8 +3500,7 @@ msgid "**replaces** (Optional) A list of proposals that this one replaces." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 -msgid "" -"**superseded-by** (Optional) A list of proposals that this one supersedes." +msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 @@ -3575,40 +3510,40 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" "The idea forming the enhancement should already have been discussed or " -"pitched in the community. As such, it needs a champion, usually the author, " -"who shepherds the enhancement. This person also has to find committers to " -"Flower willing to review the proposal." +"pitched in the community. As such, it needs a champion, usually the " +"author, who shepherds the enhancement. This person also has to find " +"committers to Flower willing to review the proposal." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" "New enhancements are checked in with a file name in the form of `NNNN-" -"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement Doc " -"number, to `enhancements`. All enhancements start in `provisional` state as " -"part of a pull request. Discussions are done as part of the pull request " -"review." +"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement " +"Doc number, to `enhancements`. All enhancements start in `provisional` " +"state as part of a pull request. Discussions are done as part of the pull" +" request review." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" -"Once an enhancement has been reviewed and approved, its status is changed to " -"`implementable`. The actual implementation is then done in separate pull " -"requests. These pull requests should mention the respective enhancement as " -"part of their description. After the implementation is done, the proposal " -"status is changed to `implemented`." +"Once an enhancement has been reviewed and approved, its status is changed" +" to `implementable`. The actual implementation is then done in separate " +"pull requests. These pull requests should mention the respective " +"enhancement as part of their description. After the implementation is " +"done, the proposal status is changed to `implemented`." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" -"Under certain conditions, other states are possible. An Enhancement has the " -"following states:" +"Under certain conditions, other states are possible. An Enhancement has " +"the following states:" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" "`provisional`: The enhancement has been proposed and is actively being " -"defined. This is the starting state while the proposal is being fleshed out " -"and actively defined and discussed." +"defined. This is the starting state while the proposal is being fleshed " +"out and actively defined and discussed." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 @@ -3622,14 +3557,13 @@ msgid "" msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 -msgid "" -"`deferred`: The enhancement is proposed but not actively being worked on." +msgid "`deferred`: The enhancement is proposed but not actively being worked on." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" -"`rejected`: The authors and reviewers have decided that this enhancement is " -"not moving forward." +"`rejected`: The authors and reviewers have decided that this enhancement " +"is not moving forward." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 @@ -3642,16 +3576,16 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" -"Adding an additional process to the ones already provided by GitHub (Issues " -"and Pull Requests) adds more complexity and can be a barrier for potential " -"first-time contributors." +"Adding an additional process to the ones already provided by GitHub " +"(Issues and Pull Requests) adds more complexity and can be a barrier for " +"potential first-time contributors." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" "Expanding the proposal template beyond the single-sentence description " -"currently required in the features issue template may be a heavy burden for " -"non-native English speakers." +"currently required in the features issue template may be a heavy burden " +"for non-native English speakers." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 @@ -3661,12 +3595,12 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" "Using GitHub Issues for these kinds of enhancements is doable. One could " -"use, for example, tags, to differentiate and filter them from other issues. " -"The main issue is in discussing and reviewing an enhancement: GitHub issues " -"only have a single thread for comments. Enhancements usually have multiple " -"threads of discussion at the same time for various parts of the doc. " -"Managing these multiple discussions can be confusing when using GitHub " -"Issues." +"use, for example, tags, to differentiate and filter them from other " +"issues. The main issue is in discussing and reviewing an enhancement: " +"GitHub issues only have a single thread for comments. Enhancements " +"usually have multiple threads of discussion at the same time for various " +"parts of the doc. Managing these multiple discussions can be confusing " +"when using GitHub Issues." msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 @@ -3675,11 +3609,12 @@ msgstr "" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" -"Google Docs allow for multiple threads of discussions. But as Google Docs " -"are hosted outside the project, their discoverability by the community needs " -"to be taken care of. A list of links to all proposals has to be managed and " -"made available for the community. Compared to shipping proposals as part of " -"Flower's repository, the potential for missing links is much higher." +"Google Docs allow for multiple threads of discussions. But as Google Docs" +" are hosted outside the project, their discoverability by the community " +"needs to be taken care of. A list of links to all proposals has to be " +"managed and made available for the community. Compared to shipping " +"proposals as part of Flower's repository, the potential for missing links" +" is much higher." msgstr "" #: ../../source/fed/index.md:1 @@ -3692,8 +3627,8 @@ msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" -"The Flower server does not prescribe a way to aggregate evaluation results, " -"but it enables the user to fully customize result aggregation." +"The Flower server does not prescribe a way to aggregate evaluation " +"results, but it enables the user to fully customize result aggregation." msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:8 @@ -3702,9 +3637,9 @@ msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" -"The same :code:`Strategy`-customization approach can be used to aggregate " -"custom evaluation results coming from individual clients. Clients can return " -"custom metrics to the server by returning a dictionary:" +"The same :code:`Strategy`-customization approach can be used to aggregate" +" custom evaluation results coming from individual clients. Clients can " +"return custom metrics to the server by returning a dictionary:" msgstr "" #: ../../source/how-to-aggregate-evaluation-results.rst:36 @@ -3719,9 +3654,10 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:4 msgid "" -"Flower has built-in support for authenticated SuperNodes that you can use to " -"verify the identities of each SuperNode connecting to a SuperLink. Flower " -"node authentication works similar to how GitHub SSH authentication works:" +"Flower has built-in support for authenticated SuperNodes that you can use" +" to verify the identities of each SuperNode connecting to a SuperLink. " +"Flower node authentication works similar to how GitHub SSH authentication" +" works:" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:7 @@ -3730,7 +3666,8 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:8 msgid "" -"Using ECDH, both SuperNode and SuperLink independently derive a shared secret" +"Using ECDH, both SuperNode and SuperLink independently derive a shared " +"secret" msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:9 @@ -3745,21 +3682,22 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:12 msgid "" -"We recommend you to check out the complete `code example `_ demonstrating " -"federated learning with Flower in an authenticated setting." +"We recommend you to check out the complete `code example " +"`_ demonstrating federated learning with Flower in an " +"authenticated setting." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:15 msgid "" -"This guide covers a preview feature that might change in future versions of " -"Flower." +"This guide covers a preview feature that might change in future versions " +"of Flower." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:18 msgid "" -"For increased security, node authentication can only be used when encrypted " -"connections (SSL/TLS) are enabled." +"For increased security, node authentication can only be used when " +"encrypted connections (SSL/TLS) are enabled." msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:21 @@ -3769,99 +3707,101 @@ msgstr "" #: ../../source/how-to-authenticate-supernodes.rst:23 msgid "" "To enable node authentication, first you need to configure SSL/TLS " -"connections to secure the SuperLink<>SuperNode communication. You can find " -"the complete guide `here `_. After configuring secure connections, you can enable " -"client authentication in a long-running Flower :code:`SuperLink`. Use the " -"following terminal command to start a Flower :code:`SuperNode` that has both " -"secure connections and node authentication enabled:" +"connections to secure the SuperLink<>SuperNode communication. You can " +"find the complete guide `here `_. After configuring secure connections, you" +" can enable client authentication in a long-running Flower " +":code:`SuperLink`. Use the following terminal command to start a Flower " +":code:`SuperNode` that has both secure connections and node " +"authentication enabled:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:36 +#: ../../source/how-to-authenticate-supernodes.rst:38 msgid "Let's break down the authentication flags:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:38 +#: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" -"The first flag :code:`--auth-list-public-keys` expects a path to a CSV file " -"storing all known node public keys. You need to store all known node public " -"keys that are allowed to participate in a federation in one CSV file (:code:" -"`.csv`)." +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " +"file storing all known node public keys. You need to store all known node" +" public keys that are allowed to participate in a federation in one CSV " +"file (:code:`.csv`)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:40 +#: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " -"example, refer to our code sample, which contains a CSV file with two known " -"node public keys." +"example, refer to our code sample, which contains a CSV file with two " +"known node public keys." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:42 +#: ../../source/how-to-authenticate-supernodes.rst:44 msgid "" -"The second and third flags :code:`--auth-superlink-private-key` and :code:`--" -"auth-superlink-public-key` expect paths to the server's private and public " -"keys. For development purposes, you can generate a private and public key " -"pair using :code:`ssh-keygen -t ecdsa -b 384`." +"The second and third flags :code:`--auth-superlink-private-key` and :code" +":`--auth-superlink-public-key` expect paths to the server's private and " +"public keys. For development purposes, you can generate a private and " +"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:45 +#: ../../source/how-to-authenticate-supernodes.rst:47 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " -"adding known node public keys to the SuperLink. To change the set of known " -"nodes, you need to shut the server down, edit the CSV file, and start the " -"server again. Support for dynamically changing the set of known nodes is on " -"the roadmap to be released in Flower 1.10 (ETA: June)." +"adding known node public keys to the SuperLink. To change the set of " +"known nodes, you need to shut the server down, edit the CSV file, and " +"start the server again. Support for dynamically changing the set of known" +" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:51 +#: ../../source/how-to-authenticate-supernodes.rst:53 msgid "Enable node authentication in :code:`SuperNode`" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:53 +#: ../../source/how-to-authenticate-supernodes.rst:55 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " -"easily enable node authentication in the long-running Flower client (:code:" -"`SuperNode`). Use the following terminal command to start an authenticated :" -"code:`SuperNode`:" +"easily enable node authentication in the long-running Flower client " +"(:code:`SuperNode`). Use the following terminal command to start an " +"authenticated :code:`SuperNode`:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:64 +#: ../../source/how-to-authenticate-supernodes.rst:66 msgid "" -"The :code:`--auth-supernode-private-key` flag expects a path to the node's " -"private key file and the :code:`--auth-supernode-public-key` flag expects a " -"path to the node's public key file. For development purposes, you can " -"generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b " -"384`." +"The :code:`--auth-supernode-private-key` flag expects a path to the " +"node's private key file and the :code:`--auth-supernode-public-key` flag " +"expects a path to the node's public key file. For development purposes, " +"you can generate a private and public key pair using :code:`ssh-keygen -t" +" ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:68 +#: ../../source/how-to-authenticate-supernodes.rst:70 msgid "Security notice" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:70 +#: ../../source/how-to-authenticate-supernodes.rst:72 msgid "" -"The system's security relies on the credentials of the SuperLink and each " -"SuperNode. Therefore, it is imperative to safeguard and safely store the " -"credentials to avoid security risks such as Public Key Infrastructure (PKI) " -"impersonation attacks. The node authentication mechanism also involves human " -"interaction, so please ensure that all of the communication is done in a " -"secure manner, using trusted communication methods." +"The system's security relies on the credentials of the SuperLink and each" +" SuperNode. Therefore, it is imperative to safeguard and safely store the" +" credentials to avoid security risks such as Public Key Infrastructure " +"(PKI) impersonation attacks. The node authentication mechanism also " +"involves human interaction, so please ensure that all of the " +"communication is done in a secure manner, using trusted communication " +"methods." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:75 -#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:68 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-authenticate-supernodes.rst:79 msgid "" -"You should now have learned how to start a long-running Flower server (:code:" -"`SuperLink`) and client (:code:`SuperNode`) with node authentication " -"enabled. You should also know the significance of the private key and store " -"it safely to minimize security risks." +"You should now have learned how to start a long-running Flower server " +"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " +"authentication enabled. You should also know the significance of the " +"private key and store it safely to minimize security risks." msgstr "" #: ../../source/how-to-configure-clients.rst:2 @@ -3871,9 +3811,9 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:4 msgid "" "Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are, " -"for example, a popular way to control client-side hyperparameters from the " -"server." +"clients. Configuration values can be used for various purposes. They are," +" for example, a popular way to control client-side hyperparameters from " +"the server." msgstr "" #: ../../source/how-to-configure-clients.rst:7 @@ -3882,34 +3822,34 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:9 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys and " -"values of type ``bool``, ``bytes``, ``double`` (64-bit precision float), " -"``int``, or ``str`` (or equivalent types in different languages). Here is an " -"example of a configuration dictionary in Python:" +"Configuration values are represented as a dictionary with ``str`` keys " +"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " +"float), ``int``, or ``str`` (or equivalent types in different languages)." +" Here is an example of a configuration dictionary in Python:" msgstr "" #: ../../source/how-to-configure-clients.rst:20 msgid "" "Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client using " -"gRPC, and then deserializes them back to Python dictionaries." +"short) to their ProtoBuf representation, transports them to the client " +"using gRPC, and then deserializes them back to Python dictionaries." msgstr "" #: ../../source/how-to-configure-clients.rst:24 msgid "" -"Currently, there is no support for directly sending collection types (e.g., " -"``Set``, ``List``, ``Map``) as values in configuration dictionaries. There " -"are several workarounds to send collections as values by converting them to " -"one of the supported value types (and converting them back on the client-" -"side)." +"Currently, there is no support for directly sending collection types " +"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " +"dictionaries. There are several workarounds to send collections as values" +" by converting them to one of the supported value types (and converting " +"them back on the client-side)." msgstr "" #: ../../source/how-to-configure-clients.rst:26 msgid "" "One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and " -"then convert the JSON string back to a list of floating-point numbers on the " -"client." +"string, then send the JSON string using the configuration dictionary, and" +" then convert the JSON string back to a list of floating-point numbers on" +" the client." msgstr "" #: ../../source/how-to-configure-clients.rst:30 @@ -3918,50 +3858,49 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:32 msgid "" -"The easiest way to send configuration values to clients is to use a built-in " -"strategy like :code:`FedAvg`. Built-in strategies support so-called " -"configuration functions. A configuration function is a function that the " -"built-in strategy calls to get the configuration dictionary for the current " -"round. It then forwards the configuration dictionary to all the clients " -"selected during that round." +"The easiest way to send configuration values to clients is to use a " +"built-in strategy like :code:`FedAvg`. Built-in strategies support so-" +"called configuration functions. A configuration function is a function " +"that the built-in strategy calls to get the configuration dictionary for " +"the current round. It then forwards the configuration dictionary to all " +"the clients selected during that round." msgstr "" #: ../../source/how-to-configure-clients.rst:34 msgid "" "Let's start with a simple example. Imagine we want to send (a) the batch " -"size that the client should use, (b) the current global round of federated " -"learning, and (c) the number of epochs to train on the client-side. Our " -"configuration function could look like this:" +"size that the client should use, (b) the current global round of " +"federated learning, and (c) the number of epochs to train on the client-" +"side. Our configuration function could look like this:" msgstr "" #: ../../source/how-to-configure-clients.rst:47 msgid "" "To make the built-in strategies use this function, we can pass it to " -"``FedAvg`` during initialization using the parameter :code:" -"`on_fit_config_fn`:" +"``FedAvg`` during initialization using the parameter " +":code:`on_fit_config_fn`:" msgstr "" #: ../../source/how-to-configure-clients.rst:56 -msgid "" -"One the client side, we receive the configuration dictionary in ``fit``:" +msgid "One the client side, we receive the configuration dictionary in ``fit``:" msgstr "" #: ../../source/how-to-configure-clients.rst:67 msgid "" "There is also an `on_evaluate_config_fn` to configure evaluation, which " -"works the same way. They are separate functions because one might want to " -"send different configuration values to `evaluate` (for example, to use a " -"different batch size)." +"works the same way. They are separate functions because one might want to" +" send different configuration values to `evaluate` (for example, to use a" +" different batch size)." msgstr "" #: ../../source/how-to-configure-clients.rst:69 msgid "" -"The built-in strategies call this function every round (that is, every time " -"`Strategy.configure_fit` or `Strategy.configure_evaluate` runs). Calling " -"`on_evaluate_config_fn` every round allows us to vary/change the config dict " -"over consecutive rounds. If we wanted to implement a hyperparameter " -"schedule, for example, to increase the number of local epochs during later " -"rounds, we could do the following:" +"The built-in strategies call this function every round (that is, every " +"time `Strategy.configure_fit` or `Strategy.configure_evaluate` runs). " +"Calling `on_evaluate_config_fn` every round allows us to vary/change the " +"config dict over consecutive rounds. If we wanted to implement a " +"hyperparameter schedule, for example, to increase the number of local " +"epochs during later rounds, we could do the following:" msgstr "" #: ../../source/how-to-configure-clients.rst:82 @@ -3980,12 +3919,13 @@ msgstr "" #: ../../source/how-to-configure-clients.rst:89 msgid "" -"This can be achieved by customizing an existing strategy or by :doc:" -"`implementing a custom strategy from scratch `. " -"Here's a nonsensical example that customizes :code:`FedAvg` by adding a " -"custom ``\"hello\": \"world\"`` configuration key/value pair to the config " -"dict of a *single client* (only the first client in the list, the other " -"clients in this round to not receive this \"special\" config value):" +"This can be achieved by customizing an existing strategy or by " +":doc:`implementing a custom strategy from scratch `. Here's a nonsensical example that customizes :code:`FedAvg`" +" by adding a custom ``\"hello\": \"world\"`` configuration key/value pair" +" to the config dict of a *single client* (only the first client in the " +"list, the other clients in this round to not receive this \"special\" " +"config value):" msgstr "" #: ../../source/how-to-configure-logging.rst:2 @@ -3995,16 +3935,16 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:4 msgid "" "The Flower logger keeps track of all core events that take place in " -"federated learning workloads. It presents information by default following a " -"standard message format:" +"federated learning workloads. It presents information by default " +"following a standard message format:" msgstr "" #: ../../source/how-to-configure-logging.rst:13 msgid "" -"containing relevant information including: log message level (e.g. :code:" -"`INFO`, :code:`DEBUG`), a timestamp, the line where the logging took place " -"from, as well as the log message itself. In this way, the logger would " -"typically display information on your terminal as follows:" +"containing relevant information including: log message level (e.g. " +":code:`INFO`, :code:`DEBUG`), a timestamp, the line where the logging " +"took place from, as well as the log message itself. In this way, the " +"logger would typically display information on your terminal as follows:" msgstr "" #: ../../source/how-to-configure-logging.rst:34 @@ -4015,20 +3955,21 @@ msgstr "" msgid "" "By default, the Flower log is outputted to the terminal where you launch " "your Federated Learning workload from. This applies for both gRPC-based " -"federation (i.e. when you do :code:`fl.server.start_server`) and when using " -"the :code:`VirtualClientEngine` (i.e. when you do :code:`fl.simulation." -"start_simulation`). In some situations you might want to save this log to " -"disk. You can do so by calling the `fl.common.logger.configure() `_ function. " -"For example:" +"federation (i.e. when you do :code:`fl.server.start_server`) and when " +"using the :code:`VirtualClientEngine` (i.e. when you do " +":code:`fl.simulation.start_simulation`). In some situations you might " +"want to save this log to disk. You can do so by calling the " +"`fl.common.logger.configure() " +"`_" +" function. For example:" msgstr "" #: ../../source/how-to-configure-logging.rst:53 msgid "" -"With the above, Flower will record the log you see on your terminal to :code:" -"`log.txt`. This file will be created in the same directory as were you are " -"running the code from. If we inspect we see the log above is also recorded " -"but prefixing with :code:`identifier` each line:" +"With the above, Flower will record the log you see on your terminal to " +":code:`log.txt`. This file will be created in the same directory as were " +"you are running the code from. If we inspect we see the log above is also" +" recorded but prefixing with :code:`identifier` each line:" msgstr "" #: ../../source/how-to-configure-logging.rst:74 @@ -4037,15 +3978,15 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:76 msgid "" -"You might expand the information shown by default with the Flower logger by " -"adding more messages relevant to your application. You can achieve this " -"easily as follows." +"You might expand the information shown by default with the Flower logger " +"by adding more messages relevant to your application. You can achieve " +"this easily as follows." msgstr "" #: ../../source/how-to-configure-logging.rst:102 msgid "" -"In this way your logger will show, in addition to the default messages, the " -"ones introduced by the clients as specified above." +"In this way your logger will show, in addition to the default messages, " +"the ones introduced by the clients as specified above." msgstr "" #: ../../source/how-to-configure-logging.rst:128 @@ -4054,14 +3995,15 @@ msgstr "" #: ../../source/how-to-configure-logging.rst:130 msgid "" -"The :code:`fl.common.logger.configure` function, also allows specifying a " -"host to which logs can be pushed (via :code:`POST`) through a native Python :" -"code:`logging.handler.HTTPHandler`. This is a particularly useful feature " -"in :code:`gRPC`-based Federated Learning workloads where otherwise gathering " -"logs from all entities (i.e. the server and the clients) might be " -"cumbersome. Note that in Flower simulation, the server automatically " -"displays all logs. You can still specify a :code:`HTTPHandler` should you " -"wish to backup or analyze the logs somewhere else." +"The :code:`fl.common.logger.configure` function, also allows specifying a" +" host to which logs can be pushed (via :code:`POST`) through a native " +"Python :code:`logging.handler.HTTPHandler`. This is a particularly useful" +" feature in :code:`gRPC`-based Federated Learning workloads where " +"otherwise gathering logs from all entities (i.e. the server and the " +"clients) might be cumbersome. Note that in Flower simulation, the server " +"automatically displays all logs. You can still specify a " +":code:`HTTPHandler` should you wish to backup or analyze the logs " +"somewhere else." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:2 @@ -4070,23 +4012,24 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:4 msgid "" -"This guide describes how to a SSL-enabled secure Flower server (:code:" -"`SuperLink`) can be started and how a Flower client (:code:`SuperNode`) can " -"establish a secure connections to it." +"This guide describes how to a SSL-enabled secure Flower server " +"(:code:`SuperLink`) can be started and how a Flower client " +"(:code:`SuperNode`) can establish a secure connections to it." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" -"A complete code example demonstrating a secure connection can be found `here " -"`_." +"A complete code example demonstrating a secure connection can be found " +"`here `_." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" -"The code example comes with a :code:`README.md` file which explains how to " -"start it. Although it is already SSL-enabled, it might be less descriptive " -"on how it does so. Stick to this guide for a deeper introduction to the " -"topic." +"The code example comes with a :code:`README.md` file which explains how " +"to start it. Although it is already SSL-enabled, it might be less " +"descriptive on how it does so. Stick to this guide for a deeper " +"introduction to the topic." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:16 @@ -4096,27 +4039,27 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:18 msgid "" "Using SSL-enabled connections requires certificates to be passed to the " -"server and client. For the purpose of this guide we are going to generate " -"self-signed certificates. As this can become quite complex we are going to " -"ask you to run the script in :code:`examples/advanced-tensorflow/" -"certificates/generate.sh` with the following command sequence:" +"server and client. For the purpose of this guide we are going to generate" +" self-signed certificates. As this can become quite complex we are going " +"to ask you to run the script in :code:`examples/advanced-" +"tensorflow/certificates/generate.sh` with the following command sequence:" msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" -"This will generate the certificates in :code:`examples/advanced-tensorflow/." -"cache/certificates`." +"This will generate the certificates in :code:`examples/advanced-" +"tensorflow/.cache/certificates`." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:31 msgid "" -"The approach for generating SSL certificates in the context of this example " -"can serve as an inspiration and starting point, but it should not be used as " -"a reference for production environments. Please refer to other sources " -"regarding the issue of correctly generating certificates for production " -"environments. For non-critical prototyping or research projects, it might be " -"sufficient to use the self-signed certificates generated using the scripts " -"mentioned in this guide." +"The approach for generating SSL certificates in the context of this " +"example can serve as an inspiration and starting point, but it should not" +" be used as a reference for production environments. Please refer to " +"other sources regarding the issue of correctly generating certificates " +"for production environments. For non-critical prototyping or research " +"projects, it might be sufficient to use the self-signed certificates " +"generated using the scripts mentioned in this guide." msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:39 @@ -4125,55 +4068,55 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:41 msgid "" -"Use the following terminal command to start a sever (SuperLink) that uses " -"the previously generated certificates:" +"Use the following terminal command to start a sever (SuperLink) that uses" +" the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:47 +#: ../../source/how-to-enable-ssl-connections.rst:50 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates paths: CA certificate, server certificate and server private " -"key." +"certificates paths: CA certificate, server certificate and server private" +" key." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:51 +#: ../../source/how-to-enable-ssl-connections.rst:54 msgid "Client (SuperNode)" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:53 +#: ../../source/how-to-enable-ssl-connections.rst:56 msgid "" -"Use the following terminal command to start a client (SuperNode) that uses " -"the previously generated certificates:" +"Use the following terminal command to start a client (SuperNode) that " +"uses the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:64 msgid "" -"When setting :code:`root_certificates`, the client expects a file path to " -"PEM-encoded root certificates." +"When setting :code:`root_certificates`, the client expects a file path to" +" PEM-encoded root certificates." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:70 msgid "" -"You should now have learned how to generate self-signed certificates using " -"the given script, start an SSL-enabled server and have a client establish a " -"secure connection to it." +"You should now have learned how to generate self-signed certificates " +"using the given script, start an SSL-enabled server and have a client " +"establish a secure connection to it." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:72 +#: ../../source/how-to-enable-ssl-connections.rst:75 msgid "Additional resources" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:74 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" -"These additional sources might be relevant if you would like to dive deeper " -"into the topic of certificates:" +"These additional sources might be relevant if you would like to dive " +"deeper into the topic of certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:76 +#: ../../source/how-to-enable-ssl-connections.rst:79 msgid "`Let's Encrypt `_" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" msgstr "" @@ -4183,12 +4126,12 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:4 msgid "" -"The strategy abstraction enables implementation of fully custom strategies. " -"A strategy is basically the federated learning algorithm that runs on the " -"server. Strategies decide how to sample clients, how to configure clients " -"for training, how to aggregate updates, and how to evaluate models. Flower " -"provides a few built-in strategies which are based on the same API described " -"below." +"The strategy abstraction enables implementation of fully custom " +"strategies. A strategy is basically the federated learning algorithm that" +" runs on the server. Strategies decide how to sample clients, how to " +"configure clients for training, how to aggregate updates, and how to " +"evaluate models. Flower provides a few built-in strategies which are " +"based on the same API described below." msgstr "" #: ../../source/how-to-implement-strategies.rst:11 @@ -4197,10 +4140,11 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:13 msgid "" -"All strategy implementation are derived from the abstract base class :code:" -"`flwr.server.strategy.Strategy`, both built-in implementations and third " -"party implementations. This means that custom strategy implementations have " -"the exact same capabilities at their disposal as built-in ones." +"All strategy implementation are derived from the abstract base class " +":code:`flwr.server.strategy.Strategy`, both built-in implementations and " +"third party implementations. This means that custom strategy " +"implementations have the exact same capabilities at their disposal as " +"built-in ones." msgstr "" #: ../../source/how-to-implement-strategies.rst:18 @@ -4211,9 +4155,9 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:75 msgid "" -"Creating a new strategy means implementing a new :code:`class` (derived from " -"the abstract base class :code:`Strategy`) that implements for the previously " -"shown abstract methods:" +"Creating a new strategy means implementing a new :code:`class` (derived " +"from the abstract base class :code:`Strategy`) that implements for the " +"previously shown abstract methods:" msgstr "" #: ../../source/how-to-implement-strategies.rst:100 @@ -4230,35 +4174,37 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:182 msgid "" -":code:`initialize_parameters` is called only once, at the very beginning of " -"an execution. It is responsible for providing the initial global model " -"parameters in a serialized form (i.e., as a :code:`Parameters` object)." +":code:`initialize_parameters` is called only once, at the very beginning " +"of an execution. It is responsible for providing the initial global model" +" parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" #: ../../source/how-to-implement-strategies.rst:184 msgid "" -"Built-in strategies return user-provided initial parameters. The following " -"example shows how initial parameters can be passed to :code:`FedAvg`:" +"Built-in strategies return user-provided initial parameters. The " +"following example shows how initial parameters can be passed to " +":code:`FedAvg`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:209 msgid "" "The Flower server will call :code:`initialize_parameters`, which either " -"returns the parameters that were passed to :code:`initial_parameters`, or :" -"code:`None`. If no parameters are returned from :code:" -"`initialize_parameters` (i.e., :code:`None`), the server will randomly " -"select one client and ask it to provide its parameters. This is a " -"convenience feature and not recommended in practice, but it can be useful " -"for prototyping. In practice, it is recommended to always use server-side " -"parameter initialization." +"returns the parameters that were passed to :code:`initial_parameters`, or" +" :code:`None`. If no parameters are returned from " +":code:`initialize_parameters` (i.e., :code:`None`), the server will " +"randomly select one client and ask it to provide its parameters. This is " +"a convenience feature and not recommended in practice, but it can be " +"useful for prototyping. In practice, it is recommended to always use " +"server-side parameter initialization." msgstr "" #: ../../source/how-to-implement-strategies.rst:213 msgid "" "Server-side parameter initialization is a powerful mechanism. It can be " -"used, for example, to resume training from a previously saved checkpoint. It " -"is also the fundamental capability needed to implement hybrid approaches, " -"for example, to fine-tune a pre-trained model using federated learning." +"used, for example, to resume training from a previously saved checkpoint." +" It is also the fundamental capability needed to implement hybrid " +"approaches, for example, to fine-tune a pre-trained model using federated" +" learning." msgstr "" #: ../../source/how-to-implement-strategies.rst:216 @@ -4267,17 +4213,17 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:218 msgid "" -":code:`configure_fit` is responsible for configuring the upcoming round of " -"training. What does *configure* mean in this context? Configuring a round " -"means selecting clients and deciding what instructions to send to these " -"clients. The signature of :code:`configure_fit` makes this clear:" +":code:`configure_fit` is responsible for configuring the upcoming round " +"of training. What does *configure* mean in this context? Configuring a " +"round means selecting clients and deciding what instructions to send to " +"these clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" #: ../../source/how-to-implement-strategies.rst:231 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations usually " -"perform the following steps in :code:`configure_fit`:" +"that will be sent to a particular client. Strategy implementations " +"usually perform the following steps in :code:`configure_fit`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:233 @@ -4296,18 +4242,19 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:236 msgid "" "More sophisticated implementations can use :code:`configure_fit` to " -"implement custom client selection logic. A client will only participate in a " -"round if the corresponding :code:`ClientProxy` is included in the list " -"returned from :code:`configure_fit`." +"implement custom client selection logic. A client will only participate " +"in a round if the corresponding :code:`ClientProxy` is included in the " +"list returned from :code:`configure_fit`." msgstr "" #: ../../source/how-to-implement-strategies.rst:240 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies to " -"train, for example, different models on different clients, or use different " -"hyperparameters on different clients (via the :code:`config` dict)." +"instructions can be sent to each client. This enables custom strategies " +"to train, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` " +"dict)." msgstr "" #: ../../source/how-to-implement-strategies.rst:243 @@ -4316,23 +4263,24 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:245 msgid "" -":code:`aggregate_fit` is responsible for aggregating the results returned by " -"the clients that were selected and asked to train in :code:`configure_fit`." +":code:`aggregate_fit` is responsible for aggregating the results returned" +" by the clients that were selected and asked to train in " +":code:`configure_fit`." msgstr "" #: ../../source/how-to-implement-strategies.rst:258 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via :code:" -"`configure_fit`). :code:`aggregate_fit` therefore receives a list of :code:" -"`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via " +":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " +"of :code:`results`, but also a list of :code:`failures`." msgstr "" #: ../../source/how-to-implement-strategies.rst:260 msgid "" -":code:`aggregate_fit` returns an optional :code:`Parameters` object and a " -"dictionary of aggregated metrics. The :code:`Parameters` return value is " -"optional because :code:`aggregate_fit` might decide that the results " +":code:`aggregate_fit` returns an optional :code:`Parameters` object and a" +" dictionary of aggregated metrics. The :code:`Parameters` return value is" +" optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" @@ -4342,40 +4290,42 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:265 msgid "" -":code:`configure_evaluate` is responsible for configuring the upcoming round " -"of evaluation. What does *configure* mean in this context? Configuring a " -"round means selecting clients and deciding what instructions to send to " -"these clients. The signature of :code:`configure_evaluate` makes this clear:" +":code:`configure_evaluate` is responsible for configuring the upcoming " +"round of evaluation. What does *configure* mean in this context? " +"Configuring a round means selecting clients and deciding what " +"instructions to send to these clients. The signature of " +":code:`configure_evaluate` makes this clear:" msgstr "" #: ../../source/how-to-implement-strategies.rst:278 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations usually " -"perform the following steps in :code:`configure_evaluate`:" +"that will be sent to a particular client. Strategy implementations " +"usually perform the following steps in :code:`configure_evaluate`:" msgstr "" #: ../../source/how-to-implement-strategies.rst:281 msgid "" -"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding the " -"current global model :code:`parameters` and :code:`config` dict" +"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " +"the current global model :code:`parameters` and :code:`config` dict" msgstr "" #: ../../source/how-to-implement-strategies.rst:283 msgid "" "More sophisticated implementations can use :code:`configure_evaluate` to " -"implement custom client selection logic. A client will only participate in a " -"round if the corresponding :code:`ClientProxy` is included in the list " -"returned from :code:`configure_evaluate`." +"implement custom client selection logic. A client will only participate " +"in a round if the corresponding :code:`ClientProxy` is included in the " +"list returned from :code:`configure_evaluate`." msgstr "" #: ../../source/how-to-implement-strategies.rst:287 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies to " -"evaluate, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` dict)." +"instructions can be sent to each client. This enables custom strategies " +"to evaluate, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` " +"dict)." msgstr "" #: ../../source/how-to-implement-strategies.rst:291 @@ -4385,24 +4335,24 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:293 msgid "" ":code:`aggregate_evaluate` is responsible for aggregating the results " -"returned by the clients that were selected and asked to evaluate in :code:" -"`configure_evaluate`." +"returned by the clients that were selected and asked to evaluate in " +":code:`configure_evaluate`." msgstr "" #: ../../source/how-to-implement-strategies.rst:306 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via :code:" -"`configure_evaluate`). :code:`aggregate_evaluate` therefore receives a list " -"of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via " +":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " +"receives a list of :code:`results`, but also a list of :code:`failures`." msgstr "" #: ../../source/how-to-implement-strategies.rst:308 msgid "" -":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a " -"dictionary of aggregated metrics. The :code:`float` return value is optional " -"because :code:`aggregate_evaluate` might decide that the results provided " -"are not sufficient for aggregation (e.g., too many failures)." +":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a" +" dictionary of aggregated metrics. The :code:`float` return value is " +"optional because :code:`aggregate_evaluate` might decide that the results" +" provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" #: ../../source/how-to-implement-strategies.rst:311 @@ -4412,17 +4362,17 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:313 msgid "" ":code:`evaluate` is responsible for evaluating model parameters on the " -"server-side. Having :code:`evaluate` in addition to :code:" -"`configure_evaluate`/:code:`aggregate_evaluate` enables strategies to " -"perform both servers-side and client-side (federated) evaluation." +"server-side. Having :code:`evaluate` in addition to " +":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " +"to perform both servers-side and client-side (federated) evaluation." msgstr "" #: ../../source/how-to-implement-strategies.rst:323 msgid "" -"The return value is again optional because the strategy might not need to " -"implement server-side evaluation or because the user-defined :code:" -"`evaluate` method might not complete successfully (e.g., it might fail to " -"load the server-side evaluation data)." +"The return value is again optional because the strategy might not need to" +" implement server-side evaluation or because the user-defined " +":code:`evaluate` method might not complete successfully (e.g., it might " +"fail to load the server-side evaluation data)." msgstr "" #: ../../source/how-to-install-flower.rst:2 @@ -4444,7 +4394,8 @@ msgstr "" #: ../../source/how-to-install-flower.rst:17 msgid "" -"Stable releases are available on `PyPI `_::" +"Stable releases are available on `PyPI " +"`_::" msgstr "" #: ../../source/how-to-install-flower.rst:21 @@ -4463,14 +4414,14 @@ msgstr "" #: ../../source/how-to-install-flower.rst:31 msgid "" -"If you have not added ``conda-forge`` to your channels, you will first need " -"to run the following::" +"If you have not added ``conda-forge`` to your channels, you will first " +"need to run the following::" msgstr "" #: ../../source/how-to-install-flower.rst:36 msgid "" -"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be installed " -"with ``conda``::" +"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " +"installed with ``conda``::" msgstr "" #: ../../source/how-to-install-flower.rst:40 @@ -4484,8 +4435,8 @@ msgstr "" #: ../../source/how-to-install-flower.rst:48 msgid "" "The following command can be used to verify if Flower was successfully " -"installed. If everything worked, it should print the version of Flower to " -"the command line::" +"installed. If everything worked, it should print the version of Flower to" +" the command line::" msgstr "" #: ../../source/how-to-install-flower.rst:55 @@ -4506,15 +4457,15 @@ msgstr "" #: ../../source/how-to-install-flower.rst:65 msgid "" -"New (possibly unstable) versions of Flower are sometimes available as pre-" -"release versions (alpha, beta, release candidate) before the stable release " -"happens::" +"New (possibly unstable) versions of Flower are sometimes available as " +"pre-release versions (alpha, beta, release candidate) before the stable " +"release happens::" msgstr "" #: ../../source/how-to-install-flower.rst:69 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases " -"should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" +" should be installed with the ``simulation`` extra::" msgstr "" #: ../../source/how-to-install-flower.rst:74 @@ -4523,14 +4474,14 @@ msgstr "" #: ../../source/how-to-install-flower.rst:76 msgid "" -"The latest (potentially unstable) changes in Flower are available as nightly " -"releases::" +"The latest (potentially unstable) changes in Flower are available as " +"nightly releases::" msgstr "" #: ../../source/how-to-install-flower.rst:80 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr-nightly`` should " -"be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr-nightly`` " +"should be installed with the ``simulation`` extra::" msgstr "" #: ../../source/how-to-monitor-simulation.rst:2 @@ -4539,17 +4490,17 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" -"Flower allows you to monitor system resources while running your simulation. " -"Moreover, the Flower simulation engine is powerful and enables you to decide " -"how to allocate resources per client manner and constrain the total usage. " -"Insights from resource consumption can help you make smarter decisions and " -"speed up the execution time." +"Flower allows you to monitor system resources while running your " +"simulation. Moreover, the Flower simulation engine is powerful and " +"enables you to decide how to allocate resources per client manner and " +"constrain the total usage. Insights from resource consumption can help " +"you make smarter decisions and speed up the execution time." msgstr "" #: ../../source/how-to-monitor-simulation.rst:6 msgid "" -"The specific instructions assume you are using macOS and have the `Homebrew " -"`_ package manager installed." +"The specific instructions assume you are using macOS and have the " +"`Homebrew `_ package manager installed." msgstr "" #: ../../source/how-to-monitor-simulation.rst:10 @@ -4558,10 +4509,10 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" -"`Prometheus `_ is used for data collection, while " -"`Grafana `_ will enable you to visualize the collected " -"data. They are both well integrated with `Ray `_ which " -"Flower uses under the hood." +"`Prometheus `_ is used for data collection, while" +" `Grafana `_ will enable you to visualize the " +"collected data. They are both well integrated with `Ray " +"`_ which Flower uses under the hood." msgstr "" #: ../../source/how-to-monitor-simulation.rst:18 @@ -4580,21 +4531,22 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" -"Open the respective configuration files and change them. Depending on your " -"device, use one of the two following commands:" +"Open the respective configuration files and change them. Depending on " +"your device, use one of the two following commands:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" -"and then delete all the text in the file and paste a new Prometheus config " -"you see below. You may adjust the time intervals to your requirements:" +"and then delete all the text in the file and paste a new Prometheus " +"config you see below. You may adjust the time intervals to your " +"requirements:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" -"Now after you have edited the Prometheus configuration, do the same with the " -"Grafana configuration files. Open those using one of the following commands " -"as before:" +"Now after you have edited the Prometheus configuration, do the same with " +"the Grafana configuration files. Open those using one of the following " +"commands as before:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:69 @@ -4605,8 +4557,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:84 msgid "" -"Congratulations, you just downloaded all the necessary software needed for " -"metrics tracking. Now, let’s start it." +"Congratulations, you just downloaded all the necessary software needed " +"for metrics tracking. Now, let’s start it." msgstr "" #: ../../source/how-to-monitor-simulation.rst:88 @@ -4621,8 +4573,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:97 msgid "" -"Please include the following argument in your Python code when starting a " -"simulation." +"Please include the following argument in your Python code when starting a" +" simulation." msgstr "" #: ../../source/how-to-monitor-simulation.rst:108 @@ -4631,8 +4583,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:110 msgid "" -"Shortly after the simulation starts, you should see the following logs in " -"your terminal:" +"Shortly after the simulation starts, you should see the following logs in" +" your terminal:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:117 @@ -4641,17 +4593,17 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:119 msgid "" -"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the " -"lowest option)." +"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" +" lowest option)." msgstr "" #: ../../source/how-to-monitor-simulation.rst:121 msgid "" -"Or alternatively, you can just see them in Grafana by clicking on the right-" -"up corner, “View in Grafana”. Please note that the Ray dashboard is only " -"accessible during the simulation. After the simulation ends, you can only " -"use Grafana to explore the metrics. You can start Grafana by going to " -"``http://localhost:3000/``." +"Or alternatively, you can just see them in Grafana by clicking on the " +"right-up corner, “View in Grafana”. Please note that the Ray dashboard is" +" only accessible during the simulation. After the simulation ends, you " +"can only use Grafana to explore the metrics. You can start Grafana by " +"going to ``http://localhost:3000/``." msgstr "" #: ../../source/how-to-monitor-simulation.rst:123 @@ -4667,18 +4619,18 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" -"You must understand how the Ray library works to efficiently allocate system " -"resources to simulation clients on your own." +"You must understand how the Ray library works to efficiently allocate " +"system resources to simulation clients on your own." msgstr "" #: ../../source/how-to-monitor-simulation.rst:136 msgid "" "Initially, the simulation (which Ray handles under the hood) starts by " "default with all the available resources on the system, which it shares " -"among the clients. It doesn't mean it divides it equally among all of them, " -"nor that the model training happens at all of them simultaneously. You will " -"learn more about that in the later part of this blog. You can check the " -"system resources by running the following:" +"among the clients. It doesn't mean it divides it equally among all of " +"them, nor that the model training happens at all of them simultaneously. " +"You will learn more about that in the later part of this blog. You can " +"check the system resources by running the following:" msgstr "" #: ../../source/how-to-monitor-simulation.rst:143 @@ -4687,8 +4639,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:155 msgid "" -"However, you can overwrite the defaults. When starting a simulation, do the " -"following (you don't need to overwrite all of them):" +"However, you can overwrite the defaults. When starting a simulation, do " +"the following (you don't need to overwrite all of them):" msgstr "" #: ../../source/how-to-monitor-simulation.rst:175 @@ -4697,19 +4649,19 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:205 msgid "" -"Now comes the crucial part. Ray will start a new client only when it has all " -"the required resources (such that they run in parallel) when the resources " -"allow." +"Now comes the crucial part. Ray will start a new client only when it has " +"all the required resources (such that they run in parallel) when the " +"resources allow." msgstr "" #: ../../source/how-to-monitor-simulation.rst:207 msgid "" -"In the example above, only one client will be run, so your clients won't run " -"concurrently. Setting :code:`client_num_gpus = 0.5` would allow running two " -"clients and therefore enable them to run concurrently. Be careful not to " -"require more resources than available. If you specified :code:" -"`client_num_gpus = 2`, the simulation wouldn't start (even if you had 2 GPUs " -"but decided to set 1 in :code:`ray_init_args`)." +"In the example above, only one client will be run, so your clients won't " +"run concurrently. Setting :code:`client_num_gpus = 0.5` would allow " +"running two clients and therefore enable them to run concurrently. Be " +"careful not to require more resources than available. If you specified " +":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " +"had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." msgstr "" #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 @@ -4722,21 +4674,22 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:216 msgid "" -"A: The timeframe might not be properly set. The setting is in the top right " -"corner (\"Last 30 minutes\" by default). Please change the timeframe to " -"reflect the period when the simulation was running." +"A: The timeframe might not be properly set. The setting is in the top " +"right corner (\"Last 30 minutes\" by default). Please change the " +"timeframe to reflect the period when the simulation was running." msgstr "" #: ../../source/how-to-monitor-simulation.rst:218 msgid "" -"Q: I see “Grafana server not detected. Please make sure the Grafana server " -"is running and refresh this page” after going to the Metrics tab in Ray " -"Dashboard." +"Q: I see “Grafana server not detected. Please make sure the Grafana " +"server is running and refresh this page” after going to the Metrics tab " +"in Ray Dashboard." msgstr "" #: ../../source/how-to-monitor-simulation.rst:220 msgid "" -"A: You probably don't have Grafana running. Please check the running services" +"A: You probably don't have Grafana running. Please check the running " +"services" msgstr "" #: ../../source/how-to-monitor-simulation.rst:226 @@ -4747,8 +4700,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:228 msgid "" -"A: Either the simulation has already finished, or you still need to start " -"Prometheus." +"A: Either the simulation has already finished, or you still need to start" +" Prometheus." msgstr "" #: ../../source/how-to-monitor-simulation.rst:232 @@ -4771,475 +4724,545 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:4 msgid "" -"The simplest way to get started with Flower is by using the pre-made Docker " -"images, which you can find on `Docker Hub `__." +"The simplest way to get started with Flower is by using the pre-made " +"Docker images, which you can find on `Docker Hub " +"`__. Supported architectures include " +"``amd64`` and ``arm64v8``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:7 +#: ../../source/how-to-run-flower-using-docker.rst:8 msgid "Before you start, make sure that the Docker daemon is running:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:14 +#: ../../source/how-to-run-flower-using-docker.rst:15 msgid "" -"If you do not see the version of Docker but instead get an error saying that " -"the command was not found, you will need to install Docker first. You can " -"find installation instruction `here `_." +"If you do not see the version of Docker but instead get an error saying " +"that the command was not found, you will need to install Docker first. " +"You can find installation instruction `here `_." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:21 msgid "" -"On Linux, Docker commands require ``sudo`` privilege. If you want to avoid " -"using ``sudo``, you can follow the `Post-installation steps `_ on the official Docker " -"website." +"On Linux, Docker commands require ``sudo`` privilege. If you want to " +"avoid using ``sudo``, you can follow the `Post-installation steps " +"`_ on the " +"official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:26 +#: ../../source/how-to-run-flower-using-docker.rst:27 msgid "" -"To ensure optimal performance and compatibility, the SuperLink, SuperNode " -"and ServerApp image must have the same version when running together. This " -"guarantees seamless integration and avoids potential conflicts or issues " -"that may arise from using different versions." +"To ensure optimal performance and compatibility, the SuperLink, SuperNode" +" and ServerApp image must have the same version when running together. " +"This guarantees seamless integration and avoids potential conflicts or " +"issues that may arise from using different versions." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:31 +#: ../../source/how-to-run-flower-using-docker.rst:32 msgid "Flower SuperLink" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:34 +#: ../../source/how-to-run-flower-using-docker.rst:35 msgid "Quickstart" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:36 +#: ../../source/how-to-run-flower-using-docker.rst:37 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:42 +#: ../../source/how-to-run-flower-using-docker.rst:43 msgid "" -"The command pulls the Docker image with the tag ``1.8.0`` from Docker Hub. " -"The tag specifies the Flower version. In this case, Flower 1.8.0. The ``--" -"rm`` flag tells Docker to remove the container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker " +"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " +"The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:49 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " -"Docker flag ``--rm``, the state is not persisted between container starts. " -"We will show below how to save the state in a file on your host system." +"Docker flag ``--rm``, the state is not persisted between container " +"starts. We will show below how to save the state in a file on your host " +"system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:52 +#: ../../source/how-to-run-flower-using-docker.rst:53 msgid "" -"The ``-p :`` flag tells Docker to map the ports ``9091``/" -"``9092`` of the host to ``9091``/``9092`` of the container, allowing you to " -"access the Driver API on ``http://localhost:9091`` and the Fleet API on " -"``http://localhost:9092``. Lastly, any flag that comes after the tag is " -"passed to the Flower SuperLink. Here, we are passing the flag ``--insecure``." +"The ``-p :`` flag tells Docker to map the ports " +"``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " +"allowing you to access the Driver API on ``http://localhost:9091`` and " +"the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " +"after the tag is passed to the Flower SuperLink. Here, we are passing the" +" flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:59 -#: ../../source/how-to-run-flower-using-docker.rst:238 -#: ../../source/how-to-run-flower-using-docker.rst:354 +#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:259 +#: ../../source/how-to-run-flower-using-docker.rst:376 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " -"HTTPS) and should only be used for testing purposes. We strongly recommend " -"enabling `SSL `__ when deploying to a " -"production environment." +"HTTPS) and should only be used for testing purposes. We strongly " +"recommend enabling `SSL `__ when " +"deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:64 +#: ../../source/how-to-run-flower-using-docker.rst:65 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:71 +#: ../../source/how-to-run-flower-using-docker.rst:72 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:73 +#: ../../source/how-to-run-flower-using-docker.rst:74 +msgid "" +"If you want to persist the state of the SuperLink on your host system, " +"all you need to do is specify a directory where you want to save the file" +" on your host system and a name for the database file. By default, the " +"SuperLink container runs with a non-root user called ``app`` with the " +"user ID ``49999``. It is recommended to create new directory and change " +"the user ID of the directory to ``49999`` to ensure the mounted directory" +" has the proper permissions. If you later want to delete the directory, " +"you can change the user ID back to the current user ID by running ``sudo " +"chown -R $USER:$(id -gn) state``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:82 msgid "" -"If you want to persist the state of the SuperLink on your host system, all " -"you need to do is specify a path where you want to save the file on your " -"host system and a name for the database file. In the example below, we tell " -"Docker via the flag ``--volume`` to mount the user's home directory (``~/`` " -"on your host) into the ``/app/`` directory of the container. Furthermore, we " -"use the flag ``--database`` to specify the name of the database file." +"In the example below, we create a new directory, change the user ID and " +"tell Docker via the flag ``--volume`` to mount the local ``state`` " +"directory into the ``/app/state`` directory of the container. " +"Furthermore, we use the flag ``--database`` to specify the name of the " +"database file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:86 +#: ../../source/how-to-run-flower-using-docker.rst:95 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, the " -"SuperLink tries to restore the state from the file. To start the SuperLink " -"with an empty database, simply remove the ``state.db`` file." +"``state`` directory on your host system. If the file already exists, the " +"SuperLink tries to restore the state from the file. To start the " +"SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:91 -#: ../../source/how-to-run-flower-using-docker.rst:260 -#: ../../source/how-to-run-flower-using-docker.rst:375 +#: ../../source/how-to-run-flower-using-docker.rst:100 +#: ../../source/how-to-run-flower-using-docker.rst:281 +#: ../../source/how-to-run-flower-using-docker.rst:397 msgid "Enabling SSL for secure connections" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:93 +#: ../../source/how-to-run-flower-using-docker.rst:102 +msgid "" +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" +"encoded private key and a PEM-encoded certificate chain." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:106 msgid "" -"To enable SSL, you will need a PEM-encoded root certificate, a PEM-encoded " -"private key and a PEM-encoded certificate chain." +"For testing purposes, you can generate your own self-signed certificates." +" The `Enable SSL connections `__ page contains a section that" +" will guide you through the process." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:97 +#: ../../source/how-to-run-flower-using-docker.rst:110 msgid "" -"For testing purposes, you can generate your own self-signed certificates. " -"The `Enable SSL connections `__ page contains a section that will " -"guide you through the process." +"Assuming all files we need are in the local ``certificates`` directory, " +"we can use the flag ``--volume`` to mount the local directory into the " +"``/app/certificates/`` directory of the container. This allows the " +"SuperLink to access the files within the container. The ``ro`` stands for" +" ``read-only``. Docker volumes default to ``read-write``; that option " +"tells Docker to make the volume ``read-only`` instead. Finally, we pass " +"the names of the certificates and key file to the SuperLink with the " +"``--ssl-ca-certfile``, ``--ssl-certfile`` and ``--ssl-keyfile`` flag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:101 +#: ../../source/how-to-run-flower-using-docker.rst:128 msgid "" -"Assuming all files we need are in the local ``certificates`` directory, we " -"can use the flag ``--volume`` to mount the local directory into the ``/app/" -"`` directory of the container. This allows the SuperLink to access the files " -"within the container. Finally, we pass the names of the certificates to the " -"SuperLink with the ``--certificates`` flag." +"Because Flower containers, by default, run with a non-root user ``app``, " +"the mounted files and directories must have the proper permissions for " +"the user ID ``49999``. For example, to change the user ID of all files in" +" the ``certificates/`` directory, you can run ``sudo chown -R 49999:49999" +" certificates/*``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:113 +#: ../../source/how-to-run-flower-using-docker.rst:134 msgid "Flower SuperNode" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:115 +#: ../../source/how-to-run-flower-using-docker.rst:136 msgid "" -"The SuperNode Docker image comes with a pre-installed version of Flower and " -"serves as a base for building your own SuperNode image." +"The SuperNode Docker image comes with a pre-installed version of Flower " +"and serves as a base for building your own SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:120 +#: ../../source/how-to-run-flower-using-docker.rst:141 msgid "" "The SuperNode Docker image currently works only with the 1.9.0-nightly " -"release. A stable version will be available when Flower 1.9.0 (stable) gets " -"released (ETA: May). A SuperNode nightly image must be paired with the " -"corresponding SuperLink and ServerApp nightly images released on the same " -"day. To ensure the versions are in sync, using the concrete tag, e.g., " -"``1.9.0.dev20240501`` instead of ``nightly`` is recommended." +"release. A stable version will be available when Flower 1.9.0 (stable) " +"gets released (ETA: May). A SuperNode nightly image must be paired with " +"the corresponding SuperLink and ServerApp nightly images released on the " +"same day. To ensure the versions are in sync, using the concrete tag, " +"e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:126 +#: ../../source/how-to-run-flower-using-docker.rst:147 msgid "" -"We will use the ``quickstart-pytorch`` example, which you can find in the " -"Flower repository, to illustrate how you can dockerize your ClientApp." +"We will use the ``quickstart-pytorch`` example, which you can find in the" +" Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:134 +#: ../../source/how-to-run-flower-using-docker.rst:155 msgid "" "Before we can start, we need to meet a few prerequisites in our local " -"development environment. You can skip the first part if you want to run your " -"ClientApp instead of the ``quickstart-pytorch`` example." +"development environment. You can skip the first part if you want to run " +"your ClientApp instead of the ``quickstart-pytorch`` example." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:138 +#: ../../source/how-to-run-flower-using-docker.rst:159 msgid "Clone the Flower repository." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:152 +#: ../../source/how-to-run-flower-using-docker.rst:173 msgid "Creating a SuperNode Dockerfile" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:154 -#: ../../source/how-to-run-flower-using-docker.rst:289 +#: ../../source/how-to-run-flower-using-docker.rst:175 +#: ../../source/how-to-run-flower-using-docker.rst:311 msgid "Let's assume the following project layout:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:163 +#: ../../source/how-to-run-flower-using-docker.rst:184 msgid "" -"First, we need to create a ``requirements.txt`` file in the directory where " -"the ``ClientApp`` code is located. In the file, we list all the dependencies " -"that the ClientApp requires." +"First, we need to create a ``requirements.txt`` file in the directory " +"where the ``ClientApp`` code is located. In the file, we list all the " +"dependencies that the ClientApp requires." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:175 +#: ../../source/how-to-run-flower-using-docker.rst:196 msgid "" -"Note that `flwr `__ is already installed in " -"the ``flwr/supernode`` base image, so you only need to include other package " -"dependencies in your ``requirements.txt``, such as ``torch``, " +"Note that `flwr `__ is already installed " +"in the ``flwr/supernode`` base image, so you only need to include other " +"package dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:179 +#: ../../source/how-to-run-flower-using-docker.rst:200 msgid "" -"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` example, " -"create a new file called ``Dockerfile.supernode`` in ``examples/quickstart-" -"pytorch``." +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " +"example, create a new file called ``Dockerfile.supernode`` in ``examples" +"/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:182 +#: ../../source/how-to-run-flower-using-docker.rst:203 msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:196 +#: ../../source/how-to-run-flower-using-docker.rst:217 msgid "" -"In the first two lines, we instruct Docker to use the SuperNode image tagged " -"``nightly`` as a base image and set our working directory to ``/app``. The " -"following instructions will now be executed in the ``/app`` directory. Next, " -"we install the ClientApp dependencies by copying the ``requirements.txt`` " -"file into the image and run ``pip install``. In the last two lines, we copy " -"the ``client.py`` module into the image and set the entry point to ``flower-" -"client-app`` with the argument ``client:app``. The argument is the object " -"reference of the ClientApp (``:``) that will be run " -"inside the ClientApp." +"In the first two lines, we instruct Docker to use the SuperNode image " +"tagged ``nightly`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. Next, we install the ClientApp dependencies by copying the " +"``requirements.txt`` file into the image and run ``pip install``. In the " +"last two lines, we copy the ``client.py`` module into the image and set " +"the entry point to ``flower-client-app`` with the argument " +"``client:app``. The argument is the object reference of the ClientApp " +"(``:``) that will be run inside the ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:205 +#: ../../source/how-to-run-flower-using-docker.rst:226 msgid "Building the SuperNode Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:207 +#: ../../source/how-to-run-flower-using-docker.rst:228 msgid "" -"Next, we build the SuperNode Docker image by running the following command " -"in the directory where Dockerfile and ClientApp code are located." +"Next, we build the SuperNode Docker image by running the following " +"command in the directory where Dockerfile and ClientApp code are located." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:214 +#: ../../source/how-to-run-flower-using-docker.rst:235 msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:219 +#: ../../source/how-to-run-flower-using-docker.rst:240 msgid "Running the SuperNode Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:221 +#: ../../source/how-to-run-flower-using-docker.rst:242 msgid "Now that we have built the SuperNode image, we can finally run it." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:229 -#: ../../source/how-to-run-flower-using-docker.rst:345 +#: ../../source/how-to-run-flower-using-docker.rst:250 +#: ../../source/how-to-run-flower-using-docker.rst:367 msgid "Let's break down each part of this command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:231 -#: ../../source/how-to-run-flower-using-docker.rst:347 +#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:369 msgid "``docker run``: This is the command to run a new Docker container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:232 -#: ../../source/how-to-run-flower-using-docker.rst:348 +#: ../../source/how-to-run-flower-using-docker.rst:253 +#: ../../source/how-to-run-flower-using-docker.rst:370 msgid "" -"``--rm``: This option specifies that the container should be automatically " -"removed when it stops." +"``--rm``: This option specifies that the container should be " +"automatically removed when it stops." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:233 +#: ../../source/how-to-run-flower-using-docker.rst:254 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:234 -#: ../../source/how-to-run-flower-using-docker.rst:350 +#: ../../source/how-to-run-flower-using-docker.rst:255 +#: ../../source/how-to-run-flower-using-docker.rst:372 msgid "``--insecure``: This option enables insecure communication." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the " -"SuperLinks Fleet" +"``--superlink 192.168.1.100:9092``: This option specifies the address of " +"the SuperLinks Fleet" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "API to connect to. Remember to update it with your SuperLink IP." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:248 +#: ../../source/how-to-run-flower-using-docker.rst:269 msgid "" -"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " -"network to run your SuperNodes." +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your SuperNodes." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:273 msgid "" "Any argument that comes after the tag is passed to the Flower SuperNode " "binary. To see all available flags that the SuperNode supports, run:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:262 +#: ../../source/how-to-run-flower-using-docker.rst:283 msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your SuperNode container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:264 +#: ../../source/how-to-run-flower-using-docker.rst:285 msgid "" -"Assuming the certificate already exists locally, we can use the flag ``--" -"volume`` to mount the local certificate into the container's ``/app/`` " -"directory. This allows the SuperNode to access the certificate within the " -"container. Use the ``--certificates`` flag when starting the container." +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the SuperNode to access the certificate " +"within the container. Use the ``--root-certificates`` flag when starting " +"the container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:275 +#: ../../source/how-to-run-flower-using-docker.rst:297 msgid "Flower ServerApp" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:277 +#: ../../source/how-to-run-flower-using-docker.rst:299 msgid "" -"The procedure for building and running a ServerApp image is almost identical " -"to the SuperNode image." +"The procedure for building and running a ServerApp image is almost " +"identical to the SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:279 +#: ../../source/how-to-run-flower-using-docker.rst:301 msgid "" -"Similar to the SuperNode image, the ServerApp Docker image comes with a pre-" -"installed version of Flower and serves as a base for building your own " -"ServerApp image." +"Similar to the SuperNode image, the ServerApp Docker image comes with a " +"pre-installed version of Flower and serves as a base for building your " +"own ServerApp image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:282 +#: ../../source/how-to-run-flower-using-docker.rst:304 msgid "" -"We will use the same ``quickstart-pytorch`` example as we do in the Flower " -"SuperNode section. If you have not already done so, please follow the " -"`SuperNode Prerequisites`_ before proceeding." +"We will use the same ``quickstart-pytorch`` example as we do in the " +"Flower SuperNode section. If you have not already done so, please follow " +"the `SuperNode Prerequisites`_ before proceeding." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:287 +#: ../../source/how-to-run-flower-using-docker.rst:309 msgid "Creating a ServerApp Dockerfile" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:298 +#: ../../source/how-to-run-flower-using-docker.rst:320 msgid "" "First, we need to create a Dockerfile in the directory where the " "``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " -"example, create a new file called ``Dockerfile.serverapp`` in ``examples/" -"quickstart-pytorch``." +"example, create a new file called ``Dockerfile.serverapp`` in ``examples" +"/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:302 +#: ../../source/how-to-run-flower-using-docker.rst:324 msgid "" "The ``Dockerfile.serverapp`` contains the instructions that assemble the " "ServerApp image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:313 +#: ../../source/how-to-run-flower-using-docker.rst:335 msgid "" -"In the first two lines, we instruct Docker to use the ServerApp image tagged " -"``1.8.0`` as a base image and set our working directory to ``/app``. The " -"following instructions will now be executed in the ``/app`` directory. In " -"the last two lines, we copy the ``server.py`` module into the image and set " -"the entry point to ``flower-server-app`` with the argument ``server:app``. " -"The argument is the object reference of the ServerApp (``:" -"``) that will be run inside the ServerApp container." +"In the first two lines, we instruct Docker to use the ServerApp image " +"tagged ``1.8.0`` as a base image and set our working directory to " +"``/app``. The following instructions will now be executed in the ``/app``" +" directory. In the last two lines, we copy the ``server.py`` module into " +"the image and set the entry point to ``flower-server-app`` with the " +"argument ``server:app``. The argument is the object reference of the " +"ServerApp (``:``) that will be run inside the " +"ServerApp container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:321 +#: ../../source/how-to-run-flower-using-docker.rst:343 msgid "Building the ServerApp Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:323 +#: ../../source/how-to-run-flower-using-docker.rst:345 msgid "" -"Next, we build the ServerApp Docker image by running the following command " -"in the directory where Dockerfile and ServerApp code are located." +"Next, we build the ServerApp Docker image by running the following " +"command in the directory where Dockerfile and ServerApp code are located." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:330 +#: ../../source/how-to-run-flower-using-docker.rst:352 msgid "" "We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:335 +#: ../../source/how-to-run-flower-using-docker.rst:357 msgid "Running the ServerApp Docker image" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:337 +#: ../../source/how-to-run-flower-using-docker.rst:359 msgid "Now that we have built the ServerApp image, we can finally run it." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:349 +#: ../../source/how-to-run-flower-using-docker.rst:371 msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9091``: This option specifies the address of the " -"SuperLinks Driver" +"``--superlink 192.168.1.100:9091``: This option specifies the address of " +"the SuperLinks Driver" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:363 +#: ../../source/how-to-run-flower-using-docker.rst:385 msgid "" -"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " -"network to run your ServerApps." +"To test running Flower locally, you can create a `bridge network " +"`__, use the ``--network`` argument and pass the " +"name of the Docker network to run your ServerApps." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:367 +#: ../../source/how-to-run-flower-using-docker.rst:389 msgid "" "Any argument that comes after the tag is passed to the Flower ServerApp " "binary. To see all available flags that the ServerApp supports, run:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:377 +#: ../../source/how-to-run-flower-using-docker.rst:399 msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your ServerApp container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:379 +#: ../../source/how-to-run-flower-using-docker.rst:401 msgid "" -"Assuming the certificate already exists locally, we can use the flag ``--" -"volume`` to mount the local certificate into the container's ``/app/`` " -"directory. This allows the ServerApp to access the certificate within the " -"container. Use the ``--certificates`` flag when starting the container." +"Assuming the certificate already exists locally, we can use the flag " +"``--volume`` to mount the local certificate into the container's " +"``/app/`` directory. This allows the ServerApp to access the certificate " +"within the container. Use the ``--root-certificates`` flags when starting" +" the container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:390 +#: ../../source/how-to-run-flower-using-docker.rst:412 msgid "Advanced Docker options" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:393 +#: ../../source/how-to-run-flower-using-docker.rst:415 +msgid "Run with root user privileges" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:417 +msgid "" +"Flower Docker images, by default, run with a non-root user " +"(username/groupname: ``app``, UID/GID: ``49999``). Using root user is not" +" recommended unless it is necessary for specific tasks during the build " +"process. Always make sure to run the container as a non-root user in " +"production to maintain security best practices." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:422 +msgid "**Run a container with root user privileges**" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:424 +msgid "" +"Run the Docker image with the ``-u`` flag and specify ``root`` as the " +"username:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:430 +msgid "This command will run the Docker container with root user privileges." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:432 +msgid "**Run the build process with root user privileges**" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:434 +msgid "" +"If you want to switch to the root user during the build process of the " +"Docker image to install missing system dependencies, you can use the " +"``USER root`` directive within your Dockerfile." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:454 msgid "Using a different Flower version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:395 +#: ../../source/how-to-run-flower-using-docker.rst:456 msgid "" "If you want to use a different version of Flower, for example Flower " -"nightly, you can do so by changing the tag. All available versions are on " -"`Docker Hub `__." +"nightly, you can do so by changing the tag. All available versions are on" +" `Docker Hub `__." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:400 +#: ../../source/how-to-run-flower-using-docker.rst:460 msgid "Pinning a Docker image to a specific version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:402 +#: ../../source/how-to-run-flower-using-docker.rst:462 msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that you " -"always use the same image, you can specify the hash of the image instead of " -"the tag." +"change the functionality of Flower. However, if you want to ensure that " +"you always use the same image, you can specify the hash of the image " +"instead of the tag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:407 +#: ../../source/how-to-run-flower-using-docker.rst:467 msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:414 +#: ../../source/how-to-run-flower-using-docker.rst:474 msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:423 +#: ../../source/how-to-run-flower-using-docker.rst:483 msgid "Setting environment variables" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:425 +#: ../../source/how-to-run-flower-using-docker.rst:485 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." @@ -5252,60 +5275,63 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:8 msgid "" "Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients but " -"without having to source, configure and mange a large number of physical " -"devices; you might want to run your FL workloads as fast as possible on the " -"compute systems you have access to without having to go through a complex " -"setup process; you might want to validate your algorithm on different " -"scenarios at varying levels of data and system heterogeneity, client " -"availability, privacy budgets, etc. These are among some of the use-cases " -"where simulating FL workloads makes sense. Flower can accommodate these " -"scenarios by means of its `VirtualClientEngine `_ or VCE." +"cases: you might want to run your workload on a large cohort of clients " +"but without having to source, configure and mange a large number of " +"physical devices; you might want to run your FL workloads as fast as " +"possible on the compute systems you have access to without having to go " +"through a complex setup process; you might want to validate your " +"algorithm on different scenarios at varying levels of data and system " +"heterogeneity, client availability, privacy budgets, etc. These are among" +" some of the use-cases where simulating FL workloads makes sense. Flower " +"can accommodate these scenarios by means of its `VirtualClientEngine " +"`_ or " +"VCE." msgstr "" #: ../../source/how-to-run-simulations.rst:10 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " -"clients. These clients are identical to `non-virtual` clients (i.e. the ones " -"you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by creating a " -"class inheriting, for example, from `flwr.client.NumPyClient `_ and therefore behave in an identical way. In " -"addition to that, clients managed by the :code:`VirtualClientEngine` are:" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" +" clients. These clients are identical to `non-virtual` clients (i.e. the " +"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " +"creating a class inheriting, for example, from `flwr.client.NumPyClient " +"`_ and therefore behave in an " +"identical way. In addition to that, clients managed by the " +":code:`VirtualClientEngine` are:" msgstr "" #: ../../source/how-to-run-simulations.rst:12 msgid "" -"resource-aware: this means that each client gets assigned a portion of the " -"compute and memory on your system. You as a user can control this at the " -"beginning of the simulation and allows you to control the degree of " +"resource-aware: this means that each client gets assigned a portion of " +"the compute and memory on your system. You as a user can control this at " +"the beginning of the simulation and allows you to control the degree of " "parallelism of your Flower FL simulation. The fewer the resources per " "client, the more clients can run concurrently on the same hardware." msgstr "" #: ../../source/how-to-run-simulations.rst:13 msgid "" -"self-managed: this means that you as a user do not need to launch clients " -"manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"self-managed: this means that you as a user do not need to launch clients" +" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " "internals." msgstr "" #: ../../source/how-to-run-simulations.rst:14 msgid "" -"ephemeral: this means that a client is only materialized when it is required " -"in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards, releasing the resources it was " -"assigned and allowing in this way other clients to participate." +"ephemeral: this means that a client is only materialized when it is " +"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," +" releasing the resources it was assigned and allowing in this way other " +"clients to participate." msgstr "" #: ../../source/how-to-run-simulations.rst:16 msgid "" "The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " "`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use of " -"`Actors `_ to spawn " -"`virtual` clients and run their workload." +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " +"of `Actors `_ to " +"spawn `virtual` clients and run their workload." msgstr "" #: ../../source/how-to-run-simulations.rst:20 @@ -5314,11 +5340,12 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:22 msgid "" -"Running Flower simulations still require you to define your client class, a " -"strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your simulation " -"is done with `start_simulation `_ and a minimal example looks as follows:" +"Running Flower simulations still require you to define your client class," +" a strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your " +"simulation is done with `start_simulation `_ and a minimal example looks" +" as follows:" msgstr "" #: ../../source/how-to-run-simulations.rst:44 @@ -5327,16 +5354,16 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:45 msgid "" -"By default the VCE has access to all system resources (i.e. all CPUs, all " -"GPUs, etc) since that is also the default behavior when starting Ray. " -"However, in some settings you might want to limit how many of your system " -"resources are used for simulation. You can do this via the :code:" -"`ray_init_args` input argument to :code:`start_simulation` which the VCE " -"internally passes to Ray's :code:`ray.init` command. For a complete list of " -"settings you can configure check the `ray.init `_ documentation. Do not set :" -"code:`ray_init_args` if you want the VCE to use all your system's CPUs and " -"GPUs." +"By default the VCE has access to all system resources (i.e. all CPUs, all" +" GPUs, etc) since that is also the default behavior when starting Ray. " +"However, in some settings you might want to limit how many of your system" +" resources are used for simulation. You can do this via the " +":code:`ray_init_args` input argument to :code:`start_simulation` which " +"the VCE internally passes to Ray's :code:`ray.init` command. For a " +"complete list of settings you can configure check the `ray.init " +"`_" +" documentation. Do not set :code:`ray_init_args` if you want the VCE to " +"use all your system's CPUs and GPUs." msgstr "" #: ../../source/how-to-run-simulations.rst:62 @@ -5345,19 +5372,20 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:63 msgid "" -"By default the :code:`VirtualClientEngine` assigns a single CPU core (and " -"nothing else) to each virtual client. This means that if your system has 10 " -"cores, that many virtual clients can be concurrently running." +"By default the :code:`VirtualClientEngine` assigns a single CPU core (and" +" nothing else) to each virtual client. This means that if your system has" +" 10 cores, that many virtual clients can be concurrently running." msgstr "" #: ../../source/how-to-run-simulations.rst:65 msgid "" -"More often than not, you would probably like to adjust the resources your " -"clients get assigned based on the complexity (i.e. compute and memory " -"footprint) of your FL workload. You can do so when starting your simulation " -"by setting the argument `client_resources` to `start_simulation `_. Two keys are internally used " -"by Ray to schedule and spawn workloads (in our case Flower clients):" +"More often than not, you would probably like to adjust the resources your" +" clients get assigned based on the complexity (i.e. compute and memory " +"footprint) of your FL workload. You can do so when starting your " +"simulation by setting the argument `client_resources` to " +"`start_simulation `_." +" Two keys are internally used by Ray to schedule and spawn workloads (in " +"our case Flower clients):" msgstr "" #: ../../source/how-to-run-simulations.rst:67 @@ -5378,21 +5406,21 @@ msgstr "" msgid "" "While the :code:`client_resources` can be used to control the degree of " "concurrency in your FL simulation, this does not stop you from running " -"dozens, hundreds or even thousands of clients in the same round and having " -"orders of magnitude more `dormant` (i.e. not participating in a round) " -"clients. Let's say you want to have 100 clients per round but your system " -"can only accommodate 8 clients concurrently. The :code:`VirtualClientEngine` " -"will schedule 100 jobs to run (each simulating a client sampled by the " -"strategy) and then will execute them in a resource-aware manner in batches " -"of 8." +"dozens, hundreds or even thousands of clients in the same round and " +"having orders of magnitude more `dormant` (i.e. not participating in a " +"round) clients. Let's say you want to have 100 clients per round but your" +" system can only accommodate 8 clients concurrently. The " +":code:`VirtualClientEngine` will schedule 100 jobs to run (each " +"simulating a client sampled by the strategy) and then will execute them " +"in a resource-aware manner in batches of 8." msgstr "" #: ../../source/how-to-run-simulations.rst:91 msgid "" "To understand all the intricate details on how resources are used to " -"schedule FL clients and how to define custom resources, please take a look " -"at the `Ray documentation `_." +"schedule FL clients and how to define custom resources, please take a " +"look at the `Ray documentation `_." msgstr "" #: ../../source/how-to-run-simulations.rst:94 @@ -5401,22 +5429,22 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:96 msgid "" -"A few ready-to-run complete examples for Flower simulation in Tensorflow/" -"Keras and PyTorch are provided in the `Flower repository `_. You can run them on Google Colab too:" +"A few ready-to-run complete examples for Flower simulation in " +"Tensorflow/Keras and PyTorch are provided in the `Flower repository " +"`_. You can run them on Google Colab too:" msgstr "" #: ../../source/how-to-run-simulations.rst:98 msgid "" -"`Tensorflow/Keras Simulation `_: 100 clients collaboratively train a MLP " -"model on MNIST." +"`Tensorflow/Keras Simulation " +"`_: 100 clients collaboratively train a MLP model on MNIST." msgstr "" #: ../../source/how-to-run-simulations.rst:99 msgid "" -"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " +"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " "MNIST." msgstr "" @@ -5426,9 +5454,9 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:106 msgid "" -"Flower's :code:`VirtualClientEngine` allows you to run FL simulations across " -"multiple compute nodes. Before starting your multi-node simulation ensure " -"that you:" +"Flower's :code:`VirtualClientEngine` allows you to run FL simulations " +"across multiple compute nodes. Before starting your multi-node simulation" +" ensure that you:" msgstr "" #: ../../source/how-to-run-simulations.rst:108 @@ -5441,29 +5469,29 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:110 msgid "" -"Have a copy of your dataset in all nodes (more about this in :ref:" -"`simulation considerations `)" +"Have a copy of your dataset in all nodes (more about this in " +":ref:`simulation considerations `)" msgstr "" #: ../../source/how-to-run-simulations.rst:111 msgid "" -"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation `_ so the :code:" -"`VirtualClientEngine` attaches to a running Ray instance." +"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation " +"`_ so the " +":code:`VirtualClientEngine` attaches to a running Ray instance." msgstr "" #: ../../source/how-to-run-simulations.rst:112 msgid "" -"Start Ray on you head node: on the terminal type :code:`ray start --head`. " -"This command will print a few lines, one of which indicates how to attach " -"other nodes to the head node." +"Start Ray on you head node: on the terminal type :code:`ray start " +"--head`. This command will print a few lines, one of which indicates how " +"to attach other nodes to the head node." msgstr "" #: ../../source/how-to-run-simulations.rst:113 msgid "" -"Attach other nodes to the head node: copy the command shown after starting " -"the head and execute it on terminal of a new node: for example :code:`ray " -"start --address='192.168.1.132:6379'`" +"Attach other nodes to the head node: copy the command shown after " +"starting the head and execute it on terminal of a new node: for example " +":code:`ray start --address='192.168.1.132:6379'`" msgstr "" #: ../../source/how-to-run-simulations.rst:115 @@ -5474,9 +5502,9 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:117 msgid "" -"Once your simulation is finished, if you'd like to dismantle your cluster " -"you simply need to run the command :code:`ray stop` in each node's terminal " -"(including the head node)." +"Once your simulation is finished, if you'd like to dismantle your cluster" +" you simply need to run the command :code:`ray stop` in each node's " +"terminal (including the head node)." msgstr "" #: ../../source/how-to-run-simulations.rst:120 @@ -5491,19 +5519,21 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:124 msgid "" -"User :code:`ray status` to check all nodes connected to your head node as " -"well as the total resources available to the :code:`VirtualClientEngine`." +"User :code:`ray status` to check all nodes connected to your head node as" +" well as the total resources available to the " +":code:`VirtualClientEngine`." msgstr "" #: ../../source/how-to-run-simulations.rst:126 msgid "" -"When attaching a new node to the head, all its resources (i.e. all CPUs, all " -"GPUs) will be visible by the head node. This means that the :code:" -"`VirtualClientEngine` can schedule as many `virtual` clients as that node " -"can possible run. In some settings you might want to exclude certain " -"resources from the simulation. You can do this by appending `--num-" -"cpus=` and/or `--num-gpus=` in any :" -"code:`ray start` command (including when starting the head)" +"When attaching a new node to the head, all its resources (i.e. all CPUs, " +"all GPUs) will be visible by the head node. This means that the " +":code:`VirtualClientEngine` can schedule as many `virtual` clients as " +"that node can possible run. In some settings you might want to exclude " +"certain resources from the simulation. You can do this by appending " +"`--num-cpus=` and/or `--num-" +"gpus=` in any :code:`ray start` command (including " +"when starting the head)" msgstr "" #: ../../source/how-to-run-simulations.rst:132 @@ -5512,19 +5542,19 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:135 msgid "" -"We are actively working on these fronts so to make it trivial to run any FL " -"workload with Flower simulation." +"We are actively working on these fronts so to make it trivial to run any " +"FL workload with Flower simulation." msgstr "" #: ../../source/how-to-run-simulations.rst:138 msgid "" -"The current VCE allows you to run Federated Learning workloads in simulation " -"mode whether you are prototyping simple scenarios on your personal laptop or " -"you want to train a complex FL pipeline across multiple high-performance GPU " -"nodes. While we add more capabilities to the VCE, the points below highlight " -"some of the considerations to keep in mind when designing your FL pipeline " -"with Flower. We also highlight a couple of current limitations in our " -"implementation." +"The current VCE allows you to run Federated Learning workloads in " +"simulation mode whether you are prototyping simple scenarios on your " +"personal laptop or you want to train a complex FL pipeline across " +"multiple high-performance GPU nodes. While we add more capabilities to " +"the VCE, the points below highlight some of the considerations to keep in" +" mind when designing your FL pipeline with Flower. We also highlight a " +"couple of current limitations in our implementation." msgstr "" #: ../../source/how-to-run-simulations.rst:141 @@ -5533,16 +5563,17 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:143 msgid "" -"The VCE assigns a share of GPU memory to a client that specifies the key :" -"code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " +"The VCE assigns a share of GPU memory to a client that specifies the key " +":code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " "internally by the VCE) is by default:" msgstr "" #: ../../source/how-to-run-simulations.rst:146 msgid "" -"not aware of the total VRAM available on the GPUs. This means that if you " -"set :code:`num_gpus=0.5` and you have two GPUs in your system with different " -"(e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients concurrently." +"not aware of the total VRAM available on the GPUs. This means that if you" +" set :code:`num_gpus=0.5` and you have two GPUs in your system with " +"different (e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients" +" concurrently." msgstr "" #: ../../source/how-to-run-simulations.rst:147 @@ -5561,16 +5592,17 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:150 msgid "" "If you want to run several independent Flower simulations on the same " -"machine you need to mask-out your GPUs with :code:" -"`CUDA_VISIBLE_DEVICES=\"\"` when launching your experiment." +"machine you need to mask-out your GPUs with " +":code:`CUDA_VISIBLE_DEVICES=\"\"` when launching your " +"experiment." msgstr "" #: ../../source/how-to-run-simulations.rst:153 msgid "" -"In addition, the GPU resource limits passed to :code:`client_resources` are " -"not `enforced` (i.e. they can be exceeded) which can result in the situation " -"of client using more VRAM than the ratio specified when starting the " -"simulation." +"In addition, the GPU resource limits passed to :code:`client_resources` " +"are not `enforced` (i.e. they can be exceeded) which can result in the " +"situation of client using more VRAM than the ratio specified when " +"starting the simulation." msgstr "" #: ../../source/how-to-run-simulations.rst:156 @@ -5579,29 +5611,31 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:158 msgid "" -"When `using a GPU with TensorFlow `_ " -"nearly your entire GPU memory of all your GPUs visible to the process will " -"be mapped. This is done by TensorFlow for optimization purposes. However, in " -"settings such as FL simulations where we want to split the GPU into multiple " -"`virtual` clients, this is not a desirable mechanism. Luckily we can disable " -"this default behavior by `enabling memory growth `_." +"When `using a GPU with TensorFlow " +"`_ nearly your entire GPU memory of" +" all your GPUs visible to the process will be mapped. This is done by " +"TensorFlow for optimization purposes. However, in settings such as FL " +"simulations where we want to split the GPU into multiple `virtual` " +"clients, this is not a desirable mechanism. Luckily we can disable this " +"default behavior by `enabling memory growth " +"`_." msgstr "" #: ../../source/how-to-run-simulations.rst:160 msgid "" -"This would need to be done in the main process (which is where the server " -"would run) and in each Actor created by the VCE. By means of :code:" -"`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` in order " -"to specify a function to be executed upon actor initialization. In this " -"case, to enable GPU growth for TF workloads. It would look as follows:" +"This would need to be done in the main process (which is where the server" +" would run) and in each Actor created by the VCE. By means of " +":code:`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` " +"in order to specify a function to be executed upon actor initialization. " +"In this case, to enable GPU growth for TF workloads. It would look as " +"follows:" msgstr "" #: ../../source/how-to-run-simulations.rst:179 msgid "" "This is precisely the mechanism used in `Tensorflow/Keras Simulation " -"`_ " -"example." +"`_ example." msgstr "" #: ../../source/how-to-run-simulations.rst:183 @@ -5610,25 +5644,26 @@ msgstr "" #: ../../source/how-to-run-simulations.rst:185 msgid "" -"The VCE does not currently offer a way to control on which node a particular " -"`virtual` client is executed. In other words, if more than a single node " -"have the resources needed by a client to run, then any of those nodes could " -"get the client workload scheduled onto. Later in the FL process (i.e. in a " -"different round) the same client could be executed by a different node. " -"Depending on how your clients access their datasets, this might require " -"either having a copy of all dataset partitions on all nodes or a dataset " -"serving mechanism (e.g. using nfs, a database) to circumvent data " -"duplication." +"The VCE does not currently offer a way to control on which node a " +"particular `virtual` client is executed. In other words, if more than a " +"single node have the resources needed by a client to run, then any of " +"those nodes could get the client workload scheduled onto. Later in the FL" +" process (i.e. in a different round) the same client could be executed by" +" a different node. Depending on how your clients access their datasets, " +"this might require either having a copy of all dataset partitions on all " +"nodes or a dataset serving mechanism (e.g. using nfs, a database) to " +"circumvent data duplication." msgstr "" #: ../../source/how-to-run-simulations.rst:187 msgid "" -"By definition virtual clients are `stateless` due to their ephemeral nature. " -"A client state can be implemented as part of the Flower client class but " -"users need to ensure this saved to persistent storage (e.g. a database, " -"disk) and that can be retrieve later by the same client regardless on which " -"node it is running from. This is related to the point above also since, in " -"some way, the client's dataset could be seen as a type of `state`." +"By definition virtual clients are `stateless` due to their ephemeral " +"nature. A client state can be implemented as part of the Flower client " +"class but users need to ensure this saved to persistent storage (e.g. a " +"database, disk) and that can be retrieve later by the same client " +"regardless on which node it is running from. This is related to the point" +" above also since, in some way, the client's dataset could be seen as a " +"type of `state`." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:2 @@ -5637,9 +5672,9 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:4 msgid "" -"Flower does not automatically save model updates on the server-side. This " -"how-to guide describes the steps to save (and load) model checkpoints in " -"Flower." +"Flower does not automatically save model updates on the server-side. This" +" how-to guide describes the steps to save (and load) model checkpoints in" +" Flower." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:8 @@ -5648,15 +5683,16 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:10 msgid "" -"Model updates can be persisted on the server-side by customizing :code:" -"`Strategy` methods. Implementing custom strategies is always an option, but " -"for many cases it may be more convenient to simply customize an existing " -"strategy. The following code example defines a new :code:`SaveModelStrategy` " -"which customized the existing built-in :code:`FedAvg` strategy. In " -"particular, it customizes :code:`aggregate_fit` by calling :code:" -"`aggregate_fit` in the base class (:code:`FedAvg`). It then continues to " -"save returned (aggregated) weights before it returns those aggregated " -"weights to the caller (i.e., the server):" +"Model updates can be persisted on the server-side by customizing " +":code:`Strategy` methods. Implementing custom strategies is always an " +"option, but for many cases it may be more convenient to simply customize " +"an existing strategy. The following code example defines a new " +":code:`SaveModelStrategy` which customized the existing built-in " +":code:`FedAvg` strategy. In particular, it customizes " +":code:`aggregate_fit` by calling :code:`aggregate_fit` in the base class " +"(:code:`FedAvg`). It then continues to save returned (aggregated) weights" +" before it returns those aggregated weights to the caller (i.e., the " +"server):" msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:47 @@ -5665,25 +5701,25 @@ msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:49 msgid "" -"Similar to the previous example but with a few extra steps, we'll show how " -"to store a PyTorch checkpoint we'll use the ``torch.save`` function. " -"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be " -"transformed into a list of NumPy ``ndarray``'s, then those are transformed " -"into the PyTorch ``state_dict`` following the ``OrderedDict`` class " -"structure." +"Similar to the previous example but with a few extra steps, we'll show " +"how to store a PyTorch checkpoint we'll use the ``torch.save`` function. " +"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be" +" transformed into a list of NumPy ``ndarray``'s, then those are " +"transformed into the PyTorch ``state_dict`` following the ``OrderedDict``" +" class structure." msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:85 msgid "" -"To load your progress, you simply append the following lines to your code. " -"Note that this will iterate over all saved checkpoints and load the latest " -"one:" +"To load your progress, you simply append the following lines to your " +"code. Note that this will iterate over all saved checkpoints and load the" +" latest one:" msgstr "" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 msgid "" -"Return/use this object of type ``Parameters`` wherever necessary, such as in " -"the ``initial_parameters`` when defining a ``Strategy``." +"Return/use this object of type ``Parameters`` wherever necessary, such as" +" in the ``initial_parameters`` when defining a ``Strategy``." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:2 @@ -5692,10 +5728,10 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:4 msgid "" -"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable " -"foundation for future growth. Compared to Flower 0.19 (and other 0.x series " -"releases), there are a few breaking changes that make it necessary to change " -"the code of existing 0.x-series projects." +"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable" +" foundation for future growth. Compared to Flower 0.19 (and other 0.x " +"series releases), there are a few breaking changes that make it necessary" +" to change the code of existing 0.x-series projects." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 @@ -5705,8 +5741,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:10 msgid "" -"Here's how to update an existing installation to Flower 1.0 using either pip " -"or Poetry:" +"Here's how to update an existing installation to Flower 1.0 using either " +"pip or Poetry:" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:12 @@ -5733,14 +5769,13 @@ msgid "" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:19 -msgid "" -"``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" +msgid "``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:20 msgid "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when using " -"``start_simulation``)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when " +"using ``start_simulation``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 @@ -5771,7 +5806,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:34 msgid "" "Flower 1.0 (keyword arguments): " -"``start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())``" +"``start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:37 @@ -5809,8 +5845,9 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:48 msgid "" -"Flower 1.0: ``start_server(..., config=flwr.server." -"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" +"Flower 1.0: ``start_server(..., " +"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " +"...)``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:50 @@ -5822,9 +5859,9 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:51 msgid "" "Remove ``force_final_distributed_eval`` parameter from calls to " -"``start_server``. Distributed evaluation on all clients can be enabled by " -"configuring the strategy to sample all clients for evaluation after the last " -"round of training." +"``start_server``. Distributed evaluation on all clients can be enabled by" +" configuring the strategy to sample all clients for evaluation after the " +"last round of training." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:52 @@ -5841,12 +5878,12 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:57 msgid "" -"Strategy initialization: if the strategy relies on the default values for " -"``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " +"Strategy initialization: if the strategy relies on the default values for" +" ``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " "``fraction_evaluate`` manually to ``0.1``. Projects that do not manually " "create a strategy (by calling ``start_server`` or ``start_simulation`` " -"without passing a strategy instance) should now manually initialize FedAvg " -"with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." +"without passing a strategy instance) should now manually initialize " +"FedAvg with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:58 @@ -5878,14 +5915,15 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:67 msgid "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " -"Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " +"Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:68 msgid "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " -"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " +"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " +"Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:71 @@ -5894,10 +5932,11 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:73 msgid "" -"The type of parameter ``failures`` has changed from ``List[BaseException]`` " -"to ``List[Union[Tuple[ClientProxy, FitRes], BaseException]]`` (in " -"``aggregate_fit``) and ``List[Union[Tuple[ClientProxy, EvaluateRes], " -"BaseException]]`` (in ``aggregate_evaluate``)" +"The type of parameter ``failures`` has changed from " +"``List[BaseException]`` to ``List[Union[Tuple[ClientProxy, FitRes], " +"BaseException]]`` (in ``aggregate_fit``) and " +"``List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]]`` (in " +"``aggregate_evaluate``)" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:74 @@ -5914,8 +5953,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:77 msgid "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" -"> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " +"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:80 @@ -5931,8 +5970,9 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:84 msgid "" "Remove \"placeholder\" methods from subclasses of ``Client`` or " -"``NumPyClient``. If you, for example, use server-side evaluation, then empty " -"placeholder implementations of ``evaluate`` are no longer necessary." +"``NumPyClient``. If you, for example, use server-side evaluation, then " +"empty placeholder implementations of ``evaluate`` are no longer " +"necessary." msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:85 @@ -5949,11 +5989,11 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-1.0.rst:91 msgid "" -"Most official `Flower code examples `_ are already updated to Flower 1.0, they can serve as a " -"reference for using the Flower 1.0 API. If there are further questions, " -"`join the Flower Slack `_ and use the channel " -"``#questions``." +"Most official `Flower code examples " +"`_ are already updated" +" to Flower 1.0, they can serve as a reference for using the Flower 1.0 " +"API. If there are further questions, `join the Flower Slack " +"`_ and use the channel ``#questions``." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:2 @@ -5962,17 +6002,19 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:4 msgid "" -"Welcome to the migration guide for updating Flower to Flower Next! Whether " -"you're a seasoned user or just getting started, this guide will help you " -"smoothly transition your existing setup to take advantage of the latest " -"features and improvements in Flower Next, starting from version 1.8." +"Welcome to the migration guide for updating Flower to Flower Next! " +"Whether you're a seasoned user or just getting started, this guide will " +"help you smoothly transition your existing setup to take advantage of the" +" latest features and improvements in Flower Next, starting from version " +"1.8." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:9 msgid "" "This guide shows how to reuse pre-``1.8`` Flower code with minimum code " -"changes by using the *compatibility layer* in Flower Next. In another guide, " -"we will show how to run Flower Next end-to-end with pure Flower Next APIs." +"changes by using the *compatibility layer* in Flower Next. In another " +"guide, we will show how to run Flower Next end-to-end with pure Flower " +"Next APIs." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:13 @@ -5981,8 +6023,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:48 msgid "" -"Here's how to update an existing installation of Flower to Flower Next with " -"``pip``:" +"Here's how to update an existing installation of Flower to Flower Next " +"with ``pip``:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:54 @@ -5991,7 +6033,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:61 msgid "" -"Ensure you set the following version constraint in your ``requirements.txt``" +"Ensure you set the following version constraint in your " +"``requirements.txt``" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:71 @@ -6011,19 +6054,21 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:86 msgid "" -"Ensure you set the following version constraint in your ``pyproject.toml``:" +"Ensure you set the following version constraint in your " +"``pyproject.toml``:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" "In Flower Next, the *infrastructure* and *application layers* have been " -"decoupled. Instead of starting a client in code via ``start_client()``, you " -"create a |clientapp_link|_ and start it via the command line. Instead of " -"starting a server in code via ``start_server()``, you create a |" -"serverapp_link|_ and start it via the command line. The long-running " +"decoupled. Instead of starting a client in code via ``start_client()``, " +"you create a |clientapp_link|_ and start it via the command line. Instead" +" of starting a server in code via ``start_server()``, you create a " +"|serverapp_link|_ and start it via the command line. The long-running " "components of server and client are called SuperLink and SuperNode. The " -"following non-breaking changes that require manual updates and allow you to " -"run your project both in the traditional way and in the Flower Next way:" +"following non-breaking changes that require manual updates and allow you " +"to run your project both in the traditional way and in the Flower Next " +"way:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:109 @@ -6032,8 +6077,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" -"Wrap your existing client with |clientapp_link|_ instead of launching it via " -"|startclient_link|_. Here's an example:" +"Wrap your existing client with |clientapp_link|_ instead of launching it " +"via |startclient_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:132 @@ -6042,8 +6087,8 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:133 msgid "" -"Wrap your existing strategy with |serverapp_link|_ instead of starting the " -"server via |startserver_link|_. Here's an example:" +"Wrap your existing strategy with |serverapp_link|_ instead of starting " +"the server via |startserver_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:154 @@ -6052,21 +6097,24 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:155 msgid "" -"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, in " -"sequence, |flowernext_clientapp_link|_ (2x) and |flowernext_serverapp_link|" -"_. There is no need to execute `client.py` and `server.py` as Python scripts." +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " +"in sequence, |flowernext_clientapp_link|_ (2x) and " +"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" +" `server.py` as Python scripts." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:158 msgid "" -"Here's an example to start the server without HTTPS (only for prototyping):" +"Here's an example to start the server without HTTPS (only for " +"prototyping):" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" -"Here's another example to start with HTTPS. Use the ``--certificates`` " -"command line argument to pass paths to (CA certificate, server certificate, " -"and server private key)." +"Here's another example to start with HTTPS. Use the ``--ssl-ca-" +"certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line " +"options to pass paths to (CA certificate, server certificate, and server " +"private key)." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:201 @@ -6075,24 +6123,24 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:202 msgid "" -"Wrap your existing client and strategy with |clientapp_link|_ and |" -"serverapp_link|_, respectively. There is no need to use |startsim_link|_ " -"anymore. Here's an example:" +"Wrap your existing client and strategy with |clientapp_link|_ and " +"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" +" anymore. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:232 msgid "" "Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " -"``client_app`` object in the code instead of executing the Python script. " -"Here's an example (assuming the ``server_app`` and ``client_app`` objects " -"are in a ``sim.py`` module):" +"``client_app`` object in the code instead of executing the Python script." +" Here's an example (assuming the ``server_app`` and ``client_app`` " +"objects are in a ``sim.py`` module):" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:249 msgid "" "Set default resources for each |clientapp_link|_ using the ``--backend-" -"config`` command line argument instead of setting the ``client_resources`` " -"argument in |startsim_link|_. Here's an example:" +"config`` command line argument instead of setting the " +"``client_resources`` argument in |startsim_link|_. Here's an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:275 @@ -6101,19 +6149,19 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:276 msgid "" -"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's an " -"example:" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " +"an example:" msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:319 msgid "" -"Some official `Flower code examples `_ are " -"already updated to Flower Next so they can serve as a reference for using " -"the Flower Next API. If there are further questions, `join the Flower Slack " -"`_ and use the channel ``#questions``. You " -"can also `participate in Flower Discuss `_ where " -"you can find us answering questions, or share and learn from others about " -"migrating to Flower Next." +"Some official `Flower code examples `_ " +"are already updated to Flower Next so they can serve as a reference for " +"using the Flower Next API. If there are further questions, `join the " +"Flower Slack `_ and use the channel " +"``#questions``. You can also `participate in Flower Discuss " +"`_ where you can find us answering questions," +" or share and learn from others about migrating to Flower Next." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:325 @@ -6137,16 +6185,16 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:4 msgid "" -"**Note: This tutorial covers experimental features. The functionality and " -"interfaces may change in future versions.**" +"**Note: This tutorial covers experimental features. The functionality and" +" interfaces may change in future versions.**" msgstr "" #: ../../source/how-to-use-built-in-mods.rst:6 msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment the " -"behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) allow us " -"to perform operations before and after a task is processed in the " -"``ClientApp``." +"In this tutorial, we will learn how to utilize built-in mods to augment " +"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " +"allow us to perform operations before and after a task is processed in " +"the ``ClientApp``." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:9 @@ -6155,9 +6203,9 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:11 msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate or " -"inspect the incoming ``Message`` and the resulting outgoing ``Message``. The " -"signature for a ``Mod`` is as follows:" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " +"or inspect the incoming ``Message`` and the resulting outgoing " +"``Message``. The signature for a ``Mod`` is as follows:" msgstr "" #: ../../source/how-to-use-built-in-mods.rst:18 @@ -6234,16 +6282,16 @@ msgstr "" #: ../../source/how-to-use-built-in-mods.rst:82 msgid "" -"Each mod has a chance to inspect and modify the incoming ``Message`` before " -"passing it to the next mod, and likewise with the outgoing ``Message`` " -"before returning it up the stack." +"Each mod has a chance to inspect and modify the incoming ``Message`` " +"before passing it to the next mod, and likewise with the outgoing " +"``Message`` before returning it up the stack." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:87 msgid "" "By following this guide, you have learned how to effectively use mods to " -"enhance your ``ClientApp``'s functionality. Remember that the order of mods " -"is crucial and affects how the input and output are processed." +"enhance your ``ClientApp``'s functionality. Remember that the order of " +"mods is crucial and affects how the input and output are processed." msgstr "" #: ../../source/how-to-use-built-in-mods.rst:89 @@ -6256,25 +6304,25 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:3 msgid "" -"This guide explains how you can utilize differential privacy in the Flower " -"framework. If you are not yet familiar with differential privacy, you can " -"refer to :doc:`explanation-differential-privacy`." +"This guide explains how you can utilize differential privacy in the " +"Flower framework. If you are not yet familiar with differential privacy, " +"you can refer to :doc:`explanation-differential-privacy`." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:7 msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " -"these features in a production environment with sensitive data, feel free " -"contact us to discuss your requirements and to receive guidance on how to " -"best use these features." +"these features in a production environment with sensitive data, feel free" +" contact us to discuss your requirements and to receive guidance on how " +"to best use these features." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:12 msgid "" -"This approach consists of two seprate phases: clipping of the updates and " -"adding noise to the aggregated model. For the clipping phase, Flower " -"framework has made it possible to decide whether to perform clipping on the " -"server side or the client side." +"This approach consists of two seprate phases: clipping of the updates and" +" adding noise to the aggregated model. For the clipping phase, Flower " +"framework has made it possible to decide whether to perform clipping on " +"the server side or the client side." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:15 @@ -6282,16 +6330,16 @@ msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " "communication overhead for clipping values. However, it also has the " -"disadvantage of increasing the computational load on the server due to the " -"need to perform the clipping operation for all clients." +"disadvantage of increasing the computational load on the server due to " +"the need to perform the clipping operation for all clients." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:16 msgid "" -"**Client-side Clipping**: This approach has the advantage of reducing the " -"computational overhead on the server. However, it also has the disadvantage " -"of lacking centralized control, as the server has less control over the " -"clipping process." +"**Client-side Clipping**: This approach has the advantage of reducing the" +" computational overhead on the server. However, it also has the " +"disadvantage of lacking centralized control, as the server has less " +"control over the clipping process." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:21 @@ -6302,10 +6350,10 @@ msgstr "" msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " -"(for example, :code:`FedAvg`). The two wrapper classes are :code:" -"`DifferentialPrivacyServerSideFixedClipping` and :code:" -"`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and adaptive " -"clipping." +"(for example, :code:`FedAvg`). The two wrapper classes are " +":code:`DifferentialPrivacyServerSideFixedClipping` and " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " +"adaptive clipping." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6314,10 +6362,11 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:31 msgid "" -"The code sample below enables the :code:`FedAvg` strategy to use server-side " -"fixed clipping using the :code:`DifferentialPrivacyServerSideFixedClipping` " -"wrapper class. The same approach can be used with :code:" -"`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " +"The code sample below enables the :code:`FedAvg` strategy to use server-" +"side fixed clipping using the " +":code:`DifferentialPrivacyServerSideFixedClipping` wrapper class. The " +"same approach can be used with " +":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" @@ -6328,12 +6377,12 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:53 msgid "" "For central DP with client-side clipping, the server sends the clipping " -"value to selected clients on each round. Clients can use existing Flower :" -"code:`Mods` to perform the clipping. Two mods are available for fixed and " -"adaptive client-side clipping: :code:`fixedclipping_mod` and :code:" -"`adaptiveclipping_mod` with corresponding server-side wrappers :code:" -"`DifferentialPrivacyClientSideFixedClipping` and :code:" -"`DifferentialPrivacyClientSideAdaptiveClipping`." +"value to selected clients on each round. Clients can use existing Flower " +":code:`Mods` to perform the clipping. Two mods are available for fixed " +"and adaptive client-side clipping: :code:`fixedclipping_mod` and " +":code:`adaptiveclipping_mod` with corresponding server-side wrappers " +":code:`DifferentialPrivacyClientSideFixedClipping` and " +":code:`DifferentialPrivacyClientSideAdaptiveClipping`." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6343,24 +6392,24 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:63 msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " -"differential privacy with client-side fixed clipping using both the :code:" -"`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on the " -"client, :code:`fixedclipping_mod`:" +"differential privacy with client-side fixed clipping using both the " +":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " +"the client, :code:`fixedclipping_mod`:" msgstr "" #: ../../source/how-to-use-differential-privacy.rst:80 msgid "" -"In addition to the server-side strategy wrapper, the :code:`ClientApp` needs " -"to configure the matching :code:`fixedclipping_mod` to perform the client-" -"side clipping:" +"In addition to the server-side strategy wrapper, the :code:`ClientApp` " +"needs to configure the matching :code:`fixedclipping_mod` to perform the " +"client-side clipping:" msgstr "" #: ../../source/how-to-use-differential-privacy.rst:97 msgid "" -"To utilize local differential privacy (DP) and add noise to the client model " -"parameters before transmitting them to the server in Flower, you can use the " -"`LocalDpMod`. The following hyperparameters need to be set: clipping norm " -"value, sensitivity, epsilon, and delta." +"To utilize local differential privacy (DP) and add noise to the client " +"model parameters before transmitting them to the server in Flower, you " +"can use the `LocalDpMod`. The following hyperparameters need to be set: " +"clipping norm value, sensitivity, epsilon, and delta." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:-1 @@ -6373,9 +6422,10 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:122 msgid "" -"Please note that the order of mods, especially those that modify parameters, " -"is important when using multiple modifiers. Typically, differential privacy " -"(DP) modifiers should be the last to operate on parameters." +"Please note that the order of mods, especially those that modify " +"parameters, is important when using multiple modifiers. Typically, " +"differential privacy (DP) modifiers should be the last to operate on " +"parameters." msgstr "" #: ../../source/how-to-use-differential-privacy.rst:125 @@ -6384,12 +6434,13 @@ msgstr "" #: ../../source/how-to-use-differential-privacy.rst:126 msgid "" -"For ensuring data instance-level privacy during local model training on the " -"client side, consider leveraging privacy engines such as Opacus and " -"TensorFlow Privacy. For examples of using Flower with these engines, please " -"refer to the Flower examples directory (`Opacus `_, `Tensorflow Privacy `_)." +"For ensuring data instance-level privacy during local model training on " +"the client side, consider leveraging privacy engines such as Opacus and " +"TensorFlow Privacy. For examples of using Flower with these engines, " +"please refer to the Flower examples directory (`Opacus " +"`_, `Tensorflow" +" Privacy `_)." msgstr "" #: ../../source/how-to-use-strategies.rst:2 @@ -6398,15 +6449,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:4 msgid "" -"Flower allows full customization of the learning process through the :code:" -"`Strategy` abstraction. A number of built-in strategies are provided in the " -"core framework." +"Flower allows full customization of the learning process through the " +":code:`Strategy` abstraction. A number of built-in strategies are " +"provided in the core framework." msgstr "" #: ../../source/how-to-use-strategies.rst:6 msgid "" -"There are three ways to customize the way Flower orchestrates the learning " -"process on the server side:" +"There are three ways to customize the way Flower orchestrates the " +"learning process on the server side:" msgstr "" #: ../../source/how-to-use-strategies.rst:8 @@ -6429,15 +6480,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:16 msgid "" -"Flower comes with a number of popular federated learning strategies built-" -"in. A built-in strategy can be instantiated as follows:" +"Flower comes with a number of popular federated learning strategies " +"built-in. A built-in strategy can be instantiated as follows:" msgstr "" #: ../../source/how-to-use-strategies.rst:25 msgid "" -"This creates a strategy with all parameters left at their default values and " -"passes it to the :code:`start_server` function. It is usually recommended to " -"adjust a few parameters during instantiation:" +"This creates a strategy with all parameters left at their default values " +"and passes it to the :code:`start_server` function. It is usually " +"recommended to adjust a few parameters during instantiation:" msgstr "" #: ../../source/how-to-use-strategies.rst:42 @@ -6454,27 +6505,28 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:47 msgid "" "The server can pass new configuration values to the client each round by " -"providing a function to :code:`on_fit_config_fn`. The provided function will " -"be called by the strategy and must return a dictionary of configuration key " -"values pairs that will be sent to the client. It must return a dictionary of " -"arbitrary configuration values :code:`client.fit` and :code:`client." -"evaluate` functions during each round of federated learning." +"providing a function to :code:`on_fit_config_fn`. The provided function " +"will be called by the strategy and must return a dictionary of " +"configuration key values pairs that will be sent to the client. It must " +"return a dictionary of arbitrary configuration values :code:`client.fit`" +" and :code:`client.evaluate` functions during each round of federated " +"learning." msgstr "" #: ../../source/how-to-use-strategies.rst:75 msgid "" "The :code:`on_fit_config_fn` can be used to pass arbitrary configuration " "values from server to client, and poetentially change these values each " -"round, for example, to adjust the learning rate. The client will receive the " -"dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client." -"fit()` function." +"round, for example, to adjust the learning rate. The client will receive " +"the dictionary returned by the :code:`on_fit_config_fn` in its own " +":code:`client.fit()` function." msgstr "" #: ../../source/how-to-use-strategies.rst:78 msgid "" -"Similar to :code:`on_fit_config_fn`, there is also :code:" -"`on_evaluate_config_fn` to customize the configuration sent to :code:`client." -"evaluate()`" +"Similar to :code:`on_fit_config_fn`, there is also " +":code:`on_evaluate_config_fn` to customize the configuration sent to " +":code:`client.evaluate()`" msgstr "" #: ../../source/how-to-use-strategies.rst:81 @@ -6483,15 +6535,15 @@ msgstr "" #: ../../source/how-to-use-strategies.rst:83 msgid "" -"Server-side evaluation can be enabled by passing an evaluation function to :" -"code:`evaluate_fn`." +"Server-side evaluation can be enabled by passing an evaluation function " +"to :code:`evaluate_fn`." msgstr "" #: ../../source/how-to-use-strategies.rst:89 msgid "" -"Writing a fully custom strategy is a bit more involved, but it provides the " -"most flexibility. Read the `Implementing Strategies `_ guide to learn more." +"Writing a fully custom strategy is a bit more involved, but it provides " +"the most flexibility. Read the `Implementing Strategies `_ guide to learn more." msgstr "" #: ../../source/index.rst:34 @@ -6530,11 +6582,11 @@ msgstr "" msgid "Contributor how-to guides" msgstr "" -#: ../../source/index.rst:173 +#: ../../source/index.rst:172 msgid "Contributor explanations" msgstr "" -#: ../../source/index.rst:179 +#: ../../source/index.rst:178 msgid "Contributor references" msgstr "" @@ -6577,8 +6629,8 @@ msgstr "" msgid "" "The user guide is targeted at researchers and developers who want to use " "Flower to bring existing machine learning workloads into a federated " -"setting. One of Flower's design goals was to make this simple. Read on to " -"learn more." +"setting. One of Flower's design goals was to make this simple. Read on to" +" learn more." msgstr "" #: ../../source/index.rst:30 @@ -6587,20 +6639,21 @@ msgstr "" #: ../../source/index.rst:32 msgid "" -"A learning-oriented series of federated learning tutorials, the best place " -"to start." +"A learning-oriented series of federated learning tutorials, the best " +"place to start." msgstr "" #: ../../source/index.rst:61 msgid "" -"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" -"`TensorFlow ` | :doc:`🤗 Transformers " -"` | :doc:`JAX ` | :" -"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:" -"`XGBoost ` | :doc:`Android ` | :doc:`iOS `" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | " +":doc:`TensorFlow ` | :doc:`🤗 Transformers" +" ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " +"` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " +":doc:`Android ` | :doc:`iOS `" msgstr "" #: ../../source/index.rst:63 @@ -6613,8 +6666,8 @@ msgstr "" #: ../../source/index.rst:76 msgid "" -"Problem-oriented how-to guides show step-by-step how to achieve a specific " -"goal." +"Problem-oriented how-to guides show step-by-step how to achieve a " +"specific goal." msgstr "" #: ../../source/index.rst:110 @@ -6645,8 +6698,8 @@ msgstr "" #: ../../source/index.rst:150 msgid "" -"The Flower community welcomes contributions. The following docs are intended " -"to help along the way." +"The Flower community welcomes contributions. The following docs are " +"intended to help along the way." msgstr "" #: ../../source/ref-api-cli.rst:2 @@ -6673,7 +6726,8 @@ msgstr "" msgid "flwr" msgstr "" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 +#: ../../source/ref-api/flwr.client.rst:45 ../../source/ref-api/flwr.rst:25 +#: ../../source/ref-api/flwr.server.rst:49 msgid "Modules" msgstr "" @@ -6698,7 +6752,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr "" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:38::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." msgstr "" @@ -6715,6 +6769,7 @@ msgstr "" msgid "client" msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:13 #: ../../source/ref-api/flwr.client.rst:13 #: ../../source/ref-api/flwr.common.rst:13 #: ../../source/ref-api/flwr.server.rst:13 @@ -6753,8 +6808,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.rst:25::1 msgid "" -":py:obj:`start_numpy_client `\\ \\(\\*\\, " -"server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\," +" server\\_address\\, client\\)" msgstr "" #: ../../source/ref-api/flwr.client.rst:25::1 @@ -6762,9 +6817,10 @@ msgstr "" msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:30 #: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:28 +#: ../../source/ref-api/flwr.server.rst:26 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" @@ -6781,7 +6837,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.rst:34::1 msgid "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " +"mods\\]\\)" msgstr "" #: ../../source/ref-api/flwr.client.rst:34::1 @@ -6798,6 +6855,14 @@ msgstr "" msgid "Abstract base class for Flower clients using NumPy." msgstr "" +#: ../../source/ref-api/flwr.client.rst:52::1 +msgid ":py:obj:`flwr.client.mod `\\" +msgstr "" + +#: ../../source/ref-api/flwr.client.rst:52::1 flwr.client.mod:1 of +msgid "Flower Built-in Mods." +msgstr "" + #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 @@ -6808,6 +6873,7 @@ msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 #: ../../source/ref-api/flwr.client.NumPyClient.rst:15 +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:15 #: ../../source/ref-api/flwr.common.Array.rst:15 #: ../../source/ref-api/flwr.common.ClientMessage.rst:15 #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:15 @@ -6904,8 +6970,7 @@ msgid "Get the run context from this client." msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid "" -":py:obj:`get_parameters `\\ \\(ins\\)" +msgid ":py:obj:`get_parameters `\\ \\(ins\\)" msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 @@ -6916,8 +6981,7 @@ msgid "Return the current local model parameters." msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid "" -":py:obj:`get_properties `\\ \\(ins\\)" +msgid ":py:obj:`get_properties `\\ \\(ins\\)" msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:44::1 @@ -6985,6 +7049,7 @@ msgstr "" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters #: flwr.client.client.Client.get_properties +#: flwr.client.mod.localdp_mod.LocalDpMod #: flwr.client.numpy_client.NumPyClient.evaluate #: flwr.client.numpy_client.NumPyClient.fit #: flwr.client.numpy_client.NumPyClient.get_parameters @@ -7031,9 +7096,9 @@ msgstr "" #: flwr.client.client.Client.evaluate:3 of msgid "" -"The evaluation instructions containing (global) model parameters received " -"from the server and a dictionary of configuration values used to customize " -"the local evaluation process." +"The evaluation instructions containing (global) model parameters received" +" from the server and a dictionary of configuration values used to " +"customize the local evaluation process." msgstr "" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit @@ -7100,15 +7165,15 @@ msgstr "" #: flwr.client.client.Client.fit:3 of msgid "" -"The training instructions containing (global) model parameters received from " -"the server and a dictionary of configuration values used to customize the " -"local training process." +"The training instructions containing (global) model parameters received " +"from the server and a dictionary of configuration values used to " +"customize the local training process." msgstr "" #: flwr.client.client.Client.fit:8 of msgid "" -"The training result containing updated parameters and other details such as " -"the number of local training examples used for training." +"The training result containing updated parameters and other details such " +"as the number of local training examples used for training." msgstr "" #: flwr.client.client.Client.get_parameters:3 of @@ -7135,10 +7200,11 @@ msgstr "" msgid "ClientApp" msgstr "" -#: flwr.client.client_app.ClientApp:1 flwr.common.constant.MessageType:1 -#: flwr.common.constant.MessageTypeLegacy:1 flwr.common.context.Context:1 -#: flwr.common.message.Error:1 flwr.common.message.Message:1 -#: flwr.common.message.Metadata:1 flwr.common.record.parametersrecord.Array:1 +#: flwr.client.client_app.ClientApp:1 flwr.client.mod.localdp_mod.LocalDpMod:1 +#: flwr.common.constant.MessageType:1 flwr.common.constant.MessageTypeLegacy:1 +#: flwr.common.context.Context:1 flwr.common.message.Error:1 +#: flwr.common.message.Message:1 flwr.common.message.Metadata:1 +#: flwr.common.record.parametersrecord.Array:1 #: flwr.common.record.recordset.RecordSet:1 flwr.common.typing.ClientMessage:1 #: flwr.common.typing.DisconnectRes:1 flwr.common.typing.EvaluateIns:1 #: flwr.common.typing.EvaluateRes:1 flwr.common.typing.FitIns:1 @@ -7159,7 +7225,8 @@ msgstr "" #: flwr.client.client_app.ClientApp:4 #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 -#: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 +#: flwr.client.client_app.ClientApp.train:4 +#: flwr.client.mod.localdp_mod.LocalDpMod:22 flwr.server.app.start_server:41 #: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 @@ -7177,15 +7244,15 @@ msgstr "" #: flwr.client.client_app.ClientApp:16 of msgid "" -"If the above code is in a Python module called `client`, it can be started " -"as follows:" +"If the above code is in a Python module called `client`, it can be " +"started as follows:" msgstr "" #: flwr.client.client_app.ClientApp:21 of msgid "" -"In this `client:app` example, `client` refers to the Python module `client." -"py` in which the previous code lives in and `app` refers to the global " -"attribute `app` that points to an object of type `ClientApp`." +"In this `client:app` example, `client` refers to the Python module " +"`client.py` in which the previous code lives in and `app` refers to the " +"global attribute `app` that points to an object of type `ClientApp`." msgstr "" #: flwr.client.client_app.ClientApp.evaluate:1::1 of @@ -7226,8 +7293,7 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 -msgid "" -":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7258,7 +7324,8 @@ msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" -":py:obj:`set_context `\\ \\(context\\)" +":py:obj:`set_context `\\ " +"\\(context\\)" msgstr "" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 @@ -7286,10 +7353,10 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:5 of msgid "" -"Configuration parameters which allow the server to influence evaluation on " -"the client. It can be used to communicate arbitrary values from the server " -"to the client, for example, to influence the number of examples used for " -"evaluation." +"Configuration parameters which allow the server to influence evaluation " +"on the client. It can be used to communicate arbitrary values from the " +"server to the client, for example, to influence the number of examples " +"used for evaluation." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of @@ -7297,13 +7364,14 @@ msgid "" "* **loss** (*float*) -- The evaluation loss of the model on the local " "dataset. * **num_examples** (*int*) -- The number of examples used for " "evaluation. * **metrics** (*Dict[str, Scalar]*) -- A dictionary mapping " -"arbitrary string keys to values of type bool, bytes, float, int, or str. " -"It can be used to communicate arbitrary values back to the server." +"arbitrary string keys to values of type bool, bytes, float, int, or " +"str. It can be used to communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" -"**loss** (*float*) -- The evaluation loss of the model on the local dataset." +"**loss** (*float*) -- The evaluation loss of the model on the local " +"dataset." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:12 of @@ -7313,32 +7381,33 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:13 #: flwr.client.numpy_client.NumPyClient.fit:13 of msgid "" -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " -"keys to values of type bool, bytes, float, int, or str. It can be used to " -"communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " +"string keys to values of type bool, bytes, float, int, or str. It can be " +"used to communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.evaluate:19 of msgid "" -"The previous return type format (int, float, float) and the extended format " -"(int, float, float, Dict[str, Scalar]) have been deprecated and removed " -"since Flower 0.19." +"The previous return type format (int, float, float) and the extended " +"format (int, float, float, Dict[str, Scalar]) have been deprecated and " +"removed since Flower 0.19." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:5 of msgid "" -"Configuration parameters which allow the server to influence training on the " -"client. It can be used to communicate arbitrary values from the server to " -"the client, for example, to set the number of (local) training epochs." +"Configuration parameters which allow the server to influence training on " +"the client. It can be used to communicate arbitrary values from the " +"server to the client, for example, to set the number of (local) training " +"epochs." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "" "* **parameters** (*NDArrays*) -- The locally updated model parameters. * " "**num_examples** (*int*) -- The number of examples used for training. * " -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " -"keys to values of type bool, bytes, float, int, or str. It can be used to " -"communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " +"string keys to values of type bool, bytes, float, int, or str. It can " +"be used to communicate arbitrary values back to the server." msgstr "" #: flwr.client.numpy_client.NumPyClient.fit:11 of @@ -7351,28 +7420,254 @@ msgstr "" #: flwr.client.numpy_client.NumPyClient.get_parameters:3 of msgid "" -"Configuration parameters requested by the server. This can be used to tell " -"the client which parameters are needed along with some Scalar attributes." +"Configuration parameters requested by the server. This can be used to " +"tell the client which parameters are needed along with some Scalar " +"attributes." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_parameters:8 of -msgid "" -"**parameters** -- The local model parameters as a list of NumPy ndarrays." +msgid "**parameters** -- The local model parameters as a list of NumPy ndarrays." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_properties:3 of msgid "" -"Configuration parameters requested by the server. This can be used to tell " -"the client which properties are needed along with some Scalar attributes." +"Configuration parameters requested by the server. This can be used to " +"tell the client which properties are needed along with some Scalar " +"attributes." msgstr "" #: flwr.client.numpy_client.NumPyClient.get_properties:8 of msgid "" -"**properties** -- A dictionary mapping arbitrary string keys to values of " -"type bool, bytes, float, int, or str. It can be used to communicate " +"**properties** -- A dictionary mapping arbitrary string keys to values of" +" type bool, bytes, float, int, or str. It can be used to communicate " "arbitrary property values back to the server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:2 +msgid "mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`adaptiveclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:1 of +msgid "Client-side adaptive clipping modifier." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`fixedclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:1 of +msgid "Client-side fixed clipping modifier." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.utils.make_ffn:1 of +msgid "." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " +"call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secagg_mod.secagg_mod:1 of +msgid "Handle incoming message and return results, following the SecAgg protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secaggplus_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secaggplus_mod.secaggplus_mod:1 of +msgid "" +"Handle incoming message and return results, following the SecAgg+ " +"protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`message_size_mod `\\ \\(msg\\," +" ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.message_size_mod:1 of +msgid "Message size mod." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`parameters_size_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.parameters_size_mod:1 of +msgid "Parameters size mod." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +msgid "" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\," +" sensitivity\\, ...\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +#: flwr.client.mod.localdp_mod.LocalDpMod:1 of +msgid "Modifier for local differential privacy." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:2 +msgid "LocalDpMod" +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:3 of +msgid "" +"This mod clips the client model updates and adds noise to the params " +"before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:12 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:10 +#: flwr.client.mod.localdp_mod.LocalDpMod:6 of +msgid "It operates on messages of type `MessageType.TRAIN`." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:8 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +msgid "The value of the clipping norm." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:10 of +msgid "The sensitivity of the client model." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:12 of +msgid "" +"The privacy budget. Smaller value of epsilon indicates a higher level of " +"privacy protection." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:15 of +msgid "" +"The failure probability. The probability that the privacy mechanism fails" +" to provide the desired level of privacy. A smaller value of delta " +"indicates a stricter privacy guarantee." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:23 of +msgid "Create an instance of the local DP mod and add it to the client-side mods:" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.adaptiveclipping_mod.rst:2 +msgid "adaptiveclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy " +"wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:6 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:6 of +msgid "The wrapper sends the clipping_norm value to the client." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:8 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:8 of +msgid "This mod clips the client model updates before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:10 of +msgid "" +"It also sends KEY_NORM_BIT to the server for computing the new clipping " +"value." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:15 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:13 +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +msgid "Notes" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:16 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:14 of +msgid "Consider the order of mods when using multiple." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:18 of +msgid "Typically, adaptiveclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.fixedclipping_mod.rst:2 +msgid "fixedclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideFixedClipping server-side strategy wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:16 of +msgid "Typically, fixedclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.make_ffn.rst:2 +msgid "make\\_ffn" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.message_size_mod.rst:2 +msgid "message\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.message_size_mod:3 of +msgid "This mod logs the size in bytes of the message being transmited." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.parameters_size_mod.rst:2 +msgid "parameters\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.parameters_size_mod:3 of +msgid "" +"This mod logs the number of parameters transmitted in the message as well" +" as their size in bytes." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secagg_mod.rst:2 +msgid "secagg\\_mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secaggplus_mod.rst:2 +msgid "secaggplus\\_mod" +msgstr "" + #: ../../source/ref-api/flwr.client.run_client_app.rst:2 msgid "run\\_client\\_app" msgstr "" @@ -7388,7 +7683,8 @@ msgstr "" #: flwr.client.app.start_client:3 flwr.client.app.start_numpy_client:9 of msgid "" "The IPv4 or IPv6 address of the server. If the Flower server runs on the " -"same machine on port 8080, then `server_address` would be `\"[::]:8080\"`." +"same machine on port 8080, then `server_address` would be " +"`\"[::]:8080\"`." msgstr "" #: flwr.client.app.start_client:7 of @@ -7397,52 +7693,52 @@ msgstr "" #: flwr.client.app.start_client:9 of msgid "" -"An implementation of the abstract base class `flwr.client.Client` (default: " -"None)" +"An implementation of the abstract base class `flwr.client.Client` " +"(default: None)" msgstr "" #: flwr.client.app.start_client:12 flwr.client.app.start_numpy_client:15 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower " -"server. The default should be sufficient for most models. Users who train " -"very large models might need to increase this value. Note that the Flower " -"server needs to be started with the same value (see `flwr.server." -"start_server`), otherwise it will not know about the increased limit and " -"block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower" +" server. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower server needs to be started with the same value (see " +"`flwr.server.start_server`), otherwise it will not know about the " +"increased limit and block larger messages." msgstr "" #: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " -"provided, a secure connection using the certificates will be established to " -"an SSL-enabled Flower server." +"provided, a secure connection using the certificates will be established " +"to an SSL-enabled Flower server." msgstr "" #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of msgid "" -"Starts an insecure gRPC connection when True. Enables HTTPS connection when " -"False, using system certificates if `root_certificates` is None." +"Starts an insecure gRPC connection when True. Enables HTTPS connection " +"when False, using system certificates if `root_certificates` is None." msgstr "" #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" "Configure the transport layer. Allowed values: - 'grpc-bidi': gRPC, " -"bidirectional streaming - 'grpc-rere': gRPC, request-response (experimental) " -"- 'rest': HTTP (experimental)" +"bidirectional streaming - 'grpc-rere': gRPC, request-response " +"(experimental) - 'rest': HTTP (experimental)" msgstr "" #: flwr.client.app.start_client:31 of msgid "" "The maximum number of times the client will try to connect to the server " -"before giving up in case of a connection error. If set to None, there is no " -"limit to the number of tries." +"before giving up in case of a connection error. If set to None, there is " +"no limit to the number of tries." msgstr "" #: flwr.client.app.start_client:35 of msgid "" -"The maximum duration before the client stops trying to connect to the server " -"in case of connection error. If set to None, there is no limit to the total " -"time." +"The maximum duration before the client stops trying to connect to the " +"server in case of connection error. If set to None, there is no limit to " +"the total time." msgstr "" #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of @@ -7463,9 +7759,10 @@ msgstr "" #: flwr.client.app.start_numpy_client:5 of msgid "" -"This function is deprecated since 1.7.0. Use :code:`flwr.client." -"start_client` instead and first convert your :code:`NumPyClient` to type :" -"code:`flwr.client.Client` by executing its :code:`to_client()` method." +"This function is deprecated since 1.7.0. Use " +":code:`flwr.client.start_client` instead and first convert your " +":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " +":code:`to_client()` method." msgstr "" #: flwr.client.app.start_numpy_client:13 of @@ -7477,8 +7774,7 @@ msgid "common" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid "" -":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7487,8 +7783,7 @@ msgid "Create Array from NumPy ndarray." msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7530,8 +7825,7 @@ msgid "Log 'msg % args' with the integer severity 'level'." msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:30::1 @@ -7575,7 +7869,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " +"data\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7634,7 +7929,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, " +"config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7692,8 +7988,7 @@ msgid "A dataclass that stores information about an error that occurred." msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 -msgid "" -":py:obj:`GetParametersIns `\\ \\(config\\)" +msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7713,8 +8008,7 @@ msgid "Response when asked to return parameters." msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 -msgid "" -":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7764,8 +8058,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " -"src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, " +"message\\_id\\, src\\_node\\_id\\, ...\\)" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7790,8 +8084,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" -"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " +":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" #: ../../source/ref-api/flwr.common.rst:64::1 @@ -7868,21 +8162,21 @@ msgstr "" #: flwr.common.record.parametersrecord.Array:6 of msgid "" -"A string representing the data type of the serialised object (e.g. `np." -"float32`)" +"A string representing the data type of the serialised object (e.g. " +"`np.float32`)" msgstr "" #: flwr.common.record.parametersrecord.Array:8 of msgid "" -"A list representing the shape of the unserialized array-like object. This is " -"used to deserialize the data (depending on the serialization method) or " -"simply as a metadata field." +"A list representing the shape of the unserialized array-like object. This" +" is used to deserialize the data (depending on the serialization method) " +"or simply as a metadata field." msgstr "" #: flwr.common.record.parametersrecord.Array:12 of msgid "" -"A string indicating the type of serialisation mechanism used to generate the " -"bytes in `data` from an array-like or tensor-like object." +"A string indicating the type of serialisation mechanism used to generate " +"the bytes in `data` from an array-like or tensor-like object." msgstr "" #: flwr.common.record.parametersrecord.Array:15 of @@ -7928,12 +8222,14 @@ msgstr "" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_res `\\" +":py:obj:`get_parameters_res " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_properties_res `\\" +":py:obj:`get_properties_res " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:2 @@ -7950,14 +8246,14 @@ msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 @@ -7966,8 +8262,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:2 @@ -7976,12 +8272,12 @@ msgstr "" #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` | :py:class:" -"`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ [:py:class:`int`] | :" -"py:class:`~typing.List`\\ [:py:class:`float`] | :py:class:`~typing.List`\\ [:" -"py:class:`str`] | :py:class:`~typing.List`\\ [:py:class:`bytes`] | :py:class:" -"`~typing.List`\\ [:py:class:`bool`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" +" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " +"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " +":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" +" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -8027,8 +8323,7 @@ msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of -msgid "" -"If key is not found, d is returned if given, otherwise KeyError is raised." +msgid "If key is not found, d is returned if given, otherwise KeyError is raised." msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -8056,11 +8351,12 @@ msgstr "" #: flwr.common.context.Context:3 of msgid "" -"Holds records added by the entity in a given run and that will stay local. " -"This means that the data it holds will never leave the system it's running " -"from. This can be used as an intermediate storage or scratchpad when " -"executing mods. It can also be used as a memory to access at different " -"points during the lifecycle of this entity (e.g. across multiple rounds)" +"Holds records added by the entity in a given run and that will stay " +"local. This means that the data it holds will never leave the system it's" +" running from. This can be used as an intermediate storage or scratchpad " +"when executing mods. It can also be used as a memory to access at " +"different points during the lifecycle of this entity (e.g. across " +"multiple rounds)" msgstr "" #: ../../source/ref-api/flwr.common.Context.rst:28::1 @@ -8167,19 +8463,21 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`split `\\ \\(\\[sep\\, maxsplit\\]\\)" +":py:obj:`split `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -"Return a list of the substrings in the string, using sep as the separator " -"string." +"Return a list of the substrings in the string, using sep as the separator" +" string." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rsplit `\\ \\(\\[sep\\, maxsplit\\]\\)" +":py:obj:`rsplit `\\ \\(\\[sep\\, " +"maxsplit\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8237,13 +8535,14 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the number of non-overlapping occurrences of substring sub in string " -"S[start:end]." +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`expandtabs `\\ \\(\\[tabsize\\]\\)" +":py:obj:`expandtabs `\\ " +"\\(\\[tabsize\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8259,13 +8558,12 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the lowest index in S where substring sub is found, such that sub is " -"contained within S[start:end]." +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "" -":py:obj:`partition `\\ \\(sep\\, \\/\\)" +msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8281,7 +8579,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`ljust `\\ \\(width\\[\\, fillchar\\]\\)" +":py:obj:`ljust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8315,19 +8614,20 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the highest index in S where substring sub is found, such that sub is " -"contained within S[start:end]." +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rindex `\\ \\(sub\\[\\, start\\[\\, " -"end\\]\\]\\)" +":py:obj:`rindex `\\ \\(sub\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rjust `\\ \\(width\\[\\, fillchar\\]\\)" +":py:obj:`rjust `\\ \\(width\\[\\, " +"fillchar\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8345,8 +8645,7 @@ msgid "Return a copy of the string with trailing whitespace removed." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "" -":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" +msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8366,8 +8665,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.strip:1 of -msgid "" -"Return a copy of the string with leading and trailing whitespace removed." +msgid "Return a copy of the string with leading and trailing whitespace removed." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8382,8 +8680,7 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "" -":py:obj:`translate `\\ \\(table\\, \\/\\)" +msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8402,8 +8699,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`startswith `\\ \\(prefix\\[\\, " -"start\\[\\, end\\]\\]\\)" +":py:obj:`startswith `\\ \\(prefix\\[\\," +" start\\[\\, end\\]\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8422,8 +8719,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removeprefix `\\ \\(prefix\\, " -"\\/\\)" +":py:obj:`removeprefix `\\ " +"\\(prefix\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8433,8 +8730,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removesuffix `\\ \\(suffix\\, " -"\\/\\)" +":py:obj:`removesuffix `\\ " +"\\(suffix\\, \\/\\)" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8538,8 +8835,7 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isidentifier:1 of -msgid "" -"Return True if the string is a valid Python identifier, False otherwise." +msgid "Return True if the string is a valid Python identifier, False otherwise." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8558,8 +8854,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.zfill:1 of msgid "" -"Pad a numeric string with zeros on the left, to fill a field of the given " -"width." +"Pad a numeric string with zeros on the left, to fill a field of the given" +" width." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8569,8 +8865,7 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "" -"Return a formatted version of S, using substitutions from args and kwargs." +msgid "Return a formatted version of S, using substitutions from args and kwargs." msgstr "" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 @@ -8595,65 +8890,67 @@ msgid ":py:obj:`PING `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid "" -":py:obj:`START_CLIENT_ENTER `\\" +msgid ":py:obj:`START_CLIENT_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid "" -":py:obj:`START_CLIENT_LEAVE `\\" +msgid ":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid "" -":py:obj:`START_SERVER_ENTER `\\" +msgid ":py:obj:`START_SERVER_ENTER `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of -msgid "" -":py:obj:`START_SERVER_LEAVE `\\" +msgid ":py:obj:`START_SERVER_LEAVE `\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_ENTER `\\" +":py:obj:`RUN_DRIVER_API_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE `\\" +":py:obj:`RUN_DRIVER_API_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_ENTER `\\" +":py:obj:`RUN_FLEET_API_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_LEAVE `\\" +":py:obj:`RUN_FLEET_API_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_ENTER `\\" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE `\\" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_ENTER `\\" +":py:obj:`START_SIMULATION_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_LEAVE `\\" +":py:obj:`START_SIMULATION_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of @@ -8664,44 +8961,60 @@ msgstr "" msgid ":py:obj:`DRIVER_DISCONNECT `\\" msgstr "" +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_ENTER `\\" +msgstr "" + +#: flwr.common.EventType.capitalize:1::1 of +msgid ":py:obj:`START_DRIVER_LEAVE `\\" +msgstr "" + #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_DRIVER_ENTER `\\" +":py:obj:`RUN_CLIENT_APP_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_DRIVER_LEAVE `\\" +":py:obj:`RUN_CLIENT_APP_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER `\\" +":py:obj:`RUN_SERVER_APP_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE `\\" +":py:obj:`RUN_SERVER_APP_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_ENTER `\\" +":py:obj:`RUN_SUPERNODE_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE `\\" +":py:obj:`RUN_SUPERNODE_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_ENTER `\\" +":py:obj:`RUN_SUPEREXEC_ENTER " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_LEAVE `\\" +":py:obj:`RUN_SUPEREXEC_LEAVE " +"`\\" msgstr "" #: flwr.common.EventType.capitalize:3 of @@ -8712,15 +9025,14 @@ msgstr "" #: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 #: flwr.common.EventType.rjust:3 of -msgid "" -"Padding is done using the specified fill character (default is a space)." +msgid "Padding is done using the specified fill character (default is a space)." msgstr "" #: flwr.common.EventType.count:1 of msgid "" -"Return the number of non-overlapping occurrences of substring sub in string " -"S[start:end]. Optional arguments start and end are interpreted as in slice " -"notation." +"Return the number of non-overlapping occurrences of substring sub in " +"string S[start:end]. Optional arguments start and end are interpreted as" +" in slice notation." msgstr "" #: flwr.common.EventType.encode:3 of @@ -8739,16 +9051,17 @@ msgstr "" msgid "" "The error handling scheme to use for encoding errors. The default is " "'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " -"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as " -"any other name registered with codecs.register_error that can handle " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " +"as any other name registered with codecs.register_error that can handle " "UnicodeEncodeErrors." msgstr "" #: flwr.common.EventType.endswith:1 of msgid "" "Return True if S ends with the specified suffix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, stop " -"comparing S at that position. suffix can also be a tuple of strings to try." +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. suffix can also be a tuple of strings " +"to try." msgstr "" #: flwr.common.EventType.expandtabs:3 of @@ -8757,8 +9070,8 @@ msgstr "" #: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of msgid "" -"Return the lowest index in S where substring sub is found, such that sub is " -"contained within S[start:end]. Optional arguments start and end are " +"Return the lowest index in S where substring sub is found, such that sub " +"is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" @@ -8768,8 +9081,8 @@ msgstr "" #: flwr.common.EventType.format:1 of msgid "" -"Return a formatted version of S, using substitutions from args and kwargs. " -"The substitutions are identified by braces ('{' and '}')." +"Return a formatted version of S, using substitutions from args and " +"kwargs. The substitutions are identified by braces ('{' and '}')." msgstr "" #: flwr.common.EventType.format_map:1 of @@ -8784,80 +9097,80 @@ msgstr "" #: flwr.common.EventType.isalnum:3 of msgid "" -"A string is alpha-numeric if all characters in the string are alpha-numeric " -"and there is at least one character in the string." +"A string is alpha-numeric if all characters in the string are alpha-" +"numeric and there is at least one character in the string." msgstr "" #: flwr.common.EventType.isalpha:3 of msgid "" -"A string is alphabetic if all characters in the string are alphabetic and " -"there is at least one character in the string." +"A string is alphabetic if all characters in the string are alphabetic and" +" there is at least one character in the string." msgstr "" #: flwr.common.EventType.isascii:3 of msgid "" -"ASCII characters have code points in the range U+0000-U+007F. Empty string " -"is ASCII too." +"ASCII characters have code points in the range U+0000-U+007F. Empty " +"string is ASCII too." msgstr "" #: flwr.common.EventType.isdecimal:3 of msgid "" -"A string is a decimal string if all characters in the string are decimal and " -"there is at least one character in the string." +"A string is a decimal string if all characters in the string are decimal " +"and there is at least one character in the string." msgstr "" #: flwr.common.EventType.isdigit:3 of msgid "" -"A string is a digit string if all characters in the string are digits and " -"there is at least one character in the string." +"A string is a digit string if all characters in the string are digits and" +" there is at least one character in the string." msgstr "" #: flwr.common.EventType.isidentifier:3 of msgid "" -"Call keyword.iskeyword(s) to test whether string s is a reserved identifier, " -"such as \"def\" or \"class\"." +"Call keyword.iskeyword(s) to test whether string s is a reserved " +"identifier, such as \"def\" or \"class\"." msgstr "" #: flwr.common.EventType.islower:3 of msgid "" -"A string is lowercase if all cased characters in the string are lowercase " -"and there is at least one cased character in the string." +"A string is lowercase if all cased characters in the string are lowercase" +" and there is at least one cased character in the string." msgstr "" #: flwr.common.EventType.isnumeric:3 of msgid "" -"A string is numeric if all characters in the string are numeric and there is " -"at least one character in the string." +"A string is numeric if all characters in the string are numeric and there" +" is at least one character in the string." msgstr "" #: flwr.common.EventType.isprintable:3 of msgid "" -"A string is printable if all of its characters are considered printable in " -"repr() or if it is empty." +"A string is printable if all of its characters are considered printable " +"in repr() or if it is empty." msgstr "" #: flwr.common.EventType.isspace:3 of msgid "" -"A string is whitespace if all characters in the string are whitespace and " -"there is at least one character in the string." +"A string is whitespace if all characters in the string are whitespace and" +" there is at least one character in the string." msgstr "" #: flwr.common.EventType.istitle:3 of msgid "" -"In a title-cased string, upper- and title-case characters may only follow " -"uncased characters and lowercase characters only cased ones." +"In a title-cased string, upper- and title-case characters may only follow" +" uncased characters and lowercase characters only cased ones." msgstr "" #: flwr.common.EventType.isupper:3 of msgid "" -"A string is uppercase if all cased characters in the string are uppercase " -"and there is at least one cased character in the string." +"A string is uppercase if all cased characters in the string are uppercase" +" and there is at least one cased character in the string." msgstr "" #: flwr.common.EventType.join:3 of msgid "" -"The string whose method is called is inserted in between each given string. " -"The result is returned as a new string." +"The string whose method is called is inserted in between each given " +"string. The result is returned as a new string." msgstr "" #: flwr.common.EventType.join:6 of @@ -8875,9 +9188,9 @@ msgid "" "ordinals (integers) or characters to Unicode ordinals, strings or None. " "Character keys will be then converted to ordinals. If there are two " "arguments, they must be strings of equal length, and in the resulting " -"dictionary, each character in x will be mapped to the character at the same " -"position in y. If there is a third argument, it must be a string, whose " -"characters will be mapped to None in the result." +"dictionary, each character in x will be mapped to the character at the " +"same position in y. If there is a third argument, it must be a string, " +"whose characters will be mapped to None in the result." msgstr "" #: flwr.common.EventType.partition:3 of @@ -8895,8 +9208,8 @@ msgstr "" #: flwr.common.EventType.removeprefix:3 of msgid "" -"If the string starts with the prefix string, return string[len(prefix):]. " -"Otherwise, return a copy of the original string." +"If the string starts with the prefix string, return string[len(prefix):]." +" Otherwise, return a copy of the original string." msgstr "" #: flwr.common.EventType.removesuffix:3 of @@ -8918,22 +9231,22 @@ msgstr "" #: flwr.common.EventType.replace:7 of msgid "" -"If the optional argument count is given, only the first count occurrences " -"are replaced." +"If the optional argument count is given, only the first count occurrences" +" are replaced." msgstr "" #: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of msgid "" -"Return the highest index in S where substring sub is found, such that sub is " -"contained within S[start:end]. Optional arguments start and end are " +"Return the highest index in S where substring sub is found, such that sub" +" is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" #: flwr.common.EventType.rpartition:3 of msgid "" -"This will search for the separator in the string, starting at the end. If " -"the separator is found, returns a 3-tuple containing the part before the " -"separator, the separator itself, and the part after it." +"This will search for the separator in the string, starting at the end. If" +" the separator is found, returns a 3-tuple containing the part before the" +" separator, the separator itself, and the part after it." msgstr "" #: flwr.common.EventType.rpartition:7 of @@ -8952,9 +9265,9 @@ msgstr "" #: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of msgid "" -"When set to None (the default value), will split on any whitespace character " -"(including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard empty " -"strings from the result." +"When set to None (the default value), will split on any whitespace " +"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" +" empty strings from the result." msgstr "" #: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of @@ -8963,8 +9276,8 @@ msgstr "" #: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of msgid "" -"Maximum number of splits (starting from the left). -1 (the default value) " -"means no limit." +"Maximum number of splits (starting from the left). -1 (the default value)" +" means no limit." msgstr "" #: flwr.common.EventType.rsplit:13 of @@ -8974,27 +9287,28 @@ msgstr "" #: flwr.common.EventType.split:13 of msgid "" "Note, str.split() is mainly useful for data that has been intentionally " -"delimited. With natural text that includes punctuation, consider using the " -"regular expression module." +"delimited. With natural text that includes punctuation, consider using " +"the regular expression module." msgstr "" #: flwr.common.EventType.splitlines:3 of msgid "" -"Line breaks are not included in the resulting list unless keepends is given " -"and true." +"Line breaks are not included in the resulting list unless keepends is " +"given and true." msgstr "" #: flwr.common.EventType.startswith:1 of msgid "" "Return True if S starts with the specified prefix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, stop " -"comparing S at that position. prefix can also be a tuple of strings to try." +"optional start, test S beginning at that position. With optional end, " +"stop comparing S at that position. prefix can also be a tuple of strings " +"to try." msgstr "" #: flwr.common.EventType.title:3 of msgid "" -"More specifically, words start with uppercased characters and all remaining " -"cased characters have lower case." +"More specifically, words start with uppercased characters and all " +"remaining cased characters have lower case." msgstr "" #: flwr.common.EventType.translate:5 of @@ -9003,15 +9317,15 @@ msgstr "" #: flwr.common.EventType.translate:4 of msgid "" -"Translation table, which must be a mapping of Unicode ordinals to Unicode " -"ordinals, strings, or None." +"Translation table, which must be a mapping of Unicode ordinals to Unicode" +" ordinals, strings, or None." msgstr "" #: flwr.common.EventType.translate:7 of msgid "" "The table must implement lookup/indexing via __getitem__, for instance a " -"dictionary or list. If this operation raises LookupError, the character is " -"left untouched. Characters mapped to None are deleted." +"dictionary or list. If this operation raises LookupError, the character " +"is left untouched. Characters mapped to None are deleted." msgstr "" #: flwr.common.EventType.zfill:3 of @@ -9101,14 +9415,14 @@ msgstr "" #: flwr.common.message.Message:5 of msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side " -"logic to a client, or vice-versa) or that will be sent to it." +"Holds records either sent by another entity (e.g. sent by the server-side" +" logic to a client, or vice-versa) or that will be sent to it." msgstr "" #: flwr.common.message.Message:8 of msgid "" -"A dataclass that captures information about an error that took place when " -"processing another message." +"A dataclass that captures information about an error that took place when" +" processing another message." msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 @@ -9124,8 +9438,8 @@ msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -":py:obj:`create_reply `\\ \\(content\\[\\, " -"ttl\\]\\)" +":py:obj:`create_reply `\\ " +"\\(content\\[\\, ttl\\]\\)" msgstr "" #: ../../source/ref-api/flwr.common.Message.rst:35::1 @@ -9179,18 +9493,18 @@ msgstr "" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based on " -"the remaining time for the received message before it expires. This follows " -"the equation: ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta." -"created_at)" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " +"msg.meta.created_at)" msgstr "" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based on " -"the remaining time for the received message before it expires. This follows " -"the equation:" +"Time-to-live for this message in seconds. If unset, it will be set based " +"on the remaining time for the received message before it expires. This " +"follows the equation:" msgstr "" #: flwr.common.message.Message.create_error_reply:9 @@ -9200,9 +9514,9 @@ msgstr "" #: flwr.common.message.Message.create_reply:3 of msgid "" -"The method generates a new `Message` as a reply to this message. It inherits " -"'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from this message " -"and sets 'reply_to_message' to the ID of this message." +"The method generates a new `Message` as a reply to this message. It " +"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " +"this message and sets 'reply_to_message' to the ID of this message." msgstr "" #: flwr.common.message.Message.create_reply:7 of @@ -9234,13 +9548,11 @@ msgid "MessageTypeLegacy" msgstr "" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid "" -":py:obj:`GET_PARAMETERS `\\" +msgid ":py:obj:`GET_PARAMETERS `\\" msgstr "" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid "" -":py:obj:`GET_PROPERTIES `\\" +msgid ":py:obj:`GET_PROPERTIES `\\" msgstr "" #: flwr.common.Metadata.created_at:1::1 @@ -9270,8 +9582,8 @@ msgstr "" #: flwr.common.message.Metadata:13 of msgid "" -"An identifier for grouping messages. In some settings, this is used as the " -"FL round." +"An identifier for grouping messages. In some settings, this is used as " +"the FL round." msgstr "" #: flwr.common.message.Metadata:16 of @@ -9285,9 +9597,9 @@ msgstr "" #: flwr.common.message.Metadata:21 of msgid "" -"An identifier that can be used when loading a particular data partition for " -"a ClientApp. Making use of this identifier is more relevant when conducting " -"simulations." +"An identifier that can be used when loading a particular data partition " +"for a ClientApp. Making use of this identifier is more relevant when " +"conducting simulations." msgstr "" #: flwr.common.Metadata.created_at:1::1 of @@ -9356,9 +9668,10 @@ msgstr "" #: flwr.common.record.metricsrecord.MetricsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:class:`int` | :py:class:`float` | :py:class:`~typing.List`\\ [:py:" -"class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " +":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" +" [:py:class:`float`]]" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9413,15 +9726,16 @@ msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" -"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " +"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord:3 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds entries " -"as an OrderedDict[str, Array]. ParametersRecord objects can be viewed as an " -"equivalent to PyTorch's state_dict, but holding serialised tensors instead." +"A dataclass storing named Arrays in order. This means that it holds " +"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " +"viewed as an equivalent to PyTorch's state_dict, but holding serialised " +"tensors instead." msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9429,8 +9743,7 @@ msgid ":py:obj:`clear `\\ \\(\\)" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid "" -":py:obj:`count_bytes `\\ \\(\\)" +msgid ":py:obj:`count_bytes `\\ \\(\\)" msgstr "" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of @@ -9461,9 +9774,9 @@ msgstr "" #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of msgid "" -"Note that a small amount of Bytes might also be included in this counting " -"that correspond to metadata of the serialized object (e.g. of NumPy array) " -"needed for deseralization." +"Note that a small amount of Bytes might also be included in this counting" +" that correspond to metadata of the serialized object (e.g. of NumPy " +"array) needed for deseralization." msgstr "" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 @@ -9497,8 +9810,7 @@ msgid "Dictionary holding MetricsRecord instances." msgstr "" #: flwr.common.RecordSet.configs_records:1::1 of -msgid "" -":py:obj:`parameters_records `\\" +msgid ":py:obj:`parameters_records `\\" msgstr "" #: flwr.common.RecordSet.configs_records:1::1 @@ -9520,12 +9832,14 @@ msgstr "" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_ins `\\" +":py:obj:`get_parameters_ins " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_properties_ins `\\" +":py:obj:`get_properties_ins " +"`\\" msgstr "" #: ../../source/ref-api/flwr.common.Status.rst:2 @@ -9562,8 +9876,8 @@ msgstr "" #: logging.Logger.log:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a true " -"value, e.g." +"To pass exception information, use the keyword argument exc_info with a " +"true value, e.g." msgstr "" #: logging.Logger.log:6 of @@ -9591,143 +9905,124 @@ msgstr "" msgid "server" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#: ../../source/ref-api/flwr.server.rst:24::1 +msgid ":py:obj:`run_server_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_driver_api:1 of -msgid "Run Flower server (Driver API)." +#: ../../source/ref-api/flwr.server.rst:24::1 +#: flwr.server.run_serverapp.run_server_app:1 of +msgid "Run Flower server app." msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#: ../../source/ref-api/flwr.server.rst:24::1 +msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_fleet_api:1 of -msgid "Run Flower server (Fleet API)." +#: ../../source/ref-api/flwr.server.rst:24::1 +#: flwr.server.app.run_superlink:1 of +msgid "Run Flower SuperLink (Driver API and Fleet API)." msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_server_app `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.run_serverapp.run_server_app:1 of -msgid "Run Flower server app." -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_superlink `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_superlink:1 of -msgid "Run Flower SuperLink (Driver API and Fleet API)." -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.start_server:1 of msgid "Start a Flower server using the gRPC transport layer." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.ClientManager:1 of msgid "Abstract base class for managing Flower clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`Driver `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.driver.driver.Driver:1 of msgid "Abstract base Driver class for the Driver API." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`History `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.history.History:1 of msgid "History class for training and/or evaluation metrics collection." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of msgid "Legacy Context." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " "strategy\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " "strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_app.ServerApp:1 of msgid "Flower ServerApp." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\, " -"round\\_timeout\\]\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," +" round\\_timeout\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_config.ServerConfig:1 of msgid "Flower server config." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 -msgid "" -":py:obj:`SimpleClientManager `\\ \\(\\)" +#: ../../source/ref-api/flwr.server.rst:38::1 +msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.SimpleClientManager:1 of msgid "Provides a pool of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 msgid ":py:obj:`flwr.server.strategy `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.strategy:1 of msgid "Contains the strategy abstraction and different implementations." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 msgid ":py:obj:`flwr.server.workflow `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.workflow:1 of msgid "Workflows." msgstr "" @@ -9748,8 +10043,7 @@ msgid "Return all available clients." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid "" -":py:obj:`num_available `\\ \\(\\)" +msgid ":py:obj:`num_available `\\ \\(\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9772,8 +10066,8 @@ msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`sample `\\ \\(num\\_clients\\[\\, " -"min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`sample `\\ " +"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9784,8 +10078,7 @@ msgid "Sample a number of Flower ClientProxy instances." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid "" -":py:obj:`unregister `\\ \\(client\\)" +msgid ":py:obj:`unregister `\\ \\(client\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -9817,7 +10110,8 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.register:6 of msgid "" "**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any reason." +"ClientProxy is already registered or can not be registered for any " +"reason." msgstr "" #: flwr.server.client_manager.ClientManager.unregister:3 @@ -9831,8 +10125,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`create_message `\\ \\(content\\, " -"message\\_type\\, ...\\[\\, ttl\\]\\)" +":py:obj:`create_message `\\ " +"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1 @@ -9862,7 +10156,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`push_messages `\\ \\(messages\\)" +":py:obj:`push_messages `\\ " +"\\(messages\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 @@ -9883,20 +10178,20 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:3 of msgid "" -"This method constructs a new `Message` with given content and metadata. The " -"`run_id` and `src_node_id` will be set automatically." +"This method constructs a new `Message` with given content and metadata. " +"The `run_id` and `src_node_id` will be set automatically." msgstr "" #: flwr.server.driver.driver.Driver.create_message:6 of msgid "" -"The content for the new message. This holds records that are to be sent to " -"the destination node." +"The content for the new message. This holds records that are to be sent " +"to the destination node." msgstr "" #: flwr.server.driver.driver.Driver.create_message:9 of msgid "" -"The type of the message, defining the action to be executed on the receiving " -"end." +"The type of the message, defining the action to be executed on the " +"receiving end." msgstr "" #: flwr.server.driver.driver.Driver.create_message:12 of @@ -9905,16 +10200,17 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:14 of msgid "" -"The ID of the group to which this message is associated. In some settings, " -"this is used as the FL round." +"The ID of the group to which this message is associated. In some " +"settings, this is used as the FL round." msgstr "" #: flwr.server.driver.driver.Driver.create_message:17 of msgid "" -"Time-to-live for the round trip of this message, i.e., the time from sending " -"this message to receiving a reply. It specifies in seconds the duration for " -"which the message and its potential reply are considered valid. If unset, " -"the default TTL (i.e., `common.DEFAULT_TTL`) will be used." +"Time-to-live for the round trip of this message, i.e., the time from " +"sending this message to receiving a reply. It specifies in seconds the " +"duration for which the message and its potential reply are considered " +"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " +"used." msgstr "" #: flwr.server.driver.driver.Driver.create_message:23 of @@ -9925,13 +10221,12 @@ msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:3 of msgid "" -"This method is used to collect messages from the SuperLink that correspond " -"to a set of given message IDs." +"This method is used to collect messages from the SuperLink that " +"correspond to a set of given message IDs." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:6 of -msgid "" -"An iterable of message IDs for which reply messages are to be retrieved." +msgid "An iterable of message IDs for which reply messages are to be retrieved." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:9 of @@ -9940,8 +10235,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:3 of msgid "" -"This method takes an iterable of messages and sends each message to the node " -"specified in `dst_node_id`." +"This method takes an iterable of messages and sends each message to the " +"node specified in `dst_node_id`." msgstr "" #: flwr.server.driver.driver.Driver.push_messages:6 @@ -9951,42 +10246,34 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:9 of msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, which " -"can be used to pull replies." +"**message_ids** -- An iterable of IDs for the messages that were sent, " +"which can be used to pull replies." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:3 of msgid "" -"This method sends a list of messages to their destination node IDs and then " -"waits for the replies. It continues to pull replies until either all replies " -"are received or the specified timeout duration is exceeded." +"This method sends a list of messages to their destination node IDs and " +"then waits for the replies. It continues to pull replies until either all" +" replies are received or the specified timeout duration is exceeded." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:9 of msgid "" "The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the method " -"will wait until replies for all messages are received." +"replies for this duration. If `None`, there is no time limit and the " +"method will wait until replies for all messages are received." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:14 of -msgid "" -"**replies** -- An iterable of reply messages received from the SuperLink." -msgstr "" - -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -msgid "Notes" +msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:19 of msgid "" -"This method uses `push_messages` to send the messages and `pull_messages` to " -"collect the replies. If `timeout` is set, the method may not return replies " -"for all sent messages. A message remains valid until its TTL, which is not " -"affected by `timeout`." +"This method uses `push_messages` to send the messages and `pull_messages`" +" to collect the replies. If `timeout` is set, the method may not return " +"replies for all sent messages. A message remains valid until its TTL, " +"which is not affected by `timeout`." msgstr "" #: ../../source/ref-api/flwr.server.History.rst:2 @@ -9995,8 +10282,9 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_centralized `\\ " -"\\(server\\_round\\, loss\\)" +":py:obj:`add_loss_centralized " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1 @@ -10006,8 +10294,9 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_distributed `\\ " -"\\(server\\_round\\, loss\\)" +":py:obj:`add_loss_distributed " +"`\\ \\(server\\_round\\, " +"loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10017,8 +10306,9 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" +":py:obj:`add_metrics_centralized " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10028,8 +10318,9 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" +":py:obj:`add_metrics_distributed " +"`\\ \\(server\\_round\\, " +"metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10039,8 +10330,9 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" +":py:obj:`add_metrics_distributed_fit " +"`\\ \\(server\\_round\\," +" ...\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -10091,8 +10383,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" +":py:obj:`disconnect_all_clients " +"`\\ \\(timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10122,8 +10414,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\, " -"timeout\\)" +":py:obj:`fit_round `\\ \\(server\\_round\\," +" timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10143,8 +10435,7 @@ msgid "Set the max_workers used by ThreadPoolExecutor." msgstr "" #: flwr.server.server.Server.client_manager:1::1 of -msgid "" -":py:obj:`set_strategy `\\ \\(strategy\\)" +msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -10179,8 +10470,8 @@ msgstr "" #: flwr.server.server_config.ServerConfig:3 of msgid "" -"All attributes have default values which allows users to configure just the " -"ones they care about." +"All attributes have default values which allows users to configure just " +"the ones they care about." msgstr "" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 @@ -10205,13 +10496,14 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`num_available `\\ " -"\\(\\)" +":py:obj:`num_available `\\" +" \\(\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`register `\\ \\(client\\)" +":py:obj:`register `\\ " +"\\(client\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of @@ -10234,8 +10526,8 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:3 of msgid "" -"Blocks until the requested number of clients is available or until a timeout " -"is reached. Current timeout default: 1 day." +"Blocks until the requested number of clients is available or until a " +"timeout is reached. Current timeout default: 1 day." msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:6 of @@ -10276,8 +10568,8 @@ msgstr "" #: flwr.server.app.start_server:5 of msgid "" -"A server implementation, either `flwr.server.Server` or a subclass thereof. " -"If no instance is provided, then `start_server` will create one." +"A server implementation, either `flwr.server.Server` or a subclass " +"thereof. If no instance is provided, then `start_server` will create one." msgstr "" #: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of @@ -10288,41 +10580,41 @@ msgstr "" #: flwr.server.app.start_server:12 of msgid "" -"An implementation of the abstract base class `flwr.server.strategy." -"Strategy`. If no strategy is provided, then `start_server` will use `flwr." -"server.strategy.FedAvg`." +"An implementation of the abstract base class " +"`flwr.server.strategy.Strategy`. If no strategy is provided, then " +"`start_server` will use `flwr.server.strategy.FedAvg`." msgstr "" #: flwr.server.app.start_server:16 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`. If " -"no implementation is provided, then `start_server` will use `flwr.server." -"client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_server` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" #: flwr.server.app.start_server:21 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower " -"clients. The default should be sufficient for most models. Users who train " -"very large models might need to increase this value. Note that the Flower " -"clients need to be started with the same value (see `flwr.client." -"start_client`), otherwise clients will not know about the increased limit " -"and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower" +" clients. The default should be sufficient for most models. Users who " +"train very large models might need to increase this value. Note that the " +"Flower clients need to be started with the same value (see " +"`flwr.client.start_client`), otherwise clients will not know about the " +"increased limit and block larger messages." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to " -"start a secure SSL-enabled server. The tuple is expected to have three bytes " -"elements in the following order: * CA certificate. * server " -"certificate. * server private key." +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order: * CA certificate. * " +"server certificate. * server private key." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to " -"start a secure SSL-enabled server. The tuple is expected to have three bytes " -"elements in the following order:" +"Tuple containing root certificate, server certificate, and private key to" +" start a secure SSL-enabled server. The tuple is expected to have three " +"bytes elements in the following order:" msgstr "" #: flwr.server.app.start_server:32 of @@ -10355,8 +10647,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\)" +":py:obj:`Bulyan `\\ \\(\\*\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10388,8 +10680,9 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10400,8 +10693,9 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " +"`\\ " +"\\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10412,8 +10706,9 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping " +"`\\ " +"\\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10424,8 +10719,9 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" +":py:obj:`DifferentialPrivacyServerSideFixedClipping " +"`\\ " +"\\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10470,8 +10766,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedAvgAndroid `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10520,8 +10816,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedTrimmedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10575,8 +10871,9 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FaultTolerantFedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg " +"`\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10586,8 +10883,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " -"fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10597,8 +10894,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " -"qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " +"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -10766,8 +11063,8 @@ msgstr "" #: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of the " -"Bulyan (e.g., Krum)" +"Byzantine resilient aggregation rule that is used as the first step of " +"the Bulyan (e.g., Krum)" msgstr "" #: flwr.server.strategy.bulyan.Bulyan:29 of @@ -10776,8 +11073,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 @@ -10804,8 +11102,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -10884,8 +11183,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10902,8 +11202,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10920,8 +11221,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -10952,8 +11253,9 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 @@ -10973,8 +11275,9 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 @@ -10986,8 +11289,9 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -10998,8 +11302,9 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11019,15 +11324,15 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "" -"Evaluate model parameters using an evaluation function from the strategy." +msgid "Evaluate model parameters using an evaluation function from the strategy." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -11066,9 +11371,9 @@ msgstr "" msgid "" "**evaluate_configuration** -- A list of tuples. Each tuple in the list " "identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this list, " -"it means that this `ClientProxy` will not participate in the next round of " -"federated evaluation." +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated evaluation." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 @@ -11088,14 +11393,16 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -11107,21 +11414,24 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -"Configure the next round of training incorporating Differential Privacy (DP)." +"Configure the next round of training incorporating Differential Privacy " +"(DP)." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -11134,23 +11444,25 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -"Configuration of the next training round includes information related to DP, " -"such as clip norm and noise stddev." +"Configuration of the next training round includes information related to " +"DP, such as clip norm and noise stddev." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 #: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list identifies " -"a `ClientProxy` and the `FitIns` for this particular `ClientProxy`. If a " -"particular `ClientProxy` is not included in this list, it means that this " -"`ClientProxy` will not participate in the next round of federated learning." +"**fit_configuration** -- A list of tuples. Each tuple in the list " +"identifies a `ClientProxy` and the `FitIns` for this particular " +"`ClientProxy`. If a particular `ClientProxy` is not included in this " +"list, it means that this `ClientProxy` will not participate in the next " +"round of federated learning." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 @@ -11167,8 +11479,9 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `adaptiveclipping_mod`." +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " +"happen on the client-side, usually by using the built-in " +"`adaptiveclipping_mod`." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 @@ -11204,23 +11517,22 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of -msgid "" -"The desired quantile of updates which should be clipped. Defaults to 0.5." +msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 #: of msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. Andrew " -"et al. recommends to set to 0.2." +"The learning rate for the clipping norm adaptation. Defaults to 0.2. " +"Andrew et al. recommends to set to 0.2." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of msgid "" -"The stddev of the noise added to the count of updates currently below the " -"estimate. Andrew et al. recommends to set to `expected_num_records/20`" +"The stddev of the noise added to the count of updates currently below the" +" estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 @@ -11234,8 +11546,8 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 #: of msgid "" -"Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` " -"wrapper:" +"Wrap the strategy with the " +"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 @@ -11246,17 +11558,17 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -11270,33 +11582,33 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 @@ -11313,22 +11625,16 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen on " -"the client-side, usually by using the built-in `fixedclipping_mod`." +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A value " -"of 1.0 or higher is recommended for strong privacy." -msgstr "" - -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -msgid "The value of the clipping norm." +"The noise multiplier for the Gaussian mechanism for model updates. A " +"value of 1.0 or higher is recommended for strong privacy." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 @@ -11346,17 +11652,17 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 @@ -11368,33 +11674,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 @@ -11404,8 +11710,9 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 #: of msgid "" -"The standard deviation of the noise added to the count of updates below the " -"estimate. Andrew et al. recommends to set to `expected_num_records/20`" +"The standard deviation of the noise added to the count of updates below " +"the estimate. Andrew et al. recommends to set to " +"`expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 @@ -11418,49 +11725,49 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ " -"\\(server\\_round\\, parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 @@ -11470,23 +11777,24 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 #: of msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " +"wrapper" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\" +" \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 @@ -11498,33 +11806,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate `\\ \\(server\\_round\\, " -"parameters\\)" +":py:obj:`evaluate " +"`\\" +" \\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\" +" \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 @@ -11539,15 +11847,17 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11569,15 +11879,17 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -11590,26 +11902,29 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:905 +#: ../../source/ref-changelog.md:997 msgid "FedAdagrad" msgstr "" @@ -11658,26 +11973,28 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\" +" \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\" +" \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11688,20 +12005,23 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 @@ -11720,8 +12040,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11732,8 +12053,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11750,19 +12072,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -11779,16 +12104,17 @@ msgstr "" #: of msgid "" "Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will still " -"be sampled. Defaults to 1.0." +"larger than `fraction_fit * available_clients`, `min_fit_clients` will " +"still be sampled. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -"Fraction of clients used during validation. In case `min_evaluate_clients` " -"is larger than `fraction_evaluate * available_clients`, " -"`min_evaluate_clients` will still be sampled. Defaults to 1.0." +"Fraction of clients used during validation. In case " +"`min_evaluate_clients` is larger than `fraction_evaluate * " +"available_clients`, `min_evaluate_clients` will still be sampled. " +"Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:33 of @@ -11797,8 +12123,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11809,8 +12136,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11827,20 +12155,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 @@ -11850,22 +12180,24 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray " +"`\\ \\(tensor\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -11876,14 +12208,16 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -11897,15 +12231,16 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes " +"`\\ \\(ndarray\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -11916,29 +12251,33 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters " +"`\\ " +"\\(ndarrays\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" +":py:obj:`parameters_to_ndarrays " +"`\\ " +"\\(parameters\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -11957,7 +12296,8 @@ msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to 1.0." +"Server-side learning rate used in server-side optimization. Defaults to " +"1.0." msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:28 of @@ -11966,8 +12306,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11978,8 +12319,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -11996,19 +12338,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12018,8 +12363,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12035,8 +12381,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12053,19 +12400,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12083,8 +12433,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12095,8 +12446,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12113,20 +12465,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\" +" \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 @@ -12139,9 +12493,9 @@ msgstr "" #: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"The strategy in itself will not be different than FedAvg, the client needs " -"to be adjusted. A proximal term needs to be added to the loss function " -"during the training:" +"The strategy in itself will not be different than FedAvg, the client " +"needs to be adjusted. A proximal term needs to be added to the loss " +"function during the training:" msgstr "" #: flwr.server.strategy.fedprox.FedProx:9 of @@ -12174,14 +12528,15 @@ msgstr "" msgid "" "The weight of the proximal term used in the optimization. 0.0 makes this " "strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to be " -"closer to the server parameters during training)." +"regularization will be used (that is, the client parameters will need to " +"be closer to the server parameters during training)." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12192,8 +12547,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12210,19 +12566,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12244,13 +12603,15 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -12261,13 +12622,15 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -12279,20 +12642,23 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 @@ -12302,8 +12668,9 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 @@ -12317,7 +12684,8 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " +":py:obj:`aggregate_fit " +"`\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -12331,14 +12699,16 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " +":py:obj:`configure_fit " +"`\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -12352,22 +12722,25 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 @@ -12377,29 +12750,33 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\," +" results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 @@ -12412,22 +12789,25 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 @@ -12437,31 +12817,36 @@ msgstr "" #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of msgid "" "This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +"Baselines: " +"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit " +"`\\ \\(server\\_round\\, " +"results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12472,20 +12857,23 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 @@ -12506,8 +12894,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12518,8 +12907,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12536,19 +12926,22 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12562,14 +12955,15 @@ msgstr "" #: flwr.server.strategy.krum.Krum:17 of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in " -"that case classical Krum is applied." +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" +" that case classical Krum is applied." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\, " +"results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12585,8 +12979,9 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\, " +"parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12603,14 +12998,16 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -12625,8 +13022,9 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ \\(server\\_round\\," +" results\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -12637,8 +13035,9 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ \\(server\\_round\\," +" parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -12655,19 +13054,22 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients " +"`\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\ " +":py:obj:`num_fit_clients " +"`\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -12678,8 +13080,9 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate " +"`\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 @@ -12703,8 +13106,9 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate " +"`\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -12729,8 +13133,9 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" +":py:obj:`initialize_parameters " +"`\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -12740,18 +13145,17 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Successful updates from the previously selected and configured clients. Each " -"pair of `(ClientProxy, FitRes` constitutes a successful update from one of " -"the previously selected clients. Not that not all previously selected " -"clients are necessarily included in this list: a client might drop out and " -"not submit a result. For each client that did not submit an update, there " -"should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " +"one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "" -"Exceptions that occurred while the server was waiting for client updates." +msgid "Exceptions that occurred while the server was waiting for client updates." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of @@ -12762,22 +13166,23 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Successful updates from the previously selected and configured clients. Each " -"pair of `(ClientProxy, FitRes)` constitutes a successful update from one of " -"the previously selected clients. Not that not all previously selected " -"clients are necessarily included in this list: a client might drop out and " -"not submit a result. For each client that did not submit an update, there " -"should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. " +"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" +" one of the previously selected clients. Not that not all previously " +"selected clients are necessarily included in this list: a client might " +"drop out and not submit a result. For each client that did not submit an " +"update, there should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the previous " -"parameters with the ones returned from this method). If `None` is returned " -"(e.g., because there were only failures and no viable results) then the " -"server will no update the previous model parameters, the updates received in " -"this round are discarded, and the global model parameters remain the same." +"these as the new global model parameters (i.e., it will replace the " +"previous parameters with the ones returned from this method). If `None` " +"is returned (e.g., because there were only failures and no viable " +"results) then the server will no update the previous model parameters, " +"the updates received in this round are discarded, and the global model " +"parameters remain the same." msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:3 of @@ -12788,8 +13193,9 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple containing " -"loss and a dictionary containing task-specific metrics (e.g., accuracy)." +"**evaluation_result** -- The evaluation result, usually a Tuple " +"containing loss and a dictionary containing task-specific metrics (e.g., " +"accuracy)." msgstr "" #: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of @@ -12847,17 +13253,17 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 #: of msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors owned " -"by multiple parties, without accessing any individual integer vector. This " -"workflow allows the server to compute the weighted average of model " -"parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and a " -"weighted version of the locally updated parameters, both of which are masked " -"for privacy. Specifically, each client uploads \"[w, w * params]\" with " -"masks, where weighting factor 'w' is the number of examples ('num_examples') " -"and 'params' represents the model parameters ('parameters') from the " -"client's `FitRes`. The server then aggregates these contributions to compute " -"the weighted average of model parameters." +"The SecAgg+ protocol ensures the secure summation of integer vectors " +"owned by multiple parties, without accessing any individual integer " +"vector. This workflow allows the server to compute the weighted average " +"of model parameters across all clients, ensuring individual contributions" +" remain private. This is achieved by clients sending both, a weighting " +"factor and a weighted version of the locally updated parameters, both of " +"which are masked for privacy. Specifically, each client uploads \"[w, w *" +" params]\" with masks, where weighting factor 'w' is the number of " +"examples ('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 @@ -12894,39 +13300,39 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 #: of msgid "" -"Only the aggregated model parameters are exposed and passed to `Strategy." -"aggregate_fit`, ensuring individual data privacy." +"Only the aggregated model parameters are exposed and passed to " +"`Strategy.aggregate_fit`, ensuring individual data privacy." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of msgid "" -"The number of shares into which each client's private key is split under the " -"SecAgg+ protocol. If specified as a float, it represents the proportion of " -"all selected clients, and the number of shares will be set dynamically in " -"the run time. A private key can be reconstructed from these shares, allowing " -"for the secure aggregation of model updates. Each client sends one share to " -"each of its neighbors while retaining one." +"The number of shares into which each client's private key is split under " +"the SecAgg+ protocol. If specified as a float, it represents the " +"proportion of all selected clients, and the number of shares will be set " +"dynamically in the run time. A private key can be reconstructed from " +"these shares, allowing for the secure aggregation of model updates. Each " +"client sends one share to each of its neighbors while retaining one." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 #: of msgid "" -"The minimum number of shares required to reconstruct a client's private key, " -"or, if specified as a float, it represents the proportion of the total " -"number of shares needed for reconstruction. This threshold ensures privacy " -"by allowing for the recovery of contributions from dropped clients during " -"aggregation, without compromising individual client data." +"The minimum number of shares required to reconstruct a client's private " +"key, or, if specified as a float, it represents the proportion of the " +"total number of shares needed for reconstruction. This threshold ensures " +"privacy by allowing for the recovery of contributions from dropped " +"clients during aggregation, without compromising individual client data." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 #: of msgid "" -"The maximum value of the weight that can be assigned to any single client's " -"update during the weighted average calculation on the server side, e.g., in " -"the FedAvg algorithm." +"The maximum value of the weight that can be assigned to any single " +"client's update during the weighted average calculation on the server " +"side, e.g., in the FedAvg algorithm." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 @@ -12934,8 +13340,8 @@ msgstr "" #: of msgid "" "The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within [-" -"clipping_range, clipping_range], facilitating quantization." +"This parameter ensures each model parameter is bounded within " +"[-clipping_range, clipping_range], facilitating quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 @@ -12953,32 +13359,31 @@ msgstr "" #: of msgid "" "The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. Please " -"use 2**n values for `modulus_range` to prevent overflow issues." +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " +"Please use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for " -"replies for this duration each time. If `None`, there is no time limit and " -"the workflow will wait until replies for all messages are received." +"The timeout duration in seconds. If specified, the workflow will wait for" +" replies for this duration each time. If `None`, there is no time limit " +"and the workflow will wait until replies for all messages are received." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 #: of msgid "" "Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` means " -"better privacy guarantees but less tolerance to dropouts." +"increasing the computational costs; higher `reconstruction_threshold` " +"means better privacy guarantees but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of -msgid "" -"Too large `max_weight` may compromise the precision of the quantization." +msgid "Too large `max_weight` may compromise the precision of the quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 @@ -12991,34 +13396,35 @@ msgstr "" #: of msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in the " -"runtime. This allows for dynamic adjustment based on the total number of " -"participating clients." +"selected clients, and hence the number of shares will be determined in " +"the runtime. This allows for dynamic adjustment based on the total number" +" of participating clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 #: of msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted as " -"the proportion of the number of shares needed for the reconstruction of a " -"private key. This feature enables flexibility in setting the security " -"threshold relative to the number of distributed shares." +"Similarly, when `reconstruction_threshold` is a float, it is interpreted " +"as the proportion of the number of shares needed for the reconstruction " +"of a private key. This feature enables flexibility in setting the " +"security threshold relative to the number of distributed shares." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 #: of msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters " -"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+ " -"protocol." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters" +" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+" +" protocol." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\" +" \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 @@ -13030,8 +13436,9 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13043,8 +13450,9 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage " +"`\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13056,8 +13464,9 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -13072,50 +13481,51 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"Bases: :py:class:`~flwr.server.workflow.secure_aggregation." -"secaggplus_workflow.SecAggPlusWorkflow`" +"Bases: " +":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned by " -"multiple parties, without accessing any individual integer vector. This " -"workflow allows the server to compute the weighted average of model " +"The SecAgg protocol ensures the secure summation of integer vectors owned" +" by multiple parties, without accessing any individual integer vector. " +"This workflow allows the server to compute the weighted average of model " "parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and a " -"weighted version of the locally updated parameters, both of which are masked " -"for privacy. Specifically, each client uploads \"[w, w * params]\" with " -"masks, where weighting factor 'w' is the number of examples ('num_examples') " -"and 'params' represents the model parameters ('parameters') from the " -"client's `FitRes`. The server then aggregates these contributions to compute " -"the weighted average of model parameters." +"private. This is achieved by clients sending both, a weighting factor and" +" a weighted version of the locally updated parameters, both of which are " +"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" +" with masks, where weighting factor 'w' is the number of examples " +"('num_examples') and 'params' represents the model parameters " +"('parameters') from the client's `FitRes`. The server then aggregates " +"these contributions to compute the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg configuration " -"to clients and collect their public keys. - 'share keys': Broadcast public " -"keys among clients and collect encrypted secret" +"The protocol involves four main stages: - 'setup': Send SecAgg " +"configuration to clients and collect their public keys. - 'share keys': " +"Broadcast public keys among clients and collect encrypted secret" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"Each client's private key is split into N shares under the SecAgg protocol, " -"where N is the number of selected clients." +"Each client's private key is split into N shares under the SecAgg " +"protocol, where N is the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"Generally, higher `reconstruction_threshold` means better privacy guarantees " -"but less tolerance to dropouts." +"Generally, higher `reconstruction_threshold` means better privacy " +"guarantees but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in setting " -"the security threshold relative to the number of selected clients." +"reconstruction of a private key. This feature enables flexibility in " +"setting the security threshold relative to the number of selected " +"clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of @@ -13129,29 +13539,32 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\ " +"\\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\" +" \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage `\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:2 @@ -13160,8 +13573,8 @@ msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\, " -"client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\," +" client\\_fn\\[\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 @@ -13192,14 +13605,15 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive " -"messages sent by the `ServerApp`." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive" +" messages sent by the `ServerApp`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in the " -"ServerApp and receive a Message describing what the ClientApp should perform." +"Number of nodes that run a ClientApp. They can be sampled by a Driver in " +"the ServerApp and receive a Message describing what the ClientApp should " +"perform." msgstr "" #: flwr.simulation.run_simulation.run_simulation:13 of @@ -13208,26 +13622,26 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to configure a " -"backend. Values supported in are those included by `flwr.common." -"typing.ConfigsRecordValues`." +"'A dictionary, e.g {\"\": , \"\": } to " +"configure a backend. Values supported in are those included by " +"`flwr.common.typing.ConfigsRecordValues`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. This " -"is desirable if you make use of a TensorFlow model on your `ServerApp` while " -"having your `ClientApp` running on the same GPU. Without enabling this, you " -"might encounter an out-of-memory error because TensorFlow, by default, " -"allocates all GPU memory. Read more about how `tf.config.experimental." -"set_memory_growth()` works in the TensorFlow documentation: https://www." -"tensorflow.org/api/stable." +"A boolean to indicate whether to enable GPU growth on the main thread. " +"This is desirable if you make use of a TensorFlow model on your " +"`ServerApp` while having your `ClientApp` running on the same GPU. " +"Without enabling this, you might encounter an out-of-memory error because" +" TensorFlow, by default, allocates all GPU memory. Read more about how " +"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " +"documentation: https://www.tensorflow.org/api/stable." msgstr "" #: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If " -"enabled, DEBUG-level logs will be displayed." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" +" enabled, DEBUG-level logs will be displayed." msgstr "" #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 @@ -13236,15 +13650,15 @@ msgstr "" #: flwr.simulation.app.start_simulation:3 of msgid "" -"A function creating client instances. The function must take a single `str` " -"argument called `cid`. It should return a single client instance of type " -"Client. Note that the created client instances are ephemeral and will often " -"be destroyed after a single method invocation. Since client instances are " -"not long-lived, they should not attempt to carry state over method " -"invocations. Any state required by the instance (model, dataset, " +"A function creating client instances. The function must take a single " +"`str` argument called `cid`. It should return a single client instance of" +" type Client. Note that the created client instances are ephemeral and " +"will often be destroyed after a single method invocation. Since client " +"instances are not long-lived, they should not attempt to carry state over" +" method invocations. Any state required by the instance (model, dataset, " "hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load evaluation " -"data in the `evaluate` method itself)." +"`client_fn` or the call to any of the client methods (e.g., load " +"evaluation data in the `evaluate` method itself)." msgstr "" #: flwr.simulation.app.start_simulation:13 of @@ -13255,16 +13669,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:16 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients` is " -"not set. Setting both `num_clients` and `clients_ids` with " +"List `client_id`s for each client. This is only required if `num_clients`" +" is not set. Setting both `num_clients` and `clients_ids` with " "`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" #: flwr.simulation.app.start_simulation:20 of msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` and " -"`num_gpus`. To understand the GPU utilization caused by `num_gpus`, as well " -"as using custom resources, please consult the Ray documentation." +"CPU and GPU resources for a single client. Supported keys are `num_cpus` " +"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " +"as well as using custom resources, please consult the Ray documentation." msgstr "" #: flwr.simulation.app.start_simulation:25 of @@ -13275,16 +13689,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:31 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If no " -"strategy is provided, then `start_server` will use `flwr.server.strategy." -"FedAvg`." +"An implementation of the abstract base class `flwr.server.Strategy`. If " +"no strategy is provided, then `start_server` will use " +"`flwr.server.strategy.FedAvg`." msgstr "" #: flwr.simulation.app.start_simulation:35 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`. If " -"no implementation is provided, then `start_simulation` will use `flwr.server." -"client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`." +" If no implementation is provided, then `start_simulation` will use " +"`flwr.server.client_manager.SimpleClientManager`." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -13293,7 +13707,8 @@ msgid "" "ray_init_args is None (the default), Ray will be initialized with the " "following default args: { \"ignore_reinit_error\": True, " "\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to ray.init." +"(ray_init_args={}) to prevent any arguments from being passed to " +"ray.init." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -13309,13 +13724,14 @@ msgstr "" #: flwr.simulation.app.start_simulation:45 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any arguments " -"from being passed to ray.init." +"An empty dictionary can be used (ray_init_args={}) to prevent any " +"arguments from being passed to ray.init." msgstr "" #: flwr.simulation.app.start_simulation:48 of msgid "" -"Set to True to prevent `ray.shutdown()` in case `ray.is_initialized()=True`." +"Set to True to prevent `ray.shutdown()` in case " +"`ray.is_initialized()=True`." msgstr "" #: flwr.simulation.app.start_simulation:50 of @@ -13327,19 +13743,19 @@ msgstr "" #: flwr.simulation.app.start_simulation:54 of msgid "" -"If you want to create your own Actor classes, you might need to pass some " -"input argument. You can use this dictionary for such purpose." +"If you want to create your own Actor classes, you might need to pass some" +" input argument. You can use this dictionary for such purpose." msgstr "" #: flwr.simulation.app.start_simulation:57 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for the " -"VCE to choose in which node the actor is placed. If you are an advanced user " -"needed more control you can use lower-level scheduling strategies to pin " -"actors to specific compute nodes (e.g. via NodeAffinitySchedulingStrategy). " -"Please note this is an advanced feature. For all details, please refer to " -"the Ray documentation: https://docs.ray.io/en/latest/ray-core/scheduling/" -"index.html" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " +"the VCE to choose in which node the actor is placed. If you are an " +"advanced user needed more control you can use lower-level scheduling " +"strategies to pin actors to specific compute nodes (e.g. via " +"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." +" For all details, please refer to the Ray documentation: " +"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" msgstr "" #: flwr.simulation.app.start_simulation:66 of @@ -13351,2887 +13767,3601 @@ msgid "Changelog" msgstr "" #: ../../source/ref-changelog.md:3 -msgid "Unreleased" -msgstr "" - -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 -#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 -#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 -#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 -#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 -#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 -#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 -#: ../../source/ref-changelog.md:1022 -msgid "What's new?" +msgid "v1.9.0 (2024-06-10)" msgstr "" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 -#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 -#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 -#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 -#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 -#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 -#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 -msgid "Incompatible changes" +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:169 ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:362 ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:510 ../../source/ref-changelog.md:568 +#: ../../source/ref-changelog.md:637 ../../source/ref-changelog.md:706 +msgid "Thanks to our contributors" msgstr "" -#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 -#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 -#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 -#: ../../source/ref-changelog.md:603 -msgid "None" +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:171 ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:364 ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:512 ../../source/ref-changelog.md:570 +msgid "" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:11 -msgid "v1.8.0 (2024-04-03)" +#: ../../source/ref-changelog.md:9 +msgid "" +"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. " +"Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`," +" `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " msgstr "" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 -#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 -#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 -#: ../../source/ref-changelog.md:614 -msgid "Thanks to our contributors" +#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:175 ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:368 ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:516 ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:643 ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:814 ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:947 ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:1031 ../../source/ref-changelog.md:1064 +#: ../../source/ref-changelog.md:1114 +msgid "What's new?" msgstr "" -#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 -#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 -#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 -#: ../../source/ref-changelog.md:478 +#: ../../source/ref-changelog.md:13 +msgid "" +"**Introduce built-in authentication (preview)** " +"([#2946](https://github.com/adap/flower/pull/2946), " +"[#3388](https://github.com/adap/flower/pull/3388), " +"[#2948](https://github.com/adap/flower/pull/2948), " +"[#2917](https://github.com/adap/flower/pull/2917), " +"[#3386](https://github.com/adap/flower/pull/3386), " +"[#3308](https://github.com/adap/flower/pull/3308), " +"[#3001](https://github.com/adap/flower/pull/3001), " +"[#3409](https://github.com/adap/flower/pull/3409), " +"[#2999](https://github.com/adap/flower/pull/2999), " +"[#2979](https://github.com/adap/flower/pull/2979), " +"[#3389](https://github.com/adap/flower/pull/3389), " +"[#3503](https://github.com/adap/flower/pull/3503), " +"[#3366](https://github.com/adap/flower/pull/3366), " +"[#3357](https://github.com/adap/flower/pull/3357))" +msgstr "" + +#: ../../source/ref-changelog.md:15 msgid "" -"We would like to give our special thanks to all the contributors who made " -"the new version of Flower possible (in `git shortlog` order):" +"Flower 1.9 introduces the first build-in version of client node " +"authentication. In previous releases, users often wrote glue code to " +"connect Flower to external authentication systems. With this release, the" +" SuperLink can authenticate SuperNodes using a built-in authentication " +"system. A new [how-to guide](https://flower.ai/docs/framework/how-to-" +"authenticate-supernodes.html) and a new [code " +"example](https://github.com/adap/flower/tree/main/examples/flower-" +"authentication) help you to get started." msgstr "" #: ../../source/ref-changelog.md:17 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " -"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear Ashimine`, " -"`Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, `Sebastian van der " -"Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, `tabdar-khan` " +"This is the first preview release of the Flower-native authentication " +"system. Many additional features are on the roadmap for upcoming Flower " +"releases - stay tuned." +msgstr "" + +#: ../../source/ref-changelog.md:19 +msgid "" +"**Introduce end-to-end Docker support** " +"([#3483](https://github.com/adap/flower/pull/3483), " +"[#3266](https://github.com/adap/flower/pull/3266), " +"[#3390](https://github.com/adap/flower/pull/3390), " +"[#3283](https://github.com/adap/flower/pull/3283), " +"[#3285](https://github.com/adap/flower/pull/3285), " +"[#3391](https://github.com/adap/flower/pull/3391), " +"[#3403](https://github.com/adap/flower/pull/3403), " +"[#3458](https://github.com/adap/flower/pull/3458), " +"[#3533](https://github.com/adap/flower/pull/3533), " +"[#3453](https://github.com/adap/flower/pull/3453), " +"[#3486](https://github.com/adap/flower/pull/3486), " +"[#3290](https://github.com/adap/flower/pull/3290))" msgstr "" #: ../../source/ref-changelog.md:21 msgid "" -"**Introduce Flower Next high-level API (stable)** ([#3002](https://github." -"com/adap/flower/pull/3002), [#2934](https://github.com/adap/flower/" -"pull/2934), [#2958](https://github.com/adap/flower/pull/2958), [#3173]" -"(https://github.com/adap/flower/pull/3173), [#3174](https://github.com/adap/" -"flower/pull/3174), [#2923](https://github.com/adap/flower/pull/2923), [#2691]" -"(https://github.com/adap/flower/pull/2691), [#3079](https://github.com/adap/" -"flower/pull/3079), [#2961](https://github.com/adap/flower/pull/2961), [#2924]" -"(https://github.com/adap/flower/pull/2924), [#3166](https://github.com/adap/" -"flower/pull/3166), [#3031](https://github.com/adap/flower/pull/3031), [#3057]" -"(https://github.com/adap/flower/pull/3057), [#3000](https://github.com/adap/" -"flower/pull/3000), [#3113](https://github.com/adap/flower/pull/3113), [#2957]" -"(https://github.com/adap/flower/pull/2957), [#3183](https://github.com/adap/" -"flower/pull/3183), [#3180](https://github.com/adap/flower/pull/3180), [#3035]" -"(https://github.com/adap/flower/pull/3035), [#3189](https://github.com/adap/" -"flower/pull/3189), [#3185](https://github.com/adap/flower/pull/3185), [#3190]" -"(https://github.com/adap/flower/pull/3190), [#3191](https://github.com/adap/" -"flower/pull/3191), [#3195](https://github.com/adap/flower/pull/3195), [#3197]" -"(https://github.com/adap/flower/pull/3197))" +"Full Flower Next Docker support is here! With the release of Flower 1.9, " +"Flower provides stable Docker images for the Flower SuperLink, the Flower" +" SuperNode, and the Flower `ServerApp`. This set of images enables you to" +" run all Flower components in Docker. Check out the new [how-to " +"guide](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html) to get stated." msgstr "" #: ../../source/ref-changelog.md:23 msgid "" -"The Flower Next high-level API is stable! Flower Next is the future of " -"Flower - all new features (like Flower Mods) will be built on top of it. You " -"can start to migrate your existing projects to Flower Next by using " -"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or `quickstart-" -"tensorflow`, a detailed migration guide will follow shortly). Flower Next " -"allows you to run multiple projects concurrently (we call this multi-run) " -"and execute the same project in either simulation environments or deployment " -"environments without having to change a single line of code. The best part? " -"It's fully compatible with existing Flower projects that use `Strategy`, " -"`NumPyClient` & co." +"**Re-architect Flower Next simulation engine** " +"([#3307](https://github.com/adap/flower/pull/3307), " +"[#3355](https://github.com/adap/flower/pull/3355), " +"[#3272](https://github.com/adap/flower/pull/3272), " +"[#3273](https://github.com/adap/flower/pull/3273), " +"[#3417](https://github.com/adap/flower/pull/3417), " +"[#3281](https://github.com/adap/flower/pull/3281), " +"[#3343](https://github.com/adap/flower/pull/3343), " +"[#3326](https://github.com/adap/flower/pull/3326))" msgstr "" #: ../../source/ref-changelog.md:25 msgid "" -"**Introduce Flower Next low-level API (preview)** ([#3062](https://github." -"com/adap/flower/pull/3062), [#3034](https://github.com/adap/flower/" -"pull/3034), [#3069](https://github.com/adap/flower/pull/3069))" +"Flower Next simulations now use a new in-memory `Driver` that improves " +"the reliability of simulations, especially in notebook environments. This" +" is a significant step towards a complete overhaul of the Flower Next " +"simulation architecture." msgstr "" #: ../../source/ref-changelog.md:27 msgid "" -"In addition to the Flower Next *high-level* API that uses `Strategy`, " -"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the new " -"Flower Next *low-level* API. The low-level API allows for granular control " -"of every aspect of the learning process by sending/receiving individual " -"messages to/from client nodes. The new `ServerApp` supports registering a " -"custom `main` function that allows writing custom training loops for methods " -"like async FL, cyclic training, or federated analytics. The new `ClientApp` " -"supports registering `train`, `evaluate` and `query` functions that can " -"access the raw message received from the `ServerApp`. New abstractions like " -"`RecordSet`, `Message` and `Context` further enable sending multiple models, " -"multiple sets of config values and metrics, stateful computations on the " -"client node and implementations of custom SMPC protocols, to name just a few." +"**Upgrade simulation engine** " +"([#3354](https://github.com/adap/flower/pull/3354), " +"[#3378](https://github.com/adap/flower/pull/3378), " +"[#3262](https://github.com/adap/flower/pull/3262), " +"[#3435](https://github.com/adap/flower/pull/3435), " +"[#3501](https://github.com/adap/flower/pull/3501), " +"[#3482](https://github.com/adap/flower/pull/3482), " +"[#3494](https://github.com/adap/flower/pull/3494))" msgstr "" #: ../../source/ref-changelog.md:29 msgid "" -"**Introduce Flower Mods (preview)** ([#3054](https://github.com/adap/flower/" -"pull/3054), [#2911](https://github.com/adap/flower/pull/2911), [#3083]" -"(https://github.com/adap/flower/pull/3083))" +"The Flower Next simulation engine comes with improved and configurable " +"logging. The Ray-based simulation backend in Flower 1.9 was updated to " +"use Ray 2.10." msgstr "" #: ../../source/ref-changelog.md:31 msgid "" -"Flower Modifiers (we call them Mods) can intercept messages and analyze, " -"edit or handle them directly. Mods can be used to develop pluggable modules " -"that work across different projects. Flower 1.8 already includes mods to log " -"the size of a message, the number of parameters sent over the network, " -"differential privacy with fixed clipping and adaptive clipping, local " -"differential privacy and secure aggregation protocols SecAgg and SecAgg+. " -"The Flower Mods API is released as a preview, but researchers can already " -"use it to experiment with arbirtrary SMPC protocols." +"**Introduce FedPFT baseline** " +"([#3268](https://github.com/adap/flower/pull/3268))" msgstr "" #: ../../source/ref-changelog.md:33 msgid "" -"**Fine-tune LLMs with LLM FlowerTune** ([#3029](https://github.com/adap/" -"flower/pull/3029), [#3089](https://github.com/adap/flower/pull/3089), [#3092]" -"(https://github.com/adap/flower/pull/3092), [#3100](https://github.com/adap/" -"flower/pull/3100), [#3114](https://github.com/adap/flower/pull/3114), [#3162]" -"(https://github.com/adap/flower/pull/3162), [#3172](https://github.com/adap/" -"flower/pull/3172))" +"FedPFT allows you to perform one-shot Federated Learning by leveraging " +"widely available foundational models, dramatically reducing communication" +" costs while delivering high performing models. This is work led by Mahdi" +" Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " +"details in their paper: \"Parametric Feature Transfer: One-shot Federated" +" Learning with Foundation Models\" " +"([arxiv](https://arxiv.org/abs/2402.01862))" msgstr "" #: ../../source/ref-changelog.md:35 msgid "" -"We are introducing LLM FlowerTune, an introductory example that demonstrates " -"federated LLM fine-tuning of pre-trained Llama2 models on the Alpaca-GPT4 " -"dataset. The example is built to be easily adapted to use different models " -"and/or datasets. Read our blog post [LLM FlowerTune: Federated LLM Fine-" -"tuning with Flower](https://flower.ai/blog/2024-03-14-llm-flowertune-" -"federated-llm-finetuning-with-flower/) for more details." +"**Launch additional** `flwr new` **templates for Apple MLX, Hugging Face " +"Transformers, scikit-learn and TensorFlow** " +"([#3291](https://github.com/adap/flower/pull/3291), " +"[#3139](https://github.com/adap/flower/pull/3139), " +"[#3284](https://github.com/adap/flower/pull/3284), " +"[#3251](https://github.com/adap/flower/pull/3251), " +"[#3376](https://github.com/adap/flower/pull/3376), " +"[#3287](https://github.com/adap/flower/pull/3287))" msgstr "" #: ../../source/ref-changelog.md:37 msgid "" -"**Introduce built-in Differential Privacy (preview)** ([#2798](https://" -"github.com/adap/flower/pull/2798), [#2959](https://github.com/adap/flower/" -"pull/2959), [#3038](https://github.com/adap/flower/pull/3038), [#3147]" -"(https://github.com/adap/flower/pull/3147), [#2909](https://github.com/adap/" -"flower/pull/2909), [#2893](https://github.com/adap/flower/pull/2893), [#2892]" -"(https://github.com/adap/flower/pull/2892), [#3039](https://github.com/adap/" -"flower/pull/3039), [#3074](https://github.com/adap/flower/pull/3074))" +"The `flwr` CLI's `flwr new` command is starting to become everone's " +"favorite way of creating new Flower projects. This release introduces " +"additional `flwr new` templates for Apple MLX, Hugging Face Transformers," +" scikit-learn and TensorFlow. In addition to that, existing templates " +"also received updates." msgstr "" #: ../../source/ref-changelog.md:39 msgid "" -"Built-in Differential Privacy is here! Flower supports both central and " -"local differential privacy (DP). Central DP can be configured with either " -"fixed or adaptive clipping. The clipping can happen either on the server-" -"side or the client-side. Local DP does both clipping and noising on the " -"client-side. A new documentation page [explains Differential Privacy " -"approaches](https://flower.ai/docs/framework/explanation-differential-" -"privacy.html) and a new how-to guide describes [how to use the new " -"Differential Privacy components](https://flower.ai/docs/framework/how-to-use-" -"differential-privacy.html) in Flower." +"**Refine** `RecordSet` **API** " +"([#3209](https://github.com/adap/flower/pull/3209), " +"[#3331](https://github.com/adap/flower/pull/3331), " +"[#3334](https://github.com/adap/flower/pull/3334), " +"[#3335](https://github.com/adap/flower/pull/3335), " +"[#3375](https://github.com/adap/flower/pull/3375), " +"[#3368](https://github.com/adap/flower/pull/3368))" msgstr "" #: ../../source/ref-changelog.md:41 msgid "" -"**Introduce built-in Secure Aggregation (preview)** ([#3120](https://github." -"com/adap/flower/pull/3120), [#3110](https://github.com/adap/flower/" -"pull/3110), [#3108](https://github.com/adap/flower/pull/3108))" +"`RecordSet` is part of the Flower Next low-level API preview release. In " +"Flower 1.9, `RecordSet` received a number of usability improvements that " +"make it easier to build `RecordSet`-based `ServerApp`s and `ClientApp`s." msgstr "" #: ../../source/ref-changelog.md:43 msgid "" -"Built-in Secure Aggregation is here! Flower now supports different secure " -"aggregation protocols out-of-the-box. The best part? You can add secure " -"aggregation to your Flower projects with only a few lines of code. In this " -"initial release, we inlcude support for SecAgg and SecAgg+, but more " -"protocols will be implemented shortly. We'll also add detailed docs that " -"explain secure aggregation and how to use it in Flower. You can already " -"check out the new code example that shows how to use Flower to easily " -"combine Federated Learning, Differential Privacy and Secure Aggregation in " -"the same project." +"**Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), " +"[#3430](https://github.com/adap/flower/pull/3430), " +"[#3461](https://github.com/adap/flower/pull/3461), " +"[#3360](https://github.com/adap/flower/pull/3360), " +"[#3433](https://github.com/adap/flower/pull/3433))" msgstr "" #: ../../source/ref-changelog.md:45 msgid "" -"**Introduce** `flwr` **CLI (preview)** ([#2942](https://github.com/adap/" -"flower/pull/2942), [#3055](https://github.com/adap/flower/pull/3055), [#3111]" -"(https://github.com/adap/flower/pull/3111), [#3130](https://github.com/adap/" -"flower/pull/3130), [#3136](https://github.com/adap/flower/pull/3136), [#3094]" -"(https://github.com/adap/flower/pull/3094), [#3059](https://github.com/adap/" -"flower/pull/3059), [#3049](https://github.com/adap/flower/pull/3049), [#3142]" -"(https://github.com/adap/flower/pull/3142))" +"Logs received a substantial update. Not only are logs now much nicer to " +"look at, but they are also more configurable." msgstr "" #: ../../source/ref-changelog.md:47 msgid "" -"A new `flwr` CLI command allows creating new Flower projects (`flwr new`) " -"and then running them using the Simulation Engine (`flwr run`)." +"**Improve reliability** " +"([#3564](https://github.com/adap/flower/pull/3564), " +"[#3561](https://github.com/adap/flower/pull/3561), " +"[#3566](https://github.com/adap/flower/pull/3566), " +"[#3462](https://github.com/adap/flower/pull/3462), " +"[#3225](https://github.com/adap/flower/pull/3225), " +"[#3514](https://github.com/adap/flower/pull/3514), " +"[#3535](https://github.com/adap/flower/pull/3535), " +"[#3372](https://github.com/adap/flower/pull/3372))" msgstr "" #: ../../source/ref-changelog.md:49 msgid "" -"**Introduce Flower Next Simulation Engine** ([#3024](https://github.com/adap/" -"flower/pull/3024), [#3061](https://github.com/adap/flower/pull/3061), [#2997]" -"(https://github.com/adap/flower/pull/2997), [#2783](https://github.com/adap/" -"flower/pull/2783), [#3184](https://github.com/adap/flower/pull/3184), [#3075]" -"(https://github.com/adap/flower/pull/3075), [#3047](https://github.com/adap/" -"flower/pull/3047), [#2998](https://github.com/adap/flower/pull/2998), [#3009]" -"(https://github.com/adap/flower/pull/3009), [#3008](https://github.com/adap/" -"flower/pull/3008))" +"Flower 1.9 includes reliability improvements across many parts of the " +"system. One example is a much improved SuperNode shutdown procedure." msgstr "" #: ../../source/ref-changelog.md:51 msgid "" -"The Flower Simulation Engine can now run Flower Next projects. For notebook " -"environments, there's also a new `run_simulation` function that can run " -"`ServerApp` and `ClientApp`." +"**Update Swift and C++ SDKs** " +"([#3321](https://github.com/adap/flower/pull/3321), " +"[#2763](https://github.com/adap/flower/pull/2763))" msgstr "" #: ../../source/ref-changelog.md:53 msgid "" -"**Handle SuperNode connection errors** ([#2969](https://github.com/adap/" -"flower/pull/2969))" +"In the C++ SDK, communication-related code is now separate from main " +"client logic. A new abstract class `Communicator` has been introduced " +"alongside a gRPC implementation of it." msgstr "" #: ../../source/ref-changelog.md:55 msgid "" -"A SuperNode will now try to reconnect indefinitely to the SuperLink in case " -"of connection errors. The arguments `--max-retries` and `--max-wait-time` " -"can now be passed to the `flower-client-app` command. `--max-retries` will " -"define the number of tentatives the client should make before it gives up " -"trying to reconnect to the SuperLink, and, `--max-wait-time` defines the " -"time before the SuperNode gives up trying to reconnect to the SuperLink." +"**Improve testing, tooling and CI/CD infrastructure** " +"([#3294](https://github.com/adap/flower/pull/3294), " +"[#3282](https://github.com/adap/flower/pull/3282), " +"[#3311](https://github.com/adap/flower/pull/3311), " +"[#2878](https://github.com/adap/flower/pull/2878), " +"[#3333](https://github.com/adap/flower/pull/3333), " +"[#3255](https://github.com/adap/flower/pull/3255), " +"[#3349](https://github.com/adap/flower/pull/3349), " +"[#3400](https://github.com/adap/flower/pull/3400), " +"[#3401](https://github.com/adap/flower/pull/3401), " +"[#3399](https://github.com/adap/flower/pull/3399), " +"[#3346](https://github.com/adap/flower/pull/3346), " +"[#3398](https://github.com/adap/flower/pull/3398), " +"[#3397](https://github.com/adap/flower/pull/3397), " +"[#3347](https://github.com/adap/flower/pull/3347), " +"[#3502](https://github.com/adap/flower/pull/3502), " +"[#3387](https://github.com/adap/flower/pull/3387), " +"[#3542](https://github.com/adap/flower/pull/3542), " +"[#3396](https://github.com/adap/flower/pull/3396), " +"[#3496](https://github.com/adap/flower/pull/3496), " +"[#3465](https://github.com/adap/flower/pull/3465), " +"[#3473](https://github.com/adap/flower/pull/3473), " +"[#3484](https://github.com/adap/flower/pull/3484), " +"[#3521](https://github.com/adap/flower/pull/3521), " +"[#3363](https://github.com/adap/flower/pull/3363), " +"[#3497](https://github.com/adap/flower/pull/3497), " +"[#3464](https://github.com/adap/flower/pull/3464), " +"[#3495](https://github.com/adap/flower/pull/3495), " +"[#3478](https://github.com/adap/flower/pull/3478), " +"[#3271](https://github.com/adap/flower/pull/3271))" msgstr "" #: ../../source/ref-changelog.md:57 msgid "" -"**General updates to Flower Baselines** ([#2904](https://github.com/adap/" -"flower/pull/2904), [#2482](https://github.com/adap/flower/pull/2482), [#2985]" -"(https://github.com/adap/flower/pull/2985), [#2968](https://github.com/adap/" -"flower/pull/2968))" +"As always, the Flower tooling, testing, and CI/CD infrastructure has " +"received many updates." msgstr "" #: ../../source/ref-changelog.md:59 msgid "" -"There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " -"baseline. Several other baselined have been updated as well." +"**Improve documentation** " +"([#3530](https://github.com/adap/flower/pull/3530), " +"[#3539](https://github.com/adap/flower/pull/3539), " +"[#3425](https://github.com/adap/flower/pull/3425), " +"[#3520](https://github.com/adap/flower/pull/3520), " +"[#3286](https://github.com/adap/flower/pull/3286), " +"[#3516](https://github.com/adap/flower/pull/3516), " +"[#3523](https://github.com/adap/flower/pull/3523), " +"[#3545](https://github.com/adap/flower/pull/3545), " +"[#3498](https://github.com/adap/flower/pull/3498), " +"[#3439](https://github.com/adap/flower/pull/3439), " +"[#3440](https://github.com/adap/flower/pull/3440), " +"[#3382](https://github.com/adap/flower/pull/3382), " +"[#3559](https://github.com/adap/flower/pull/3559), " +"[#3432](https://github.com/adap/flower/pull/3432), " +"[#3278](https://github.com/adap/flower/pull/3278), " +"[#3371](https://github.com/adap/flower/pull/3371), " +"[#3519](https://github.com/adap/flower/pull/3519), " +"[#3267](https://github.com/adap/flower/pull/3267), " +"[#3204](https://github.com/adap/flower/pull/3204), " +"[#3274](https://github.com/adap/flower/pull/3274))" msgstr "" #: ../../source/ref-changelog.md:61 msgid "" -"**Improve documentation and translations** ([#3050](https://github.com/adap/" -"flower/pull/3050), [#3044](https://github.com/adap/flower/pull/3044), [#3043]" -"(https://github.com/adap/flower/pull/3043), [#2986](https://github.com/adap/" -"flower/pull/2986), [#3041](https://github.com/adap/flower/pull/3041), [#3046]" -"(https://github.com/adap/flower/pull/3046), [#3042](https://github.com/adap/" -"flower/pull/3042), [#2978](https://github.com/adap/flower/pull/2978), [#2952]" -"(https://github.com/adap/flower/pull/2952), [#3167](https://github.com/adap/" -"flower/pull/3167), [#2953](https://github.com/adap/flower/pull/2953), [#3045]" -"(https://github.com/adap/flower/pull/3045), [#2654](https://github.com/adap/" -"flower/pull/2654), [#3082](https://github.com/adap/flower/pull/3082), [#2990]" -"(https://github.com/adap/flower/pull/2990), [#2989](https://github.com/adap/" -"flower/pull/2989))" +"As always, the Flower documentation has received many updates. Notable " +"new pages include:" msgstr "" #: ../../source/ref-changelog.md:63 msgid "" -"As usual, we merged many smaller and larger improvements to the " -"documentation. A special thank you goes to [Sebastian van der Voort](https://" -"github.com/svdvoort) for landing a big documentation PR!" +"[How-to upgrate to Flower Next (Flower Next migration " +"guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-" +"next.html)" msgstr "" #: ../../source/ref-changelog.md:65 msgid "" -"**General updates to Flower Examples** ([3134](https://github.com/adap/" -"flower/pull/3134), [2996](https://github.com/adap/flower/pull/2996), [2930]" -"(https://github.com/adap/flower/pull/2930), [2967](https://github.com/adap/" -"flower/pull/2967), [2467](https://github.com/adap/flower/pull/2467), [2910]" -"(https://github.com/adap/flower/pull/2910), [#2918](https://github.com/adap/" -"flower/pull/2918), [#2773](https://github.com/adap/flower/pull/2773), [#3063]" -"(https://github.com/adap/flower/pull/3063), [#3116](https://github.com/adap/" -"flower/pull/3116), [#3117](https://github.com/adap/flower/pull/3117))" +"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-" +"run-flower-using-docker.html)" msgstr "" #: ../../source/ref-changelog.md:67 msgid "" -"Two new examples show federated training of a Vision Transformer (ViT) and " -"federated learning in a medical context using the popular MONAI library. " -"`quickstart-pytorch` and `quickstart-tensorflow` demonstrate the new Flower " -"Next `ServerApp` and `ClientApp`. Many other examples received considerable " -"updates as well." +"[Flower Mods reference](https://flower.ai/docs/framework/ref-" +"api/flwr.client.mod.html#module-flwr.client.mod)" msgstr "" #: ../../source/ref-changelog.md:69 msgid "" -"**General improvements** ([#3171](https://github.com/adap/flower/pull/3171), " -"[3099](https://github.com/adap/flower/pull/3099), [3003](https://github.com/" -"adap/flower/pull/3003), [3145](https://github.com/adap/flower/pull/3145), " -"[3017](https://github.com/adap/flower/pull/3017), [3085](https://github.com/" -"adap/flower/pull/3085), [3012](https://github.com/adap/flower/pull/3012), " -"[3119](https://github.com/adap/flower/pull/3119), [2991](https://github.com/" -"adap/flower/pull/2991), [2970](https://github.com/adap/flower/pull/2970), " -"[2980](https://github.com/adap/flower/pull/2980), [3086](https://github.com/" -"adap/flower/pull/3086), [2932](https://github.com/adap/flower/pull/2932), " -"[2928](https://github.com/adap/flower/pull/2928), [2941](https://github.com/" -"adap/flower/pull/2941), [2933](https://github.com/adap/flower/pull/2933), " -"[3181](https://github.com/adap/flower/pull/3181), [2973](https://github.com/" -"adap/flower/pull/2973), [2992](https://github.com/adap/flower/pull/2992), " -"[2915](https://github.com/adap/flower/pull/2915), [3040](https://github.com/" -"adap/flower/pull/3040), [3022](https://github.com/adap/flower/pull/3022), " -"[3032](https://github.com/adap/flower/pull/3032), [2902](https://github.com/" -"adap/flower/pull/2902), [2931](https://github.com/adap/flower/pull/2931), " -"[3005](https://github.com/adap/flower/pull/3005), [3132](https://github.com/" -"adap/flower/pull/3132), [3115](https://github.com/adap/flower/pull/3115), " -"[2944](https://github.com/adap/flower/pull/2944), [3064](https://github.com/" -"adap/flower/pull/3064), [3106](https://github.com/adap/flower/pull/3106), " -"[2974](https://github.com/adap/flower/pull/2974), [3178](https://github.com/" -"adap/flower/pull/3178), [2993](https://github.com/adap/flower/pull/2993), " -"[3186](https://github.com/adap/flower/pull/3186), [3091](https://github.com/" -"adap/flower/pull/3091), [3125](https://github.com/adap/flower/pull/3125), " -"[3093](https://github.com/adap/flower/pull/3093), [3013](https://github.com/" -"adap/flower/pull/3013), [3033](https://github.com/adap/flower/pull/3033), " -"[3133](https://github.com/adap/flower/pull/3133), [3068](https://github.com/" -"adap/flower/pull/3068), [2916](https://github.com/adap/flower/pull/2916), " -"[2975](https://github.com/adap/flower/pull/2975), [2984](https://github.com/" -"adap/flower/pull/2984), [2846](https://github.com/adap/flower/pull/2846), " -"[3077](https://github.com/adap/flower/pull/3077), [3143](https://github.com/" -"adap/flower/pull/3143), [2921](https://github.com/adap/flower/pull/2921), " -"[3101](https://github.com/adap/flower/pull/3101), [2927](https://github.com/" -"adap/flower/pull/2927), [2995](https://github.com/adap/flower/pull/2995), " -"[2972](https://github.com/adap/flower/pull/2972), [2912](https://github.com/" -"adap/flower/pull/2912), [3065](https://github.com/adap/flower/pull/3065), " -"[3028](https://github.com/adap/flower/pull/3028), [2922](https://github.com/" -"adap/flower/pull/2922), [2982](https://github.com/adap/flower/pull/2982), " -"[2914](https://github.com/adap/flower/pull/2914), [3179](https://github.com/" -"adap/flower/pull/3179), [3080](https://github.com/adap/flower/pull/3080), " -"[2994](https://github.com/adap/flower/pull/2994), [3187](https://github.com/" -"adap/flower/pull/3187), [2926](https://github.com/adap/flower/pull/2926), " -"[3018](https://github.com/adap/flower/pull/3018), [3144](https://github.com/" -"adap/flower/pull/3144), [3011](https://github.com/adap/flower/pull/3011), " -"[#3152](https://github.com/adap/flower/pull/3152), [#2836](https://github." -"com/adap/flower/pull/2836), [#2929](https://github.com/adap/flower/" -"pull/2929), [#2943](https://github.com/adap/flower/pull/2943), [#2955]" -"(https://github.com/adap/flower/pull/2955), [#2954](https://github.com/adap/" -"flower/pull/2954))" -msgstr "" - -#: ../../source/ref-changelog.md:75 -msgid "v1.7.0 (2024-02-05)" +"**General updates to Flower Examples** " +"([#3205](https://github.com/adap/flower/pull/3205), " +"[#3226](https://github.com/adap/flower/pull/3226), " +"[#3211](https://github.com/adap/flower/pull/3211), " +"[#3252](https://github.com/adap/flower/pull/3252), " +"[#3427](https://github.com/adap/flower/pull/3427), " +"[#3410](https://github.com/adap/flower/pull/3410), " +"[#3426](https://github.com/adap/flower/pull/3426), " +"[#3228](https://github.com/adap/flower/pull/3228), " +"[#3342](https://github.com/adap/flower/pull/3342), " +"[#3200](https://github.com/adap/flower/pull/3200), " +"[#3202](https://github.com/adap/flower/pull/3202), " +"[#3394](https://github.com/adap/flower/pull/3394), " +"[#3488](https://github.com/adap/flower/pull/3488), " +"[#3329](https://github.com/adap/flower/pull/3329), " +"[#3526](https://github.com/adap/flower/pull/3526), " +"[#3392](https://github.com/adap/flower/pull/3392), " +"[#3474](https://github.com/adap/flower/pull/3474), " +"[#3269](https://github.com/adap/flower/pull/3269))" +msgstr "" + +#: ../../source/ref-changelog.md:71 +msgid "As always, Flower code examples have received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:73 +msgid "" +"**General improvements** " +"([#3532](https://github.com/adap/flower/pull/3532), " +"[#3318](https://github.com/adap/flower/pull/3318), " +"[#3565](https://github.com/adap/flower/pull/3565), " +"[#3296](https://github.com/adap/flower/pull/3296), " +"[#3305](https://github.com/adap/flower/pull/3305), " +"[#3246](https://github.com/adap/flower/pull/3246), " +"[#3224](https://github.com/adap/flower/pull/3224), " +"[#3475](https://github.com/adap/flower/pull/3475), " +"[#3297](https://github.com/adap/flower/pull/3297), " +"[#3317](https://github.com/adap/flower/pull/3317), " +"[#3429](https://github.com/adap/flower/pull/3429), " +"[#3196](https://github.com/adap/flower/pull/3196), " +"[#3534](https://github.com/adap/flower/pull/3534), " +"[#3240](https://github.com/adap/flower/pull/3240), " +"[#3365](https://github.com/adap/flower/pull/3365), " +"[#3407](https://github.com/adap/flower/pull/3407), " +"[#3563](https://github.com/adap/flower/pull/3563), " +"[#3344](https://github.com/adap/flower/pull/3344), " +"[#3330](https://github.com/adap/flower/pull/3330), " +"[#3436](https://github.com/adap/flower/pull/3436), " +"[#3300](https://github.com/adap/flower/pull/3300), " +"[#3327](https://github.com/adap/flower/pull/3327), " +"[#3254](https://github.com/adap/flower/pull/3254), " +"[#3253](https://github.com/adap/flower/pull/3253), " +"[#3419](https://github.com/adap/flower/pull/3419), " +"[#3289](https://github.com/adap/flower/pull/3289), " +"[#3208](https://github.com/adap/flower/pull/3208), " +"[#3245](https://github.com/adap/flower/pull/3245), " +"[#3319](https://github.com/adap/flower/pull/3319), " +"[#3203](https://github.com/adap/flower/pull/3203), " +"[#3423](https://github.com/adap/flower/pull/3423), " +"[#3352](https://github.com/adap/flower/pull/3352), " +"[#3292](https://github.com/adap/flower/pull/3292), " +"[#3261](https://github.com/adap/flower/pull/3261))" +msgstr "" + +#: ../../source/ref-changelog.md:75 ../../source/ref-changelog.md:1058 +msgid "Deprecations" +msgstr "" + +#: ../../source/ref-changelog.md:77 +msgid "**Deprecate Python 3.8 support**" +msgstr "" + +#: ../../source/ref-changelog.md:79 +msgid "" +"Python 3.8 will stop receiving security fixes in [October " +"2024](https://devguide.python.org/versions/). Support for Python 3.8 is " +"now deprecated and will be removed in an upcoming release." msgstr "" #: ../../source/ref-changelog.md:81 msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles Beauville`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S Chaitanya Kumar`, `Mohammad " -"Naseri`, `Nikos Vlachakis`, `Pritam Neog`, `Robert Kuska`, `Robert Steiner`, " -"`Taner Topal`, `Yahia Salaheldin Shaaban`, `Yan Gao`, `Yasar Abbas` " +"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-" +"api` ([#3416](https://github.com/adap/flower/pull/3416), " +"[#3420](https://github.com/adap/flower/pull/3420))" +msgstr "" + +#: ../../source/ref-changelog.md:83 +msgid "" +"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api`" +" and `flower-fleet-api`. Both commands will be removed in an upcoming " +"release. Use `flower-superlink` instead." msgstr "" #: ../../source/ref-changelog.md:85 msgid "" -"**Introduce stateful clients (experimental)** ([#2770](https://github.com/" -"adap/flower/pull/2770), [#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), [#2643](https://github." -"com/adap/flower/pull/2643), [#2769](https://github.com/adap/flower/" -"pull/2769))" +"**Deprecate** `--server` **in favor of** `--superlink` " +"([#3518](https://github.com/adap/flower/pull/3518))" msgstr "" #: ../../source/ref-changelog.md:87 msgid "" -"Subclasses of `Client` and `NumPyClient` can now store local state that " -"remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via `start_simulation`) " -"and networked clients (via `start_client`). It's also the first preview of " -"new abstractions like `Context` and `RecordSet`. Clients can access state of " -"type `RecordSet` via `state: RecordSet = self.context.state`. Changes to " -"this `RecordSet` are preserved across different rounds of execution to " -"enable stateful computations in a unified way across simulation and " -"deployment." +"The commands `flower-server-app` and `flower-client-app` should use " +"`--superlink` instead of the now deprecated `--server`. Support for " +"`--server` will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:89 -msgid "" -"**Improve performance** ([#2293](https://github.com/adap/flower/pull/2293))" +#: ../../source/ref-changelog.md:89 ../../source/ref-changelog.md:163 +#: ../../source/ref-changelog.md:238 ../../source/ref-changelog.md:350 +#: ../../source/ref-changelog.md:440 ../../source/ref-changelog.md:504 +#: ../../source/ref-changelog.md:562 ../../source/ref-changelog.md:631 +#: ../../source/ref-changelog.md:693 ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:868 ../../source/ref-changelog.md:939 +#: ../../source/ref-changelog.md:976 ../../source/ref-changelog.md:1019 +msgid "Incompatible changes" msgstr "" #: ../../source/ref-changelog.md:91 msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-place " -"aggregation to reduce memory consumption. The Flower client serialization/" -"deserialization has been rewritten from the ground up, which results in " -"significant speedups, especially when the client-side training time is short." +"**Replace** `flower-superlink` **CLI option** `--certificates` **with** " +"`--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` " +"([#3512](https://github.com/adap/flower/pull/3512), " +"[#3408](https://github.com/adap/flower/pull/3408))" msgstr "" #: ../../source/ref-changelog.md:93 msgid "" -"**Support Federated Learning with Apple MLX and Flower** ([#2693](https://" -"github.com/adap/flower/pull/2693))" +"SSL-related `flower-superlink` CLI arguments were restructured in an " +"incompatible way. Instead of passing a single `--certificates` flag with " +"three values, you now need to pass three flags (`--ssl-ca-certfile`, " +"`--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the " +"[SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-" +"connections.html) documentation page for details." msgstr "" #: ../../source/ref-changelog.md:95 msgid "" -"Flower has official support for federated learning using [Apple MLX](https://" -"ml-explore.github.io/mlx) via the new `quickstart-mlx` code example." +"**Remove SuperLink** `--vce` **option** " +"([#3513](https://github.com/adap/flower/pull/3513))" msgstr "" #: ../../source/ref-changelog.md:97 msgid "" -"**Introduce new XGBoost cyclic strategy** ([#2666](https://github.com/adap/" -"flower/pull/2666), [#2668](https://github.com/adap/flower/pull/2668))" +"Instead of separately starting a SuperLink and a `ServerApp` for " +"simulation, simulations must now be started using the single `flower-" +"simulation` command." msgstr "" #: ../../source/ref-changelog.md:99 msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of " -"training (often called cyclic). The `xgboost-comprehensive` code example " -"shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower offers " -"best-in-class XGBoost support." +"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** " +"([#3527](https://github.com/adap/flower/pull/3527))" msgstr "" #: ../../source/ref-changelog.md:101 msgid "" -"**Support Python 3.11** ([#2394](https://github.com/adap/flower/pull/2394))" +"To simplify the usage of `flower-superlink`, previously separate sets of " +"CLI options for gRPC and REST were merged into one unified set of " +"options. Consult the [Flower CLI reference " +"documentation](https://flower.ai/docs/framework/ref-api-cli.html) for " +"details." msgstr "" #: ../../source/ref-changelog.md:103 -msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will ensure " -"better support for users using more recent Python versions." -msgstr "" - -#: ../../source/ref-changelog.md:105 -msgid "" -"**Update gRPC and ProtoBuf dependencies** ([#2814](https://github.com/adap/" -"flower/pull/2814))" -msgstr "" - -#: ../../source/ref-changelog.md:107 -msgid "" -"The `grpcio` and `protobuf` dependencies were updated to their latest " -"versions for improved security and performance." +msgid "v1.8.0 (2024-04-03)" msgstr "" #: ../../source/ref-changelog.md:109 msgid "" -"**Introduce Docker image for Flower server** ([#2700](https://github.com/" -"adap/flower/pull/2700), [#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), [#2695](https://github." -"com/adap/flower/pull/2695), [#2747](https://github.com/adap/flower/" -"pull/2747), [#2746](https://github.com/adap/flower/pull/2746), [#2680]" -"(https://github.com/adap/flower/pull/2680), [#2682](https://github.com/adap/" -"flower/pull/2682), [#2701](https://github.com/adap/flower/pull/2701))" -msgstr "" - -#: ../../source/ref-changelog.md:111 -msgid "" -"The Flower server can now be run using an official Docker image. A new how-" -"to guide explains [how to run Flower using Docker](https://flower.ai/docs/" -"framework/how-to-run-flower-using-docker.html). An official Flower client " -"Docker image will follow." +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " msgstr "" #: ../../source/ref-changelog.md:113 msgid "" -"**Introduce** `flower-via-docker-compose` **example** ([#2626](https://" -"github.com/adap/flower/pull/2626))" +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" msgstr "" #: ../../source/ref-changelog.md:115 msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** ([#2719](https://" -"github.com/adap/flower/pull/2719))" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " +"this multi-run) and execute the same project in either simulation " +"environments or deployment environments without having to change a single" +" line of code. The best part? It's fully compatible with existing Flower " +"projects that use `Strategy`, `NumPyClient` & co." msgstr "" #: ../../source/ref-changelog.md:117 msgid "" -"**Introduce** `custom-metrics` **example** ([#1958](https://github.com/adap/" -"flower/pull/1958))" +"**Introduce Flower Next low-level API (preview)** " +"([#3062](https://github.com/adap/flower/pull/3062), " +"[#3034](https://github.com/adap/flower/pull/3034), " +"[#3069](https://github.com/adap/flower/pull/3069))" msgstr "" #: ../../source/ref-changelog.md:119 msgid "" -"**Update code examples to use Flower Datasets** ([#2450](https://github.com/" -"adap/flower/pull/2450), [#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), [#2712](https://github." -"com/adap/flower/pull/2712))" +"In addition to the Flower Next *high-level* API that uses `Strategy`, " +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " +"new Flower Next *low-level* API. The low-level API allows for granular " +"control of every aspect of the learning process by sending/receiving " +"individual messages to/from client nodes. The new `ServerApp` supports " +"registering a custom `main` function that allows writing custom training " +"loops for methods like async FL, cyclic training, or federated analytics." +" The new `ClientApp` supports registering `train`, `evaluate` and `query`" +" functions that can access the raw message received from the `ServerApp`." +" New abstractions like `RecordSet`, `Message` and `Context` further " +"enable sending multiple models, multiple sets of config values and " +"metrics, stateful computations on the client node and implementations of " +"custom SMPC protocols, to name just a few." msgstr "" #: ../../source/ref-changelog.md:121 msgid "" -"Several code examples were updated to use [Flower Datasets](https://flower." -"ai/docs/datasets/)." +"**Introduce Flower Mods (preview)** " +"([#3054](https://github.com/adap/flower/pull/3054), " +"[#2911](https://github.com/adap/flower/pull/2911), " +"[#3083](https://github.com/adap/flower/pull/3083))" msgstr "" #: ../../source/ref-changelog.md:123 msgid "" -"**General updates to Flower Examples** ([#2381](https://github.com/adap/" -"flower/pull/2381), [#2805](https://github.com/adap/flower/pull/2805), [#2782]" -"(https://github.com/adap/flower/pull/2782), [#2806](https://github.com/adap/" -"flower/pull/2806), [#2829](https://github.com/adap/flower/pull/2829), [#2825]" -"(https://github.com/adap/flower/pull/2825), [#2816](https://github.com/adap/" -"flower/pull/2816), [#2726](https://github.com/adap/flower/pull/2726), [#2659]" -"(https://github.com/adap/flower/pull/2659), [#2655](https://github.com/adap/" -"flower/pull/2655))" +"Flower Modifiers (we call them Mods) can intercept messages and analyze, " +"edit or handle them directly. Mods can be used to develop pluggable " +"modules that work across different projects. Flower 1.8 already includes " +"mods to log the size of a message, the number of parameters sent over the" +" network, differential privacy with fixed clipping and adaptive clipping," +" local differential privacy and secure aggregation protocols SecAgg and " +"SecAgg+. The Flower Mods API is released as a preview, but researchers " +"can already use it to experiment with arbirtrary SMPC protocols." msgstr "" #: ../../source/ref-changelog.md:125 -msgid "Many Flower code examples received substantial updates." +msgid "" +"**Fine-tune LLMs with LLM FlowerTune** " +"([#3029](https://github.com/adap/flower/pull/3029), " +"[#3089](https://github.com/adap/flower/pull/3089), " +"[#3092](https://github.com/adap/flower/pull/3092), " +"[#3100](https://github.com/adap/flower/pull/3100), " +"[#3114](https://github.com/adap/flower/pull/3114), " +"[#3162](https://github.com/adap/flower/pull/3162), " +"[#3172](https://github.com/adap/flower/pull/3172))" msgstr "" -#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 -msgid "**Update Flower Baselines**" +#: ../../source/ref-changelog.md:127 +msgid "" +"We are introducing LLM FlowerTune, an introductory example that " +"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " +"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" +" different models and/or datasets. Read our blog post [LLM FlowerTune: " +"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" +"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" #: ../../source/ref-changelog.md:129 msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), [#2771]" -"(https://github.com/adap/flower/pull/2771))" -msgstr "" - -#: ../../source/ref-changelog.md:130 -msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" +"**Introduce built-in Differential Privacy (preview)** " +"([#2798](https://github.com/adap/flower/pull/2798), " +"[#2959](https://github.com/adap/flower/pull/2959), " +"[#3038](https://github.com/adap/flower/pull/3038), " +"[#3147](https://github.com/adap/flower/pull/3147), " +"[#2909](https://github.com/adap/flower/pull/2909), " +"[#2893](https://github.com/adap/flower/pull/2893), " +"[#2892](https://github.com/adap/flower/pull/2892), " +"[#3039](https://github.com/adap/flower/pull/3039), " +"[#3074](https://github.com/adap/flower/pull/3074))" msgstr "" #: ../../source/ref-changelog.md:131 -msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" +msgid "" +"Built-in Differential Privacy is here! Flower supports both central and " +"local differential privacy (DP). Central DP can be configured with either" +" fixed or adaptive clipping. The clipping can happen either on the " +"server-side or the client-side. Local DP does both clipping and noising " +"on the client-side. A new documentation page [explains Differential " +"Privacy approaches](https://flower.ai/docs/framework/explanation-" +"differential-privacy.html) and a new how-to guide describes [how to use " +"the new Differential Privacy components](https://flower.ai/docs/framework" +"/how-to-use-differential-privacy.html) in Flower." msgstr "" -#: ../../source/ref-changelog.md:132 -msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" +#: ../../source/ref-changelog.md:133 +msgid "" +"**Introduce built-in Secure Aggregation (preview)** " +"([#3120](https://github.com/adap/flower/pull/3120), " +"[#3110](https://github.com/adap/flower/pull/3110), " +"[#3108](https://github.com/adap/flower/pull/3108))" msgstr "" -#: ../../source/ref-changelog.md:133 -msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" +#: ../../source/ref-changelog.md:135 +msgid "" +"Built-in Secure Aggregation is here! Flower now supports different secure" +" aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In " +"this initial release, we inlcude support for SecAgg and SecAgg+, but more" +" protocols will be implemented shortly. We'll also add detailed docs that" +" explain secure aggregation and how to use it in Flower. You can already " +"check out the new code example that shows how to use Flower to easily " +"combine Federated Learning, Differential Privacy and Secure Aggregation " +"in the same project." msgstr "" -#: ../../source/ref-changelog.md:134 -msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" +#: ../../source/ref-changelog.md:137 +msgid "" +"**Introduce** `flwr` **CLI (preview)** " +"([#2942](https://github.com/adap/flower/pull/2942), " +"[#3055](https://github.com/adap/flower/pull/3055), " +"[#3111](https://github.com/adap/flower/pull/3111), " +"[#3130](https://github.com/adap/flower/pull/3130), " +"[#3136](https://github.com/adap/flower/pull/3136), " +"[#3094](https://github.com/adap/flower/pull/3094), " +"[#3059](https://github.com/adap/flower/pull/3059), " +"[#3049](https://github.com/adap/flower/pull/3049), " +"[#3142](https://github.com/adap/flower/pull/3142))" msgstr "" -#: ../../source/ref-changelog.md:136 -msgid "" -"**Improve documentation** ([#2674](https://github.com/adap/flower/" -"pull/2674), [#2480](https://github.com/adap/flower/pull/2480), [#2826]" -"(https://github.com/adap/flower/pull/2826), [#2727](https://github.com/adap/" -"flower/pull/2727), [#2761](https://github.com/adap/flower/pull/2761), [#2900]" -"(https://github.com/adap/flower/pull/2900))" -msgstr "" - -#: ../../source/ref-changelog.md:138 -msgid "" -"**Improved testing and development infrastructure** ([#2797](https://github." -"com/adap/flower/pull/2797), [#2676](https://github.com/adap/flower/" -"pull/2676), [#2644](https://github.com/adap/flower/pull/2644), [#2656]" -"(https://github.com/adap/flower/pull/2656), [#2848](https://github.com/adap/" -"flower/pull/2848), [#2675](https://github.com/adap/flower/pull/2675), [#2735]" -"(https://github.com/adap/flower/pull/2735), [#2767](https://github.com/adap/" -"flower/pull/2767), [#2732](https://github.com/adap/flower/pull/2732), [#2744]" -"(https://github.com/adap/flower/pull/2744), [#2681](https://github.com/adap/" -"flower/pull/2681), [#2699](https://github.com/adap/flower/pull/2699), [#2745]" -"(https://github.com/adap/flower/pull/2745), [#2734](https://github.com/adap/" -"flower/pull/2734), [#2731](https://github.com/adap/flower/pull/2731), [#2652]" -"(https://github.com/adap/flower/pull/2652), [#2720](https://github.com/adap/" -"flower/pull/2720), [#2721](https://github.com/adap/flower/pull/2721), [#2717]" -"(https://github.com/adap/flower/pull/2717), [#2864](https://github.com/adap/" -"flower/pull/2864), [#2694](https://github.com/adap/flower/pull/2694), [#2709]" -"(https://github.com/adap/flower/pull/2709), [#2658](https://github.com/adap/" -"flower/pull/2658), [#2796](https://github.com/adap/flower/pull/2796), [#2692]" -"(https://github.com/adap/flower/pull/2692), [#2657](https://github.com/adap/" -"flower/pull/2657), [#2813](https://github.com/adap/flower/pull/2813), [#2661]" -"(https://github.com/adap/flower/pull/2661), [#2398](https://github.com/adap/" -"flower/pull/2398))" -msgstr "" - -#: ../../source/ref-changelog.md:140 -msgid "" -"The Flower testing and development infrastructure has received substantial " -"updates. This makes Flower 1.7 the most tested release ever." -msgstr "" - -#: ../../source/ref-changelog.md:142 -msgid "" -"**Update dependencies** ([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), [#2739](https://github." -"com/adap/flower/pull/2739), [#2837](https://github.com/adap/flower/" -"pull/2837), [#2788](https://github.com/adap/flower/pull/2788), [#2811]" -"(https://github.com/adap/flower/pull/2811), [#2774](https://github.com/adap/" -"flower/pull/2774), [#2790](https://github.com/adap/flower/pull/2790), [#2751]" -"(https://github.com/adap/flower/pull/2751), [#2850](https://github.com/adap/" -"flower/pull/2850), [#2812](https://github.com/adap/flower/pull/2812), [#2872]" -"(https://github.com/adap/flower/pull/2872), [#2736](https://github.com/adap/" -"flower/pull/2736), [#2756](https://github.com/adap/flower/pull/2756), [#2857]" -"(https://github.com/adap/flower/pull/2857), [#2757](https://github.com/adap/" -"flower/pull/2757), [#2810](https://github.com/adap/flower/pull/2810), [#2740]" -"(https://github.com/adap/flower/pull/2740), [#2789](https://github.com/adap/" -"flower/pull/2789))" -msgstr "" - -#: ../../source/ref-changelog.md:144 -msgid "" -"**General improvements** ([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." -"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/" -"pull/2690), [#2889](https://github.com/adap/flower/pull/2889), [#2874]" -"(https://github.com/adap/flower/pull/2874), [#2819](https://github.com/adap/" -"flower/pull/2819), [#2689](https://github.com/adap/flower/pull/2689), [#2457]" -"(https://github.com/adap/flower/pull/2457), [#2870](https://github.com/adap/" -"flower/pull/2870), [#2669](https://github.com/adap/flower/pull/2669), [#2876]" -"(https://github.com/adap/flower/pull/2876), [#2885](https://github.com/adap/" -"flower/pull/2885), [#2858](https://github.com/adap/flower/pull/2858), [#2867]" -"(https://github.com/adap/flower/pull/2867), [#2351](https://github.com/adap/" -"flower/pull/2351), [#2886](https://github.com/adap/flower/pull/2886), [#2860]" -"(https://github.com/adap/flower/pull/2860), [#2828](https://github.com/adap/" -"flower/pull/2828), [#2869](https://github.com/adap/flower/pull/2869), [#2875]" -"(https://github.com/adap/flower/pull/2875), [#2733](https://github.com/adap/" -"flower/pull/2733), [#2488](https://github.com/adap/flower/pull/2488), [#2646]" -"(https://github.com/adap/flower/pull/2646), [#2879](https://github.com/adap/" -"flower/pull/2879), [#2821](https://github.com/adap/flower/pull/2821), [#2855]" -"(https://github.com/adap/flower/pull/2855), [#2800](https://github.com/adap/" -"flower/pull/2800), [#2807](https://github.com/adap/flower/pull/2807), [#2801]" -"(https://github.com/adap/flower/pull/2801), [#2804](https://github.com/adap/" -"flower/pull/2804), [#2851](https://github.com/adap/flower/pull/2851), [#2787]" -"(https://github.com/adap/flower/pull/2787), [#2852](https://github.com/adap/" -"flower/pull/2852), [#2672](https://github.com/adap/flower/pull/2672), [#2759]" -"(https://github.com/adap/flower/pull/2759))" -msgstr "" - -#: ../../source/ref-changelog.md:148 -msgid "" -"**Deprecate** `start_numpy_client` ([#2563](https://github.com/adap/flower/" -"pull/2563), [#2718](https://github.com/adap/flower/pull/2718))" -msgstr "" - -#: ../../source/ref-changelog.md:150 +#: ../../source/ref-changelog.md:139 msgid "" -"Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we have " -"introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need to " -"first call the `.to_client()` method and then pass returned `Client` object " -"to `start_client`. The examples and the documentation have been updated " -"accordingly." +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" +" and then running them using the Simulation Engine (`flwr run`)." msgstr "" -#: ../../source/ref-changelog.md:152 +#: ../../source/ref-changelog.md:141 msgid "" -"**Deprecate legacy DP wrappers** ([#2749](https://github.com/adap/flower/" -"pull/2749))" +"**Introduce Flower Next Simulation Engine** " +"([#3024](https://github.com/adap/flower/pull/3024), " +"[#3061](https://github.com/adap/flower/pull/3061), " +"[#2997](https://github.com/adap/flower/pull/2997), " +"[#2783](https://github.com/adap/flower/pull/2783), " +"[#3184](https://github.com/adap/flower/pull/3184), " +"[#3075](https://github.com/adap/flower/pull/3075), " +"[#3047](https://github.com/adap/flower/pull/3047), " +"[#2998](https://github.com/adap/flower/pull/2998), " +"[#3009](https://github.com/adap/flower/pull/3009), " +"[#3008](https://github.com/adap/flower/pull/3008))" msgstr "" -#: ../../source/ref-changelog.md:154 +#: ../../source/ref-changelog.md:143 msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is in " -"preparation for an all-new pluggable version of differential privacy support " -"in Flower." +"The Flower Simulation Engine can now run Flower Next projects. For " +"notebook environments, there's also a new `run_simulation` function that " +"can run `ServerApp` and `ClientApp`." msgstr "" -#: ../../source/ref-changelog.md:156 +#: ../../source/ref-changelog.md:145 msgid "" -"**Make optional arg** `--callable` **in** `flower-client` **a required " -"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" +"**Handle SuperNode connection errors** " +"([#2969](https://github.com/adap/flower/pull/2969))" msgstr "" -#: ../../source/ref-changelog.md:158 +#: ../../source/ref-changelog.md:147 msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` ([#2890]" -"(https://github.com/adap/flower/pull/2890))" +"A SuperNode will now try to reconnect indefinitely to the SuperLink in " +"case of connection errors. The arguments `--max-retries` and `--max-wait-" +"time` can now be passed to the `flower-client-app` command. `--max-" +"retries` will define the number of tentatives the client should make " +"before it gives up trying to reconnect to the SuperLink, and, `--max-" +"wait-time` defines the time before the SuperNode gives up trying to " +"reconnect to the SuperLink." msgstr "" -#: ../../source/ref-changelog.md:160 +#: ../../source/ref-changelog.md:149 msgid "" -"**Drop experimental** `Task` **fields** ([#2866](https://github.com/adap/" -"flower/pull/2866), [#2865](https://github.com/adap/flower/pull/2865))" +"**General updates to Flower Baselines** " +"([#2904](https://github.com/adap/flower/pull/2904), " +"[#2482](https://github.com/adap/flower/pull/2482), " +"[#2985](https://github.com/adap/flower/pull/2985), " +"[#2968](https://github.com/adap/flower/pull/2968))" msgstr "" -#: ../../source/ref-changelog.md:162 +#: ../../source/ref-changelog.md:151 msgid "" -"Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed fields " -"are superseded by the new `RecordSet` abstraction." +"There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " +"baseline. Several other baselined have been updated as well." msgstr "" -#: ../../source/ref-changelog.md:164 +#: ../../source/ref-changelog.md:153 msgid "" -"**Retire MXNet examples** ([#2724](https://github.com/adap/flower/pull/2724))" +"**Improve documentation and translations** " +"([#3050](https://github.com/adap/flower/pull/3050), " +"[#3044](https://github.com/adap/flower/pull/3044), " +"[#3043](https://github.com/adap/flower/pull/3043), " +"[#2986](https://github.com/adap/flower/pull/2986), " +"[#3041](https://github.com/adap/flower/pull/3041), " +"[#3046](https://github.com/adap/flower/pull/3046), " +"[#3042](https://github.com/adap/flower/pull/3042), " +"[#2978](https://github.com/adap/flower/pull/2978), " +"[#2952](https://github.com/adap/flower/pull/2952), " +"[#3167](https://github.com/adap/flower/pull/3167), " +"[#2953](https://github.com/adap/flower/pull/2953), " +"[#3045](https://github.com/adap/flower/pull/3045), " +"[#2654](https://github.com/adap/flower/pull/2654), " +"[#3082](https://github.com/adap/flower/pull/3082), " +"[#2990](https://github.com/adap/flower/pull/2990), " +"[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" -#: ../../source/ref-changelog.md:166 +#: ../../source/ref-changelog.md:155 msgid "" -"The development of the MXNet fremework has ended and the project is now " -"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " -"examples won't receive updates." +"As usual, we merged many smaller and larger improvements to the " +"documentation. A special thank you goes to [Sebastian van der " +"Voort](https://github.com/svdvoort) for landing a big documentation PR!" +msgstr "" + +#: ../../source/ref-changelog.md:157 +msgid "" +"**General updates to Flower Examples** " +"([3134](https://github.com/adap/flower/pull/3134), " +"[2996](https://github.com/adap/flower/pull/2996), " +"[2930](https://github.com/adap/flower/pull/2930), " +"[2967](https://github.com/adap/flower/pull/2967), " +"[2467](https://github.com/adap/flower/pull/2467), " +"[2910](https://github.com/adap/flower/pull/2910), " +"[#2918](https://github.com/adap/flower/pull/2918), " +"[#2773](https://github.com/adap/flower/pull/2773), " +"[#3063](https://github.com/adap/flower/pull/3063), " +"[#3116](https://github.com/adap/flower/pull/3116), " +"[#3117](https://github.com/adap/flower/pull/3117))" +msgstr "" + +#: ../../source/ref-changelog.md:159 +msgid "" +"Two new examples show federated training of a Vision Transformer (ViT) " +"and federated learning in a medical context using the popular MONAI " +"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" +" new Flower Next `ServerApp` and `ClientApp`. Many other examples " +"received considerable updates as well." +msgstr "" + +#: ../../source/ref-changelog.md:161 +msgid "" +"**General improvements** " +"([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), " +"[3003](https://github.com/adap/flower/pull/3003), " +"[3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), " +"[3085](https://github.com/adap/flower/pull/3085), " +"[3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), " +"[2991](https://github.com/adap/flower/pull/2991), " +"[2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), " +"[3086](https://github.com/adap/flower/pull/3086), " +"[2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), " +"[2941](https://github.com/adap/flower/pull/2941), " +"[2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), " +"[2973](https://github.com/adap/flower/pull/2973), " +"[2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), " +"[3040](https://github.com/adap/flower/pull/3040), " +"[3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), " +"[2902](https://github.com/adap/flower/pull/2902), " +"[2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), " +"[3132](https://github.com/adap/flower/pull/3132), " +"[3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), " +"[3064](https://github.com/adap/flower/pull/3064), " +"[3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), " +"[3178](https://github.com/adap/flower/pull/3178), " +"[2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), " +"[3091](https://github.com/adap/flower/pull/3091), " +"[3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), " +"[3013](https://github.com/adap/flower/pull/3013), " +"[3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), " +"[3068](https://github.com/adap/flower/pull/3068), " +"[2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), " +"[2984](https://github.com/adap/flower/pull/2984), " +"[2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), " +"[3143](https://github.com/adap/flower/pull/3143), " +"[2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), " +"[2927](https://github.com/adap/flower/pull/2927), " +"[2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), " +"[2912](https://github.com/adap/flower/pull/2912), " +"[3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), " +"[2922](https://github.com/adap/flower/pull/2922), " +"[2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), " +"[3179](https://github.com/adap/flower/pull/3179), " +"[3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), " +"[3187](https://github.com/adap/flower/pull/3187), " +"[2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), " +"[3144](https://github.com/adap/flower/pull/3144), " +"[3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), " +"[#2836](https://github.com/adap/flower/pull/2836), " +"[#2929](https://github.com/adap/flower/pull/2929), " +"[#2943](https://github.com/adap/flower/pull/2943), " +"[#2955](https://github.com/adap/flower/pull/2955), " +"[#2954](https://github.com/adap/flower/pull/2954))" +msgstr "" + +#: ../../source/ref-changelog.md:165 ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:506 ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:633 ../../source/ref-changelog.md:695 +msgid "None" msgstr "" -#: ../../source/ref-changelog.md:168 -msgid "v1.6.0 (2023-11-28)" +#: ../../source/ref-changelog.md:167 +msgid "v1.7.0 (2024-02-05)" msgstr "" -#: ../../source/ref-changelog.md:174 +#: ../../source/ref-changelog.md:173 msgid "" -"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " -"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, " -"`Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " -"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " -"`k3nfalt` " +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " +"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " +"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " +"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " +"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " +"Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:177 msgid "" -"**Add experimental support for Python 3.12** ([#2565](https://github.com/" -"adap/flower/pull/2565))" +"**Introduce stateful clients (experimental)** " +"([#2770](https://github.com/adap/flower/pull/2770), " +"[#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), " +"[#2643](https://github.com/adap/flower/pull/2643), " +"[#2769](https://github.com/adap/flower/pull/2769))" msgstr "" -#: ../../source/ref-changelog.md:180 +#: ../../source/ref-changelog.md:179 msgid "" -"**Add new XGBoost examples** ([#2612](https://github.com/adap/flower/" -"pull/2612), [#2554](https://github.com/adap/flower/pull/2554), [#2617]" -"(https://github.com/adap/flower/pull/2617), [#2618](https://github.com/adap/" -"flower/pull/2618), [#2619](https://github.com/adap/flower/pull/2619), [#2567]" -"(https://github.com/adap/flower/pull/2567))" +"Subclasses of `Client` and `NumPyClient` can now store local state that " +"remains on the client. Let's start with the highlight first: this new " +"feature is compatible with both simulated clients (via " +"`start_simulation`) and networked clients (via `start_client`). It's also" +" the first preview of new abstractions like `Context` and `RecordSet`. " +"Clients can access state of type `RecordSet` via `state: RecordSet = " +"self.context.state`. Changes to this `RecordSet` are preserved across " +"different rounds of execution to enable stateful computations in a " +"unified way across simulation and deployment." msgstr "" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:181 msgid "" -"We have added a new `xgboost-quickstart` example alongside a new `xgboost-" -"comprehensive` example that goes more in-depth." +"**Improve performance** " +"([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:183 msgid "" -"**Add Vertical FL example** ([#2598](https://github.com/adap/flower/" -"pull/2598))" +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" +"place aggregation to reduce memory consumption. The Flower client " +"serialization/deserialization has been rewritten from the ground up, " +"which results in significant speedups, especially when the client-side " +"training time is short." msgstr "" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:185 msgid "" -"We had many questions about Vertical Federated Learning using Flower, so we " -"decided to add an simple example for it on the [Titanic dataset](https://www." -"kaggle.com/competitions/titanic/data) alongside a tutorial (in the README)." +"**Support Federated Learning with Apple MLX and Flower** " +"([#2693](https://github.com/adap/flower/pull/2693))" msgstr "" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:187 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` ([#2292](https://" -"github.com/adap/flower/pull/2292))" +"Flower has official support for federated learning using [Apple " +"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " +"example." msgstr "" -#: ../../source/ref-changelog.md:190 +#: ../../source/ref-changelog.md:189 msgid "" -"**Update REST API to support create and delete nodes** ([#2283](https://" -"github.com/adap/flower/pull/2283))" +"**Introduce new XGBoost cyclic strategy** " +"([#2666](https://github.com/adap/flower/pull/2666), " +"[#2668](https://github.com/adap/flower/pull/2668))" msgstr "" -#: ../../source/ref-changelog.md:192 +#: ../../source/ref-changelog.md:191 msgid "" -"**Update the Android SDK** ([#2187](https://github.com/adap/flower/" -"pull/2187))" +"A new strategy called `FedXgbCyclic` supports a client-by-client style of" +" training (often called cyclic). The `xgboost-comprehensive` code example" +" shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower " +"offers best-in-class XGBoost support." msgstr "" -#: ../../source/ref-changelog.md:194 -msgid "Add gRPC request-response capability to the Android SDK." +#: ../../source/ref-changelog.md:193 +msgid "" +"**Support Python 3.11** " +"([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:195 msgid "" -"**Update the C++ SDK** ([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), [#2523](https://github." -"com/adap/flower/pull/2523), [#2522](https://github.com/adap/flower/" -"pull/2522))" +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " +"ensure better support for users using more recent Python versions." msgstr "" -#: ../../source/ref-changelog.md:198 -msgid "Add gRPC request-response capability to the C++ SDK." +#: ../../source/ref-changelog.md:197 +msgid "" +"**Update gRPC and ProtoBuf dependencies** " +"([#2814](https://github.com/adap/flower/pull/2814))" msgstr "" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:199 msgid "" -"**Make HTTPS the new default** ([#2591](https://github.com/adap/flower/" -"pull/2591), [#2636](https://github.com/adap/flower/pull/2636))" +"The `grpcio` and `protobuf` dependencies were updated to their latest " +"versions for improved security and performance." msgstr "" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:201 msgid "" -"Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP for " -"prototyping. The same applies to `flower-client`, which can either use user-" -"provided credentials or gRPC-bundled certificates to connect to an HTTPS-" -"enabled server or requires opt-out via passing `--insecure` to enable " -"insecure HTTP connections." +"**Introduce Docker image for Flower server** " +"([#2700](https://github.com/adap/flower/pull/2700), " +"[#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), " +"[#2695](https://github.com/adap/flower/pull/2695), " +"[#2747](https://github.com/adap/flower/pull/2747), " +"[#2746](https://github.com/adap/flower/pull/2746), " +"[#2680](https://github.com/adap/flower/pull/2680), " +"[#2682](https://github.com/adap/flower/pull/2682), " +"[#2701](https://github.com/adap/flower/pull/2701))" msgstr "" -#: ../../source/ref-changelog.md:204 +#: ../../source/ref-changelog.md:203 msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` will " -"still start in insecure mode by default. In a future release, insecure " -"connections will require user opt-in by passing `insecure=True`." +"The Flower server can now be run using an official Docker image. A new " +"how-to guide explains [how to run Flower using " +"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html). An official Flower client Docker image will follow." msgstr "" -#: ../../source/ref-changelog.md:206 +#: ../../source/ref-changelog.md:205 msgid "" -"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), [#2493](https://github." -"com/adap/flower/pull/2493))" +"**Introduce** `flower-via-docker-compose` **example** " +"([#2626](https://github.com/adap/flower/pull/2626))" msgstr "" -#: ../../source/ref-changelog.md:208 +#: ../../source/ref-changelog.md:207 msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as standalone " -"processes (i.e. via `start_client`) or in simulation (i.e. via " -"`start_simulation`) without requiring changes to how the client class is " -"defined and instantiated. The `to_client()` function is introduced to " -"convert a `NumPyClient` to a `Client`." +"**Introduce** `quickstart-sklearn-tabular` **example** " +"([#2719](https://github.com/adap/flower/pull/2719))" msgstr "" -#: ../../source/ref-changelog.md:210 +#: ../../source/ref-changelog.md:209 msgid "" -"**Add new** `Bulyan` **strategy** ([#1817](https://github.com/adap/flower/" -"pull/1817), [#1891](https://github.com/adap/flower/pull/1891))" +"**Introduce** `custom-metrics` **example** " +"([#1958](https://github.com/adap/flower/pull/1958))" msgstr "" -#: ../../source/ref-changelog.md:212 +#: ../../source/ref-changelog.md:211 msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., 2018]" -"(https://arxiv.org/abs/1802.07927)" +"**Update code examples to use Flower Datasets** " +"([#2450](https://github.com/adap/flower/pull/2450), " +"[#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), " +"[#2712](https://github.com/adap/flower/pull/2712))" msgstr "" -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:213 msgid "" -"**Add new** `XGB Bagging` **strategy** ([#2611](https://github.com/adap/" -"flower/pull/2611))" +"Several code examples were updated to use [Flower " +"Datasets](https://flower.ai/docs/datasets/)." msgstr "" -#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 +#: ../../source/ref-changelog.md:215 msgid "" -"**Introduce `WorkloadState`** ([#2564](https://github.com/adap/flower/" -"pull/2564), [#2632](https://github.com/adap/flower/pull/2632))" +"**General updates to Flower Examples** " +"([#2381](https://github.com/adap/flower/pull/2381), " +"[#2805](https://github.com/adap/flower/pull/2805), " +"[#2782](https://github.com/adap/flower/pull/2782), " +"[#2806](https://github.com/adap/flower/pull/2806), " +"[#2829](https://github.com/adap/flower/pull/2829), " +"[#2825](https://github.com/adap/flower/pull/2825), " +"[#2816](https://github.com/adap/flower/pull/2816), " +"[#2726](https://github.com/adap/flower/pull/2726), " +"[#2659](https://github.com/adap/flower/pull/2659), " +"[#2655](https://github.com/adap/flower/pull/2655))" msgstr "" -#: ../../source/ref-changelog.md:222 +#: ../../source/ref-changelog.md:217 +msgid "Many Flower code examples received substantial updates." +msgstr "" + +#: ../../source/ref-changelog.md:219 ../../source/ref-changelog.md:312 +msgid "**Update Flower Baselines**" +msgstr "" + +#: ../../source/ref-changelog.md:221 msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" -"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" -"pull/2509))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " +"[#2771](https://github.com/adap/flower/pull/2771))" +msgstr "" + +#: ../../source/ref-changelog.md:222 +msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" +msgstr "" + +#: ../../source/ref-changelog.md:223 +msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "" #: ../../source/ref-changelog.md:224 -msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), [#2400]" -"(https://github.com/adap/flower/pull/2400))" +msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" +msgstr "" + +#: ../../source/ref-changelog.md:225 +msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" msgstr "" #: ../../source/ref-changelog.md:226 -msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" -"github.com/adap/flower/pull/2507))" +msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" msgstr "" #: ../../source/ref-changelog.md:228 msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" -"github.com/adap/flower/pull/2508))" +"**Improve documentation** " +"([#2674](https://github.com/adap/flower/pull/2674), " +"[#2480](https://github.com/adap/flower/pull/2480), " +"[#2826](https://github.com/adap/flower/pull/2826), " +"[#2727](https://github.com/adap/flower/pull/2727), " +"[#2761](https://github.com/adap/flower/pull/2761), " +"[#2900](https://github.com/adap/flower/pull/2900))" msgstr "" #: ../../source/ref-changelog.md:230 -msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" +msgid "" +"**Improved testing and development infrastructure** " +"([#2797](https://github.com/adap/flower/pull/2797), " +"[#2676](https://github.com/adap/flower/pull/2676), " +"[#2644](https://github.com/adap/flower/pull/2644), " +"[#2656](https://github.com/adap/flower/pull/2656), " +"[#2848](https://github.com/adap/flower/pull/2848), " +"[#2675](https://github.com/adap/flower/pull/2675), " +"[#2735](https://github.com/adap/flower/pull/2735), " +"[#2767](https://github.com/adap/flower/pull/2767), " +"[#2732](https://github.com/adap/flower/pull/2732), " +"[#2744](https://github.com/adap/flower/pull/2744), " +"[#2681](https://github.com/adap/flower/pull/2681), " +"[#2699](https://github.com/adap/flower/pull/2699), " +"[#2745](https://github.com/adap/flower/pull/2745), " +"[#2734](https://github.com/adap/flower/pull/2734), " +"[#2731](https://github.com/adap/flower/pull/2731), " +"[#2652](https://github.com/adap/flower/pull/2652), " +"[#2720](https://github.com/adap/flower/pull/2720), " +"[#2721](https://github.com/adap/flower/pull/2721), " +"[#2717](https://github.com/adap/flower/pull/2717), " +"[#2864](https://github.com/adap/flower/pull/2864), " +"[#2694](https://github.com/adap/flower/pull/2694), " +"[#2709](https://github.com/adap/flower/pull/2709), " +"[#2658](https://github.com/adap/flower/pull/2658), " +"[#2796](https://github.com/adap/flower/pull/2796), " +"[#2692](https://github.com/adap/flower/pull/2692), " +"[#2657](https://github.com/adap/flower/pull/2657), " +"[#2813](https://github.com/adap/flower/pull/2813), " +"[#2661](https://github.com/adap/flower/pull/2661), " +"[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" #: ../../source/ref-changelog.md:232 -msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" +msgid "" +"The Flower testing and development infrastructure has received " +"substantial updates. This makes Flower 1.7 the most tested release ever." msgstr "" #: ../../source/ref-changelog.md:234 -msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" +msgid "" +"**Update dependencies** " +"([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), " +"[#2739](https://github.com/adap/flower/pull/2739), " +"[#2837](https://github.com/adap/flower/pull/2837), " +"[#2788](https://github.com/adap/flower/pull/2788), " +"[#2811](https://github.com/adap/flower/pull/2811), " +"[#2774](https://github.com/adap/flower/pull/2774), " +"[#2790](https://github.com/adap/flower/pull/2790), " +"[#2751](https://github.com/adap/flower/pull/2751), " +"[#2850](https://github.com/adap/flower/pull/2850), " +"[#2812](https://github.com/adap/flower/pull/2812), " +"[#2872](https://github.com/adap/flower/pull/2872), " +"[#2736](https://github.com/adap/flower/pull/2736), " +"[#2756](https://github.com/adap/flower/pull/2756), " +"[#2857](https://github.com/adap/flower/pull/2857), " +"[#2757](https://github.com/adap/flower/pull/2757), " +"[#2810](https://github.com/adap/flower/pull/2810), " +"[#2740](https://github.com/adap/flower/pull/2740), " +"[#2789](https://github.com/adap/flower/pull/2789))" msgstr "" #: ../../source/ref-changelog.md:236 -msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" -msgstr "" - -#: ../../source/ref-changelog.md:238 -msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" +msgid "" +"**General improvements** " +"([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), " +"[#2877](https://github.com/adap/flower/pull/2877), " +"[#2690](https://github.com/adap/flower/pull/2690), " +"[#2889](https://github.com/adap/flower/pull/2889), " +"[#2874](https://github.com/adap/flower/pull/2874), " +"[#2819](https://github.com/adap/flower/pull/2819), " +"[#2689](https://github.com/adap/flower/pull/2689), " +"[#2457](https://github.com/adap/flower/pull/2457), " +"[#2870](https://github.com/adap/flower/pull/2870), " +"[#2669](https://github.com/adap/flower/pull/2669), " +"[#2876](https://github.com/adap/flower/pull/2876), " +"[#2885](https://github.com/adap/flower/pull/2885), " +"[#2858](https://github.com/adap/flower/pull/2858), " +"[#2867](https://github.com/adap/flower/pull/2867), " +"[#2351](https://github.com/adap/flower/pull/2351), " +"[#2886](https://github.com/adap/flower/pull/2886), " +"[#2860](https://github.com/adap/flower/pull/2860), " +"[#2828](https://github.com/adap/flower/pull/2828), " +"[#2869](https://github.com/adap/flower/pull/2869), " +"[#2875](https://github.com/adap/flower/pull/2875), " +"[#2733](https://github.com/adap/flower/pull/2733), " +"[#2488](https://github.com/adap/flower/pull/2488), " +"[#2646](https://github.com/adap/flower/pull/2646), " +"[#2879](https://github.com/adap/flower/pull/2879), " +"[#2821](https://github.com/adap/flower/pull/2821), " +"[#2855](https://github.com/adap/flower/pull/2855), " +"[#2800](https://github.com/adap/flower/pull/2800), " +"[#2807](https://github.com/adap/flower/pull/2807), " +"[#2801](https://github.com/adap/flower/pull/2801), " +"[#2804](https://github.com/adap/flower/pull/2804), " +"[#2851](https://github.com/adap/flower/pull/2851), " +"[#2787](https://github.com/adap/flower/pull/2787), " +"[#2852](https://github.com/adap/flower/pull/2852), " +"[#2672](https://github.com/adap/flower/pull/2672), " +"[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" #: ../../source/ref-changelog.md:240 -msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" +msgid "" +"**Deprecate** `start_numpy_client` " +"([#2563](https://github.com/adap/flower/pull/2563), " +"[#2718](https://github.com/adap/flower/pull/2718))" msgstr "" #: ../../source/ref-changelog.md:242 -msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" +msgid "" +"Until now, clients of type `NumPyClient` needed to be started via " +"`start_numpy_client`. In our efforts to consolidate framework APIs, we " +"have introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need " +"to first call the `.to_client()` method and then pass returned `Client` " +"object to `start_client`. The examples and the documentation have been " +"updated accordingly." msgstr "" #: ../../source/ref-changelog.md:244 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" -"github.com/adap/flower/pull/2615))" +"**Deprecate legacy DP wrappers** " +"([#2749](https://github.com/adap/flower/pull/2749))" msgstr "" #: ../../source/ref-changelog.md:246 msgid "" -"**General updates to Flower Examples** ([#2384](https://github.com/adap/" -"flower/pull/2384), [#2425](https://github.com/adap/flower/pull/2425), [#2526]" -"(https://github.com/adap/flower/pull/2526), [#2302](https://github.com/adap/" -"flower/pull/2302), [#2545](https://github.com/adap/flower/pull/2545))" +"Legacy DP wrapper classes are deprecated, but still functional. This is " +"in preparation for an all-new pluggable version of differential privacy " +"support in Flower." msgstr "" #: ../../source/ref-changelog.md:248 msgid "" -"**General updates to Flower Baselines** ([#2301](https://github.com/adap/" -"flower/pull/2301), [#2305](https://github.com/adap/flower/pull/2305), [#2307]" -"(https://github.com/adap/flower/pull/2307), [#2327](https://github.com/adap/" -"flower/pull/2327), [#2435](https://github.com/adap/flower/pull/2435), [#2462]" -"(https://github.com/adap/flower/pull/2462), [#2463](https://github.com/adap/" -"flower/pull/2463), [#2461](https://github.com/adap/flower/pull/2461), [#2469]" -"(https://github.com/adap/flower/pull/2469), [#2466](https://github.com/adap/" -"flower/pull/2466), [#2471](https://github.com/adap/flower/pull/2471), [#2472]" -"(https://github.com/adap/flower/pull/2472), [#2470](https://github.com/adap/" -"flower/pull/2470))" +"**Make optional arg** `--callable` **in** `flower-client` **a required " +"positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" #: ../../source/ref-changelog.md:250 msgid "" -"**General updates to the simulation engine** ([#2331](https://github.com/" -"adap/flower/pull/2331), [#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), [#2294](https://github." -"com/adap/flower/pull/2294))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " +"([#2890](https://github.com/adap/flower/pull/2890))" msgstr "" #: ../../source/ref-changelog.md:252 msgid "" -"**General updates to Flower SDKs** ([#2288](https://github.com/adap/flower/" -"pull/2288), [#2429](https://github.com/adap/flower/pull/2429), [#2555]" -"(https://github.com/adap/flower/pull/2555), [#2543](https://github.com/adap/" -"flower/pull/2543), [#2544](https://github.com/adap/flower/pull/2544), [#2597]" -"(https://github.com/adap/flower/pull/2597), [#2623](https://github.com/adap/" -"flower/pull/2623))" +"**Drop experimental** `Task` **fields** " +"([#2866](https://github.com/adap/flower/pull/2866), " +"[#2865](https://github.com/adap/flower/pull/2865))" msgstr "" #: ../../source/ref-changelog.md:254 msgid "" -"**General improvements** ([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." -"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/" -"pull/2316), [#2317](https://github.com/adap/flower/pull/2317), [#2349]" -"(https://github.com/adap/flower/pull/2349), [#2360](https://github.com/adap/" -"flower/pull/2360), [#2402](https://github.com/adap/flower/pull/2402), [#2446]" -"(https://github.com/adap/flower/pull/2446), [#2561](https://github.com/adap/" -"flower/pull/2561), [#2273](https://github.com/adap/flower/pull/2273), [#2267]" -"(https://github.com/adap/flower/pull/2267), [#2274](https://github.com/adap/" -"flower/pull/2274), [#2275](https://github.com/adap/flower/pull/2275), [#2432]" -"(https://github.com/adap/flower/pull/2432), [#2251](https://github.com/adap/" -"flower/pull/2251), [#2321](https://github.com/adap/flower/pull/2321), [#1936]" -"(https://github.com/adap/flower/pull/1936), [#2408](https://github.com/adap/" -"flower/pull/2408), [#2413](https://github.com/adap/flower/pull/2413), [#2401]" -"(https://github.com/adap/flower/pull/2401), [#2531](https://github.com/adap/" -"flower/pull/2531), [#2534](https://github.com/adap/flower/pull/2534), [#2535]" -"(https://github.com/adap/flower/pull/2535), [#2521](https://github.com/adap/" -"flower/pull/2521), [#2553](https://github.com/adap/flower/pull/2553), [#2596]" -"(https://github.com/adap/flower/pull/2596))" -msgstr "" - -#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 -#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 -#: ../../source/ref-changelog.md:531 -msgid "" -"Flower received many improvements under the hood, too many to list here." +"Experimental fields `sa`, `legacy_server_message` and " +"`legacy_client_message` were removed from `Task` message. The removed " +"fields are superseded by the new `RecordSet` abstraction." msgstr "" -#: ../../source/ref-changelog.md:260 +#: ../../source/ref-changelog.md:256 msgid "" -"**Remove support for Python 3.7** ([#2280](https://github.com/adap/flower/" -"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" -"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" -"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" -"(https://github.com/adap/flower/pull/2356))" +"**Retire MXNet examples** " +"([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:258 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes " -"support. Flower now requires Python 3.8." +"The development of the MXNet fremework has ended and the project is now " +"[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " +"examples won't receive updates." msgstr "" -#: ../../source/ref-changelog.md:264 -msgid "" -"**Remove experimental argument** `rest` **from** `start_client` ([#2324]" -"(https://github.com/adap/flower/pull/2324))" +#: ../../source/ref-changelog.md:260 +msgid "v1.6.0 (2023-11-28)" msgstr "" #: ../../source/ref-changelog.md:266 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` and " -"`start_numpy_client`. Use `transport=\"rest\"` to opt into the experimental " -"REST API instead." +"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " +"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," +" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " +"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " +"`cnxdeveloper`, `k3nfalt` " +msgstr "" + +#: ../../source/ref-changelog.md:270 +msgid "" +"**Add experimental support for Python 3.12** " +"([#2565](https://github.com/adap/flower/pull/2565))" msgstr "" -#: ../../source/ref-changelog.md:268 -msgid "v1.5.0 (2023-08-31)" +#: ../../source/ref-changelog.md:272 +msgid "" +"**Add new XGBoost examples** " +"([#2612](https://github.com/adap/flower/pull/2612), " +"[#2554](https://github.com/adap/flower/pull/2554), " +"[#2617](https://github.com/adap/flower/pull/2617), " +"[#2618](https://github.com/adap/flower/pull/2618), " +"[#2619](https://github.com/adap/flower/pull/2619), " +"[#2567](https://github.com/adap/flower/pull/2567))" msgstr "" #: ../../source/ref-changelog.md:274 msgid "" -"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " -"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " +"We have added a new `xgboost-quickstart` example alongside a new " +"`xgboost-comprehensive` example that goes more in-depth." +msgstr "" + +#: ../../source/ref-changelog.md:276 +msgid "" +"**Add Vertical FL example** " +"([#2598](https://github.com/adap/flower/pull/2598))" msgstr "" #: ../../source/ref-changelog.md:278 msgid "" -"**Introduce new simulation engine** ([#1969](https://github.com/adap/flower/" -"pull/1969), [#2221](https://github.com/adap/flower/pull/2221), [#2248]" -"(https://github.com/adap/flower/pull/2248))" +"We had many questions about Vertical Federated Learning using Flower, so " +"we decided to add an simple example for it on the [Titanic " +"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " +"tutorial (in the README)." msgstr "" #: ../../source/ref-changelog.md:280 msgid "" -"The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and " -"memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-only, " -"CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"**Support custom** `ClientManager` **in** `start_driver()` " +"([#2292](https://github.com/adap/flower/pull/2292))" msgstr "" #: ../../source/ref-changelog.md:282 msgid "" -"Comprehensive documentation includes a new [how-to run simulations](https://" -"flower.ai/docs/framework/how-to-run-simulations.html) guide, new [simulation-" -"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " -"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial series](https://www." -"youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +"**Update REST API to support create and delete nodes** " +"([#2283](https://github.com/adap/flower/pull/2283))" msgstr "" #: ../../source/ref-changelog.md:284 msgid "" -"**Restructure Flower Docs** ([#1824](https://github.com/adap/flower/" -"pull/1824), [#1865](https://github.com/adap/flower/pull/1865), [#1884]" -"(https://github.com/adap/flower/pull/1884), [#1887](https://github.com/adap/" -"flower/pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" -"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" -"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" -"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" -"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" -"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" -"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" -"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" -"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" -"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" -"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" -"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" -"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" -"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" -"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" -"(https://github.com/adap/flower/pull/2227))" +"**Update the Android SDK** " +"([#2187](https://github.com/adap/flower/pull/2187))" msgstr "" #: ../../source/ref-changelog.md:286 -msgid "" -"Much effort went into a completely restructured Flower docs experience. The " -"documentation on [flower.ai/docs](https://flower.ai/docs) is now divided " -"into Flower Framework, Flower Baselines, Flower Android SDK, Flower iOS SDK, " -"and code example projects." +msgid "Add gRPC request-response capability to the Android SDK." msgstr "" #: ../../source/ref-changelog.md:288 msgid "" -"**Introduce Flower Swift SDK** ([#1858](https://github.com/adap/flower/" -"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" +"**Update the C++ SDK** " +"([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" msgstr "" #: ../../source/ref-changelog.md:290 -msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support on " -"iOS is improving, and alongside the Swift SDK and code example, there is now " -"also an iOS quickstart tutorial." +msgid "Add gRPC request-response capability to the C++ SDK." msgstr "" #: ../../source/ref-changelog.md:292 msgid "" -"**Introduce Flower Android SDK** ([#2131](https://github.com/adap/flower/" -"pull/2131))" +"**Make HTTPS the new default** " +"([#2591](https://github.com/adap/flower/pull/2591), " +"[#2636](https://github.com/adap/flower/pull/2636))" msgstr "" #: ../../source/ref-changelog.md:294 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower support " -"on Android is improving, and alongside the Kotlin SDK and code example, " -"there is now also an Android quickstart tutorial." +"Flower is moving to HTTPS by default. The new `flower-server` requires " +"passing `--certificates`, but users can enable `--insecure` to use HTTP " +"for prototyping. The same applies to `flower-client`, which can either " +"use user-provided credentials or gRPC-bundled certificates to connect to " +"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " +"enable insecure HTTP connections." msgstr "" #: ../../source/ref-changelog.md:296 msgid "" -"**Introduce new end-to-end testing infrastructure** ([#1842](https://github." -"com/adap/flower/pull/1842), [#2071](https://github.com/adap/flower/" -"pull/2071), [#2072](https://github.com/adap/flower/pull/2072), [#2068]" -"(https://github.com/adap/flower/pull/2068), [#2067](https://github.com/adap/" -"flower/pull/2067), [#2069](https://github.com/adap/flower/pull/2069), [#2073]" -"(https://github.com/adap/flower/pull/2073), [#2070](https://github.com/adap/" -"flower/pull/2070), [#2074](https://github.com/adap/flower/pull/2074), [#2082]" -"(https://github.com/adap/flower/pull/2082), [#2084](https://github.com/adap/" -"flower/pull/2084), [#2093](https://github.com/adap/flower/pull/2093), [#2109]" -"(https://github.com/adap/flower/pull/2109), [#2095](https://github.com/adap/" -"flower/pull/2095), [#2140](https://github.com/adap/flower/pull/2140), [#2137]" -"(https://github.com/adap/flower/pull/2137), [#2165](https://github.com/adap/" -"flower/pull/2165))" +"For backward compatibility, `start_client()` and `start_numpy_client()` " +"will still start in insecure mode by default. In a future release, " +"insecure connections will require user opt-in by passing `insecure=True`." msgstr "" #: ../../source/ref-changelog.md:298 msgid "" -"A new testing infrastructure ensures that new changes stay compatible with " -"existing framework integrations or strategies." +"**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " +"[#2390](https://github.com/adap/flower/pull/2390), " +"[#2493](https://github.com/adap/flower/pull/2493))" msgstr "" #: ../../source/ref-changelog.md:300 -msgid "**Deprecate Python 3.7**" +msgid "" +"Using the `client_fn`, Flower clients can interchangeably run as " +"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" +" `start_simulation`) without requiring changes to how the client class is" +" defined and instantiated. The `to_client()` function is introduced to " +"convert a `NumPyClient` to a `Client`." msgstr "" #: ../../source/ref-changelog.md:302 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for " -"Python 3.7 is now deprecated and will be removed in an upcoming release." +"**Add new** `Bulyan` **strategy** " +"([#1817](https://github.com/adap/flower/pull/1817), " +"[#1891](https://github.com/adap/flower/pull/1891))" msgstr "" #: ../../source/ref-changelog.md:304 msgid "" -"**Add new** `FedTrimmedAvg` **strategy** ([#1769](https://github.com/adap/" -"flower/pull/1769), [#1853](https://github.com/adap/flower/pull/1853))" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " +"2018](https://arxiv.org/abs/1802.07927)" msgstr "" #: ../../source/ref-changelog.md:306 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, 2018]" -"(https://arxiv.org/abs/1803.01498)." +"**Add new** `XGB Bagging` **strategy** " +"([#2611](https://github.com/adap/flower/pull/2611))" msgstr "" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:308 ../../source/ref-changelog.md:310 msgid "" -"**Introduce start_driver** ([#1697](https://github.com/adap/flower/" -"pull/1697))" -msgstr "" - -#: ../../source/ref-changelog.md:310 -msgid "" -"In addition to `start_server` and using the raw Driver API, there is a new " -"`start_driver` function that allows for running `start_server` scripts as a " -"Flower driver with only a single-line code change. Check out the `mt-" -"pytorch` code example to see a working example using `start_driver`." -msgstr "" - -#: ../../source/ref-changelog.md:312 -msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** ([#1785]" -"(https://github.com/adap/flower/pull/1785))" +"**Introduce `WorkloadState`** " +"([#2564](https://github.com/adap/flower/pull/2564), " +"[#2632](https://github.com/adap/flower/pull/2632))" msgstr "" #: ../../source/ref-changelog.md:314 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a " -"driver script. The included `driver.py` and `server.py` have been aligned to " -"demonstrate both the low-level way and the high-level way of building server-" -"side logic." +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " +"[#2286](https://github.com/adap/flower/pull/2286), " +"[#2509](https://github.com/adap/flower/pull/2509))" msgstr "" #: ../../source/ref-changelog.md:316 msgid "" -"**Migrate experimental REST API to Starlette** ([2171](https://github.com/" -"adap/flower/pull/2171))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " +"[#2400](https://github.com/adap/flower/pull/2400))" msgstr "" #: ../../source/ref-changelog.md:318 msgid "" -"The (experimental) REST API used to be implemented in [FastAPI](https://" -"fastapi.tiangolo.com/), but it has now been migrated to use [Starlette]" -"(https://www.starlette.io/) directly." +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " +"[#2507](https://github.com/adap/flower/pull/2507))" msgstr "" #: ../../source/ref-changelog.md:320 msgid "" -"Please note: The REST request-response API is still experimental and will " -"likely change significantly over time." +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " +"[#2508](https://github.com/adap/flower/pull/2508))" msgstr "" #: ../../source/ref-changelog.md:322 -msgid "" -"**Introduce experimental gRPC request-response API** ([#1867](https://github." -"com/adap/flower/pull/1867), [#1901](https://github.com/adap/flower/" -"pull/1901))" +msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "" #: ../../source/ref-changelog.md:324 -msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) and " -"the experimental REST API, there is now a new gRPC API that uses a request-" -"response model to communicate with client nodes." +msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "" #: ../../source/ref-changelog.md:326 -msgid "" -"Please note: The gRPC request-response API is still experimental and will " -"likely change significantly over time." +msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "" #: ../../source/ref-changelog.md:328 -msgid "" -"**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` ([#1880](https://github.com/adap/flower/" -"pull/1880))" +msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "" #: ../../source/ref-changelog.md:330 -msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in favour " -"of a new argument `transport`. `start_client(transport=\"rest\")` will yield " -"the same behaviour as `start_client(rest=True)` did before. All code should " -"migrate to the new argument `transport`. The deprecated argument `rest` will " -"be removed in a future release." +msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "" #: ../../source/ref-changelog.md:332 -msgid "" -"**Add a new gRPC option** ([#2197](https://github.com/adap/flower/pull/2197))" +msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "" #: ../../source/ref-changelog.md:334 -msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls` " -"option set to 0 by default. This prevents the clients from sending keepalive " -"pings when there is no outstanding stream." +msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "" #: ../../source/ref-changelog.md:336 msgid "" -"**Improve example notebooks** ([#2005](https://github.com/adap/flower/" -"pull/2005))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" msgstr "" #: ../../source/ref-changelog.md:338 -msgid "There's a new 30min Federated Learning PyTorch tutorial!" +msgid "" +"**General updates to Flower Examples** " +"([#2384](https://github.com/adap/flower/pull/2384), " +"[#2425](https://github.com/adap/flower/pull/2425), " +"[#2526](https://github.com/adap/flower/pull/2526), " +"[#2302](https://github.com/adap/flower/pull/2302), " +"[#2545](https://github.com/adap/flower/pull/2545))" msgstr "" #: ../../source/ref-changelog.md:340 msgid "" -"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), [#1981](https://github." -"com/adap/flower/pull/1981), [#1988](https://github.com/adap/flower/" -"pull/1988), [#1984](https://github.com/adap/flower/pull/1984), [#1982]" -"(https://github.com/adap/flower/pull/1982), [#2112](https://github.com/adap/" -"flower/pull/2112), [#2144](https://github.com/adap/flower/pull/2144), [#2174]" -"(https://github.com/adap/flower/pull/2174), [#2225](https://github.com/adap/" -"flower/pull/2225), [#2183](https://github.com/adap/flower/pull/2183))" +"**General updates to Flower Baselines** " +"([#2301](https://github.com/adap/flower/pull/2301), " +"[#2305](https://github.com/adap/flower/pull/2305), " +"[#2307](https://github.com/adap/flower/pull/2307), " +"[#2327](https://github.com/adap/flower/pull/2327), " +"[#2435](https://github.com/adap/flower/pull/2435), " +"[#2462](https://github.com/adap/flower/pull/2462), " +"[#2463](https://github.com/adap/flower/pull/2463), " +"[#2461](https://github.com/adap/flower/pull/2461), " +"[#2469](https://github.com/adap/flower/pull/2469), " +"[#2466](https://github.com/adap/flower/pull/2466), " +"[#2471](https://github.com/adap/flower/pull/2471), " +"[#2472](https://github.com/adap/flower/pull/2472), " +"[#2470](https://github.com/adap/flower/pull/2470))" msgstr "" #: ../../source/ref-changelog.md:342 msgid "" -"Many examples have received significant updates, including simplified " -"advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A " -"major upgrade is that all code examples now have a `requirements.txt` (in " -"addition to `pyproject.toml`)." +"**General updates to the simulation engine** " +"([#2331](https://github.com/adap/flower/pull/2331), " +"[#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), " +"[#2294](https://github.com/adap/flower/pull/2294))" msgstr "" #: ../../source/ref-changelog.md:344 msgid "" -"**General improvements** ([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), [#1884](https://github." -"com/adap/flower/pull/1884), [#1837](https://github.com/adap/flower/" -"pull/1837), [#1477](https://github.com/adap/flower/pull/1477), [#2171]" -"(https://github.com/adap/flower/pull/2171))" +"**General updates to Flower SDKs** " +"([#2288](https://github.com/adap/flower/pull/2288), " +"[#2429](https://github.com/adap/flower/pull/2429), " +"[#2555](https://github.com/adap/flower/pull/2555), " +"[#2543](https://github.com/adap/flower/pull/2543), " +"[#2544](https://github.com/adap/flower/pull/2544), " +"[#2597](https://github.com/adap/flower/pull/2597), " +"[#2623](https://github.com/adap/flower/pull/2623))" +msgstr "" + +#: ../../source/ref-changelog.md:346 +msgid "" +"**General improvements** " +"([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), " +"[#2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[#2317](https://github.com/adap/flower/pull/2317), " +"[#2349](https://github.com/adap/flower/pull/2349), " +"[#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446), " +"[#2561](https://github.com/adap/flower/pull/2561), " +"[#2273](https://github.com/adap/flower/pull/2273), " +"[#2267](https://github.com/adap/flower/pull/2267), " +"[#2274](https://github.com/adap/flower/pull/2274), " +"[#2275](https://github.com/adap/flower/pull/2275), " +"[#2432](https://github.com/adap/flower/pull/2432), " +"[#2251](https://github.com/adap/flower/pull/2251), " +"[#2321](https://github.com/adap/flower/pull/2321), " +"[#1936](https://github.com/adap/flower/pull/1936), " +"[#2408](https://github.com/adap/flower/pull/2408), " +"[#2413](https://github.com/adap/flower/pull/2413), " +"[#2401](https://github.com/adap/flower/pull/2401), " +"[#2531](https://github.com/adap/flower/pull/2531), " +"[#2534](https://github.com/adap/flower/pull/2534), " +"[#2535](https://github.com/adap/flower/pull/2535), " +"[#2521](https://github.com/adap/flower/pull/2521), " +"[#2553](https://github.com/adap/flower/pull/2553), " +"[#2596](https://github.com/adap/flower/pull/2596))" +msgstr "" + +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:502 ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:623 +msgid "Flower received many improvements under the hood, too many to list here." msgstr "" #: ../../source/ref-changelog.md:352 -msgid "v1.4.0 (2023-04-21)" +msgid "" +"**Remove support for Python 3.7** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" msgstr "" -#: ../../source/ref-changelog.md:358 +#: ../../source/ref-changelog.md:354 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" -"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " -"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " -"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " -"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"Python 3.7 support was deprecated in Flower 1.5, and this release removes" +" support. Flower now requires Python 3.8." msgstr "" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:356 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and example)** " -"([#1694](https://github.com/adap/flower/pull/1694), [#1709](https://github." -"com/adap/flower/pull/1709), [#1715](https://github.com/adap/flower/" -"pull/1715), [#1717](https://github.com/adap/flower/pull/1717), [#1763]" -"(https://github.com/adap/flower/pull/1763), [#1795](https://github.com/adap/" -"flower/pull/1795))" +"**Remove experimental argument** `rest` **from** `start_client` " +"([#2324](https://github.com/adap/flower/pull/2324))" msgstr "" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:358 msgid "" -"XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg` " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/" -"strategy/fedxgb_nn_avg.py), and a [code example](https://github.com/adap/" -"flower/tree/main/examples/xgboost-quickstart) that demonstrates the usage of " -"this new strategy in an XGBoost project." +"The (still experimental) argument `rest` was removed from `start_client` " +"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " +"experimental REST API instead." msgstr "" -#: ../../source/ref-changelog.md:366 -msgid "" -"**Introduce iOS SDK (preview)** ([#1621](https://github.com/adap/flower/" -"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" +#: ../../source/ref-changelog.md:360 +msgid "v1.5.0 (2023-08-31)" msgstr "" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:366 msgid "" -"This is a major update for anyone wanting to implement Federated Learning on " -"iOS mobile devices. We now have a swift iOS SDK present under [src/swift/" -"flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) that will " -"facilitate greatly the app creating process. To showcase its use, the [iOS " -"example](https://github.com/adap/flower/tree/main/examples/ios) has also " -"been updated!" +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " msgstr "" #: ../../source/ref-changelog.md:370 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** ([#1657](https://" -"github.com/adap/flower/pull/1657), [#1721](https://github.com/adap/flower/" -"pull/1721))" +"**Introduce new simulation engine** " +"([#1969](https://github.com/adap/flower/pull/1969), " +"[#2221](https://github.com/adap/flower/pull/2221), " +"[#2248](https://github.com/adap/flower/pull/2248))" msgstr "" #: ../../source/ref-changelog.md:372 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-what-" -"is-federated-learning.html) in our documentation explains the basics of " -"Fedetated Learning. It enables anyone who's unfamiliar with Federated " -"Learning to start their journey with Flower. Forward it to anyone who's " -"interested in Federated Learning!" +"The new simulation engine has been rewritten from the ground up, yet it " +"remains fully backwards compatible. It offers much improved stability and" +" memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-" +"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" #: ../../source/ref-changelog.md:374 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" -"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." -"com/adap/flower/pull/1679))" +"Comprehensive documentation includes a new [how-to run " +"simulations](https://flower.ai/docs/framework/how-to-run-" +"simulations.html) guide, new [simulation-" +"pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " +"[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" +"tensorflow.html) notebooks, and a new [YouTube tutorial " +"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" #: ../../source/ref-changelog.md:376 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated " -"Optimization in Heterogeneous Networks (Li et al., 2018)](https://arxiv.org/" -"abs/1812.06127). It uses the `FedProx` strategy, which aims at making " -"convergence more robust in heterogeneous settings." +"**Restructure Flower Docs** " +"([#1824](https://github.com/adap/flower/pull/1824), " +"[#1865](https://github.com/adap/flower/pull/1865), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1887](https://github.com/adap/flower/pull/1887), " +"[#1919](https://github.com/adap/flower/pull/1919), " +"[#1922](https://github.com/adap/flower/pull/1922), " +"[#1920](https://github.com/adap/flower/pull/1920), " +"[#1923](https://github.com/adap/flower/pull/1923), " +"[#1924](https://github.com/adap/flower/pull/1924), " +"[#1962](https://github.com/adap/flower/pull/1962), " +"[#2006](https://github.com/adap/flower/pull/2006), " +"[#2133](https://github.com/adap/flower/pull/2133), " +"[#2203](https://github.com/adap/flower/pull/2203), " +"[#2215](https://github.com/adap/flower/pull/2215), " +"[#2122](https://github.com/adap/flower/pull/2122), " +"[#2223](https://github.com/adap/flower/pull/2223), " +"[#2219](https://github.com/adap/flower/pull/2219), " +"[#2232](https://github.com/adap/flower/pull/2232), " +"[#2233](https://github.com/adap/flower/pull/2233), " +"[#2234](https://github.com/adap/flower/pull/2234), " +"[#2235](https://github.com/adap/flower/pull/2235), " +"[#2237](https://github.com/adap/flower/pull/2237), " +"[#2238](https://github.com/adap/flower/pull/2238), " +"[#2242](https://github.com/adap/flower/pull/2242), " +"[#2231](https://github.com/adap/flower/pull/2231), " +"[#2243](https://github.com/adap/flower/pull/2243), " +"[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" #: ../../source/ref-changelog.md:378 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** ([#1655](https://github." -"com/adap/flower/pull/1655))" +"Much effort went into a completely restructured Flower docs experience. " +"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " +"divided into Flower Framework, Flower Baselines, Flower Android SDK, " +"Flower iOS SDK, and code example projects." msgstr "" #: ../../source/ref-changelog.md:380 msgid "" -"This new baseline replicates an experiment evaluating the performance of the " -"FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A Benchmark " -"for Federated Settings (Caldas et al., 2018)](https://arxiv.org/" -"abs/1812.01097)." +"**Introduce Flower Swift SDK** " +"([#1858](https://github.com/adap/flower/pull/1858), " +"[#1897](https://github.com/adap/flower/pull/1897))" msgstr "" #: ../../source/ref-changelog.md:382 msgid "" -"**Introduce (experimental) REST API** ([#1594](https://github.com/adap/" -"flower/pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" -"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" -"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" -"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" -"flower/pull/1733))" +"This is the first preview release of the Flower Swift SDK. Flower support" +" on iOS is improving, and alongside the Swift SDK and code example, there" +" is now also an iOS quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:384 msgid "" -"A new REST API has been introduced as an alternative to the gRPC-based " -"communication stack. In this initial version, the REST API only supports " -"anonymous clients." +"**Introduce Flower Android SDK** " +"([#2131](https://github.com/adap/flower/pull/2131))" msgstr "" #: ../../source/ref-changelog.md:386 msgid "" -"Please note: The REST API is still experimental and will likely change " -"significantly over time." +"This is the first preview release of the Flower Kotlin SDK. Flower " +"support on Android is improving, and alongside the Kotlin SDK and code " +"example, there is now also an Android quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:388 msgid "" -"**Improve the (experimental) Driver API** ([#1663](https://github.com/adap/" -"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" -"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" -"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" -"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" -"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" -"(https://github.com/adap/flower/pull/1794))" +"**Introduce new end-to-end testing infrastructure** " +"([#1842](https://github.com/adap/flower/pull/1842), " +"[#2071](https://github.com/adap/flower/pull/2071), " +"[#2072](https://github.com/adap/flower/pull/2072), " +"[#2068](https://github.com/adap/flower/pull/2068), " +"[#2067](https://github.com/adap/flower/pull/2067), " +"[#2069](https://github.com/adap/flower/pull/2069), " +"[#2073](https://github.com/adap/flower/pull/2073), " +"[#2070](https://github.com/adap/flower/pull/2070), " +"[#2074](https://github.com/adap/flower/pull/2074), " +"[#2082](https://github.com/adap/flower/pull/2082), " +"[#2084](https://github.com/adap/flower/pull/2084), " +"[#2093](https://github.com/adap/flower/pull/2093), " +"[#2109](https://github.com/adap/flower/pull/2109), " +"[#2095](https://github.com/adap/flower/pull/2095), " +"[#2140](https://github.com/adap/flower/pull/2140), " +"[#2137](https://github.com/adap/flower/pull/2137), " +"[#2165](https://github.com/adap/flower/pull/2165))" msgstr "" #: ../../source/ref-changelog.md:390 msgid "" -"The Driver API is still an experimental feature, but this release introduces " -"some major upgrades. One of the main improvements is the introduction of an " -"SQLite database to store server state on disk (instead of in-memory). " -"Another improvement is that tasks (instructions or results) that have been " -"delivered will now be deleted. This greatly improves the memory efficiency " -"of a long-running Flower server." +"A new testing infrastructure ensures that new changes stay compatible " +"with existing framework integrations or strategies." msgstr "" #: ../../source/ref-changelog.md:392 -msgid "" -"**Fix spilling issues related to Ray during simulations** ([#1698](https://" -"github.com/adap/flower/pull/1698))" +msgid "**Deprecate Python 3.7**" msgstr "" #: ../../source/ref-changelog.md:394 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts of " -"data that would make the training unable to continue. This is now fixed! 🎉" +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" +" Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" #: ../../source/ref-changelog.md:396 msgid "" -"**Add new example using** `TabNet` **and Flower** ([#1725](https://github." -"com/adap/flower/pull/1725))" +"**Add new** `FedTrimmedAvg` **strategy** " +"([#1769](https://github.com/adap/flower/pull/1769), " +"[#1853](https://github.com/adap/flower/pull/1853))" msgstr "" #: ../../source/ref-changelog.md:398 msgid "" -"TabNet is a powerful and flexible framework for training machine learning " -"models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples/" -"quickstart-tabnet)." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " +"2018](https://arxiv.org/abs/1803.01498)." msgstr "" #: ../../source/ref-changelog.md:400 msgid "" -"**Add new how-to guide for monitoring simulations** ([#1649](https://github." -"com/adap/flower/pull/1649))" +"**Introduce start_driver** " +"([#1697](https://github.com/adap/flower/pull/1697))" msgstr "" #: ../../source/ref-changelog.md:402 msgid "" -"We now have a documentation guide to help users monitor their performance " -"during simulations." +"In addition to `start_server` and using the raw Driver API, there is a " +"new `start_driver` function that allows for running `start_server` " +"scripts as a Flower driver with only a single-line code change. Check out" +" the `mt-pytorch` code example to see a working example using " +"`start_driver`." msgstr "" #: ../../source/ref-changelog.md:404 msgid "" -"**Add training metrics to** `History` **object during simulations** ([#1696]" -"(https://github.com/adap/flower/pull/1696))" +"**Add parameter aggregation to** `mt-pytorch` **code example** " +"([#1785](https://github.com/adap/flower/pull/1785))" msgstr "" #: ../../source/ref-changelog.md:406 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training metrics, " -"but previous releases did not save the results in the `History` object. This " -"is now the case!" +"The `mt-pytorch` example shows how to aggregate parameters when writing a" +" driver script. The included `driver.py` and `server.py` have been " +"aligned to demonstrate both the low-level way and the high-level way of " +"building server-side logic." msgstr "" #: ../../source/ref-changelog.md:408 msgid "" -"**General improvements** ([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), [#1647](https://github." -"com/adap/flower/pull/1647), [#1471](https://github.com/adap/flower/" -"pull/1471), [#1648](https://github.com/adap/flower/pull/1648), [#1651]" -"(https://github.com/adap/flower/pull/1651), [#1652](https://github.com/adap/" -"flower/pull/1652), [#1653](https://github.com/adap/flower/pull/1653), [#1659]" -"(https://github.com/adap/flower/pull/1659), [#1665](https://github.com/adap/" -"flower/pull/1665), [#1670](https://github.com/adap/flower/pull/1670), [#1672]" -"(https://github.com/adap/flower/pull/1672), [#1677](https://github.com/adap/" -"flower/pull/1677), [#1684](https://github.com/adap/flower/pull/1684), [#1683]" -"(https://github.com/adap/flower/pull/1683), [#1686](https://github.com/adap/" -"flower/pull/1686), [#1682](https://github.com/adap/flower/pull/1682), [#1685]" -"(https://github.com/adap/flower/pull/1685), [#1692](https://github.com/adap/" -"flower/pull/1692), [#1705](https://github.com/adap/flower/pull/1705), [#1708]" -"(https://github.com/adap/flower/pull/1708), [#1711](https://github.com/adap/" -"flower/pull/1711), [#1713](https://github.com/adap/flower/pull/1713), [#1714]" -"(https://github.com/adap/flower/pull/1714), [#1718](https://github.com/adap/" -"flower/pull/1718), [#1716](https://github.com/adap/flower/pull/1716), [#1723]" -"(https://github.com/adap/flower/pull/1723), [#1735](https://github.com/adap/" -"flower/pull/1735), [#1678](https://github.com/adap/flower/pull/1678), [#1750]" -"(https://github.com/adap/flower/pull/1750), [#1753](https://github.com/adap/" -"flower/pull/1753), [#1736](https://github.com/adap/flower/pull/1736), [#1766]" -"(https://github.com/adap/flower/pull/1766), [#1760](https://github.com/adap/" -"flower/pull/1760), [#1775](https://github.com/adap/flower/pull/1775), [#1776]" -"(https://github.com/adap/flower/pull/1776), [#1777](https://github.com/adap/" -"flower/pull/1777), [#1779](https://github.com/adap/flower/pull/1779), [#1784]" -"(https://github.com/adap/flower/pull/1784), [#1773](https://github.com/adap/" -"flower/pull/1773), [#1755](https://github.com/adap/flower/pull/1755), [#1789]" -"(https://github.com/adap/flower/pull/1789), [#1788](https://github.com/adap/" -"flower/pull/1788), [#1798](https://github.com/adap/flower/pull/1798), [#1799]" -"(https://github.com/adap/flower/pull/1799), [#1739](https://github.com/adap/" -"flower/pull/1739), [#1800](https://github.com/adap/flower/pull/1800), [#1804]" -"(https://github.com/adap/flower/pull/1804), [#1805](https://github.com/adap/" -"flower/pull/1805))" +"**Migrate experimental REST API to Starlette** " +"([2171](https://github.com/adap/flower/pull/2171))" +msgstr "" + +#: ../../source/ref-changelog.md:410 +msgid "" +"The (experimental) REST API used to be implemented in " +"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" +" use [Starlette](https://www.starlette.io/) directly." +msgstr "" + +#: ../../source/ref-changelog.md:412 +msgid "" +"Please note: The REST request-response API is still experimental and will" +" likely change significantly over time." +msgstr "" + +#: ../../source/ref-changelog.md:414 +msgid "" +"**Introduce experimental gRPC request-response API** " +"([#1867](https://github.com/adap/flower/pull/1867), " +"[#1901](https://github.com/adap/flower/pull/1901))" msgstr "" #: ../../source/ref-changelog.md:416 -msgid "v1.3.0 (2023-02-06)" +msgid "" +"In addition to the existing gRPC API (based on bidirectional streaming) " +"and the experimental REST API, there is now a new gRPC API that uses a " +"request-response model to communicate with client nodes." +msgstr "" + +#: ../../source/ref-changelog.md:418 +msgid "" +"Please note: The gRPC request-response API is still experimental and will" +" likely change significantly over time." +msgstr "" + +#: ../../source/ref-changelog.md:420 +msgid "" +"**Replace the experimental** `start_client(rest=True)` **with the new** " +"`start_client(transport=\"rest\")` " +"([#1880](https://github.com/adap/flower/pull/1880))" msgstr "" #: ../../source/ref-changelog.md:422 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " -"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"The (experimental) `start_client` argument `rest` was deprecated in " +"favour of a new argument `transport`. `start_client(transport=\"rest\")` " +"will yield the same behaviour as `start_client(rest=True)` did before. " +"All code should migrate to the new argument `transport`. The deprecated " +"argument `rest` will be removed in a future release." +msgstr "" + +#: ../../source/ref-changelog.md:424 +msgid "" +"**Add a new gRPC option** " +"([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" #: ../../source/ref-changelog.md:426 msgid "" -"**Add support for** `workload_id` **and** `group_id` **in Driver API** " -"([#1595](https://github.com/adap/flower/pull/1595))" +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" +" option set to 0 by default. This prevents the clients from sending " +"keepalive pings when there is no outstanding stream." msgstr "" #: ../../source/ref-changelog.md:428 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be used " -"to identify which workload a task belongs to. It also supports a new " -"`group_id` that can be used, for example, to indicate the current training " -"round. Both the `workload_id` and `group_id` enable client nodes to decide " -"whether they want to handle a task or not." +"**Improve example notebooks** " +"([#2005](https://github.com/adap/flower/pull/2005))" msgstr "" #: ../../source/ref-changelog.md:430 -msgid "" -"**Make Driver API and Fleet API address configurable** ([#1637](https://" -"github.com/adap/flower/pull/1637))" +msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "" #: ../../source/ref-changelog.md:432 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) can " -"now configure the server address of both Driver API (via `--driver-api-" -"address`) and Fleet API (via `--fleet-api-address`) when starting:" +"**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " +"[#1873](https://github.com/adap/flower/pull/1873), " +"[#1981](https://github.com/adap/flower/pull/1981), " +"[#1988](https://github.com/adap/flower/pull/1988), " +"[#1984](https://github.com/adap/flower/pull/1984), " +"[#1982](https://github.com/adap/flower/pull/1982), " +"[#2112](https://github.com/adap/flower/pull/2112), " +"[#2144](https://github.com/adap/flower/pull/2144), " +"[#2174](https://github.com/adap/flower/pull/2174), " +"[#2225](https://github.com/adap/flower/pull/2225), " +"[#2183](https://github.com/adap/flower/pull/2183))" msgstr "" #: ../../source/ref-changelog.md:434 msgid "" +"Many examples have received significant updates, including simplified " +"advanced-tensorflow and advanced-pytorch examples, improved macOS " +"compatibility of TensorFlow examples, and code examples for simulation. A" +" major upgrade is that all code examples now have a `requirements.txt` " +"(in addition to `pyproject.toml`)." +msgstr "" + +#: ../../source/ref-changelog.md:436 +msgid "" +"**General improvements** " +"([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" +msgstr "" + +#: ../../source/ref-changelog.md:444 +msgid "v1.4.0 (2023-04-21)" +msgstr "" + +#: ../../source/ref-changelog.md:450 +msgid "" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " +"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " +"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " +"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " +"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +msgstr "" + +#: ../../source/ref-changelog.md:454 +msgid "" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " +"example)** ([#1694](https://github.com/adap/flower/pull/1694), " +"[#1709](https://github.com/adap/flower/pull/1709), " +"[#1715](https://github.com/adap/flower/pull/1715), " +"[#1717](https://github.com/adap/flower/pull/1717), " +"[#1763](https://github.com/adap/flower/pull/1763), " +"[#1795](https://github.com/adap/flower/pull/1795))" +msgstr "" + +#: ../../source/ref-changelog.md:456 +msgid "" +"XGBoost is a tree-based ensemble machine learning algorithm that uses " +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" +" " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," +" and a [code example](https://github.com/adap/flower/tree/main/examples" +"/xgboost-quickstart) that demonstrates the usage of this new strategy in " +"an XGBoost project." +msgstr "" + +#: ../../source/ref-changelog.md:458 +msgid "" +"**Introduce iOS SDK (preview)** " +"([#1621](https://github.com/adap/flower/pull/1621), " +"[#1764](https://github.com/adap/flower/pull/1764))" +msgstr "" + +#: ../../source/ref-changelog.md:460 +msgid "" +"This is a major update for anyone wanting to implement Federated Learning" +" on iOS mobile devices. We now have a swift iOS SDK present under " +"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" +" that will facilitate greatly the app creating process. To showcase its " +"use, the [iOS " +"example](https://github.com/adap/flower/tree/main/examples/ios) has also " +"been updated!" +msgstr "" + +#: ../../source/ref-changelog.md:462 +msgid "" +"**Introduce new \"What is Federated Learning?\" tutorial** " +"([#1657](https://github.com/adap/flower/pull/1657), " +"[#1721](https://github.com/adap/flower/pull/1721))" +msgstr "" + +#: ../../source/ref-changelog.md:464 +msgid "" +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" +"what-is-federated-learning.html) in our documentation explains the basics" +" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" +" Learning to start their journey with Flower. Forward it to anyone who's " +"interested in Federated Learning!" +msgstr "" + +#: ../../source/ref-changelog.md:466 +msgid "" +"**Introduce new Flower Baseline: FedProx MNIST** " +"([#1513](https://github.com/adap/flower/pull/1513), " +"[#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), " +"[#1679](https://github.com/adap/flower/pull/1679))" +msgstr "" + +#: ../../source/ref-changelog.md:468 +msgid "" +"This new baseline replicates the MNIST+CNN task from the paper [Federated" +" Optimization in Heterogeneous Networks (Li et al., " +"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," +" which aims at making convergence more robust in heterogeneous settings." +msgstr "" + +#: ../../source/ref-changelog.md:470 +msgid "" +"**Introduce new Flower Baseline: FedAvg FEMNIST** " +"([#1655](https://github.com/adap/flower/pull/1655))" +msgstr "" + +#: ../../source/ref-changelog.md:472 +msgid "" +"This new baseline replicates an experiment evaluating the performance of " +"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " +"Benchmark for Federated Settings (Caldas et al., " +"2018)](https://arxiv.org/abs/1812.01097)." +msgstr "" + +#: ../../source/ref-changelog.md:474 +msgid "" +"**Introduce (experimental) REST API** " +"([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" +msgstr "" + +#: ../../source/ref-changelog.md:476 +msgid "" +"A new REST API has been introduced as an alternative to the gRPC-based " +"communication stack. In this initial version, the REST API only supports " +"anonymous clients." +msgstr "" + +#: ../../source/ref-changelog.md:478 +msgid "" +"Please note: The REST API is still experimental and will likely change " +"significantly over time." +msgstr "" + +#: ../../source/ref-changelog.md:480 +msgid "" +"**Improve the (experimental) Driver API** " +"([#1663](https://github.com/adap/flower/pull/1663), " +"[#1666](https://github.com/adap/flower/pull/1666), " +"[#1667](https://github.com/adap/flower/pull/1667), " +"[#1664](https://github.com/adap/flower/pull/1664), " +"[#1675](https://github.com/adap/flower/pull/1675), " +"[#1676](https://github.com/adap/flower/pull/1676), " +"[#1693](https://github.com/adap/flower/pull/1693), " +"[#1662](https://github.com/adap/flower/pull/1662), " +"[#1794](https://github.com/adap/flower/pull/1794))" +msgstr "" + +#: ../../source/ref-changelog.md:482 +msgid "" +"The Driver API is still an experimental feature, but this release " +"introduces some major upgrades. One of the main improvements is the " +"introduction of an SQLite database to store server state on disk (instead" +" of in-memory). Another improvement is that tasks (instructions or " +"results) that have been delivered will now be deleted. This greatly " +"improves the memory efficiency of a long-running Flower server." +msgstr "" + +#: ../../source/ref-changelog.md:484 +msgid "" +"**Fix spilling issues related to Ray during simulations** " +"([#1698](https://github.com/adap/flower/pull/1698))" +msgstr "" + +#: ../../source/ref-changelog.md:486 +msgid "" +"While running long simulations, `ray` was sometimes spilling huge amounts" +" of data that would make the training unable to continue. This is now " +"fixed! 🎉" +msgstr "" + +#: ../../source/ref-changelog.md:488 +msgid "" +"**Add new example using** `TabNet` **and Flower** " +"([#1725](https://github.com/adap/flower/pull/1725))" +msgstr "" + +#: ../../source/ref-changelog.md:490 +msgid "" +"TabNet is a powerful and flexible framework for training machine learning" +" models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" +"/quickstart-tabnet)." +msgstr "" + +#: ../../source/ref-changelog.md:492 +msgid "" +"**Add new how-to guide for monitoring simulations** " +"([#1649](https://github.com/adap/flower/pull/1649))" +msgstr "" + +#: ../../source/ref-changelog.md:494 +msgid "" +"We now have a documentation guide to help users monitor their performance" +" during simulations." +msgstr "" + +#: ../../source/ref-changelog.md:496 +msgid "" +"**Add training metrics to** `History` **object during simulations** " +"([#1696](https://github.com/adap/flower/pull/1696))" +msgstr "" + +#: ../../source/ref-changelog.md:498 +msgid "" +"The `fit_metrics_aggregation_fn` can be used to aggregate training " +"metrics, but previous releases did not save the results in the `History` " +"object. This is now the case!" +msgstr "" + +#: ../../source/ref-changelog.md:500 +msgid "" +"**General improvements** " +"([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), " +"[#1647](https://github.com/adap/flower/pull/1647), " +"[#1471](https://github.com/adap/flower/pull/1471), " +"[#1648](https://github.com/adap/flower/pull/1648), " +"[#1651](https://github.com/adap/flower/pull/1651), " +"[#1652](https://github.com/adap/flower/pull/1652), " +"[#1653](https://github.com/adap/flower/pull/1653), " +"[#1659](https://github.com/adap/flower/pull/1659), " +"[#1665](https://github.com/adap/flower/pull/1665), " +"[#1670](https://github.com/adap/flower/pull/1670), " +"[#1672](https://github.com/adap/flower/pull/1672), " +"[#1677](https://github.com/adap/flower/pull/1677), " +"[#1684](https://github.com/adap/flower/pull/1684), " +"[#1683](https://github.com/adap/flower/pull/1683), " +"[#1686](https://github.com/adap/flower/pull/1686), " +"[#1682](https://github.com/adap/flower/pull/1682), " +"[#1685](https://github.com/adap/flower/pull/1685), " +"[#1692](https://github.com/adap/flower/pull/1692), " +"[#1705](https://github.com/adap/flower/pull/1705), " +"[#1708](https://github.com/adap/flower/pull/1708), " +"[#1711](https://github.com/adap/flower/pull/1711), " +"[#1713](https://github.com/adap/flower/pull/1713), " +"[#1714](https://github.com/adap/flower/pull/1714), " +"[#1718](https://github.com/adap/flower/pull/1718), " +"[#1716](https://github.com/adap/flower/pull/1716), " +"[#1723](https://github.com/adap/flower/pull/1723), " +"[#1735](https://github.com/adap/flower/pull/1735), " +"[#1678](https://github.com/adap/flower/pull/1678), " +"[#1750](https://github.com/adap/flower/pull/1750), " +"[#1753](https://github.com/adap/flower/pull/1753), " +"[#1736](https://github.com/adap/flower/pull/1736), " +"[#1766](https://github.com/adap/flower/pull/1766), " +"[#1760](https://github.com/adap/flower/pull/1760), " +"[#1775](https://github.com/adap/flower/pull/1775), " +"[#1776](https://github.com/adap/flower/pull/1776), " +"[#1777](https://github.com/adap/flower/pull/1777), " +"[#1779](https://github.com/adap/flower/pull/1779), " +"[#1784](https://github.com/adap/flower/pull/1784), " +"[#1773](https://github.com/adap/flower/pull/1773), " +"[#1755](https://github.com/adap/flower/pull/1755), " +"[#1789](https://github.com/adap/flower/pull/1789), " +"[#1788](https://github.com/adap/flower/pull/1788), " +"[#1798](https://github.com/adap/flower/pull/1798), " +"[#1799](https://github.com/adap/flower/pull/1799), " +"[#1739](https://github.com/adap/flower/pull/1739), " +"[#1800](https://github.com/adap/flower/pull/1800), " +"[#1804](https://github.com/adap/flower/pull/1804), " +"[#1805](https://github.com/adap/flower/pull/1805))" +msgstr "" + +#: ../../source/ref-changelog.md:508 +msgid "v1.3.0 (2023-02-06)" +msgstr "" + +#: ../../source/ref-changelog.md:514 +msgid "" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " +"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +msgstr "" + +#: ../../source/ref-changelog.md:518 +msgid "" +"**Add support for** `workload_id` **and** `group_id` **in Driver API** " +"([#1595](https://github.com/adap/flower/pull/1595))" +msgstr "" + +#: ../../source/ref-changelog.md:520 +msgid "" +"The (experimental) Driver API now supports a `workload_id` that can be " +"used to identify which workload a task belongs to. It also supports a new" +" `group_id` that can be used, for example, to indicate the current " +"training round. Both the `workload_id` and `group_id` enable client nodes" +" to decide whether they want to handle a task or not." +msgstr "" + +#: ../../source/ref-changelog.md:522 +msgid "" +"**Make Driver API and Fleet API address configurable** " +"([#1637](https://github.com/adap/flower/pull/1637))" +msgstr "" + +#: ../../source/ref-changelog.md:524 +msgid "" +"The (experimental) long-running Flower server (Driver API and Fleet API) " +"can now configure the server address of both Driver API (via `--driver-" +"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +msgstr "" + +#: ../../source/ref-changelog.md:526 +msgid "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " "\"0.0.0.0:8086\"`" msgstr "" -#: ../../source/ref-changelog.md:436 +#: ../../source/ref-changelog.md:528 msgid "Both IPv4 and IPv6 addresses are supported." msgstr "" -#: ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:530 msgid "" -"**Add new example of Federated Learning using fastai and Flower** ([#1598]" -"(https://github.com/adap/flower/pull/1598))" +"**Add new example of Federated Learning using fastai and Flower** " +"([#1598](https://github.com/adap/flower/pull/1598))" msgstr "" -#: ../../source/ref-changelog.md:440 +#: ../../source/ref-changelog.md:532 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples/" -"quickstart-fastai)." +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" +"/quickstart-fastai)." msgstr "" -#: ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:534 msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest " -"versions of Android** ([#1603](https://github.com/adap/flower/pull/1603))" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" +" versions of Android** " +"([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -#: ../../source/ref-changelog.md:444 +#: ../../source/ref-changelog.md:536 msgid "" -"The Android code example has received a substantial update: the project is " -"compatible with Flower 1.0 (and later), the UI received a full refresh, and " -"the project is updated to be compatible with newer Android tooling." +"The Android code example has received a substantial update: the project " +"is compatible with Flower 1.0 (and later), the UI received a full " +"refresh, and the project is updated to be compatible with newer Android " +"tooling." msgstr "" -#: ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:538 msgid "" -"**Add new `FedProx` strategy** ([#1619](https://github.com/adap/flower/" -"pull/1619))" +"**Add new `FedProx` strategy** " +"([#1619](https://github.com/adap/flower/pull/1619))" msgstr "" -#: ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:540 msgid "" -"This [strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/" -"strategy/fedprox.py) is almost identical to [`FedAvg`](https://github.com/" -"adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py), but helps " -"users replicate what is described in this [paper](https://arxiv.org/" -"abs/1812.06127). It essentially adds a parameter called `proximal_mu` to " -"regularize the local models with respect to the global models." +"This " +"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" +" is almost identical to " +"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," +" but helps users replicate what is described in this " +"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " +"parameter called `proximal_mu` to regularize the local models with " +"respect to the global models." msgstr "" -#: ../../source/ref-changelog.md:450 +#: ../../source/ref-changelog.md:542 msgid "" -"**Add new metrics to telemetry events** ([#1640](https://github.com/adap/" -"flower/pull/1640))" +"**Add new metrics to telemetry events** " +"([#1640](https://github.com/adap/flower/pull/1640))" msgstr "" -#: ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:544 msgid "" "An updated event structure allows, for example, the clustering of events " "within the same workload." msgstr "" -#: ../../source/ref-changelog.md:454 +#: ../../source/ref-changelog.md:546 msgid "" -"**Add new custom strategy tutorial section** [#1623](https://github.com/adap/" -"flower/pull/1623)" +"**Add new custom strategy tutorial section** " +"[#1623](https://github.com/adap/flower/pull/1623)" msgstr "" -#: ../../source/ref-changelog.md:456 +#: ../../source/ref-changelog.md:548 msgid "" -"The Flower tutorial now has a new section that covers implementing a custom " -"strategy from scratch: [Open in Colab](https://colab.research.google.com/" -"github/adap/flower/blob/main/doc/source/tutorial-build-a-strategy-from-" -"scratch-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers implementing a " +"custom strategy from scratch: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:458 +#: ../../source/ref-changelog.md:550 msgid "" -"**Add new custom serialization tutorial section** ([#1622](https://github." -"com/adap/flower/pull/1622))" +"**Add new custom serialization tutorial section** " +"([#1622](https://github.com/adap/flower/pull/1622))" msgstr "" -#: ../../source/ref-changelog.md:460 +#: ../../source/ref-changelog.md:552 msgid "" -"The Flower tutorial now has a new section that covers custom serialization: " -"[Open in Colab](https://colab.research.google.com/github/adap/flower/blob/" -"main/doc/source/tutorial-customize-the-client-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers custom " +"serialization: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" +"/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:462 +#: ../../source/ref-changelog.md:554 msgid "" -"**General improvements** ([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), [#1636](https://github." -"com/adap/flower/pull/1636), [#1635](https://github.com/adap/flower/" -"pull/1635), [#1633](https://github.com/adap/flower/pull/1633), [#1632]" -"(https://github.com/adap/flower/pull/1632), [#1631](https://github.com/adap/" -"flower/pull/1631), [#1630](https://github.com/adap/flower/pull/1630), [#1627]" -"(https://github.com/adap/flower/pull/1627), [#1593](https://github.com/adap/" -"flower/pull/1593), [#1616](https://github.com/adap/flower/pull/1616), [#1615]" -"(https://github.com/adap/flower/pull/1615), [#1607](https://github.com/adap/" -"flower/pull/1607), [#1609](https://github.com/adap/flower/pull/1609), [#1608]" -"(https://github.com/adap/flower/pull/1608), [#1603](https://github.com/adap/" -"flower/pull/1603), [#1590](https://github.com/adap/flower/pull/1590), [#1580]" -"(https://github.com/adap/flower/pull/1580), [#1599](https://github.com/adap/" -"flower/pull/1599), [#1600](https://github.com/adap/flower/pull/1600), [#1601]" -"(https://github.com/adap/flower/pull/1601), [#1597](https://github.com/adap/" -"flower/pull/1597), [#1595](https://github.com/adap/flower/pull/1595), [#1591]" -"(https://github.com/adap/flower/pull/1591), [#1588](https://github.com/adap/" -"flower/pull/1588), [#1589](https://github.com/adap/flower/pull/1589), [#1587]" -"(https://github.com/adap/flower/pull/1587), [#1573](https://github.com/adap/" -"flower/pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" -"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" -"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" -"(https://github.com/adap/flower/pull/1586))" +"**General improvements** " +"([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), " +"[#1636](https://github.com/adap/flower/pull/1636), " +"[#1635](https://github.com/adap/flower/pull/1635), " +"[#1633](https://github.com/adap/flower/pull/1633), " +"[#1632](https://github.com/adap/flower/pull/1632), " +"[#1631](https://github.com/adap/flower/pull/1631), " +"[#1630](https://github.com/adap/flower/pull/1630), " +"[#1627](https://github.com/adap/flower/pull/1627), " +"[#1593](https://github.com/adap/flower/pull/1593), " +"[#1616](https://github.com/adap/flower/pull/1616), " +"[#1615](https://github.com/adap/flower/pull/1615), " +"[#1607](https://github.com/adap/flower/pull/1607), " +"[#1609](https://github.com/adap/flower/pull/1609), " +"[#1608](https://github.com/adap/flower/pull/1608), " +"[#1603](https://github.com/adap/flower/pull/1603), " +"[#1590](https://github.com/adap/flower/pull/1590), " +"[#1580](https://github.com/adap/flower/pull/1580), " +"[#1599](https://github.com/adap/flower/pull/1599), " +"[#1600](https://github.com/adap/flower/pull/1600), " +"[#1601](https://github.com/adap/flower/pull/1601), " +"[#1597](https://github.com/adap/flower/pull/1597), " +"[#1595](https://github.com/adap/flower/pull/1595), " +"[#1591](https://github.com/adap/flower/pull/1591), " +"[#1588](https://github.com/adap/flower/pull/1588), " +"[#1589](https://github.com/adap/flower/pull/1589), " +"[#1587](https://github.com/adap/flower/pull/1587), " +"[#1573](https://github.com/adap/flower/pull/1573), " +"[#1581](https://github.com/adap/flower/pull/1581), " +"[#1578](https://github.com/adap/flower/pull/1578), " +"[#1574](https://github.com/adap/flower/pull/1574), " +"[#1572](https://github.com/adap/flower/pull/1572), " +"[#1586](https://github.com/adap/flower/pull/1586))" msgstr "" -#: ../../source/ref-changelog.md:466 +#: ../../source/ref-changelog.md:558 msgid "" -"**Updated documentation** ([#1629](https://github.com/adap/flower/" -"pull/1629), [#1628](https://github.com/adap/flower/pull/1628), [#1620]" -"(https://github.com/adap/flower/pull/1620), [#1618](https://github.com/adap/" -"flower/pull/1618), [#1617](https://github.com/adap/flower/pull/1617), [#1613]" -"(https://github.com/adap/flower/pull/1613), [#1614](https://github.com/adap/" -"flower/pull/1614))" +"**Updated documentation** " +"([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614))" msgstr "" -#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 +#: ../../source/ref-changelog.md:560 ../../source/ref-changelog.md:627 msgid "" -"As usual, the documentation has improved quite a bit. It is another step in " -"our effort to make the Flower documentation the best documentation of any " -"project. Stay tuned and as always, feel free to provide feedback!" +"As usual, the documentation has improved quite a bit. It is another step " +"in our effort to make the Flower documentation the best documentation of " +"any project. Stay tuned and as always, feel free to provide feedback!" msgstr "" -#: ../../source/ref-changelog.md:474 +#: ../../source/ref-changelog.md:566 msgid "v1.2.0 (2023-01-13)" msgstr "" -#: ../../source/ref-changelog.md:480 +#: ../../source/ref-changelog.md:572 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " -"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." +" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -#: ../../source/ref-changelog.md:484 +#: ../../source/ref-changelog.md:576 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/" -"adap/flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" +"**Introduce new Flower Baseline: FedAvg MNIST** " +"([#1497](https://github.com/adap/flower/pull/1497), " +"[#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -#: ../../source/ref-changelog.md:486 +#: ../../source/ref-changelog.md:578 msgid "" "Over the coming weeks, we will be releasing a number of new reference " "implementations useful especially to FL newcomers. They will typically " "revisit well known papers from the literature, and be suitable for " "integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in this " -"series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-pack-" -"fedavg-mnist-cnn/)" +"deepen your knowledge of FL in general. Today's release is the first in " +"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" +"pack-fedavg-mnist-cnn/)" msgstr "" -#: ../../source/ref-changelog.md:488 +#: ../../source/ref-changelog.md:580 msgid "" -"**Improve GPU support in simulations** ([#1555](https://github.com/adap/" -"flower/pull/1555))" +"**Improve GPU support in simulations** " +"([#1555](https://github.com/adap/flower/pull/1555))" msgstr "" -#: ../../source/ref-changelog.md:490 +#: ../../source/ref-changelog.md:582 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated to " -"improve GPU support. The update includes some of the hard-earned lessons " -"from scaling simulations in GPU cluster environments. New defaults make " -"running GPU-based simulations substantially more robust." +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" +" to improve GPU support. The update includes some of the hard-earned " +"lessons from scaling simulations in GPU cluster environments. New " +"defaults make running GPU-based simulations substantially more robust." msgstr "" -#: ../../source/ref-changelog.md:492 +#: ../../source/ref-changelog.md:584 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** ([#1527](https://" -"github.com/adap/flower/pull/1527), [#1558](https://github.com/adap/flower/" -"pull/1558))" +"**Improve GPU support in Jupyter Notebook tutorials** " +"([#1527](https://github.com/adap/flower/pull/1527), " +"[#1558](https://github.com/adap/flower/pull/1558))" msgstr "" -#: ../../source/ref-changelog.md:494 +#: ../../source/ref-changelog.md:586 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to use " -"on GPU instances. We listened and made improvements to all of our Jupyter " -"notebooks! Check out the updated notebooks here:" +"Some users reported that Jupyter Notebooks have not always been easy to " +"use on GPU instances. We listened and made improvements to all of our " +"Jupyter notebooks! Check out the updated notebooks here:" msgstr "" -#: ../../source/ref-changelog.md:496 +#: ../../source/ref-changelog.md:588 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework/" -"tutorial-get-started-with-flower-pytorch.html)" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework" +"/tutorial-get-started-with-flower-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:589 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework/tutorial-" -"use-a-federated-learning-strategy-pytorch.html)" +"[Strategies in Federated Learning](https://flower.ai/docs/framework" +"/tutorial-use-a-federated-learning-strategy-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:498 +#: ../../source/ref-changelog.md:590 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a-" -"strategy-from-scratch-pytorch.html)" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" +"-strategy-from-scratch-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:591 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" -"the-client-pytorch.html)" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" +"customize-the-client-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:593 msgid "" -"**Introduce optional telemetry** ([#1533](https://github.com/adap/flower/" -"pull/1533), [#1544](https://github.com/adap/flower/pull/1544), [#1584]" -"(https://github.com/adap/flower/pull/1584))" +"**Introduce optional telemetry** " +"([#1533](https://github.com/adap/flower/pull/1533), " +"[#1544](https://github.com/adap/flower/pull/1544), " +"[#1584](https://github.com/adap/flower/pull/1584))" msgstr "" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:595 msgid "" -"After a [request for feedback](https://github.com/adap/flower/issues/1534) " -"from the community, the Flower open-source project introduces optional " -"collection of *anonymous* usage metrics to make well-informed decisions to " -"improve Flower. Doing this enables the Flower team to understand how Flower " -"is used and what challenges users might face." +"After a [request for " +"feedback](https://github.com/adap/flower/issues/1534) from the community," +" the Flower open-source project introduces optional collection of " +"*anonymous* usage metrics to make well-informed decisions to improve " +"Flower. Doing this enables the Flower team to understand how Flower is " +"used and what challenges users might face." msgstr "" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:597 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.** " -"Staying true to this statement, Flower makes it easy to disable telemetry " -"for users who do not want to share anonymous usage metrics. [Read more.]" -"(https://flower.ai/docs/telemetry.html)." +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users who do not want to share anonymous usage metrics. " +"[Read more.](https://flower.ai/docs/telemetry.html)." msgstr "" -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:599 msgid "" -"**Introduce (experimental) Driver API** ([#1520](https://github.com/adap/" -"flower/pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" -"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" -"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" -"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" -"flower/pull/1567))" +"**Introduce (experimental) Driver API** " +"([#1520](https://github.com/adap/flower/pull/1520), " +"[#1525](https://github.com/adap/flower/pull/1525), " +"[#1545](https://github.com/adap/flower/pull/1545), " +"[#1546](https://github.com/adap/flower/pull/1546), " +"[#1550](https://github.com/adap/flower/pull/1550), " +"[#1551](https://github.com/adap/flower/pull/1551), " +"[#1567](https://github.com/adap/flower/pull/1567))" msgstr "" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:601 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API " -"will be the abstraction that many upcoming features will be built on - and " -"you can start building those things now, too." +"Analytics applications. Phew, that's a lot! Going forward, the Driver API" +" will be the abstraction that many upcoming features will be built on - " +"and you can start building those things now, too." msgstr "" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:603 msgid "" -"The Driver API also enables a new execution mode in which the server runs " -"indefinitely. Multiple individual workloads can run concurrently and start " -"and stop their execution independent of the server. This is especially " -"useful for users who want to deploy Flower in production." +"The Driver API also enables a new execution mode in which the server runs" +" indefinitely. Multiple individual workloads can run concurrently and " +"start and stop their execution independent of the server. This is " +"especially useful for users who want to deploy Flower in production." msgstr "" -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:605 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward to " -"you feedback!" +"To learn more, check out the `mt-pytorch` code example. We look forward " +"to you feedback!" msgstr "" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:607 msgid "" -"Please note: *The Driver API is still experimental and will likely change " -"significantly over time.*" +"Please note: *The Driver API is still experimental and will likely change" +" significantly over time.*" msgstr "" -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:609 msgid "" -"**Add new Federated Analytics with Pandas example** ([#1469](https://github." -"com/adap/flower/pull/1469), [#1535](https://github.com/adap/flower/" -"pull/1535))" +"**Add new Federated Analytics with Pandas example** " +"([#1469](https://github.com/adap/flower/pull/1469), " +"[#1535](https://github.com/adap/flower/pull/1535))" msgstr "" -#: ../../source/ref-changelog.md:519 +#: ../../source/ref-changelog.md:611 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics " -"with Pandas and Flower. You can find it here: [quickstart-pandas](https://" -"github.com/adap/flower/tree/main/examples/quickstart-pandas)." +"A new code example (`quickstart-pandas`) demonstrates federated analytics" +" with Pandas and Flower. You can find it here: [quickstart-" +"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" +"pandas)." msgstr "" -#: ../../source/ref-changelog.md:521 +#: ../../source/ref-changelog.md:613 msgid "" -"**Add new strategies: Krum and MultiKrum** ([#1481](https://github.com/adap/" -"flower/pull/1481))" +"**Add new strategies: Krum and MultiKrum** " +"([#1481](https://github.com/adap/flower/pull/1481))" msgstr "" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:615 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum and " -"MultiKrum in their workloads." +"contributed a new `Krum` strategy that enables users to easily use Krum " +"and MultiKrum in their workloads." msgstr "" -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:617 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** ([#1495](https://" -"github.com/adap/flower/pull/1495))" +"**Update C++ example to be compatible with Flower v1.2.0** " +"([#1495](https://github.com/adap/flower/pull/1495))" msgstr "" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:619 msgid "" -"The C++ code example has received a substantial update to make it compatible " -"with the latest version of Flower." +"The C++ code example has received a substantial update to make it " +"compatible with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:621 msgid "" -"**General improvements** ([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), [#1506](https://github." -"com/adap/flower/pull/1506), [#1514](https://github.com/adap/flower/" -"pull/1514), [#1522](https://github.com/adap/flower/pull/1522), [#1523]" -"(https://github.com/adap/flower/pull/1523), [#1526](https://github.com/adap/" -"flower/pull/1526), [#1528](https://github.com/adap/flower/pull/1528), [#1547]" -"(https://github.com/adap/flower/pull/1547), [#1549](https://github.com/adap/" -"flower/pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" -"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" -"flower/pull/1566))" +"**General improvements** " +"([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), " +"[#1506](https://github.com/adap/flower/pull/1506), " +"[#1514](https://github.com/adap/flower/pull/1514), " +"[#1522](https://github.com/adap/flower/pull/1522), " +"[#1523](https://github.com/adap/flower/pull/1523), " +"[#1526](https://github.com/adap/flower/pull/1526), " +"[#1528](https://github.com/adap/flower/pull/1528), " +"[#1547](https://github.com/adap/flower/pull/1547), " +"[#1549](https://github.com/adap/flower/pull/1549), " +"[#1560](https://github.com/adap/flower/pull/1560), " +"[#1564](https://github.com/adap/flower/pull/1564), " +"[#1566](https://github.com/adap/flower/pull/1566))" msgstr "" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:625 msgid "" -"**Updated documentation** ([#1494](https://github.com/adap/flower/" -"pull/1494), [#1496](https://github.com/adap/flower/pull/1496), [#1500]" -"(https://github.com/adap/flower/pull/1500), [#1503](https://github.com/adap/" -"flower/pull/1503), [#1505](https://github.com/adap/flower/pull/1505), [#1524]" -"(https://github.com/adap/flower/pull/1524), [#1518](https://github.com/adap/" -"flower/pull/1518), [#1519](https://github.com/adap/flower/pull/1519), [#1515]" -"(https://github.com/adap/flower/pull/1515))" +"**Updated documentation** " +"([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" msgstr "" -#: ../../source/ref-changelog.md:537 +#: ../../source/ref-changelog.md:629 msgid "" -"One highlight is the new [first time contributor guide](https://flower.ai/" -"docs/first-time-contributors.html): if you've never contributed on GitHub " -"before, this is the perfect place to start!" +"One highlight is the new [first time contributor " +"guide](https://flower.ai/docs/first-time-contributors.html): if you've " +"never contributed on GitHub before, this is the perfect place to start!" msgstr "" -#: ../../source/ref-changelog.md:543 +#: ../../source/ref-changelog.md:635 msgid "v1.1.0 (2022-10-31)" msgstr "" -#: ../../source/ref-changelog.md:547 +#: ../../source/ref-changelog.md:639 msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:549 +#: ../../source/ref-changelog.md:641 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " -"`edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " +"`danielnugraha`, `edogab33`" msgstr "" -#: ../../source/ref-changelog.md:553 +#: ../../source/ref-changelog.md:645 msgid "" -"**Introduce Differential Privacy wrappers (preview)** ([#1357](https://" -"github.com/adap/flower/pull/1357), [#1460](https://github.com/adap/flower/" -"pull/1460))" +"**Introduce Differential Privacy wrappers (preview)** " +"([#1357](https://github.com/adap/flower/pull/1357), " +"[#1460](https://github.com/adap/flower/pull/1460))" msgstr "" -#: ../../source/ref-changelog.md:555 +#: ../../source/ref-changelog.md:647 msgid "" -"The first (experimental) preview of pluggable Differential Privacy wrappers " -"enables easy configuration and usage of differential privacy (DP). The " -"pluggable DP wrappers enable framework-agnostic **and** strategy-agnostic " -"usage of both client-side DP and server-side DP. Head over to the Flower " -"docs, a new explainer goes into more detail." +"The first (experimental) preview of pluggable Differential Privacy " +"wrappers enables easy configuration and usage of differential privacy " +"(DP). The pluggable DP wrappers enable framework-agnostic **and** " +"strategy-agnostic usage of both client-side DP and server-side DP. Head " +"over to the Flower docs, a new explainer goes into more detail." msgstr "" -#: ../../source/ref-changelog.md:557 +#: ../../source/ref-changelog.md:649 msgid "" -"**New iOS CoreML code example** ([#1289](https://github.com/adap/flower/" -"pull/1289))" +"**New iOS CoreML code example** " +"([#1289](https://github.com/adap/flower/pull/1289))" msgstr "" -#: ../../source/ref-changelog.md:559 +#: ../../source/ref-changelog.md:651 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can be " -"built for iOS. The code example contains both Flower iOS SDK components that " -"can be used for many tasks, and one task example running on CoreML." +"Flower goes iOS! A massive new code example shows how Flower clients can " +"be built for iOS. The code example contains both Flower iOS SDK " +"components that can be used for many tasks, and one task example running " +"on CoreML." msgstr "" -#: ../../source/ref-changelog.md:561 +#: ../../source/ref-changelog.md:653 msgid "" -"**New FedMedian strategy** ([#1461](https://github.com/adap/flower/" -"pull/1461))" +"**New FedMedian strategy** " +"([#1461](https://github.com/adap/flower/pull/1461))" msgstr "" -#: ../../source/ref-changelog.md:563 +#: ../../source/ref-changelog.md:655 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by [Yin " -"et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"The new `FedMedian` strategy implements Federated Median (FedMedian) by " +"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -#: ../../source/ref-changelog.md:565 +#: ../../source/ref-changelog.md:657 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** ([#1493](https://" -"github.com/adap/flower/pull/1493))" +"**Log** `Client` **exceptions in Virtual Client Engine** " +"([#1493](https://github.com/adap/flower/pull/1493))" msgstr "" -#: ../../source/ref-changelog.md:567 +#: ../../source/ref-changelog.md:659 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default and " -"not just exposed to the configured `Strategy` (via the `failures` argument)." +"All `Client` exceptions happening in the VCE are now logged by default " +"and not just exposed to the configured `Strategy` (via the `failures` " +"argument)." msgstr "" -#: ../../source/ref-changelog.md:569 +#: ../../source/ref-changelog.md:661 msgid "" -"**Improve Virtual Client Engine internals** ([#1401](https://github.com/adap/" -"flower/pull/1401), [#1453](https://github.com/adap/flower/pull/1453))" +"**Improve Virtual Client Engine internals** " +"([#1401](https://github.com/adap/flower/pull/1401), " +"[#1453](https://github.com/adap/flower/pull/1453))" msgstr "" -#: ../../source/ref-changelog.md:571 +#: ../../source/ref-changelog.md:663 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE now " -"uses Ray 2.0 under the hood, the value type of the `client_resources` " -"dictionary changed to `float` to allow fractions of resources to be " +"Some internals of the Virtual Client Engine have been revamped. The VCE " +"now uses Ray 2.0 under the hood, the value type of the `client_resources`" +" dictionary changed to `float` to allow fractions of resources to be " "allocated." msgstr "" -#: ../../source/ref-changelog.md:573 +#: ../../source/ref-changelog.md:665 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual Client " -"Engine**" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " +"Client Engine**" msgstr "" -#: ../../source/ref-changelog.md:575 +#: ../../source/ref-changelog.md:667 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and " -"`NumPyClient`) methods." +"The Virtual Client Engine now has full support for optional `Client` (and" +" `NumPyClient`) methods." msgstr "" -#: ../../source/ref-changelog.md:577 +#: ../../source/ref-changelog.md:669 msgid "" -"**Provide type information to packages using** `flwr` ([#1377](https://" -"github.com/adap/flower/pull/1377))" +"**Provide type information to packages using** `flwr` " +"([#1377](https://github.com/adap/flower/pull/1377))" msgstr "" -#: ../../source/ref-changelog.md:579 +#: ../../source/ref-changelog.md:671 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that the " -"package is typed. This enables typing support for projects or packages that " -"use `flwr` by enabling them to improve their code using static type checkers " -"like `mypy`." +"The package `flwr` is now bundled with a `py.typed` file indicating that " +"the package is typed. This enables typing support for projects or " +"packages that use `flwr` by enabling them to improve their code using " +"static type checkers like `mypy`." msgstr "" -#: ../../source/ref-changelog.md:581 +#: ../../source/ref-changelog.md:673 msgid "" -"**Updated code example** ([#1344](https://github.com/adap/flower/pull/1344), " +"**Updated code example** " +"([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -#: ../../source/ref-changelog.md:583 +#: ../../source/ref-changelog.md:675 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:585 +#: ../../source/ref-changelog.md:677 msgid "" -"**Updated documentation** ([#1355](https://github.com/adap/flower/" -"pull/1355), [#1558](https://github.com/adap/flower/pull/1558), [#1379]" -"(https://github.com/adap/flower/pull/1379), [#1380](https://github.com/adap/" -"flower/pull/1380), [#1381](https://github.com/adap/flower/pull/1381), [#1332]" -"(https://github.com/adap/flower/pull/1332), [#1391](https://github.com/adap/" -"flower/pull/1391), [#1403](https://github.com/adap/flower/pull/1403), [#1364]" -"(https://github.com/adap/flower/pull/1364), [#1409](https://github.com/adap/" -"flower/pull/1409), [#1419](https://github.com/adap/flower/pull/1419), [#1444]" -"(https://github.com/adap/flower/pull/1444), [#1448](https://github.com/adap/" -"flower/pull/1448), [#1417](https://github.com/adap/flower/pull/1417), [#1449]" -"(https://github.com/adap/flower/pull/1449), [#1465](https://github.com/adap/" -"flower/pull/1465), [#1467](https://github.com/adap/flower/pull/1467))" +"**Updated documentation** " +"([#1355](https://github.com/adap/flower/pull/1355), " +"[#1558](https://github.com/adap/flower/pull/1558), " +"[#1379](https://github.com/adap/flower/pull/1379), " +"[#1380](https://github.com/adap/flower/pull/1380), " +"[#1381](https://github.com/adap/flower/pull/1381), " +"[#1332](https://github.com/adap/flower/pull/1332), " +"[#1391](https://github.com/adap/flower/pull/1391), " +"[#1403](https://github.com/adap/flower/pull/1403), " +"[#1364](https://github.com/adap/flower/pull/1364), " +"[#1409](https://github.com/adap/flower/pull/1409), " +"[#1419](https://github.com/adap/flower/pull/1419), " +"[#1444](https://github.com/adap/flower/pull/1444), " +"[#1448](https://github.com/adap/flower/pull/1448), " +"[#1417](https://github.com/adap/flower/pull/1417), " +"[#1449](https://github.com/adap/flower/pull/1449), " +"[#1465](https://github.com/adap/flower/pull/1465), " +"[#1467](https://github.com/adap/flower/pull/1467))" msgstr "" -#: ../../source/ref-changelog.md:587 +#: ../../source/ref-changelog.md:679 msgid "" "There have been so many documentation updates that it doesn't even make " "sense to list them individually." msgstr "" -#: ../../source/ref-changelog.md:589 +#: ../../source/ref-changelog.md:681 msgid "" -"**Restructured documentation** ([#1387](https://github.com/adap/flower/" -"pull/1387))" +"**Restructured documentation** " +"([#1387](https://github.com/adap/flower/pull/1387))" msgstr "" -#: ../../source/ref-changelog.md:591 +#: ../../source/ref-changelog.md:683 msgid "" -"The documentation has been restructured to make it easier to navigate. This " -"is just the first step in a larger effort to make the Flower documentation " -"the best documentation of any project ever. Stay tuned!" +"The documentation has been restructured to make it easier to navigate. " +"This is just the first step in a larger effort to make the Flower " +"documentation the best documentation of any project ever. Stay tuned!" msgstr "" -#: ../../source/ref-changelog.md:593 +#: ../../source/ref-changelog.md:685 msgid "" -"**Open in Colab button** ([#1389](https://github.com/adap/flower/pull/1389))" +"**Open in Colab button** " +"([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" -#: ../../source/ref-changelog.md:595 +#: ../../source/ref-changelog.md:687 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a new " -"`Open in Colab` button. No need to install anything on your local machine, " -"you can now use and learn about Flower in your browser, it's only a single " -"click away." +"The four parts of the Flower Federated Learning Tutorial now come with a " +"new `Open in Colab` button. No need to install anything on your local " +"machine, you can now use and learn about Flower in your browser, it's " +"only a single click away." msgstr "" -#: ../../source/ref-changelog.md:597 +#: ../../source/ref-changelog.md:689 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468), " -"[#1470](https://github.com/adap/flower/pull/1470), [#1472](https://github." -"com/adap/flower/pull/1472), [#1473](https://github.com/adap/flower/" -"pull/1473), [#1474](https://github.com/adap/flower/pull/1474), [#1475]" -"(https://github.com/adap/flower/pull/1475))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," +" [#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475))" msgstr "" -#: ../../source/ref-changelog.md:599 +#: ../../source/ref-changelog.md:691 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved (many " -"small changes and fixes)." +"`NumPyClient`. The existing parts one and two have also been improved " +"(many small changes and fixes)." msgstr "" -#: ../../source/ref-changelog.md:605 +#: ../../source/ref-changelog.md:697 msgid "v1.0.0 (2022-07-28)" msgstr "" -#: ../../source/ref-changelog.md:607 +#: ../../source/ref-changelog.md:699 msgid "Highlights" msgstr "" -#: ../../source/ref-changelog.md:609 +#: ../../source/ref-changelog.md:701 msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:702 msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "" -#: ../../source/ref-changelog.md:611 +#: ../../source/ref-changelog.md:703 msgid "Configurable `get_parameters`" msgstr "" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:704 msgid "" -"Tons of small API cleanups resulting in a more coherent developer experience" +"Tons of small API cleanups resulting in a more coherent developer " +"experience" msgstr "" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:708 msgid "" "We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub Contributors](https://github." -"com/adap/flower/graphs/contributors) order):" -msgstr "" - -#: ../../source/ref-changelog.md:618 -msgid "" -"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" -"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" -"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" -"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." -"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" -"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." -"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." -"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" -"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" -"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" -"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" -"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" -"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." -"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" -"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" -"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" -"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" -"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" -"tanertopal), [@danieljanes](https://github.com/danieljanes)." -msgstr "" - -#: ../../source/ref-changelog.md:622 -msgid "" -"**All arguments must be passed as keyword arguments** ([#1338](https://" -"github.com/adap/flower/pull/1338))" +"made Flower 1.0 possible (in reverse [GitHub " +"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +msgstr "" + +#: ../../source/ref-changelog.md:710 +msgid "" +"[@rtaiello](https://github.com/rtaiello), " +"[@g-pichler](https://github.com/g-pichler), [@rob-" +"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" +"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " +"[@nfnt](https://github.com/nfnt), " +"[@tatiana-s](https://github.com/tatiana-s), " +"[@TParcollet](https://github.com/TParcollet), " +"[@vballoli](https://github.com/vballoli), " +"[@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " +"[@hei411](https://github.com/hei411), " +"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), " +"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" +"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " +"[@lbhm](https://github.com/lbhm), " +"[@sishtiaq](https://github.com/sishtiaq), " +"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" +"/Jueun-Park), [@architjen](https://github.com/architjen), " +"[@PratikGarai](https://github.com/PratikGarai), " +"[@mrinaald](https://github.com/mrinaald), " +"[@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), " +"[@sancarlim](https://github.com/sancarlim), " +"[@gubertoli](https://github.com/gubertoli), " +"[@Vingt100](https://github.com/Vingt100), " +"[@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), " +"[@jafermarq](https://github.com/jafermarq), " +"[@sisco0](https://github.com/sisco0), " +"[@akhilmathurs](https://github.com/akhilmathurs), " +"[@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), " +"[@pedropgusmao](https://github.com/pedropgusmao), " +"[@tanertopal](https://github.com/tanertopal), " +"[@danieljanes](https://github.com/danieljanes)." +msgstr "" + +#: ../../source/ref-changelog.md:714 +msgid "" +"**All arguments must be passed as keyword arguments** " +"([#1338](https://github.com/adap/flower/pull/1338))" msgstr "" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:716 msgid "" -"Pass all arguments as keyword arguments, positional arguments are not longer " -"supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword for " -"each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())`)." +"Pass all arguments as keyword arguments, positional arguments are not " +"longer supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " +"for each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", " +"client=FlowerClient())`)." msgstr "" -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:718 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` ([#1317](https://github.com/adap/flower/" -"pull/1317))" +"**and** `start_simulation` " +"([#1317](https://github.com/adap/flower/pull/1317))" msgstr "" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:720 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": 600.0}" -"`, `start_server` and `start_simulation` now expect a configuration object " -"of type `flwr.server.ServerConfig`. `ServerConfig` takes the same arguments " -"that as the previous config dict, but it makes writing type-safe code easier " -"and the default parameters values more transparent." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " +"600.0}`, `start_server` and `start_simulation` now expect a configuration" +" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" +" arguments that as the previous config dict, but it makes writing type-" +"safe code easier and the default parameters values more transparent." msgstr "" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:722 msgid "" -"**Rename built-in strategy parameters for clarity** ([#1334](https://github." -"com/adap/flower/pull/1334))" +"**Rename built-in strategy parameters for clarity** " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:632 +#: ../../source/ref-changelog.md:724 msgid "" "The following built-in strategy parameters were renamed to improve " "readability and consistency with other API's:" msgstr "" -#: ../../source/ref-changelog.md:634 +#: ../../source/ref-changelog.md:726 msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:635 +#: ../../source/ref-changelog.md:727 msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "" -#: ../../source/ref-changelog.md:636 +#: ../../source/ref-changelog.md:728 msgid "`eval_fn` --> `evaluate_fn`" msgstr "" -#: ../../source/ref-changelog.md:638 +#: ../../source/ref-changelog.md:730 msgid "" -"**Update default arguments of built-in strategies** ([#1278](https://github." -"com/adap/flower/pull/1278))" +"**Update default arguments of built-in strategies** " +"([#1278](https://github.com/adap/flower/pull/1278))" msgstr "" -#: ../../source/ref-changelog.md:640 +#: ../../source/ref-changelog.md:732 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently available " -"clients for training and evaluation. Projects that relied on the previous " -"default values can get the previous behaviour by initializing the strategy " -"in the following way:" +"`fraction_evaluate=1.0`, which means they select *all* currently " +"available clients for training and evaluation. Projects that relied on " +"the previous default values can get the previous behaviour by " +"initializing the strategy in the following way:" msgstr "" -#: ../../source/ref-changelog.md:642 +#: ../../source/ref-changelog.md:734 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "" -#: ../../source/ref-changelog.md:644 +#: ../../source/ref-changelog.md:736 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` ([#1334](https://github." -"com/adap/flower/pull/1334))" +"**Add** `server_round` **to** `Strategy.evaluate` " +"([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:646 +#: ../../source/ref-changelog.md:738 msgid "" -"The `Strategy` method `evaluate` now receives the current round of federated " -"learning/evaluation as the first parameter." +"The `Strategy` method `evaluate` now receives the current round of " +"federated learning/evaluation as the first parameter." msgstr "" -#: ../../source/ref-changelog.md:648 +#: ../../source/ref-changelog.md:740 msgid "" "**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:742 msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), and " -"(3) a config dictionary (`config`)." +"(`server_round`), (2) the model parameters to evaluate (`parameters`), " +"and (3) a config dictionary (`config`)." msgstr "" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:744 msgid "" -"**Rename** `rnd` **to** `server_round` ([#1321](https://github.com/adap/" -"flower/pull/1321))" +"**Rename** `rnd` **to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" msgstr "" -#: ../../source/ref-changelog.md:654 +#: ../../source/ref-changelog.md:746 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. To " -"improve reaability and avoid confusion with *random*, this parameter has " -"been renamed from `rnd` to `server_round`." +"current round of federated learning/evaluation as their first parameter. " +"To improve reaability and avoid confusion with *random*, this parameter " +"has been renamed from `rnd` to `server_round`." msgstr "" -#: ../../source/ref-changelog.md:656 +#: ../../source/ref-changelog.md:748 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` ([#1273](https://github.com/" -"adap/flower/pull/1273))" +"**Move** `flwr.dataset` **to** `flwr_baselines` " +"([#1273](https://github.com/adap/flower/pull/1273))" msgstr "" -#: ../../source/ref-changelog.md:658 -msgid "" -"The experimental package `flwr.dataset` was migrated to Flower Baselines." +#: ../../source/ref-changelog.md:750 +msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "" -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:752 msgid "" -"**Remove experimental strategies** ([#1280](https://github.com/adap/flower/" -"pull/1280))" +"**Remove experimental strategies** " +"([#1280](https://github.com/adap/flower/pull/1280))" msgstr "" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:754 msgid "" "Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " "`FedFSv1`)." msgstr "" -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:756 msgid "" -"**Rename** `Weights` **to** `NDArrays` ([#1258](https://github.com/adap/" -"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" +"**Rename** `Weights` **to** `NDArrays` " +"([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:758 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." msgstr "" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:760 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** `start_server` " -"([#1258](https://github.com/adap/flower/pull/1258), [#1259](https://github." -"com/adap/flower/pull/1259))" +"**Remove antiquated** `force_final_distributed_eval` **from** " +"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " +"[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:762 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been a " -"historic artefact, in this release it is finally gone for good." +"The `start_server` parameter `force_final_distributed_eval` has long been" +" a historic artefact, in this release it is finally gone for good." msgstr "" -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:764 msgid "" -"**Make** `get_parameters` **configurable** ([#1242](https://github.com/adap/" -"flower/pull/1242))" +"**Make** `get_parameters` **configurable** " +"([#1242](https://github.com/adap/flower/pull/1242))" msgstr "" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:766 msgid "" "The `get_parameters` method now accepts a configuration dictionary, just " "like `get_properties`, `fit`, and `evaluate`." msgstr "" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:768 msgid "" "**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " "**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:770 msgid "" "The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the consistency " -"between `start_simulation` and `start_server` and makes transitioning " -"between the two easier." +"`config` instead of the `num_rounds` integer. This improves the " +"consistency between `start_simulation` and `start_server` and makes " +"transitioning between the two easier." msgstr "" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:774 msgid "" -"**Support Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.10** " +"([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:776 msgid "" -"The previous Flower release introduced experimental support for Python 3.10, " -"this release declares Python 3.10 support as stable." +"The previous Flower release introduced experimental support for Python " +"3.10, this release declares Python 3.10 support as stable." msgstr "" -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:778 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** ([#1260]" -"(https://github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/" -"flower/pull/1277))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** " +"([#1260](https://github.com/adap/flower/pull/1260), " +"[#1277](https://github.com/adap/flower/pull/1277))" msgstr "" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:780 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that " -"implement, for example, only `fit`, but no other method. No need to " +"`fit`, and `evaluate` are all optional. This enables writing clients that" +" implement, for example, only `fit`, but no other method. No need to " "implement `evaluate` when using centralized evaluation!" msgstr "" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:782 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` ([#1281]" -"(https://github.com/adap/flower/pull/1281))" +"**Enable passing a** `Server` **instance to** `start_simulation` " +"([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:784 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server` " -"instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the " -"Virtual Client Engine." +"Similar to `start_server`, `start_simulation` now accepts a full `Server`" +" instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the" +" Virtual Client Engine." msgstr "" -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:786 msgid "" -"**Update code examples** ([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), [#1282](https://github." -"com/adap/flower/pull/1282))" +"**Update code examples** " +"([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), " +"[#1282](https://github.com/adap/flower/pull/1282))" msgstr "" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:788 msgid "" -"Many code examples received small or even large maintenance updates, among " -"them are" +"Many code examples received small or even large maintenance updates, " +"among them are" msgstr "" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:790 msgid "`scikit-learn`" msgstr "" -#: ../../source/ref-changelog.md:699 +#: ../../source/ref-changelog.md:791 msgid "`simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:792 msgid "`quickstart_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:701 +#: ../../source/ref-changelog.md:793 msgid "`quickstart_simulation`" msgstr "" -#: ../../source/ref-changelog.md:702 +#: ../../source/ref-changelog.md:794 msgid "`quickstart_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:703 +#: ../../source/ref-changelog.md:795 msgid "`advanced_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:797 msgid "" -"**Remove the obsolete simulation example** ([#1328](https://github.com/adap/" -"flower/pull/1328))" +"**Remove the obsolete simulation example** " +"([#1328](https://github.com/adap/flower/pull/1328))" msgstr "" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:799 msgid "" "Removes the obsolete `simulation` example and renames " "`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " "naming of `simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:709 +#: ../../source/ref-changelog.md:801 msgid "" -"**Update documentation** ([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), [#1251](https://github." -"com/adap/flower/pull/1251), [#1257](https://github.com/adap/flower/" -"pull/1257), [#1267](https://github.com/adap/flower/pull/1267), [#1268]" -"(https://github.com/adap/flower/pull/1268), [#1300](https://github.com/adap/" -"flower/pull/1300), [#1304](https://github.com/adap/flower/pull/1304), [#1305]" -"(https://github.com/adap/flower/pull/1305), [#1307](https://github.com/adap/" -"flower/pull/1307))" +"**Update documentation** " +"([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" msgstr "" -#: ../../source/ref-changelog.md:711 +#: ../../source/ref-changelog.md:803 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the `flwr." -"common` module in the API reference, includes support for markdown-based " -"documentation, migrates the changelog from `.rst` to `.md`, and fixes a " -"number of smaller details!" +"deprecated library, updates documentation dependencies, includes the " +"`flwr.common` module in the API reference, includes support for markdown-" +"based documentation, migrates the changelog from `.rst` to `.md`, and " +"fixes a number of smaller details!" msgstr "" -#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 -#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +#: ../../source/ref-changelog.md:805 ../../source/ref-changelog.md:860 +#: ../../source/ref-changelog.md:929 ../../source/ref-changelog.md:968 msgid "**Minor updates**" msgstr "" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:807 msgid "" -"Add round number to fit and evaluate log messages ([#1266](https://github." -"com/adap/flower/pull/1266))" +"Add round number to fit and evaluate log messages " +"([#1266](https://github.com/adap/flower/pull/1266))" msgstr "" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:808 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example ([#847]" -"(https://github.com/adap/flower/pull/847))" +"Add secure gRPC connection to the `advanced_tensorflow` code example " +"([#847](https://github.com/adap/flower/pull/847))" msgstr "" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:809 msgid "" -"Update developer tooling ([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), [#1301](https://github." -"com/adap/flower/pull/1301), [#1310](https://github.com/adap/flower/" -"pull/1310))" +"Update developer tooling " +"([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), " +"[#1301](https://github.com/adap/flower/pull/1301), " +"[#1310](https://github.com/adap/flower/pull/1310))" msgstr "" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:810 msgid "" -"Rename ProtoBuf messages to improve consistency ([#1214](https://github.com/" -"adap/flower/pull/1214), [#1258](https://github.com/adap/flower/pull/1258), " +"Rename ProtoBuf messages to improve consistency " +"([#1214](https://github.com/adap/flower/pull/1214), " +"[#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:720 +#: ../../source/ref-changelog.md:812 msgid "v0.19.0 (2022-05-18)" msgstr "" -#: ../../source/ref-changelog.md:724 +#: ../../source/ref-changelog.md:816 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** ([#919](https://" -"github.com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" -"pull/1127), [#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " +"([#919](https://github.com/adap/flower/pull/919), " +"[#1127](https://github.com/adap/flower/pull/1127), " +"[#914](https://github.com/adap/flower/pull/914))" msgstr "" -#: ../../source/ref-changelog.md:726 +#: ../../source/ref-changelog.md:818 msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how to " -"use [Flower Baselines](https://flower.ai/docs/using-baselines.html). With " -"this first preview release we're also inviting the community to [contribute " -"their own baselines](https://flower.ai/docs/baselines/how-to-contribute-" -"baselines.html)." +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " +"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " +"With this first preview release we're also inviting the community to " +"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" +"contribute-baselines.html)." msgstr "" -#: ../../source/ref-changelog.md:728 +#: ../../source/ref-changelog.md:820 msgid "" -"**C++ client SDK (preview) and code example** ([#1111](https://github.com/" -"adap/flower/pull/1111))" +"**C++ client SDK (preview) and code example** " +"([#1111](https://github.com/adap/flower/pull/1111))" msgstr "" -#: ../../source/ref-changelog.md:730 +#: ../../source/ref-changelog.md:822 msgid "" -"Preview support for Flower clients written in C++. The C++ preview includes " -"a Flower client SDK and a quickstart code example that demonstrates a simple " -"C++ client using the SDK." +"Preview support for Flower clients written in C++. The C++ preview " +"includes a Flower client SDK and a quickstart code example that " +"demonstrates a simple C++ client using the SDK." msgstr "" -#: ../../source/ref-changelog.md:732 +#: ../../source/ref-changelog.md:824 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** ([#1135]" -"(https://github.com/adap/flower/pull/1135))" +"**Add experimental support for Python 3.10 and Python 3.11** " +"([#1135](https://github.com/adap/flower/pull/1135))" msgstr "" -#: ../../source/ref-changelog.md:734 +#: ../../source/ref-changelog.md:826 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due to " -"be released in October. This Flower release adds experimental support for " -"both Python versions." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due" +" to be released in October. This Flower release adds experimental support" +" for both Python versions." msgstr "" -#: ../../source/ref-changelog.md:736 +#: ../../source/ref-changelog.md:828 msgid "" -"**Aggregate custom metrics through user-provided functions** ([#1144]" -"(https://github.com/adap/flower/pull/1144))" +"**Aggregate custom metrics through user-provided functions** " +"([#1144](https://github.com/adap/flower/pull/1144))" msgstr "" -#: ../../source/ref-changelog.md:738 +#: ../../source/ref-changelog.md:830 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to " -"customize the strategy. Built-in strategies support two new arguments, " +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" +" customize the strategy. Built-in strategies support two new arguments, " "`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " "allow passing custom metric aggregation functions." msgstr "" -#: ../../source/ref-changelog.md:740 +#: ../../source/ref-changelog.md:832 msgid "" -"**User-configurable round timeout** ([#1162](https://github.com/adap/flower/" -"pull/1162))" +"**User-configurable round timeout** " +"([#1162](https://github.com/adap/flower/pull/1162))" msgstr "" -#: ../../source/ref-changelog.md:742 +#: ../../source/ref-changelog.md:834 msgid "" "A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary contains a " -"`round_timeout` key (with a `float` value in seconds), the server will wait " -"*at least* `round_timeout` seconds before it closes the connection." +"`start_server` and `start_simulation`. If the `config` dictionary " +"contains a `round_timeout` key (with a `float` value in seconds), the " +"server will wait *at least* `round_timeout` seconds before it closes the " +"connection." msgstr "" -#: ../../source/ref-changelog.md:744 +#: ../../source/ref-changelog.md:836 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used at " -"the same time in all built-in strategies** ([#1091](https://github.com/adap/" -"flower/pull/1091))" +"**Enable both federated evaluation and centralized evaluation to be used " +"at the same time in all built-in strategies** " +"([#1091](https://github.com/adap/flower/pull/1091))" msgstr "" -#: ../../source/ref-changelog.md:746 +#: ../../source/ref-changelog.md:838 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., client-" -"side) and centralized evaluation (i.e., server-side) in the same round. " -"Federated evaluation can be disabled by setting `fraction_eval` to `0.0`." +"Built-in strategies can now perform both federated evaluation (i.e., " +"client-side) and centralized evaluation (i.e., server-side) in the same " +"round. Federated evaluation can be disabled by setting `fraction_eval` to" +" `0.0`." msgstr "" -#: ../../source/ref-changelog.md:748 +#: ../../source/ref-changelog.md:840 msgid "" -"**Two new Jupyter Notebook tutorials** ([#1141](https://github.com/adap/" -"flower/pull/1141))" +"**Two new Jupyter Notebook tutorials** " +"([#1141](https://github.com/adap/flower/pull/1141))" msgstr "" -#: ../../source/ref-changelog.md:750 +#: ../../source/ref-changelog.md:842 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain basic " -"and intermediate Flower features:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " +"basic and intermediate Flower features:" msgstr "" -#: ../../source/ref-changelog.md:752 +#: ../../source/ref-changelog.md:844 msgid "" -"*An Introduction to Federated Learning*: [Open in Colab](https://colab." -"research.google.com/github/adap/flower/blob/main/tutorials/Flower-1-Intro-to-" -"FL-PyTorch.ipynb)" +"*An Introduction to Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" +"-Intro-to-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:754 +#: ../../source/ref-changelog.md:846 msgid "" -"*Using Strategies in Federated Learning*: [Open in Colab](https://colab." -"research.google.com/github/adap/flower/blob/main/tutorials/Flower-2-" -"Strategies-in-FL-PyTorch.ipynb)" +"*Using Strategies in Federated Learning*: [Open in " +"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" +"-Strategies-in-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:756 +#: ../../source/ref-changelog.md:848 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** ([#1076]" -"(https://github.com/adap/flower/pull/1076))" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " +"([#1076](https://github.com/adap/flower/pull/1076))" msgstr "" -#: ../../source/ref-changelog.md:758 +#: ../../source/ref-changelog.md:850 msgid "" "The new `FedAvgM` strategy implements Federated Averaging with Server " "Momentum \\[Hsu et al., 2019\\]." msgstr "" -#: ../../source/ref-changelog.md:760 +#: ../../source/ref-changelog.md:852 msgid "" -"**New advanced PyTorch code example** ([#1007](https://github.com/adap/" -"flower/pull/1007))" +"**New advanced PyTorch code example** " +"([#1007](https://github.com/adap/flower/pull/1007))" msgstr "" -#: ../../source/ref-changelog.md:762 +#: ../../source/ref-changelog.md:854 msgid "" "A new code example (`advanced_pytorch`) demonstrates advanced Flower " "concepts with PyTorch." msgstr "" -#: ../../source/ref-changelog.md:764 +#: ../../source/ref-changelog.md:856 msgid "" -"**New JAX code example** ([#906](https://github.com/adap/flower/pull/906), " +"**New JAX code example** " +"([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" -#: ../../source/ref-changelog.md:766 +#: ../../source/ref-changelog.md:858 msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." msgstr "" -#: ../../source/ref-changelog.md:770 +#: ../../source/ref-changelog.md:862 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -#: ../../source/ref-changelog.md:771 +#: ../../source/ref-changelog.md:863 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -#: ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:864 msgid "" -"New documentation for [implementing strategies](https://flower.ai/docs/" -"framework/how-to-implement-strategies.html) ([#1097](https://github.com/adap/" -"flower/pull/1097), [#1175](https://github.com/adap/flower/pull/1175))" +"New documentation for [implementing " +"strategies](https://flower.ai/docs/framework/how-to-implement-" +"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " +"[#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:865 msgid "" -"New mobile-friendly documentation theme ([#1174](https://github.com/adap/" -"flower/pull/1174))" +"New mobile-friendly documentation theme " +"([#1174](https://github.com/adap/flower/pull/1174))" msgstr "" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:866 msgid "" "Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) ([#1205](https://github.com/adap/" -"flower/pull/1205))" +"compatible releases (`>=1.9.2,<1.12.0`) " +"([#1205](https://github.com/adap/flower/pull/1205))" msgstr "" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:870 msgid "" -"**Remove deprecated support for Python 3.6** ([#871](https://github.com/adap/" -"flower/pull/871))" +"**Remove deprecated support for Python 3.6** " +"([#871](https://github.com/adap/flower/pull/871))" msgstr "" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:871 msgid "" -"**Remove deprecated KerasClient** ([#857](https://github.com/adap/flower/" -"pull/857))" +"**Remove deprecated KerasClient** " +"([#857](https://github.com/adap/flower/pull/857))" msgstr "" -#: ../../source/ref-changelog.md:780 +#: ../../source/ref-changelog.md:872 msgid "" -"**Remove deprecated no-op extra installs** ([#973](https://github.com/adap/" -"flower/pull/973))" +"**Remove deprecated no-op extra installs** " +"([#973](https://github.com/adap/flower/pull/973))" msgstr "" -#: ../../source/ref-changelog.md:781 +#: ../../source/ref-changelog.md:873 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/ref-changelog.md:782 +#: ../../source/ref-changelog.md:874 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** ([#1107]" -"(https://github.com/adap/flower/pull/1107))" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " +"([#1107](https://github.com/adap/flower/pull/1107))" msgstr "" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:875 msgid "" -"**Remove deprecated DefaultStrategy strategy** ([#1142](https://github.com/" -"adap/flower/pull/1142))" +"**Remove deprecated DefaultStrategy strategy** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:784 +#: ../../source/ref-changelog.md:876 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** ([#1142]" -"(https://github.com/adap/flower/pull/1142))" +"**Remove deprecated support for eval_fn accuracy return value** " +"([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:877 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:787 +#: ../../source/ref-changelog.md:879 msgid "v0.18.0 (2022-02-28)" msgstr "" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:883 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), [#872]" -"(https://github.com/adap/flower/pull/872), [#833](https://github.com/adap/" -"flower/pull/833), [#1036](https://github.com/adap/flower/pull/1036))" +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " +"[#872](https://github.com/adap/flower/pull/872), " +"[#833](https://github.com/adap/flower/pull/833), " +"[#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:885 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) now " -"work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"Simulations (using the Virtual Client Engine through `start_simulation`) " +"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " "installing Flower with the `simulation` extra (`pip install " "flwr[simulation]`)." msgstr "" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:887 msgid "" -"**New Jupyter Notebook code example** ([#833](https://github.com/adap/flower/" -"pull/833))" +"**New Jupyter Notebook code example** " +"([#833](https://github.com/adap/flower/pull/833))" msgstr "" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:889 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower simulations " -"using the Virtual Client Engine through Jupyter Notebook (incl. Google " -"Colab)." +"A new code example (`quickstart_simulation`) demonstrates Flower " +"simulations using the Virtual Client Engine through Jupyter Notebook " +"(incl. Google Colab)." msgstr "" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:891 msgid "" -"**Client properties (feature preview)** ([#795](https://github.com/adap/" -"flower/pull/795))" +"**Client properties (feature preview)** " +"([#795](https://github.com/adap/flower/pull/795))" msgstr "" -#: ../../source/ref-changelog.md:801 +#: ../../source/ref-changelog.md:893 msgid "" -"Clients can implement a new method `get_properties` to enable server-side " -"strategies to query client properties." +"Clients can implement a new method `get_properties` to enable server-side" +" strategies to query client properties." msgstr "" -#: ../../source/ref-changelog.md:803 +#: ../../source/ref-changelog.md:895 msgid "" -"**Experimental Android support with TFLite** ([#865](https://github.com/adap/" -"flower/pull/865))" +"**Experimental Android support with TFLite** " +"([#865](https://github.com/adap/flower/pull/865))" msgstr "" -#: ../../source/ref-changelog.md:805 +#: ../../source/ref-changelog.md:897 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has become a " -"lot easier." +"client platforms and with this release, using Flower on Android has " +"become a lot easier." msgstr "" -#: ../../source/ref-changelog.md:807 +#: ../../source/ref-changelog.md:899 msgid "" -"The example uses TFLite on the client side, along with a new `FedAvgAndroid` " -"strategy. The Android client and `FedAvgAndroid` are still experimental, but " -"they are a first step towards a fully-fledged Android SDK and a unified " -"`FedAvg` implementation that integrated the new functionality from " -"`FedAvgAndroid`." +"The example uses TFLite on the client side, along with a new " +"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " +"still experimental, but they are a first step towards a fully-fledged " +"Android SDK and a unified `FedAvg` implementation that integrated the new" +" functionality from `FedAvgAndroid`." msgstr "" -#: ../../source/ref-changelog.md:809 +#: ../../source/ref-changelog.md:901 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default keepalive " -"time** ([#1069](https://github.com/adap/flower/pull/1069))" +"**Make gRPC keepalive time user-configurable and decrease default " +"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -#: ../../source/ref-changelog.md:811 +#: ../../source/ref-changelog.md:903 msgid "" "The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, Microsoft " -"Azure). Users can configure the keepalive time to customize the gRPC stack " -"based on specific requirements." +"compatibility of Flower with more cloud environments (for example, " +"Microsoft Azure). Users can configure the keepalive time to customize the" +" gRPC stack based on specific requirements." msgstr "" -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:905 msgid "" -"**New differential privacy example using Opacus and PyTorch** ([#805]" -"(https://github.com/adap/flower/pull/805))" +"**New differential privacy example using Opacus and PyTorch** " +"([#805](https://github.com/adap/flower/pull/805))" msgstr "" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:907 msgid "" -"A new code example (`opacus`) demonstrates differentially-private federated " -"learning with Opacus, PyTorch, and Flower." +"A new code example (`opacus`) demonstrates differentially-private " +"federated learning with Opacus, PyTorch, and Flower." msgstr "" -#: ../../source/ref-changelog.md:817 +#: ../../source/ref-changelog.md:909 msgid "" -"**New Hugging Face Transformers code example** ([#863](https://github.com/" -"adap/flower/pull/863))" +"**New Hugging Face Transformers code example** " +"([#863](https://github.com/adap/flower/pull/863))" msgstr "" -#: ../../source/ref-changelog.md:819 +#: ../../source/ref-changelog.md:911 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of Hugging " -"Face Transformers with Flower." +"A new code example (`quickstart_huggingface`) demonstrates usage of " +"Hugging Face Transformers with Flower." msgstr "" -#: ../../source/ref-changelog.md:821 +#: ../../source/ref-changelog.md:913 msgid "" -"**New MLCube code example** ([#779](https://github.com/adap/flower/" -"pull/779), [#1034](https://github.com/adap/flower/pull/1034), [#1065]" -"(https://github.com/adap/flower/pull/1065), [#1090](https://github.com/adap/" -"flower/pull/1090))" +"**New MLCube code example** " +"([#779](https://github.com/adap/flower/pull/779), " +"[#1034](https://github.com/adap/flower/pull/1034), " +"[#1065](https://github.com/adap/flower/pull/1065), " +"[#1090](https://github.com/adap/flower/pull/1090))" msgstr "" -#: ../../source/ref-changelog.md:823 +#: ../../source/ref-changelog.md:915 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube with " -"Flower." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " +"with Flower." msgstr "" -#: ../../source/ref-changelog.md:825 +#: ../../source/ref-changelog.md:917 msgid "" -"**SSL-enabled server and client** ([#842](https://github.com/adap/flower/" -"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" -"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" -"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" -"github.com/adap/flower/pull/994))" +"**SSL-enabled server and client** " +"([#842](https://github.com/adap/flower/pull/842), " +"[#844](https://github.com/adap/flower/pull/844), " +"[#845](https://github.com/adap/flower/pull/845), " +"[#847](https://github.com/adap/flower/pull/847), " +"[#993](https://github.com/adap/flower/pull/993), " +"[#994](https://github.com/adap/flower/pull/994))" msgstr "" -#: ../../source/ref-changelog.md:827 +#: ../../source/ref-changelog.md:919 msgid "" -"SSL enables secure encrypted connections between clients and servers. This " -"release open-sources the Flower secure gRPC implementation to make encrypted " -"communication channels accessible to all Flower users." +"SSL enables secure encrypted connections between clients and servers. " +"This release open-sources the Flower secure gRPC implementation to make " +"encrypted communication channels accessible to all Flower users." msgstr "" -#: ../../source/ref-changelog.md:829 +#: ../../source/ref-changelog.md:921 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** ([#885](https://" -"github.com/adap/flower/pull/885), [#895](https://github.com/adap/flower/" -"pull/895))" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** " +"([#885](https://github.com/adap/flower/pull/885), " +"[#895](https://github.com/adap/flower/pull/895))" msgstr "" -#: ../../source/ref-changelog.md:831 +#: ../../source/ref-changelog.md:923 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive Federated " -"Optimization paper." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive " +"Federated Optimization paper." msgstr "" -#: ../../source/ref-changelog.md:833 +#: ../../source/ref-changelog.md:925 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** ([#860]" -"(https://github.com/adap/flower/pull/860))" +"**Initialize** `start_simulation` **with a list of client IDs** " +"([#860](https://github.com/adap/flower/pull/860))" msgstr "" -#: ../../source/ref-changelog.md:835 +#: ../../source/ref-changelog.md:927 msgid "" "`start_simulation` can now be called with a list of client IDs " "(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " @@ -16240,227 +17370,232 @@ msgid "" "identifiers." msgstr "" -#: ../../source/ref-changelog.md:839 +#: ../../source/ref-changelog.md:931 msgid "" -"Update `num_examples` calculation in PyTorch code examples in ([#909]" -"(https://github.com/adap/flower/pull/909))" +"Update `num_examples` calculation in PyTorch code examples in " +"([#909](https://github.com/adap/flower/pull/909))" msgstr "" -#: ../../source/ref-changelog.md:840 +#: ../../source/ref-changelog.md:932 msgid "" -"Expose Flower version through `flwr.__version__` ([#952](https://github.com/" -"adap/flower/pull/952))" +"Expose Flower version through `flwr.__version__` " +"([#952](https://github.com/adap/flower/pull/952))" msgstr "" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:933 msgid "" -"`start_server` in `app.py` now returns a `History` object containing metrics " -"from training ([#974](https://github.com/adap/flower/pull/974))" +"`start_server` in `app.py` now returns a `History` object containing " +"metrics from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -#: ../../source/ref-changelog.md:842 +#: ../../source/ref-changelog.md:934 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable ([#978]" -"(https://github.com/adap/flower/pull/978))" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " +"([#978](https://github.com/adap/flower/pull/978))" msgstr "" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:935 msgid "" -"Increase sleep time after server start to three seconds in all code examples " -"([#1086](https://github.com/adap/flower/pull/1086))" +"Increase sleep time after server start to three seconds in all code " +"examples ([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" -#: ../../source/ref-changelog.md:844 +#: ../../source/ref-changelog.md:936 msgid "" -"Added a new FAQ section to the documentation ([#948](https://github.com/adap/" -"flower/pull/948))" +"Added a new FAQ section to the documentation " +"([#948](https://github.com/adap/flower/pull/948))" msgstr "" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:937 msgid "" "And many more under-the-hood changes, library updates, documentation " "changes, and tooling improvements!" msgstr "" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:941 msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:943 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " "builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in an " -"upcoming release." +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " +"an upcoming release." msgstr "" -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:945 msgid "v0.17.0 (2021-09-24)" msgstr "" -#: ../../source/ref-changelog.md:857 +#: ../../source/ref-changelog.md:949 msgid "" -"**Experimental virtual client engine** ([#781](https://github.com/adap/" -"flower/pull/781) [#790](https://github.com/adap/flower/pull/790) [#791]" -"(https://github.com/adap/flower/pull/791))" +"**Experimental virtual client engine** " +"([#781](https://github.com/adap/flower/pull/781) " +"[#790](https://github.com/adap/flower/pull/790) " +"[#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:951 msgid "" -"One of Flower's goals is to enable research at scale. This release enables a " -"first (experimental) peek at a major new feature, codenamed the virtual " -"client engine. Virtual clients enable simulations that scale to a (very) " -"large number of clients on a single machine or compute cluster. The easiest " -"way to test the new functionality is to look at the two new code examples " -"called `quickstart_simulation` and `simulation_pytorch`." +"One of Flower's goals is to enable research at scale. This release " +"enables a first (experimental) peek at a major new feature, codenamed the" +" virtual client engine. Virtual clients enable simulations that scale to " +"a (very) large number of clients on a single machine or compute cluster. " +"The easiest way to test the new functionality is to look at the two new " +"code examples called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -#: ../../source/ref-changelog.md:861 +#: ../../source/ref-changelog.md:953 msgid "" -"The feature is still experimental, so there's no stability guarantee for the " -"API. It's also not quite ready for prime time and comes with a few known " -"caveats. However, those who are curious are encouraged to try it out and " -"share their thoughts." +"The feature is still experimental, so there's no stability guarantee for " +"the API. It's also not quite ready for prime time and comes with a few " +"known caveats. However, those who are curious are encouraged to try it " +"out and share their thoughts." msgstr "" -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:955 msgid "" -"**New built-in strategies** ([#828](https://github.com/adap/flower/pull/828) " +"**New built-in strategies** " +"([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:957 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/ref-changelog.md:866 +#: ../../source/ref-changelog.md:958 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/ref-changelog.md:868 +#: ../../source/ref-changelog.md:960 msgid "" -"**New PyTorch Lightning code example** ([#617](https://github.com/adap/" -"flower/pull/617))" +"**New PyTorch Lightning code example** " +"([#617](https://github.com/adap/flower/pull/617))" msgstr "" -#: ../../source/ref-changelog.md:870 +#: ../../source/ref-changelog.md:962 msgid "" -"**New Variational Auto-Encoder code example** ([#752](https://github.com/" -"adap/flower/pull/752))" +"**New Variational Auto-Encoder code example** " +"([#752](https://github.com/adap/flower/pull/752))" msgstr "" -#: ../../source/ref-changelog.md:872 +#: ../../source/ref-changelog.md:964 msgid "" -"**New scikit-learn code example** ([#748](https://github.com/adap/flower/" -"pull/748))" +"**New scikit-learn code example** " +"([#748](https://github.com/adap/flower/pull/748))" msgstr "" -#: ../../source/ref-changelog.md:874 +#: ../../source/ref-changelog.md:966 msgid "" -"**New experimental TensorBoard strategy** ([#789](https://github.com/adap/" -"flower/pull/789))" +"**New experimental TensorBoard strategy** " +"([#789](https://github.com/adap/flower/pull/789))" msgstr "" -#: ../../source/ref-changelog.md:878 +#: ../../source/ref-changelog.md:970 msgid "" -"Improved advanced TensorFlow code example ([#769](https://github.com/adap/" -"flower/pull/769))" +"Improved advanced TensorFlow code example " +"([#769](https://github.com/adap/flower/pull/769))" msgstr "" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:971 msgid "" -"Warning when `min_available_clients` is misconfigured ([#830](https://github." -"com/adap/flower/pull/830))" +"Warning when `min_available_clients` is misconfigured " +"([#830](https://github.com/adap/flower/pull/830))" msgstr "" -#: ../../source/ref-changelog.md:880 +#: ../../source/ref-changelog.md:972 msgid "" -"Improved gRPC server docs ([#841](https://github.com/adap/flower/pull/841))" +"Improved gRPC server docs " +"([#841](https://github.com/adap/flower/pull/841))" msgstr "" -#: ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:973 msgid "" -"Improved error message in `NumPyClient` ([#851](https://github.com/adap/" -"flower/pull/851))" +"Improved error message in `NumPyClient` " +"([#851](https://github.com/adap/flower/pull/851))" msgstr "" -#: ../../source/ref-changelog.md:882 +#: ../../source/ref-changelog.md:974 msgid "" -"Improved PyTorch quickstart code example ([#852](https://github.com/adap/" -"flower/pull/852))" +"Improved PyTorch quickstart code example " +"([#852](https://github.com/adap/flower/pull/852))" msgstr "" -#: ../../source/ref-changelog.md:886 +#: ../../source/ref-changelog.md:978 msgid "" -"**Disabled final distributed evaluation** ([#800](https://github.com/adap/" -"flower/pull/800))" +"**Disabled final distributed evaluation** " +"([#800](https://github.com/adap/flower/pull/800))" msgstr "" -#: ../../source/ref-changelog.md:888 +#: ../../source/ref-changelog.md:980 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on " -"all connected clients, which is often not required (e.g., when using server-" -"side evaluation). The prior behaviour can be enabled by passing " +"Prior behaviour was to perform a final round of distributed evaluation on" +" all connected clients, which is often not required (e.g., when using " +"server-side evaluation). The prior behaviour can be enabled by passing " "`force_final_distributed_eval=True` to `start_server`." msgstr "" -#: ../../source/ref-changelog.md:890 +#: ../../source/ref-changelog.md:982 msgid "" -"**Renamed q-FedAvg strategy** ([#802](https://github.com/adap/flower/" -"pull/802))" +"**Renamed q-FedAvg strategy** " +"([#802](https://github.com/adap/flower/pull/802))" msgstr "" -#: ../../source/ref-changelog.md:892 +#: ../../source/ref-changelog.md:984 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect the " -"notation given in the original paper (q-FFL is the optimization objective, q-" -"FedAvg is the proposed solver). Note the original (now deprecated) " -"`QffedAvg` class is still available for compatibility reasons (it will be " -"removed in a future release)." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " +"the notation given in the original paper (q-FFL is the optimization " +"objective, q-FedAvg is the proposed solver). Note the original (now " +"deprecated) `QffedAvg` class is still available for compatibility reasons" +" (it will be removed in a future release)." msgstr "" -#: ../../source/ref-changelog.md:894 +#: ../../source/ref-changelog.md:986 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/pull/791))" +"`simulation_pytorch_legacy` " +"([#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/ref-changelog.md:896 +#: ../../source/ref-changelog.md:988 msgid "" -"This example has been replaced by a new example. The new example is based on " -"the experimental virtual client engine, which will become the new default " -"way of doing most types of large-scale simulations in Flower. The existing " -"example was kept for reference purposes, but it might be removed in the " -"future." +"This example has been replaced by a new example. The new example is based" +" on the experimental virtual client engine, which will become the new " +"default way of doing most types of large-scale simulations in Flower. The" +" existing example was kept for reference purposes, but it might be " +"removed in the future." msgstr "" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:990 msgid "v0.16.0 (2021-05-11)" msgstr "" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:994 msgid "" -"**New built-in strategies** ([#549](https://github.com/adap/flower/pull/549))" +"**New built-in strategies** " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:904 +#: ../../source/ref-changelog.md:996 msgid "(abstract) FedOpt" msgstr "" -#: ../../source/ref-changelog.md:907 +#: ../../source/ref-changelog.md:999 msgid "" -"**Custom metrics for server and strategies** ([#717](https://github.com/adap/" -"flower/pull/717))" +"**Custom metrics for server and strategies** " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/ref-changelog.md:909 +#: ../../source/ref-changelog.md:1001 msgid "" "The Flower server is now fully task-agnostic, all remaining instances of " "task-specific metrics (such as `accuracy`) have been replaced by custom " @@ -16469,119 +17604,125 @@ msgid "" "release, custom metrics replace task-specific metrics on the server." msgstr "" -#: ../../source/ref-changelog.md:911 +#: ../../source/ref-changelog.md:1003 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are " -"returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and they " -"enable evaluation functions passed to built-in strategies (via `eval_fn`) to " -"return more than two evaluation metrics. Strategies can even return " -"*aggregated* metrics dictionaries for the server to keep track of." +"Custom metric dictionaries are now used in two user-facing APIs: they are" +" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " +"they enable evaluation functions passed to built-in strategies (via " +"`eval_fn`) to return more than two evaluation metrics. Strategies can " +"even return *aggregated* metrics dictionaries for the server to keep " +"track of." msgstr "" -#: ../../source/ref-changelog.md:913 +#: ../../source/ref-changelog.md:1005 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate " -"from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"returning an empty `{}`), server-side evaluation functions should migrate" +" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -#: ../../source/ref-changelog.md:915 +#: ../../source/ref-changelog.md:1007 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:917 +#: ../../source/ref-changelog.md:1009 msgid "" -"**Migration warnings for deprecated functionality** ([#690](https://github." -"com/adap/flower/pull/690))" +"**Migration warnings for deprecated functionality** " +"([#690](https://github.com/adap/flower/pull/690))" msgstr "" -#: ../../source/ref-changelog.md:919 +#: ../../source/ref-changelog.md:1011 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces detailed " -"warning messages if usage of deprecated APIs is detected. The new warning " -"messages often provide details on how to migrate to more recent APIs, thus " -"easing the transition from one release to another." +"maintaining compatibility with legacy APIs. This release introduces " +"detailed warning messages if usage of deprecated APIs is detected. The " +"new warning messages often provide details on how to migrate to more " +"recent APIs, thus easing the transition from one release to another." msgstr "" -#: ../../source/ref-changelog.md:921 +#: ../../source/ref-changelog.md:1013 msgid "" -"Improved docs and docstrings ([#691](https://github.com/adap/flower/" -"pull/691) [#692](https://github.com/adap/flower/pull/692) [#713](https://" -"github.com/adap/flower/pull/713))" +"Improved docs and docstrings " +"([#691](https://github.com/adap/flower/pull/691) " +"[#692](https://github.com/adap/flower/pull/692) " +"[#713](https://github.com/adap/flower/pull/713))" msgstr "" -#: ../../source/ref-changelog.md:923 +#: ../../source/ref-changelog.md:1015 msgid "MXNet example and documentation" msgstr "" -#: ../../source/ref-changelog.md:925 +#: ../../source/ref-changelog.md:1017 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) [#702](https://github.com/" -"adap/flower/pull/702) [#705](https://github.com/adap/flower/pull/705))" +"([#696](https://github.com/adap/flower/pull/696) " +"[#702](https://github.com/adap/flower/pull/702) " +"[#705](https://github.com/adap/flower/pull/705))" msgstr "" -#: ../../source/ref-changelog.md:929 +#: ../../source/ref-changelog.md:1021 msgid "" -"**Serialization-agnostic server** ([#721](https://github.com/adap/flower/" -"pull/721))" +"**Serialization-agnostic server** " +"([#721](https://github.com/adap/flower/pull/721))" msgstr "" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:1023 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of class " -"`Weights` (which represents parameters as deserialized NumPy ndarrays) was " -"replaced by class `Parameters` (e.g., in `Strategy`). `Parameters` objects " -"are fully serialization-agnostic and represents parameters as byte arrays, " -"the `tensor_type` attributes indicates how these byte arrays should be " -"interpreted (e.g., for serialization/deserialization)." +"The Flower server is now fully serialization-agnostic. Prior usage of " +"class `Weights` (which represents parameters as deserialized NumPy " +"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " +"`Parameters` objects are fully serialization-agnostic and represents " +"parameters as byte arrays, the `tensor_type` attributes indicates how " +"these byte arrays should be interpreted (e.g., for " +"serialization/deserialization)." msgstr "" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:1025 msgid "" -"Built-in strategies implement this approach by handling serialization and " -"deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"Built-in strategies implement this approach by handling serialization and" +" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " "implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR [#721](https://github.com/adap/" -"flower/pull/721) to see how strategies can easily migrate to the new format." +"definitions. Strategy authors can consult PR " +"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" +" easily migrate to the new format." msgstr "" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:1027 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use `flwr.server.Server." -"evaluate_round` instead ([#717](https://github.com/adap/flower/pull/717))" +"Deprecated `flwr.server.Server.evaluate`, use " +"`flwr.server.Server.evaluate_round` instead " +"([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:1029 msgid "v0.15.0 (2021-03-12)" msgstr "" -#: ../../source/ref-changelog.md:941 +#: ../../source/ref-changelog.md:1033 msgid "" -"**Server-side parameter initialization** ([#658](https://github.com/adap/" -"flower/pull/658))" +"**Server-side parameter initialization** " +"([#658](https://github.com/adap/flower/pull/658))" msgstr "" -#: ../../source/ref-changelog.md:943 +#: ../../source/ref-changelog.md:1035 msgid "" "Model parameters can now be initialized on the server-side. Server-side " "parameter initialization works via a new `Strategy` method called " "`initialize_parameters`." msgstr "" -#: ../../source/ref-changelog.md:945 +#: ../../source/ref-changelog.md:1037 msgid "" "Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies will " -"provide these initial parameters to the server on startup and then delete " -"them to free the memory afterwards." +"`initial_parameters` to set the initial parameters. Built-in strategies " +"will provide these initial parameters to the server on startup and then " +"delete them to free the memory afterwards." msgstr "" -#: ../../source/ref-changelog.md:964 +#: ../../source/ref-changelog.md:1056 msgid "" "If no initial parameters are provided to the strategy, the server will " "continue to use the current behaviour (namely, it will ask one of the " @@ -16589,220 +17730,221 @@ msgid "" "parameters)." msgstr "" -#: ../../source/ref-changelog.md:966 -msgid "Deprecations" -msgstr "" - -#: ../../source/ref-changelog.md:968 +#: ../../source/ref-changelog.md:1060 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to `flwr.server." -"strategy.FedAvg`, which is equivalent)" +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " +"`flwr.server.strategy.FedAvg`, which is equivalent)" msgstr "" -#: ../../source/ref-changelog.md:970 +#: ../../source/ref-changelog.md:1062 msgid "v0.14.0 (2021-02-18)" msgstr "" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:1066 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) [#572](https://github.com/" -"adap/flower/pull/572) [#633](https://github.com/adap/flower/pull/633))" +"([#610](https://github.com/adap/flower/pull/610) " +"[#572](https://github.com/adap/flower/pull/572) " +"[#633](https://github.com/adap/flower/pull/633))" msgstr "" -#: ../../source/ref-changelog.md:976 +#: ../../source/ref-changelog.md:1068 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to values " -"of the following types: `bool`, `bytes`, `float`, `int`, `str`. This means " -"one can return almost arbitrary values from `fit`/`evaluate` and make use of " -"them on the server side!" +"Clients can now return an additional dictionary mapping `str` keys to " +"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " +"This means one can return almost arbitrary values from `fit`/`evaluate` " +"and make use of them on the server side!" msgstr "" -#: ../../source/ref-changelog.md:978 +#: ../../source/ref-changelog.md:1070 msgid "" -"This improvement also allowed for more consistent return types between `fit` " -"and `evaluate`: `evaluate` should now return a tuple `(float, int, dict)` " -"representing the loss, number of examples, and a dictionary holding " -"arbitrary problem-specific values like accuracy." +"This improvement also allowed for more consistent return types between " +"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " +"dict)` representing the loss, number of examples, and a dictionary " +"holding arbitrary problem-specific values like accuracy." msgstr "" -#: ../../source/ref-changelog.md:980 +#: ../../source/ref-changelog.md:1072 msgid "" -"In case you wondered: this feature is compatible with existing projects, the " -"additional dictionary return value is optional. New code should however " -"migrate to the new return types to be compatible with upcoming Flower " -"releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, `evaluate`: " -"`float, int, Dict[str, Scalar]`). See the example below for details." +"In case you wondered: this feature is compatible with existing projects, " +"the additional dictionary return value is optional. New code should " +"however migrate to the new return types to be compatible with upcoming " +"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " +"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " +"details." msgstr "" -#: ../../source/ref-changelog.md:982 +#: ../../source/ref-changelog.md:1074 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" msgstr "" -#: ../../source/ref-changelog.md:997 +#: ../../source/ref-changelog.md:1089 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** `Client." -"evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Generalized** `config` **argument in** `Client.fit` **and** " +"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -#: ../../source/ref-changelog.md:999 +#: ../../source/ref-changelog.md:1091 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means that " -"dictionary values were expected to be strings. The new release generalizes " -"this to enable values of the following types: `bool`, `bytes`, `float`, " -"`int`, `str`." +"The `config` argument used to be of type `Dict[str, str]`, which means " +"that dictionary values were expected to be strings. The new release " +"generalizes this to enable values of the following types: `bool`, " +"`bytes`, `float`, `int`, `str`." msgstr "" -#: ../../source/ref-changelog.md:1001 +#: ../../source/ref-changelog.md:1093 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-side " -"and `int(config[\"epochs\"])` on the client side!" +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" +"side and `int(config[\"epochs\"])` on the client side!" msgstr "" -#: ../../source/ref-changelog.md:1003 +#: ../../source/ref-changelog.md:1095 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" msgstr "" -#: ../../source/ref-changelog.md:1020 +#: ../../source/ref-changelog.md:1112 msgid "v0.13.0 (2021-01-08)" msgstr "" -#: ../../source/ref-changelog.md:1024 +#: ../../source/ref-changelog.md:1116 msgid "" -"New example: PyTorch From Centralized To Federated ([#549](https://github." -"com/adap/flower/pull/549))" +"New example: PyTorch From Centralized To Federated " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:1025 +#: ../../source/ref-changelog.md:1117 msgid "Improved documentation" msgstr "" -#: ../../source/ref-changelog.md:1026 -msgid "" -"New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +#: ../../source/ref-changelog.md:1118 +msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" -#: ../../source/ref-changelog.md:1027 +#: ../../source/ref-changelog.md:1119 msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "" -#: ../../source/ref-changelog.md:1028 +#: ../../source/ref-changelog.md:1120 msgid "" -"Updated examples documentation ([#549](https://github.com/adap/flower/" -"pull/549))" +"Updated examples documentation " +"([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:1029 +#: ../../source/ref-changelog.md:1121 msgid "" -"Removed obsolete documentation ([#548](https://github.com/adap/flower/" -"pull/548))" +"Removed obsolete documentation " +"([#548](https://github.com/adap/flower/pull/548))" msgstr "" -#: ../../source/ref-changelog.md:1031 +#: ../../source/ref-changelog.md:1123 msgid "Bugfix:" msgstr "" -#: ../../source/ref-changelog.md:1033 +#: ../../source/ref-changelog.md:1125 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the " -"clients is now handled in `flwr.server.start_server` ([#553](https://github." -"com/adap/flower/pull/553) [#540](https://github.com/adap/flower/issues/540))." +"`Server.fit` does not disconnect clients when finished, disconnecting the" +" clients is now handled in `flwr.server.start_server` " +"([#553](https://github.com/adap/flower/pull/553) " +"[#540](https://github.com/adap/flower/issues/540))." msgstr "" -#: ../../source/ref-changelog.md:1035 +#: ../../source/ref-changelog.md:1127 msgid "v0.12.0 (2020-12-07)" msgstr "" -#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +#: ../../source/ref-changelog.md:1129 ../../source/ref-changelog.md:1145 msgid "Important changes:" msgstr "" -#: ../../source/ref-changelog.md:1039 +#: ../../source/ref-changelog.md:1131 msgid "" -"Added an example for embedded devices ([#507](https://github.com/adap/flower/" -"pull/507))" +"Added an example for embedded devices " +"([#507](https://github.com/adap/flower/pull/507))" msgstr "" -#: ../../source/ref-changelog.md:1040 +#: ../../source/ref-changelog.md:1132 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) ([#504]" -"(https://github.com/adap/flower/pull/504) [#508](https://github.com/adap/" -"flower/pull/508))" +"Added a new NumPyClient (in addition to the existing KerasClient) " +"([#504](https://github.com/adap/flower/pull/504) " +"[#508](https://github.com/adap/flower/pull/508))" msgstr "" -#: ../../source/ref-changelog.md:1041 +#: ../../source/ref-changelog.md:1133 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into the " -"top-level `examples` directory ([#494](https://github.com/adap/flower/" -"pull/494) [#512](https://github.com/adap/flower/pull/512))" +"Deprecated `flwr_example` package and started to migrate examples into " +"the top-level `examples` directory " +"([#494](https://github.com/adap/flower/pull/494) " +"[#512](https://github.com/adap/flower/pull/512))" msgstr "" -#: ../../source/ref-changelog.md:1043 +#: ../../source/ref-changelog.md:1135 msgid "v0.11.0 (2020-11-30)" msgstr "" -#: ../../source/ref-changelog.md:1045 +#: ../../source/ref-changelog.md:1137 msgid "Incompatible changes:" msgstr "" -#: ../../source/ref-changelog.md:1047 +#: ../../source/ref-changelog.md:1139 msgid "" -"Renamed strategy methods ([#486](https://github.com/adap/flower/pull/486)) " -"to unify the naming of Flower's public APIs. Other public methods/functions " -"(e.g., every method in `Client`, but also `Strategy.evaluate`) do not use " -"the `on_` prefix, which is why we're removing it from the four methods in " -"Strategy. To migrate rename the following `Strategy` methods accordingly:" +"Renamed strategy methods " +"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " +"Flower's public APIs. Other public methods/functions (e.g., every method " +"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " +"which is why we're removing it from the four methods in Strategy. To " +"migrate rename the following `Strategy` methods accordingly:" msgstr "" -#: ../../source/ref-changelog.md:1048 +#: ../../source/ref-changelog.md:1140 msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:1049 +#: ../../source/ref-changelog.md:1141 msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:1050 +#: ../../source/ref-changelog.md:1142 msgid "`on_configure_fit` => `configure_fit`" msgstr "" -#: ../../source/ref-changelog.md:1051 +#: ../../source/ref-changelog.md:1143 msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "" -#: ../../source/ref-changelog.md:1055 +#: ../../source/ref-changelog.md:1147 msgid "" -"Deprecated `DefaultStrategy` ([#479](https://github.com/adap/flower/" -"pull/479)). To migrate use `FedAvg` instead." +"Deprecated `DefaultStrategy` " +"([#479](https://github.com/adap/flower/pull/479)). To migrate use " +"`FedAvg` instead." msgstr "" -#: ../../source/ref-changelog.md:1056 +#: ../../source/ref-changelog.md:1148 msgid "" -"Simplified examples and baselines ([#484](https://github.com/adap/flower/" -"pull/484))." +"Simplified examples and baselines " +"([#484](https://github.com/adap/flower/pull/484))." msgstr "" -#: ../../source/ref-changelog.md:1057 +#: ../../source/ref-changelog.md:1149 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface ([#483]" -"(https://github.com/adap/flower/pull/483))." +"Removed presently unused `on_conclude_round` from strategy interface " +"([#483](https://github.com/adap/flower/pull/483))." msgstr "" -#: ../../source/ref-changelog.md:1058 +#: ../../source/ref-changelog.md:1150 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 ([#471](https://github." -"com/adap/flower/pull/471))." +"Set minimal Python version to 3.6.1 instead of 3.6.9 " +"([#471](https://github.com/adap/flower/pull/471))." msgstr "" -#: ../../source/ref-changelog.md:1059 +#: ../../source/ref-changelog.md:1151 msgid "" -"Improved `Strategy` docstrings ([#470](https://github.com/adap/flower/" -"pull/470))." +"Improved `Strategy` docstrings " +"([#470](https://github.com/adap/flower/pull/470))." msgstr "" #: ../../source/ref-example-projects.rst:2 @@ -16811,11 +17953,11 @@ msgstr "" #: ../../source/ref-example-projects.rst:4 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate how " -"Flower can be used to federate different kinds of existing machine learning " -"pipelines, usually leveraging popular machine learning frameworks such as " -"`PyTorch `_ or `TensorFlow `_." +"Flower comes with a number of usage examples. The examples demonstrate " +"how Flower can be used to federate different kinds of existing machine " +"learning pipelines, usually leveraging popular machine learning " +"frameworks such as `PyTorch `_ or `TensorFlow " +"`_." msgstr "" #: ../../source/ref-example-projects.rst:10 @@ -16826,25 +17968,25 @@ msgstr "" #: ../../source/ref-example-projects.rst:14 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image classification " -"with MobileNetV2:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image " +"classification with MobileNetV2:" msgstr "" #: ../../source/ref-example-projects.rst:17 msgid "" -"`Quickstart TensorFlow (Code) `_" +"`Quickstart TensorFlow (Code) " +"`_" msgstr "" #: ../../source/ref-example-projects.rst:18 -msgid "" -":doc:`Quickstart TensorFlow (Tutorial) `" +msgid ":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" #: ../../source/ref-example-projects.rst:19 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" #: ../../source/ref-example-projects.rst:23 @@ -16854,14 +17996,14 @@ msgstr "" #: ../../source/ref-example-projects.rst:25 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a " -"simple Convolutional Neural Network:" +"The PyTorch quickstart example shows CIFAR-10 image classification with a" +" simple Convolutional Neural Network:" msgstr "" #: ../../source/ref-example-projects.rst:28 msgid "" -"`Quickstart PyTorch (Code) `_" +"`Quickstart PyTorch (Code) " +"`_" msgstr "" #: ../../source/ref-example-projects.rst:29 @@ -16880,8 +18022,9 @@ msgstr "" #: ../../source/ref-example-projects.rst:37 msgid "" -"`PyTorch: From Centralized To Federated (Code) `_" +"`PyTorch: From Centralized To Federated (Code) " +"`_" msgstr "" #: ../../source/ref-example-projects.rst:38 @@ -16902,15 +18045,14 @@ msgstr "" #: ../../source/ref-example-projects.rst:46 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) `_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " +"`_" msgstr "" #: ../../source/ref-example-projects.rst:47 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) `_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " +"`_" msgstr "" #: ../../source/ref-faq.rst:4 @@ -16925,20 +18067,22 @@ msgstr "" #: ../../source/ref-faq.rst:8 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to " -"make it work even better on Colab. Here's a quickstart example:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to" +" make it work even better on Colab. Here's a quickstart example:" msgstr "" #: ../../source/ref-faq.rst:10 msgid "" -"`Flower simulation PyTorch `_" +"`Flower simulation PyTorch " +"`_" msgstr "" #: ../../source/ref-faq.rst:11 msgid "" -"`Flower simulation TensorFlow/Keras `_" +"`Flower simulation TensorFlow/Keras " +"`_" msgstr "" #: ../../source/ref-faq.rst @@ -16948,28 +18092,26 @@ msgstr "" #: ../../source/ref-faq.rst:15 msgid "" "Find the `blog post about federated learning on embedded device here " -"`_ " -"and the corresponding `GitHub code example `_." +"`_" +" and the corresponding `GitHub code example " +"`_." msgstr "" #: ../../source/ref-faq.rst -msgid "" -":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr "" #: ../../source/ref-faq.rst:19 msgid "" -"Yes, it does. Please take a look at our `blog post `_ or " -"check out the code examples:" +"Yes, it does. Please take a look at our `blog post " +"`_ or check out the code examples:" msgstr "" #: ../../source/ref-faq.rst:21 msgid "" -"`Android Kotlin example `_" +"`Android Kotlin example `_" msgstr "" #: ../../source/ref-faq.rst:22 @@ -16988,33 +18130,33 @@ msgstr "" #: ../../source/ref-faq.rst:28 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" #: ../../source/ref-faq.rst:29 msgid "" -"`Flower meets Nevermined YouTube video `_." +"`Flower meets Nevermined YouTube video " +"`_." msgstr "" #: ../../source/ref-faq.rst:30 msgid "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." msgstr "" #: ../../source/ref-faq.rst:31 msgid "" "`Flower meets Talan blog post `_ ." +"learning-same-mask-different-faces-imen-" +"ayari/?trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ ." msgstr "" #: ../../source/ref-faq.rst:32 msgid "" -"`Flower meets Talan GitHub Repository `_ ." +"`Flower meets Talan GitHub Repository " +"`_ ." msgstr "" #: ../../source/ref-telemetry.md:1 @@ -17023,16 +18165,17 @@ msgstr "" #: ../../source/ref-telemetry.md:3 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to make " -"well-informed decisions to improve Flower. Doing this enables the Flower " -"team to understand how Flower is used and what challenges users might face." +"The Flower open-source project collects **anonymous** usage metrics to " +"make well-informed decisions to improve Flower. Doing this enables the " +"Flower team to understand how Flower is used and what challenges users " +"might face." msgstr "" #: ../../source/ref-telemetry.md:5 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.** " -"Staying true to this statement, Flower makes it easy to disable telemetry " -"for users that do not want to share anonymous usage metrics." +"**Flower is a friendly framework for collaborative AI and data science.**" +" Staying true to this statement, Flower makes it easy to disable " +"telemetry for users that do not want to share anonymous usage metrics." msgstr "" #: ../../source/ref-telemetry.md:7 @@ -17040,34 +18183,35 @@ msgid "Principles" msgstr "" #: ../../source/ref-telemetry.md:9 -msgid "" -"We follow strong principles guarding anonymous usage metrics collection:" +msgid "We follow strong principles guarding anonymous usage metrics collection:" msgstr "" #: ../../source/ref-telemetry.md:11 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to learn " -"“[How to opt-out](#how-to-opt-out)”." +"**Optional:** You will always be able to disable telemetry; read on to " +"learn “[How to opt-out](#how-to-opt-out)”." msgstr "" #: ../../source/ref-telemetry.md:12 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not contain " -"any personally identifiable information (PII). See “[Collected metrics]" -"(#collected-metrics)” to understand what metrics are being reported." +"**Anonymous:** The reported usage metrics are anonymous and do not " +"contain any personally identifiable information (PII). See “[Collected " +"metrics](#collected-metrics)” to understand what metrics are being " +"reported." msgstr "" #: ../../source/ref-telemetry.md:13 msgid "" "**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-to-" -"inspect-what-is-being-reported)”" +"reported; see the section “[How to inspect what is being reported](#how-" +"to-inspect-what-is-being-reported)”" msgstr "" #: ../../source/ref-telemetry.md:14 msgid "" -"**Open for feedback:** You can always reach out to us if you have feedback; " -"see the section “[How to contact us](#how-to-contact-us)” for details." +"**Open for feedback:** You can always reach out to us if you have " +"feedback; see the section “[How to contact us](#how-to-contact-us)” for " +"details." msgstr "" #: ../../source/ref-telemetry.md:16 @@ -17084,9 +18228,9 @@ msgstr "" #: ../../source/ref-telemetry.md:24 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `." -"bashrc` (or whatever configuration file applies to your environment) to " -"disable Flower telemetry permanently." +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," +" `.bashrc` (or whatever configuration file applies to your environment) " +"to disable Flower telemetry permanently." msgstr "" #: ../../source/ref-telemetry.md:26 @@ -17099,10 +18243,10 @@ msgstr "" #: ../../source/ref-telemetry.md:30 msgid "" -"**Flower version.** Understand which versions of Flower are currently being " -"used. This helps us to decide whether we should invest effort into releasing " -"a patch version for an older version of Flower or instead use the bandwidth " -"to build new features." +"**Flower version.** Understand which versions of Flower are currently " +"being used. This helps us to decide whether we should invest effort into " +"releasing a patch version for an older version of Flower or instead use " +"the bandwidth to build new features." msgstr "" #: ../../source/ref-telemetry.md:32 @@ -17121,15 +18265,15 @@ msgstr "" #: ../../source/ref-telemetry.md:36 msgid "" -"**Hardware properties.** Understanding the hardware environment that Flower " -"is being used in helps to decide whether we should, for example, put more " -"effort into supporting low-resource environments." +"**Hardware properties.** Understanding the hardware environment that " +"Flower is being used in helps to decide whether we should, for example, " +"put more effort into supporting low-resource environments." msgstr "" #: ../../source/ref-telemetry.md:38 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables us " -"to understand how heavily certain features are being used and better " +"**Execution mode.** Knowing what execution mode Flower starts in enables " +"us to understand how heavily certain features are being used and better " "prioritize based on that." msgstr "" @@ -17137,34 +18281,37 @@ msgstr "" msgid "" "**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " "time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete them." +"types not only start Flower workloads but also successfully complete " +"them." msgstr "" #: ../../source/ref-telemetry.md:42 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/" -"source` the first time a telemetry event is generated. The source ID is " -"important to identify whether an issue is recurring or whether an issue is " -"triggered by multiple clusters running concurrently (which often happens in " -"simulation). For example, if a device runs multiple workloads at the same " -"time, and this results in an issue, then, in order to reproduce the issue, " -"multiple workloads must be started at the same time." +"**Source.** Flower telemetry tries to store a random source ID in " +"`~/.flwr/source` the first time a telemetry event is generated. The " +"source ID is important to identify whether an issue is recurring or " +"whether an issue is triggered by multiple clusters running concurrently " +"(which often happens in simulation). For example, if a device runs " +"multiple workloads at the same time, and this results in an issue, then, " +"in order to reproduce the issue, multiple workloads must be started at " +"the same time." msgstr "" #: ../../source/ref-telemetry.md:44 msgid "" -"You may delete the source ID at any time. If you wish for all events logged " -"under a specific source ID to be deleted, you can send a deletion request " -"mentioning the source ID to `telemetry@flower.ai`. All events related to " -"that source ID will then be permanently deleted." +"You may delete the source ID at any time. If you wish for all events " +"logged under a specific source ID to be deleted, you can send a deletion " +"request mentioning the source ID to `telemetry@flower.ai`. All events " +"related to that source ID will then be permanently deleted." msgstr "" #: ../../source/ref-telemetry.md:46 msgid "" -"We will not collect any personally identifiable information. If you think " -"any of the metrics collected could be misused in any way, please [get in " -"touch with us](#how-to-contact-us). We will update this page to reflect any " -"changes to the metrics collected and publish changes in the changelog." +"We will not collect any personally identifiable information. If you think" +" any of the metrics collected could be misused in any way, please [get in" +" touch with us](#how-to-contact-us). We will update this page to reflect " +"any changes to the metrics collected and publish changes in the " +"changelog." msgstr "" #: ../../source/ref-telemetry.md:48 @@ -17181,17 +18328,17 @@ msgstr "" #: ../../source/ref-telemetry.md:52 msgid "" "We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information by " -"setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is " -"disabled by default. You may use logging independently from " +"metrics are reported. You can view all the reported telemetry information" +" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " +"is disabled by default. You may use logging independently from " "`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " "without sending any metrics." msgstr "" #: ../../source/ref-telemetry.md:58 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics, " -"use both environment variables:" +"The inspect Flower telemetry without sending any anonymous usage metrics," +" use both environment variables:" msgstr "" #: ../../source/ref-telemetry.md:64 @@ -17208,8 +18355,8 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android app " -"using Flower." +"Read this Federated Learning quickstart tutorial for creating an Android " +"app using Flower." msgstr "" #: ../../source/tutorial-quickstart-android.rst:5 @@ -17218,19 +18365,21 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"Let's build a federated learning system using TFLite and Flower on Android!" +"Let's build a federated learning system using TFLite and Flower on " +"Android!" msgstr "" #: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ to learn " +"more." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"FastAI to train a vision model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with FastAI to train a vision model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:5 @@ -17243,14 +18392,15 @@ msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower with " -"HuggingFace Transformers in order to fine-tune an LLM." +"Check out this Federating Learning quickstart tutorial for using Flower " +"with HuggingFace Transformers in order to fine-tune an LLM." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:5 @@ -17259,17 +18409,17 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Let's build a federated learning system using Hugging Face Transformers and " -"Flower!" +"Let's build a federated learning system using Hugging Face Transformers " +"and Flower!" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"We will leverage Hugging Face to federate the training of language models " -"over multiple clients using Flower. More specifically, we will fine-tune a " -"pre-trained Transformer model (distilBERT) for sequence classification over " -"a dataset of IMDB ratings. The end goal is to detect if a movie rating is " -"positive or negative." +"We will leverage Hugging Face to federate the training of language models" +" over multiple clients using Flower. More specifically, we will fine-tune" +" a pre-trained Transformer model (distilBERT) for sequence classification" +" over a dataset of IMDB ratings. The end goal is to detect if a movie " +"rating is positive or negative." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:18 @@ -17279,8 +18429,9 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:20 msgid "" "To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, " -"and :code:`transformers`. This can be done using :code:`pip`:" +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " +":code:`torch`, and :code:`transformers`. This can be done using " +":code:`pip`:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:30 @@ -17304,9 +18455,9 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"Once we have a way of creating our trainloader and testloader, we can take " -"care of the training and testing. This is very similar to any :code:" -"`PyTorch` training or testing loop:" +"Once we have a way of creating our trainloader and testloader, we can " +"take care of the training and testing. This is very similar to any " +":code:`PyTorch` training or testing loop:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:121 @@ -17315,8 +18466,8 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT " -"model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"To create the model itself, we will just load the pre-trained distillBERT" +" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:136 @@ -17330,17 +18481,18 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" "To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). This " -"is very easy, as our model is a standard :code:`PyTorch` model:" +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " +"This is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" "The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the server " -"to send its parameters to the client. Finally, the :code:`fit` function " -"trains the model locally for the client, and the :code:`evaluate` function " -"tests the model locally and returns the relevant metrics." +"parameters. Inversely, the :code:`set_parameters` function allows the " +"server to send its parameters to the client. Finally, the :code:`fit` " +"function trains the model locally for the client, and the " +":code:`evaluate` function tests the model locally and returns the " +"relevant metrics." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:175 @@ -17349,19 +18501,19 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Now that we have a way to instantiate clients, we need to create our server " -"in order to aggregate the results. Using Flower, this can be done very " -"easily by first choosing a strategy (here, we are using :code:`FedAvg`, " -"which will define the global weights as the average of all the clients' " -"weights at each round) and then using the :code:`flwr.server.start_server` " -"function:" +"Now that we have a way to instantiate clients, we need to create our " +"server in order to aggregate the results. Using Flower, this can be done " +"very easily by first choosing a strategy (here, we are using " +":code:`FedAvg`, which will define the global weights as the average of " +"all the clients' weights at each round) and then using the " +":code:`flwr.server.start_server` function:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"The :code:`weighted_average` function is there to provide a way to aggregate " -"the metrics distributed amongst the clients (basically this allows us to " -"display a nice average accuracy and loss for every round)." +"The :code:`weighted_average` function is there to provide a way to " +"aggregate the metrics distributed amongst the clients (basically this " +"allows us to display a nice average accuracy and loss for every round)." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:209 @@ -17380,22 +18532,22 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:223 msgid "" -"If you want to check out everything put together, you should check out the " -"`full code example `_ ." +"If you want to check out everything put together, you should check out " +"the `full code example `_ ." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Of course, this is a very basic example, and a lot can be added or modified, " -"it was just to showcase how simply we could federate a Hugging Face workflow " -"using Flower." +"Of course, this is a very basic example, and a lot can be added or " +"modified, it was just to showcase how simply we could federate a Hugging " +"Face workflow using Flower." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very " -"well used :code:`TensorFlow`." +"Note that in this example we used :code:`PyTorch`, but we could have very" +" well used :code:`TensorFlow`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:-1 @@ -17410,38 +18562,38 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST using " -"Flower and CoreML on iOS devices." +"In this tutorial we will learn how to train a Neural Network on MNIST " +"using Flower and CoreML on iOS devices." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:12 msgid "" "First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv " -"`. For the Flower client " +"create a virtual environment and run everything within a :doc:`virtualenv" +" `. For the Flower client " "implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that " -"all have the same model." +"Our example consists of one Python *server* and two iPhone *clients* that" +" all have the same model." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"*Clients* are responsible for generating individual weight updates for the " -"model based on their local datasets. These updates are then sent to the " -"*server* which will aggregate them to produce a better model. Finally, the " -"*server* sends this improved version of the model back to each *client*. A " -"complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:21 msgid "" "Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You " -"can do this by using pip:" +"setup our Flower server environment. We first need to install Flower. You" +" can do this by using pip:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:27 @@ -17459,20 +18611,21 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:36 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and MNIST " -"as our dataset. For simplicity reasons we will use the complete Flower " -"client with CoreML, that has been implemented and stored inside the Swift " -"SDK. The client implementation can be seen below:" +"distributed training using CoreML as our local training pipeline and " +"MNIST as our dataset. For simplicity reasons we will use the complete " +"Flower client with CoreML, that has been implemented and stored inside " +"the Swift SDK. The client implementation can be seen below:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a " -"dependency in your project. For our application, we will store the logic of " -"our app in :code:`FLiOSModel.swift` and the UI elements in :code:" -"`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift` in this " -"quickstart. Please refer to the `full code example `_ to learn more about the app." +"Let's create a new application project in Xcode and add :code:`flwr` as a" +" dependency in your project. For our application, we will store the logic" +" of our app in :code:`FLiOSModel.swift` and the UI elements in " +":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" +" in this quickstart. Please refer to the `full code example " +"`_ to learn more " +"about the app." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:75 @@ -17482,21 +18635,22 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:83 msgid "" "Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS device. " -"We need to pass the url to access mlmodel and run CoreML machine learning " -"processes, it can be retrieved by calling the function :code:`Bundle.main." -"url`. For the MNIST dataset, we need to preprocess it into :code:" -"`MLBatchProvider` object. The preprocessing is done inside :code:`DataLoader." -"swift`." +"will be bundled inside the application during deployment to your iOS " +"device. We need to pass the url to access mlmodel and run CoreML machine " +"learning processes, it can be retrieved by calling the function " +":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " +"into :code:`MLBatchProvider` object. The preprocessing is done inside " +":code:`DataLoader.swift`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:99 msgid "" -"Since CoreML does not allow the model parameters to be seen before training, " -"and accessing the model parameters during or after the training can only be " -"done by specifying the layer name, we need to know this information " -"beforehand, through looking at the model specification, which are written as " -"proto files. The implementation can be seen in :code:`MLModelInspect`." +"Since CoreML does not allow the model parameters to be seen before " +"training, and accessing the model parameters during or after the training" +" can only be done by specifying the layer name, we need to know this " +"information beforehand, through looking at the model specification, which" +" are written as proto files. The implementation can be seen in " +":code:`MLModelInspect`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:102 @@ -17507,18 +18661,18 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"Then start the Flower gRPC client and start communicating to the server by " -"passing our Flower client to the function :code:`startFlwrGRPC`." +"Then start the Flower gRPC client and start communicating to the server " +"by passing our Flower client to the function :code:`startFlwrGRPC`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:124 msgid "" -"That's it for the client. We only have to implement :code:`Client` or call " -"the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. The " -"attribute :code:`hostname` and :code:`port` tells the client which server to " -"connect to. This can be done by entering the hostname and port in the " -"application before clicking the start button to start the federated learning " -"process." +"That's it for the client. We only have to implement :code:`Client` or " +"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " +"The attribute :code:`hostname` and :code:`port` tells the client which " +"server to connect to. This can be done by entering the hostname and port " +"in the application before clicking the start button to start the " +"federated learning process." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:129 @@ -17534,8 +18688,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" "For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named :code:" -"`server.py`, import Flower and start the server:" +"configuration possibilities at their default values. In a file named " +":code:`server.py`, import Flower and start the server:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:142 @@ -17551,31 +18705,32 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" "With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and multiple " -"clients. We therefore have to start the server first:" +"federated learning in action. FL systems usually have a server and " +"multiple clients. We therefore have to start the server first:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"Once the server is running we can start the clients in different terminals. " -"Build and run the client through your Xcode, one through Xcode Simulator and " -"the other by deploying it to your iPhone. To see more about how to deploy " -"your app to iPhone or Simulator visit `here `_." +"Once the server is running we can start the clients in different " +"terminals. Build and run the client through your Xcode, one through Xcode" +" Simulator and the other by deploying it to your iPhone. To see more " +"about how to deploy your app to iPhone or Simulator visit `here " +"`_." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:156 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code `_ for this example can be found in :" -"code:`examples/ios`." +"learning system in your ios device. The full `source code " +"`_ for this " +"example can be found in :code:`examples/ios`." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"Jax to train a linear regression model on a scikit-learn dataset." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Jax to train a linear regression model on a scikit-learn dataset." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:5 @@ -17584,8 +18739,8 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"Pandas to perform Federated Analytics." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with Pandas to perform Federated Analytics." msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:5 @@ -17598,44 +18753,45 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ " +"to learn more." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"PyTorch to train a CNN model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch to train a CNN model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural Network " -"on CIFAR10 using Flower and PyTorch." +"In this tutorial we will learn how to train a Convolutional Neural " +"Network on CIFAR10 using Flower and PyTorch." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:15 #: ../../source/tutorial-quickstart-xgboost.rst:39 msgid "" "First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"everything within a :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:17 #: ../../source/tutorial-quickstart-scikitlearn.rst:14 msgid "" -"Our example consists of one *server* and two *clients* all having the same " -"model." +"Our example consists of one *server* and two *clients* all having the " +"same model." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:19 msgid "" -"*Clients* are responsible for generating individual weight-updates for the " -"model based on their local datasets. These updates are then sent to the " -"*server* which will aggregate them to produce a better model. Finally, the " -"*server* sends this improved version of the model back to each *client*. A " -"complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce a better model. " +"Finally, the *server* sends this improved version of the model back to " +"each *client*. A complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:23 @@ -17646,15 +18802,16 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go ahead " -"and install PyTorch and the **torchvision** library:" +"Since we want to use PyTorch to solve a computer vision task, let's go " +"ahead and install PyTorch and the **torchvision** library:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:39 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training procedure " -"and network architecture are based on PyTorch's `Deep Learning with PyTorch " +"distributed training with two clients and one server. Our training " +"procedure and network architecture are based on PyTorch's `Deep Learning " +"with PyTorch " "`_." msgstr "" @@ -17671,33 +18828,33 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" "We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads the " -"training and test data that are then normalized." +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " +"the training and test data that are then normalized." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset is " -"done by looping over the dataset, measure the corresponding loss and " +"Define the loss and optimizer with PyTorch. The training of the dataset " +"is done by looping over the dataset, measure the corresponding loss and " "optimize it." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"Define then the validation of the machine learning network. We loop over " -"the test set and measure the loss and accuracy of the test set." +"Define then the validation of the machine learning network. We loop over" +" the test set and measure the loss and accuracy of the test set." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:113 msgid "" -"After defining the training and testing of a PyTorch machine learning model, " -"we use the functions for the Flower clients." +"After defining the training and testing of a PyTorch machine learning " +"model, we use the functions for the Flower clients." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 Minute " -"Blitz':" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " +"Minute Blitz':" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:142 @@ -17709,19 +18866,20 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:144 #: ../../source/tutorial-quickstart-tensorflow.rst:54 msgid "" -"The Flower server interacts with clients through an interface called :code:" -"`Client`. When the server selects a particular client for training, it sends " -"training instructions over the network. The client receives those " -"instructions and calls one of the :code:`Client` methods to run your code (i." -"e., to train the neural network we defined earlier)." +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to train the neural network we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"PyTorch. Implementing :code:`NumPyClient` usually means defining the " -"following methods (:code:`set_parameters` is optional though):" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " +"defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:156 @@ -17737,7 +18895,8 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:158 #: ../../source/tutorial-quickstart-scikitlearn.rst:121 msgid "" -"update the local model weights with the parameters received from the server" +"update the local model weights with the parameters received from the " +"server" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:160 @@ -17767,22 +18926,22 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:189 #: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add one " -"line to actually run this client:" +"We can now create an instance of our class :code:`CifarClient` and add " +"one line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:196 #: ../../source/tutorial-quickstart-tensorflow.rst:90 msgid "" -"That's it for the client. We only have to implement :code:`Client` or :code:" -"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " -"client of type :code:`NumPyClient` you'll need to first call its :code:" -"`to_client()` method. The string :code:`\"[::]:8080\"` tells the client " -"which server to connect to. In our case we can run the server and the client " -"on the same machine, therefore we use :code:`\"[::]:8080\"`. If we run a " -"truly federated workload with the server and clients running on different " -"machines, all that needs to change is the :code:`server_address` we point " -"the client at." +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " +"the client which server to connect to. In our case we can run the server " +"and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:226 @@ -17790,8 +18949,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:122 #: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"Once the server is running we can start the clients in different terminals. " -"Open a new terminal and start the first client:" +"Once the server is running we can start the clients in different " +"terminals. Open a new terminal and start the first client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:233 @@ -17805,22 +18964,24 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:252 #: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Each client will have its own dataset. You should now see how the training " -"does in the very first terminal (the one that started the server):" +"Each client will have its own dataset. You should now see how the " +"training does in the very first terminal (the one that started the " +"server):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this example can be found " -"in :code:`examples/quickstart-pytorch`." +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples" +"/quickstart-pytorch`." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"PyTorch Lightning to train an Auto Encoder model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with PyTorch Lightning to train an Auto Encoder model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 @@ -17829,20 +18990,21 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 msgid "" -"Let's build a horizontal federated learning system using PyTorch Lightning " -"and Flower!" +"Let's build a horizontal federated learning system using PyTorch " +"Lightning and Flower!" msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"Please refer to the `full code example `_ to learn more." +"Please refer to the `full code example " +"`_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"scikit-learn to train a linear regression model." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with scikit-learn to train a linear regression model." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:5 @@ -17851,23 +19013,24 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic Regression` " -"model on MNIST using Flower and scikit-learn." +"In this tutorial, we will learn how to train a :code:`Logistic " +"Regression` model on MNIST using Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:12 msgid "" -"It is recommended to create a virtual environment and run everything within " -"this :doc:`virtualenv `." +"It is recommended to create a virtual environment and run everything " +"within this :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"*Clients* are responsible for generating individual model parameter updates " -"for the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce an updated global model. " -"Finally, the *server* sends this improved version of the model back to each " -"*client*. A complete cycle of parameters updates is called a *round*." +"*Clients* are responsible for generating individual model parameter " +"updates for the model based on their local datasets. These updates are " +"then sent to the *server* which will aggregate them to produce an updated" +" global model. Finally, the *server* sends this improved version of the " +"model back to each *client*. A complete cycle of parameters updates is " +"called a *round*." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:20 @@ -17888,10 +19051,10 @@ msgstr "" msgid "" "Now that we have all our dependencies installed, let's run a simple " "distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that we " -"need for our federated learning setup within :code:`utils.py`. The :code:" -"`utils.py` contains different functions defining all the machine learning " -"basics:" +"setting up the client and server, we will define all functionalities that" +" we need for our federated learning setup within :code:`utils.py`. The " +":code:`utils.py` contains different functions defining all the machine " +"learning basics:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:45 @@ -17920,44 +19083,46 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:52 msgid "" -"Please check out :code:`utils.py` `here `_ for more details. The pre-" -"defined functions are used in the :code:`client.py` and imported. The :code:" -"`client.py` also requires to import several packages such as Flower and " -"scikit-learn:" +"Please check out :code:`utils.py` `here " +"`_ for more details. The pre-defined functions are used in" +" the :code:`client.py` and imported. The :code:`client.py` also requires " +"to import several packages such as Flower and scikit-learn:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"Prior to local training, we need to load the MNIST dataset, a popular image " -"classification dataset of handwritten digits for machine learning, and " -"partition the dataset for FL. This can be conveniently achieved using " -"`Flower Datasets `_. The :code:" -"`FederatedDataset.load_partition()` method loads the partitioned training " -"set for each partition ID defined in the :code:`--partition-id` argument." +"Prior to local training, we need to load the MNIST dataset, a popular " +"image classification dataset of handwritten digits for machine learning, " +"and partition the dataset for FL. This can be conveniently achieved using" +" `Flower Datasets `_. The " +":code:`FederatedDataset.load_partition()` method loads the partitioned " +"training set for each partition ID defined in the :code:`--partition-id` " +"argument." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" -"Next, the logistic regression model is defined and initialized with :code:" -"`utils.set_initial_params()`." +"Next, the logistic regression model is defined and initialized with " +":code:`utils.set_initial_params()`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"The Flower server interacts with clients through an interface called :code:" -"`Client`. When the server selects a particular client for training, it sends " -"training instructions over the network. The client receives those " -"instructions and calls one of the :code:`Client` methods to run your code (i." -"e., to fit the logistic regression we defined earlier)." +"The Flower server interacts with clients through an interface called " +":code:`Client`. When the server selects a particular client for training," +" it sends training instructions over the network. The client receives " +"those instructions and calls one of the :code:`Client` methods to run " +"your code (i.e., to fit the logistic regression we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"scikit-learn. Implementing :code:`NumPyClient` usually means defining the " -"following methods (:code:`set_parameters` is optional though):" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " +"means defining the following methods (:code:`set_parameters` is optional " +"though):" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:122 @@ -17970,28 +19135,28 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:153 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add one " -"line to actually run this client:" +"We can now create an instance of our class :code:`MnistClient` and add " +"one line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:160 msgid "" -"That's it for the client. We only have to implement :code:`Client` or :code:" -"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " -"client of type :code:`NumPyClient` you'll need to first call its :code:" -"`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells the client " -"which server to connect to. In our case we can run the server and the client " -"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " -"truly federated workload with the server and clients running on different " -"machines, all that needs to change is the :code:`server_address` we pass to " -"the client." +"That's it for the client. We only have to implement :code:`Client` or " +":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " +"implement a client of type :code:`NumPyClient` you'll need to first call " +"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" +" the client which server to connect to. In our case we can run the server" +" and the client on the same machine, therefore we use " +":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we pass to the client." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:169 msgid "" "The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import again " -"all required libraries such as Flower and scikit-learn." +"evaluation function for the server-side evaluation. First, we import " +"again all required libraries such as Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:172 @@ -18000,44 +19165,46 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:185 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and " -"the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"The number of federated learning rounds is set in :code:`fit_round()` and" +" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " "function is called after each federated learning round and gives you " -"information about loss and accuracy. Note that we also make use of Flower " -"Datasets here to load the test split of the MNIST dataset for server-side " -"evaluation." +"information about loss and accuracy. Note that we also make use of Flower" +" Datasets here to load the test split of the MNIST dataset for server-" +"side evaluation." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"The :code:`main` contains the server-side parameter initialization :code:" -"`utils.set_initial_params()` as well as the aggregation strategy :code:`fl." -"server.strategy:FedAvg()`. The strategy is the default one, federated " -"averaging (or FedAvg), with two clients and evaluation after each federated " -"learning round. The server can be started with the command :code:`fl.server." -"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." -"server.ServerConfig(num_rounds=3))`." +"The :code:`main` contains the server-side parameter initialization " +":code:`utils.set_initial_params()` as well as the aggregation strategy " +":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " +"federated averaging (or FedAvg), with two clients and evaluation after " +"each federated learning round. The server can be started with the command" +" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " +"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:232 msgid "" "With both client and server ready, we can now run everything and see " "federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server first:" +"server and multiple clients. We, therefore, have to start the server " +"first:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:286 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this example can be found in :code:" -"`examples/sklearn-logreg-mnist`." +"learning system. The full `source code " +"`_ for this example can be found in :code:`examples/sklearn-logreg-" +"mnist`." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"TensorFlow to train a MobilNetV2 model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with TensorFlow to train a MobilNetV2 model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:5 @@ -18054,8 +19221,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install TF " -"as well:" +"Since we want to use the Keras API of TensorFlow (TF), we have to install" +" TF as well:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:31 @@ -18064,24 +19231,25 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image " -"classification dataset for machine learning. The call to :code:`tf.keras." -"datasets.cifar10.load_data()` downloads CIFAR10, caches it locally, and then " -"returns the entire training and test set as NumPy ndarrays." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image" +" classification dataset for machine learning. The call to " +":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " +"it locally, and then returns the entire training and test set as NumPy " +"ndarrays." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use MobilNetV2 " -"with 10 output classes:" +"Next, we need a model. For the purpose of this tutorial, we use " +"MobilNetV2 with 10 output classes:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which makes " -"it easier to implement the :code:`Client` interface when your workload uses " -"Keras. The :code:`NumPyClient` interface defines three methods which can be " -"implemented in the following way:" +"Flower provides a convenience class called :code:`NumPyClient` which " +"makes it easier to implement the :code:`Client` interface when your " +"workload uses Keras. The :code:`NumPyClient` interface defines three " +"methods which can be implemented in the following way:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:135 @@ -18090,22 +19258,23 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"You should now see how the training does in the very first terminal (the one " -"that started the server):" +"You should now see how the training does in the very first terminal (the " +"one that started the server):" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code `_ for this can be found in :" -"code:`examples/quickstart-tensorflow/client.py`." +"learning system. The full `source code " +"`_ for this can be found in :code:`examples" +"/quickstart-tensorflow/client.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower with " -"XGBoost to train classification models on trees." +"Check out this Federated Learning quickstart tutorial for using Flower " +"with XGBoost to train classification models on trees." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:5 @@ -18119,17 +19288,18 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" "EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that maximises " -"the computational boundaries for boosted tree methods. It's primarily " -"designed to enhance both the performance and computational speed of machine " -"learning models. In XGBoost, trees are constructed concurrently, unlike the " -"sequential approach taken by GBDT." +"implementation of gradient-boosted decision tree (**GBDT**), that " +"maximises the computational boundaries for boosted tree methods. It's " +"primarily designed to enhance both the performance and computational " +"speed of machine learning models. In XGBoost, trees are constructed " +"concurrently, unlike the sequential approach taken by GBDT." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" "Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning techniques." +"training examples, XGBoost surpasses the results of deep learning " +"techniques." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:23 @@ -18139,30 +19309,30 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" "Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems for " -"specialised applications, like survival analysis and financial fraud " +"there's an increasing requirement to implement federated XGBoost systems " +"for specialised applications, like survival analysis and financial fraud " "detection." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"Federated learning ensures that raw data remains on the local device, making " -"it an attractive approach for sensitive domains where data security and " -"privacy are paramount. Given the robustness and efficiency of XGBoost, " -"combining it with federated learning offers a promising solution for these " -"specific challenges." +"Federated learning ensures that raw data remains on the local device, " +"making it an attractive approach for sensitive domains where data " +"security and privacy are paramount. Given the robustness and efficiency " +"of XGBoost, combining it with federated learning offers a promising " +"solution for these specific challenges." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" "In this tutorial we will learn how to train a federated XGBoost model on " "HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart `_) with two *clients* and one *server* to " -"demonstrate how federated XGBoost works, and then we dive into a more " -"complex example (`full code xgboost-comprehensive `_) to run various " -"experiments." +"example (`full code xgboost-quickstart " +"`_)" +" with two *clients* and one *server* to demonstrate how federated XGBoost" +" works, and then we dive into a more complex example (`full code xgboost-" +"comprehensive `_) to run various experiments." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:37 @@ -18183,16 +19353,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"*Clients* are responsible for generating individual weight-updates for the " -"model based on their local datasets. Now that we have all our dependencies " -"installed, let's run a simple distributed training with two clients and one " -"server." +"*Clients* are responsible for generating individual weight-updates for " +"the model based on their local datasets. Now that we have all our " +"dependencies installed, let's run a simple distributed training with two " +"clients and one server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:60 msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower Datasets " -"and other related functions:" +"In a file called :code:`client.py`, import xgboost, Flower, Flower " +"Datasets and other related functions:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:87 @@ -18201,15 +19371,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower " -"Datasets and conduct data partitioning for FL:" +"Prior to local training, we require loading the HIGGS dataset from Flower" +" Datasets and conduct data partitioning for FL:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" "In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load the " -"partition for the given client based on :code:`node_id`:" +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " +"the partition for the given client based on :code:`node_id`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:121 @@ -18220,8 +19390,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"The functions of :code:`train_test_split` and :code:" -"`transform_dataset_to_dmatrix` are defined as below:" +"The functions of :code:`train_test_split` and " +":code:`transform_dataset_to_dmatrix` are defined as below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:158 @@ -18230,10 +19400,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"The :code:`num_local_round` represents the number of iterations for local " -"tree boost. We use CPU for the training in default. One can shift it to GPU " -"by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as evaluation " -"metric." +"The :code:`num_local_round` represents the number of iterations for local" +" tree boost. We use CPU for the training in default. One can shift it to " +"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " +"evaluation metric." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:181 @@ -18242,85 +19412,86 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"After loading the dataset we define the Flower client. We follow the general " -"rule to define :code:`XgbClient` class inherited from :code:`fl.client." -"Client`." +"After loading the dataset we define the Flower client. We follow the " +"general rule to define :code:`XgbClient` class inherited from " +":code:`fl.client.Client`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" "The :code:`self.bst` is used to keep the Booster objects that remain " "consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures " -"for training." +"integrated in earlier rounds and maintain other essential data structures" +" for training." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:196 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and :code:`evaluate` " -"methods insides :code:`XgbClient` class as follows." +"Then, we override :code:`get_parameters`, :code:`fit` and " +":code:`evaluate` methods insides :code:`XgbClient` class as follows." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" "Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use :code:`get_parameters` " -"and :code:`set_parameters` to initialise model parameters for XGBoost. As a " -"result, let's return an empty tensor in :code:`get_parameters` when it is " -"called by the server at the first round." +"specified random weights. In this case, we do not use " +":code:`get_parameters` and :code:`set_parameters` to initialise model " +"parameters for XGBoost. As a result, let's return an empty tensor in " +":code:`get_parameters` when it is called by the server at the first " +"round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build up " -"the first set of trees. the returned Booster object and config are stored " -"in :code:`self.bst` and :code:`self.config`, respectively. From the second " -"round, we load the global model sent from server to :code:`self.bst`, and " -"then update model weights on local training data with function :code:" -"`local_boost` as follows:" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " +"up the first set of trees. the returned Booster object and config are " +"stored in :code:`self.bst` and :code:`self.config`, respectively. From " +"the second round, we load the global model sent from server to " +":code:`self.bst`, and then update model weights on local training data " +"with function :code:`local_boost` as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"Given :code:`num_local_round`, we update trees by calling :code:`self.bst." -"update` method. After training, the last :code:`N=num_local_round` trees " -"will be extracted to send to the server." +"Given :code:`num_local_round`, we update trees by calling " +":code:`self.bst.update` method. After training, the last " +":code:`N=num_local_round` trees will be extracted to send to the server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to conduct " -"evaluation on valid set. The AUC value will be returned." +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " +"conduct evaluation on valid set. The AUC value will be returned." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one " -"line to actually run this client:" +"Now, we can create an instance of our class :code:`XgbClient` and add one" +" line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"That's it for the client. We only have to implement :code:`Client`and call :" -"code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` tells the " -"client which server to connect to. In our case we can run the server and the " -"client on the same machine, therefore we use :code:`\"[::]:8080\"`. If we " -"run a truly federated workload with the server and clients running on " -"different machines, all that needs to change is the :code:`server_address` " -"we point the client at." +"That's it for the client. We only have to implement :code:`Client`and " +"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " +"tells the client which server to connect to. In our case we can run the " +"server and the client on the same machine, therefore we use " +":code:`\"[::]:8080\"`. If we run a truly federated workload with the " +"server and clients running on different machines, all that needs to " +"change is the :code:`server_address` we point the client at." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" "These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version of " -"the model back to each *client* to finish a complete FL round." +"produce a better model. Finally, the *server* sends this improved version" +" of the model back to each *client* to finish a complete FL round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from :" -"code:`flwr.server.strategy`." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from " +":code:`flwr.server.strategy`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:316 @@ -18329,9 +19500,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"We use two clients for this example. An :code:`evaluate_metrics_aggregation` " -"function is defined to collect and wighted average the AUC values from " -"clients." +"We use two clients for this example. An " +":code:`evaluate_metrics_aggregation` function is defined to collect and " +"wighted average the AUC values from clients." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:342 @@ -18344,16 +19515,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"You must be curious about how bagging aggregation works. Let's look into the " -"details." +"You must be curious about how bagging aggregation works. Let's look into " +"the details." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define :code:" -"`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`. Then, we " -"override the :code:`aggregate_fit`, :code:`aggregate_evaluate` and :code:" -"`evaluate` methods as follows:" +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " +":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." +" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " +"and :code:`evaluate` methods as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:454 @@ -18365,10 +19536,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" "In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling :code:" -"`_get_tree_nums`. Then, the fetched information will be aggregated. After " -"that, the trees (containing model weights) are aggregated to generate a new " -"tree model." +"parallel trees for the current and previous model by calling " +":code:`_get_tree_nums`. Then, the fetched information will be aggregated." +" After that, the trees (containing model weights) are aggregated to " +"generate a new tree model." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:518 @@ -18384,16 +19555,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" "Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in :code:" -"`metrics_distributed`. One can see that the average AUC increases over FL " -"rounds." +"XGBoost system. The AUC values can be checked in " +":code:`metrics_distributed`. One can see that the average AUC increases " +"over FL rounds." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"The full `source code `_ for this example can be found in :code:`examples/" -"xgboost-quickstart`." +"The full `source code `_ for this example can be found in :code:`examples" +"/xgboost-quickstart`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:594 @@ -18402,15 +19573,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:596 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time to " -"run some more comprehensive experiments by customising the experimental " -"settings. In the xgboost-comprehensive example (`full code `_), we provide " -"more options to define various experimental setups, including aggregation " -"strategies, data partitioning and centralised/distributed evaluation. We " -"also support :doc:`Flower simulation ` making it " -"easy to simulate large client cohorts in a resource-aware manner. Let's take " -"a look!" +"Now that you have known how federated XGBoost work with Flower, it's time" +" to run some more comprehensive experiments by customising the " +"experimental settings. In the xgboost-comprehensive example (`full code " +"`_), we provide more options to define various experimental" +" setups, including aggregation strategies, data partitioning and " +"centralised/distributed evaluation. We also support :doc:`Flower " +"simulation ` making it easy to simulate large " +"client cohorts in a resource-aware manner. Let's take a look!" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:603 @@ -18419,40 +19590,41 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, which " -"performs FL in a client-by-client fashion. Instead of aggregating multiple " -"clients, there is only one single client participating in the training per " -"round in the cyclic training scenario. The trained local XGBoost trees will " -"be passed to the next client as an initialised model for next round's " -"boosting." +"In addition to bagging aggregation, we offer a cyclic training scheme, " +"which performs FL in a client-by-client fashion. Instead of aggregating " +"multiple clients, there is only one single client participating in the " +"training per round in the cyclic training scenario. The trained local " +"XGBoost trees will be passed to the next client as an initialised model " +"for next round's boosting." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"To do this, we first customise a :code:`ClientManager` in :code:" -"`server_utils.py`:" +"To do this, we first customise a :code:`ClientManager` in " +":code:`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"The customised :code:`ClientManager` samples all available clients in each " -"FL round based on the order of connection to the server. Then, we define a " -"new strategy :code:`FedXgbCyclic` in :code:`flwr.server.strategy." -"fedxgb_cyclic.py`, in order to sequentially select only one client in given " -"round and pass the received model to next client." +"The customised :code:`ClientManager` samples all available clients in " +"each FL round based on the order of connection to the server. Then, we " +"define a new strategy :code:`FedXgbCyclic` in " +":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " +"select only one client in given round and pass the received model to next" +" client." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" "Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model by " -"overriding :code:`aggregate_fit`." +"Instead, we just make a copy of the received client model as global model" +" by overriding :code:`aggregate_fit`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate` " -"methods ensure the clients to be sequentially selected given FL round:" +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" +" methods ensure the clients to be sequentially selected given FL round:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:757 @@ -18461,11 +19633,11 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner` to " -"instantiate the data partitioner based on the given :code:`num_partitions` " -"and :code:`partitioner_type`. Currently, we provide four supported " -"partitioner type to simulate the uniformity/non-uniformity in data quantity " -"(uniform, linear, square, exponential)." +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" +" to instantiate the data partitioner based on the given " +":code:`num_partitions` and :code:`partitioner_type`. Currently, we " +"provide four supported partitioner type to simulate the uniformity/non-" +"uniformity in data quantity (uniform, linear, square, exponential)." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:790 @@ -18474,23 +19646,23 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:792 msgid "" -"To facilitate centralised evaluation, we define a function in :code:" -"`server_utils.py`:" +"To facilitate centralised evaluation, we define a function in " +":code:`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"This function returns a evaluation function which instantiates a :code:" -"`Booster` object and loads the global model weights to it. The evaluation is " -"conducted by calling :code:`eval_set()` method, and the tested AUC value is " -"reported." +"This function returns a evaluation function which instantiates a " +":code:`Booster` object and loads the global model weights to it. The " +"evaluation is conducted by calling :code:`eval_set()` method, and the " +"tested AUC value is reported." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:827 msgid "" -"As for distributed evaluation on the clients, it's same as the quick-start " -"example by overriding the :code:`evaluate()` method insides the :code:" -"`XgbClient` class in :code:`client_utils.py`." +"As for distributed evaluation on the clients, it's same as the quick-" +"start example by overriding the :code:`evaluate()` method insides the " +":code:`XgbClient` class in :code:`client_utils.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:831 @@ -18500,21 +19672,21 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a " -"single machine or a cluster of machines." +"capabilities of Flower to simulate federated XGBoost training on either a" +" single machine or a cluster of machines." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"After importing all required packages, we define a :code:`main()` function " -"to perform the simulation process:" +"After importing all required packages, we define a :code:`main()` " +"function to perform the simulation process:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" "We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, the " -"clients won't need to pre-process their partitions again." +"processed data is stored in a :code:`list`. After the simulation begins, " +"the clients won't need to pre-process their partitions again." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:924 @@ -18523,8 +19695,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"After that, we start the simulation by calling :code:`fl.simulation." -"start_simulation`:" +"After that, we start the simulation by calling " +":code:`fl.simulation.start_simulation`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:995 @@ -18539,18 +19711,18 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1040 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server and " -"simulation, allowing users to specify different experimental settings. Let's " -"first see the sever side:" +"In :code:`utils.py`, we define the arguments parsers for clients, server " +"and simulation, allowing users to specify different experimental " +"settings. Let's first see the sever side:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1086 msgid "" "This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and " -"evaluation fashion. Note that with :code:`--centralised-eval`, the sever " -"will do centralised evaluation and all functionalities for client evaluation " -"will be disabled." +"clients / FL rounds / participating clients / clients for evaluation, and" +" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" +" will do centralised evaluation and all functionalities for client " +"evaluation will be disabled." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1090 @@ -18559,10 +19731,11 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1144 msgid "" -"This defines various options for client data partitioning. Besides, clients " -"also have an option to conduct evaluation on centralised test set by " -"setting :code:`--centralised-eval`, as well as an option to perform scaled " -"learning rate based on the number of clients by setting :code:`--scaled-lr`." +"This defines various options for client data partitioning. Besides, " +"clients also have an option to conduct evaluation on centralised test set" +" by setting :code:`--centralised-eval`, as well as an option to perform " +"scaled learning rate based on the number of clients by setting :code" +":`--scaled-lr`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1148 @@ -18579,9 +19752,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1231 msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 clients " -"with exponential distribution for 50 rounds, we first start the server as " -"below:" +"To run a centralised evaluated experiment with bagging strategy on 5 " +"clients with exponential distribution for 50 rounds, we first start the " +"server as below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1238 @@ -18594,9 +19767,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1250 msgid "" -"The full `code `_ for this comprehensive example can be found in :code:" -"`examples/xgboost-comprehensive`." +"The full `code `_ for this comprehensive example can be found in" +" :code:`examples/xgboost-comprehensive`." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 @@ -18607,18 +19780,19 @@ msgstr "" msgid "" "Welcome to the third part of the Flower federated learning tutorial. In " "previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies can be " -"used to customize the execution on both the server and the clients (`part 2 " -"`__)." +"PyTorch and Flower (`part 1 `__) and we learned how strategies " +"can be used to customize the execution on both the server and the clients" +" (`part 2 `__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"In this notebook, we'll continue to customize the federated learning system " -"we built previously by creating a custom version of FedAvg (again, using " -"`Flower `__ and `PyTorch `__)." +"In this notebook, we'll continue to customize the federated learning " +"system we built previously by creating a custom version of FedAvg (again," +" using `Flower `__ and `PyTorch " +"`__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 @@ -18626,11 +19800,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join the " -"Flower community on Slack to connect, ask questions, and get help: `Join " -"Slack `__ 🌼 We'd love to hear from you in the " -"``#introductions`` channel! And if anything is unclear, head over to the " -"``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join " +"the Flower community on Slack to connect, ask questions, and get help: " +"`Join Slack `__ 🌼 We'd love to hear from " +"you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 @@ -18676,14 +19850,14 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled (on " -"Google Colab: ``Runtime > Change runtime type > Hardware acclerator: GPU > " -"Save``). Note, however, that Google Colab is not always able to offer GPU " -"acceleration. If you see an error related to GPU availability in one of the " -"following sections, consider switching back to CPU-based execution by " -"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " -"acceleration enabled, you should see the output ``Training on cuda``, " -"otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " +"GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 @@ -18695,11 +19869,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into ten " -"smaller datasets (each split into training and validation set), and wrap " -"everything in their own ``DataLoader``. We introduce a new parameter " -"``num_clients`` which allows us to call ``load_datasets`` with different " -"numbers of clients." +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``. We introduce a new parameter" +" ``num_clients`` which allows us to call ``load_datasets`` with different" +" numbers of clients." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 @@ -18712,8 +19886,8 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"Let's continue with the usual model definition (including ``set_parameters`` " -"and ``get_parameters``), training and test functions:" +"Let's continue with the usual model definition (including " +"``set_parameters`` and ``get_parameters``), training and test functions:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 @@ -18724,10 +19898,10 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"To implement the Flower client, we (again) create a subclass of ``flwr." -"client.NumPyClient`` and implement the three methods ``get_parameters``, " -"``fit``, and ``evaluate``. Here, we also pass the ``cid`` to the client and " -"use it log additional details:" +"To implement the Flower client, we (again) create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " +"``cid`` to the client and use it log additional details:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 @@ -18740,11 +19914,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher " -"learning rate (potentially also other hyperparameters) to the optimizer of a " -"fraction of the clients. We will keep the sampling of the clients as it is " -"in ``FedAvg`` and then change the configuration dictionary (one of the " -"``FitIns`` attributes)." +"Let’s overwrite the ``configure_fit`` method such that it passes a higher" +" learning rate (potentially also other hyperparameters) to the optimizer " +"of a fraction of the clients. We will keep the sampling of the clients as" +" it is in ``FedAvg`` and then change the configuration dictionary (one of" +" the ``FitIns`` attributes)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 @@ -18761,13 +19935,13 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom " -"strategy enables granular control over client node configuration, result " -"aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``. To " -"make custom strategies even more powerful, you can pass custom functions to " -"the constructor of your new class (``__init__``) and then call these " -"functions whenever needed." +"In this notebook, we’ve seen how to implement a custom strategy. A custom" +" strategy enables granular control over client node configuration, result" +" aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``." +" To make custom strategies even more powerful, you can pass custom " +"functions to the constructor of your new class (``__init__``) and then " +"call these functions whenever needed." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 @@ -18776,8 +19950,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"Before you continue, make sure to join the Flower community on Slack: `Join " -"Slack `__" +"Before you continue, make sure to join the Flower community on Slack: " +"`Join Slack `__" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 @@ -18786,15 +19960,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd also " -"love to hear who you are in ``#introductions``!" +"There's a dedicated ``#questions`` channel if you need help, but we'd " +"also love to hear who you are in ``#introductions``!" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 `__ introduces " -"``Client``, the flexible API underlying ``NumPyClient``." +"The `Flower Federated Learning Tutorial - Part 4 " +"`__ introduces ``Client``, the flexible API underlying " +"``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 @@ -18803,26 +19978,26 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In the " -"previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__), we learned how strategies can be used " -"to customize the execution on both the server and the clients (`part 2 " -"`__), and we built our own custom strategy from scratch (`part " -"3 `__)." +"Welcome to the fourth part of the Flower federated learning tutorial. In " +"the previous parts of this tutorial, we introduced federated learning " +"with PyTorch and Flower (`part 1 `__), we learned how " +"strategies can be used to customize the execution on both the server and " +"the clients (`part 2 `__), and we built our own " +"custom strategy from scratch (`part 3 `__)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new baseclass " -"for building clients, simply named ``Client``. In previous parts of this " -"tutorial, we've based our client on ``NumPyClient``, a convenience class " -"which makes it easy to work with machine learning libraries that have good " -"NumPy interoperability. With ``Client``, we gain a lot of flexibility that " -"we didn't have before, but we'll also have to do a few things the we didn't " -"have to do before." +"In this notebook, we revisit ``NumPyClient`` and introduce a new " +"baseclass for building clients, simply named ``Client``. In previous " +"parts of this tutorial, we've based our client on ``NumPyClient``, a " +"convenience class which makes it easy to work with machine learning " +"libraries that have good NumPy interoperability. With ``Client``, we gain" +" a lot of flexibility that we didn't have before, but we'll also have to " +"do a few things the we didn't have to do before." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 @@ -18838,9 +20013,9 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into ten " -"smaller datasets (each split into training and validation set), and wrap " -"everything in their own ``DataLoader``." +"Let's now load the CIFAR-10 training and test set, partition them into " +"ten smaller datasets (each split into training and validation set), and " +"wrap everything in their own ``DataLoader``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 @@ -18849,10 +20024,10 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"So far, we've implemented our client by subclassing ``flwr.client." -"NumPyClient``. The three methods we implemented are ``get_parameters``, " -"``fit``, and ``evaluate``. Finally, we wrap the creation of instances of " -"this class in a function called ``client_fn``:" +"So far, we've implemented our client by subclassing " +"``flwr.client.NumPyClient``. The three methods we implemented are " +"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " +"creation of instances of this class in a function called ``client_fn``:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 @@ -18874,24 +20049,25 @@ msgid "" "Let's dive a little bit deeper and discuss how Flower executes this " "simulation. Whenever a client is selected to do some work, " "``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and the " -"data)." +"instance of our ``FlowerNumPyClient`` (along with loading the model and " +"the data)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" "But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to makes " -"it look like a subclass of ``flwr.client.Client``, not ``flwr.client." -"NumPyClient``. In fact, the Flower core framework doesn't know how to handle " -"``NumPyClient``'s, it only knows how to handle ``Client``'s. ``NumPyClient`` " -"is just a convenience abstraction built on top of ``Client``." +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " +"makes it look like a subclass of ``flwr.client.Client``, not " +"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " +"know how to handle ``NumPyClient``'s, it only knows how to handle " +"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " +"top of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on top " -"of ``Client``." +"Instead of building on top of ``NumPyClient``, we can directly build on " +"top of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 @@ -18900,13 +20076,14 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 msgid "" -"Let's try to do the same thing using ``Client`` instead of ``NumPyClient``." +"Let's try to do the same thing using ``Client`` instead of " +"``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta make " -"sure our new ``Client``-based client works, right?" +"Before we discuss the code in more detail, let's try to run it! Gotta " +"make sure our new ``Client``-based client works, right?" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 @@ -18917,40 +20094,40 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"First of all, it's more code. But why? The difference comes from the fact " -"that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the network, " -"it eventually needs to turn these parameters into ``bytes``. Turning " -"parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"First of all, it's more code. But why? The difference comes from the fact" +" that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the " +"network, it eventually needs to turn these parameters into ``bytes``. " +"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " "serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it needs " -"to serialize parameters on the server-side and send them to the client, the " -"client needs to deserialize them to use them for local training, and then " -"serialize the updated parameters again to send them back to the server, " -"which (finally!) deserializes them again in order to aggregate them with the " -"updates received from other clients." +"``ndarray``'s) is called deserialization. Flower needs to do both: it " +"needs to serialize parameters on the server-side and send them to the " +"client, the client needs to deserialize them to use them for local " +"training, and then serialize the updated parameters again to send them " +"back to the server, which (finally!) deserializes them again in order to " +"aggregate them with the updates received from other clients." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" "The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It can " -"do so because it expects you to return parameters as NumPy ndarray's, and it " -"knows how to handle these. This makes working with machine learning " -"libraries that have good NumPy support (most of them) a breeze." +"NumPyClient takes care of serialization and deserialization for you. It " +"can do so because it expects you to return parameters as NumPy ndarray's," +" and it knows how to handle these. This makes working with machine " +"learning libraries that have good NumPy support (most of them) a breeze." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"In terms of API, there's one major difference: all methods in Client take " -"exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return exactly " -"one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"In terms of API, there's one major difference: all methods in Client take" +" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " +"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " "``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return " -"values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These ``*Ins`` " -"and ``*Res`` objects in ``Client`` wrap all the individual values you're " -"used to from ``NumPyClient``." +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" +" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These " +"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " +"values you're used to from ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 @@ -18967,16 +20144,17 @@ msgstr "" msgid "" "But first what is serialization? Serialization is just the process of " "converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an object. " -"This is very useful for network communication. Indeed, without " +"deserialization is the process of converting raw bytes back into an " +"object. This is very useful for network communication. Indeed, without " "serialization, you could not just a Python object through the internet." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 msgid "" -"Federated Learning relies heavily on internet communication for training by " -"sending Python objects back and forth between the clients and the server. " -"This means that serialization is an essential part of Federated Learning." +"Federated Learning relies heavily on internet communication for training " +"by sending Python objects back and forth between the clients and the " +"server. This means that serialization is an essential part of Federated " +"Learning." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 @@ -18996,15 +20174,15 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"This is where the real serialization/deserialization will happen, especially " -"in ``ndarray_to_sparse_bytes`` for serialization and " +"This is where the real serialization/deserialization will happen, " +"especially in ``ndarray_to_sparse_bytes`` for serialization and " "``sparse_bytes_to_ndarray`` for deserialization." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert our " -"arrays." +"Note that we imported the ``scipy.sparse`` library in order to convert " +"our arrays." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 @@ -19013,28 +20191,30 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we will " -"just have to call our custom functions in our ``flwr.client.Client``." +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " +"will just have to call our custom functions in our " +"``flwr.client.Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 msgid "" "Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` defined " -"above." +"from our network using our custom ``ndarrays_to_sparse_parameters`` " +"defined above." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" "In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we need " -"to serialize our local results with ``ndarrays_to_sparse_parameters``." +"server using our custom ``sparse_parameters_to_ndarrays`` and then we " +"need to serialize our local results with " +"``ndarrays_to_sparse_parameters``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters with " -"our custom function." +"In ``evaluate``, we will only need to deserialize the global parameters " +"with our custom function." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 @@ -19043,10 +20223,11 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change the " -"serialization and deserialization here, we only need to reimplement the " -"``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other " -"functions of the strategy will be inherited from the super class ``FedAvg``." +"For this example, we will just use ``FedAvg`` as a strategy. To change " +"the serialization and deserialization here, we only need to reimplement " +"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" +" functions of the strategy will be inherited from the super class " +"``FedAvg``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 @@ -19071,19 +20252,19 @@ msgstr "" msgid "" "In this part of the tutorial, we've seen how we can build clients by " "subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine learning " -"libraries that have good NumPy interoperability. ``Client`` is a more " -"flexible abstraction that allows us to do things that are not possible in " -"``NumPyClient``. In order to do so, it requires us to handle parameter " -"serialization and deserialization ourselves." +"convenience abstraction that makes it easier to work with machine " +"learning libraries that have good NumPy interoperability. ``Client`` is a" +" more flexible abstraction that allows us to do things that are not " +"possible in ``NumPyClient``. In order to do so, it requires us to handle " +"parameter serialization and deserialization ourselves." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"This is the final part of the Flower tutorial (for now!), congratulations! " -"You're now well equipped to understand the rest of the documentation. There " -"are many topics we didn't cover in the tutorial, we recommend the following " -"resources:" +"This is the final part of the Flower tutorial (for now!), " +"congratulations! You're now well equipped to understand the rest of the " +"documentation. There are many topics we didn't cover in the tutorial, we " +"recommend the following resources:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 @@ -19092,20 +20273,20 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"`Check out Flower Code Examples `__" +"`Check out Flower Code Examples " +"`__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"`Use Flower Baselines for your research `__" +"`Use Flower Baselines for your research " +"`__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"`Watch Flower Summit 2023 videos `__" +"`Watch Flower Summit 2023 videos `__" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 @@ -19120,9 +20301,10 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 msgid "" "In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In part " -"1, we use PyTorch for the model training pipeline and data loading. In part " -"2, we continue to federate the PyTorch-based pipeline using Flower." +"`Flower Datasets `__ and PyTorch. In " +"part 1, we use PyTorch for the model training pipeline and data loading. " +"In part 2, we continue to federate the PyTorch-based pipeline using " +"Flower." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 @@ -19139,19 +20321,20 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 msgid "" "Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower (``flwr``):" +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " +"(``flwr``):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled (on " -"Google Colab: ``Runtime > Change runtime type > Hardware accelerator: GPU > " -"Save``). Note, however, that Google Colab is not always able to offer GPU " -"acceleration. If you see an error related to GPU availability in one of the " -"following sections, consider switching back to CPU-based execution by " -"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " -"acceleration enabled, you should see the output ``Training on cuda``, " -"otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled " +"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" +" GPU > Save``). Note, however, that Google Colab is not always able to " +"offer GPU acceleration. If you see an error related to GPU availability " +"in one of the following sections, consider switching back to CPU-based " +"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " +"has GPU acceleration enabled, you should see the output ``Training on " +"cuda``, otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 @@ -19160,50 +20343,51 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 msgid "" -"Federated learning can be applied to many different types of tasks across " -"different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular CIFAR-10 " -"dataset. CIFAR-10 can be used to train image classifiers that distinguish " -"between images from ten different classes: 'airplane', 'automobile', 'bird', " -"'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and 'truck'." +"Federated learning can be applied to many different types of tasks across" +" different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular " +"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " +"distinguish between images from ten different classes: 'airplane', " +"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " +"'truck'." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" "We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the " -"original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely for " -"experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the data " -"is naturally partitioned)." +"called the \"cross-silo\" setting in federated learning) by splitting the" +" original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely " +"for experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the " +"data is naturally partitioned)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 msgid "" -"Each organization will act as a client in the federated learning system. So " -"having ten organizations participate in a federation means having ten " +"Each organization will act as a client in the federated learning system. " +"So having ten organizations participate in a federation means having ten " "clients connected to the federated learning server." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 msgid "" "Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training and " -"test set for each edge device and wrap each of them into a PyTorch " +"datasets`` that partitions the CIFAR-10. We will create small training " +"and test set for each edge device and wrap each of them into a PyTorch " "``DataLoader``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 msgid "" "We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten different " -"organizations. Each ``trainloader``/``valloader`` pair contains 4000 " -"training examples and 1000 validation examples. There's also a single " -"``testloader`` (we did not split the test set). Again, this is only " -"necessary for building research or educational systems, actual federated " -"learning systems have their data naturally distributed across multiple " -"partitions." +"(``trainloaders`` and ``valloaders``) representing the data of ten " +"different organizations. Each ``trainloader``/``valloader`` pair contains" +" 4000 training examples and 1000 validation examples. There's also a " +"single ``testloader`` (we did not split the test set). Again, this is " +"only necessary for building research or educational systems, actual " +"federated learning systems have their data naturally distributed across " +"multiple partitions." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 @@ -19217,8 +20401,8 @@ msgid "" "The output above shows a random batch of images from the first " "``trainloader`` in our list of ten ``trainloaders``. It also prints the " "labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another batch " -"of images." +"we've seen above). If you run the cell again, you should see another " +"batch of images." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 @@ -19231,8 +20415,8 @@ msgid "" "network. This introduction assumes basic familiarity with PyTorch, so it " "doesn't cover the PyTorch-related aspects in full detail. If you want to " "dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ `__." +"MINUTE BLITZ " +"`__." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 @@ -19241,9 +20425,9 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"We use the simple CNN described in the `PyTorch tutorial `__:" +"We use the simple CNN described in the `PyTorch tutorial " +"`__:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 @@ -19257,19 +20441,20 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" "We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train the " -"model on the dataset of one of our organizations (``trainloaders[0]``). This " -"simulates the reality of most machine learning projects today: each " -"organization has their own data and trains models only on this internal data:" +"training function, and a test function. Let's put them together to train " +"the model on the dataset of one of our organizations " +"(``trainloaders[0]``). This simulates the reality of most machine " +"learning projects today: each organization has their own data and trains " +"models only on this internal data:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result in " -"a test set accuracy of about 41%, which is not good, but at the same time, " -"it doesn't really matter for the purposes of this tutorial. The intent was " -"just to show a simplistic centralized training pipeline that sets the stage " -"for what comes next - federated learning!" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " +"in a test set accuracy of about 41%, which is not good, but at the same " +"time, it doesn't really matter for the purposes of this tutorial. The " +"intent was just to show a simplistic centralized training pipeline that " +"sets the stage for what comes next - federated learning!" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 @@ -19278,11 +20463,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was in " -"one place (i.e., a single ``trainloader`` and a single ``valloader``). Next, " -"we'll simulate a situation where we have multiple datasets in multiple " -"organizations and where we train a model over these organizations using " -"federated learning." +"Step 1 demonstrated a simple centralized training pipeline. All data was " +"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." +" Next, we'll simulate a situation where we have multiple datasets in " +"multiple organizations and where we train a model over these " +"organizations using federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 @@ -19291,29 +20476,30 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"In federated learning, the server sends the global model parameters to the " -"client, and the client updates the local model with the parameters received " -"from the server. It then trains the model on the local data (which changes " -"the model parameters locally) and sends the updated/changed model parameters " -"back to the server (or, alternatively, it sends just the gradients back to " -"the server, not the full model parameters)." +"In federated learning, the server sends the global model parameters to " +"the client, and the client updates the local model with the parameters " +"received from the server. It then trains the model on the local data " +"(which changes the model parameters locally) and sends the " +"updated/changed model parameters back to the server (or, alternatively, " +"it sends just the gradients back to the server, not the full model " +"parameters)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" "We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the " -"local model: ``set_parameters`` and ``get_parameters``. The following two " -"functions do just that for the PyTorch model above." +"received from the server and to get the updated model parameters from the" +" local model: ``set_parameters`` and ``get_parameters``. The following " +"two functions do just that for the PyTorch model above." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 msgid "" -"The details of how this works are not really important here (feel free to " -"consult the PyTorch documentation if you want to learn more). In essence, we " -"use ``state_dict`` to access PyTorch model parameter tensors. The parameter " -"tensors are then converted to/from a list of NumPy ndarray's (which Flower " -"knows how to serialize/deserialize):" +"The details of how this works are not really important here (feel free to" +" consult the PyTorch documentation if you want to learn more). In " +"essence, we use ``state_dict`` to access PyTorch model parameter tensors." +" The parameter tensors are then converted to/from a list of NumPy " +"ndarray's (which Flower knows how to serialize/deserialize):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 @@ -19322,18 +20508,19 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"With that out of the way, let's move on to the interesting part. Federated " -"learning systems consist of a server and multiple clients. In Flower, we " -"create clients by implementing subclasses of ``flwr.client.Client`` or " -"``flwr.client.NumPyClient``. We use ``NumPyClient`` in this tutorial because " -"it is easier to implement and requires us to write less boilerplate." +"With that out of the way, let's move on to the interesting part. " +"Federated learning systems consist of a server and multiple clients. In " +"Flower, we create clients by implementing subclasses of " +"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " +"``NumPyClient`` in this tutorial because it is easier to implement and " +"requires us to write less boilerplate." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"To implement the Flower client, we create a subclass of ``flwr.client." -"NumPyClient`` and implement the three methods ``get_parameters``, ``fit``, " -"and ``evaluate``:" +"To implement the Flower client, we create a subclass of " +"``flwr.client.NumPyClient`` and implement the three methods " +"``get_parameters``, ``fit``, and ``evaluate``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 @@ -19343,14 +20530,15 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" "``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters to " -"the server" +"parameters on the local data, and return the (updated) model parameters " +"to the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the model " -"parameters on the local data, and return the evaluation result to the server" +"``evaluate``: Receive model parameters from the server, evaluate the " +"model parameters on the local data, and return the evaluation result to " +"the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 @@ -19363,15 +20551,16 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" "Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through " -"``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a " -"*single client* in our federated learning system. Federated learning systems " -"have multiple clients (otherwise, there's not much to federate), so each " -"client will be represented by its own instance of ``FlowerClient``. If we " -"have, for example, three clients in our workload, then we'd have three " -"instances of ``FlowerClient``. Flower calls ``FlowerClient.fit`` on the " -"respective instance when the server selects a particular client for training " -"(and ``FlowerClient.evaluate`` for evaluation)." +"performed and allows Flower to call the local training/evaluation through" +" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" +" *single client* in our federated learning system. Federated learning " +"systems have multiple clients (otherwise, there's not much to federate), " +"so each client will be represented by its own instance of " +"``FlowerClient``. If we have, for example, three clients in our workload," +" then we'd have three instances of ``FlowerClient``. Flower calls " +"``FlowerClient.fit`` on the respective instance when the server selects a" +" particular client for training (and ``FlowerClient.evaluate`` for " +"evaluation)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 @@ -19380,13 +20569,13 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In this notebook, we want to simulate a federated learning system with 10 " -"clients on a single machine. This means that the server and all 10 clients " -"will live on a single machine and share resources such as CPU, GPU, and " -"memory. Having 10 clients would mean having 10 instances of ``FlowerClient`` " -"in memory. Doing this on a single machine can quickly exhaust the available " -"memory resources, even if only a subset of these clients participates in a " -"single round of federated learning." +"In this notebook, we want to simulate a federated learning system with 10" +" clients on a single machine. This means that the server and all 10 " +"clients will live on a single machine and share resources such as CPU, " +"GPU, and memory. Having 10 clients would mean having 10 instances of " +"``FlowerClient`` in memory. Doing this on a single machine can quickly " +"exhaust the available memory resources, even if only a subset of these " +"clients participates in a single round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 @@ -19395,14 +20584,14 @@ msgid "" "multiple machines, Flower, therefore, provides special simulation " "capabilities that create ``FlowerClient`` instances only when they are " "actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a function " -"called ``client_fn`` that creates a ``FlowerClient`` instance on demand. " -"Flower calls ``client_fn`` whenever it needs an instance of one particular " -"client to call ``fit`` or ``evaluate`` (those instances are usually " -"discarded after use, so they should not keep any local state). Clients are " -"identified by a client ID, or short ``cid``. The ``cid`` can be used, for " -"example, to load different local data partitions for different clients, as " -"can be seen below:" +"framework to create clients when necessary, we need to implement a " +"function called ``client_fn`` that creates a ``FlowerClient`` instance on" +" demand. Flower calls ``client_fn`` whenever it needs an instance of one " +"particular client to call ``fit`` or ``evaluate`` (those instances are " +"usually discarded after use, so they should not keep any local state). " +"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " +"be used, for example, to load different local data partitions for " +"different clients, as can be seen below:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 @@ -19411,31 +20600,31 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"We now have the class ``FlowerClient`` which defines client-side training/" -"evaluation and ``client_fn`` which allows Flower to create ``FlowerClient`` " -"instances whenever it needs to call ``fit`` or ``evaluate`` on one " -"particular client. The last step is to start the actual simulation using " -"``flwr.simulation.start_simulation``." +"We now have the class ``FlowerClient`` which defines client-side " +"training/evaluation and ``client_fn`` which allows Flower to create " +"``FlowerClient`` instances whenever it needs to call ``fit`` or " +"``evaluate`` on one particular client. The last step is to start the " +"actual simulation using ``flwr.simulation.start_simulation``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 msgid "" "The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the number " -"of clients to simulate (``num_clients``), the number of federated learning " -"rounds (``num_rounds``), and the strategy. The strategy encapsulates the " -"federated learning approach/algorithm, for example, *Federated Averaging* " -"(FedAvg)." +"them the ``client_fn`` used to create ``FlowerClient`` instances, the " +"number of clients to simulate (``num_clients``), the number of federated " +"learning rounds (``num_rounds``), and the strategy. The strategy " +"encapsulates the federated learning approach/algorithm, for example, " +"*Federated Averaging* (FedAvg)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" "Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated " -"learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last step " -"is the actual call to ``start_simulation`` which - you guessed it - starts " -"the simulation:" +"strategy implementations to customize nearly all aspects of the federated" +" learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last " +"step is the actual call to ``start_simulation`` which - you guessed it - " +"starts the simulation:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 @@ -19449,20 +20638,20 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 #, python-format msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 clients " -"(``num_clients=10``). Flower then goes ahead an asks the ``FedAvg`` strategy " -"to select clients. ``FedAvg`` knows that it should select 100% of the " -"available clients (``fraction_fit=1.0``), so it goes ahead and selects 10 " -"random clients (i.e., 100% of 10)." +"When we call ``start_simulation``, we tell Flower that there are 10 " +"clients (``num_clients=10``). Flower then goes ahead an asks the " +"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " +"select 100% of the available clients (``fraction_fit=1.0``), so it goes " +"ahead and selects 10 random clients (i.e., 100% of 10)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 msgid "" -"Flower then asks the selected 10 clients to train the model. When the server " -"receives the model parameter updates from the clients, it hands those " -"updates over to the strategy (*FedAvg*) for aggregation. The strategy " -"aggregates those updates and returns the new global model, which then gets " -"used in the next round of federated learning." +"Flower then asks the selected 10 clients to train the model. When the " +"server receives the model parameter updates from the clients, it hands " +"those updates over to the strategy (*FedAvg*) for aggregation. The " +"strategy aggregates those updates and returns the new global model, which" +" then gets used in the next round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 @@ -19471,27 +20660,28 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` are " -"empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"You may have noticed that all metrics except for ``losses_distributed`` " +"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 msgid "" -"Flower can automatically aggregate losses returned by individual clients, " -"but it cannot do the same for metrics in the generic metrics dictionary (the " -"one with the ``accuracy`` key). Metrics dictionaries can contain very " -"different kinds of metrics and even key/value pairs that are not metrics at " -"all, so the framework does not (and can not) know how to handle these " -"automatically." +"Flower can automatically aggregate losses returned by individual clients," +" but it cannot do the same for metrics in the generic metrics dictionary " +"(the one with the ``accuracy`` key). Metrics dictionaries can contain " +"very different kinds of metrics and even key/value pairs that are not " +"metrics at all, so the framework does not (and can not) know how to " +"handle these automatically." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 msgid "" -"As users, we need to tell the framework how to handle/aggregate these custom " -"metrics, and we do so by passing metric aggregation functions to the " -"strategy. The strategy will then call these functions whenever it receives " -"fit or evaluate metrics from clients. The two possible functions are " -"``fit_metrics_aggregation_fn`` and ``evaluate_metrics_aggregation_fn``." +"As users, we need to tell the framework how to handle/aggregate these " +"custom metrics, and we do so by passing metric aggregation functions to " +"the strategy. The strategy will then call these functions whenever it " +"receives fit or evaluate metrics from clients. The two possible functions" +" are ``fit_metrics_aggregation_fn`` and " +"``evaluate_metrics_aggregation_fn``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 @@ -19509,17 +20699,17 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 msgid "" "We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom " -"evaluation metrics and calculates a single ``accuracy`` metric across all " -"clients on the server side." +"evaluation. It uses the ``weighted_average`` function to aggregate custom" +" evaluation metrics and calculates a single ``accuracy`` metric across " +"all clients on the server side." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 msgid "" "The other two categories of metrics (``losses_centralized`` and " "``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial will " -"cover centralized evaluation." +"centralized evaluation is being used. Part two of the Flower tutorial " +"will cover centralized evaluation." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 @@ -19529,28 +20719,28 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 msgid "" -"Congratulations, you just trained a convolutional neural network, federated " -"over 10 clients! With that, you understand the basics of federated learning " -"with Flower. The same approach you've seen can be used with other machine " -"learning frameworks (not just PyTorch) and tasks (not just CIFAR-10 images " -"classification), for example NLP with Hugging Face Transformers or speech " -"with SpeechBrain." +"Congratulations, you just trained a convolutional neural network, " +"federated over 10 clients! With that, you understand the basics of " +"federated learning with Flower. The same approach you've seen can be used" +" with other machine learning frameworks (not just PyTorch) and tasks (not" +" just CIFAR-10 images classification), for example NLP with Hugging Face " +"Transformers or speech with SpeechBrain." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. Want " -"to customize your strategy? Initialize parameters on the server side? Or " -"evaluate the aggregated model on the server side? We'll cover all this and " -"more in the next tutorial." +"In the next notebook, we're going to cover some more advanced concepts. " +"Want to customize your strategy? Initialize parameters on the server " +"side? Or evaluate the aggregated model on the server side? We'll cover " +"all this and more in the next tutorial." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 `__ goes " -"into more depth about strategies and all the advanced things you can build " -"with them." +"The `Flower Federated Learning Tutorial - Part 2 " +"`__ goes into more depth about strategies and all " +"the advanced things you can build with them." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 @@ -19560,16 +20750,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 msgid "" "Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and " -"Flower (`part 1 `__)." +"parts of this tutorial, we introduced federated learning with PyTorch and" +" Flower (`part 1 `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 msgid "" -"In this notebook, we'll begin to customize the federated learning system we " -"built in the introductory notebook (again, using `Flower `__ and `PyTorch `__)." +"In this notebook, we'll begin to customize the federated learning system " +"we built in the introductory notebook (again, using `Flower " +"`__ and `PyTorch `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 @@ -19583,8 +20773,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 msgid "" "So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of new " -"features." +"introductory notebook. With that, we're ready to introduce a number of " +"new features." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 @@ -19593,16 +20783,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 msgid "" -"Flower, by default, initializes the global model by asking one random client " -"for the initial parameters. In many cases, we want more control over " -"parameter initialization though. Flower therefore allows you to directly " -"pass the initial parameters to the Strategy:" +"Flower, by default, initializes the global model by asking one random " +"client for the initial parameters. In many cases, we want more control " +"over parameter initialization though. Flower therefore allows you to " +"directly pass the initial parameters to the Strategy:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower " -"from asking one of the clients for the initial parameters. If we look " +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" +" from asking one of the clients for the initial parameters. If we look " "closely, we can see that the logs do not show any calls to the " "``FlowerClient.get_parameters`` method." msgstr "" @@ -19613,17 +20803,17 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number of " -"arguments, amongst them the ``client_fn`` used to create ``FlowerClient`` " -"instances, the number of clients to simulate ``num_clients``, the number of " -"rounds ``num_rounds``, and the strategy." +"We've seen the function ``start_simulation`` before. It accepts a number " +"of arguments, amongst them the ``client_fn`` used to create " +"``FlowerClient`` instances, the number of clients to simulate " +"``num_clients``, the number of rounds ``num_rounds``, and the strategy." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 msgid "" "The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different strategy " -"this time:" +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " +"strategy this time:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 @@ -19632,9 +20822,9 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the client-" -"side. Client-side and server-side evaluation are similar in some ways, but " -"different in others." +"Flower can evaluate the aggregated model on the server-side or on the " +"client-side. Client-side and server-side evaluation are similar in some " +"ways, but different in others." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 @@ -19642,33 +20832,33 @@ msgid "" "**Centralized Evaluation** (or *server-side evaluation*) is conceptually " "simple: it works the same way that evaluation in centralized machine " "learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly aggregated " -"model after each round of training without having to send the model to " -"clients. We're also fortunate in the sense that our entire evaluation " -"dataset is available at all times." +"evaluation purposes, then that's great. We can evaluate the newly " +"aggregated model after each round of training without having to send the " +"model to clients. We're also fortunate in the sense that our entire " +"evaluation dataset is available at all times." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, but " -"also more powerful: it doesn't require a centralized dataset and allows us " -"to evaluate models over a larger set of data, which often yields more " -"realistic evaluation results. In fact, many scenarios require us to use " -"**Federated Evaluation** if we want to get representative evaluation results " -"at all. But this power comes at a cost: once we start to evaluate on the " -"client side, we should be aware that our evaluation dataset can change over " -"consecutive rounds of learning if those clients are not always available. " -"Moreover, the dataset held by each client can also change over consecutive " -"rounds. This can lead to evaluation results that are not stable, so even if " -"we would not change the model, we'd see our evaluation results fluctuate " -"over consecutive rounds." +"**Federated Evaluation** (or *client-side evaluation*) is more complex, " +"but also more powerful: it doesn't require a centralized dataset and " +"allows us to evaluate models over a larger set of data, which often " +"yields more realistic evaluation results. In fact, many scenarios require" +" us to use **Federated Evaluation** if we want to get representative " +"evaluation results at all. But this power comes at a cost: once we start " +"to evaluate on the client side, we should be aware that our evaluation " +"dataset can change over consecutive rounds of learning if those clients " +"are not always available. Moreover, the dataset held by each client can " +"also change over consecutive rounds. This can lead to evaluation results " +"that are not stable, so even if we would not change the model, we'd see " +"our evaluation results fluctuate over consecutive rounds." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 msgid "" "We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see how " -"we can evaluate aggregated model parameters on the server-side:" +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " +"how we can evaluate aggregated model parameters on the server-side:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 @@ -19677,48 +20867,50 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 msgid "" -"In some situations, we want to configure client-side execution (training, " -"evaluation) from the server-side. One example for that is the server asking " -"the clients to train for a certain number of local epochs. Flower provides a " -"way to send configuration values from the server to the clients using a " -"dictionary. Let's look at an example where the clients receive values from " -"the server through the ``config`` parameter in ``fit`` (``config`` is also " -"available in ``evaluate``). The ``fit`` method receives the configuration " -"dictionary through the ``config`` parameter and can then read values from " -"this dictionary. In this example, it reads ``server_round`` and " -"``local_epochs`` and uses those values to improve the logging and configure " -"the number of local training epochs:" +"In some situations, we want to configure client-side execution (training," +" evaluation) from the server-side. One example for that is the server " +"asking the clients to train for a certain number of local epochs. Flower " +"provides a way to send configuration values from the server to the " +"clients using a dictionary. Let's look at an example where the clients " +"receive values from the server through the ``config`` parameter in " +"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " +"method receives the configuration dictionary through the ``config`` " +"parameter and can then read values from this dictionary. In this example," +" it reads ``server_round`` and ``local_epochs`` and uses those values to " +"improve the logging and configure the number of local training epochs:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 msgid "" -"So how can we send this config dictionary from server to clients? The built-" -"in Flower Strategies provide way to do this, and it works similarly to the " -"way server-side evaluation works. We provide a function to the strategy, and " -"the strategy calls this function for every round of federated learning:" +"So how can we send this config dictionary from server to clients? The " +"built-in Flower Strategies provide way to do this, and it works similarly" +" to the way server-side evaluation works. We provide a function to the " +"strategy, and the strategy calls this function for every round of " +"federated learning:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before starting " -"the simulation:" +"Next, we'll just pass this function to the FedAvg strategy before " +"starting the simulation:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 msgid "" -"As we can see, the client logs now include the current round of federated " -"learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second " -"round of federated learning, and then for two epochs during the third round." +"As we can see, the client logs now include the current round of federated" +" learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second" +" round of federated learning, and then for two epochs during the third " +"round." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 msgid "" "Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and used " -"this concept throughout this notebook without mentioning it explicitly: our " -"``FlowerClient`` returns a dictionary containing a custom key/value pair as " -"the third return value in ``evaluate``." +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " +"used this concept throughout this notebook without mentioning it " +"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" +" key/value pair as the third return value in ``evaluate``." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 @@ -19735,13 +20927,14 @@ msgstr "" #, python-format msgid "" "We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is quite " -"small, we should probably train the model a bit longer, so we configure the " -"clients to perform 3 local training epochs. We should also adjust the " -"fraction of clients selected for training during each round (we don't want " -"all 1000 clients participating in every round), so we adjust " -"``fraction_fit`` to ``0.05``, which means that only 5% of available clients " -"(so 50 clients) will be selected for training each round:" +"examples. Given that the number of training examples on each client is " +"quite small, we should probably train the model a bit longer, so we " +"configure the clients to perform 3 local training epochs. We should also " +"adjust the fraction of clients selected for training during each round " +"(we don't want all 1000 clients participating in every round), so we " +"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " +"available clients (so 50 clients) will be selected for training each " +"round:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 @@ -19754,18 +20947,19 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 msgid "" -"In the later sections, we've seen how we can communicate arbitrary values " -"between server and clients to fully customize client-side execution. With " -"that capability, we built a large-scale Federated Learning simulation using " -"the Flower Virtual Client Engine and ran an experiment involving 1000 " -"clients in the same workload - all in a Jupyter Notebook!" +"In the later sections, we've seen how we can communicate arbitrary values" +" between server and clients to fully customize client-side execution. " +"With that capability, we built a large-scale Federated Learning " +"simulation using the Flower Virtual Client Engine and ran an experiment " +"involving 1000 clients in the same workload - all in a Jupyter Notebook!" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 `__ shows how " -"to build a fully custom ``Strategy`` from scratch." +"The `Flower Federated Learning Tutorial - Part 3 " +"`__ shows how to build a fully custom ``Strategy`` from " +"scratch." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 @@ -19776,24 +20970,24 @@ msgstr "" msgid "" "In this tutorial, you will learn what federated learning is, build your " "first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated learning " -"systems that approach the current state of the art in the field." +"parts of the tutorial, you will be able to build advanced federated " +"learning systems that approach the current state of the art in the field." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with federated " -"learning. Only a basic understanding of data science and Python programming " -"is assumed." +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " +"federated learning. Only a basic understanding of data science and Python" +" programming is assumed." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join the " -"open-source Flower community on Slack to connect, ask questions, and get " -"help: `Join Slack `__ 🌼 We'd love to hear " -"from you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join " +"the open-source Flower community on Slack to connect, ask questions, and " +"get help: `Join Slack `__ 🌼 We'd love to " +"hear from you in the ``#introductions`` channel! And if anything is " +"unclear, head over to the ``#questions`` channel." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 @@ -19802,19 +20996,19 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how most " -"machine learning works today." +"Before we begin to discuss federated learning, let us quickly recap how " +"most machine learning works today." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 msgid "" -"In machine learning, we have a model, and we have data. The model could be a " -"neural network (as depicted here), or something else, like classical linear " -"regression." +"In machine learning, we have a model, and we have data. The model could " +"be a neural network (as depicted here), or something else, like classical" +" linear regression." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgid "|93b02017c78049bbbd5ae456dcb2c91b|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 @@ -19823,13 +21017,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 msgid "" -"We train the model using the data to perform a useful task. A task could be " -"to detect objects in images, transcribe an audio recording, or play a game " -"like Go." +"We train the model using the data to perform a useful task. A task could " +"be to detect objects in images, transcribe an audio recording, or play a " +"game like Go." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgid "|01471150fd5144c080a176b43e92a3ff|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 @@ -19838,8 +21032,8 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 msgid "" -"Now, in practice, the training data we work with doesn't originate on the " -"machine we train the model on. It gets created somewhere else." +"Now, in practice, the training data we work with doesn't originate on the" +" machine we train the model on. It gets created somewhere else." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 @@ -19850,7 +21044,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|2bc8e069228d4873804061ff4a95048c|" +msgid "|9bc21c7dbd17444a8f070c60786e3484|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 @@ -19860,13 +21054,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 msgid "" "What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running " -"the same app. But it could also be several organizations, all generating " -"data for the same task." +"just one place, it's many places. It could be several devices all running" +" the same app. But it could also be several organizations, all generating" +" data for the same task." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +msgid "|3047bbce54b34099ae559963d0420d79|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 @@ -19875,13 +21069,14 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 msgid "" -"So to use machine learning, or any kind of data analysis, the approach that " -"has been used in the past was to collect all data on a central server. This " -"server can be somewhere in a data center, or somewhere in the cloud." +"So to use machine learning, or any kind of data analysis, the approach " +"that has been used in the past was to collect all data on a central " +"server. This server can be somewhere in a data center, or somewhere in " +"the cloud." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|d5f962c3f4ec48529efda980868c14b0|" +msgid "|e9f8ce948593444fb838d2f354c7ec5d|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 @@ -19896,7 +21091,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|a5eccea18d4c43a68b54b65043cabef8|" +msgid "|c24c1478b30e4f74839208628a842d1e|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 @@ -19909,14 +21104,14 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 msgid "" -"The classic machine learning approach we've just seen can be used in some " -"cases. Great examples include categorizing holiday photos, or analyzing web " -"traffic. Cases, where all the data is naturally available on a centralized " -"server." +"The classic machine learning approach we've just seen can be used in some" +" cases. Great examples include categorizing holiday photos, or analyzing " +"web traffic. Cases, where all the data is naturally available on a " +"centralized server." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgid "|1b3613d7a58847b59e1d3180802dbc09|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 @@ -19925,13 +21120,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 msgid "" -"But the approach can not be used in many other cases. Cases, where the data " -"is not available on a centralized server, or cases where the data available " -"on one server is not enough to train a good model." +"But the approach can not be used in many other cases. Cases, where the " +"data is not available on a centralized server, or cases where the data " +"available on one server is not enough to train a good model." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|241fc906441a4f038c625a19d30d01b2|" +msgid "|9980b5213db547d0b8024a50992b9e3f|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 @@ -19940,9 +21135,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 msgid "" -"There are many reasons why the classic centralized machine learning approach " -"does not work for a large number of highly important real-world use cases. " -"Those reasons include:" +"There are many reasons why the classic centralized machine learning " +"approach does not work for a large number of highly important real-world " +"use cases. Those reasons include:" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 @@ -19952,32 +21147,32 @@ msgid "" "(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " "(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " "protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own users' " -"data for artificial intelligence training because those users live in " -"different parts of the world, and their data is governed by different data " -"protection regulations." +"sometimes even prevent single organizations from combining their own " +"users' data for artificial intelligence training because those users live" +" in different parts of the world, and their data is governed by different" +" data protection regulations." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 msgid "" -"**User preference**: In addition to regulation, there are use cases where " -"users just expect that no data leaves their device, ever. If you type your " -"passwords and credit card info into the digital keyboard of your phone, you " -"don't expect those passwords to end up on the server of the company that " -"developed that keyboard, do you? In fact, that use case was the reason " -"federated learning was invented in the first place." +"**User preference**: In addition to regulation, there are use cases where" +" users just expect that no data leaves their device, ever. If you type " +"your passwords and credit card info into the digital keyboard of your " +"phone, you don't expect those passwords to end up on the server of the " +"company that developed that keyboard, do you? In fact, that use case was " +"the reason federated learning was invented in the first place." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data volume " -"that it is neither feasible nor economic to collect all the data (due to, " -"for example, bandwidth or communication efficiency). Think about a national " -"rail service with hundreds of train stations across the country. If each of " -"these train stations is outfitted with a number of security cameras, the " -"volume of raw on-device data they produce requires incredibly powerful and " -"exceedingly expensive infrastructure to process and store. And most of the " -"data isn't even useful." +"**Data volume**: Some sensors, like cameras, produce such a high data " +"volume that it is neither feasible nor economic to collect all the data " +"(due to, for example, bandwidth or communication efficiency). Think about" +" a national rail service with hundreds of train stations across the " +"country. If each of these train stations is outfitted with a number of " +"security cameras, the volume of raw on-device data they produce requires " +"incredibly powerful and exceedingly expensive infrastructure to process " +"and store. And most of the data isn't even useful." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 @@ -19992,7 +21187,8 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 msgid "" -"Financial information from different organizations to detect financial fraud" +"Financial information from different organizations to detect financial " +"fraud" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 @@ -20005,13 +21201,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 msgid "" -"The popularity of privacy-enhancing systems like the `Brave `__ browser or the `Signal `__ messenger shows " -"that users care about privacy. In fact, they choose the privacy-enhancing " -"version over other alternatives, if such an alternative exists. But what can " -"we do to apply machine learning and data science to these cases to utilize " -"private data? After all, these are all areas that would benefit " -"significantly from recent advances in AI." +"The popularity of privacy-enhancing systems like the `Brave " +"`__ browser or the `Signal `__ " +"messenger shows that users care about privacy. In fact, they choose the " +"privacy-enhancing version over other alternatives, if such an alternative" +" exists. But what can we do to apply machine learning and data science to" +" these cases to utilize private data? After all, these are all areas that" +" would benefit significantly from recent advances in AI." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 @@ -20021,8 +21217,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 msgid "" "Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead of " -"moving the data to the training. Here's the single-sentence explanation:" +"learning on distributed data by moving the training to the data, instead " +"of moving the data to the training. Here's the single-sentence " +"explanation:" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 @@ -20035,22 +21232,22 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 msgid "" -"By doing so, it enables us to use machine learning (and other data science " -"approaches) in areas where it wasn't possible before. We can now train " -"excellent medical AI models by enabling different hospitals to work " -"together. We can solve financial fraud by training AI models on the data of " -"different financial institutions. We can build novel privacy-enhancing " -"applications (such as secure messaging) that have better built-in AI than " -"their non-privacy-enhancing alternatives. And those are just a few of the " -"examples that come to mind. As we deploy federated learning, we discover " -"more and more areas that can suddenly be reinvented because they now have " -"access to vast amounts of previously inaccessible data." +"By doing so, it enables us to use machine learning (and other data " +"science approaches) in areas where it wasn't possible before. We can now " +"train excellent medical AI models by enabling different hospitals to work" +" together. We can solve financial fraud by training AI models on the data" +" of different financial institutions. We can build novel privacy-" +"enhancing applications (such as secure messaging) that have better built-" +"in AI than their non-privacy-enhancing alternatives. And those are just a" +" few of the examples that come to mind. As we deploy federated learning, " +"we discover more and more areas that can suddenly be reinvented because " +"they now have access to vast amounts of previously inaccessible data." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 msgid "" -"So how does federated learning work, exactly? Let's start with an intuitive " -"explanation." +"So how does federated learning work, exactly? Let's start with an " +"intuitive explanation." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 @@ -20063,13 +21260,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 msgid "" -"We start by initializing the model on the server. This is exactly the same " -"in classic centralized learning: we initialize the model parameters, either " -"randomly or from a previously saved checkpoint." +"We start by initializing the model on the server. This is exactly the " +"same in classic centralized learning: we initialize the model parameters," +" either randomly or from a previously saved checkpoint." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|0aa5aa05810b44b6a835cecce28f3137|" +msgid "|c7afb4c92d154bfaa5e8cb9a150e17f1|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 @@ -20078,22 +21275,22 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client " -"nodes)" +"Step 1: Send model to a number of connected organizations/devices (client" +" nodes)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 msgid "" "Next, we send the parameters of the global model to the connected client " "nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts their " -"local training using the same model parameters. We often use only a few of " -"the connected nodes instead of all nodes. The reason for this is that " -"selecting more and more client nodes has diminishing returns." +"organizations). This is to ensure that each participating node starts " +"their local training using the same model parameters. We often use only a" +" few of the connected nodes instead of all nodes. The reason for this is " +"that selecting more and more client nodes has diminishing returns." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +msgid "|032eb6fed6924ac387b9f13854919196|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 @@ -20102,22 +21299,22 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 msgid "" -"Step 2: Train model locally on the data of each organization/device (client " -"node)" +"Step 2: Train model locally on the data of each organization/device " +"(client node)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 msgid "" -"Now that all (selected) client nodes have the latest version of the global " -"model parameters, they start the local training. They use their own local " -"dataset to train their own local model. They don't train the model until " -"full convergence, but they only train for a little while. This could be as " -"little as one epoch on the local data, or even just a few steps (mini-" -"batches)." +"Now that all (selected) client nodes have the latest version of the " +"global model parameters, they start the local training. They use their " +"own local dataset to train their own local model. They don't train the " +"model until full convergence, but they only train for a little while. " +"This could be as little as one epoch on the local data, or even just a " +"few steps (mini-batches)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +msgid "|fbf225add7fd4df5a9bf25a95597d954|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 @@ -20130,16 +21327,17 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 msgid "" -"After local training, each client node has a slightly different version of " -"the model parameters they originally received. The parameters are all " +"After local training, each client node has a slightly different version " +"of the model parameters they originally received. The parameters are all " "different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the server. " -"The model updates they send can either be the full model parameters or just " -"the gradients that were accumulated during local training." +"dataset. The client nodes then send those model updates back to the " +"server. The model updates they send can either be the full model " +"parameters or just the gradients that were accumulated during local " +"training." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgid "|7efbe3d29d8349b89594e8947e910525|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 @@ -20153,30 +21351,31 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 msgid "" "The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of the " -"original global model, each trained on the local data of one client. But " -"didn't we want to have one model that contains the learnings from the data " -"of all 100 client nodes?" +"selected 100 client nodes, it now has 100 slightly different versions of " +"the original global model, each trained on the local data of one client. " +"But didn't we want to have one model that contains the learnings from the" +" data of all 100 client nodes?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 msgid "" -"In order to get one single model, we have to combine all the model updates " -"we received from the client nodes. This process is called *aggregation*, and " -"there are many different ways to do it. The most basic way to do it is " -"called *Federated Averaging* (`McMahan et al., 2016 `__), often abbreviated as *FedAvg*. *FedAvg* takes the 100 " -"model updates and, as the name suggests, averages them. To be more precise, " -"it takes the *weighted average* of the model updates, weighted by the number " -"of examples each client used for training. The weighting is important to " -"make sure that each data example has the same \"influence\" on the resulting " -"global model. If one client has 10 examples, and another client has 100 " -"examples, then - without weighting - each of the 10 examples would influence " -"the global model ten times as much as each of the 100 examples." +"In order to get one single model, we have to combine all the model " +"updates we received from the client nodes. This process is called " +"*aggregation*, and there are many different ways to do it. The most basic" +" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " +"`__), often abbreviated as *FedAvg*. " +"*FedAvg* takes the 100 model updates and, as the name suggests, averages " +"them. To be more precise, it takes the *weighted average* of the model " +"updates, weighted by the number of examples each client used for " +"training. The weighting is important to make sure that each data example " +"has the same \"influence\" on the resulting global model. If one client " +"has 10 examples, and another client has 100 examples, then - without " +"weighting - each of the 10 examples would influence the global model ten " +"times as much as each of the 100 examples." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|72939caf6e294b0986fee6dde96614d7|" +msgid "|329fb3c04c744eda83bb51fa444c2266|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 @@ -20190,39 +21389,41 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 msgid "" "Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step 1), " -"the client nodes train on their local data (step 2), they send their updated " -"models to the server (step 3), and the server then aggregates the model " -"updates to get a new version of the global model (step 4)." +"global model parameters get sent to the participating client nodes (step " +"1), the client nodes train on their local data (step 2), they send their " +"updated models to the server (step 3), and the server then aggregates the" +" model updates to get a new version of the global model (step 4)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 msgid "" -"During a single round, each client node that participates in that iteration " -"only trains for a little while. This means that after the aggregation step " -"(step 4), we have a model that has been trained on all the data of all " -"participating client nodes, but only for a little while. We then have to " -"repeat this training process over and over again to eventually arrive at a " -"fully trained model that performs well across the data of all client nodes." +"During a single round, each client node that participates in that " +"iteration only trains for a little while. This means that after the " +"aggregation step (step 4), we have a model that has been trained on all " +"the data of all participating client nodes, but only for a little while. " +"We then have to repeat this training process over and over again to " +"eventually arrive at a fully trained model that performs well across the " +"data of all client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 msgid "" "Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning in " -"a nutshell. In later parts of this tutorial, we will go into more detail. " -"Interesting questions include: How can we select the best client nodes that " -"should participate in the next round? What's the best way to aggregate model " -"updates? How can we handle failing client nodes (stragglers)?" +"There's a lot more to discuss, of course, but that was federated learning" +" in a nutshell. In later parts of this tutorial, we will go into more " +"detail. Interesting questions include: How can we select the best client " +"nodes that should participate in the next round? What's the best way to " +"aggregate model updates? How can we handle failing client nodes " +"(stragglers)?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 msgid "" -"Just like we can train a model on the decentralized data of different client " -"nodes, we can also evaluate the model on that data to receive valuable " -"metrics. This is called federated evaluation, sometimes abbreviated as FE. " -"In fact, federated evaluation is an integral part of most federated learning " -"systems." +"Just like we can train a model on the decentralized data of different " +"client nodes, we can also evaluate the model on that data to receive " +"valuable metrics. This is called federated evaluation, sometimes " +"abbreviated as FE. In fact, federated evaluation is an integral part of " +"most federated learning systems." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 @@ -20231,24 +21432,25 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 msgid "" -"In many cases, machine learning isn't necessary to derive value from data. " -"Data analysis can yield valuable insights, but again, there's often not " -"enough data to get a clear answer. What's the average age at which people " -"develop a certain type of health condition? Federated analytics enables such " -"queries over multiple client nodes. It is usually used in conjunction with " -"other privacy-enhancing technologies like secure aggregation to prevent the " -"server from seeing the results submitted by individual client nodes." +"In many cases, machine learning isn't necessary to derive value from " +"data. Data analysis can yield valuable insights, but again, there's often" +" not enough data to get a clear answer. What's the average age at which " +"people develop a certain type of health condition? Federated analytics " +"enables such queries over multiple client nodes. It is usually used in " +"conjunction with other privacy-enhancing technologies like secure " +"aggregation to prevent the server from seeing the results submitted by " +"individual client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 msgid "" "Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and sharing " -"statistical data, ensuring the privacy of individual participants. DP " -"achieves this by adding statistical noise to the model updates, ensuring any " -"individual participants’ information cannot be distinguished or re-" -"identified. This technique can be considered an optimization that provides a " -"quantifiable privacy protection measure." +"Learning. It is a privacy-preserving method used when analyzing and " +"sharing statistical data, ensuring the privacy of individual " +"participants. DP achieves this by adding statistical noise to the model " +"updates, ensuring any individual participants’ information cannot be " +"distinguished or re-identified. This technique can be considered an " +"optimization that provides a quantifiable privacy protection measure." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 @@ -20257,40 +21459,360 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 msgid "" -"Federated learning, federated evaluation, and federated analytics require " -"infrastructure to move machine learning models back and forth, train and " -"evaluate them on local data, and then aggregate the updated models. Flower " -"provides the infrastructure to do exactly that in an easy, scalable, and " -"secure way. In short, Flower presents a unified approach to federated " -"learning, analytics, and evaluation. It allows the user to federate any " -"workload, any ML framework, and any programming language." +"Federated learning, federated evaluation, and federated analytics require" +" infrastructure to move machine learning models back and forth, train and" +" evaluate them on local data, and then aggregate the updated models. " +"Flower provides the infrastructure to do exactly that in an easy, " +"scalable, and secure way. In short, Flower presents a unified approach to" +" federated learning, analytics, and evaluation. It allows the user to " +"federate any workload, any ML framework, and any programming language." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +msgid "|c00bf2750bc24d229737a0fe1395f0fc|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal " -"computer, roomba, and phone)" +"Flower federated learning server and client nodes (car, scooter, personal" +" computer, roomba, and phone)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 msgid "" -"Congratulations, you just learned the basics of federated learning and how " -"it relates to the classic (centralized) machine learning!" +"Congratulations, you just learned the basics of federated learning and " +"how it relates to the classic (centralized) machine learning!" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 msgid "" -"In the next part of this tutorial, we are going to build a first federated " -"learning system with Flower." +"In the next part of this tutorial, we are going to build a first " +"federated learning system with Flower." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 msgid "" -"The `Flower Federated Learning Tutorial - Part 1 `__ shows how to " -"build a simple federated learning system with PyTorch and Flower." -msgstr "" +"The `Flower Federated Learning Tutorial - Part 1 " +"`__ shows how to build a simple federated learning system " +"with PyTorch and Flower." +msgstr "" + +#~ msgid "" +#~ "Currently, Flower provides two images, a" +#~ " ``base`` image and a ``superlink`` " +#~ "image. The base image, as the name" +#~ " suggests, contains basic dependencies that" +#~ " the SuperLink needs. This includes " +#~ "system dependencies, Python and Python " +#~ "tools. The SuperLink image is based " +#~ "on the base image, but it " +#~ "additionally installs the SuperLink using " +#~ "``pip``." +#~ msgstr "" +#~ "현재, Flower는 \"base\" 이미지 그리고 " +#~ "\"superlink\" 이미지를 제공합니다. base 이미지는 이름에서" +#~ " 알 수 있듯이 SuperLink가 필요로 하는 기본" +#~ " dependencies를 포함하고 있습니다. 여기에는 시스템 " +#~ "dependencies, Python 및 Python 도구가 포함됩니다." +#~ " SuperLink 이미지는 base 이미지를 기반으로 하지만" +#~ " \"pip\"을 사용하여 SuperLink를 추가로 설치합니다." + +#~ msgid "``3.11``" +#~ msgstr "``3.11``" + +#~ msgid "Defaults to ``22.04``." +#~ msgstr "``22.04``이 기본값." + +#~ msgid "Defaults to ``flwr/base``." +#~ msgstr "``flwr/base``이 기본값." + +#~ msgid "The Python version of the base image." +#~ msgstr "base 이미지의 Python 버전." + +#~ msgid "Defaults to ``py3.11``." +#~ msgstr "``py3.11``이 기본값." + +#~ msgid "Defaults to ``ubuntu22.04``." +#~ msgstr "``ubuntu22.04``이 기본값." + +#~ msgid "Defaults to ``flwr``." +#~ msgstr "``flwr``이 기본값." + +#~ msgid "" +#~ "The name of image is ``flwr_superlink``" +#~ " and the tag ``0.1.0``. Remember that" +#~ " the build arguments as well as " +#~ "the name and tag can be adapted" +#~ " to your needs. These values serve" +#~ " as examples only." +#~ msgstr "" +#~ "이미지의 이름은 ``flwr_superlink``이고 태그는 " +#~ "``0.1.0``입니다. 필요에 따라 빌드 argument들 뿐만 " +#~ "아니라 이름과 태그도 정할 수 있습니다. 이 값들은" +#~ " 예시일 뿐입니다." + +#~ msgid "Creating New Messages" +#~ msgstr "" + +#~ msgid "" +#~ "This is a simple guide for " +#~ "creating a new type of message " +#~ "between the server and clients in " +#~ "Flower." +#~ msgstr "" + +#~ msgid "" +#~ "Let's suppose we have the following " +#~ "example functions in :code:`server.py` and " +#~ ":code:`numpy_client.py`..." +#~ msgstr "" + +#~ msgid "Server's side:" +#~ msgstr "" + +#~ msgid "Client's side:" +#~ msgstr "" + +#~ msgid "" +#~ "Let's now see what we need to " +#~ "implement in order to get this " +#~ "simple function between the server and" +#~ " client to work!" +#~ msgstr "" + +#~ msgid "Message Types for Protocol Buffers" +#~ msgstr "" + +#~ msgid "" +#~ "The first thing we need to do " +#~ "is to define a message type for" +#~ " the RPC system in :code:`transport.proto`." +#~ " Note that we have to do it " +#~ "for both the request and response " +#~ "messages. For more details on the " +#~ "syntax of proto3, please see the " +#~ "`official documentation `_." +#~ msgstr "" + +#~ msgid "Within the :code:`ServerMessage` block:" +#~ msgstr "" + +#~ msgid "Within the ClientMessage block:" +#~ msgstr "" + +#~ msgid "" +#~ "Make sure to also add a field " +#~ "of the newly created message type " +#~ "in :code:`oneof msg`." +#~ msgstr "" + +#~ msgid "Once that is done, we will compile the file with:" +#~ msgstr "" + +#~ msgid "If it compiles successfully, you should see the following message:" +#~ msgstr "" + +#~ msgid "Serialization and Deserialization Functions" +#~ msgstr "" + +#~ msgid "" +#~ "Our next step is to add functions" +#~ " to serialize and deserialize Python " +#~ "datatypes to or from our defined " +#~ "RPC message types. You should add " +#~ "these functions in :code:`serde.py`." +#~ msgstr "" + +#~ msgid "The four functions:" +#~ msgstr "" + +#~ msgid "Sending the Message from the Server" +#~ msgstr "" + +#~ msgid "" +#~ "Now write the request function in " +#~ "your Client Proxy class (e.g., " +#~ ":code:`grpc_client_proxy.py`) using the serde " +#~ "functions you just created:" +#~ msgstr "" + +#~ msgid "Receiving the Message by the Client" +#~ msgstr "" + +#~ msgid "" +#~ "Last step! Modify the code in " +#~ ":code:`message_handler.py` to check the field" +#~ " of your message and call the " +#~ ":code:`example_response` function. Remember to " +#~ "use the serde functions!" +#~ msgstr "" + +#~ msgid "Within the handle function:" +#~ msgstr "" + +#~ msgid "And add a new function:" +#~ msgstr "" + +#~ msgid "Hopefully, when you run your program you will get the intended result!" +#~ msgstr "" + +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to persist the state" +#~ " of the SuperLink on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``--volume``" +#~ " to mount the user's home directory" +#~ " (``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." +#~ msgstr "" + +#~ msgid "" +#~ "As soon as the SuperLink starts, " +#~ "the file ``state.db`` is created in " +#~ "the user's home directory on your " +#~ "host system. If the file already " +#~ "exists, the SuperLink tries to restore" +#~ " the state from the file. To " +#~ "start the SuperLink with an empty " +#~ "database, simply remove the ``state.db`` " +#~ "file." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``--volume`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the SuperLink to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the SuperLink with the" +#~ " ``--certificates`` flag." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9092``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Fleet" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the SuperNode to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9091``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Driver" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the ServerApp to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to use a different " +#~ "version of Flower, for example Flower" +#~ " nightly, you can do so by " +#~ "changing the tag. All available versions" +#~ " are on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "Here's another example to start with " +#~ "HTTPS. Use the ``--certificates`` command " +#~ "line argument to pass paths to (CA" +#~ " certificate, server certificate, and " +#~ "server private key)." +#~ msgstr "" + +#~ msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Driver API)." +#~ msgstr "" + +#~ msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Fleet API)." +#~ msgstr "" + +#~ msgid "Unreleased" +#~ msgstr "" + +#~ msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +#~ msgstr "" + +#~ msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +#~ msgstr "" + +#~ msgid "|2bc8e069228d4873804061ff4a95048c|" +#~ msgstr "" + +#~ msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +#~ msgstr "" + +#~ msgid "|d5f962c3f4ec48529efda980868c14b0|" +#~ msgstr "" + +#~ msgid "|a5eccea18d4c43a68b54b65043cabef8|" +#~ msgstr "" + +#~ msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +#~ msgstr "" + +#~ msgid "|241fc906441a4f038c625a19d30d01b2|" +#~ msgstr "" + +#~ msgid "|0aa5aa05810b44b6a835cecce28f3137|" +#~ msgstr "" + +#~ msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +#~ msgstr "" + +#~ msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +#~ msgstr "" + +#~ msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +#~ msgstr "" + +#~ msgid "|72939caf6e294b0986fee6dde96614d7|" +#~ msgstr "" + +#~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +#~ msgstr "" + diff --git a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po index f0127ad93ed7..49bb01908421 100644 --- a/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po +++ b/doc/locales/pt_BR/LC_MESSAGES/framework-docs.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-28 11:47+0200\n" +"POT-Creation-Date: 2024-06-17 16:09+0200\n" "PO-Revision-Date: 2024-05-25 11:09+0000\n" "Last-Translator: Gustavo Bertoli \n" "Language: pt_BR\n" @@ -70,10 +70,11 @@ msgstr "Como construir imagens Docker do Flower localmente" msgid "" "Flower provides pre-made docker images on `Docker Hub " "`_ that include all necessary dependencies" -" for running the SuperLink. You can also build your own custom docker " -"images from scratch with a different version of Python or Ubuntu if that " -"is what you need. In this guide, we will explain what images exist and " -"how to build them locally." +" for running the SuperLink, SuperNode or ServerApp. You can also build " +"your own custom docker images from scratch with a different version of " +"Python or Linux distribution (Ubuntu/Alpine) if that is what you need. In" +" this guide, we will explain what images exist and how to build them " +"locally." msgstr "" "Flower disponibiliza imagens docker em `Docker Hub " "`_ que incluem todas as " @@ -82,7 +83,7 @@ msgstr "" " diferente do Python ou do Ubuntu se isso for o que você precisa. Neste " "guia, explicaremos quais imagens existem e como compilar localmente." -#: ../../source/contributor-how-to-build-docker-images.rst:9 +#: ../../source/contributor-how-to-build-docker-images.rst:10 msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." @@ -90,17 +91,17 @@ msgstr "" "Antes de começarmos, precisamos encontrar alguns pré-requisitos em nosso " "ambiente de desenvolvimento local." -#: ../../source/contributor-how-to-build-docker-images.rst:11 +#: ../../source/contributor-how-to-build-docker-images.rst:12 msgid "Clone the flower repository." msgstr "Clone o repositório do flower." -#: ../../source/contributor-how-to-build-docker-images.rst:17 -#: ../../source/how-to-run-flower-using-docker.rst:144 +#: ../../source/contributor-how-to-build-docker-images.rst:18 +#: ../../source/how-to-run-flower-using-docker.rst:165 msgid "Verify the Docker daemon is running." msgstr "Verifique que o serviço Docker está rodando." -#: ../../source/contributor-how-to-build-docker-images.rst:19 -#: ../../source/how-to-run-flower-using-docker.rst:146 +#: ../../source/contributor-how-to-build-docker-images.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:167 msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." @@ -108,23 +109,7 @@ msgstr "" "Por favor, siga a primeira seção em :doc:`Execute o Flower usando Docker " "` que cobre este passo em mais detalhes." -#: ../../source/contributor-how-to-build-docker-images.rst:23 -#, fuzzy -msgid "" -"Currently, Flower provides two images, a ``base`` image and a " -"``superlink`` image. The base image, as the name suggests, contains basic" -" dependencies that the SuperLink needs. This includes system " -"dependencies, Python and Python tools. The SuperLink image is based on " -"the base image, but it additionally installs the SuperLink using ``pip``." -msgstr "" -"Atualmente, Flower fornece duas imagens, uma imagem base e uma imagem de " -"servidor. Também haverá uma imagem de cliente em breve. A imagem base, " -"como o nome sugere, contém dependências básicas que tanto o servidor " -"quanto o cliente precisam. Isso inclui dependências do sistema, Python e " -"ferramentas Python. A imagem do servidor é baseada na imagem base, mas " -"também instala o servidor Flower usando ``pip```." - -#: ../../source/contributor-how-to-build-docker-images.rst:28 +#: ../../source/contributor-how-to-build-docker-images.rst:25 msgid "" "The build instructions that assemble the images are located in the " "respective Dockerfiles. You can find them in the subdirectories of " @@ -134,16 +119,16 @@ msgstr "" "respectivos Dockerfiles. Você pode encontrá-los nos subdiretórios " "``src/docker```." -#: ../../source/contributor-how-to-build-docker-images.rst:31 +#: ../../source/contributor-how-to-build-docker-images.rst:28 #, fuzzy msgid "" -"Both, base and SuperLink image are configured via build arguments. " -"Through build arguments, we can make our build more flexible. For " -"example, in the base image, we can specify the version of Python to " -"install using the ``PYTHON_VERSION`` build argument. Some of the build " -"arguments have default values, others must be specified when building the" -" image. All available build arguments for each image are listed in one of" -" the tables below." +"Flower Docker images are configured via build arguments. Through build " +"arguments, we can make the creation of images more flexible. For example," +" in the base image, we can specify the version of Python to install using" +" the ``PYTHON_VERSION`` build argument. Some of the build arguments have " +"default values, others must be specified when building the image. All " +"available build arguments for each image are listed in one of the tables " +"below." msgstr "" "Ambas, imagens base e do servidor são configuradas através dos argumentos" " de compilação. Através dos argumentos de compilação, podemos tornar " @@ -154,96 +139,146 @@ msgstr "" "Todos os argumentos de compilação disponíveis para cada imagem estão " "listados em uma das tabelas abaixo." -#: ../../source/contributor-how-to-build-docker-images.rst:38 +#: ../../source/contributor-how-to-build-docker-images.rst:35 msgid "Building the base image" msgstr "Construindo a imagem base" -#: ../../source/contributor-how-to-build-docker-images.rst:44 -#: ../../source/contributor-how-to-build-docker-images.rst:86 +#: ../../source/contributor-how-to-build-docker-images.rst:41 +#: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "Build argument" msgstr "Argumento de compilação" -#: ../../source/contributor-how-to-build-docker-images.rst:45 -#: ../../source/contributor-how-to-build-docker-images.rst:87 +#: ../../source/contributor-how-to-build-docker-images.rst:42 +#: ../../source/contributor-how-to-build-docker-images.rst:99 msgid "Description" msgstr "Descrição" -#: ../../source/contributor-how-to-build-docker-images.rst:46 -#: ../../source/contributor-how-to-build-docker-images.rst:88 +#: ../../source/contributor-how-to-build-docker-images.rst:43 +#: ../../source/contributor-how-to-build-docker-images.rst:100 msgid "Required" msgstr "Necessário" -#: ../../source/contributor-how-to-build-docker-images.rst:47 -#: ../../source/contributor-how-to-build-docker-images.rst:89 +#: ../../source/contributor-how-to-build-docker-images.rst:44 +#: ../../source/contributor-how-to-build-docker-images.rst:101 msgid "Example" msgstr "Exemplo" +#: ../../source/contributor-how-to-build-docker-images.rst:45 +msgid "``DISTRO``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:46 +#, fuzzy +msgid "The Linux distribution to use as the base image." +msgstr "O nome do repositório da imagem base." + +#: ../../source/contributor-how-to-build-docker-images.rst:47 +#: ../../source/contributor-how-to-build-docker-images.rst:51 +#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:71 +#: ../../source/contributor-how-to-build-docker-images.rst:104 +msgid "No" +msgstr "" + #: ../../source/contributor-how-to-build-docker-images.rst:48 -#: ../../source/contributor-how-to-build-docker-images.rst:94 -msgid "``PYTHON_VERSION``" -msgstr "``PYTHON_VERSION``" +#, fuzzy +msgid "``ubuntu``" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:49 -msgid "Version of ``python`` to be installed." -msgstr "Versão do ``python`` a ser instalada." +#, fuzzy +msgid "``DISTRO_VERSION``" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:50 +msgid "Version of the Linux distribution." +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:52 +#, fuzzy +msgid "``22.04``" +msgstr "``23.0.1``" + +#: ../../source/contributor-how-to-build-docker-images.rst:53 +msgid "``PYTHON_VERSION``" +msgstr "``PYTHON_VERSION``" + #: ../../source/contributor-how-to-build-docker-images.rst:54 -#: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:108 -msgid "Yes" -msgstr "Sim" +msgid "Version of ``python`` to be installed." +msgstr "Versão do ``python`` a ser instalada." -#: ../../source/contributor-how-to-build-docker-images.rst:51 -msgid "``3.11``" -msgstr "``3.11``" +#: ../../source/contributor-how-to-build-docker-images.rst:56 +msgid "``3.11`` or ``3.11.1``" +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:52 +#: ../../source/contributor-how-to-build-docker-images.rst:57 msgid "``PIP_VERSION``" msgstr "``PIP_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:53 +#: ../../source/contributor-how-to-build-docker-images.rst:58 msgid "Version of ``pip`` to be installed." msgstr "Versão do ``pip`` a ser instalada." -#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:63 +#: ../../source/contributor-how-to-build-docker-images.rst:67 +#: ../../source/contributor-how-to-build-docker-images.rst:108 +msgid "Yes" +msgstr "Sim" + +#: ../../source/contributor-how-to-build-docker-images.rst:60 msgid "``23.0.1``" msgstr "``23.0.1``" -#: ../../source/contributor-how-to-build-docker-images.rst:56 +#: ../../source/contributor-how-to-build-docker-images.rst:61 msgid "``SETUPTOOLS_VERSION``" msgstr "``SETUPTOOLS_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:57 +#: ../../source/contributor-how-to-build-docker-images.rst:62 msgid "Version of ``setuptools`` to be installed." msgstr "Versão do ``setuptools`` a ser instalada." -#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:64 msgid "``69.0.2``" msgstr "``69.0.2``" -#: ../../source/contributor-how-to-build-docker-images.rst:60 -#: ../../source/contributor-how-to-build-docker-images.rst:98 -msgid "``UBUNTU_VERSION``" -msgstr "``UBUNTU_VERSION``" +#: ../../source/contributor-how-to-build-docker-images.rst:65 +msgid "``FLWR_VERSION``" +msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:61 -msgid "Version of the official Ubuntu Docker image." -msgstr "Versão da imagem Docker oficial do Ubuntu." +#: ../../source/contributor-how-to-build-docker-images.rst:66 +msgid "Version of Flower to be installed." +msgstr "Versão do Flower a ser instalada." -#: ../../source/contributor-how-to-build-docker-images.rst:62 -msgid "Defaults to ``22.04``." -msgstr "Como padrão ``22.04``." +#: ../../source/contributor-how-to-build-docker-images.rst:68 +#, fuzzy +msgid "``1.8.0``" +msgstr "``1.7.0``" -#: ../../source/contributor-how-to-build-docker-images.rst:65 +#: ../../source/contributor-how-to-build-docker-images.rst:69 +#, fuzzy +msgid "``FLWR_PACKAGE``" +msgstr "``FLWR_VERSION``" + +#: ../../source/contributor-how-to-build-docker-images.rst:70 +#, fuzzy +msgid "The Flower package to be installed." +msgstr "Versão do Flower a ser instalada." + +#: ../../source/contributor-how-to-build-docker-images.rst:72 +msgid "``flwr`` or ``flwr-nightly``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:75 +#, fuzzy msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1" -" and setuptools 69.0.2:" +"The following example creates a base Ubuntu/Alpine image with Python " +"3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" msgstr "" "O exemplo seguinte cria uma imagem base com Python 3.11.0, pip 23.0.1 e " "setuptools 69.0.2:" -#: ../../source/contributor-how-to-build-docker-images.rst:76 +#: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "" "The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " "the build arguments as well as the name and tag can be adapted to your " @@ -253,76 +288,43 @@ msgstr "" "argumentos de construção assim como o nome e a tag podem ser adaptados de" " acordo com suas necessidades. Estes valores servem apenas como exemplo." -#: ../../source/contributor-how-to-build-docker-images.rst:80 +#: ../../source/contributor-how-to-build-docker-images.rst:92 #, fuzzy -msgid "Building the SuperLink image" +msgid "Building the SuperLink/SuperNode or ServerApp image" msgstr "Construindo a imagem do servidor" -#: ../../source/contributor-how-to-build-docker-images.rst:90 +#: ../../source/contributor-how-to-build-docker-images.rst:102 msgid "``BASE_REPOSITORY``" msgstr "``BASE_REPOSITORY``" -#: ../../source/contributor-how-to-build-docker-images.rst:91 +#: ../../source/contributor-how-to-build-docker-images.rst:103 msgid "The repository name of the base image." msgstr "O nome do repositório da imagem base." -#: ../../source/contributor-how-to-build-docker-images.rst:92 -#, fuzzy -msgid "Defaults to ``flwr/base``." -msgstr "Pré-definido para ``flwr/server``." - -#: ../../source/contributor-how-to-build-docker-images.rst:95 -#, fuzzy -msgid "The Python version of the base image." -msgstr "O nome do repositório da imagem base." - -#: ../../source/contributor-how-to-build-docker-images.rst:96 -#, fuzzy -msgid "Defaults to ``py3.11``." -msgstr "Como padrão ``22.04``." - -#: ../../source/contributor-how-to-build-docker-images.rst:99 -#, fuzzy -msgid "The Ubuntu version of the base image." -msgstr "O nome do repositório da imagem base." - -#: ../../source/contributor-how-to-build-docker-images.rst:100 -#, fuzzy -msgid "Defaults to ``ubuntu22.04``." -msgstr "Pré-definido para ``py3.11-ubuntu22.04``." - -#: ../../source/contributor-how-to-build-docker-images.rst:102 +#: ../../source/contributor-how-to-build-docker-images.rst:105 #, fuzzy -msgid "``FLWR_PACKAGE``" +msgid "``flwr/base``" msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 -msgid "The PyPI package to install." -msgstr "" - -#: ../../source/contributor-how-to-build-docker-images.rst:104 -#, fuzzy -msgid "Defaults to ``flwr``." -msgstr "Pré-definido para ``flwr/server``." - #: ../../source/contributor-how-to-build-docker-images.rst:106 -msgid "``FLWR_VERSION``" -msgstr "``FLWR_VERSION``" +#, fuzzy +msgid "``BASE_IMAGE``" +msgstr "``BASE_REPOSITORY``" #: ../../source/contributor-how-to-build-docker-images.rst:107 -msgid "Version of Flower to be installed." -msgstr "Versão do Flower a ser instalada." +#, fuzzy +msgid "The Tag of the Flower base image." +msgstr "O nome do repositório da imagem base." #: ../../source/contributor-how-to-build-docker-images.rst:109 -#, fuzzy -msgid "``1.8.0``" -msgstr "``1.7.0``" +msgid "``1.8.0-py3.10-ubuntu22.04``" +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:112 +#: ../../source/contributor-how-to-build-docker-images.rst:111 #, fuzzy msgid "" -"The following example creates a SuperLink image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.8.0:" +"The following example creates a SuperLink/SuperNode or ServerApp image " +"with the official Flower base image:" msgstr "" "O exemplo a seguir cria uma imagem de servidor com a imagem base oficial " "do Flower py3.11-ubuntu22.04 e Flower 1.7.0:" @@ -330,20 +332,9 @@ msgstr "" #: ../../source/contributor-how-to-build-docker-images.rst:122 #, fuzzy msgid "" -"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " -"that the build arguments as well as the name and tag can be adapted to " -"your needs. These values serve as examples only." -msgstr "" -"O nome da imagem é ``flwr_server`` e a tag ``0.1.0``. Lembre-se que os " -"argumentos de compilação, bem como o nome e a tag podem ser adaptados às " -"suas necessidades. Esses valores servem apenas como exemplos." - -#: ../../source/contributor-how-to-build-docker-images.rst:125 -#, fuzzy -msgid "" "If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." +"base image, all you need to do is set the ``BASE_REPOSITORY`` build " +"argument." msgstr "" "Se você quiser usar sua própria imagem base ao invés da imagem oficial " "base do Flower, tudo que você precisa fazer é definir os argumentos " @@ -352,7 +343,7 @@ msgstr "" "sua imagem e o valor de ``BASE_IMAGE_TAG`` deve corresponder à tag da sua" " imagem." -#: ../../source/contributor-how-to-build-docker-images.rst:138 +#: ../../source/contributor-how-to-build-docker-images.rst:133 msgid "After creating the image, we can test whether the image is working:" msgstr "Depois de criar a imagem, podemos testar se a imagem está funcionando:" @@ -516,120 +507,6 @@ msgstr "" "abrindo uma issue no nosso `repositório GitHub " "`_." -#: ../../source/contributor-how-to-create-new-messages.rst:2 -#, fuzzy -msgid "Creating New Messages" -msgstr "Criando novas mensagens" - -#: ../../source/contributor-how-to-create-new-messages.rst:4 -msgid "" -"This is a simple guide for creating a new type of message between the " -"server and clients in Flower." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:6 -msgid "" -"Let's suppose we have the following example functions in " -":code:`server.py` and :code:`numpy_client.py`..." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:8 -msgid "Server's side:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:17 -msgid "Client's side:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:26 -msgid "" -"Let's now see what we need to implement in order to get this simple " -"function between the server and client to work!" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:30 -msgid "Message Types for Protocol Buffers" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:32 -msgid "" -"The first thing we need to do is to define a message type for the RPC " -"system in :code:`transport.proto`. Note that we have to do it for both " -"the request and response messages. For more details on the syntax of " -"proto3, please see the `official documentation `_." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:35 -msgid "Within the :code:`ServerMessage` block:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:52 -msgid "Within the ClientMessage block:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:70 -msgid "" -"Make sure to also add a field of the newly created message type in " -":code:`oneof msg`." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:72 -msgid "Once that is done, we will compile the file with:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:78 -msgid "If it compiles successfully, you should see the following message:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:87 -msgid "Serialization and Deserialization Functions" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:89 -msgid "" -"Our next step is to add functions to serialize and deserialize Python " -"datatypes to or from our defined RPC message types. You should add these " -"functions in :code:`serde.py`." -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:91 -msgid "The four functions:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:112 -msgid "Sending the Message from the Server" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:114 -msgid "" -"Now write the request function in your Client Proxy class (e.g., " -":code:`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:128 -msgid "Receiving the Message by the Client" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:130 -msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the " -"field of your message and call the :code:`example_response` function. " -"Remember to use the serde functions!" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:132 -msgid "Within the handle function:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:139 -msgid "And add a new function:" -msgstr "" - -#: ../../source/contributor-how-to-create-new-messages.rst:149 -msgid "Hopefully, when you run your program you will get the intended result!" -msgstr "" - #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" msgstr "" @@ -938,96 +815,145 @@ msgstr "" msgid "Check the draft release on GitHub, and if everything is good, publish it." msgstr "" +#: ../../source/contributor-how-to-release-flower.rst:15 +#, fuzzy +msgid "Trigger the CI for building the Docker images." +msgstr "Versão da imagem Docker oficial do Ubuntu." + #: ../../source/contributor-how-to-release-flower.rst:17 +msgid "" +"To trigger the workflow, a collaborator must create a " +"``workflow_dispatch`` event in the GitHub CI. This can be done either " +"through the UI or via the GitHub CLI. The event requires only one input, " +"the Flower version, to be released." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:21 +msgid "**Via the UI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:23 +msgid "" +"Go to the ``Build docker images`` workflow `page " +"`_." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:24 +msgid "" +"Click on the ``Run workflow`` button and type the new version of Flower " +"in the ``Version of Flower`` input field." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:25 +msgid "Click on the **green** ``Run workflow`` button." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:29 +msgid "**Via the GitHub CI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:31 +msgid "" +"Make sure you are logged in via ``gh auth login`` and that the current " +"working directory is the root of the Flower repository." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:32 +msgid "" +"Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" +"version=``." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:19 +#: ../../source/contributor-how-to-release-flower.rst:37 msgid "Create a pull request which contains the following changes:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:21 +#: ../../source/contributor-how-to-release-flower.rst:39 msgid "Increase the minor version in ``pyproject.toml`` by one." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:22 +#: ../../source/contributor-how-to-release-flower.rst:40 msgid "Update all files which contain the current version number if necessary." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:23 +#: ../../source/contributor-how-to-release-flower.rst:41 msgid "Add a new ``Unreleased`` section in ``changelog.md``." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:25 +#: ../../source/contributor-how-to-release-flower.rst:43 msgid "" "Merge the pull request on the same day (i.e., before a new nightly " "release gets published to PyPI)." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:28 +#: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:31 +#: ../../source/contributor-how-to-release-flower.rst:49 msgid "Pre-release naming" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:33 +#: ../../source/contributor-how-to-release-flower.rst:51 msgid "" "PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" " MUST use one of the following naming patterns:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:35 +#: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:36 +#: ../../source/contributor-how-to-release-flower.rst:54 msgid "Beta: ``MAJOR.MINOR.PATCHbN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:37 +#: ../../source/contributor-how-to-release-flower.rst:55 msgid "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:39 +#: ../../source/contributor-how-to-release-flower.rst:57 msgid "Examples include:" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:41 +#: ../../source/contributor-how-to-release-flower.rst:59 msgid "``1.0.0a0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:42 +#: ../../source/contributor-how-to-release-flower.rst:60 msgid "``1.0.0b0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:43 +#: ../../source/contributor-how-to-release-flower.rst:61 msgid "``1.0.0rc0``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:44 +#: ../../source/contributor-how-to-release-flower.rst:62 msgid "``1.0.0rc1``" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:46 +#: ../../source/contributor-how-to-release-flower.rst:64 msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:49 +#: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:50 +#: ../../source/contributor-how-to-release-flower.rst:68 msgid "" "`PyPA Choosing a versioning scheme " "`_" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:52 +#: ../../source/contributor-how-to-release-flower.rst:70 msgid "" "Note that the approach defined by PyPA is not compatible with SemVer " "2.0.0 spec, for details consult the `Semantic Versioning Specification " @@ -1035,26 +961,26 @@ msgid "" "11 on precedence)." msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:55 +#: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:57 +#: ../../source/contributor-how-to-release-flower.rst:75 msgid "Should the next pre-release be called alpha, beta, or release candidate?" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:59 +#: ../../source/contributor-how-to-release-flower.rst:77 msgid "" "RC: feature complete, no known issues (apart from issues that are " "classified as \"won't fix\" for the next stable release) - if no issues " "surface this will become the next stable release" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:60 +#: ../../source/contributor-how-to-release-flower.rst:78 msgid "Beta: feature complete, allowed to have known issues" msgstr "" -#: ../../source/contributor-how-to-release-flower.rst:61 +#: ../../source/contributor-how-to-release-flower.rst:79 msgid "Alpha: not feature complete, allowed to have known issues" msgstr "" @@ -1992,7 +1918,7 @@ msgid "Get started as a contributor" msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 -#: ../../source/how-to-run-flower-using-docker.rst:132 +#: ../../source/how-to-run-flower-using-docker.rst:153 msgid "Prerequisites" msgstr "" @@ -3783,11 +3709,11 @@ msgid "" "authentication enabled:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:36 +#: ../../source/how-to-authenticate-supernodes.rst:38 msgid "Let's break down the authentication flags:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:38 +#: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" "The first flag :code:`--auth-list-public-keys` expects a path to a CSV " "file storing all known node public keys. You need to store all known node" @@ -3795,7 +3721,7 @@ msgid "" "file (:code:`.csv`)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:40 +#: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " @@ -3803,7 +3729,7 @@ msgid "" "known node public keys." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:42 +#: ../../source/how-to-authenticate-supernodes.rst:44 msgid "" "The second and third flags :code:`--auth-superlink-private-key` and :code" ":`--auth-superlink-public-key` expect paths to the server's private and " @@ -3811,7 +3737,7 @@ msgid "" "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:45 +#: ../../source/how-to-authenticate-supernodes.rst:47 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " "adding known node public keys to the SuperLink. To change the set of " @@ -3820,11 +3746,11 @@ msgid "" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:51 +#: ../../source/how-to-authenticate-supernodes.rst:53 msgid "Enable node authentication in :code:`SuperNode`" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:53 +#: ../../source/how-to-authenticate-supernodes.rst:55 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " "easily enable node authentication in the long-running Flower client " @@ -3832,7 +3758,7 @@ msgid "" "authenticated :code:`SuperNode`:" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:64 +#: ../../source/how-to-authenticate-supernodes.rst:66 msgid "" "The :code:`--auth-supernode-private-key` flag expects a path to the " "node's private key file and the :code:`--auth-supernode-public-key` flag " @@ -3841,11 +3767,11 @@ msgid "" " ecdsa -b 384`." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:68 +#: ../../source/how-to-authenticate-supernodes.rst:70 msgid "Security notice" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:70 +#: ../../source/how-to-authenticate-supernodes.rst:72 msgid "" "The system's security relies on the credentials of the SuperLink and each" " SuperNode. Therefore, it is imperative to safeguard and safely store the" @@ -3856,14 +3782,14 @@ msgid "" "methods." msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:75 -#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:68 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" msgstr "" -#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-authenticate-supernodes.rst:79 msgid "" "You should now have learned how to start a long-running Flower server " "(:code:`SuperLink`) and client (:code:`SuperNode`) with node " @@ -4139,51 +4065,51 @@ msgid "" " the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:47 +#: ../../source/how-to-enable-ssl-connections.rst:50 msgid "" "When providing certificates, the server expects a tuple of three " "certificates paths: CA certificate, server certificate and server private" " key." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:51 +#: ../../source/how-to-enable-ssl-connections.rst:54 msgid "Client (SuperNode)" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:53 +#: ../../source/how-to-enable-ssl-connections.rst:56 msgid "" "Use the following terminal command to start a client (SuperNode) that " "uses the previously generated certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:64 msgid "" "When setting :code:`root_certificates`, the client expects a file path to" " PEM-encoded root certificates." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:70 msgid "" "You should now have learned how to generate self-signed certificates " "using the given script, start an SSL-enabled server and have a client " "establish a secure connection to it." msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:72 +#: ../../source/how-to-enable-ssl-connections.rst:75 msgid "Additional resources" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:74 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:76 +#: ../../source/how-to-enable-ssl-connections.rst:79 msgid "`Let's Encrypt `_" msgstr "" -#: ../../source/how-to-enable-ssl-connections.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" msgstr "" @@ -4793,14 +4719,15 @@ msgstr "" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`__." +"`__. Supported architectures include " +"``amd64`` and ``arm64v8``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:7 +#: ../../source/how-to-run-flower-using-docker.rst:8 msgid "Before you start, make sure that the Docker daemon is running:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:14 +#: ../../source/how-to-run-flower-using-docker.rst:15 msgid "" "If you do not see the version of Docker but instead get an error saying " "that the command was not found, you will need to install Docker first. " @@ -4808,7 +4735,7 @@ msgid "" "docker/>`_." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:21 msgid "" "On Linux, Docker commands require ``sudo`` privilege. If you want to " "avoid using ``sudo``, you can follow the `Post-installation steps " @@ -4816,7 +4743,7 @@ msgid "" "official Docker website." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:26 +#: ../../source/how-to-run-flower-using-docker.rst:27 msgid "" "To ensure optimal performance and compatibility, the SuperLink, SuperNode" " and ServerApp image must have the same version when running together. " @@ -4824,26 +4751,26 @@ msgid "" "issues that may arise from using different versions." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:31 +#: ../../source/how-to-run-flower-using-docker.rst:32 msgid "Flower SuperLink" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:34 +#: ../../source/how-to-run-flower-using-docker.rst:35 msgid "Quickstart" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:36 +#: ../../source/how-to-run-flower-using-docker.rst:37 msgid "If you're looking to try out Flower, you can use the following command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:42 +#: ../../source/how-to-run-flower-using-docker.rst:43 msgid "" "The command pulls the Docker image with the tag ``1.8.0`` from Docker " "Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " "The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:49 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " "Docker flag ``--rm``, the state is not persisted between container " @@ -4851,7 +4778,7 @@ msgid "" "system." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:52 +#: ../../source/how-to-run-flower-using-docker.rst:53 msgid "" "The ``-p :`` flag tells Docker to map the ports " "``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " @@ -4861,9 +4788,9 @@ msgid "" " flag ``--insecure``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:59 -#: ../../source/how-to-run-flower-using-docker.rst:238 -#: ../../source/how-to-run-flower-using-docker.rst:354 +#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:259 +#: ../../source/how-to-run-flower-using-docker.rst:376 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " "HTTPS) and should only be used for testing purposes. We strongly " @@ -4872,48 +4799,59 @@ msgid "" "deploying to a production environment." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:64 +#: ../../source/how-to-run-flower-using-docker.rst:65 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:71 +#: ../../source/how-to-run-flower-using-docker.rst:72 msgid "Mounting a volume to store the state on the host system" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:73 +#: ../../source/how-to-run-flower-using-docker.rst:74 msgid "" "If you want to persist the state of the SuperLink on your host system, " -"all you need to do is specify a path where you want to save the file on " -"your host system and a name for the database file. In the example below, " -"we tell Docker via the flag ``--volume`` to mount the user's home " -"directory (``~/`` on your host) into the ``/app/`` directory of the " -"container. Furthermore, we use the flag ``--database`` to specify the " -"name of the database file." +"all you need to do is specify a directory where you want to save the file" +" on your host system and a name for the database file. By default, the " +"SuperLink container runs with a non-root user called ``app`` with the " +"user ID ``49999``. It is recommended to create new directory and change " +"the user ID of the directory to ``49999`` to ensure the mounted directory" +" has the proper permissions. If you later want to delete the directory, " +"you can change the user ID back to the current user ID by running ``sudo " +"chown -R $USER:$(id -gn) state``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:86 +#: ../../source/how-to-run-flower-using-docker.rst:82 +msgid "" +"In the example below, we create a new directory, change the user ID and " +"tell Docker via the flag ``--volume`` to mount the local ``state`` " +"directory into the ``/app/state`` directory of the container. " +"Furthermore, we use the flag ``--database`` to specify the name of the " +"database file." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:95 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, " -"the SuperLink tries to restore the state from the file. To start the " +"``state`` directory on your host system. If the file already exists, the " +"SuperLink tries to restore the state from the file. To start the " "SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:91 -#: ../../source/how-to-run-flower-using-docker.rst:260 -#: ../../source/how-to-run-flower-using-docker.rst:375 +#: ../../source/how-to-run-flower-using-docker.rst:100 +#: ../../source/how-to-run-flower-using-docker.rst:281 +#: ../../source/how-to-run-flower-using-docker.rst:397 msgid "Enabling SSL for secure connections" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:93 +#: ../../source/how-to-run-flower-using-docker.rst:102 msgid "" "To enable SSL, you will need a PEM-encoded root certificate, a PEM-" "encoded private key and a PEM-encoded certificate chain." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:97 +#: ../../source/how-to-run-flower-using-docker.rst:106 msgid "" "For testing purposes, you can generate your own self-signed certificates." " The `Enable SSL connections `__ is already installed " "in the ``flwr/supernode`` base image, so you only need to include other " @@ -4995,20 +4945,20 @@ msgid "" "``tensorflow``, etc." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:179 +#: ../../source/how-to-run-flower-using-docker.rst:200 msgid "" "Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " "example, create a new file called ``Dockerfile.supernode`` in ``examples" "/quickstart-pytorch``." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:182 +#: ../../source/how-to-run-flower-using-docker.rst:203 msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:196 +#: ../../source/how-to-run-flower-using-docker.rst:217 msgid "" "In the first two lines, we instruct Docker to use the SuperNode image " "tagged ``nightly`` as a base image and set our working directory to " @@ -5021,70 +4971,70 @@ msgid "" "(``:``) that will be run inside the ClientApp." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:205 +#: ../../source/how-to-run-flower-using-docker.rst:226 #, fuzzy msgid "Building the SuperNode Docker image" msgstr "Construindo a imagem do servidor" -#: ../../source/how-to-run-flower-using-docker.rst:207 +#: ../../source/how-to-run-flower-using-docker.rst:228 msgid "" "Next, we build the SuperNode Docker image by running the following " "command in the directory where Dockerfile and ClientApp code are located." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:214 +#: ../../source/how-to-run-flower-using-docker.rst:235 msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:219 +#: ../../source/how-to-run-flower-using-docker.rst:240 #, fuzzy msgid "Running the SuperNode Docker image" msgstr "Construindo a imagem do servidor" -#: ../../source/how-to-run-flower-using-docker.rst:221 +#: ../../source/how-to-run-flower-using-docker.rst:242 msgid "Now that we have built the SuperNode image, we can finally run it." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:229 -#: ../../source/how-to-run-flower-using-docker.rst:345 +#: ../../source/how-to-run-flower-using-docker.rst:250 +#: ../../source/how-to-run-flower-using-docker.rst:367 msgid "Let's break down each part of this command:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:231 -#: ../../source/how-to-run-flower-using-docker.rst:347 +#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:369 msgid "``docker run``: This is the command to run a new Docker container." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:232 -#: ../../source/how-to-run-flower-using-docker.rst:348 +#: ../../source/how-to-run-flower-using-docker.rst:253 +#: ../../source/how-to-run-flower-using-docker.rst:370 msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:233 +#: ../../source/how-to-run-flower-using-docker.rst:254 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:234 -#: ../../source/how-to-run-flower-using-docker.rst:350 +#: ../../source/how-to-run-flower-using-docker.rst:255 +#: ../../source/how-to-run-flower-using-docker.rst:372 msgid "``--insecure``: This option enables insecure communication." msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the" -" SuperLinks Fleet" +"``--superlink 192.168.1.100:9092``: This option specifies the address of " +"the SuperLinks Fleet" msgstr "" #: ../../source/how-to-run-flower-using-docker.rst msgid "API to connect to. Remember to update it with your SuperLink IP." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:248 +#: ../../source/how-to-run-flower-using-docker.rst:269 msgid "" "To test running Flower locally, you can create a `bridge network " "`__." +" `Docker Hub `__." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:400 +#: ../../source/how-to-run-flower-using-docker.rst:460 msgid "Pinning a Docker image to a specific version" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:402 +#: ../../source/how-to-run-flower-using-docker.rst:462 msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " @@ -5261,21 +5249,21 @@ msgid "" "instead of the tag." msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:407 +#: ../../source/how-to-run-flower-using-docker.rst:467 msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:414 +#: ../../source/how-to-run-flower-using-docker.rst:474 msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:423 +#: ../../source/how-to-run-flower-using-docker.rst:483 msgid "Setting environment variables" msgstr "" -#: ../../source/how-to-run-flower-using-docker.rst:425 +#: ../../source/how-to-run-flower-using-docker.rst:485 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." @@ -6124,9 +6112,10 @@ msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" -"Here's another example to start with HTTPS. Use the ``--certificates`` " -"command line argument to pass paths to (CA certificate, server " -"certificate, and server private key)." +"Here's another example to start with HTTPS. Use the ``--ssl-ca-" +"certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line " +"options to pass paths to (CA certificate, server certificate, and server " +"private key)." msgstr "" #: ../../source/how-to-upgrade-to-flower-next.rst:201 @@ -6594,11 +6583,11 @@ msgstr "" msgid "Contributor how-to guides" msgstr "" -#: ../../source/index.rst:173 +#: ../../source/index.rst:172 msgid "Contributor explanations" msgstr "" -#: ../../source/index.rst:179 +#: ../../source/index.rst:178 msgid "Contributor references" msgstr "" @@ -6738,7 +6727,8 @@ msgstr "" msgid "flwr" msgstr "" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 +#: ../../source/ref-api/flwr.client.rst:45 ../../source/ref-api/flwr.rst:25 +#: ../../source/ref-api/flwr.server.rst:49 msgid "Modules" msgstr "" @@ -6763,7 +6753,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr "" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:38::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." msgstr "" @@ -6780,6 +6770,7 @@ msgstr "" msgid "client" msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:13 #: ../../source/ref-api/flwr.client.rst:13 #: ../../source/ref-api/flwr.common.rst:13 #: ../../source/ref-api/flwr.server.rst:13 @@ -6827,9 +6818,10 @@ msgstr "" msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:30 #: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:28 +#: ../../source/ref-api/flwr.server.rst:26 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" @@ -6864,6 +6856,14 @@ msgstr "" msgid "Abstract base class for Flower clients using NumPy." msgstr "" +#: ../../source/ref-api/flwr.client.rst:52::1 +msgid ":py:obj:`flwr.client.mod `\\" +msgstr "" + +#: ../../source/ref-api/flwr.client.rst:52::1 flwr.client.mod:1 of +msgid "Flower Built-in Mods." +msgstr "" + #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 @@ -6874,6 +6874,7 @@ msgstr "" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 #: ../../source/ref-api/flwr.client.NumPyClient.rst:15 +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:15 #: ../../source/ref-api/flwr.common.Array.rst:15 #: ../../source/ref-api/flwr.common.ClientMessage.rst:15 #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:15 @@ -7049,6 +7050,7 @@ msgstr "" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters #: flwr.client.client.Client.get_properties +#: flwr.client.mod.localdp_mod.LocalDpMod #: flwr.client.numpy_client.NumPyClient.evaluate #: flwr.client.numpy_client.NumPyClient.fit #: flwr.client.numpy_client.NumPyClient.get_parameters @@ -7199,10 +7201,11 @@ msgstr "" msgid "ClientApp" msgstr "" -#: flwr.client.client_app.ClientApp:1 flwr.common.constant.MessageType:1 -#: flwr.common.constant.MessageTypeLegacy:1 flwr.common.context.Context:1 -#: flwr.common.message.Error:1 flwr.common.message.Message:1 -#: flwr.common.message.Metadata:1 flwr.common.record.parametersrecord.Array:1 +#: flwr.client.client_app.ClientApp:1 flwr.client.mod.localdp_mod.LocalDpMod:1 +#: flwr.common.constant.MessageType:1 flwr.common.constant.MessageTypeLegacy:1 +#: flwr.common.context.Context:1 flwr.common.message.Error:1 +#: flwr.common.message.Message:1 flwr.common.message.Metadata:1 +#: flwr.common.record.parametersrecord.Array:1 #: flwr.common.record.recordset.RecordSet:1 flwr.common.typing.ClientMessage:1 #: flwr.common.typing.DisconnectRes:1 flwr.common.typing.EvaluateIns:1 #: flwr.common.typing.EvaluateRes:1 flwr.common.typing.FitIns:1 @@ -7223,7 +7226,8 @@ msgstr "" #: flwr.client.client_app.ClientApp:4 #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 -#: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 +#: flwr.client.client_app.ClientApp.train:4 +#: flwr.client.mod.localdp_mod.LocalDpMod:22 flwr.server.app.start_server:41 #: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 @@ -7440,6 +7444,231 @@ msgid "" "arbitrary property values back to the server." msgstr "" +#: ../../source/ref-api/flwr.client.mod.rst:2 +msgid "mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`adaptiveclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:1 of +msgid "Client-side adaptive clipping modifier." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`fixedclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:1 of +msgid "Client-side fixed clipping modifier." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.utils.make_ffn:1 of +msgid "." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " +"call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secagg_mod.secagg_mod:1 of +msgid "Handle incoming message and return results, following the SecAgg protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`secaggplus_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secaggplus_mod.secaggplus_mod:1 of +msgid "" +"Handle incoming message and return results, following the SecAgg+ " +"protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`message_size_mod `\\ \\(msg\\," +" ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.message_size_mod:1 of +msgid "Message size mod." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`parameters_size_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.parameters_size_mod:1 of +msgid "Parameters size mod." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +msgid "" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\," +" sensitivity\\, ...\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +#: flwr.client.mod.localdp_mod.LocalDpMod:1 of +msgid "Modifier for local differential privacy." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:2 +msgid "LocalDpMod" +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:3 of +msgid "" +"This mod clips the client model updates and adds noise to the params " +"before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:12 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:10 +#: flwr.client.mod.localdp_mod.LocalDpMod:6 of +msgid "It operates on messages of type `MessageType.TRAIN`." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:8 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +msgid "The value of the clipping norm." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:10 of +msgid "The sensitivity of the client model." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:12 of +msgid "" +"The privacy budget. Smaller value of epsilon indicates a higher level of " +"privacy protection." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:15 of +msgid "" +"The failure probability. The probability that the privacy mechanism fails" +" to provide the desired level of privacy. A smaller value of delta " +"indicates a stricter privacy guarantee." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:23 of +msgid "Create an instance of the local DP mod and add it to the client-side mods:" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.adaptiveclipping_mod.rst:2 +msgid "adaptiveclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy " +"wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:6 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:6 of +msgid "The wrapper sends the clipping_norm value to the client." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:8 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:8 of +msgid "This mod clips the client model updates before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:10 of +msgid "" +"It also sends KEY_NORM_BIT to the server for computing the new clipping " +"value." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:15 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:13 +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +msgid "Notes" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:16 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:14 of +msgid "Consider the order of mods when using multiple." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:18 of +msgid "Typically, adaptiveclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.fixedclipping_mod.rst:2 +msgid "fixedclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:3 of +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideFixedClipping server-side strategy wrapper." +msgstr "" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:16 of +msgid "Typically, fixedclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.make_ffn.rst:2 +msgid "make\\_ffn" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.message_size_mod.rst:2 +msgid "message\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.message_size_mod:3 of +msgid "This mod logs the size in bytes of the message being transmited." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.parameters_size_mod.rst:2 +msgid "parameters\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.parameters_size_mod:3 of +msgid "" +"This mod logs the number of parameters transmitted in the message as well" +" as their size in bytes." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secagg_mod.rst:2 +msgid "secagg\\_mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secaggplus_mod.rst:2 +msgid "secaggplus\\_mod" +msgstr "" + #: ../../source/ref-api/flwr.client.run_client_app.rst:2 msgid "run\\_client\\_app" msgstr "" @@ -8777,6 +9006,18 @@ msgid "" "`\\" msgstr "" +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPEREXEC_ENTER " +"`\\" +msgstr "" + +#: flwr.common.EventType.capitalize:1::1 of +msgid "" +":py:obj:`RUN_SUPEREXEC_LEAVE " +"`\\" +msgstr "" + #: flwr.common.EventType.capitalize:3 of msgid "" "More specifically, make the first character have upper case and the rest " @@ -9665,142 +9906,124 @@ msgstr "" msgid "server" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_driver_api `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_driver_api:1 of -msgid "Run Flower server (Driver API)." -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_fleet_api:1 of -msgid "Run Flower server (Fleet API)." -msgstr "" - -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid ":py:obj:`run_server_app `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.run_serverapp.run_server_app:1 of msgid "Run Flower server app." msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.run_superlink:1 of msgid "Run Flower SuperLink (Driver API and Fleet API)." msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 msgid "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.start_server:1 of msgid "Start a Flower server using the gRPC transport layer." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.ClientManager:1 of msgid "Abstract base class for managing Flower clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`Driver `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.driver.driver.Driver:1 of msgid "Abstract base Driver class for the Driver API." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`History `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.history.History:1 of msgid "History class for training and/or evaluation metrics collection." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of msgid "Legacy Context." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " "strategy\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " "strategy\\, ...\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_app.ServerApp:1 of msgid "Flower ServerApp." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid "" ":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," " round\\_timeout\\]\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_config.ServerConfig:1 of msgid "Flower server config." msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.SimpleClientManager:1 of msgid "Provides a pool of available clients." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 msgid ":py:obj:`flwr.server.strategy `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.strategy:1 of msgid "Contains the strategy abstraction and different implementations." msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 msgid ":py:obj:`flwr.server.workflow `\\" msgstr "" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.workflow:1 of msgid "Workflows." msgstr "" @@ -10046,13 +10269,6 @@ msgstr "" msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -msgid "Notes" -msgstr "" - #: flwr.server.driver.driver.Driver.send_and_receive:19 of msgid "" "This method uses `push_messages` to send the messages and `pull_messages`" @@ -11422,12 +11638,6 @@ msgid "" "value of 1.0 or higher is recommended for strong privacy." msgstr "" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -msgid "The value of the clipping norm." -msgstr "" - #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 #: of msgid "" @@ -11715,7 +11925,7 @@ msgid "" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:905 +#: ../../source/ref-changelog.md:997 msgid "FedAdagrad" msgstr "" @@ -13558,122 +13768,576 @@ msgid "Changelog" msgstr "" #: ../../source/ref-changelog.md:3 -msgid "Unreleased" -msgstr "" - -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 -#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 -#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 -#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 -#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 -#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 -#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 -#: ../../source/ref-changelog.md:1022 -msgid "What's new?" +msgid "v1.9.0 (2024-06-10)" msgstr "" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 -#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 -#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 -#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 -#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 -#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 -#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 -msgid "Incompatible changes" +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:169 ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:362 ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:510 ../../source/ref-changelog.md:568 +#: ../../source/ref-changelog.md:637 ../../source/ref-changelog.md:706 +msgid "Thanks to our contributors" msgstr "" -#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 -#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 -#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 -#: ../../source/ref-changelog.md:603 -msgid "None" +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:171 ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:364 ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:512 ../../source/ref-changelog.md:570 +msgid "" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:11 -msgid "v1.8.0 (2024-04-03)" +#: ../../source/ref-changelog.md:9 +msgid "" +"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. " +"Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`," +" `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " msgstr "" -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 -#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 -#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 -#: ../../source/ref-changelog.md:614 -msgid "Thanks to our contributors" +#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:175 ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:368 ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:516 ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:643 ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:814 ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:947 ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:1031 ../../source/ref-changelog.md:1064 +#: ../../source/ref-changelog.md:1114 +msgid "What's new?" msgstr "" -#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 -#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 -#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 -#: ../../source/ref-changelog.md:478 +#: ../../source/ref-changelog.md:13 msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" +"**Introduce built-in authentication (preview)** " +"([#2946](https://github.com/adap/flower/pull/2946), " +"[#3388](https://github.com/adap/flower/pull/3388), " +"[#2948](https://github.com/adap/flower/pull/2948), " +"[#2917](https://github.com/adap/flower/pull/2917), " +"[#3386](https://github.com/adap/flower/pull/3386), " +"[#3308](https://github.com/adap/flower/pull/3308), " +"[#3001](https://github.com/adap/flower/pull/3001), " +"[#3409](https://github.com/adap/flower/pull/3409), " +"[#2999](https://github.com/adap/flower/pull/2999), " +"[#2979](https://github.com/adap/flower/pull/2979), " +"[#3389](https://github.com/adap/flower/pull/3389), " +"[#3503](https://github.com/adap/flower/pull/3503), " +"[#3366](https://github.com/adap/flower/pull/3366), " +"[#3357](https://github.com/adap/flower/pull/3357))" +msgstr "" + +#: ../../source/ref-changelog.md:15 +msgid "" +"Flower 1.9 introduces the first build-in version of client node " +"authentication. In previous releases, users often wrote glue code to " +"connect Flower to external authentication systems. With this release, the" +" SuperLink can authenticate SuperNodes using a built-in authentication " +"system. A new [how-to guide](https://flower.ai/docs/framework/how-to-" +"authenticate-supernodes.html) and a new [code " +"example](https://github.com/adap/flower/tree/main/examples/flower-" +"authentication) help you to get started." msgstr "" #: ../../source/ref-changelog.md:17 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " -"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " -"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " -"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " -"`tabdar-khan` " +"This is the first preview release of the Flower-native authentication " +"system. Many additional features are on the roadmap for upcoming Flower " +"releases - stay tuned." +msgstr "" + +#: ../../source/ref-changelog.md:19 +msgid "" +"**Introduce end-to-end Docker support** " +"([#3483](https://github.com/adap/flower/pull/3483), " +"[#3266](https://github.com/adap/flower/pull/3266), " +"[#3390](https://github.com/adap/flower/pull/3390), " +"[#3283](https://github.com/adap/flower/pull/3283), " +"[#3285](https://github.com/adap/flower/pull/3285), " +"[#3391](https://github.com/adap/flower/pull/3391), " +"[#3403](https://github.com/adap/flower/pull/3403), " +"[#3458](https://github.com/adap/flower/pull/3458), " +"[#3533](https://github.com/adap/flower/pull/3533), " +"[#3453](https://github.com/adap/flower/pull/3453), " +"[#3486](https://github.com/adap/flower/pull/3486), " +"[#3290](https://github.com/adap/flower/pull/3290))" msgstr "" #: ../../source/ref-changelog.md:21 msgid "" -"**Introduce Flower Next high-level API (stable)** " -"([#3002](https://github.com/adap/flower/pull/3002), " -"[#2934](https://github.com/adap/flower/pull/2934), " -"[#2958](https://github.com/adap/flower/pull/2958), " -"[#3173](https://github.com/adap/flower/pull/3173), " -"[#3174](https://github.com/adap/flower/pull/3174), " -"[#2923](https://github.com/adap/flower/pull/2923), " -"[#2691](https://github.com/adap/flower/pull/2691), " -"[#3079](https://github.com/adap/flower/pull/3079), " -"[#2961](https://github.com/adap/flower/pull/2961), " -"[#2924](https://github.com/adap/flower/pull/2924), " -"[#3166](https://github.com/adap/flower/pull/3166), " -"[#3031](https://github.com/adap/flower/pull/3031), " -"[#3057](https://github.com/adap/flower/pull/3057), " -"[#3000](https://github.com/adap/flower/pull/3000), " -"[#3113](https://github.com/adap/flower/pull/3113), " -"[#2957](https://github.com/adap/flower/pull/2957), " -"[#3183](https://github.com/adap/flower/pull/3183), " -"[#3180](https://github.com/adap/flower/pull/3180), " -"[#3035](https://github.com/adap/flower/pull/3035), " -"[#3189](https://github.com/adap/flower/pull/3189), " -"[#3185](https://github.com/adap/flower/pull/3185), " -"[#3190](https://github.com/adap/flower/pull/3190), " -"[#3191](https://github.com/adap/flower/pull/3191), " -"[#3195](https://github.com/adap/flower/pull/3195), " -"[#3197](https://github.com/adap/flower/pull/3197))" +"Full Flower Next Docker support is here! With the release of Flower 1.9, " +"Flower provides stable Docker images for the Flower SuperLink, the Flower" +" SuperNode, and the Flower `ServerApp`. This set of images enables you to" +" run all Flower components in Docker. Check out the new [how-to " +"guide](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html) to get stated." msgstr "" #: ../../source/ref-changelog.md:23 msgid "" -"The Flower Next high-level API is stable! Flower Next is the future of " -"Flower - all new features (like Flower Mods) will be built on top of it. " -"You can start to migrate your existing projects to Flower Next by using " -"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " -"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." -" Flower Next allows you to run multiple projects concurrently (we call " -"this multi-run) and execute the same project in either simulation " -"environments or deployment environments without having to change a single" -" line of code. The best part? It's fully compatible with existing Flower " -"projects that use `Strategy`, `NumPyClient` & co." +"**Re-architect Flower Next simulation engine** " +"([#3307](https://github.com/adap/flower/pull/3307), " +"[#3355](https://github.com/adap/flower/pull/3355), " +"[#3272](https://github.com/adap/flower/pull/3272), " +"[#3273](https://github.com/adap/flower/pull/3273), " +"[#3417](https://github.com/adap/flower/pull/3417), " +"[#3281](https://github.com/adap/flower/pull/3281), " +"[#3343](https://github.com/adap/flower/pull/3343), " +"[#3326](https://github.com/adap/flower/pull/3326))" msgstr "" #: ../../source/ref-changelog.md:25 msgid "" -"**Introduce Flower Next low-level API (preview)** " -"([#3062](https://github.com/adap/flower/pull/3062), " -"[#3034](https://github.com/adap/flower/pull/3034), " -"[#3069](https://github.com/adap/flower/pull/3069))" +"Flower Next simulations now use a new in-memory `Driver` that improves " +"the reliability of simulations, especially in notebook environments. This" +" is a significant step towards a complete overhaul of the Flower Next " +"simulation architecture." msgstr "" #: ../../source/ref-changelog.md:27 msgid "" +"**Upgrade simulation engine** " +"([#3354](https://github.com/adap/flower/pull/3354), " +"[#3378](https://github.com/adap/flower/pull/3378), " +"[#3262](https://github.com/adap/flower/pull/3262), " +"[#3435](https://github.com/adap/flower/pull/3435), " +"[#3501](https://github.com/adap/flower/pull/3501), " +"[#3482](https://github.com/adap/flower/pull/3482), " +"[#3494](https://github.com/adap/flower/pull/3494))" +msgstr "" + +#: ../../source/ref-changelog.md:29 +msgid "" +"The Flower Next simulation engine comes with improved and configurable " +"logging. The Ray-based simulation backend in Flower 1.9 was updated to " +"use Ray 2.10." +msgstr "" + +#: ../../source/ref-changelog.md:31 +msgid "" +"**Introduce FedPFT baseline** " +"([#3268](https://github.com/adap/flower/pull/3268))" +msgstr "" + +#: ../../source/ref-changelog.md:33 +msgid "" +"FedPFT allows you to perform one-shot Federated Learning by leveraging " +"widely available foundational models, dramatically reducing communication" +" costs while delivering high performing models. This is work led by Mahdi" +" Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " +"details in their paper: \"Parametric Feature Transfer: One-shot Federated" +" Learning with Foundation Models\" " +"([arxiv](https://arxiv.org/abs/2402.01862))" +msgstr "" + +#: ../../source/ref-changelog.md:35 +msgid "" +"**Launch additional** `flwr new` **templates for Apple MLX, Hugging Face " +"Transformers, scikit-learn and TensorFlow** " +"([#3291](https://github.com/adap/flower/pull/3291), " +"[#3139](https://github.com/adap/flower/pull/3139), " +"[#3284](https://github.com/adap/flower/pull/3284), " +"[#3251](https://github.com/adap/flower/pull/3251), " +"[#3376](https://github.com/adap/flower/pull/3376), " +"[#3287](https://github.com/adap/flower/pull/3287))" +msgstr "" + +#: ../../source/ref-changelog.md:37 +msgid "" +"The `flwr` CLI's `flwr new` command is starting to become everone's " +"favorite way of creating new Flower projects. This release introduces " +"additional `flwr new` templates for Apple MLX, Hugging Face Transformers," +" scikit-learn and TensorFlow. In addition to that, existing templates " +"also received updates." +msgstr "" + +#: ../../source/ref-changelog.md:39 +msgid "" +"**Refine** `RecordSet` **API** " +"([#3209](https://github.com/adap/flower/pull/3209), " +"[#3331](https://github.com/adap/flower/pull/3331), " +"[#3334](https://github.com/adap/flower/pull/3334), " +"[#3335](https://github.com/adap/flower/pull/3335), " +"[#3375](https://github.com/adap/flower/pull/3375), " +"[#3368](https://github.com/adap/flower/pull/3368))" +msgstr "" + +#: ../../source/ref-changelog.md:41 +msgid "" +"`RecordSet` is part of the Flower Next low-level API preview release. In " +"Flower 1.9, `RecordSet` received a number of usability improvements that " +"make it easier to build `RecordSet`-based `ServerApp`s and `ClientApp`s." +msgstr "" + +#: ../../source/ref-changelog.md:43 +msgid "" +"**Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), " +"[#3430](https://github.com/adap/flower/pull/3430), " +"[#3461](https://github.com/adap/flower/pull/3461), " +"[#3360](https://github.com/adap/flower/pull/3360), " +"[#3433](https://github.com/adap/flower/pull/3433))" +msgstr "" + +#: ../../source/ref-changelog.md:45 +msgid "" +"Logs received a substantial update. Not only are logs now much nicer to " +"look at, but they are also more configurable." +msgstr "" + +#: ../../source/ref-changelog.md:47 +msgid "" +"**Improve reliability** " +"([#3564](https://github.com/adap/flower/pull/3564), " +"[#3561](https://github.com/adap/flower/pull/3561), " +"[#3566](https://github.com/adap/flower/pull/3566), " +"[#3462](https://github.com/adap/flower/pull/3462), " +"[#3225](https://github.com/adap/flower/pull/3225), " +"[#3514](https://github.com/adap/flower/pull/3514), " +"[#3535](https://github.com/adap/flower/pull/3535), " +"[#3372](https://github.com/adap/flower/pull/3372))" +msgstr "" + +#: ../../source/ref-changelog.md:49 +msgid "" +"Flower 1.9 includes reliability improvements across many parts of the " +"system. One example is a much improved SuperNode shutdown procedure." +msgstr "" + +#: ../../source/ref-changelog.md:51 +msgid "" +"**Update Swift and C++ SDKs** " +"([#3321](https://github.com/adap/flower/pull/3321), " +"[#2763](https://github.com/adap/flower/pull/2763))" +msgstr "" + +#: ../../source/ref-changelog.md:53 +msgid "" +"In the C++ SDK, communication-related code is now separate from main " +"client logic. A new abstract class `Communicator` has been introduced " +"alongside a gRPC implementation of it." +msgstr "" + +#: ../../source/ref-changelog.md:55 +msgid "" +"**Improve testing, tooling and CI/CD infrastructure** " +"([#3294](https://github.com/adap/flower/pull/3294), " +"[#3282](https://github.com/adap/flower/pull/3282), " +"[#3311](https://github.com/adap/flower/pull/3311), " +"[#2878](https://github.com/adap/flower/pull/2878), " +"[#3333](https://github.com/adap/flower/pull/3333), " +"[#3255](https://github.com/adap/flower/pull/3255), " +"[#3349](https://github.com/adap/flower/pull/3349), " +"[#3400](https://github.com/adap/flower/pull/3400), " +"[#3401](https://github.com/adap/flower/pull/3401), " +"[#3399](https://github.com/adap/flower/pull/3399), " +"[#3346](https://github.com/adap/flower/pull/3346), " +"[#3398](https://github.com/adap/flower/pull/3398), " +"[#3397](https://github.com/adap/flower/pull/3397), " +"[#3347](https://github.com/adap/flower/pull/3347), " +"[#3502](https://github.com/adap/flower/pull/3502), " +"[#3387](https://github.com/adap/flower/pull/3387), " +"[#3542](https://github.com/adap/flower/pull/3542), " +"[#3396](https://github.com/adap/flower/pull/3396), " +"[#3496](https://github.com/adap/flower/pull/3496), " +"[#3465](https://github.com/adap/flower/pull/3465), " +"[#3473](https://github.com/adap/flower/pull/3473), " +"[#3484](https://github.com/adap/flower/pull/3484), " +"[#3521](https://github.com/adap/flower/pull/3521), " +"[#3363](https://github.com/adap/flower/pull/3363), " +"[#3497](https://github.com/adap/flower/pull/3497), " +"[#3464](https://github.com/adap/flower/pull/3464), " +"[#3495](https://github.com/adap/flower/pull/3495), " +"[#3478](https://github.com/adap/flower/pull/3478), " +"[#3271](https://github.com/adap/flower/pull/3271))" +msgstr "" + +#: ../../source/ref-changelog.md:57 +msgid "" +"As always, the Flower tooling, testing, and CI/CD infrastructure has " +"received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:59 +msgid "" +"**Improve documentation** " +"([#3530](https://github.com/adap/flower/pull/3530), " +"[#3539](https://github.com/adap/flower/pull/3539), " +"[#3425](https://github.com/adap/flower/pull/3425), " +"[#3520](https://github.com/adap/flower/pull/3520), " +"[#3286](https://github.com/adap/flower/pull/3286), " +"[#3516](https://github.com/adap/flower/pull/3516), " +"[#3523](https://github.com/adap/flower/pull/3523), " +"[#3545](https://github.com/adap/flower/pull/3545), " +"[#3498](https://github.com/adap/flower/pull/3498), " +"[#3439](https://github.com/adap/flower/pull/3439), " +"[#3440](https://github.com/adap/flower/pull/3440), " +"[#3382](https://github.com/adap/flower/pull/3382), " +"[#3559](https://github.com/adap/flower/pull/3559), " +"[#3432](https://github.com/adap/flower/pull/3432), " +"[#3278](https://github.com/adap/flower/pull/3278), " +"[#3371](https://github.com/adap/flower/pull/3371), " +"[#3519](https://github.com/adap/flower/pull/3519), " +"[#3267](https://github.com/adap/flower/pull/3267), " +"[#3204](https://github.com/adap/flower/pull/3204), " +"[#3274](https://github.com/adap/flower/pull/3274))" +msgstr "" + +#: ../../source/ref-changelog.md:61 +msgid "" +"As always, the Flower documentation has received many updates. Notable " +"new pages include:" +msgstr "" + +#: ../../source/ref-changelog.md:63 +msgid "" +"[How-to upgrate to Flower Next (Flower Next migration " +"guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-" +"next.html)" +msgstr "" + +#: ../../source/ref-changelog.md:65 +msgid "" +"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-" +"run-flower-using-docker.html)" +msgstr "" + +#: ../../source/ref-changelog.md:67 +msgid "" +"[Flower Mods reference](https://flower.ai/docs/framework/ref-" +"api/flwr.client.mod.html#module-flwr.client.mod)" +msgstr "" + +#: ../../source/ref-changelog.md:69 +msgid "" +"**General updates to Flower Examples** " +"([#3205](https://github.com/adap/flower/pull/3205), " +"[#3226](https://github.com/adap/flower/pull/3226), " +"[#3211](https://github.com/adap/flower/pull/3211), " +"[#3252](https://github.com/adap/flower/pull/3252), " +"[#3427](https://github.com/adap/flower/pull/3427), " +"[#3410](https://github.com/adap/flower/pull/3410), " +"[#3426](https://github.com/adap/flower/pull/3426), " +"[#3228](https://github.com/adap/flower/pull/3228), " +"[#3342](https://github.com/adap/flower/pull/3342), " +"[#3200](https://github.com/adap/flower/pull/3200), " +"[#3202](https://github.com/adap/flower/pull/3202), " +"[#3394](https://github.com/adap/flower/pull/3394), " +"[#3488](https://github.com/adap/flower/pull/3488), " +"[#3329](https://github.com/adap/flower/pull/3329), " +"[#3526](https://github.com/adap/flower/pull/3526), " +"[#3392](https://github.com/adap/flower/pull/3392), " +"[#3474](https://github.com/adap/flower/pull/3474), " +"[#3269](https://github.com/adap/flower/pull/3269))" +msgstr "" + +#: ../../source/ref-changelog.md:71 +msgid "As always, Flower code examples have received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:73 +msgid "" +"**General improvements** " +"([#3532](https://github.com/adap/flower/pull/3532), " +"[#3318](https://github.com/adap/flower/pull/3318), " +"[#3565](https://github.com/adap/flower/pull/3565), " +"[#3296](https://github.com/adap/flower/pull/3296), " +"[#3305](https://github.com/adap/flower/pull/3305), " +"[#3246](https://github.com/adap/flower/pull/3246), " +"[#3224](https://github.com/adap/flower/pull/3224), " +"[#3475](https://github.com/adap/flower/pull/3475), " +"[#3297](https://github.com/adap/flower/pull/3297), " +"[#3317](https://github.com/adap/flower/pull/3317), " +"[#3429](https://github.com/adap/flower/pull/3429), " +"[#3196](https://github.com/adap/flower/pull/3196), " +"[#3534](https://github.com/adap/flower/pull/3534), " +"[#3240](https://github.com/adap/flower/pull/3240), " +"[#3365](https://github.com/adap/flower/pull/3365), " +"[#3407](https://github.com/adap/flower/pull/3407), " +"[#3563](https://github.com/adap/flower/pull/3563), " +"[#3344](https://github.com/adap/flower/pull/3344), " +"[#3330](https://github.com/adap/flower/pull/3330), " +"[#3436](https://github.com/adap/flower/pull/3436), " +"[#3300](https://github.com/adap/flower/pull/3300), " +"[#3327](https://github.com/adap/flower/pull/3327), " +"[#3254](https://github.com/adap/flower/pull/3254), " +"[#3253](https://github.com/adap/flower/pull/3253), " +"[#3419](https://github.com/adap/flower/pull/3419), " +"[#3289](https://github.com/adap/flower/pull/3289), " +"[#3208](https://github.com/adap/flower/pull/3208), " +"[#3245](https://github.com/adap/flower/pull/3245), " +"[#3319](https://github.com/adap/flower/pull/3319), " +"[#3203](https://github.com/adap/flower/pull/3203), " +"[#3423](https://github.com/adap/flower/pull/3423), " +"[#3352](https://github.com/adap/flower/pull/3352), " +"[#3292](https://github.com/adap/flower/pull/3292), " +"[#3261](https://github.com/adap/flower/pull/3261))" +msgstr "" + +#: ../../source/ref-changelog.md:75 ../../source/ref-changelog.md:1058 +msgid "Deprecations" +msgstr "" + +#: ../../source/ref-changelog.md:77 +msgid "**Deprecate Python 3.8 support**" +msgstr "" + +#: ../../source/ref-changelog.md:79 +msgid "" +"Python 3.8 will stop receiving security fixes in [October " +"2024](https://devguide.python.org/versions/). Support for Python 3.8 is " +"now deprecated and will be removed in an upcoming release." +msgstr "" + +#: ../../source/ref-changelog.md:81 +msgid "" +"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-" +"api` ([#3416](https://github.com/adap/flower/pull/3416), " +"[#3420](https://github.com/adap/flower/pull/3420))" +msgstr "" + +#: ../../source/ref-changelog.md:83 +msgid "" +"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api`" +" and `flower-fleet-api`. Both commands will be removed in an upcoming " +"release. Use `flower-superlink` instead." +msgstr "" + +#: ../../source/ref-changelog.md:85 +msgid "" +"**Deprecate** `--server` **in favor of** `--superlink` " +"([#3518](https://github.com/adap/flower/pull/3518))" +msgstr "" + +#: ../../source/ref-changelog.md:87 +msgid "" +"The commands `flower-server-app` and `flower-client-app` should use " +"`--superlink` instead of the now deprecated `--server`. Support for " +"`--server` will be removed in a future release." +msgstr "" + +#: ../../source/ref-changelog.md:89 ../../source/ref-changelog.md:163 +#: ../../source/ref-changelog.md:238 ../../source/ref-changelog.md:350 +#: ../../source/ref-changelog.md:440 ../../source/ref-changelog.md:504 +#: ../../source/ref-changelog.md:562 ../../source/ref-changelog.md:631 +#: ../../source/ref-changelog.md:693 ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:868 ../../source/ref-changelog.md:939 +#: ../../source/ref-changelog.md:976 ../../source/ref-changelog.md:1019 +msgid "Incompatible changes" +msgstr "" + +#: ../../source/ref-changelog.md:91 +msgid "" +"**Replace** `flower-superlink` **CLI option** `--certificates` **with** " +"`--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` " +"([#3512](https://github.com/adap/flower/pull/3512), " +"[#3408](https://github.com/adap/flower/pull/3408))" +msgstr "" + +#: ../../source/ref-changelog.md:93 +msgid "" +"SSL-related `flower-superlink` CLI arguments were restructured in an " +"incompatible way. Instead of passing a single `--certificates` flag with " +"three values, you now need to pass three flags (`--ssl-ca-certfile`, " +"`--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the " +"[SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-" +"connections.html) documentation page for details." +msgstr "" + +#: ../../source/ref-changelog.md:95 +msgid "" +"**Remove SuperLink** `--vce` **option** " +"([#3513](https://github.com/adap/flower/pull/3513))" +msgstr "" + +#: ../../source/ref-changelog.md:97 +msgid "" +"Instead of separately starting a SuperLink and a `ServerApp` for " +"simulation, simulations must now be started using the single `flower-" +"simulation` command." +msgstr "" + +#: ../../source/ref-changelog.md:99 +msgid "" +"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** " +"([#3527](https://github.com/adap/flower/pull/3527))" +msgstr "" + +#: ../../source/ref-changelog.md:101 +msgid "" +"To simplify the usage of `flower-superlink`, previously separate sets of " +"CLI options for gRPC and REST were merged into one unified set of " +"options. Consult the [Flower CLI reference " +"documentation](https://flower.ai/docs/framework/ref-api-cli.html) for " +"details." +msgstr "" + +#: ../../source/ref-changelog.md:103 +msgid "v1.8.0 (2024-04-03)" +msgstr "" + +#: ../../source/ref-changelog.md:109 +msgid "" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " +"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " +"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " +"`tabdar-khan` " +msgstr "" + +#: ../../source/ref-changelog.md:113 +msgid "" +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" +msgstr "" + +#: ../../source/ref-changelog.md:115 +msgid "" +"The Flower Next high-level API is stable! Flower Next is the future of " +"Flower - all new features (like Flower Mods) will be built on top of it. " +"You can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " +"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." +" Flower Next allows you to run multiple projects concurrently (we call " +"this multi-run) and execute the same project in either simulation " +"environments or deployment environments without having to change a single" +" line of code. The best part? It's fully compatible with existing Flower " +"projects that use `Strategy`, `NumPyClient` & co." +msgstr "" + +#: ../../source/ref-changelog.md:117 +msgid "" +"**Introduce Flower Next low-level API (preview)** " +"([#3062](https://github.com/adap/flower/pull/3062), " +"[#3034](https://github.com/adap/flower/pull/3034), " +"[#3069](https://github.com/adap/flower/pull/3069))" +msgstr "" + +#: ../../source/ref-changelog.md:119 +msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " "`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " "new Flower Next *low-level* API. The low-level API allows for granular " @@ -13689,7 +14353,7 @@ msgid "" "custom SMPC protocols, to name just a few." msgstr "" -#: ../../source/ref-changelog.md:29 +#: ../../source/ref-changelog.md:121 msgid "" "**Introduce Flower Mods (preview)** " "([#3054](https://github.com/adap/flower/pull/3054), " @@ -13697,7 +14361,7 @@ msgid "" "[#3083](https://github.com/adap/flower/pull/3083))" msgstr "" -#: ../../source/ref-changelog.md:31 +#: ../../source/ref-changelog.md:123 msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " "edit or handle them directly. Mods can be used to develop pluggable " @@ -13709,7 +14373,7 @@ msgid "" "can already use it to experiment with arbirtrary SMPC protocols." msgstr "" -#: ../../source/ref-changelog.md:33 +#: ../../source/ref-changelog.md:125 msgid "" "**Fine-tune LLMs with LLM FlowerTune** " "([#3029](https://github.com/adap/flower/pull/3029), " @@ -13721,7 +14385,7 @@ msgid "" "[#3172](https://github.com/adap/flower/pull/3172))" msgstr "" -#: ../../source/ref-changelog.md:35 +#: ../../source/ref-changelog.md:127 msgid "" "We are introducing LLM FlowerTune, an introductory example that " "demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " @@ -13731,7 +14395,7 @@ msgid "" "-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -#: ../../source/ref-changelog.md:37 +#: ../../source/ref-changelog.md:129 msgid "" "**Introduce built-in Differential Privacy (preview)** " "([#2798](https://github.com/adap/flower/pull/2798), " @@ -13745,7 +14409,7 @@ msgid "" "[#3074](https://github.com/adap/flower/pull/3074))" msgstr "" -#: ../../source/ref-changelog.md:39 +#: ../../source/ref-changelog.md:131 msgid "" "Built-in Differential Privacy is here! Flower supports both central and " "local differential privacy (DP). Central DP can be configured with either" @@ -13758,7 +14422,7 @@ msgid "" "/how-to-use-differential-privacy.html) in Flower." msgstr "" -#: ../../source/ref-changelog.md:41 +#: ../../source/ref-changelog.md:133 msgid "" "**Introduce built-in Secure Aggregation (preview)** " "([#3120](https://github.com/adap/flower/pull/3120), " @@ -13766,7 +14430,7 @@ msgid "" "[#3108](https://github.com/adap/flower/pull/3108))" msgstr "" -#: ../../source/ref-changelog.md:43 +#: ../../source/ref-changelog.md:135 msgid "" "Built-in Secure Aggregation is here! Flower now supports different secure" " aggregation protocols out-of-the-box. The best part? You can add secure " @@ -13779,7 +14443,7 @@ msgid "" "in the same project." msgstr "" -#: ../../source/ref-changelog.md:45 +#: ../../source/ref-changelog.md:137 msgid "" "**Introduce** `flwr` **CLI (preview)** " "([#2942](https://github.com/adap/flower/pull/2942), " @@ -13793,13 +14457,13 @@ msgid "" "[#3142](https://github.com/adap/flower/pull/3142))" msgstr "" -#: ../../source/ref-changelog.md:47 +#: ../../source/ref-changelog.md:139 msgid "" "A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" " and then running them using the Simulation Engine (`flwr run`)." msgstr "" -#: ../../source/ref-changelog.md:49 +#: ../../source/ref-changelog.md:141 msgid "" "**Introduce Flower Next Simulation Engine** " "([#3024](https://github.com/adap/flower/pull/3024), " @@ -13814,20 +14478,20 @@ msgid "" "[#3008](https://github.com/adap/flower/pull/3008))" msgstr "" -#: ../../source/ref-changelog.md:51 +#: ../../source/ref-changelog.md:143 msgid "" "The Flower Simulation Engine can now run Flower Next projects. For " "notebook environments, there's also a new `run_simulation` function that " "can run `ServerApp` and `ClientApp`." msgstr "" -#: ../../source/ref-changelog.md:53 +#: ../../source/ref-changelog.md:145 msgid "" "**Handle SuperNode connection errors** " "([#2969](https://github.com/adap/flower/pull/2969))" msgstr "" -#: ../../source/ref-changelog.md:55 +#: ../../source/ref-changelog.md:147 msgid "" "A SuperNode will now try to reconnect indefinitely to the SuperLink in " "case of connection errors. The arguments `--max-retries` and `--max-wait-" @@ -13838,7 +14502,7 @@ msgid "" "reconnect to the SuperLink." msgstr "" -#: ../../source/ref-changelog.md:57 +#: ../../source/ref-changelog.md:149 msgid "" "**General updates to Flower Baselines** " "([#2904](https://github.com/adap/flower/pull/2904), " @@ -13847,13 +14511,13 @@ msgid "" "[#2968](https://github.com/adap/flower/pull/2968))" msgstr "" -#: ../../source/ref-changelog.md:59 +#: ../../source/ref-changelog.md:151 msgid "" "There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " "baseline. Several other baselined have been updated as well." msgstr "" -#: ../../source/ref-changelog.md:61 +#: ../../source/ref-changelog.md:153 msgid "" "**Improve documentation and translations** " "([#3050](https://github.com/adap/flower/pull/3050), " @@ -13874,14 +14538,14 @@ msgid "" "[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" -#: ../../source/ref-changelog.md:63 +#: ../../source/ref-changelog.md:155 msgid "" "As usual, we merged many smaller and larger improvements to the " "documentation. A special thank you goes to [Sebastian van der " "Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" -#: ../../source/ref-changelog.md:65 +#: ../../source/ref-changelog.md:157 msgid "" "**General updates to Flower Examples** " "([3134](https://github.com/adap/flower/pull/3134), " @@ -13897,7 +14561,7 @@ msgid "" "[#3117](https://github.com/adap/flower/pull/3117))" msgstr "" -#: ../../source/ref-changelog.md:67 +#: ../../source/ref-changelog.md:159 msgid "" "Two new examples show federated training of a Vision Transformer (ViT) " "and federated learning in a medical context using the popular MONAI " @@ -13906,7 +14570,7 @@ msgid "" "received considerable updates as well." msgstr "" -#: ../../source/ref-changelog.md:69 +#: ../../source/ref-changelog.md:161 msgid "" "**General improvements** " "([#3171](https://github.com/adap/flower/pull/3171), " @@ -13984,11 +14648,17 @@ msgid "" "[#2954](https://github.com/adap/flower/pull/2954))" msgstr "" -#: ../../source/ref-changelog.md:75 +#: ../../source/ref-changelog.md:165 ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:506 ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:633 ../../source/ref-changelog.md:695 +msgid "None" +msgstr "" + +#: ../../source/ref-changelog.md:167 msgid "v1.7.0 (2024-02-05)" msgstr "" -#: ../../source/ref-changelog.md:81 +#: ../../source/ref-changelog.md:173 msgid "" "`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " "Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " @@ -13998,7 +14668,7 @@ msgid "" "Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" -#: ../../source/ref-changelog.md:85 +#: ../../source/ref-changelog.md:177 msgid "" "**Introduce stateful clients (experimental)** " "([#2770](https://github.com/adap/flower/pull/2770), " @@ -14008,7 +14678,7 @@ msgid "" "[#2769](https://github.com/adap/flower/pull/2769))" msgstr "" -#: ../../source/ref-changelog.md:87 +#: ../../source/ref-changelog.md:179 msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " @@ -14021,13 +14691,13 @@ msgid "" "unified way across simulation and deployment." msgstr "" -#: ../../source/ref-changelog.md:89 +#: ../../source/ref-changelog.md:181 msgid "" "**Improve performance** " "([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" -#: ../../source/ref-changelog.md:91 +#: ../../source/ref-changelog.md:183 msgid "" "Flower is faster than ever. All `FedAvg`-derived strategies now use in-" "place aggregation to reduce memory consumption. The Flower client " @@ -14036,27 +14706,27 @@ msgid "" "training time is short." msgstr "" -#: ../../source/ref-changelog.md:93 +#: ../../source/ref-changelog.md:185 msgid "" "**Support Federated Learning with Apple MLX and Flower** " "([#2693](https://github.com/adap/flower/pull/2693))" msgstr "" -#: ../../source/ref-changelog.md:95 +#: ../../source/ref-changelog.md:187 msgid "" "Flower has official support for federated learning using [Apple " "MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " "example." msgstr "" -#: ../../source/ref-changelog.md:97 +#: ../../source/ref-changelog.md:189 msgid "" "**Introduce new XGBoost cyclic strategy** " "([#2666](https://github.com/adap/flower/pull/2666), " "[#2668](https://github.com/adap/flower/pull/2668))" msgstr "" -#: ../../source/ref-changelog.md:99 +#: ../../source/ref-changelog.md:191 msgid "" "A new strategy called `FedXgbCyclic` supports a client-by-client style of" " training (often called cyclic). The `xgboost-comprehensive` code example" @@ -14065,31 +14735,31 @@ msgid "" "offers best-in-class XGBoost support." msgstr "" -#: ../../source/ref-changelog.md:101 +#: ../../source/ref-changelog.md:193 msgid "" "**Support Python 3.11** " "([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" -#: ../../source/ref-changelog.md:103 +#: ../../source/ref-changelog.md:195 msgid "" "Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " "ensure better support for users using more recent Python versions." msgstr "" -#: ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:197 msgid "" "**Update gRPC and ProtoBuf dependencies** " "([#2814](https://github.com/adap/flower/pull/2814))" msgstr "" -#: ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:199 msgid "" "The `grpcio` and `protobuf` dependencies were updated to their latest " "versions for improved security and performance." msgstr "" -#: ../../source/ref-changelog.md:109 +#: ../../source/ref-changelog.md:201 msgid "" "**Introduce Docker image for Flower server** " "([#2700](https://github.com/adap/flower/pull/2700), " @@ -14103,7 +14773,7 @@ msgid "" "[#2701](https://github.com/adap/flower/pull/2701))" msgstr "" -#: ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:203 msgid "" "The Flower server can now be run using an official Docker image. A new " "how-to guide explains [how to run Flower using " @@ -14111,25 +14781,25 @@ msgid "" "docker.html). An official Flower client Docker image will follow." msgstr "" -#: ../../source/ref-changelog.md:113 +#: ../../source/ref-changelog.md:205 msgid "" "**Introduce** `flower-via-docker-compose` **example** " "([#2626](https://github.com/adap/flower/pull/2626))" msgstr "" -#: ../../source/ref-changelog.md:115 +#: ../../source/ref-changelog.md:207 msgid "" "**Introduce** `quickstart-sklearn-tabular` **example** " "([#2719](https://github.com/adap/flower/pull/2719))" msgstr "" -#: ../../source/ref-changelog.md:117 +#: ../../source/ref-changelog.md:209 msgid "" "**Introduce** `custom-metrics` **example** " "([#1958](https://github.com/adap/flower/pull/1958))" msgstr "" -#: ../../source/ref-changelog.md:119 +#: ../../source/ref-changelog.md:211 msgid "" "**Update code examples to use Flower Datasets** " "([#2450](https://github.com/adap/flower/pull/2450), " @@ -14138,13 +14808,13 @@ msgid "" "[#2712](https://github.com/adap/flower/pull/2712))" msgstr "" -#: ../../source/ref-changelog.md:121 +#: ../../source/ref-changelog.md:213 msgid "" "Several code examples were updated to use [Flower " "Datasets](https://flower.ai/docs/datasets/)." msgstr "" -#: ../../source/ref-changelog.md:123 +#: ../../source/ref-changelog.md:215 msgid "" "**General updates to Flower Examples** " "([#2381](https://github.com/adap/flower/pull/2381), " @@ -14159,41 +14829,41 @@ msgid "" "[#2655](https://github.com/adap/flower/pull/2655))" msgstr "" -#: ../../source/ref-changelog.md:125 +#: ../../source/ref-changelog.md:217 msgid "Many Flower code examples received substantial updates." msgstr "" -#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 +#: ../../source/ref-changelog.md:219 ../../source/ref-changelog.md:312 msgid "**Update Flower Baselines**" msgstr "" -#: ../../source/ref-changelog.md:129 +#: ../../source/ref-changelog.md:221 msgid "" "HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " "[#2771](https://github.com/adap/flower/pull/2771))" msgstr "" -#: ../../source/ref-changelog.md:130 +#: ../../source/ref-changelog.md:222 msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "" -#: ../../source/ref-changelog.md:131 +#: ../../source/ref-changelog.md:223 msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "" -#: ../../source/ref-changelog.md:132 +#: ../../source/ref-changelog.md:224 msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" msgstr "" -#: ../../source/ref-changelog.md:133 +#: ../../source/ref-changelog.md:225 msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" msgstr "" -#: ../../source/ref-changelog.md:134 +#: ../../source/ref-changelog.md:226 msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" msgstr "" -#: ../../source/ref-changelog.md:136 +#: ../../source/ref-changelog.md:228 msgid "" "**Improve documentation** " "([#2674](https://github.com/adap/flower/pull/2674), " @@ -14204,7 +14874,7 @@ msgid "" "[#2900](https://github.com/adap/flower/pull/2900))" msgstr "" -#: ../../source/ref-changelog.md:138 +#: ../../source/ref-changelog.md:230 msgid "" "**Improved testing and development infrastructure** " "([#2797](https://github.com/adap/flower/pull/2797), " @@ -14238,13 +14908,13 @@ msgid "" "[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" -#: ../../source/ref-changelog.md:140 +#: ../../source/ref-changelog.md:232 msgid "" "The Flower testing and development infrastructure has received " "substantial updates. This makes Flower 1.7 the most tested release ever." msgstr "" -#: ../../source/ref-changelog.md:142 +#: ../../source/ref-changelog.md:234 msgid "" "**Update dependencies** " "([#2753](https://github.com/adap/flower/pull/2753), " @@ -14268,7 +14938,7 @@ msgid "" "[#2789](https://github.com/adap/flower/pull/2789))" msgstr "" -#: ../../source/ref-changelog.md:144 +#: ../../source/ref-changelog.md:236 msgid "" "**General improvements** " "([#2803](https://github.com/adap/flower/pull/2803), " @@ -14309,14 +14979,14 @@ msgid "" "[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" -#: ../../source/ref-changelog.md:148 +#: ../../source/ref-changelog.md:240 msgid "" "**Deprecate** `start_numpy_client` " "([#2563](https://github.com/adap/flower/pull/2563), " "[#2718](https://github.com/adap/flower/pull/2718))" msgstr "" -#: ../../source/ref-changelog.md:150 +#: ../../source/ref-changelog.md:242 msgid "" "Until now, clients of type `NumPyClient` needed to be started via " "`start_numpy_client`. In our efforts to consolidate framework APIs, we " @@ -14327,63 +14997,63 @@ msgid "" "updated accordingly." msgstr "" -#: ../../source/ref-changelog.md:152 +#: ../../source/ref-changelog.md:244 msgid "" "**Deprecate legacy DP wrappers** " "([#2749](https://github.com/adap/flower/pull/2749))" msgstr "" -#: ../../source/ref-changelog.md:154 +#: ../../source/ref-changelog.md:246 msgid "" "Legacy DP wrapper classes are deprecated, but still functional. This is " "in preparation for an all-new pluggable version of differential privacy " "support in Flower." msgstr "" -#: ../../source/ref-changelog.md:156 +#: ../../source/ref-changelog.md:248 msgid "" "**Make optional arg** `--callable` **in** `flower-client` **a required " "positional arg** ([#2673](https://github.com/adap/flower/pull/2673))" msgstr "" -#: ../../source/ref-changelog.md:158 +#: ../../source/ref-changelog.md:250 msgid "" "**Rename** `certificates` **to** `root_certificates` **in** `Driver` " "([#2890](https://github.com/adap/flower/pull/2890))" msgstr "" -#: ../../source/ref-changelog.md:160 +#: ../../source/ref-changelog.md:252 msgid "" "**Drop experimental** `Task` **fields** " "([#2866](https://github.com/adap/flower/pull/2866), " "[#2865](https://github.com/adap/flower/pull/2865))" msgstr "" -#: ../../source/ref-changelog.md:162 +#: ../../source/ref-changelog.md:254 msgid "" "Experimental fields `sa`, `legacy_server_message` and " "`legacy_client_message` were removed from `Task` message. The removed " "fields are superseded by the new `RecordSet` abstraction." msgstr "" -#: ../../source/ref-changelog.md:164 +#: ../../source/ref-changelog.md:256 msgid "" "**Retire MXNet examples** " "([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" -#: ../../source/ref-changelog.md:166 +#: ../../source/ref-changelog.md:258 msgid "" "The development of the MXNet fremework has ended and the project is now " "[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " "examples won't receive updates." msgstr "" -#: ../../source/ref-changelog.md:168 +#: ../../source/ref-changelog.md:260 msgid "v1.6.0 (2023-11-28)" msgstr "" -#: ../../source/ref-changelog.md:174 +#: ../../source/ref-changelog.md:266 msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " @@ -14393,13 +15063,13 @@ msgid "" "`cnxdeveloper`, `k3nfalt` " msgstr "" -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:270 msgid "" "**Add experimental support for Python 3.12** " "([#2565](https://github.com/adap/flower/pull/2565))" msgstr "" -#: ../../source/ref-changelog.md:180 +#: ../../source/ref-changelog.md:272 msgid "" "**Add new XGBoost examples** " "([#2612](https://github.com/adap/flower/pull/2612), " @@ -14410,19 +15080,19 @@ msgid "" "[#2567](https://github.com/adap/flower/pull/2567))" msgstr "" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:274 msgid "" "We have added a new `xgboost-quickstart` example alongside a new " "`xgboost-comprehensive` example that goes more in-depth." msgstr "" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:276 msgid "" "**Add Vertical FL example** " "([#2598](https://github.com/adap/flower/pull/2598))" msgstr "" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:278 msgid "" "We had many questions about Vertical Federated Learning using Flower, so " "we decided to add an simple example for it on the [Titanic " @@ -14430,29 +15100,29 @@ msgid "" "tutorial (in the README)." msgstr "" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:280 msgid "" "**Support custom** `ClientManager` **in** `start_driver()` " "([#2292](https://github.com/adap/flower/pull/2292))" msgstr "" -#: ../../source/ref-changelog.md:190 +#: ../../source/ref-changelog.md:282 msgid "" "**Update REST API to support create and delete nodes** " "([#2283](https://github.com/adap/flower/pull/2283))" msgstr "" -#: ../../source/ref-changelog.md:192 +#: ../../source/ref-changelog.md:284 msgid "" "**Update the Android SDK** " "([#2187](https://github.com/adap/flower/pull/2187))" msgstr "" -#: ../../source/ref-changelog.md:194 +#: ../../source/ref-changelog.md:286 msgid "Add gRPC request-response capability to the Android SDK." msgstr "" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:288 msgid "" "**Update the C++ SDK** " "([#2537](https://github.com/adap/flower/pull/2537), " @@ -14461,18 +15131,18 @@ msgid "" "[#2522](https://github.com/adap/flower/pull/2522))" msgstr "" -#: ../../source/ref-changelog.md:198 +#: ../../source/ref-changelog.md:290 msgid "Add gRPC request-response capability to the C++ SDK." msgstr "" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:292 msgid "" "**Make HTTPS the new default** " "([#2591](https://github.com/adap/flower/pull/2591), " "[#2636](https://github.com/adap/flower/pull/2636))" msgstr "" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:294 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " "passing `--certificates`, but users can enable `--insecure` to use HTTP " @@ -14482,21 +15152,21 @@ msgid "" "enable insecure HTTP connections." msgstr "" -#: ../../source/ref-changelog.md:204 +#: ../../source/ref-changelog.md:296 msgid "" "For backward compatibility, `start_client()` and `start_numpy_client()` " "will still start in insecure mode by default. In a future release, " "insecure connections will require user opt-in by passing `insecure=True`." msgstr "" -#: ../../source/ref-changelog.md:206 +#: ../../source/ref-changelog.md:298 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " "[#2390](https://github.com/adap/flower/pull/2390), " "[#2493](https://github.com/adap/flower/pull/2493))" msgstr "" -#: ../../source/ref-changelog.md:208 +#: ../../source/ref-changelog.md:300 msgid "" "Using the `client_fn`, Flower clients can interchangeably run as " "standalone processes (i.e. via `start_client`) or in simulation (i.e. via" @@ -14505,92 +15175,92 @@ msgid "" "convert a `NumPyClient` to a `Client`." msgstr "" -#: ../../source/ref-changelog.md:210 +#: ../../source/ref-changelog.md:302 msgid "" "**Add new** `Bulyan` **strategy** " "([#1817](https://github.com/adap/flower/pull/1817), " "[#1891](https://github.com/adap/flower/pull/1891))" msgstr "" -#: ../../source/ref-changelog.md:212 +#: ../../source/ref-changelog.md:304 msgid "" "The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " "2018](https://arxiv.org/abs/1802.07927)" msgstr "" -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:306 msgid "" "**Add new** `XGB Bagging` **strategy** " "([#2611](https://github.com/adap/flower/pull/2611))" msgstr "" -#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 +#: ../../source/ref-changelog.md:308 ../../source/ref-changelog.md:310 msgid "" "**Introduce `WorkloadState`** " "([#2564](https://github.com/adap/flower/pull/2564), " "[#2632](https://github.com/adap/flower/pull/2632))" msgstr "" -#: ../../source/ref-changelog.md:222 +#: ../../source/ref-changelog.md:314 msgid "" "FedProx ([#2210](https://github.com/adap/flower/pull/2210), " "[#2286](https://github.com/adap/flower/pull/2286), " "[#2509](https://github.com/adap/flower/pull/2509))" msgstr "" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-changelog.md:316 msgid "" "Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " "[#2400](https://github.com/adap/flower/pull/2400))" msgstr "" -#: ../../source/ref-changelog.md:226 +#: ../../source/ref-changelog.md:318 msgid "" "FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " "[#2507](https://github.com/adap/flower/pull/2507))" msgstr "" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-changelog.md:320 msgid "" "TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " "[#2508](https://github.com/adap/flower/pull/2508))" msgstr "" -#: ../../source/ref-changelog.md:230 +#: ../../source/ref-changelog.md:322 msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "" -#: ../../source/ref-changelog.md:232 +#: ../../source/ref-changelog.md:324 msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "" -#: ../../source/ref-changelog.md:234 +#: ../../source/ref-changelog.md:326 msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "" -#: ../../source/ref-changelog.md:236 +#: ../../source/ref-changelog.md:328 msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "" -#: ../../source/ref-changelog.md:238 +#: ../../source/ref-changelog.md:330 msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "" -#: ../../source/ref-changelog.md:240 +#: ../../source/ref-changelog.md:332 msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "" -#: ../../source/ref-changelog.md:242 +#: ../../source/ref-changelog.md:334 msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "" -#: ../../source/ref-changelog.md:244 +#: ../../source/ref-changelog.md:336 msgid "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " "[#2615](https://github.com/adap/flower/pull/2615))" msgstr "" -#: ../../source/ref-changelog.md:246 +#: ../../source/ref-changelog.md:338 msgid "" "**General updates to Flower Examples** " "([#2384](https://github.com/adap/flower/pull/2384), " @@ -14600,7 +15270,7 @@ msgid "" "[#2545](https://github.com/adap/flower/pull/2545))" msgstr "" -#: ../../source/ref-changelog.md:248 +#: ../../source/ref-changelog.md:340 msgid "" "**General updates to Flower Baselines** " "([#2301](https://github.com/adap/flower/pull/2301), " @@ -14618,7 +15288,7 @@ msgid "" "[#2470](https://github.com/adap/flower/pull/2470))" msgstr "" -#: ../../source/ref-changelog.md:250 +#: ../../source/ref-changelog.md:342 msgid "" "**General updates to the simulation engine** " "([#2331](https://github.com/adap/flower/pull/2331), " @@ -14627,7 +15297,7 @@ msgid "" "[#2294](https://github.com/adap/flower/pull/2294))" msgstr "" -#: ../../source/ref-changelog.md:252 +#: ../../source/ref-changelog.md:344 msgid "" "**General updates to Flower SDKs** " "([#2288](https://github.com/adap/flower/pull/2288), " @@ -14639,7 +15309,7 @@ msgid "" "[#2623](https://github.com/adap/flower/pull/2623))" msgstr "" -#: ../../source/ref-changelog.md:254 +#: ../../source/ref-changelog.md:346 msgid "" "**General improvements** " "([#2309](https://github.com/adap/flower/pull/2309), " @@ -14671,13 +15341,13 @@ msgid "" "[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" -#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 -#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 -#: ../../source/ref-changelog.md:531 +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:502 ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:623 msgid "Flower received many improvements under the hood, too many to list here." msgstr "" -#: ../../source/ref-changelog.md:260 +#: ../../source/ref-changelog.md:352 msgid "" "**Remove support for Python 3.7** " "([#2280](https://github.com/adap/flower/pull/2280), " @@ -14688,30 +15358,30 @@ msgid "" "[#2356](https://github.com/adap/flower/pull/2356))" msgstr "" -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:354 msgid "" "Python 3.7 support was deprecated in Flower 1.5, and this release removes" " support. Flower now requires Python 3.8." msgstr "" -#: ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:356 msgid "" "**Remove experimental argument** `rest` **from** `start_client` " "([#2324](https://github.com/adap/flower/pull/2324))" msgstr "" -#: ../../source/ref-changelog.md:266 +#: ../../source/ref-changelog.md:358 msgid "" "The (still experimental) argument `rest` was removed from `start_client` " "and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " "experimental REST API instead." msgstr "" -#: ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:360 msgid "v1.5.0 (2023-08-31)" msgstr "" -#: ../../source/ref-changelog.md:274 +#: ../../source/ref-changelog.md:366 msgid "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -14720,7 +15390,7 @@ msgid "" "TOKEN_v1.5.0-->" msgstr "" -#: ../../source/ref-changelog.md:278 +#: ../../source/ref-changelog.md:370 msgid "" "**Introduce new simulation engine** " "([#1969](https://github.com/adap/flower/pull/1969), " @@ -14728,7 +15398,7 @@ msgid "" "[#2248](https://github.com/adap/flower/pull/2248))" msgstr "" -#: ../../source/ref-changelog.md:280 +#: ../../source/ref-changelog.md:372 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " "remains fully backwards compatible. It offers much improved stability and" @@ -14737,7 +15407,7 @@ msgid "" "only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" -#: ../../source/ref-changelog.md:282 +#: ../../source/ref-changelog.md:374 msgid "" "Comprehensive documentation includes a new [how-to run " "simulations](https://flower.ai/docs/framework/how-to-run-" @@ -14748,7 +15418,7 @@ msgid "" "series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" -#: ../../source/ref-changelog.md:284 +#: ../../source/ref-changelog.md:376 msgid "" "**Restructure Flower Docs** " "([#1824](https://github.com/adap/flower/pull/1824), " @@ -14780,7 +15450,7 @@ msgid "" "[#2227](https://github.com/adap/flower/pull/2227))" msgstr "" -#: ../../source/ref-changelog.md:286 +#: ../../source/ref-changelog.md:378 msgid "" "Much effort went into a completely restructured Flower docs experience. " "The documentation on [flower.ai/docs](https://flower.ai/docs) is now " @@ -14788,34 +15458,34 @@ msgid "" "Flower iOS SDK, and code example projects." msgstr "" -#: ../../source/ref-changelog.md:288 +#: ../../source/ref-changelog.md:380 msgid "" "**Introduce Flower Swift SDK** " "([#1858](https://github.com/adap/flower/pull/1858), " "[#1897](https://github.com/adap/flower/pull/1897))" msgstr "" -#: ../../source/ref-changelog.md:290 +#: ../../source/ref-changelog.md:382 msgid "" "This is the first preview release of the Flower Swift SDK. Flower support" " on iOS is improving, and alongside the Swift SDK and code example, there" " is now also an iOS quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:384 msgid "" "**Introduce Flower Android SDK** " "([#2131](https://github.com/adap/flower/pull/2131))" msgstr "" -#: ../../source/ref-changelog.md:294 +#: ../../source/ref-changelog.md:386 msgid "" "This is the first preview release of the Flower Kotlin SDK. Flower " "support on Android is improving, and alongside the Kotlin SDK and code " "example, there is now also an Android quickstart tutorial." msgstr "" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:388 msgid "" "**Introduce new end-to-end testing infrastructure** " "([#1842](https://github.com/adap/flower/pull/1842), " @@ -14837,42 +15507,42 @@ msgid "" "[#2165](https://github.com/adap/flower/pull/2165))" msgstr "" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:390 msgid "" "A new testing infrastructure ensures that new changes stay compatible " "with existing framework integrations or strategies." msgstr "" -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:392 msgid "**Deprecate Python 3.7**" msgstr "" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:394 msgid "" "Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" " Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:396 msgid "" "**Add new** `FedTrimmedAvg` **strategy** " "([#1769](https://github.com/adap/flower/pull/1769), " "[#1853](https://github.com/adap/flower/pull/1853))" msgstr "" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:398 msgid "" "The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " "2018](https://arxiv.org/abs/1803.01498)." msgstr "" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:400 msgid "" "**Introduce start_driver** " "([#1697](https://github.com/adap/flower/pull/1697))" msgstr "" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:402 msgid "" "In addition to `start_server` and using the raw Driver API, there is a " "new `start_driver` function that allows for running `start_server` " @@ -14881,13 +15551,13 @@ msgid "" "`start_driver`." msgstr "" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:404 msgid "" "**Add parameter aggregation to** `mt-pytorch` **code example** " "([#1785](https://github.com/adap/flower/pull/1785))" msgstr "" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:406 msgid "" "The `mt-pytorch` example shows how to aggregate parameters when writing a" " driver script. The included `driver.py` and `server.py` have been " @@ -14895,53 +15565,53 @@ msgid "" "building server-side logic." msgstr "" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:408 msgid "" "**Migrate experimental REST API to Starlette** " "([2171](https://github.com/adap/flower/pull/2171))" msgstr "" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:410 msgid "" "The (experimental) REST API used to be implemented in " "[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" " use [Starlette](https://www.starlette.io/) directly." msgstr "" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:412 msgid "" "Please note: The REST request-response API is still experimental and will" " likely change significantly over time." msgstr "" -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:414 msgid "" "**Introduce experimental gRPC request-response API** " "([#1867](https://github.com/adap/flower/pull/1867), " "[#1901](https://github.com/adap/flower/pull/1901))" msgstr "" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:416 msgid "" "In addition to the existing gRPC API (based on bidirectional streaming) " "and the experimental REST API, there is now a new gRPC API that uses a " "request-response model to communicate with client nodes." msgstr "" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:418 msgid "" "Please note: The gRPC request-response API is still experimental and will" " likely change significantly over time." msgstr "" -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:420 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " "`start_client(transport=\"rest\")` " "([#1880](https://github.com/adap/flower/pull/1880))" msgstr "" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:422 msgid "" "The (experimental) `start_client` argument `rest` was deprecated in " "favour of a new argument `transport`. `start_client(transport=\"rest\")` " @@ -14950,30 +15620,30 @@ msgid "" "argument `rest` will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:424 msgid "" "**Add a new gRPC option** " "([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:426 msgid "" "We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" " option set to 0 by default. This prevents the clients from sending " "keepalive pings when there is no outstanding stream." msgstr "" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:428 msgid "" "**Improve example notebooks** " "([#2005](https://github.com/adap/flower/pull/2005))" msgstr "" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:430 msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:432 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " "[#1873](https://github.com/adap/flower/pull/1873), " @@ -14988,7 +15658,7 @@ msgid "" "[#2183](https://github.com/adap/flower/pull/2183))" msgstr "" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:434 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " @@ -14997,7 +15667,7 @@ msgid "" "(in addition to `pyproject.toml`)." msgstr "" -#: ../../source/ref-changelog.md:344 +#: ../../source/ref-changelog.md:436 msgid "" "**General improvements** " "([#1872](https://github.com/adap/flower/pull/1872), " @@ -15008,11 +15678,11 @@ msgid "" "[#2171](https://github.com/adap/flower/pull/2171))" msgstr "" -#: ../../source/ref-changelog.md:352 +#: ../../source/ref-changelog.md:444 msgid "v1.4.0 (2023-04-21)" msgstr "" -#: ../../source/ref-changelog.md:358 +#: ../../source/ref-changelog.md:450 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " @@ -15022,7 +15692,7 @@ msgid "" "`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:454 msgid "" "**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " "example)** ([#1694](https://github.com/adap/flower/pull/1694), " @@ -15033,7 +15703,7 @@ msgid "" "[#1795](https://github.com/adap/flower/pull/1795))" msgstr "" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:456 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " "gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" @@ -15044,14 +15714,14 @@ msgid "" "an XGBoost project." msgstr "" -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:458 msgid "" "**Introduce iOS SDK (preview)** " "([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" msgstr "" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:460 msgid "" "This is a major update for anyone wanting to implement Federated Learning" " on iOS mobile devices. We now have a swift iOS SDK present under " @@ -15062,14 +15732,14 @@ msgid "" "been updated!" msgstr "" -#: ../../source/ref-changelog.md:370 +#: ../../source/ref-changelog.md:462 msgid "" "**Introduce new \"What is Federated Learning?\" tutorial** " "([#1657](https://github.com/adap/flower/pull/1657), " "[#1721](https://github.com/adap/flower/pull/1721))" msgstr "" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:464 msgid "" "A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" "what-is-federated-learning.html) in our documentation explains the basics" @@ -15078,7 +15748,7 @@ msgid "" "interested in Federated Learning!" msgstr "" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:466 msgid "" "**Introduce new Flower Baseline: FedProx MNIST** " "([#1513](https://github.com/adap/flower/pull/1513), " @@ -15087,7 +15757,7 @@ msgid "" "[#1679](https://github.com/adap/flower/pull/1679))" msgstr "" -#: ../../source/ref-changelog.md:376 +#: ../../source/ref-changelog.md:468 msgid "" "This new baseline replicates the MNIST+CNN task from the paper [Federated" " Optimization in Heterogeneous Networks (Li et al., " @@ -15095,13 +15765,13 @@ msgid "" " which aims at making convergence more robust in heterogeneous settings." msgstr "" -#: ../../source/ref-changelog.md:378 +#: ../../source/ref-changelog.md:470 msgid "" "**Introduce new Flower Baseline: FedAvg FEMNIST** " "([#1655](https://github.com/adap/flower/pull/1655))" msgstr "" -#: ../../source/ref-changelog.md:380 +#: ../../source/ref-changelog.md:472 msgid "" "This new baseline replicates an experiment evaluating the performance of " "the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " @@ -15109,7 +15779,7 @@ msgid "" "2018)](https://arxiv.org/abs/1812.01097)." msgstr "" -#: ../../source/ref-changelog.md:382 +#: ../../source/ref-changelog.md:474 msgid "" "**Introduce (experimental) REST API** " "([#1594](https://github.com/adap/flower/pull/1594), " @@ -15121,20 +15791,20 @@ msgid "" "[#1733](https://github.com/adap/flower/pull/1733))" msgstr "" -#: ../../source/ref-changelog.md:384 +#: ../../source/ref-changelog.md:476 msgid "" "A new REST API has been introduced as an alternative to the gRPC-based " "communication stack. In this initial version, the REST API only supports " "anonymous clients." msgstr "" -#: ../../source/ref-changelog.md:386 +#: ../../source/ref-changelog.md:478 msgid "" "Please note: The REST API is still experimental and will likely change " "significantly over time." msgstr "" -#: ../../source/ref-changelog.md:388 +#: ../../source/ref-changelog.md:480 msgid "" "**Improve the (experimental) Driver API** " "([#1663](https://github.com/adap/flower/pull/1663), " @@ -15148,7 +15818,7 @@ msgid "" "[#1794](https://github.com/adap/flower/pull/1794))" msgstr "" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:482 msgid "" "The Driver API is still an experimental feature, but this release " "introduces some major upgrades. One of the main improvements is the " @@ -15158,26 +15828,26 @@ msgid "" "improves the memory efficiency of a long-running Flower server." msgstr "" -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:484 msgid "" "**Fix spilling issues related to Ray during simulations** " "([#1698](https://github.com/adap/flower/pull/1698))" msgstr "" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:486 msgid "" "While running long simulations, `ray` was sometimes spilling huge amounts" " of data that would make the training unable to continue. This is now " "fixed! 🎉" msgstr "" -#: ../../source/ref-changelog.md:396 +#: ../../source/ref-changelog.md:488 msgid "" "**Add new example using** `TabNet` **and Flower** " "([#1725](https://github.com/adap/flower/pull/1725))" msgstr "" -#: ../../source/ref-changelog.md:398 +#: ../../source/ref-changelog.md:490 msgid "" "TabNet is a powerful and flexible framework for training machine learning" " models on tabular data. We now have a federated example using Flower: " @@ -15185,32 +15855,32 @@ msgid "" "/quickstart-tabnet)." msgstr "" -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:492 msgid "" "**Add new how-to guide for monitoring simulations** " "([#1649](https://github.com/adap/flower/pull/1649))" msgstr "" -#: ../../source/ref-changelog.md:402 +#: ../../source/ref-changelog.md:494 msgid "" "We now have a documentation guide to help users monitor their performance" " during simulations." msgstr "" -#: ../../source/ref-changelog.md:404 +#: ../../source/ref-changelog.md:496 msgid "" "**Add training metrics to** `History` **object during simulations** " "([#1696](https://github.com/adap/flower/pull/1696))" msgstr "" -#: ../../source/ref-changelog.md:406 +#: ../../source/ref-changelog.md:498 msgid "" "The `fit_metrics_aggregation_fn` can be used to aggregate training " "metrics, but previous releases did not save the results in the `History` " "object. This is now the case!" msgstr "" -#: ../../source/ref-changelog.md:408 +#: ../../source/ref-changelog.md:500 msgid "" "**General improvements** " "([#1659](https://github.com/adap/flower/pull/1659), " @@ -15264,23 +15934,23 @@ msgid "" "[#1805](https://github.com/adap/flower/pull/1805))" msgstr "" -#: ../../source/ref-changelog.md:416 +#: ../../source/ref-changelog.md:508 msgid "v1.3.0 (2023-02-06)" msgstr "" -#: ../../source/ref-changelog.md:422 +#: ../../source/ref-changelog.md:514 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" -#: ../../source/ref-changelog.md:426 +#: ../../source/ref-changelog.md:518 msgid "" "**Add support for** `workload_id` **and** `group_id` **in Driver API** " "([#1595](https://github.com/adap/flower/pull/1595))" msgstr "" -#: ../../source/ref-changelog.md:428 +#: ../../source/ref-changelog.md:520 msgid "" "The (experimental) Driver API now supports a `workload_id` that can be " "used to identify which workload a task belongs to. It also supports a new" @@ -15289,36 +15959,36 @@ msgid "" " to decide whether they want to handle a task or not." msgstr "" -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:522 msgid "" "**Make Driver API and Fleet API address configurable** " "([#1637](https://github.com/adap/flower/pull/1637))" msgstr "" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:524 msgid "" "The (experimental) long-running Flower server (Driver API and Fleet API) " "can now configure the server address of both Driver API (via `--driver-" "api-address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" -#: ../../source/ref-changelog.md:434 +#: ../../source/ref-changelog.md:526 msgid "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " "\"0.0.0.0:8086\"`" msgstr "" -#: ../../source/ref-changelog.md:436 +#: ../../source/ref-changelog.md:528 msgid "Both IPv4 and IPv6 addresses are supported." msgstr "" -#: ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:530 msgid "" "**Add new example of Federated Learning using fastai and Flower** " "([#1598](https://github.com/adap/flower/pull/1598))" msgstr "" -#: ../../source/ref-changelog.md:440 +#: ../../source/ref-changelog.md:532 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " @@ -15326,14 +15996,14 @@ msgid "" "/quickstart-fastai)." msgstr "" -#: ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:534 msgid "" "**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" " versions of Android** " "([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" -#: ../../source/ref-changelog.md:444 +#: ../../source/ref-changelog.md:536 msgid "" "The Android code example has received a substantial update: the project " "is compatible with Flower 1.0 (and later), the UI received a full " @@ -15341,13 +16011,13 @@ msgid "" "tooling." msgstr "" -#: ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:538 msgid "" "**Add new `FedProx` strategy** " "([#1619](https://github.com/adap/flower/pull/1619))" msgstr "" -#: ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:540 msgid "" "This " "[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" @@ -15359,25 +16029,25 @@ msgid "" "respect to the global models." msgstr "" -#: ../../source/ref-changelog.md:450 +#: ../../source/ref-changelog.md:542 msgid "" "**Add new metrics to telemetry events** " "([#1640](https://github.com/adap/flower/pull/1640))" msgstr "" -#: ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:544 msgid "" "An updated event structure allows, for example, the clustering of events " "within the same workload." msgstr "" -#: ../../source/ref-changelog.md:454 +#: ../../source/ref-changelog.md:546 msgid "" "**Add new custom strategy tutorial section** " "[#1623](https://github.com/adap/flower/pull/1623)" msgstr "" -#: ../../source/ref-changelog.md:456 +#: ../../source/ref-changelog.md:548 msgid "" "The Flower tutorial now has a new section that covers implementing a " "custom strategy from scratch: [Open in " @@ -15385,13 +16055,13 @@ msgid "" "/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:458 +#: ../../source/ref-changelog.md:550 msgid "" "**Add new custom serialization tutorial section** " "([#1622](https://github.com/adap/flower/pull/1622))" msgstr "" -#: ../../source/ref-changelog.md:460 +#: ../../source/ref-changelog.md:552 msgid "" "The Flower tutorial now has a new section that covers custom " "serialization: [Open in " @@ -15399,7 +16069,7 @@ msgid "" "/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:462 +#: ../../source/ref-changelog.md:554 msgid "" "**General improvements** " "([#1638](https://github.com/adap/flower/pull/1638), " @@ -15437,7 +16107,7 @@ msgid "" "[#1586](https://github.com/adap/flower/pull/1586))" msgstr "" -#: ../../source/ref-changelog.md:466 +#: ../../source/ref-changelog.md:558 msgid "" "**Updated documentation** " "([#1629](https://github.com/adap/flower/pull/1629), " @@ -15449,31 +16119,31 @@ msgid "" "[#1614](https://github.com/adap/flower/pull/1614))" msgstr "" -#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 +#: ../../source/ref-changelog.md:560 ../../source/ref-changelog.md:627 msgid "" "As usual, the documentation has improved quite a bit. It is another step " "in our effort to make the Flower documentation the best documentation of " "any project. Stay tuned and as always, feel free to provide feedback!" msgstr "" -#: ../../source/ref-changelog.md:474 +#: ../../source/ref-changelog.md:566 msgid "v1.2.0 (2023-01-13)" msgstr "" -#: ../../source/ref-changelog.md:480 +#: ../../source/ref-changelog.md:572 msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." " Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" -#: ../../source/ref-changelog.md:484 +#: ../../source/ref-changelog.md:576 msgid "" "**Introduce new Flower Baseline: FedAvg MNIST** " "([#1497](https://github.com/adap/flower/pull/1497), " "[#1552](https://github.com/adap/flower/pull/1552))" msgstr "" -#: ../../source/ref-changelog.md:486 +#: ../../source/ref-changelog.md:578 msgid "" "Over the coming weeks, we will be releasing a number of new reference " "implementations useful especially to FL newcomers. They will typically " @@ -15484,13 +16154,13 @@ msgid "" "pack-fedavg-mnist-cnn/)" msgstr "" -#: ../../source/ref-changelog.md:488 +#: ../../source/ref-changelog.md:580 msgid "" "**Improve GPU support in simulations** " "([#1555](https://github.com/adap/flower/pull/1555))" msgstr "" -#: ../../source/ref-changelog.md:490 +#: ../../source/ref-changelog.md:582 msgid "" "The Ray-based Virtual Client Engine (`start_simulation`) has been updated" " to improve GPU support. The update includes some of the hard-earned " @@ -15498,45 +16168,45 @@ msgid "" "defaults make running GPU-based simulations substantially more robust." msgstr "" -#: ../../source/ref-changelog.md:492 +#: ../../source/ref-changelog.md:584 msgid "" "**Improve GPU support in Jupyter Notebook tutorials** " "([#1527](https://github.com/adap/flower/pull/1527), " "[#1558](https://github.com/adap/flower/pull/1558))" msgstr "" -#: ../../source/ref-changelog.md:494 +#: ../../source/ref-changelog.md:586 msgid "" "Some users reported that Jupyter Notebooks have not always been easy to " "use on GPU instances. We listened and made improvements to all of our " "Jupyter notebooks! Check out the updated notebooks here:" msgstr "" -#: ../../source/ref-changelog.md:496 +#: ../../source/ref-changelog.md:588 msgid "" "[An Introduction to Federated Learning](https://flower.ai/docs/framework" "/tutorial-get-started-with-flower-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:589 msgid "" "[Strategies in Federated Learning](https://flower.ai/docs/framework" "/tutorial-use-a-federated-learning-strategy-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:498 +#: ../../source/ref-changelog.md:590 msgid "" "[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" "-strategy-from-scratch-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:591 msgid "" "[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" "customize-the-client-pytorch.html)" msgstr "" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:593 msgid "" "**Introduce optional telemetry** " "([#1533](https://github.com/adap/flower/pull/1533), " @@ -15544,7 +16214,7 @@ msgid "" "[#1584](https://github.com/adap/flower/pull/1584))" msgstr "" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:595 msgid "" "After a [request for " "feedback](https://github.com/adap/flower/issues/1534) from the community," @@ -15554,7 +16224,7 @@ msgid "" "used and what challenges users might face." msgstr "" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:597 msgid "" "**Flower is a friendly framework for collaborative AI and data science.**" " Staying true to this statement, Flower makes it easy to disable " @@ -15562,7 +16232,7 @@ msgid "" "[Read more.](https://flower.ai/docs/telemetry.html)." msgstr "" -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:599 msgid "" "**Introduce (experimental) Driver API** " "([#1520](https://github.com/adap/flower/pull/1520), " @@ -15574,7 +16244,7 @@ msgid "" "[#1567](https://github.com/adap/flower/pull/1567))" msgstr "" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:601 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " @@ -15583,7 +16253,7 @@ msgid "" "and you can start building those things now, too." msgstr "" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:603 msgid "" "The Driver API also enables a new execution mode in which the server runs" " indefinitely. Multiple individual workloads can run concurrently and " @@ -15591,26 +16261,26 @@ msgid "" "especially useful for users who want to deploy Flower in production." msgstr "" -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:605 msgid "" "To learn more, check out the `mt-pytorch` code example. We look forward " "to you feedback!" msgstr "" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:607 msgid "" "Please note: *The Driver API is still experimental and will likely change" " significantly over time.*" msgstr "" -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:609 msgid "" "**Add new Federated Analytics with Pandas example** " "([#1469](https://github.com/adap/flower/pull/1469), " "[#1535](https://github.com/adap/flower/pull/1535))" msgstr "" -#: ../../source/ref-changelog.md:519 +#: ../../source/ref-changelog.md:611 msgid "" "A new code example (`quickstart-pandas`) demonstrates federated analytics" " with Pandas and Flower. You can find it here: [quickstart-" @@ -15618,32 +16288,32 @@ msgid "" "pandas)." msgstr "" -#: ../../source/ref-changelog.md:521 +#: ../../source/ref-changelog.md:613 msgid "" "**Add new strategies: Krum and MultiKrum** " "([#1481](https://github.com/adap/flower/pull/1481))" msgstr "" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:615 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " "contributed a new `Krum` strategy that enables users to easily use Krum " "and MultiKrum in their workloads." msgstr "" -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:617 msgid "" "**Update C++ example to be compatible with Flower v1.2.0** " "([#1495](https://github.com/adap/flower/pull/1495))" msgstr "" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:619 msgid "" "The C++ code example has received a substantial update to make it " "compatible with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:621 msgid "" "**General improvements** " "([#1491](https://github.com/adap/flower/pull/1491), " @@ -15661,7 +16331,7 @@ msgid "" "[#1566](https://github.com/adap/flower/pull/1566))" msgstr "" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:625 msgid "" "**Updated documentation** " "([#1494](https://github.com/adap/flower/pull/1494), " @@ -15675,24 +16345,24 @@ msgid "" "[#1515](https://github.com/adap/flower/pull/1515))" msgstr "" -#: ../../source/ref-changelog.md:537 +#: ../../source/ref-changelog.md:629 msgid "" "One highlight is the new [first time contributor " "guide](https://flower.ai/docs/first-time-contributors.html): if you've " "never contributed on GitHub before, this is the perfect place to start!" msgstr "" -#: ../../source/ref-changelog.md:543 +#: ../../source/ref-changelog.md:635 msgid "v1.1.0 (2022-10-31)" msgstr "" -#: ../../source/ref-changelog.md:547 +#: ../../source/ref-changelog.md:639 msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" msgstr "" -#: ../../source/ref-changelog.md:549 +#: ../../source/ref-changelog.md:641 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " @@ -15700,14 +16370,14 @@ msgid "" "`danielnugraha`, `edogab33`" msgstr "" -#: ../../source/ref-changelog.md:553 +#: ../../source/ref-changelog.md:645 msgid "" "**Introduce Differential Privacy wrappers (preview)** " "([#1357](https://github.com/adap/flower/pull/1357), " "[#1460](https://github.com/adap/flower/pull/1460))" msgstr "" -#: ../../source/ref-changelog.md:555 +#: ../../source/ref-changelog.md:647 msgid "" "The first (experimental) preview of pluggable Differential Privacy " "wrappers enables easy configuration and usage of differential privacy " @@ -15716,13 +16386,13 @@ msgid "" "over to the Flower docs, a new explainer goes into more detail." msgstr "" -#: ../../source/ref-changelog.md:557 +#: ../../source/ref-changelog.md:649 msgid "" "**New iOS CoreML code example** " "([#1289](https://github.com/adap/flower/pull/1289))" msgstr "" -#: ../../source/ref-changelog.md:559 +#: ../../source/ref-changelog.md:651 msgid "" "Flower goes iOS! A massive new code example shows how Flower clients can " "be built for iOS. The code example contains both Flower iOS SDK " @@ -15730,39 +16400,39 @@ msgid "" "on CoreML." msgstr "" -#: ../../source/ref-changelog.md:561 +#: ../../source/ref-changelog.md:653 msgid "" "**New FedMedian strategy** " "([#1461](https://github.com/adap/flower/pull/1461))" msgstr "" -#: ../../source/ref-changelog.md:563 +#: ../../source/ref-changelog.md:655 msgid "" "The new `FedMedian` strategy implements Federated Median (FedMedian) by " "[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" -#: ../../source/ref-changelog.md:565 +#: ../../source/ref-changelog.md:657 msgid "" "**Log** `Client` **exceptions in Virtual Client Engine** " "([#1493](https://github.com/adap/flower/pull/1493))" msgstr "" -#: ../../source/ref-changelog.md:567 +#: ../../source/ref-changelog.md:659 msgid "" "All `Client` exceptions happening in the VCE are now logged by default " "and not just exposed to the configured `Strategy` (via the `failures` " "argument)." msgstr "" -#: ../../source/ref-changelog.md:569 +#: ../../source/ref-changelog.md:661 msgid "" "**Improve Virtual Client Engine internals** " "([#1401](https://github.com/adap/flower/pull/1401), " "[#1453](https://github.com/adap/flower/pull/1453))" msgstr "" -#: ../../source/ref-changelog.md:571 +#: ../../source/ref-changelog.md:663 msgid "" "Some internals of the Virtual Client Engine have been revamped. The VCE " "now uses Ray 2.0 under the hood, the value type of the `client_resources`" @@ -15770,25 +16440,25 @@ msgid "" "allocated." msgstr "" -#: ../../source/ref-changelog.md:573 +#: ../../source/ref-changelog.md:665 msgid "" "**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " "Client Engine**" msgstr "" -#: ../../source/ref-changelog.md:575 +#: ../../source/ref-changelog.md:667 msgid "" "The Virtual Client Engine now has full support for optional `Client` (and" " `NumPyClient`) methods." msgstr "" -#: ../../source/ref-changelog.md:577 +#: ../../source/ref-changelog.md:669 msgid "" "**Provide type information to packages using** `flwr` " "([#1377](https://github.com/adap/flower/pull/1377))" msgstr "" -#: ../../source/ref-changelog.md:579 +#: ../../source/ref-changelog.md:671 msgid "" "The package `flwr` is now bundled with a `py.typed` file indicating that " "the package is typed. This enables typing support for projects or " @@ -15796,20 +16466,20 @@ msgid "" "static type checkers like `mypy`." msgstr "" -#: ../../source/ref-changelog.md:581 +#: ../../source/ref-changelog.md:673 msgid "" "**Updated code example** " "([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" -#: ../../source/ref-changelog.md:583 +#: ../../source/ref-changelog.md:675 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." msgstr "" -#: ../../source/ref-changelog.md:585 +#: ../../source/ref-changelog.md:677 msgid "" "**Updated documentation** " "([#1355](https://github.com/adap/flower/pull/1355), " @@ -15831,32 +16501,32 @@ msgid "" "[#1467](https://github.com/adap/flower/pull/1467))" msgstr "" -#: ../../source/ref-changelog.md:587 +#: ../../source/ref-changelog.md:679 msgid "" "There have been so many documentation updates that it doesn't even make " "sense to list them individually." msgstr "" -#: ../../source/ref-changelog.md:589 +#: ../../source/ref-changelog.md:681 msgid "" "**Restructured documentation** " "([#1387](https://github.com/adap/flower/pull/1387))" msgstr "" -#: ../../source/ref-changelog.md:591 +#: ../../source/ref-changelog.md:683 msgid "" "The documentation has been restructured to make it easier to navigate. " "This is just the first step in a larger effort to make the Flower " "documentation the best documentation of any project ever. Stay tuned!" msgstr "" -#: ../../source/ref-changelog.md:593 +#: ../../source/ref-changelog.md:685 msgid "" "**Open in Colab button** " "([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" -#: ../../source/ref-changelog.md:595 +#: ../../source/ref-changelog.md:687 msgid "" "The four parts of the Flower Federated Learning Tutorial now come with a " "new `Open in Colab` button. No need to install anything on your local " @@ -15864,7 +16534,7 @@ msgid "" "only a single click away." msgstr "" -#: ../../source/ref-changelog.md:597 +#: ../../source/ref-changelog.md:689 msgid "" "**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," " [#1470](https://github.com/adap/flower/pull/1470), " @@ -15874,7 +16544,7 @@ msgid "" "[#1475](https://github.com/adap/flower/pull/1475))" msgstr "" -#: ../../source/ref-changelog.md:599 +#: ../../source/ref-changelog.md:691 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " @@ -15882,40 +16552,40 @@ msgid "" "(many small changes and fixes)." msgstr "" -#: ../../source/ref-changelog.md:605 +#: ../../source/ref-changelog.md:697 msgid "v1.0.0 (2022-07-28)" msgstr "" -#: ../../source/ref-changelog.md:607 +#: ../../source/ref-changelog.md:699 msgid "Highlights" msgstr "" -#: ../../source/ref-changelog.md:609 +#: ../../source/ref-changelog.md:701 msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:702 msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "" -#: ../../source/ref-changelog.md:611 +#: ../../source/ref-changelog.md:703 msgid "Configurable `get_parameters`" msgstr "" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:704 msgid "" "Tons of small API cleanups resulting in a more coherent developer " "experience" msgstr "" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:708 msgid "" "We would like to give our **special thanks** to all the contributors who " "made Flower 1.0 possible (in reverse [GitHub " "Contributors](https://github.com/adap/flower/graphs/contributors) order):" msgstr "" -#: ../../source/ref-changelog.md:618 +#: ../../source/ref-changelog.md:710 msgid "" "[@rtaiello](https://github.com/rtaiello), " "[@g-pichler](https://github.com/g-pichler), [@rob-" @@ -15955,13 +16625,13 @@ msgid "" "[@danieljanes](https://github.com/danieljanes)." msgstr "" -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:714 msgid "" "**All arguments must be passed as keyword arguments** " "([#1338](https://github.com/adap/flower/pull/1338))" msgstr "" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:716 msgid "" "Pass all arguments as keyword arguments, positional arguments are not " "longer supported. Code that uses positional arguments (e.g., " @@ -15971,14 +16641,14 @@ msgid "" "client=FlowerClient())`)." msgstr "" -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:718 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " "**and** `start_simulation` " "([#1317](https://github.com/adap/flower/pull/1317))" msgstr "" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:720 msgid "" "Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " "600.0}`, `start_server` and `start_simulation` now expect a configuration" @@ -15987,37 +16657,37 @@ msgid "" "safe code easier and the default parameters values more transparent." msgstr "" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:722 msgid "" "**Rename built-in strategy parameters for clarity** " "([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:632 +#: ../../source/ref-changelog.md:724 msgid "" "The following built-in strategy parameters were renamed to improve " "readability and consistency with other API's:" msgstr "" -#: ../../source/ref-changelog.md:634 +#: ../../source/ref-changelog.md:726 msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:635 +#: ../../source/ref-changelog.md:727 msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "" -#: ../../source/ref-changelog.md:636 +#: ../../source/ref-changelog.md:728 msgid "`eval_fn` --> `evaluate_fn`" msgstr "" -#: ../../source/ref-changelog.md:638 +#: ../../source/ref-changelog.md:730 msgid "" "**Update default arguments of built-in strategies** " "([#1278](https://github.com/adap/flower/pull/1278))" msgstr "" -#: ../../source/ref-changelog.md:640 +#: ../../source/ref-changelog.md:732 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " "`fraction_evaluate=1.0`, which means they select *all* currently " @@ -16026,29 +16696,29 @@ msgid "" "initializing the strategy in the following way:" msgstr "" -#: ../../source/ref-changelog.md:642 +#: ../../source/ref-changelog.md:734 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "" -#: ../../source/ref-changelog.md:644 +#: ../../source/ref-changelog.md:736 msgid "" "**Add** `server_round` **to** `Strategy.evaluate` " "([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:646 +#: ../../source/ref-changelog.md:738 msgid "" "The `Strategy` method `evaluate` now receives the current round of " "federated learning/evaluation as the first parameter." msgstr "" -#: ../../source/ref-changelog.md:648 +#: ../../source/ref-changelog.md:740 msgid "" "**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" msgstr "" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:742 msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " @@ -16056,13 +16726,13 @@ msgid "" "and (3) a config dictionary (`config`)." msgstr "" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:744 msgid "" "**Rename** `rnd` **to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" msgstr "" -#: ../../source/ref-changelog.md:654 +#: ../../source/ref-changelog.md:746 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " @@ -16071,73 +16741,73 @@ msgid "" "has been renamed from `rnd` to `server_round`." msgstr "" -#: ../../source/ref-changelog.md:656 +#: ../../source/ref-changelog.md:748 msgid "" "**Move** `flwr.dataset` **to** `flwr_baselines` " "([#1273](https://github.com/adap/flower/pull/1273))" msgstr "" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:750 msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "" -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:752 msgid "" "**Remove experimental strategies** " "([#1280](https://github.com/adap/flower/pull/1280))" msgstr "" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:754 msgid "" "Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " "`FedFSv1`)." msgstr "" -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:756 msgid "" "**Rename** `Weights` **to** `NDArrays` " "([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:758 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." msgstr "" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:760 msgid "" "**Remove antiquated** `force_final_distributed_eval` **from** " "`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:762 msgid "" "The `start_server` parameter `force_final_distributed_eval` has long been" " a historic artefact, in this release it is finally gone for good." msgstr "" -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:764 msgid "" "**Make** `get_parameters` **configurable** " "([#1242](https://github.com/adap/flower/pull/1242))" msgstr "" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:766 msgid "" "The `get_parameters` method now accepts a configuration dictionary, just " "like `get_properties`, `fit`, and `evaluate`." msgstr "" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:768 msgid "" "**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " "**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:770 msgid "" "The `start_simulation` function now accepts a configuration dictionary " "`config` instead of the `num_rounds` integer. This improves the " @@ -16145,26 +16815,26 @@ msgid "" "transitioning between the two easier." msgstr "" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:774 msgid "" "**Support Python 3.10** " "([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:776 msgid "" "The previous Flower release introduced experimental support for Python " "3.10, this release declares Python 3.10 support as stable." msgstr "" -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:778 msgid "" "**Make all** `Client` **and** `NumPyClient` **methods optional** " "([#1260](https://github.com/adap/flower/pull/1260), " "[#1277](https://github.com/adap/flower/pull/1277))" msgstr "" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:780 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " "`fit`, and `evaluate` are all optional. This enables writing clients that" @@ -16172,13 +16842,13 @@ msgid "" "implement `evaluate` when using centralized evaluation!" msgstr "" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:782 msgid "" "**Enable passing a** `Server` **instance to** `start_simulation` " "([#1281](https://github.com/adap/flower/pull/1281))" msgstr "" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:784 msgid "" "Similar to `start_server`, `start_simulation` now accepts a full `Server`" " instance. This enables users to heavily customize the execution of " @@ -16186,7 +16856,7 @@ msgid "" " Virtual Client Engine." msgstr "" -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:786 msgid "" "**Update code examples** " "([#1291](https://github.com/adap/flower/pull/1291), " @@ -16194,50 +16864,50 @@ msgid "" "[#1282](https://github.com/adap/flower/pull/1282))" msgstr "" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:788 msgid "" "Many code examples received small or even large maintenance updates, " "among them are" msgstr "" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:790 msgid "`scikit-learn`" msgstr "" -#: ../../source/ref-changelog.md:699 +#: ../../source/ref-changelog.md:791 msgid "`simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:792 msgid "`quickstart_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:701 +#: ../../source/ref-changelog.md:793 msgid "`quickstart_simulation`" msgstr "" -#: ../../source/ref-changelog.md:702 +#: ../../source/ref-changelog.md:794 msgid "`quickstart_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:703 +#: ../../source/ref-changelog.md:795 msgid "`advanced_tensorflow`" msgstr "" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:797 msgid "" "**Remove the obsolete simulation example** " "([#1328](https://github.com/adap/flower/pull/1328))" msgstr "" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:799 msgid "" "Removes the obsolete `simulation` example and renames " "`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " "naming of `simulation_pytorch`" msgstr "" -#: ../../source/ref-changelog.md:709 +#: ../../source/ref-changelog.md:801 msgid "" "**Update documentation** " "([#1223](https://github.com/adap/flower/pull/1223), " @@ -16252,7 +16922,7 @@ msgid "" "[#1307](https://github.com/adap/flower/pull/1307))" msgstr "" -#: ../../source/ref-changelog.md:711 +#: ../../source/ref-changelog.md:803 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " @@ -16262,24 +16932,24 @@ msgid "" "fixes a number of smaller details!" msgstr "" -#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 -#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +#: ../../source/ref-changelog.md:805 ../../source/ref-changelog.md:860 +#: ../../source/ref-changelog.md:929 ../../source/ref-changelog.md:968 msgid "**Minor updates**" msgstr "" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:807 msgid "" "Add round number to fit and evaluate log messages " "([#1266](https://github.com/adap/flower/pull/1266))" msgstr "" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:808 msgid "" "Add secure gRPC connection to the `advanced_tensorflow` code example " "([#847](https://github.com/adap/flower/pull/847))" msgstr "" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:809 msgid "" "Update developer tooling " "([#1231](https://github.com/adap/flower/pull/1231), " @@ -16288,7 +16958,7 @@ msgid "" "[#1310](https://github.com/adap/flower/pull/1310))" msgstr "" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:810 msgid "" "Rename ProtoBuf messages to improve consistency " "([#1214](https://github.com/adap/flower/pull/1214), " @@ -16296,11 +16966,11 @@ msgid "" "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" -#: ../../source/ref-changelog.md:720 +#: ../../source/ref-changelog.md:812 msgid "v0.19.0 (2022-05-18)" msgstr "" -#: ../../source/ref-changelog.md:724 +#: ../../source/ref-changelog.md:816 msgid "" "**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " "([#919](https://github.com/adap/flower/pull/919), " @@ -16308,7 +16978,7 @@ msgid "" "[#914](https://github.com/adap/flower/pull/914))" msgstr "" -#: ../../source/ref-changelog.md:726 +#: ../../source/ref-changelog.md:818 msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " @@ -16319,39 +16989,39 @@ msgid "" "contribute-baselines.html)." msgstr "" -#: ../../source/ref-changelog.md:728 +#: ../../source/ref-changelog.md:820 msgid "" "**C++ client SDK (preview) and code example** " "([#1111](https://github.com/adap/flower/pull/1111))" msgstr "" -#: ../../source/ref-changelog.md:730 +#: ../../source/ref-changelog.md:822 msgid "" "Preview support for Flower clients written in C++. The C++ preview " "includes a Flower client SDK and a quickstart code example that " "demonstrates a simple C++ client using the SDK." msgstr "" -#: ../../source/ref-changelog.md:732 +#: ../../source/ref-changelog.md:824 msgid "" "**Add experimental support for Python 3.10 and Python 3.11** " "([#1135](https://github.com/adap/flower/pull/1135))" msgstr "" -#: ../../source/ref-changelog.md:734 +#: ../../source/ref-changelog.md:826 msgid "" "Python 3.10 is the latest stable release of Python and Python 3.11 is due" " to be released in October. This Flower release adds experimental support" " for both Python versions." msgstr "" -#: ../../source/ref-changelog.md:736 +#: ../../source/ref-changelog.md:828 msgid "" "**Aggregate custom metrics through user-provided functions** " "([#1144](https://github.com/adap/flower/pull/1144))" msgstr "" -#: ../../source/ref-changelog.md:738 +#: ../../source/ref-changelog.md:830 msgid "" "Custom metrics (e.g., `accuracy`) can now be aggregated without having to" " customize the strategy. Built-in strategies support two new arguments, " @@ -16359,13 +17029,13 @@ msgid "" "allow passing custom metric aggregation functions." msgstr "" -#: ../../source/ref-changelog.md:740 +#: ../../source/ref-changelog.md:832 msgid "" "**User-configurable round timeout** " "([#1162](https://github.com/adap/flower/pull/1162))" msgstr "" -#: ../../source/ref-changelog.md:742 +#: ../../source/ref-changelog.md:834 msgid "" "A new configuration value allows the round timeout to be set for " "`start_server` and `start_simulation`. If the `config` dictionary " @@ -16374,14 +17044,14 @@ msgid "" "connection." msgstr "" -#: ../../source/ref-changelog.md:744 +#: ../../source/ref-changelog.md:836 msgid "" "**Enable both federated evaluation and centralized evaluation to be used " "at the same time in all built-in strategies** " "([#1091](https://github.com/adap/flower/pull/1091))" msgstr "" -#: ../../source/ref-changelog.md:746 +#: ../../source/ref-changelog.md:838 msgid "" "Built-in strategies can now perform both federated evaluation (i.e., " "client-side) and centralized evaluation (i.e., server-side) in the same " @@ -16389,82 +17059,82 @@ msgid "" " `0.0`." msgstr "" -#: ../../source/ref-changelog.md:748 +#: ../../source/ref-changelog.md:840 msgid "" "**Two new Jupyter Notebook tutorials** " "([#1141](https://github.com/adap/flower/pull/1141))" msgstr "" -#: ../../source/ref-changelog.md:750 +#: ../../source/ref-changelog.md:842 msgid "" "Two Jupyter Notebook tutorials (compatible with Google Colab) explain " "basic and intermediate Flower features:" msgstr "" -#: ../../source/ref-changelog.md:752 +#: ../../source/ref-changelog.md:844 msgid "" "*An Introduction to Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" "-Intro-to-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:754 +#: ../../source/ref-changelog.md:846 msgid "" "*Using Strategies in Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" "-Strategies-in-FL-PyTorch.ipynb)" msgstr "" -#: ../../source/ref-changelog.md:756 +#: ../../source/ref-changelog.md:848 msgid "" "**New FedAvgM strategy (Federated Averaging with Server Momentum)** " "([#1076](https://github.com/adap/flower/pull/1076))" msgstr "" -#: ../../source/ref-changelog.md:758 +#: ../../source/ref-changelog.md:850 msgid "" "The new `FedAvgM` strategy implements Federated Averaging with Server " "Momentum \\[Hsu et al., 2019\\]." msgstr "" -#: ../../source/ref-changelog.md:760 +#: ../../source/ref-changelog.md:852 msgid "" "**New advanced PyTorch code example** " "([#1007](https://github.com/adap/flower/pull/1007))" msgstr "" -#: ../../source/ref-changelog.md:762 +#: ../../source/ref-changelog.md:854 msgid "" "A new code example (`advanced_pytorch`) demonstrates advanced Flower " "concepts with PyTorch." msgstr "" -#: ../../source/ref-changelog.md:764 +#: ../../source/ref-changelog.md:856 msgid "" "**New JAX code example** " "([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" -#: ../../source/ref-changelog.md:766 +#: ../../source/ref-changelog.md:858 msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." msgstr "" -#: ../../source/ref-changelog.md:770 +#: ../../source/ref-changelog.md:862 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" msgstr "" -#: ../../source/ref-changelog.md:771 +#: ../../source/ref-changelog.md:863 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" msgstr "" -#: ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:864 msgid "" "New documentation for [implementing " "strategies](https://flower.ai/docs/framework/how-to-implement-" @@ -16472,72 +17142,72 @@ msgid "" "[#1175](https://github.com/adap/flower/pull/1175))" msgstr "" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:865 msgid "" "New mobile-friendly documentation theme " "([#1174](https://github.com/adap/flower/pull/1174))" msgstr "" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:866 msgid "" "Limit version range for (optional) `ray` dependency to include only " "compatible releases (`>=1.9.2,<1.12.0`) " "([#1205](https://github.com/adap/flower/pull/1205))" msgstr "" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:870 msgid "" "**Remove deprecated support for Python 3.6** " "([#871](https://github.com/adap/flower/pull/871))" msgstr "" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:871 msgid "" "**Remove deprecated KerasClient** " "([#857](https://github.com/adap/flower/pull/857))" msgstr "" -#: ../../source/ref-changelog.md:780 +#: ../../source/ref-changelog.md:872 msgid "" "**Remove deprecated no-op extra installs** " "([#973](https://github.com/adap/flower/pull/973))" msgstr "" -#: ../../source/ref-changelog.md:781 +#: ../../source/ref-changelog.md:873 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/ref-changelog.md:782 +#: ../../source/ref-changelog.md:874 msgid "" "**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " "([#1107](https://github.com/adap/flower/pull/1107))" msgstr "" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:875 msgid "" "**Remove deprecated DefaultStrategy strategy** " "([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:784 +#: ../../source/ref-changelog.md:876 msgid "" "**Remove deprecated support for eval_fn accuracy return value** " "([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:877 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" msgstr "" -#: ../../source/ref-changelog.md:787 +#: ../../source/ref-changelog.md:879 msgid "v0.18.0 (2022-02-28)" msgstr "" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:883 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " "Google Colab** ([#866](https://github.com/adap/flower/pull/866), " @@ -16546,7 +17216,7 @@ msgid "" "[#1036](https://github.com/adap/flower/pull/1036))" msgstr "" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:885 msgid "" "Simulations (using the Virtual Client Engine through `start_simulation`) " "now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " @@ -16554,38 +17224,38 @@ msgid "" "flwr[simulation]`)." msgstr "" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:887 msgid "" "**New Jupyter Notebook code example** " "([#833](https://github.com/adap/flower/pull/833))" msgstr "" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:889 msgid "" "A new code example (`quickstart_simulation`) demonstrates Flower " "simulations using the Virtual Client Engine through Jupyter Notebook " "(incl. Google Colab)." msgstr "" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:891 msgid "" "**Client properties (feature preview)** " "([#795](https://github.com/adap/flower/pull/795))" msgstr "" -#: ../../source/ref-changelog.md:801 +#: ../../source/ref-changelog.md:893 msgid "" "Clients can implement a new method `get_properties` to enable server-side" " strategies to query client properties." msgstr "" -#: ../../source/ref-changelog.md:803 +#: ../../source/ref-changelog.md:895 msgid "" "**Experimental Android support with TFLite** " "([#865](https://github.com/adap/flower/pull/865))" msgstr "" -#: ../../source/ref-changelog.md:805 +#: ../../source/ref-changelog.md:897 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " @@ -16593,7 +17263,7 @@ msgid "" "become a lot easier." msgstr "" -#: ../../source/ref-changelog.md:807 +#: ../../source/ref-changelog.md:899 msgid "" "The example uses TFLite on the client side, along with a new " "`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " @@ -16602,13 +17272,13 @@ msgid "" " functionality from `FedAvgAndroid`." msgstr "" -#: ../../source/ref-changelog.md:809 +#: ../../source/ref-changelog.md:901 msgid "" "**Make gRPC keepalive time user-configurable and decrease default " "keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" -#: ../../source/ref-changelog.md:811 +#: ../../source/ref-changelog.md:903 msgid "" "The default gRPC keepalive time has been reduced to increase the " "compatibility of Flower with more cloud environments (for example, " @@ -16616,31 +17286,31 @@ msgid "" " gRPC stack based on specific requirements." msgstr "" -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:905 msgid "" "**New differential privacy example using Opacus and PyTorch** " "([#805](https://github.com/adap/flower/pull/805))" msgstr "" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:907 msgid "" "A new code example (`opacus`) demonstrates differentially-private " "federated learning with Opacus, PyTorch, and Flower." msgstr "" -#: ../../source/ref-changelog.md:817 +#: ../../source/ref-changelog.md:909 msgid "" "**New Hugging Face Transformers code example** " "([#863](https://github.com/adap/flower/pull/863))" msgstr "" -#: ../../source/ref-changelog.md:819 +#: ../../source/ref-changelog.md:911 msgid "" "A new code example (`quickstart_huggingface`) demonstrates usage of " "Hugging Face Transformers with Flower." msgstr "" -#: ../../source/ref-changelog.md:821 +#: ../../source/ref-changelog.md:913 msgid "" "**New MLCube code example** " "([#779](https://github.com/adap/flower/pull/779), " @@ -16649,13 +17319,13 @@ msgid "" "[#1090](https://github.com/adap/flower/pull/1090))" msgstr "" -#: ../../source/ref-changelog.md:823 +#: ../../source/ref-changelog.md:915 msgid "" "A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " "with Flower." msgstr "" -#: ../../source/ref-changelog.md:825 +#: ../../source/ref-changelog.md:917 msgid "" "**SSL-enabled server and client** " "([#842](https://github.com/adap/flower/pull/842), " @@ -16666,33 +17336,33 @@ msgid "" "[#994](https://github.com/adap/flower/pull/994))" msgstr "" -#: ../../source/ref-changelog.md:827 +#: ../../source/ref-changelog.md:919 msgid "" "SSL enables secure encrypted connections between clients and servers. " "This release open-sources the Flower secure gRPC implementation to make " "encrypted communication channels accessible to all Flower users." msgstr "" -#: ../../source/ref-changelog.md:829 +#: ../../source/ref-changelog.md:921 msgid "" "**Updated** `FedAdam` **and** `FedYogi` **strategies** " "([#885](https://github.com/adap/flower/pull/885), " "[#895](https://github.com/adap/flower/pull/895))" msgstr "" -#: ../../source/ref-changelog.md:831 +#: ../../source/ref-changelog.md:923 msgid "" "`FedAdam` and `FedAdam` match the latest version of the Adaptive " "Federated Optimization paper." msgstr "" -#: ../../source/ref-changelog.md:833 +#: ../../source/ref-changelog.md:925 msgid "" "**Initialize** `start_simulation` **with a list of client IDs** " "([#860](https://github.com/adap/flower/pull/860))" msgstr "" -#: ../../source/ref-changelog.md:835 +#: ../../source/ref-changelog.md:927 msgid "" "`start_simulation` can now be called with a list of client IDs " "(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " @@ -16701,55 +17371,55 @@ msgid "" "identifiers." msgstr "" -#: ../../source/ref-changelog.md:839 +#: ../../source/ref-changelog.md:931 msgid "" "Update `num_examples` calculation in PyTorch code examples in " "([#909](https://github.com/adap/flower/pull/909))" msgstr "" -#: ../../source/ref-changelog.md:840 +#: ../../source/ref-changelog.md:932 msgid "" "Expose Flower version through `flwr.__version__` " "([#952](https://github.com/adap/flower/pull/952))" msgstr "" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:933 msgid "" "`start_server` in `app.py` now returns a `History` object containing " "metrics from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" -#: ../../source/ref-changelog.md:842 +#: ../../source/ref-changelog.md:934 msgid "" "Make `max_workers` (used by `ThreadPoolExecutor`) configurable " "([#978](https://github.com/adap/flower/pull/978))" msgstr "" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:935 msgid "" "Increase sleep time after server start to three seconds in all code " "examples ([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" -#: ../../source/ref-changelog.md:844 +#: ../../source/ref-changelog.md:936 msgid "" "Added a new FAQ section to the documentation " "([#948](https://github.com/adap/flower/pull/948))" msgstr "" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:937 msgid "" "And many more under-the-hood changes, library updates, documentation " "changes, and tooling improvements!" msgstr "" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:941 msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" msgstr "" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:943 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " @@ -16758,11 +17428,11 @@ msgid "" "an upcoming release." msgstr "" -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:945 msgid "v0.17.0 (2021-09-24)" msgstr "" -#: ../../source/ref-changelog.md:857 +#: ../../source/ref-changelog.md:949 msgid "" "**Experimental virtual client engine** " "([#781](https://github.com/adap/flower/pull/781) " @@ -16770,7 +17440,7 @@ msgid "" "[#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:951 msgid "" "One of Flower's goals is to enable research at scale. This release " "enables a first (experimental) peek at a major new feature, codenamed the" @@ -16780,7 +17450,7 @@ msgid "" "code examples called `quickstart_simulation` and `simulation_pytorch`." msgstr "" -#: ../../source/ref-changelog.md:861 +#: ../../source/ref-changelog.md:953 msgid "" "The feature is still experimental, so there's no stability guarantee for " "the API. It's also not quite ready for prime time and comes with a few " @@ -16788,86 +17458,86 @@ msgid "" "out and share their thoughts." msgstr "" -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:955 msgid "" "**New built-in strategies** " "([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:957 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/ref-changelog.md:866 +#: ../../source/ref-changelog.md:958 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "" -#: ../../source/ref-changelog.md:868 +#: ../../source/ref-changelog.md:960 msgid "" "**New PyTorch Lightning code example** " "([#617](https://github.com/adap/flower/pull/617))" msgstr "" -#: ../../source/ref-changelog.md:870 +#: ../../source/ref-changelog.md:962 msgid "" "**New Variational Auto-Encoder code example** " "([#752](https://github.com/adap/flower/pull/752))" msgstr "" -#: ../../source/ref-changelog.md:872 +#: ../../source/ref-changelog.md:964 msgid "" "**New scikit-learn code example** " "([#748](https://github.com/adap/flower/pull/748))" msgstr "" -#: ../../source/ref-changelog.md:874 +#: ../../source/ref-changelog.md:966 msgid "" "**New experimental TensorBoard strategy** " "([#789](https://github.com/adap/flower/pull/789))" msgstr "" -#: ../../source/ref-changelog.md:878 +#: ../../source/ref-changelog.md:970 msgid "" "Improved advanced TensorFlow code example " "([#769](https://github.com/adap/flower/pull/769))" msgstr "" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:971 msgid "" "Warning when `min_available_clients` is misconfigured " "([#830](https://github.com/adap/flower/pull/830))" msgstr "" -#: ../../source/ref-changelog.md:880 +#: ../../source/ref-changelog.md:972 msgid "" "Improved gRPC server docs " "([#841](https://github.com/adap/flower/pull/841))" msgstr "" -#: ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:973 msgid "" "Improved error message in `NumPyClient` " "([#851](https://github.com/adap/flower/pull/851))" msgstr "" -#: ../../source/ref-changelog.md:882 +#: ../../source/ref-changelog.md:974 msgid "" "Improved PyTorch quickstart code example " "([#852](https://github.com/adap/flower/pull/852))" msgstr "" -#: ../../source/ref-changelog.md:886 +#: ../../source/ref-changelog.md:978 msgid "" "**Disabled final distributed evaluation** " "([#800](https://github.com/adap/flower/pull/800))" msgstr "" -#: ../../source/ref-changelog.md:888 +#: ../../source/ref-changelog.md:980 msgid "" "Prior behaviour was to perform a final round of distributed evaluation on" " all connected clients, which is often not required (e.g., when using " @@ -16875,13 +17545,13 @@ msgid "" "`force_final_distributed_eval=True` to `start_server`." msgstr "" -#: ../../source/ref-changelog.md:890 +#: ../../source/ref-changelog.md:982 msgid "" "**Renamed q-FedAvg strategy** " "([#802](https://github.com/adap/flower/pull/802))" msgstr "" -#: ../../source/ref-changelog.md:892 +#: ../../source/ref-changelog.md:984 msgid "" "The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " "the notation given in the original paper (q-FFL is the optimization " @@ -16890,14 +17560,14 @@ msgid "" " (it will be removed in a future release)." msgstr "" -#: ../../source/ref-changelog.md:894 +#: ../../source/ref-changelog.md:986 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " "`simulation_pytorch_legacy` " "([#791](https://github.com/adap/flower/pull/791))" msgstr "" -#: ../../source/ref-changelog.md:896 +#: ../../source/ref-changelog.md:988 msgid "" "This example has been replaced by a new example. The new example is based" " on the experimental virtual client engine, which will become the new " @@ -16906,27 +17576,27 @@ msgid "" "removed in the future." msgstr "" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:990 msgid "v0.16.0 (2021-05-11)" msgstr "" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:994 msgid "" "**New built-in strategies** " "([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:904 +#: ../../source/ref-changelog.md:996 msgid "(abstract) FedOpt" msgstr "" -#: ../../source/ref-changelog.md:907 +#: ../../source/ref-changelog.md:999 msgid "" "**Custom metrics for server and strategies** " "([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/ref-changelog.md:909 +#: ../../source/ref-changelog.md:1001 msgid "" "The Flower server is now fully task-agnostic, all remaining instances of " "task-specific metrics (such as `accuracy`) have been replaced by custom " @@ -16935,7 +17605,7 @@ msgid "" "release, custom metrics replace task-specific metrics on the server." msgstr "" -#: ../../source/ref-changelog.md:911 +#: ../../source/ref-changelog.md:1003 msgid "" "Custom metric dictionaries are now used in two user-facing APIs: they are" " returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " @@ -16945,7 +17615,7 @@ msgid "" "track of." msgstr "" -#: ../../source/ref-changelog.md:913 +#: ../../source/ref-changelog.md:1005 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " @@ -16953,19 +17623,19 @@ msgid "" " from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" -#: ../../source/ref-changelog.md:915 +#: ../../source/ref-changelog.md:1007 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." msgstr "" -#: ../../source/ref-changelog.md:917 +#: ../../source/ref-changelog.md:1009 msgid "" "**Migration warnings for deprecated functionality** " "([#690](https://github.com/adap/flower/pull/690))" msgstr "" -#: ../../source/ref-changelog.md:919 +#: ../../source/ref-changelog.md:1011 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " "maintaining compatibility with legacy APIs. This release introduces " @@ -16974,7 +17644,7 @@ msgid "" "recent APIs, thus easing the transition from one release to another." msgstr "" -#: ../../source/ref-changelog.md:921 +#: ../../source/ref-changelog.md:1013 msgid "" "Improved docs and docstrings " "([#691](https://github.com/adap/flower/pull/691) " @@ -16982,11 +17652,11 @@ msgid "" "[#713](https://github.com/adap/flower/pull/713))" msgstr "" -#: ../../source/ref-changelog.md:923 +#: ../../source/ref-changelog.md:1015 msgid "MXNet example and documentation" msgstr "" -#: ../../source/ref-changelog.md:925 +#: ../../source/ref-changelog.md:1017 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " "([#696](https://github.com/adap/flower/pull/696) " @@ -16994,13 +17664,13 @@ msgid "" "[#705](https://github.com/adap/flower/pull/705))" msgstr "" -#: ../../source/ref-changelog.md:929 +#: ../../source/ref-changelog.md:1021 msgid "" "**Serialization-agnostic server** " "([#721](https://github.com/adap/flower/pull/721))" msgstr "" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:1023 msgid "" "The Flower server is now fully serialization-agnostic. Prior usage of " "class `Weights` (which represents parameters as deserialized NumPy " @@ -17011,7 +17681,7 @@ msgid "" "serialization/deserialization)." msgstr "" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:1025 msgid "" "Built-in strategies implement this approach by handling serialization and" " deserialization to/from `Weights` internally. Custom/3rd-party Strategy " @@ -17021,31 +17691,31 @@ msgid "" " easily migrate to the new format." msgstr "" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:1027 msgid "" "Deprecated `flwr.server.Server.evaluate`, use " "`flwr.server.Server.evaluate_round` instead " "([#717](https://github.com/adap/flower/pull/717))" msgstr "" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:1029 msgid "v0.15.0 (2021-03-12)" msgstr "" -#: ../../source/ref-changelog.md:941 +#: ../../source/ref-changelog.md:1033 msgid "" "**Server-side parameter initialization** " "([#658](https://github.com/adap/flower/pull/658))" msgstr "" -#: ../../source/ref-changelog.md:943 +#: ../../source/ref-changelog.md:1035 msgid "" "Model parameters can now be initialized on the server-side. Server-side " "parameter initialization works via a new `Strategy` method called " "`initialize_parameters`." msgstr "" -#: ../../source/ref-changelog.md:945 +#: ../../source/ref-changelog.md:1037 msgid "" "Built-in strategies support a new constructor argument called " "`initial_parameters` to set the initial parameters. Built-in strategies " @@ -17053,7 +17723,7 @@ msgid "" "delete them to free the memory afterwards." msgstr "" -#: ../../source/ref-changelog.md:964 +#: ../../source/ref-changelog.md:1056 msgid "" "If no initial parameters are provided to the strategy, the server will " "continue to use the current behaviour (namely, it will ask one of the " @@ -17061,21 +17731,17 @@ msgid "" "parameters)." msgstr "" -#: ../../source/ref-changelog.md:966 -msgid "Deprecations" -msgstr "" - -#: ../../source/ref-changelog.md:968 +#: ../../source/ref-changelog.md:1060 msgid "" "Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " "`flwr.server.strategy.FedAvg`, which is equivalent)" msgstr "" -#: ../../source/ref-changelog.md:970 +#: ../../source/ref-changelog.md:1062 msgid "v0.14.0 (2021-02-18)" msgstr "" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:1066 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " "([#610](https://github.com/adap/flower/pull/610) " @@ -17083,7 +17749,7 @@ msgid "" "[#633](https://github.com/adap/flower/pull/633))" msgstr "" -#: ../../source/ref-changelog.md:976 +#: ../../source/ref-changelog.md:1068 msgid "" "Clients can now return an additional dictionary mapping `str` keys to " "values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " @@ -17091,7 +17757,7 @@ msgid "" "and make use of them on the server side!" msgstr "" -#: ../../source/ref-changelog.md:978 +#: ../../source/ref-changelog.md:1070 msgid "" "This improvement also allowed for more consistent return types between " "`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " @@ -17099,7 +17765,7 @@ msgid "" "holding arbitrary problem-specific values like accuracy." msgstr "" -#: ../../source/ref-changelog.md:980 +#: ../../source/ref-changelog.md:1072 msgid "" "In case you wondered: this feature is compatible with existing projects, " "the additional dictionary return value is optional. New code should " @@ -17109,19 +17775,19 @@ msgid "" "details." msgstr "" -#: ../../source/ref-changelog.md:982 +#: ../../source/ref-changelog.md:1074 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" msgstr "" -#: ../../source/ref-changelog.md:997 +#: ../../source/ref-changelog.md:1089 msgid "" "**Generalized** `config` **argument in** `Client.fit` **and** " "`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" -#: ../../source/ref-changelog.md:999 +#: ../../source/ref-changelog.md:1091 msgid "" "The `config` argument used to be of type `Dict[str, str]`, which means " "that dictionary values were expected to be strings. The new release " @@ -17129,58 +17795,58 @@ msgid "" "`bytes`, `float`, `int`, `str`." msgstr "" -#: ../../source/ref-changelog.md:1001 +#: ../../source/ref-changelog.md:1093 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " "using the `config` dictionary. Yay, no more `str(epochs)` on the server-" "side and `int(config[\"epochs\"])` on the client side!" msgstr "" -#: ../../source/ref-changelog.md:1003 +#: ../../source/ref-changelog.md:1095 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" msgstr "" -#: ../../source/ref-changelog.md:1020 +#: ../../source/ref-changelog.md:1112 msgid "v0.13.0 (2021-01-08)" msgstr "" -#: ../../source/ref-changelog.md:1024 +#: ../../source/ref-changelog.md:1116 msgid "" "New example: PyTorch From Centralized To Federated " "([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:1025 +#: ../../source/ref-changelog.md:1117 msgid "Improved documentation" msgstr "" -#: ../../source/ref-changelog.md:1026 +#: ../../source/ref-changelog.md:1118 msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" -#: ../../source/ref-changelog.md:1027 +#: ../../source/ref-changelog.md:1119 msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "" -#: ../../source/ref-changelog.md:1028 +#: ../../source/ref-changelog.md:1120 msgid "" "Updated examples documentation " "([#549](https://github.com/adap/flower/pull/549))" msgstr "" -#: ../../source/ref-changelog.md:1029 +#: ../../source/ref-changelog.md:1121 msgid "" "Removed obsolete documentation " "([#548](https://github.com/adap/flower/pull/548))" msgstr "" -#: ../../source/ref-changelog.md:1031 +#: ../../source/ref-changelog.md:1123 msgid "Bugfix:" msgstr "" -#: ../../source/ref-changelog.md:1033 +#: ../../source/ref-changelog.md:1125 msgid "" "`Server.fit` does not disconnect clients when finished, disconnecting the" " clients is now handled in `flwr.server.start_server` " @@ -17188,28 +17854,28 @@ msgid "" "[#540](https://github.com/adap/flower/issues/540))." msgstr "" -#: ../../source/ref-changelog.md:1035 +#: ../../source/ref-changelog.md:1127 msgid "v0.12.0 (2020-12-07)" msgstr "" -#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +#: ../../source/ref-changelog.md:1129 ../../source/ref-changelog.md:1145 msgid "Important changes:" msgstr "" -#: ../../source/ref-changelog.md:1039 +#: ../../source/ref-changelog.md:1131 msgid "" "Added an example for embedded devices " "([#507](https://github.com/adap/flower/pull/507))" msgstr "" -#: ../../source/ref-changelog.md:1040 +#: ../../source/ref-changelog.md:1132 msgid "" "Added a new NumPyClient (in addition to the existing KerasClient) " "([#504](https://github.com/adap/flower/pull/504) " "[#508](https://github.com/adap/flower/pull/508))" msgstr "" -#: ../../source/ref-changelog.md:1041 +#: ../../source/ref-changelog.md:1133 msgid "" "Deprecated `flwr_example` package and started to migrate examples into " "the top-level `examples` directory " @@ -17217,15 +17883,15 @@ msgid "" "[#512](https://github.com/adap/flower/pull/512))" msgstr "" -#: ../../source/ref-changelog.md:1043 +#: ../../source/ref-changelog.md:1135 msgid "v0.11.0 (2020-11-30)" msgstr "" -#: ../../source/ref-changelog.md:1045 +#: ../../source/ref-changelog.md:1137 msgid "Incompatible changes:" msgstr "" -#: ../../source/ref-changelog.md:1047 +#: ../../source/ref-changelog.md:1139 msgid "" "Renamed strategy methods " "([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " @@ -17235,48 +17901,48 @@ msgid "" "migrate rename the following `Strategy` methods accordingly:" msgstr "" -#: ../../source/ref-changelog.md:1048 +#: ../../source/ref-changelog.md:1140 msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:1049 +#: ../../source/ref-changelog.md:1141 msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "" -#: ../../source/ref-changelog.md:1050 +#: ../../source/ref-changelog.md:1142 msgid "`on_configure_fit` => `configure_fit`" msgstr "" -#: ../../source/ref-changelog.md:1051 +#: ../../source/ref-changelog.md:1143 msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "" -#: ../../source/ref-changelog.md:1055 +#: ../../source/ref-changelog.md:1147 msgid "" "Deprecated `DefaultStrategy` " "([#479](https://github.com/adap/flower/pull/479)). To migrate use " "`FedAvg` instead." msgstr "" -#: ../../source/ref-changelog.md:1056 +#: ../../source/ref-changelog.md:1148 msgid "" "Simplified examples and baselines " "([#484](https://github.com/adap/flower/pull/484))." msgstr "" -#: ../../source/ref-changelog.md:1057 +#: ../../source/ref-changelog.md:1149 msgid "" "Removed presently unused `on_conclude_round` from strategy interface " "([#483](https://github.com/adap/flower/pull/483))." msgstr "" -#: ../../source/ref-changelog.md:1058 +#: ../../source/ref-changelog.md:1150 msgid "" "Set minimal Python version to 3.6.1 instead of 3.6.9 " "([#471](https://github.com/adap/flower/pull/471))." msgstr "" -#: ../../source/ref-changelog.md:1059 +#: ../../source/ref-changelog.md:1151 msgid "" "Improved `Strategy` docstrings " "([#470](https://github.com/adap/flower/pull/470))." @@ -20343,7 +21009,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgid "|93b02017c78049bbbd5ae456dcb2c91b|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 @@ -20358,7 +21024,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +msgid "|01471150fd5144c080a176b43e92a3ff|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 @@ -20379,7 +21045,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -msgid "|2bc8e069228d4873804061ff4a95048c|" +msgid "|9bc21c7dbd17444a8f070c60786e3484|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 @@ -20395,7 +21061,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +msgid "|3047bbce54b34099ae559963d0420d79|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 @@ -20411,7 +21077,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -msgid "|d5f962c3f4ec48529efda980868c14b0|" +msgid "|e9f8ce948593444fb838d2f354c7ec5d|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 @@ -20426,7 +21092,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -msgid "|a5eccea18d4c43a68b54b65043cabef8|" +msgid "|c24c1478b30e4f74839208628a842d1e|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 @@ -20446,7 +21112,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgid "|1b3613d7a58847b59e1d3180802dbc09|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 @@ -20461,7 +21127,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -msgid "|241fc906441a4f038c625a19d30d01b2|" +msgid "|9980b5213db547d0b8024a50992b9e3f|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 @@ -20601,7 +21267,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -msgid "|0aa5aa05810b44b6a835cecce28f3137|" +msgid "|c7afb4c92d154bfaa5e8cb9a150e17f1|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 @@ -20625,7 +21291,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +msgid "|032eb6fed6924ac387b9f13854919196|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 @@ -20649,7 +21315,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +msgid "|fbf225add7fd4df5a9bf25a95597d954|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 @@ -20672,7 +21338,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgid "|7efbe3d29d8349b89594e8947e910525|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 @@ -20710,7 +21376,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -msgid "|72939caf6e294b0986fee6dde96614d7|" +msgid "|329fb3c04c744eda83bb51fa444c2266|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 @@ -20804,7 +21470,7 @@ msgid "" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +msgid "|c00bf2750bc24d229737a0fe1395f0fc|" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 @@ -23908,3 +24574,335 @@ msgstr "" #~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" +#~ msgid "" +#~ "Currently, Flower provides two images, a" +#~ " ``base`` image and a ``superlink`` " +#~ "image. The base image, as the name" +#~ " suggests, contains basic dependencies that" +#~ " the SuperLink needs. This includes " +#~ "system dependencies, Python and Python " +#~ "tools. The SuperLink image is based " +#~ "on the base image, but it " +#~ "additionally installs the SuperLink using " +#~ "``pip``." +#~ msgstr "" +#~ "Atualmente, Flower fornece duas imagens, " +#~ "uma imagem base e uma imagem de" +#~ " servidor. Também haverá uma imagem " +#~ "de cliente em breve. A imagem " +#~ "base, como o nome sugere, contém " +#~ "dependências básicas que tanto o " +#~ "servidor quanto o cliente precisam. Isso" +#~ " inclui dependências do sistema, Python " +#~ "e ferramentas Python. A imagem do " +#~ "servidor é baseada na imagem base, " +#~ "mas também instala o servidor Flower " +#~ "usando ``pip```." + +#~ msgid "``3.11``" +#~ msgstr "``3.11``" + +#~ msgid "Defaults to ``22.04``." +#~ msgstr "Como padrão ``22.04``." + +#~ msgid "Building the SuperLink image" +#~ msgstr "Construindo a imagem do servidor" + +#~ msgid "Defaults to ``flwr/base``." +#~ msgstr "Pré-definido para ``flwr/server``." + +#~ msgid "The Python version of the base image." +#~ msgstr "O nome do repositório da imagem base." + +#~ msgid "Defaults to ``py3.11``." +#~ msgstr "Como padrão ``22.04``." + +#~ msgid "Defaults to ``ubuntu22.04``." +#~ msgstr "Pré-definido para ``py3.11-ubuntu22.04``." + +#~ msgid "The PyPI package to install." +#~ msgstr "" + +#~ msgid "Defaults to ``flwr``." +#~ msgstr "Pré-definido para ``flwr/server``." + +#~ msgid "" +#~ "The name of image is ``flwr_superlink``" +#~ " and the tag ``0.1.0``. Remember that" +#~ " the build arguments as well as " +#~ "the name and tag can be adapted" +#~ " to your needs. These values serve" +#~ " as examples only." +#~ msgstr "" +#~ "O nome da imagem é ``flwr_server`` " +#~ "e a tag ``0.1.0``. Lembre-se que" +#~ " os argumentos de compilação, bem " +#~ "como o nome e a tag podem " +#~ "ser adaptados às suas necessidades. " +#~ "Esses valores servem apenas como " +#~ "exemplos." + +#~ msgid "Creating New Messages" +#~ msgstr "Criando novas mensagens" + +#~ msgid "" +#~ "This is a simple guide for " +#~ "creating a new type of message " +#~ "between the server and clients in " +#~ "Flower." +#~ msgstr "" + +#~ msgid "" +#~ "Let's suppose we have the following " +#~ "example functions in :code:`server.py` and " +#~ ":code:`numpy_client.py`..." +#~ msgstr "" + +#~ msgid "Server's side:" +#~ msgstr "" + +#~ msgid "Client's side:" +#~ msgstr "" + +#~ msgid "" +#~ "Let's now see what we need to " +#~ "implement in order to get this " +#~ "simple function between the server and" +#~ " client to work!" +#~ msgstr "" + +#~ msgid "Message Types for Protocol Buffers" +#~ msgstr "" + +#~ msgid "" +#~ "The first thing we need to do " +#~ "is to define a message type for" +#~ " the RPC system in :code:`transport.proto`." +#~ " Note that we have to do it " +#~ "for both the request and response " +#~ "messages. For more details on the " +#~ "syntax of proto3, please see the " +#~ "`official documentation `_." +#~ msgstr "" + +#~ msgid "Within the :code:`ServerMessage` block:" +#~ msgstr "" + +#~ msgid "Within the ClientMessage block:" +#~ msgstr "" + +#~ msgid "" +#~ "Make sure to also add a field " +#~ "of the newly created message type " +#~ "in :code:`oneof msg`." +#~ msgstr "" + +#~ msgid "Once that is done, we will compile the file with:" +#~ msgstr "" + +#~ msgid "If it compiles successfully, you should see the following message:" +#~ msgstr "" + +#~ msgid "Serialization and Deserialization Functions" +#~ msgstr "" + +#~ msgid "" +#~ "Our next step is to add functions" +#~ " to serialize and deserialize Python " +#~ "datatypes to or from our defined " +#~ "RPC message types. You should add " +#~ "these functions in :code:`serde.py`." +#~ msgstr "" + +#~ msgid "The four functions:" +#~ msgstr "" + +#~ msgid "Sending the Message from the Server" +#~ msgstr "" + +#~ msgid "" +#~ "Now write the request function in " +#~ "your Client Proxy class (e.g., " +#~ ":code:`grpc_client_proxy.py`) using the serde " +#~ "functions you just created:" +#~ msgstr "" + +#~ msgid "Receiving the Message by the Client" +#~ msgstr "" + +#~ msgid "" +#~ "Last step! Modify the code in " +#~ ":code:`message_handler.py` to check the field" +#~ " of your message and call the " +#~ ":code:`example_response` function. Remember to " +#~ "use the serde functions!" +#~ msgstr "" + +#~ msgid "Within the handle function:" +#~ msgstr "" + +#~ msgid "And add a new function:" +#~ msgstr "" + +#~ msgid "Hopefully, when you run your program you will get the intended result!" +#~ msgstr "" + +#~ msgid "" +#~ "The simplest way to get started " +#~ "with Flower is by using the " +#~ "pre-made Docker images, which you can" +#~ " find on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to persist the state" +#~ " of the SuperLink on your host " +#~ "system, all you need to do is " +#~ "specify a path where you want to" +#~ " save the file on your host " +#~ "system and a name for the database" +#~ " file. In the example below, we " +#~ "tell Docker via the flag ``--volume``" +#~ " to mount the user's home directory" +#~ " (``~/`` on your host) into the " +#~ "``/app/`` directory of the container. " +#~ "Furthermore, we use the flag " +#~ "``--database`` to specify the name of" +#~ " the database file." +#~ msgstr "" + +#~ msgid "" +#~ "As soon as the SuperLink starts, " +#~ "the file ``state.db`` is created in " +#~ "the user's home directory on your " +#~ "host system. If the file already " +#~ "exists, the SuperLink tries to restore" +#~ " the state from the file. To " +#~ "start the SuperLink with an empty " +#~ "database, simply remove the ``state.db`` " +#~ "file." +#~ msgstr "" + +#~ msgid "" +#~ "Assuming all files we need are in" +#~ " the local ``certificates`` directory, we" +#~ " can use the flag ``--volume`` to " +#~ "mount the local directory into the " +#~ "``/app/`` directory of the container. " +#~ "This allows the SuperLink to access " +#~ "the files within the container. Finally," +#~ " we pass the names of the " +#~ "certificates to the SuperLink with the" +#~ " ``--certificates`` flag." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9092``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Fleet" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the SuperNode to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "``--server 192.168.1.100:9091``: This option " +#~ "specifies the address of the SuperLinks" +#~ " Driver" +#~ msgstr "" + +#~ msgid "" +#~ "Assuming the certificate already exists " +#~ "locally, we can use the flag " +#~ "``--volume`` to mount the local " +#~ "certificate into the container's ``/app/`` " +#~ "directory. This allows the ServerApp to" +#~ " access the certificate within the " +#~ "container. Use the ``--certificates`` flag " +#~ "when starting the container." +#~ msgstr "" + +#~ msgid "" +#~ "If you want to use a different " +#~ "version of Flower, for example Flower" +#~ " nightly, you can do so by " +#~ "changing the tag. All available versions" +#~ " are on `Docker Hub " +#~ "`__." +#~ msgstr "" + +#~ msgid "" +#~ "Here's another example to start with " +#~ "HTTPS. Use the ``--certificates`` command " +#~ "line argument to pass paths to (CA" +#~ " certificate, server certificate, and " +#~ "server private key)." +#~ msgstr "" + +#~ msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Driver API)." +#~ msgstr "" + +#~ msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#~ msgstr "" + +#~ msgid "Run Flower server (Fleet API)." +#~ msgstr "" + +#~ msgid "Unreleased" +#~ msgstr "" + +#~ msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +#~ msgstr "" + +#~ msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +#~ msgstr "" + +#~ msgid "|2bc8e069228d4873804061ff4a95048c|" +#~ msgstr "" + +#~ msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +#~ msgstr "" + +#~ msgid "|d5f962c3f4ec48529efda980868c14b0|" +#~ msgstr "" + +#~ msgid "|a5eccea18d4c43a68b54b65043cabef8|" +#~ msgstr "" + +#~ msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +#~ msgstr "" + +#~ msgid "|241fc906441a4f038c625a19d30d01b2|" +#~ msgstr "" + +#~ msgid "|0aa5aa05810b44b6a835cecce28f3137|" +#~ msgstr "" + +#~ msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +#~ msgstr "" + +#~ msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +#~ msgstr "" + +#~ msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +#~ msgstr "" + +#~ msgid "|72939caf6e294b0986fee6dde96614d7|" +#~ msgstr "" + +#~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +#~ msgstr "" + diff --git a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po index 7ca5b00176fb..d07217ea35f7 100644 --- a/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po +++ b/doc/locales/zh_Hans/LC_MESSAGES/framework-docs.po @@ -7,17 +7,16 @@ msgid "" msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-28 11:47+0200\n" +"POT-Creation-Date: 2024-06-17 16:09+0200\n" "PO-Revision-Date: 2024-06-12 10:09+0000\n" "Last-Translator: Yan Gao \n" -"Language-Team: Chinese (Simplified) \n" "Language: zh_Hans\n" +"Language-Team: Chinese (Simplified) \n" +"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=1; plural=0;\n" -"X-Generator: Weblate 5.6-dev\n" "Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -63,35 +62,36 @@ msgstr "如何在本地搭建Docker Flower images" msgid "" "Flower provides pre-made docker images on `Docker Hub " "`_ that include all necessary dependencies" -" for running the SuperLink. You can also build your own custom docker " -"images from scratch with a different version of Python or Ubuntu if that " -"is what you need. In this guide, we will explain what images exist and " -"how to build them locally." +" for running the SuperLink, SuperNode or ServerApp. You can also build " +"your own custom docker images from scratch with a different version of " +"Python or Linux distribution (Ubuntu/Alpine) if that is what you need. In" +" this guide, we will explain what images exist and how to build them " +"locally." msgstr "" "Flower 在 `Docker Hub `_ " "上提供了预制的 docker 镜像,其中包括运行服务器所需的所有依赖项。如果你需要,也可以使用不同版本的 Python 或 Ubuntu " "从头开始构建自己的定制 docker 镜像。在本指南中,我们将介绍有哪些镜像,以及如何在本地构建它们。" -#: ../../source/contributor-how-to-build-docker-images.rst:9 +#: ../../source/contributor-how-to-build-docker-images.rst:10 #, fuzzy msgid "" "Before we can start, we need to meet a few prerequisites in our local " "development environment." msgstr "在开始之前,我们需要在本地开发环境中满足一些先决条件。" -#: ../../source/contributor-how-to-build-docker-images.rst:11 +#: ../../source/contributor-how-to-build-docker-images.rst:12 #, fuzzy msgid "Clone the flower repository." msgstr "**叉花仓库**" -#: ../../source/contributor-how-to-build-docker-images.rst:17 -#: ../../source/how-to-run-flower-using-docker.rst:144 +#: ../../source/contributor-how-to-build-docker-images.rst:18 +#: ../../source/how-to-run-flower-using-docker.rst:165 #, fuzzy msgid "Verify the Docker daemon is running." msgstr "验证 Docker 守护进程是否正在运行。" -#: ../../source/contributor-how-to-build-docker-images.rst:19 -#: ../../source/how-to-run-flower-using-docker.rst:146 +#: ../../source/contributor-how-to-build-docker-images.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:167 #, fuzzy msgid "" "Please follow the first section on :doc:`Run Flower using Docker ` " "的第一节,其中更详细地介绍了这一步骤。" -#: ../../source/contributor-how-to-build-docker-images.rst:23 -#, fuzzy -msgid "" -"Currently, Flower provides two images, a ``base`` image and a " -"``superlink`` image. The base image, as the name suggests, contains basic" -" dependencies that the SuperLink needs. This includes system " -"dependencies, Python and Python tools. The SuperLink image is based on " -"the base image, but it additionally installs the SuperLink using ``pip``." -msgstr "" -"目前,Flower " -"提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依赖项、Python" -" 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` 额外安装 Flower 服务器。" - -#: ../../source/contributor-how-to-build-docker-images.rst:28 +#: ../../source/contributor-how-to-build-docker-images.rst:25 #, fuzzy msgid "" "The build instructions that assemble the images are located in the " @@ -121,128 +108,176 @@ msgid "" "``src/docker``." msgstr "组装镜像的构建说明位于各自的 Dockerfile 中。你可以在 ``src/docker`` 的子目录中找到它们。" -#: ../../source/contributor-how-to-build-docker-images.rst:31 +#: ../../source/contributor-how-to-build-docker-images.rst:28 #, fuzzy msgid "" -"Both, base and SuperLink image are configured via build arguments. " -"Through build arguments, we can make our build more flexible. For " -"example, in the base image, we can specify the version of Python to " -"install using the ``PYTHON_VERSION`` build argument. Some of the build " -"arguments have default values, others must be specified when building the" -" image. All available build arguments for each image are listed in one of" -" the tables below." +"Flower Docker images are configured via build arguments. Through build " +"arguments, we can make the creation of images more flexible. For example," +" in the base image, we can specify the version of Python to install using" +" the ``PYTHON_VERSION`` build argument. Some of the build arguments have " +"default values, others must be specified when building the image. All " +"available build arguments for each image are listed in one of the tables " +"below." msgstr "" "基础镜像和服务器镜像都是通过构建参数配置的。通过联编参数,我们可以使联编更加灵活。例如,在基础镜像中,我们可以使用 " "``PYTHON_VERSION`` 联编参数指定要安装的 Python " "版本。有些联编参数有默认值,有些则必须在联编映像时指定。每个映像的所有可用联编参数都列在下表中。" -#: ../../source/contributor-how-to-build-docker-images.rst:38 +#: ../../source/contributor-how-to-build-docker-images.rst:35 #, fuzzy msgid "Building the base image" msgstr "加载数据" -#: ../../source/contributor-how-to-build-docker-images.rst:44 -#: ../../source/contributor-how-to-build-docker-images.rst:86 +#: ../../source/contributor-how-to-build-docker-images.rst:41 +#: ../../source/contributor-how-to-build-docker-images.rst:98 #, fuzzy msgid "Build argument" msgstr "构建文档" -#: ../../source/contributor-how-to-build-docker-images.rst:45 -#: ../../source/contributor-how-to-build-docker-images.rst:87 +#: ../../source/contributor-how-to-build-docker-images.rst:42 +#: ../../source/contributor-how-to-build-docker-images.rst:99 #, fuzzy msgid "Description" msgstr "停用" -#: ../../source/contributor-how-to-build-docker-images.rst:46 -#: ../../source/contributor-how-to-build-docker-images.rst:88 +#: ../../source/contributor-how-to-build-docker-images.rst:43 +#: ../../source/contributor-how-to-build-docker-images.rst:100 #, fuzzy msgid "Required" msgstr "所需变更" -#: ../../source/contributor-how-to-build-docker-images.rst:47 -#: ../../source/contributor-how-to-build-docker-images.rst:89 +#: ../../source/contributor-how-to-build-docker-images.rst:44 +#: ../../source/contributor-how-to-build-docker-images.rst:101 #, fuzzy msgid "Example" msgstr "实例" +#: ../../source/contributor-how-to-build-docker-images.rst:45 +msgid "``DISTRO``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:46 +#, fuzzy +msgid "The Linux distribution to use as the base image." +msgstr "基础镜像的存储库名称。" + +#: ../../source/contributor-how-to-build-docker-images.rst:47 +#: ../../source/contributor-how-to-build-docker-images.rst:51 +#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:71 +#: ../../source/contributor-how-to-build-docker-images.rst:104 +#, fuzzy +msgid "No" +msgstr "现在" + #: ../../source/contributor-how-to-build-docker-images.rst:48 -#: ../../source/contributor-how-to-build-docker-images.rst:94 #, fuzzy -msgid "``PYTHON_VERSION``" -msgstr "Python 版本" +msgid "``ubuntu``" +msgstr "``UBUNTU_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:49 #, fuzzy -msgid "Version of ``python`` to be installed." -msgstr "要安装的 ``python`` 版本。" +msgid "``DISTRO_VERSION``" +msgstr "``PIP_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:50 -#: ../../source/contributor-how-to-build-docker-images.rst:54 -#: ../../source/contributor-how-to-build-docker-images.rst:58 -#: ../../source/contributor-how-to-build-docker-images.rst:108 -#, fuzzy -msgid "Yes" -msgstr "类型" +msgid "Version of the Linux distribution." +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:51 +#: ../../source/contributor-how-to-build-docker-images.rst:52 #, fuzzy -msgid "``3.11``" +msgid "``22.04``" msgstr "``1.0.0rc1``" -#: ../../source/contributor-how-to-build-docker-images.rst:52 +#: ../../source/contributor-how-to-build-docker-images.rst:53 +#, fuzzy +msgid "``PYTHON_VERSION``" +msgstr "Python 版本" + +#: ../../source/contributor-how-to-build-docker-images.rst:54 +#, fuzzy +msgid "Version of ``python`` to be installed." +msgstr "要安装的 ``python`` 版本。" + +#: ../../source/contributor-how-to-build-docker-images.rst:56 +msgid "``3.11`` or ``3.11.1``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:57 #, fuzzy msgid "``PIP_VERSION``" msgstr "``PIP_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:53 +#: ../../source/contributor-how-to-build-docker-images.rst:58 #, fuzzy msgid "Version of ``pip`` to be installed." msgstr "要安装的 ``pip` 版本。" -#: ../../source/contributor-how-to-build-docker-images.rst:55 +#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:63 +#: ../../source/contributor-how-to-build-docker-images.rst:67 +#: ../../source/contributor-how-to-build-docker-images.rst:108 +#, fuzzy +msgid "Yes" +msgstr "类型" + +#: ../../source/contributor-how-to-build-docker-images.rst:60 #, fuzzy msgid "``23.0.1``" msgstr "``1.0.0rc1``" -#: ../../source/contributor-how-to-build-docker-images.rst:56 +#: ../../source/contributor-how-to-build-docker-images.rst:61 #, fuzzy msgid "``SETUPTOOLS_VERSION``" msgstr "设置工具版本" -#: ../../source/contributor-how-to-build-docker-images.rst:57 +#: ../../source/contributor-how-to-build-docker-images.rst:62 #, fuzzy msgid "Version of ``setuptools`` to be installed." msgstr "要安装的 `setuptools`` 版本。" -#: ../../source/contributor-how-to-build-docker-images.rst:59 +#: ../../source/contributor-how-to-build-docker-images.rst:64 #, fuzzy msgid "``69.0.2``" msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-build-docker-images.rst:60 -#: ../../source/contributor-how-to-build-docker-images.rst:98 +#: ../../source/contributor-how-to-build-docker-images.rst:65 #, fuzzy -msgid "``UBUNTU_VERSION``" -msgstr "``UBUNTU_VERSION``" +msgid "``FLWR_VERSION``" +msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:61 +#: ../../source/contributor-how-to-build-docker-images.rst:66 #, fuzzy -msgid "Version of the official Ubuntu Docker image." -msgstr "官方 Ubuntu Docker 映像的版本。" +msgid "Version of Flower to be installed." +msgstr "要安装的 Flower 版本。" -#: ../../source/contributor-how-to-build-docker-images.rst:62 +#: ../../source/contributor-how-to-build-docker-images.rst:68 +#, fuzzy +msgid "``1.8.0``" +msgstr "``1.0.0b0``" + +#: ../../source/contributor-how-to-build-docker-images.rst:69 #, fuzzy -msgid "Defaults to ``22.04``." -msgstr "默认为 ``22.04``。" +msgid "``FLWR_PACKAGE``" +msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:65 +#: ../../source/contributor-how-to-build-docker-images.rst:70 +#, fuzzy +msgid "The Flower package to be installed." +msgstr "要安装的 PyPI 软件包。" + +#: ../../source/contributor-how-to-build-docker-images.rst:72 +msgid "``flwr`` or ``flwr-nightly``" +msgstr "" + +#: ../../source/contributor-how-to-build-docker-images.rst:75 #, fuzzy msgid "" -"The following example creates a base image with Python 3.11.0, pip 23.0.1" -" and setuptools 69.0.2:" +"The following example creates a base Ubuntu/Alpine image with Python " +"3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" msgstr "下面的示例使用 Python 3.11.0、pip 23.0.1 和 setuptools 69.0.2 创建了基本映像:" -#: ../../source/contributor-how-to-build-docker-images.rst:76 +#: ../../source/contributor-how-to-build-docker-images.rst:88 #, fuzzy msgid "" "The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " @@ -250,103 +285,59 @@ msgid "" "needs. These values serve as examples only." msgstr "图像名称为 ``flwr_base``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" -#: ../../source/contributor-how-to-build-docker-images.rst:80 +#: ../../source/contributor-how-to-build-docker-images.rst:92 #, fuzzy -msgid "Building the SuperLink image" +msgid "Building the SuperLink/SuperNode or ServerApp image" msgstr "启动服务器" -#: ../../source/contributor-how-to-build-docker-images.rst:90 +#: ../../source/contributor-how-to-build-docker-images.rst:102 #, fuzzy msgid "``BASE_REPOSITORY``" msgstr "基础存储库" -#: ../../source/contributor-how-to-build-docker-images.rst:91 +#: ../../source/contributor-how-to-build-docker-images.rst:103 #, fuzzy msgid "The repository name of the base image." msgstr "基础镜像的存储库名称。" -#: ../../source/contributor-how-to-build-docker-images.rst:92 -#, fuzzy -msgid "Defaults to ``flwr/base``." -msgstr "默认为 ``flwr/server``。" - -#: ../../source/contributor-how-to-build-docker-images.rst:95 -#, fuzzy -msgid "The Python version of the base image." -msgstr "基础镜像的存储库名称。" - -#: ../../source/contributor-how-to-build-docker-images.rst:96 -#, fuzzy -msgid "Defaults to ``py3.11``." -msgstr "默认为 ``22.04``。" - -#: ../../source/contributor-how-to-build-docker-images.rst:99 -#, fuzzy -msgid "The Ubuntu version of the base image." -msgstr "基础镜像的存储库名称。" - -#: ../../source/contributor-how-to-build-docker-images.rst:100 -#, fuzzy -msgid "Defaults to ``ubuntu22.04``." -msgstr "默认为 ``py3.11-ubuntu22.04``。" - -#: ../../source/contributor-how-to-build-docker-images.rst:102 +#: ../../source/contributor-how-to-build-docker-images.rst:105 #, fuzzy -msgid "``FLWR_PACKAGE``" +msgid "``flwr/base``" msgstr "``FLWR_VERSION``" -#: ../../source/contributor-how-to-build-docker-images.rst:103 -#, fuzzy -msgid "The PyPI package to install." -msgstr "要安装的 PyPI 软件包。" - -#: ../../source/contributor-how-to-build-docker-images.rst:104 -#, fuzzy -msgid "Defaults to ``flwr``." -msgstr "默认为 ``flwr/server``。" - #: ../../source/contributor-how-to-build-docker-images.rst:106 #, fuzzy -msgid "``FLWR_VERSION``" -msgstr "``FLWR_VERSION``" +msgid "``BASE_IMAGE``" +msgstr "基础存储库" #: ../../source/contributor-how-to-build-docker-images.rst:107 #, fuzzy -msgid "Version of Flower to be installed." -msgstr "要安装的 Flower 版本。" +msgid "The Tag of the Flower base image." +msgstr "基础镜像的存储库名称。" #: ../../source/contributor-how-to-build-docker-images.rst:109 -#, fuzzy -msgid "``1.8.0``" -msgstr "``1.0.0b0``" +msgid "``1.8.0-py3.10-ubuntu22.04``" +msgstr "" -#: ../../source/contributor-how-to-build-docker-images.rst:112 +#: ../../source/contributor-how-to-build-docker-images.rst:111 #, fuzzy msgid "" -"The following example creates a SuperLink image with the official Flower " -"base image py3.11-ubuntu22.04 and Flower 1.8.0:" +"The following example creates a SuperLink/SuperNode or ServerApp image " +"with the official Flower base image:" msgstr "下面的示例使用官方的 Flower 基本镜像 py3.11-ubuntu22.04 和 Flower 1.7.0 创建了一个服务器镜像:" #: ../../source/contributor-how-to-build-docker-images.rst:122 #, fuzzy msgid "" -"The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " -"that the build arguments as well as the name and tag can be adapted to " -"your needs. These values serve as examples only." -msgstr "图像名称为 ``flwr_server``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" - -#: ../../source/contributor-how-to-build-docker-images.rst:125 -#, fuzzy -msgid "" "If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` and ``UBUNTU_VERSION`` build arguments." +"base image, all you need to do is set the ``BASE_REPOSITORY`` build " +"argument." msgstr "" "如果您想使用自己的基础图片而不是 Flower 官方的基础图片,只需设置 ``BASE_REPOSITORY`` 和 " "``BASE_IMAGE_TAG`` " "联编参数即可。`BASE_REPOSITORY``的值必须与您的图像名称一致,`BASE_IMAGE_TAG``的值必须与您的图像标签一致。" -#: ../../source/contributor-how-to-build-docker-images.rst:138 +#: ../../source/contributor-how-to-build-docker-images.rst:133 #, fuzzy msgid "After creating the image, we can test whether the image is working:" msgstr "创建图像后,我们可以测试图像是否正常工作:" @@ -479,127 +470,6 @@ msgstr "" "如果您想添加新语言,请先联系我们,可以在 `Slack `_ 上联系,也可以在我们的 " "`GitHub repo `_ 上提交问题。" -#: ../../source/contributor-how-to-create-new-messages.rst:2 -msgid "Creating New Messages" -msgstr "创建新信息" - -#: ../../source/contributor-how-to-create-new-messages.rst:4 -msgid "" -"This is a simple guide for creating a new type of message between the " -"server and clients in Flower." -msgstr "这是一个如何用Flower在服务器和客户端之间创建新类型的信息的简要指导。" - -#: ../../source/contributor-how-to-create-new-messages.rst:6 -msgid "" -"Let's suppose we have the following example functions in " -":code:`server.py` and :code:`numpy_client.py`..." -msgstr "假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." - -#: ../../source/contributor-how-to-create-new-messages.rst:8 -msgid "Server's side:" -msgstr "在服务器端:" - -#: ../../source/contributor-how-to-create-new-messages.rst:17 -msgid "Client's side:" -msgstr "在客户端:" - -#: ../../source/contributor-how-to-create-new-messages.rst:26 -msgid "" -"Let's now see what we need to implement in order to get this simple " -"function between the server and client to work!" -msgstr "现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要实现哪些功能!" - -#: ../../source/contributor-how-to-create-new-messages.rst:30 -msgid "Message Types for Protocol Buffers" -msgstr "协议缓冲区的信息类型" - -#: ../../source/contributor-how-to-create-new-messages.rst:32 -#, fuzzy -msgid "" -"The first thing we need to do is to define a message type for the RPC " -"system in :code:`transport.proto`. Note that we have to do it for both " -"the request and response messages. For more details on the syntax of " -"proto3, please see the `official documentation `_." -msgstr "" -"我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC " -"系统的消息类型。请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请参阅官方文档 " -"`_。" - -#: ../../source/contributor-how-to-create-new-messages.rst:35 -msgid "Within the :code:`ServerMessage` block:" -msgstr "在 :code:`ServerMessage` 代码块中:" - -#: ../../source/contributor-how-to-create-new-messages.rst:52 -msgid "Within the ClientMessage block:" -msgstr "在 ClientMessage 代码块中:" - -#: ../../source/contributor-how-to-create-new-messages.rst:70 -msgid "" -"Make sure to also add a field of the newly created message type in " -":code:`oneof msg`." -msgstr "确保在 :code:`oneof msg` 中也添加一个新创建的消息类型字段。" - -#: ../../source/contributor-how-to-create-new-messages.rst:72 -msgid "Once that is done, we will compile the file with:" -msgstr "完成后,我们将使用:" - -#: ../../source/contributor-how-to-create-new-messages.rst:78 -msgid "If it compiles successfully, you should see the following message:" -msgstr "如果编译成功,你应该会看到以下信息:" - -#: ../../source/contributor-how-to-create-new-messages.rst:87 -msgid "Serialization and Deserialization Functions" -msgstr "序列化和反序列化函数" - -#: ../../source/contributor-how-to-create-new-messages.rst:89 -msgid "" -"Our next step is to add functions to serialize and deserialize Python " -"datatypes to or from our defined RPC message types. You should add these " -"functions in :code:`serde.py`." -msgstr "" -"下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC 消息类型或从我们定义的 RPC 消息类型反序列化和反序列化 " -"Python 数据类型。您应该在 :code:`serde.py` 中添加这些函数。" - -#: ../../source/contributor-how-to-create-new-messages.rst:91 -msgid "The four functions:" -msgstr "四种函数:" - -#: ../../source/contributor-how-to-create-new-messages.rst:112 -msgid "Sending the Message from the Server" -msgstr "从服务器发送信息" - -#: ../../source/contributor-how-to-create-new-messages.rst:114 -msgid "" -"Now write the request function in your Client Proxy class (e.g., " -":code:`grpc_client_proxy.py`) using the serde functions you just created:" -msgstr "现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 serde 函数编写请求函数:" - -#: ../../source/contributor-how-to-create-new-messages.rst:128 -msgid "Receiving the Message by the Client" -msgstr "由客户端接收信息" - -#: ../../source/contributor-how-to-create-new-messages.rst:130 -msgid "" -"Last step! Modify the code in :code:`message_handler.py` to check the " -"field of your message and call the :code:`example_response` function. " -"Remember to use the serde functions!" -msgstr "" -"最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用 " -":code:`example_response` 函数。记住使用 serde 函数!" - -#: ../../source/contributor-how-to-create-new-messages.rst:132 -msgid "Within the handle function:" -msgstr "在句柄函数内:" - -#: ../../source/contributor-how-to-create-new-messages.rst:139 -msgid "And add a new function:" -msgstr "并增加一个新函数:" - -#: ../../source/contributor-how-to-create-new-messages.rst:149 -msgid "Hopefully, when you run your program you will get the intended result!" -msgstr "希望您在运行程序时能得到预期的结果!" - #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" msgstr "使用 VSCode Dev Containers 进行开发" @@ -966,89 +836,139 @@ msgstr "" msgid "Check the draft release on GitHub, and if everything is good, publish it." msgstr "检查 GitHub 上的发布稿,如果一切正常,就发布它。" +#: ../../source/contributor-how-to-release-flower.rst:15 +#, fuzzy +msgid "Trigger the CI for building the Docker images." +msgstr "官方 Ubuntu Docker 映像的版本。" + #: ../../source/contributor-how-to-release-flower.rst:17 +msgid "" +"To trigger the workflow, a collaborator must create a " +"``workflow_dispatch`` event in the GitHub CI. This can be done either " +"through the UI or via the GitHub CLI. The event requires only one input, " +"the Flower version, to be released." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:21 +#, fuzzy +msgid "**Via the UI**" +msgstr "**审查 PR**" + +#: ../../source/contributor-how-to-release-flower.rst:23 +msgid "" +"Go to the ``Build docker images`` workflow `page " +"`_." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:24 +msgid "" +"Click on the ``Run workflow`` button and type the new version of Flower " +"in the ``Version of Flower`` input field." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:25 +msgid "Click on the **green** ``Run workflow`` button." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:29 +msgid "**Via the GitHub CI**" +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:31 +msgid "" +"Make sure you are logged in via ``gh auth login`` and that the current " +"working directory is the root of the Flower repository." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:32 +msgid "" +"Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" +"version=``." +msgstr "" + +#: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" msgstr "发布后" -#: ../../source/contributor-how-to-release-flower.rst:19 +#: ../../source/contributor-how-to-release-flower.rst:37 msgid "Create a pull request which contains the following changes:" msgstr "创建包含以下更改的拉取请求:" -#: ../../source/contributor-how-to-release-flower.rst:21 +#: ../../source/contributor-how-to-release-flower.rst:39 msgid "Increase the minor version in ``pyproject.toml`` by one." msgstr "将 ``pyproject.toml`` 中的次要版本增加一个。" -#: ../../source/contributor-how-to-release-flower.rst:22 +#: ../../source/contributor-how-to-release-flower.rst:40 msgid "Update all files which contain the current version number if necessary." msgstr "如有必要,更新包含当前版本号的所有文件。" -#: ../../source/contributor-how-to-release-flower.rst:23 +#: ../../source/contributor-how-to-release-flower.rst:41 msgid "Add a new ``Unreleased`` section in ``changelog.md``." msgstr "在 ``changelog.md`` 中添加新的 ``Unreleased`` 部分。" -#: ../../source/contributor-how-to-release-flower.rst:25 +#: ../../source/contributor-how-to-release-flower.rst:43 msgid "" "Merge the pull request on the same day (i.e., before a new nightly " "release gets published to PyPI)." msgstr "在同一天合并拉取请求(即在新版本发布到 PyPI 之前)。" -#: ../../source/contributor-how-to-release-flower.rst:28 +#: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" msgstr "发布预发布版本" -#: ../../source/contributor-how-to-release-flower.rst:31 +#: ../../source/contributor-how-to-release-flower.rst:49 msgid "Pre-release naming" msgstr "释放前命名" -#: ../../source/contributor-how-to-release-flower.rst:33 +#: ../../source/contributor-how-to-release-flower.rst:51 msgid "" "PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" " MUST use one of the following naming patterns:" msgstr "PyPI 支持预发布版本(alpha、beta、release candidate)。预发布版本必须使用以下命名模式之一:" -#: ../../source/contributor-how-to-release-flower.rst:35 +#: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" msgstr "阿尔法 ``MAJOR.MINOR.PATCHaN``" -#: ../../source/contributor-how-to-release-flower.rst:36 +#: ../../source/contributor-how-to-release-flower.rst:54 msgid "Beta: ``MAJOR.MINOR.PATCHbN``" msgstr "贝塔: ``MAJOR.MINOR.PATCHbN``" -#: ../../source/contributor-how-to-release-flower.rst:37 +#: ../../source/contributor-how-to-release-flower.rst:55 msgid "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" msgstr "版本代号 (RC): ``MAJOR.MINOR.PATCHrcN``" -#: ../../source/contributor-how-to-release-flower.rst:39 +#: ../../source/contributor-how-to-release-flower.rst:57 msgid "Examples include:" msgstr "例子包括:" -#: ../../source/contributor-how-to-release-flower.rst:41 +#: ../../source/contributor-how-to-release-flower.rst:59 msgid "``1.0.0a0``" msgstr "``1.0.0a0``" -#: ../../source/contributor-how-to-release-flower.rst:42 +#: ../../source/contributor-how-to-release-flower.rst:60 msgid "``1.0.0b0``" msgstr "``1.0.0b0``" -#: ../../source/contributor-how-to-release-flower.rst:43 +#: ../../source/contributor-how-to-release-flower.rst:61 msgid "``1.0.0rc0``" msgstr "``1.0.0rc0``" -#: ../../source/contributor-how-to-release-flower.rst:44 +#: ../../source/contributor-how-to-release-flower.rst:62 msgid "``1.0.0rc1``" msgstr "``1.0.0rc1``" -#: ../../source/contributor-how-to-release-flower.rst:46 +#: ../../source/contributor-how-to-release-flower.rst:64 msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" msgstr "这符合 PEP-440 和 Python 包装管理局 (PyPA) 的建议:" -#: ../../source/contributor-how-to-release-flower.rst:49 +#: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" msgstr "`PEP-440 `_" -#: ../../source/contributor-how-to-release-flower.rst:50 +#: ../../source/contributor-how-to-release-flower.rst:68 msgid "" "`PyPA Choosing a versioning scheme " "`_" -#: ../../source/contributor-how-to-release-flower.rst:52 +#: ../../source/contributor-how-to-release-flower.rst:70 msgid "" "Note that the approach defined by PyPA is not compatible with SemVer " "2.0.0 spec, for details consult the `Semantic Versioning Specification " @@ -1068,26 +988,26 @@ msgstr "" "规范不兼容,详情请查阅《语义版本规范》`_(特别是关于优先级的第 11 项)。" -#: ../../source/contributor-how-to-release-flower.rst:55 +#: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" msgstr "发布前分类" -#: ../../source/contributor-how-to-release-flower.rst:57 +#: ../../source/contributor-how-to-release-flower.rst:75 msgid "Should the next pre-release be called alpha, beta, or release candidate?" msgstr "下一个预发布版应该叫阿尔法版、贝塔版还是候选发布版?" -#: ../../source/contributor-how-to-release-flower.rst:59 +#: ../../source/contributor-how-to-release-flower.rst:77 msgid "" "RC: feature complete, no known issues (apart from issues that are " "classified as \"won't fix\" for the next stable release) - if no issues " "surface this will become the next stable release" msgstr "RC:功能完整,无已知问题(除了下一个稳定版中被列为 \"不会修复 \"的问题)--如果没有问题出现,这将成为下一个稳定版" -#: ../../source/contributor-how-to-release-flower.rst:60 +#: ../../source/contributor-how-to-release-flower.rst:78 msgid "Beta: feature complete, allowed to have known issues" msgstr "贝塔版:功能完整,允许存在已知问题" -#: ../../source/contributor-how-to-release-flower.rst:61 +#: ../../source/contributor-how-to-release-flower.rst:79 msgid "Alpha: not feature complete, allowed to have known issues" msgstr "阿尔法版:功能不完整,允许存在已知问题" @@ -1127,9 +1047,8 @@ msgid "" "most `Python 3.11 `_ for running Flower " "simulations." msgstr "" -"由于已知与 `ray `_ 不兼容," -"我们目前建议最多使用 `Python 3.11 `_ 运行 " -"Flower 仿真。" +"由于已知与 `ray `_ 不兼容,我们目前建议最多使用 `Python 3.11" +" `_ 运行 Flower 仿真。" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 #, fuzzy @@ -1750,8 +1669,8 @@ msgid "" "guidelines, otherwise it won't be possible to merge the PR. So in this " "case, a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" -"应该修改标题以符合 :ref:`pr_title_format` 准则,否则将无法合并 " -"PR。因此,在这种情况下,正确的标题可能是 ``docs(framework:skip)修复错字``。" +"应该修改标题以符合 :ref:`pr_title_format` 准则,否则将无法合并 PR。因此,在这种情况下,正确的标题可能是 " +"``docs(framework:skip)修复错字``。" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" @@ -2003,8 +1922,7 @@ msgstr "将更改推送到分叉" msgid "" "Open a PR (as shown above) with title ``docs(framework) Update how-to " "guide title``" -msgstr "打开一个 PR(如上图所示),标题为\"`docs(framework) Update how-to guide " -"title```\"。" +msgstr "打开一个 PR(如上图所示),标题为\"`docs(framework) Update how-to guide title```\"。" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" @@ -2072,8 +1990,7 @@ msgid "" msgstr "" "其中 ```` 需要使用 ``{ci, fix, feat, docs, refactor, break}``, " "```` 应该使用 ``{framework, baselines, datasets, examples, 或者 '*' " -"当修改多个项目时需要使用 ':skip'标记}``, 并且 ```` " -"应该以一个大写的动词开始。" +"当修改多个项目时需要使用 ':skip'标记}``, 并且 ```` 应该以一个大写的动词开始。" #: ../../source/contributor-tutorial-contribute-on-github.rst:341 #, fuzzy @@ -2131,15 +2048,15 @@ msgstr "feat(框架) 添加 flwr 构建 CLI 命令。" #, fuzzy msgid "``Add flwr build CLI command.`` (missing ``()``)" msgstr "" -"``添加 flwr build CLI 命令.``(缺少``()``) ``Add flwr build " -"CLI command.`` (missing ``()``)" +"``添加 flwr build CLI 命令.``(缺少``()``) ``Add flwr build CLI " +"command.`` (missing ``()``)" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 msgid "Get started as a contributor" msgstr "成为贡献者" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 -#: ../../source/how-to-run-flower-using-docker.rst:132 +#: ../../source/how-to-run-flower-using-docker.rst:153 msgid "Prerequisites" msgstr "先决条件" @@ -2308,8 +2225,8 @@ msgid "" "``./dev/format.sh`` and ``./dev/test.sh`` scripts." msgstr "" "开发人员可利用 `pre-commit `_ " -"库将预提交钩子集成到工作流程中。预提交钩子被配置为执行两个主要操作: `./dev/" -"format.sh`` 和 ``./dev/test.sh`` 脚本。" +"库将预提交钩子集成到工作流程中。预提交钩子被配置为执行两个主要操作: `./dev/format.sh`` 和 ``./dev/test.sh``" +" 脚本。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 #, fuzzy @@ -2341,16 +2258,14 @@ msgid "" "For developers who prefer not to install the hook permanently, it is " "possible to execute a one-time check prior to committing changes by using" " the following command:" -msgstr "对于不想永久安装钩子的开发人员,可以使用以下命令在提交更改之前执行一次性检查" -":" +msgstr "对于不想永久安装钩子的开发人员,可以使用以下命令在提交更改之前执行一次性检查:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 #, fuzzy msgid "" "This executes the formatting and linting checks/tests on all the files " "without modifying the default behavior of ``git commit``." -msgstr "这将在不修改 ``git commit`` " -"默认行为的情况下对所有文件执行格式化和词排检查/测试。" +msgstr "这将在不修改 ``git commit`` 默认行为的情况下对所有文件执行格式化和词排检查/测试。" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 msgid "Run Github Actions (CI) locally" @@ -4124,9 +4039,8 @@ msgid "" "Flower node authentication works similar to how GitHub SSH authentication" " works:" msgstr "" -"Flower 内置了对经过身份验证的超级节点的支持,您可以用它来验证连接到超级链接的" -"每个超级节点的身份。Flower 节点身份验证的工作方式与 GitHub SSH " -"身份验证的工作方式类似:" +"Flower 内置了对经过身份验证的超级节点的支持,您可以用它来验证连接到超级链接的每个超级节点的身份。Flower 节点身份验证的工作方式与 " +"GitHub SSH 身份验证的工作方式类似:" #: ../../source/how-to-authenticate-supernodes.rst:7 #, fuzzy @@ -4194,19 +4108,18 @@ msgid "" ":code:`SuperNode` that has both secure connections and node " "authentication enabled:" msgstr "" -"要启用节点验证,首先需要配置 SSL/TLS 连接,以确保 SuperLink<>SuperNode " -"通信的安全。您可以在 `_ 找到完整的指南。配置安全连接后,您就可以在长期运行的 " -"Flower :code:`SuperLink`中启用客户端身份验证。" -"使用以下终端命令启动一个同时启用了安全连接和节点验证的 Flower " +"要启用节点验证,首先需要配置 SSL/TLS 连接,以确保 SuperLink<>SuperNode 通信的安全。您可以在 " +"`_ " +"找到完整的指南。配置安全连接后,您就可以在长期运行的 Flower " +":code:`SuperLink`中启用客户端身份验证。使用以下终端命令启动一个同时启用了安全连接和节点验证的 Flower " ":code:`SuperNode`:" -#: ../../source/how-to-authenticate-supernodes.rst:36 +#: ../../source/how-to-authenticate-supernodes.rst:38 #, fuzzy msgid "Let's break down the authentication flags:" msgstr "让我们来分析一下身份验证标志:" -#: ../../source/how-to-authenticate-supernodes.rst:38 +#: ../../source/how-to-authenticate-supernodes.rst:40 #, fuzzy msgid "" "The first flag :code:`--auth-list-public-keys` expects a path to a CSV " @@ -4214,11 +4127,10 @@ msgid "" " public keys that are allowed to participate in a federation in one CSV " "file (:code:`.csv`)." msgstr "" -"第一个标志 :code:`--auth-list-public-keys`(密码:`--auth-list-public-keys`)" -"需要一个 CSV 文件路径,该文件存储了所有已知节点的公钥。您需要在一个 CSV " -"文件(:code:`.csv`)中存储所有允许参与联盟的已知节点公钥。" +"第一个标志 :code:`--auth-list-public-keys`(密码:`--auth-list-public-keys`)需要一个 " +"CSV 文件路径,该文件存储了所有已知节点的公钥。您需要在一个 CSV 文件(:code:`.csv`)中存储所有允许参与联盟的已知节点公钥。" -#: ../../source/how-to-authenticate-supernodes.rst:40 +#: ../../source/how-to-authenticate-supernodes.rst:42 #, fuzzy msgid "" "A valid CSV file storing known node public keys should list the keys in " @@ -4227,10 +4139,9 @@ msgid "" "known node public keys." msgstr "" "存储已知节点公开密钥的有效 CSV 文件应以 OpenSSH " -"格式列出密钥,以逗号分隔,不含任何注释。有关示例,请参阅我们的代码示例," -"其中包含一个包含两个已知节点公钥的 CSV 文件。" +"格式列出密钥,以逗号分隔,不含任何注释。有关示例,请参阅我们的代码示例,其中包含一个包含两个已知节点公钥的 CSV 文件。" -#: ../../source/how-to-authenticate-supernodes.rst:42 +#: ../../source/how-to-authenticate-supernodes.rst:44 #, fuzzy msgid "" "The second and third flags :code:`--auth-superlink-private-key` and :code" @@ -4238,11 +4149,11 @@ msgid "" "public keys. For development purposes, you can generate a private and " "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -"第二和第三个标记 :code:`--auth-superlink-private-key` 和 :code:`--auth-" -"superlink-public-key` 希望指向服务器私钥和公钥的路径。出于开发目的," -"您可以使用 :code:`ssh-keygen -t ecdsa -b 384` 生成一对私钥和公钥。" +"第二和第三个标记 :code:`--auth-superlink-private-key` 和 :code:`--auth-superlink-" +"public-key` 希望指向服务器私钥和公钥的路径。出于开发目的,您可以使用 :code:`ssh-keygen -t ecdsa -b " +"384` 生成一对私钥和公钥。" -#: ../../source/how-to-authenticate-supernodes.rst:45 +#: ../../source/how-to-authenticate-supernodes.rst:47 #, fuzzy msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " @@ -4251,16 +4162,15 @@ msgid "" "start the server again. Support for dynamically changing the set of known" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -"在 Flower 1.9 中,超级链接不支持动态删除、编辑或添加已知节点公钥。要更改已知" -"节点集,您需要关闭服务器,编辑 CSV 文件,然后重新启动服务器。" -"动态更改已知节点集的支持已列入 Flower 1.10(预计发布时间:6 月)的路线图。" +"在 Flower 1.9 中,超级链接不支持动态删除、编辑或添加已知节点公钥。要更改已知节点集,您需要关闭服务器,编辑 CSV " +"文件,然后重新启动服务器。动态更改已知节点集的支持已列入 Flower 1.10(预计发布时间:6 月)的路线图。" -#: ../../source/how-to-authenticate-supernodes.rst:51 +#: ../../source/how-to-authenticate-supernodes.rst:53 #, fuzzy msgid "Enable node authentication in :code:`SuperNode`" msgstr "在 :code:`SuperNode` 中启用节点验证" -#: ../../source/how-to-authenticate-supernodes.rst:53 +#: ../../source/how-to-authenticate-supernodes.rst:55 #, fuzzy msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " @@ -4268,11 +4178,10 @@ msgid "" "(:code:`SuperNode`). Use the following terminal command to start an " "authenticated :code:`SuperNode`:" msgstr "" -"与长期运行的 Flower 服务器(:code:`SuperLink`)类似,您也可以在长期运行的 " -"Flower 客户端(:code:`SuperNode`)中轻松启用节点身份验证。" -"使用以下终端命令启动已验证的 :code:`SuperNode`:" +"与长期运行的 Flower 服务器(:code:`SuperLink`)类似,您也可以在长期运行的 Flower " +"客户端(:code:`SuperNode`)中轻松启用节点身份验证。使用以下终端命令启动已验证的 :code:`SuperNode`:" -#: ../../source/how-to-authenticate-supernodes.rst:64 +#: ../../source/how-to-authenticate-supernodes.rst:66 #, fuzzy msgid "" "The :code:`--auth-supernode-private-key` flag expects a path to the " @@ -4281,16 +4190,16 @@ msgid "" "you can generate a private and public key pair using :code:`ssh-keygen -t" " ecdsa -b 384`." msgstr "" -":code:`--auth-supernode-private-key`标志需要节点私钥文件的路径,:code:`-auth-" -"supernode-public-key`标志需要节点公钥文件的路径。出于开发目的,可以使用 :code" -":`ssh-keygen -t ecdsa -b 384` 生成一对私钥和公钥。" +":code:`--auth-supernode-private-key`标志需要节点私钥文件的路径,:code:`-auth-supernode-" +"public-key`标志需要节点公钥文件的路径。出于开发目的,可以使用 :code:`ssh-keygen -t ecdsa -b 384` " +"生成一对私钥和公钥。" -#: ../../source/how-to-authenticate-supernodes.rst:68 +#: ../../source/how-to-authenticate-supernodes.rst:70 #, fuzzy msgid "Security notice" msgstr "安全通知" -#: ../../source/how-to-authenticate-supernodes.rst:70 +#: ../../source/how-to-authenticate-supernodes.rst:72 #, fuzzy msgid "" "The system's security relies on the credentials of the SuperLink and each" @@ -4301,18 +4210,17 @@ msgid "" "communication is done in a secure manner, using trusted communication " "methods." msgstr "" -"系统的安全性依赖于超级链接和每个超级节点的凭证。因此,必须保护和安全存储凭证" -",以避免公钥基础设施 (PKI) 假冒攻击等安全风险。节点验证机制还涉及人机交互,因" -"此请确保使用可信的通信方法,以安全的方式进行所有通信。" +"系统的安全性依赖于超级链接和每个超级节点的凭证。因此,必须保护和安全存储凭证,以避免公钥基础设施 (PKI) " +"假冒攻击等安全风险。节点验证机制还涉及人机交互,因此请确保使用可信的通信方法,以安全的方式进行所有通信。" -#: ../../source/how-to-authenticate-supernodes.rst:75 -#: ../../source/how-to-enable-ssl-connections.rst:65 +#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:68 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" msgstr "总结" -#: ../../source/how-to-authenticate-supernodes.rst:77 +#: ../../source/how-to-authenticate-supernodes.rst:79 #, fuzzy msgid "" "You should now have learned how to start a long-running Flower server " @@ -4320,9 +4228,8 @@ msgid "" "authentication enabled. You should also know the significance of the " "private key and store it safely to minimize security risks." msgstr "" -"现在,您应该已经学会了如何启动长期运行的 Flower 服务器(:code:`SuperLink`)和" -"客户端(:code:`SuperNode`)并启用节点身份验证。您还应该知道私钥的重要性,并将" -"其安全存储,以尽量减少安全风险。" +"现在,您应该已经学会了如何启动长期运行的 Flower " +"服务器(:code:`SuperLink`)和客户端(:code:`SuperNode`)并启用节点身份验证。您还应该知道私钥的重要性,并将其安全存储,以尽量减少安全风险。" #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" @@ -4636,7 +4543,7 @@ msgid "" " the previously generated certificates:" msgstr "现在我们将演示如何编写一个客户端,使用之前生成的脚本:" -#: ../../source/how-to-enable-ssl-connections.rst:47 +#: ../../source/how-to-enable-ssl-connections.rst:50 #, fuzzy msgid "" "When providing certificates, the server expects a tuple of three " @@ -4644,19 +4551,19 @@ msgid "" " key." msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" -#: ../../source/how-to-enable-ssl-connections.rst:51 +#: ../../source/how-to-enable-ssl-connections.rst:54 #, fuzzy msgid "Client (SuperNode)" msgstr "客户端状态代码。" -#: ../../source/how-to-enable-ssl-connections.rst:53 +#: ../../source/how-to-enable-ssl-connections.rst:56 #, fuzzy msgid "" "Use the following terminal command to start a client (SuperNode) that " "uses the previously generated certificates:" msgstr "现在我们将演示如何编写一个客户端,使用之前生成的脚本:" -#: ../../source/how-to-enable-ssl-connections.rst:61 +#: ../../source/how-to-enable-ssl-connections.rst:64 #, fuzzy msgid "" "When setting :code:`root_certificates`, the client expects a file path to" @@ -4665,7 +4572,7 @@ msgstr "" "当设置 :code:`root_certificates` 时,客户端希望 PEM 编码的根证书是字节字符串。我们再次使用 " ":code:`Path` 来简化以字节字符串形式读取证书的过程。" -#: ../../source/how-to-enable-ssl-connections.rst:67 +#: ../../source/how-to-enable-ssl-connections.rst:70 #, fuzzy msgid "" "You should now have learned how to generate self-signed certificates " @@ -4673,21 +4580,21 @@ msgid "" "establish a secure connection to it." msgstr "现在,你应该已经学会了如何使用给定的脚本生成自签名证书、启动启用 SSL 的服务器并让客户端与其建立安全连接。" -#: ../../source/how-to-enable-ssl-connections.rst:72 +#: ../../source/how-to-enable-ssl-connections.rst:75 msgid "Additional resources" msgstr "补充资源" -#: ../../source/how-to-enable-ssl-connections.rst:74 +#: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" msgstr "如果您想更深入地了解证书主题,这些额外的资料来源可能有帮助:" -#: ../../source/how-to-enable-ssl-connections.rst:76 +#: ../../source/how-to-enable-ssl-connections.rst:79 msgid "`Let's Encrypt `_" msgstr "`让我们加密 `_" -#: ../../source/how-to-enable-ssl-connections.rst:77 +#: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" msgstr "`certbot `_" @@ -5377,17 +5284,18 @@ msgstr "使用 Docker 运行 Flower" msgid "" "The simplest way to get started with Flower is by using the pre-made " "Docker images, which you can find on `Docker Hub " -"`__." +"`__. Supported architectures include " +"``amd64`` and ``arm64v8``." msgstr "" "开始使用 Flower 的最简单方法是使用预制的 Docker 镜像,您可以在 `Docker Hub " "`_ 上找到这些镜像。" -#: ../../source/how-to-run-flower-using-docker.rst:7 +#: ../../source/how-to-run-flower-using-docker.rst:8 #, fuzzy msgid "Before you start, make sure that the Docker daemon is running:" msgstr "开始之前,请确保 Docker 守护进程正在运行:" -#: ../../source/how-to-run-flower-using-docker.rst:14 +#: ../../source/how-to-run-flower-using-docker.rst:15 #, fuzzy msgid "" "If you do not see the version of Docker but instead get an error saying " @@ -5398,7 +5306,7 @@ msgstr "" "如果没有看到 Docker 的版本,而是出现找不到命令的错误,则需要先安装 Docker。你可以在 " "`_ 找到安装说明。" -#: ../../source/how-to-run-flower-using-docker.rst:20 +#: ../../source/how-to-run-flower-using-docker.rst:21 #, fuzzy msgid "" "On Linux, Docker commands require ``sudo`` privilege. If you want to " @@ -5409,7 +5317,7 @@ msgstr "" "在 Linux 上,Docker 命令需要 ``sudo`` 权限。如果你想避免使用 ``sudo``,可以按照 Docker 官方网站上的 " "`安装后步骤 `_进行操作。" -#: ../../source/how-to-run-flower-using-docker.rst:26 +#: ../../source/how-to-run-flower-using-docker.rst:27 #, fuzzy msgid "" "To ensure optimal performance and compatibility, the SuperLink, SuperNode" @@ -5417,26 +5325,25 @@ msgid "" "This guarantees seamless integration and avoids potential conflicts or " "issues that may arise from using different versions." msgstr "" -"为确保最佳性能和兼容性,SuperLink、SuperNode 和 ServerApp 映像在一起运行时必" -"须具有相同的版本。这可确保无缝集成,并避免因使用不同版本而可能产生的潜在冲突" -"或问题。" +"为确保最佳性能和兼容性,SuperLink、SuperNode 和 ServerApp " +"映像在一起运行时必须具有相同的版本。这可确保无缝集成,并避免因使用不同版本而可能产生的潜在冲突或问题。" -#: ../../source/how-to-run-flower-using-docker.rst:31 +#: ../../source/how-to-run-flower-using-docker.rst:32 #, fuzzy msgid "Flower SuperLink" msgstr "flower-superlink" -#: ../../source/how-to-run-flower-using-docker.rst:34 +#: ../../source/how-to-run-flower-using-docker.rst:35 #, fuzzy msgid "Quickstart" msgstr "快速入门 JAX" -#: ../../source/how-to-run-flower-using-docker.rst:36 +#: ../../source/how-to-run-flower-using-docker.rst:37 #, fuzzy msgid "If you're looking to try out Flower, you can use the following command:" msgstr "如果您想试用 Flower,可以使用以下命令:" -#: ../../source/how-to-run-flower-using-docker.rst:42 +#: ../../source/how-to-run-flower-using-docker.rst:43 #, fuzzy msgid "" "The command pulls the Docker image with the tag ``1.8.0`` from Docker " @@ -5447,7 +5354,7 @@ msgstr "" "Flower、Python 和 Ubuntu 的信息。在本例中,它使用了 Flower 1.7.0、Python 3.11 和 Ubuntu " "22.04。rm \"标记告诉 Docker 在退出后移除容器。" -#: ../../source/how-to-run-flower-using-docker.rst:48 +#: ../../source/how-to-run-flower-using-docker.rst:49 #, fuzzy msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " @@ -5458,7 +5365,7 @@ msgstr "" "默认情况下,Flower 服务器会将状态保存在内存中。使用 Docker 标志 ``--rm`` " "时,状态不会在容器启动之间持久化。下面我们将展示如何将状态保存到主机系统上的文件中。" -#: ../../source/how-to-run-flower-using-docker.rst:52 +#: ../../source/how-to-run-flower-using-docker.rst:53 #, fuzzy msgid "" "The ``-p :`` flag tells Docker to map the ports " @@ -5473,9 +5380,9 @@ msgstr "" "``http://localhost:9092`` 上访问 Fleet API。最后,标签后面的任何标志都会传递给 Flower " "服务器。在这里,我们传递的标志是 ``--insecure`` 。" -#: ../../source/how-to-run-flower-using-docker.rst:59 -#: ../../source/how-to-run-flower-using-docker.rst:238 -#: ../../source/how-to-run-flower-using-docker.rst:354 +#: ../../source/how-to-run-flower-using-docker.rst:60 +#: ../../source/how-to-run-flower-using-docker.rst:259 +#: ../../source/how-to-run-flower-using-docker.rst:376 #, fuzzy msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " @@ -5488,59 +5395,70 @@ msgstr "" "`_。" -#: ../../source/how-to-run-flower-using-docker.rst:64 +#: ../../source/how-to-run-flower-using-docker.rst:65 #, fuzzy msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" msgstr "您可以使用 ``--help`` 查看服务器支持的所有可用标记:" -#: ../../source/how-to-run-flower-using-docker.rst:71 +#: ../../source/how-to-run-flower-using-docker.rst:72 #, fuzzy msgid "Mounting a volume to store the state on the host system" msgstr "在主机系统上挂载卷以存储状态" -#: ../../source/how-to-run-flower-using-docker.rst:73 -#, fuzzy +#: ../../source/how-to-run-flower-using-docker.rst:74 msgid "" "If you want to persist the state of the SuperLink on your host system, " -"all you need to do is specify a path where you want to save the file on " -"your host system and a name for the database file. In the example below, " -"we tell Docker via the flag ``--volume`` to mount the user's home " -"directory (``~/`` on your host) into the ``/app/`` directory of the " -"container. Furthermore, we use the flag ``--database`` to specify the " -"name of the database file." +"all you need to do is specify a directory where you want to save the file" +" on your host system and a name for the database file. By default, the " +"SuperLink container runs with a non-root user called ``app`` with the " +"user ID ``49999``. It is recommended to create new directory and change " +"the user ID of the directory to ``49999`` to ensure the mounted directory" +" has the proper permissions. If you later want to delete the directory, " +"you can change the user ID back to the current user ID by running ``sudo " +"chown -R $USER:$(id -gn) state``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:82 +#, fuzzy +msgid "" +"In the example below, we create a new directory, change the user ID and " +"tell Docker via the flag ``--volume`` to mount the local ``state`` " +"directory into the ``/app/state`` directory of the container. " +"Furthermore, we use the flag ``--database`` to specify the name of the " +"database file." msgstr "" "如果想在主机系统上持久保存服务器的状态,只需在主机系统上指定保存文件的路径和数据库文件的名称即可。在下面的示例中,我们通过标志 ``-v`` 告诉" " Docker 将用户的主目录(主机上的 ``~/``)挂载到容器的 ``/app/`` 目录中。此外,我们使用标志 ``--database``" " 来指定数据库文件的名称。" -#: ../../source/how-to-run-flower-using-docker.rst:86 +#: ../../source/how-to-run-flower-using-docker.rst:95 #, fuzzy msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " -"user's home directory on your host system. If the file already exists, " -"the SuperLink tries to restore the state from the file. To start the " +"``state`` directory on your host system. If the file already exists, the " +"SuperLink tries to restore the state from the file. To start the " "SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" "服务器一启动,就会在主机系统的用户主目录下创建文件 " "``state.db``。如果该文件已经存在,服务器会尝试从该文件恢复状态。要以空数据库启动服务器,只需删除 ``state.db`` 文件即可。" -#: ../../source/how-to-run-flower-using-docker.rst:91 -#: ../../source/how-to-run-flower-using-docker.rst:260 -#: ../../source/how-to-run-flower-using-docker.rst:375 +#: ../../source/how-to-run-flower-using-docker.rst:100 +#: ../../source/how-to-run-flower-using-docker.rst:281 +#: ../../source/how-to-run-flower-using-docker.rst:397 #, fuzzy msgid "Enabling SSL for secure connections" msgstr "启用 SSL 连接" -#: ../../source/how-to-run-flower-using-docker.rst:93 +#: ../../source/how-to-run-flower-using-docker.rst:102 #, fuzzy msgid "" "To enable SSL, you will need a PEM-encoded root certificate, a PEM-" "encoded private key and a PEM-encoded certificate chain." msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" -#: ../../source/how-to-run-flower-using-docker.rst:97 +#: ../../source/how-to-run-flower-using-docker.rst:106 #, fuzzy msgid "" "For testing purposes, you can generate your own self-signed certificates." @@ -5551,31 +5469,43 @@ msgstr "" "出于测试目的,你可以生成自己的自签名证书。启用 SSL 连接 `_ 页面中有一个部分将指导你完成这一过程。" -#: ../../source/how-to-run-flower-using-docker.rst:101 +#: ../../source/how-to-run-flower-using-docker.rst:110 #, fuzzy msgid "" "Assuming all files we need are in the local ``certificates`` directory, " "we can use the flag ``--volume`` to mount the local directory into the " -"``/app/`` directory of the container. This allows the SuperLink to access" -" the files within the container. Finally, we pass the names of the " -"certificates to the SuperLink with the ``--certificates`` flag." +"``/app/certificates/`` directory of the container. This allows the " +"SuperLink to access the files within the container. The ``ro`` stands for" +" ``read-only``. Docker volumes default to ``read-write``; that option " +"tells Docker to make the volume ``read-only`` instead. Finally, we pass " +"the names of the certificates and key file to the SuperLink with the " +"``--ssl-ca-certfile``, ``--ssl-certfile`` and ``--ssl-keyfile`` flag." msgstr "" "假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " "``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" -#: ../../source/how-to-run-flower-using-docker.rst:113 -#, fuzzy -msgid "Flower SuperNode" -msgstr "Flower 服务器" +#: ../../source/how-to-run-flower-using-docker.rst:128 +msgid "" +"Because Flower containers, by default, run with a non-root user ``app``, " +"the mounted files and directories must have the proper permissions for " +"the user ID ``49999``. For example, to change the user ID of all files in" +" the ``certificates/`` directory, you can run ``sudo chown -R 49999:49999" +" certificates/*``." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:134 +#, fuzzy +msgid "Flower SuperNode" +msgstr "Flower 服务器" -#: ../../source/how-to-run-flower-using-docker.rst:115 +#: ../../source/how-to-run-flower-using-docker.rst:136 #, fuzzy msgid "" "The SuperNode Docker image comes with a pre-installed version of Flower " "and serves as a base for building your own SuperNode image." msgstr "超级节点 Docker 镜像预装了 Flower 版本,可作为构建自己的超级节点镜像的基础。" -#: ../../source/how-to-run-flower-using-docker.rst:120 +#: ../../source/how-to-run-flower-using-docker.rst:141 #, fuzzy msgid "" "The SuperNode Docker image currently works only with the 1.9.0-nightly " @@ -5585,21 +5515,18 @@ msgid "" "same day. To ensure the versions are in sync, using the concrete tag, " "e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" -"超级节点 Docker 映像目前仅适用于 1.9.0-nightly 版本。稳定版将在 Flower 1.9." -"0(稳定版)发布时推出(预计发布时间:5 月)。超级节点夜间镜像必须与同一天发布" -"的相应超级链接和服务器应用程序夜间镜像配对。为确保版本同步,建议使用具体标签" -",例如``1.9.0.dev20240501``,而不是``nightly``。" +"超级节点 Docker 映像目前仅适用于 1.9.0-nightly 版本。稳定版将在 Flower " +"1.9.0(稳定版)发布时推出(预计发布时间:5 " +"月)。超级节点夜间镜像必须与同一天发布的相应超级链接和服务器应用程序夜间镜像配对。为确保版本同步,建议使用具体标签,例如``1.9.0.dev20240501``,而不是``nightly``。" -#: ../../source/how-to-run-flower-using-docker.rst:126 +#: ../../source/how-to-run-flower-using-docker.rst:147 #, fuzzy msgid "" "We will use the ``quickstart-pytorch`` example, which you can find in the" " Flower repository, to illustrate how you can dockerize your ClientApp." -msgstr "" -"我们将使用 \"quickstart-pytorch\"(快速启动-pytorch)示例来说明如何对 " -"ClientApp 进行 docker 化。" +msgstr "我们将使用 \"quickstart-pytorch\"(快速启动-pytorch)示例来说明如何对 ClientApp 进行 docker 化。" -#: ../../source/how-to-run-flower-using-docker.rst:134 +#: ../../source/how-to-run-flower-using-docker.rst:155 #, fuzzy msgid "" "Before we can start, we need to meet a few prerequisites in our local " @@ -5607,33 +5534,33 @@ msgid "" "your ClientApp instead of the ``quickstart-pytorch`` example." msgstr "在开始之前,我们需要在本地开发环境中满足一些先决条件。" -#: ../../source/how-to-run-flower-using-docker.rst:138 +#: ../../source/how-to-run-flower-using-docker.rst:159 #, fuzzy msgid "Clone the Flower repository." msgstr "**叉花仓库**" -#: ../../source/how-to-run-flower-using-docker.rst:152 +#: ../../source/how-to-run-flower-using-docker.rst:173 #, fuzzy msgid "Creating a SuperNode Dockerfile" msgstr "创建超级节点 Dockerfile" -#: ../../source/how-to-run-flower-using-docker.rst:154 -#: ../../source/how-to-run-flower-using-docker.rst:289 +#: ../../source/how-to-run-flower-using-docker.rst:175 +#: ../../source/how-to-run-flower-using-docker.rst:311 #, fuzzy msgid "Let's assume the following project layout:" msgstr "假设项目布局如下" -#: ../../source/how-to-run-flower-using-docker.rst:163 +#: ../../source/how-to-run-flower-using-docker.rst:184 #, fuzzy msgid "" "First, we need to create a ``requirements.txt`` file in the directory " "where the ``ClientApp`` code is located. In the file, we list all the " "dependencies that the ClientApp requires." msgstr "" -"首先,我们需要在 ``ClientApp`` 代码所在的目录中创建一个 ``requirements.txt`` " -"文件。在该文件中,我们列出了 ClientApp 需要的所有依赖项。" +"首先,我们需要在 ``ClientApp`` 代码所在的目录中创建一个 ``requirements.txt`` 文件。在该文件中,我们列出了 " +"ClientApp 需要的所有依赖项。" -#: ../../source/how-to-run-flower-using-docker.rst:175 +#: ../../source/how-to-run-flower-using-docker.rst:196 #, fuzzy msgid "" "Note that `flwr `__ is already installed " @@ -5641,29 +5568,27 @@ msgid "" "package dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" -"请注意,`flwr `__ 已经安装在`flwr/" -"supernode``基础镜像中,因此只需在`requirements." -"txt``中包含其他依赖包,如`torch``、`tensorflow`等。" +"请注意,`flwr `__ " +"已经安装在`flwr/supernode``基础镜像中,因此只需在`requirements.txt``中包含其他依赖包,如`torch``、`tensorflow`等。" -#: ../../source/how-to-run-flower-using-docker.rst:179 +#: ../../source/how-to-run-flower-using-docker.rst:200 #, fuzzy msgid "" "Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " "example, create a new file called ``Dockerfile.supernode`` in ``examples" "/quickstart-pytorch``." msgstr "" -"接下来,我们创建一个 Dockerfile。如果使用 ``quickstart-pytorch`` 示例,请在 " -"``examples/quickstart-pytorch`` 中创建一个名为 ``Dockerfile.supernode`` " -"的新文件。" +"接下来,我们创建一个 Dockerfile。如果使用 ``quickstart-pytorch`` 示例,请在 ``examples" +"/quickstart-pytorch`` 中创建一个名为 ``Dockerfile.supernode`` 的新文件。" -#: ../../source/how-to-run-flower-using-docker.rst:182 +#: ../../source/how-to-run-flower-using-docker.rst:203 #, fuzzy msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." msgstr "Dockerfile.supernode \"包含组装超级节点映像的指令。" -#: ../../source/how-to-run-flower-using-docker.rst:196 +#: ../../source/how-to-run-flower-using-docker.rst:217 #, fuzzy msgid "" "In the first two lines, we instruct Docker to use the SuperNode image " @@ -5676,74 +5601,69 @@ msgid "" "``client:app``. The argument is the object reference of the ClientApp " "(``:``) that will be run inside the ClientApp." msgstr "" -"在前两行中,我们指示 Docker 使用标记为 ``nightly`` 的 SuperNode " -"镜像作为基础镜像,并将工作目录设置为 ``/app``。下面的指令将在 ``/app`` " -"目录中执行。接下来,我们通过将 ``requirements.txt`` 文件复制到映像中并运行 ``" -"pip install`` 来安装 ClientApp 依赖项。最后两行,我们将 ``client.py`` " -"模块复制到映像中,并将入口点设置为 ``flower-client-app``,参数为 " -"``client:app``。参数是将在 ClientApp 内运行的 ClientApp " -"的对象引用(``<模块>:<属性>``)。" +"在前两行中,我们指示 Docker 使用标记为 ``nightly`` 的 SuperNode 镜像作为基础镜像,并将工作目录设置为 " +"``/app``。下面的指令将在 ``/app`` 目录中执行。接下来,我们通过将 ``requirements.txt`` " +"文件复制到映像中并运行 ``pip install`` 来安装 ClientApp 依赖项。最后两行,我们将 ``client.py`` " +"模块复制到映像中,并将入口点设置为 ``flower-client-app``,参数为 ``client:app``。参数是将在 " +"ClientApp 内运行的 ClientApp 的对象引用(``<模块>:<属性>``)。" -#: ../../source/how-to-run-flower-using-docker.rst:205 +#: ../../source/how-to-run-flower-using-docker.rst:226 #, fuzzy msgid "Building the SuperNode Docker image" msgstr "启动服务器" -#: ../../source/how-to-run-flower-using-docker.rst:207 +#: ../../source/how-to-run-flower-using-docker.rst:228 #, fuzzy msgid "" "Next, we build the SuperNode Docker image by running the following " "command in the directory where Dockerfile and ClientApp code are located." -msgstr "接下来,我们在 Dockerfile 和 ClientApp 代码所在的目录下运行以下命令,构建 " -"SuperNode Docker 映像。" +msgstr "接下来,我们在 Dockerfile 和 ClientApp 代码所在的目录下运行以下命令,构建 SuperNode Docker 映像。" -#: ../../source/how-to-run-flower-using-docker.rst:214 +#: ../../source/how-to-run-flower-using-docker.rst:235 #, fuzzy msgid "" "We gave the image the name ``flwr_supernode``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." -msgstr "" -"我们将图像命名为 ``flwr_supernode``,标签为 ``0.0." -"1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" +msgstr "我们将图像命名为 ``flwr_supernode``,标签为 ``0.0.1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" -#: ../../source/how-to-run-flower-using-docker.rst:219 +#: ../../source/how-to-run-flower-using-docker.rst:240 #, fuzzy msgid "Running the SuperNode Docker image" msgstr "启动服务器" -#: ../../source/how-to-run-flower-using-docker.rst:221 +#: ../../source/how-to-run-flower-using-docker.rst:242 #, fuzzy msgid "Now that we have built the SuperNode image, we can finally run it." msgstr "现在,我们已经构建了超级节点镜像,终于可以运行它了。" -#: ../../source/how-to-run-flower-using-docker.rst:229 -#: ../../source/how-to-run-flower-using-docker.rst:345 +#: ../../source/how-to-run-flower-using-docker.rst:250 +#: ../../source/how-to-run-flower-using-docker.rst:367 #, fuzzy msgid "Let's break down each part of this command:" msgstr "让我们来分析一下这条命令的各个部分:" -#: ../../source/how-to-run-flower-using-docker.rst:231 -#: ../../source/how-to-run-flower-using-docker.rst:347 +#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:369 #, fuzzy msgid "``docker run``: This is the command to run a new Docker container." msgstr "`docker run``: 这是运行新 Docker 容器的命令。" -#: ../../source/how-to-run-flower-using-docker.rst:232 -#: ../../source/how-to-run-flower-using-docker.rst:348 +#: ../../source/how-to-run-flower-using-docker.rst:253 +#: ../../source/how-to-run-flower-using-docker.rst:370 #, fuzzy msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." msgstr "`-rm``: 该选项指定容器停止时应自动移除。" -#: ../../source/how-to-run-flower-using-docker.rst:233 +#: ../../source/how-to-run-flower-using-docker.rst:254 #, fuzzy msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." msgstr "flwr_supernode:0.0.1``: 要使用的 Docker 映像的名称和标记。" -#: ../../source/how-to-run-flower-using-docker.rst:234 -#: ../../source/how-to-run-flower-using-docker.rst:350 +#: ../../source/how-to-run-flower-using-docker.rst:255 +#: ../../source/how-to-run-flower-using-docker.rst:372 #, fuzzy msgid "``--insecure``: This option enables insecure communication." msgstr "不安全\": 该选项启用不安全通信。" @@ -5751,8 +5671,8 @@ msgstr "不安全\": 该选项启用不安全通信。" #: ../../source/how-to-run-flower-using-docker.rst #, fuzzy msgid "" -"``--server 192.168.1.100:9092``: This option specifies the address of the" -" SuperLinks Fleet" +"``--superlink 192.168.1.100:9092``: This option specifies the address of " +"the SuperLinks Fleet" msgstr "``--server 192.168.1.100:9092``: 该选项指定超级链接舰队的地址" #: ../../source/how-to-run-flower-using-docker.rst @@ -5760,7 +5680,7 @@ msgstr "``--server 192.168.1.100:9092``: 该选项指定超级链接舰队的地 msgid "API to connect to. Remember to update it with your SuperLink IP." msgstr "要连接的 API。记住用您的超级链接 IP 更新它。" -#: ../../source/how-to-run-flower-using-docker.rst:248 +#: ../../source/how-to-run-flower-using-docker.rst:269 #, fuzzy msgid "" "To test running Flower locally, you can create a `bridge network " @@ -5768,75 +5688,74 @@ msgid "" "defined-bridge-networks>`__, use the ``--network`` argument and pass the " "name of the Docker network to run your SuperNodes." msgstr "" -"要测试在本地运行 Flower,可以创建一个 \"桥接网络 `__\"," -"使用\"--网络 \"参数并传递 Docker 网络的名称,以运行超级节点。" +"要测试在本地运行 Flower,可以创建一个 \"桥接网络 `__\",使用\"--网络 " +"\"参数并传递 Docker 网络的名称,以运行超级节点。" -#: ../../source/how-to-run-flower-using-docker.rst:252 +#: ../../source/how-to-run-flower-using-docker.rst:273 #, fuzzy msgid "" "Any argument that comes after the tag is passed to the Flower SuperNode " "binary. To see all available flags that the SuperNode supports, run:" -msgstr "标记后的任何参数都将传递给 Flower " -"超级节点二进制文件。要查看超级节点支持的所有可用标记,请运行" +msgstr "标记后的任何参数都将传递给 Flower 超级节点二进制文件。要查看超级节点支持的所有可用标记,请运行" -#: ../../source/how-to-run-flower-using-docker.rst:262 +#: ../../source/how-to-run-flower-using-docker.rst:283 #, fuzzy msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your SuperNode container." msgstr "要启用 SSL,我们需要将 PEM 编码的根证书挂载到 SuperNode 容器中。" -#: ../../source/how-to-run-flower-using-docker.rst:264 +#: ../../source/how-to-run-flower-using-docker.rst:285 #, fuzzy msgid "" "Assuming the certificate already exists locally, we can use the flag " "``--volume`` to mount the local certificate into the container's " "``/app/`` directory. This allows the SuperNode to access the certificate " -"within the container. Use the ``--certificates`` flag when starting the " -"container." +"within the container. Use the ``--root-certificates`` flag when starting " +"the container." msgstr "" "假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " "``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" -#: ../../source/how-to-run-flower-using-docker.rst:275 +#: ../../source/how-to-run-flower-using-docker.rst:297 #, fuzzy msgid "Flower ServerApp" msgstr "Flower 服务器。" -#: ../../source/how-to-run-flower-using-docker.rst:277 +#: ../../source/how-to-run-flower-using-docker.rst:299 #, fuzzy msgid "" "The procedure for building and running a ServerApp image is almost " "identical to the SuperNode image." msgstr "构建和运行 ServerApp 映像的程序与 SuperNode 映像几乎完全相同。" -#: ../../source/how-to-run-flower-using-docker.rst:279 +#: ../../source/how-to-run-flower-using-docker.rst:301 #, fuzzy msgid "" "Similar to the SuperNode image, the ServerApp Docker image comes with a " "pre-installed version of Flower and serves as a base for building your " "own ServerApp image." msgstr "" -"与 SuperNode 映像类似,ServerApp Docker 映像也预装了 Flower 版本," -"可作为构建自己的 ServerApp 映像的基础。" +"与 SuperNode 映像类似,ServerApp Docker 映像也预装了 Flower 版本,可作为构建自己的 ServerApp " +"映像的基础。" -#: ../../source/how-to-run-flower-using-docker.rst:282 +#: ../../source/how-to-run-flower-using-docker.rst:304 #, fuzzy msgid "" "We will use the same ``quickstart-pytorch`` example as we do in the " "Flower SuperNode section. If you have not already done so, please follow " "the `SuperNode Prerequisites`_ before proceeding." msgstr "" -"我们将使用与 \"Flower SuperNode \"部分相同的 \"quickstart-pytorch \"示例" -"。如果您还没有这样做,请在继续之前遵循 \"SuperNode 先决条件\"。" +"我们将使用与 \"Flower SuperNode \"部分相同的 \"quickstart-pytorch " +"\"示例。如果您还没有这样做,请在继续之前遵循 \"SuperNode 先决条件\"。" -#: ../../source/how-to-run-flower-using-docker.rst:287 +#: ../../source/how-to-run-flower-using-docker.rst:309 #, fuzzy msgid "Creating a ServerApp Dockerfile" msgstr "创建 ServerApp Dockerfile" -#: ../../source/how-to-run-flower-using-docker.rst:298 +#: ../../source/how-to-run-flower-using-docker.rst:320 #, fuzzy msgid "" "First, we need to create a Dockerfile in the directory where the " @@ -5844,18 +5763,18 @@ msgid "" "example, create a new file called ``Dockerfile.serverapp`` in ``examples" "/quickstart-pytorch``." msgstr "" -"首先,我们需要在 ``ServerApp`` 代码所在的目录中创建一个 Dockerfile。如果使用 " -"``quickstart-pytorch`` 示例,请在 ``examples/quickstart-pytorch`` " -"中创建一个名为 ``Dockerfile.serverapp`` 的新文件。" +"首先,我们需要在 ``ServerApp`` 代码所在的目录中创建一个 Dockerfile。如果使用 ``quickstart-" +"pytorch`` 示例,请在 ``examples/quickstart-pytorch`` 中创建一个名为 " +"``Dockerfile.serverapp`` 的新文件。" -#: ../../source/how-to-run-flower-using-docker.rst:302 +#: ../../source/how-to-run-flower-using-docker.rst:324 #, fuzzy msgid "" "The ``Dockerfile.serverapp`` contains the instructions that assemble the " "ServerApp image." msgstr "Dockerfile.serverapp \"包含组装 ServerApp 镜像的说明。" -#: ../../source/how-to-run-flower-using-docker.rst:313 +#: ../../source/how-to-run-flower-using-docker.rst:335 #, fuzzy msgid "" "In the first two lines, we instruct Docker to use the ServerApp image " @@ -5867,46 +5786,42 @@ msgid "" "ServerApp (``:``) that will be run inside the " "ServerApp container." msgstr "" -"在前两行中,我们指示 Docker 使用标记为 ``1.8.0`` 的 ServerApp " -"镜像作为基础镜像,并将工作目录设置为 ``/app``。下面的指令将在 ``/app`` " -"目录中执行。在最后两行中,我们将 ``server.py`` 模块复制到映像中," -"并将入口点设置为 ``flower-server-app``,参数为 ``server:app``。参数是将在 " +"在前两行中,我们指示 Docker 使用标记为 ``1.8.0`` 的 ServerApp 镜像作为基础镜像,并将工作目录设置为 " +"``/app``。下面的指令将在 ``/app`` 目录中执行。在最后两行中,我们将 ``server.py`` " +"模块复制到映像中,并将入口点设置为 ``flower-server-app``,参数为 ``server:app``。参数是将在 " "ServerApp 容器内运行的 ServerApp 的对象引用(``<模块>:<属性>``)。" -#: ../../source/how-to-run-flower-using-docker.rst:321 +#: ../../source/how-to-run-flower-using-docker.rst:343 #, fuzzy msgid "Building the ServerApp Docker image" msgstr "启动服务器" -#: ../../source/how-to-run-flower-using-docker.rst:323 +#: ../../source/how-to-run-flower-using-docker.rst:345 #, fuzzy msgid "" "Next, we build the ServerApp Docker image by running the following " "command in the directory where Dockerfile and ServerApp code are located." -msgstr "接下来,我们在 Dockerfile 和 ServerApp 代码所在的目录下运行以下命令,构建 " -"ServerApp Docker 镜像。" +msgstr "接下来,我们在 Dockerfile 和 ServerApp 代码所在的目录下运行以下命令,构建 ServerApp Docker 镜像。" -#: ../../source/how-to-run-flower-using-docker.rst:330 +#: ../../source/how-to-run-flower-using-docker.rst:352 #, fuzzy msgid "" "We gave the image the name ``flwr_serverapp``, and the tag ``0.0.1``. " "Remember that the here chosen values only serve as an example. You can " "change them to your needs." -msgstr "" -"我们给图片命名为 ``flwr_serverapp``,标签为 ``0.0." -"1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" +msgstr "我们给图片命名为 ``flwr_serverapp``,标签为 ``0.0.1``。请记住,这里选择的值只是一个示例。您可以根据自己的需要进行更改。" -#: ../../source/how-to-run-flower-using-docker.rst:335 +#: ../../source/how-to-run-flower-using-docker.rst:357 #, fuzzy msgid "Running the ServerApp Docker image" msgstr "启动服务器" -#: ../../source/how-to-run-flower-using-docker.rst:337 +#: ../../source/how-to-run-flower-using-docker.rst:359 #, fuzzy msgid "Now that we have built the ServerApp image, we can finally run it." msgstr "现在我们已经构建了 ServerApp 镜像,终于可以运行它了。" -#: ../../source/how-to-run-flower-using-docker.rst:349 +#: ../../source/how-to-run-flower-using-docker.rst:371 #, fuzzy msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." msgstr "flwr_serverapp:0.0.1``: 要使用的 Docker 映像的名称和标记。" @@ -5914,11 +5829,11 @@ msgstr "flwr_serverapp:0.0.1``: 要使用的 Docker 映像的名称和标记 #: ../../source/how-to-run-flower-using-docker.rst #, fuzzy msgid "" -"``--server 192.168.1.100:9091``: This option specifies the address of the" -" SuperLinks Driver" +"``--superlink 192.168.1.100:9091``: This option specifies the address of " +"the SuperLinks Driver" msgstr "``--server 192.168.1.100:9091``: 此选项指定超级链接驱动程序的地址" -#: ../../source/how-to-run-flower-using-docker.rst:363 +#: ../../source/how-to-run-flower-using-docker.rst:385 #, fuzzy msgid "" "To test running Flower locally, you can create a `bridge network " @@ -5926,64 +5841,100 @@ msgid "" "defined-bridge-networks>`__, use the ``--network`` argument and pass the " "name of the Docker network to run your ServerApps." msgstr "" -"要测试在本地运行 Flower,可以创建一个 ``bridge network `___,使用 ``--network`` 参数并传递 Docker 网络的名称,以运行 " -"ServerApps。" +"要测试在本地运行 Flower,可以创建一个 ``bridge network `___,使用 " +"``--network`` 参数并传递 Docker 网络的名称,以运行 ServerApps。" -#: ../../source/how-to-run-flower-using-docker.rst:367 +#: ../../source/how-to-run-flower-using-docker.rst:389 #, fuzzy msgid "" "Any argument that comes after the tag is passed to the Flower ServerApp " "binary. To see all available flags that the ServerApp supports, run:" -msgstr "标记后的任何参数都将传递给 Flower ServerApp 二进制文件。要查看 ServerApp " -"支持的所有可用标记,请运行" +msgstr "标记后的任何参数都将传递给 Flower ServerApp 二进制文件。要查看 ServerApp 支持的所有可用标记,请运行" -#: ../../source/how-to-run-flower-using-docker.rst:377 +#: ../../source/how-to-run-flower-using-docker.rst:399 #, fuzzy msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your ServerApp container." msgstr "要启用 SSL,需要 CA 证书、服务器证书和服务器私钥。" -#: ../../source/how-to-run-flower-using-docker.rst:379 +#: ../../source/how-to-run-flower-using-docker.rst:401 #, fuzzy msgid "" "Assuming the certificate already exists locally, we can use the flag " "``--volume`` to mount the local certificate into the container's " "``/app/`` directory. This allows the ServerApp to access the certificate " -"within the container. Use the ``--certificates`` flag when starting the " -"container." +"within the container. Use the ``--root-certificates`` flags when starting" +" the container." msgstr "" "假设我们需要的所有文件都在本地的 ``certificates`` 目录中,我们可以使用标记 ``-v`` 将本地目录挂载到容器的 " "``/app/`` 目录中。这样,服务器就可以访问容器内的文件。最后,我们使用 ``--certificates`` 标志将证书名称传递给服务器。" -#: ../../source/how-to-run-flower-using-docker.rst:390 +#: ../../source/how-to-run-flower-using-docker.rst:412 #, fuzzy msgid "Advanced Docker options" msgstr "高级安装选项" -#: ../../source/how-to-run-flower-using-docker.rst:393 +#: ../../source/how-to-run-flower-using-docker.rst:415 +msgid "Run with root user privileges" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:417 +msgid "" +"Flower Docker images, by default, run with a non-root user " +"(username/groupname: ``app``, UID/GID: ``49999``). Using root user is not" +" recommended unless it is necessary for specific tasks during the build " +"process. Always make sure to run the container as a non-root user in " +"production to maintain security best practices." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:422 +msgid "**Run a container with root user privileges**" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:424 +msgid "" +"Run the Docker image with the ``-u`` flag and specify ``root`` as the " +"username:" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:430 +msgid "This command will run the Docker container with root user privileges." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:432 +msgid "**Run the build process with root user privileges**" +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:434 +msgid "" +"If you want to switch to the root user during the build process of the " +"Docker image to install missing system dependencies, you can use the " +"``USER root`` directive within your Dockerfile." +msgstr "" + +#: ../../source/how-to-run-flower-using-docker.rst:454 #, fuzzy msgid "Using a different Flower version" msgstr "使用不同的 Flower 或 Python 版本" -#: ../../source/how-to-run-flower-using-docker.rst:395 +#: ../../source/how-to-run-flower-using-docker.rst:456 #, fuzzy msgid "" "If you want to use a different version of Flower, for example Flower " "nightly, you can do so by changing the tag. All available versions are on" -" `Docker Hub `__." +" `Docker Hub `__." msgstr "" "如果您想使用不同版本的 Flower 或 Python,可以通过更改标签来实现。我们提供的所有版本都可以在 `Docker Hub " "`_ 上找到。" -#: ../../source/how-to-run-flower-using-docker.rst:400 +#: ../../source/how-to-run-flower-using-docker.rst:460 #, fuzzy msgid "Pinning a Docker image to a specific version" msgstr "将 Docker 映像固定到特定版本" -#: ../../source/how-to-run-flower-using-docker.rst:402 +#: ../../source/how-to-run-flower-using-docker.rst:462 #, fuzzy msgid "" "It may happen that we update the images behind the tags. Such updates " @@ -5995,24 +5946,24 @@ msgstr "" "我们可能会更新标签后面的图像。此类更新通常包括系统依赖项的安全更新,不会改变 Flower " "的功能。不过,如果您想确保始终使用同一张图片,可以指定图片的哈希值而不是标签。" -#: ../../source/how-to-run-flower-using-docker.rst:407 +#: ../../source/how-to-run-flower-using-docker.rst:467 #, fuzzy msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "下面的命令将返回由 ``server:1.7.0-py3.11-ubuntu22.04`` 标记引用的当前图像哈希值:" -#: ../../source/how-to-run-flower-using-docker.rst:414 +#: ../../source/how-to-run-flower-using-docker.rst:474 #, fuzzy msgid "Next, we can pin the hash when running a new SuperLink container:" msgstr "接下来,我们可以在运行新服务器容器时将哈希值固定下来:" -#: ../../source/how-to-run-flower-using-docker.rst:423 +#: ../../source/how-to-run-flower-using-docker.rst:483 #, fuzzy msgid "Setting environment variables" msgstr "设置编码环境" -#: ../../source/how-to-run-flower-using-docker.rst:425 +#: ../../source/how-to-run-flower-using-docker.rst:485 #, fuzzy msgid "" "To set a variable inside a Docker container, you can use the ``-e " @@ -6910,10 +6861,8 @@ msgid "" " latest features and improvements in Flower Next, starting from version " "1.8." msgstr "" -"欢迎阅读从 Flower 升级到 Flower Next 的迁移指南!" -"无论您是经验丰富的用户还是刚刚开始使用 " -"Flower,本指南都将帮助您顺利过渡现有设置,以利用 Flower Next 从 1.8 " -"版开始的最新功能和改进。" +"欢迎阅读从 Flower 升级到 Flower Next 的迁移指南!无论您是经验丰富的用户还是刚刚开始使用 " +"Flower,本指南都将帮助您顺利过渡现有设置,以利用 Flower Next 从 1.8 版开始的最新功能和改进。" #: ../../source/how-to-upgrade-to-flower-next.rst:9 #, fuzzy @@ -6923,9 +6872,8 @@ msgid "" "guide, we will show how to run Flower Next end-to-end with pure Flower " "Next APIs." msgstr "" -"本指南展示了如何通过使用 Flower Next 中的*可兼容层*,以最小的代码改动重用```1" -".8```前的 Flower 代码。在另一个指南中,我们将介绍如何使用纯 Flower Next API " -"端到端运行 Flower Next。" +"本指南展示了如何通过使用 Flower Next 中的*可兼容层*,以最小的代码改动重用```1.8```前的 Flower " +"代码。在另一个指南中,我们将介绍如何使用纯 Flower Next API 端到端运行 Flower Next。" #: ../../source/how-to-upgrade-to-flower-next.rst:13 #, fuzzy @@ -6991,12 +6939,11 @@ msgid "" "to run your project both in the traditional way and in the Flower Next " "way:" msgstr "" -"在 Flower Next 中,*基础架构层*和*应用层*已经解耦。你不再需要在代码中通过``st" -"art_client()``启动客户端,而是创建一个|clientapp_link|_,然后通过命令行启动它" -"。无需通过``start_server()``在代码中启动服务器,而是创建一个 |serverapp_link|" -"_ 并通过命令行启动它。服务器和客户端的长期运行组件被称为超级链接(SuperLink)" -"和超级节点(SuperNode)。以下是无需手动更新的非破坏性更改," -"可让您以传统方式和 Flower Next 方式运行项目:" +"在 Flower Next " +"中,*基础架构层*和*应用层*已经解耦。你不再需要在代码中通过``start_client()``启动客户端,而是创建一个|clientapp_link|_,然后通过命令行启动它。无需通过``start_server()``在代码中启动服务器,而是创建一个" +" |serverapp_link|_ " +"并通过命令行启动它。服务器和客户端的长期运行组件被称为超级链接(SuperLink)和超级节点(SuperNode)。以下是无需手动更新的非破坏性更改,可让您以传统方式和" +" Flower Next 方式运行项目:" #: ../../source/how-to-upgrade-to-flower-next.rst:109 #, fuzzy @@ -7008,8 +6955,7 @@ msgstr "客户端" msgid "" "Wrap your existing client with |clientapp_link|_ instead of launching it " "via |startclient_link|_. Here's an example:" -msgstr "用 |clientapp_link|_ 封装现有客户端,而不是通过 |startclient_link|_ " -"启动。下面是一个例子:" +msgstr "用 |clientapp_link|_ 封装现有客户端,而不是通过 |startclient_link|_ 启动。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:132 #, fuzzy @@ -7021,8 +6967,7 @@ msgstr "服务器" msgid "" "Wrap your existing strategy with |serverapp_link|_ instead of starting " "the server via |startserver_link|_. Here's an example:" -msgstr "用 |serverapp_link|_ 包住现有策略,而不是通过 |startserver_link|_ " -"启动服务器。下面是一个例子:" +msgstr "用 |serverapp_link|_ 包住现有策略,而不是通过 |startserver_link|_ 启动服务器。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:154 #, fuzzy @@ -7038,8 +6983,8 @@ msgid "" " `server.py` as Python scripts." msgstr "" "在依次运行 |flowernext_clientapp_link|_ (2x) 和 |flowernext_serverapp_link|_ " -"之前,使用 |flowernext_superlink_link|_ 运行 ``SuperLink`` 。无需将 |client." -"py` 和 `server.py` 作为 Python 脚本执行。" +"之前,使用 |flowernext_superlink_link|_ 运行 ``SuperLink`` 。无需将 |client.py` 和 " +"`server.py` 作为 Python 脚本执行。" #: ../../source/how-to-upgrade-to-flower-next.rst:158 #, fuzzy @@ -7051,11 +6996,11 @@ msgstr "下面是一个在不使用 HTTPS 的情况下启动服务器的示例 #: ../../source/how-to-upgrade-to-flower-next.rst:174 #, fuzzy msgid "" -"Here's another example to start with HTTPS. Use the ``--certificates`` " -"command line argument to pass paths to (CA certificate, server " -"certificate, and server private key)." -msgstr "下面是另一个使用 HTTPS 的示例。使用 ``--certificates`` 命令行参数传递路径(" -"CA 证书、服务器证书和服务器私钥)。" +"Here's another example to start with HTTPS. Use the ``--ssl-ca-" +"certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line " +"options to pass paths to (CA certificate, server certificate, and server " +"private key)." +msgstr "下面是另一个使用 HTTPS 的示例。使用 ``--certificates`` 命令行参数传递路径(CA 证书、服务器证书和服务器私钥)。" #: ../../source/how-to-upgrade-to-flower-next.rst:201 #, fuzzy @@ -7069,8 +7014,8 @@ msgid "" "|serverapp_link|_, respectively. There is no need to use |startsim_link|_" " anymore. Here's an example:" msgstr "" -"分别用 |clientapp_link|_ 和 |serverapp_link|_ 封装现有的客户端和策略。" -"无需再使用 |startsim_link|_。下面是一个示例:" +"分别用 |clientapp_link|_ 和 |serverapp_link|_ 封装现有的客户端和策略。无需再使用 " +"|startsim_link|_。下面是一个示例:" #: ../../source/how-to-upgrade-to-flower-next.rst:232 #, fuzzy @@ -7081,8 +7026,8 @@ msgid "" "objects are in a ``sim.py`` module):" msgstr "" "在 CLI 中运行 |flower_simulation_link|_ 并指向代码中的 ``server_app`` " -"/``client_app`` 对象,而不是执行 Python 脚本。下面是一个示例(假定 " -"`server_app`` 和 `client_app`` 对象位于 `sim.py`` 模块中):" +"/``client_app`` 对象,而不是执行 Python 脚本。下面是一个示例(假定 `server_app`` 和 " +"`client_app`` 对象位于 `sim.py`` 模块中):" #: ../../source/how-to-upgrade-to-flower-next.rst:249 #, fuzzy @@ -7091,8 +7036,8 @@ msgid "" "config`` command line argument instead of setting the " "``client_resources`` argument in |startsim_link|_. Here's an example:" msgstr "" -"使用 ``--backend-config`` 命令行参数为每个 |clientapp_link|_ 设置默认资源," -"而不是在 |startsim_link|_ 中设置 ``client_resources`` 参数。下面是一个例子:" +"使用 ``--backend-config`` 命令行参数为每个 |clientapp_link|_ 设置默认资源,而不是在 " +"|startsim_link|_ 中设置 ``client_resources`` 参数。下面是一个例子:" #: ../../source/how-to-upgrade-to-flower-next.rst:275 #, fuzzy @@ -7132,8 +7077,7 @@ msgid "" "As we continuously enhance Flower Next at a rapid pace, we'll be " "periodically updating this guide. Please feel free to share any feedback " "with us!" -msgstr "随着 Flower Next " -"的不断快速改进,我们将定期更新本指南。如有任何反馈,请随时与我们分享!" +msgstr "随着 Flower Next 的不断快速改进,我们将定期更新本指南。如有任何反馈,请随时与我们分享!" #: ../../source/how-to-upgrade-to-flower-next.rst:334 #, fuzzy @@ -7632,11 +7576,11 @@ msgstr "贡献者教程" msgid "Contributor how-to guides" msgstr "投稿指南" -#: ../../source/index.rst:173 +#: ../../source/index.rst:172 msgid "Contributor explanations" msgstr "贡献者解释" -#: ../../source/index.rst:179 +#: ../../source/index.rst:178 msgid "Contributor references" msgstr "贡献者参考资料" @@ -7794,7 +7738,8 @@ msgstr "flower-driver-api" msgid "flwr" msgstr "Flower" -#: ../../source/ref-api/flwr.rst:25 ../../source/ref-api/flwr.server.rst:51 +#: ../../source/ref-api/flwr.client.rst:45 ../../source/ref-api/flwr.rst:25 +#: ../../source/ref-api/flwr.server.rst:49 #, fuzzy msgid "Modules" msgstr "模块" @@ -7823,7 +7768,7 @@ msgid ":py:obj:`flwr.server `\\" msgstr ":py:obj:`flwr.server `\\" #: ../../source/ref-api/flwr.rst:35::1 -#: ../../source/ref-api/flwr.server.rst:40::1 flwr.server:1 +#: ../../source/ref-api/flwr.server.rst:38::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." msgstr "Flower 服务器。" @@ -7842,6 +7787,7 @@ msgstr "运行模拟" msgid "client" msgstr "客户端" +#: ../../source/ref-api/flwr.client.mod.rst:13 #: ../../source/ref-api/flwr.client.rst:13 #: ../../source/ref-api/flwr.common.rst:13 #: ../../source/ref-api/flwr.server.rst:13 @@ -7900,9 +7846,10 @@ msgstr "" msgid "Start a Flower NumPyClient which connects to a gRPC server." msgstr "启动 Flower NumPyClient,连接到 gRPC 服务器。" +#: ../../source/ref-api/flwr.client.mod.rst:30 #: ../../source/ref-api/flwr.client.rst:27 #: ../../source/ref-api/flwr.common.rst:32 -#: ../../source/ref-api/flwr.server.rst:28 +#: ../../source/ref-api/flwr.server.rst:26 #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 #, fuzzy @@ -7944,6 +7891,16 @@ msgstr ":py:obj:`NumPyClient `\\ \\(\\)" msgid "Abstract base class for Flower clients using NumPy." msgstr "使用 NumPy 的 Flower 客户端的抽象基类。" +#: ../../source/ref-api/flwr.client.rst:52::1 +#, fuzzy +msgid ":py:obj:`flwr.client.mod `\\" +msgstr ":py:obj:`flwr.client `\\" + +#: ../../source/ref-api/flwr.client.rst:52::1 flwr.client.mod:1 of +#, fuzzy +msgid "Flower Built-in Mods." +msgstr "使用内置调制器" + #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 @@ -7955,6 +7912,7 @@ msgstr "Bases: :py:class:`~abc.ABC`" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 #: ../../source/ref-api/flwr.client.NumPyClient.rst:15 +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:15 #: ../../source/ref-api/flwr.common.Array.rst:15 #: ../../source/ref-api/flwr.common.ClientMessage.rst:15 #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:15 @@ -8142,6 +8100,7 @@ msgstr ":py:obj:`context `\\" #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters #: flwr.client.client.Client.get_properties +#: flwr.client.mod.localdp_mod.LocalDpMod #: flwr.client.numpy_client.NumPyClient.evaluate #: flwr.client.numpy_client.NumPyClient.fit #: flwr.client.numpy_client.NumPyClient.get_parameters @@ -8293,10 +8252,11 @@ msgstr "当前客户端属性。" msgid "ClientApp" msgstr "客户端" -#: flwr.client.client_app.ClientApp:1 flwr.common.constant.MessageType:1 -#: flwr.common.constant.MessageTypeLegacy:1 flwr.common.context.Context:1 -#: flwr.common.message.Error:1 flwr.common.message.Message:1 -#: flwr.common.message.Metadata:1 flwr.common.record.parametersrecord.Array:1 +#: flwr.client.client_app.ClientApp:1 flwr.client.mod.localdp_mod.LocalDpMod:1 +#: flwr.common.constant.MessageType:1 flwr.common.constant.MessageTypeLegacy:1 +#: flwr.common.context.Context:1 flwr.common.message.Error:1 +#: flwr.common.message.Message:1 flwr.common.message.Metadata:1 +#: flwr.common.record.parametersrecord.Array:1 #: flwr.common.record.recordset.RecordSet:1 flwr.common.typing.ClientMessage:1 #: flwr.common.typing.DisconnectRes:1 flwr.common.typing.EvaluateIns:1 #: flwr.common.typing.EvaluateRes:1 flwr.common.typing.FitIns:1 @@ -8318,7 +8278,8 @@ msgstr "Bases: :py:class:`object`" #: flwr.client.client_app.ClientApp:4 #: flwr.client.client_app.ClientApp.evaluate:4 #: flwr.client.client_app.ClientApp.query:4 -#: flwr.client.client_app.ClientApp.train:4 flwr.server.app.start_server:41 +#: flwr.client.client_app.ClientApp.train:4 +#: flwr.client.mod.localdp_mod.LocalDpMod:22 flwr.server.app.start_server:41 #: flwr.server.server_app.ServerApp:4 flwr.server.server_app.ServerApp.main:4 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:29 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:22 @@ -8574,6 +8535,260 @@ msgstr "" "**properties** -- 将任意字符串键映射到 bool、bytes、float、int 或 str " "类型值的字典。它可用于将任意属性值传回服务器。" +#: ../../source/ref-api/flwr.client.mod.rst:2 +#, fuzzy +msgid "mod" +msgstr "模块" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`adaptiveclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:1 of +#, fuzzy +msgid "Client-side adaptive clipping modifier." +msgstr "客户端逻辑" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +msgid "" +":py:obj:`fixedclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:1 of +#, fuzzy +msgid "Client-side fixed clipping modifier." +msgstr "客户端逻辑" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" +msgstr ":py:obj:`Client `\\ \\(\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.utils.make_ffn:1 of +msgid "." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid "" +":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " +"call\\_next\\)" +msgstr ":py:obj:`set_context `\\ \\(context\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secagg_mod.secagg_mod:1 of +msgid "Handle incoming message and return results, following the SecAgg protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid "" +":py:obj:`secaggplus_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" +msgstr "" +":py:obj:`SecAggPlusWorkflow `\\ " +"\\(num\\_shares\\, ...\\[\\, ...\\]\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.secure_aggregation.secaggplus_mod.secaggplus_mod:1 of +msgid "" +"Handle incoming message and return results, following the SecAgg+ " +"protocol." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid "" +":py:obj:`message_size_mod `\\ \\(msg\\," +" ctxt\\, call\\_next\\)" +msgstr "" +":py:obj:`Message `\\ \\(metadata\\[\\, content\\, " +"error\\]\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.message_size_mod:1 of +#, fuzzy +msgid "Message size mod." +msgstr "信息类型。" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#, fuzzy +msgid "" +":py:obj:`parameters_size_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" +msgstr "" +":py:obj:`ParametersRecord `\\ " +"\\(\\[array\\_dict\\, keep\\_input\\]\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:28::1 +#: flwr.client.mod.comms_mods.parameters_size_mod:1 of +#, fuzzy +msgid "Parameters size mod." +msgstr "参数" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +#, fuzzy +msgid "" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\," +" sensitivity\\, ...\\)" +msgstr "" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " +"mods\\]\\)" + +#: ../../source/ref-api/flwr.client.mod.rst:35::1 +#: flwr.client.mod.localdp_mod.LocalDpMod:1 of +#, fuzzy +msgid "Modifier for local differential privacy." +msgstr "差分隐私" + +#: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:2 +#, fuzzy +msgid "LocalDpMod" +msgstr "本地 DP 模式" + +#: flwr.client.mod.localdp_mod.LocalDpMod:3 of +msgid "" +"This mod clips the client model updates and adds noise to the params " +"before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:12 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:10 +#: flwr.client.mod.localdp_mod.LocalDpMod:6 of +msgid "It operates on messages of type `MessageType.TRAIN`." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:8 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 +#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 +#: of +#, fuzzy +msgid "The value of the clipping norm." +msgstr "削波法线的值。" + +#: flwr.client.mod.localdp_mod.LocalDpMod:10 of +msgid "The sensitivity of the client model." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:12 of +msgid "" +"The privacy budget. Smaller value of epsilon indicates a higher level of " +"privacy protection." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:15 of +msgid "" +"The failure probability. The probability that the privacy mechanism fails" +" to provide the desired level of privacy. A smaller value of delta " +"indicates a stricter privacy guarantee." +msgstr "" + +#: flwr.client.mod.localdp_mod.LocalDpMod:23 of +msgid "Create an instance of the local DP mod and add it to the client-side mods:" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.adaptiveclipping_mod.rst:2 +msgid "adaptiveclipping\\_mod" +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:3 of +#, fuzzy +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy " +"wrapper." +msgstr "用 \"DifferentialPrivacyClientSideAdaptiveClipping \"包装器对策略进行包装:" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:6 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:6 of +#, fuzzy +msgid "The wrapper sends the clipping_norm value to the client." +msgstr "向客户发送近端因子mu" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:8 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:8 of +msgid "This mod clips the client model updates before sending them to the server." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:10 of +msgid "" +"It also sends KEY_NORM_BIT to the server for computing the new clipping " +"value." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:15 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:13 +#: flwr.server.driver.driver.Driver.send_and_receive:18 +#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 +#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 +#: of +#, fuzzy +msgid "Notes" +msgstr "无" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:16 +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:14 of +msgid "Consider the order of mods when using multiple." +msgstr "" + +#: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:18 of +msgid "Typically, adaptiveclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.fixedclipping_mod.rst:2 +#, fuzzy +msgid "fixedclipping\\_mod" +msgstr "剪贴" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:3 of +#, fuzzy +msgid "" +"This mod needs to be used with the " +"DifferentialPrivacyClientSideFixedClipping server-side strategy wrapper." +msgstr "用 \"DifferentialPrivacyClientSideFixedClipping \"包装器包装策略:" + +#: flwr.client.mod.centraldp_mods.fixedclipping_mod:16 of +msgid "Typically, fixedclipping_mod should be the last to operate on params." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.make_ffn.rst:2 +msgid "make\\_ffn" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.message_size_mod.rst:2 +msgid "message\\_size\\_mod" +msgstr "" + +#: flwr.client.mod.comms_mods.message_size_mod:3 of +msgid "This mod logs the size in bytes of the message being transmited." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.parameters_size_mod.rst:2 +#, fuzzy +msgid "parameters\\_size\\_mod" +msgstr "参数" + +#: flwr.client.mod.comms_mods.parameters_size_mod:3 of +msgid "" +"This mod logs the number of parameters transmitted in the message as well" +" as their size in bytes." +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secagg_mod.rst:2 +msgid "secagg\\_mod" +msgstr "" + +#: ../../source/ref-api/flwr.client.mod.secaggplus_mod.rst:2 +#, fuzzy +msgid "secaggplus\\_mod" +msgstr "工作流程" + #: ../../source/ref-api/flwr.client.run_client_app.rst:2 #, fuzzy msgid "run\\_client\\_app" @@ -10249,6 +10464,24 @@ msgstr "" ":py:obj:`RUN_SUPERLINK_LEAVE " "`\\" +#: flwr.common.EventType.capitalize:1::1 of +#, fuzzy +msgid "" +":py:obj:`RUN_SUPEREXEC_ENTER " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_ENTER " +"`\\" + +#: flwr.common.EventType.capitalize:1::1 of +#, fuzzy +msgid "" +":py:obj:`RUN_SUPEREXEC_LEAVE " +"`\\" +msgstr "" +":py:obj:`RUN_SUPERLINK_LEAVE " +"`\\" + #: flwr.common.EventType.capitalize:3 of #, fuzzy msgid "" @@ -10268,8 +10501,7 @@ msgid "" "Return the number of non-overlapping occurrences of substring sub in " "string S[start:end]. Optional arguments start and end are interpreted as" " in slice notation." -msgstr "返回子串 sub 在字符串 S[start:end] 中非重叠出现的次数。 可选参数 start 和 " -"end 按切分符号解释。" +msgstr "返回子串 sub 在字符串 S[start:end] 中非重叠出现的次数。 可选参数 start 和 end 按切分符号解释。" #: flwr.common.EventType.encode:3 of #, fuzzy @@ -10295,10 +10527,9 @@ msgid "" "as any other name registered with codecs.register_error that can handle " "UnicodeEncodeErrors." msgstr "" -"编码错误的错误处理方案。默认值为 \"strict\",即编码错误会引发 " -"UnicodeEncodeError。 其他可能的值包括 \"ignore\"、\"replace \"和 " -"\"xmlcharrefreplace\",以及通过 codecs.register_error 注册的、可处理 " -"UnicodeEncodeErrror 的其他名称。" +"编码错误的错误处理方案。默认值为 \"strict\",即编码错误会引发 UnicodeEncodeError。 其他可能的值包括 " +"\"ignore\"、\"replace \"和 \"xmlcharrefreplace\",以及通过 codecs.register_error" +" 注册的、可处理 UnicodeEncodeErrror 的其他名称。" #: flwr.common.EventType.endswith:1 of #, fuzzy @@ -10308,9 +10539,8 @@ msgid "" "stop comparing S at that position. suffix can also be a tuple of strings " "to try." msgstr "" -"如果 S 以指定后缀结束,则返回 True,否则返回 False。如果起始位置可选," -"则从该位置开始测试 S。如果使用可选的 end,则在该位置停止比较 " -"S。后缀也可以是要尝试的字符串元组。" +"如果 S 以指定后缀结束,则返回 True,否则返回 False。如果起始位置可选,则从该位置开始测试 S。如果使用可选的 " +"end,则在该位置停止比较 S。后缀也可以是要尝试的字符串元组。" #: flwr.common.EventType.expandtabs:3 of #, fuzzy @@ -10323,9 +10553,7 @@ msgid "" "Return the lowest index in S where substring sub is found, such that sub " "is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." -msgstr "" -"返回在 S 中找到子串 sub 的最低索引,即 sub 包含在 S[start:end] 中。 可选参数 " -"start 和 end 按切分符号解释。" +msgstr "返回在 S 中找到子串 sub 的最低索引,即 sub 包含在 S[start:end] 中。 可选参数 start 和 end 按切分符号解释。" #: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of #, fuzzy @@ -10337,8 +10565,7 @@ msgstr "失败时返回-1。" msgid "" "Return a formatted version of S, using substitutions from args and " "kwargs. The substitutions are identified by braces ('{' and '}')." -msgstr "使用来自 args 和 kwargs 的替换,返回 S " -"的格式化版本。替换用大括号('{'和'}')标识。" +msgstr "使用来自 args 和 kwargs 的替换,返回 S 的格式化版本。替换用大括号('{'和'}')标识。" #: flwr.common.EventType.format_map:1 of #, fuzzy @@ -10357,16 +10584,14 @@ msgstr "如果未找到子串,则引发 ValueError。" msgid "" "A string is alpha-numeric if all characters in the string are alpha-" "numeric and there is at least one character in the string." -msgstr "如果字符串中的所有字符都是字母数字,且字符串中至少有一个字符,则该字符串为字" -"母数字字符串。" +msgstr "如果字符串中的所有字符都是字母数字,且字符串中至少有一个字符,则该字符串为字母数字字符串。" #: flwr.common.EventType.isalpha:3 of #, fuzzy msgid "" "A string is alphabetic if all characters in the string are alphabetic and" " there is at least one character in the string." -msgstr "如果字符串中的所有字符都是字母,并且字符串中至少有一个字符,那么该字符串就是" -"字母字符串。" +msgstr "如果字符串中的所有字符都是字母,并且字符串中至少有一个字符,那么该字符串就是字母字符串。" #: flwr.common.EventType.isascii:3 of #, fuzzy @@ -10380,48 +10605,42 @@ msgstr "ASCII 字符的码位范围为 U+0000-U+007F。空字符串也是 ASCII msgid "" "A string is a decimal string if all characters in the string are decimal " "and there is at least one character in the string." -msgstr "如果字符串中的所有字符都是十进制,并且字符串中至少有一个字符是十进制,那么该" -"字符串就是十进制字符串。" +msgstr "如果字符串中的所有字符都是十进制,并且字符串中至少有一个字符是十进制,那么该字符串就是十进制字符串。" #: flwr.common.EventType.isdigit:3 of #, fuzzy msgid "" "A string is a digit string if all characters in the string are digits and" " there is at least one character in the string." -msgstr "如果字符串中的所有字符都是数字,并且字符串中至少有一个字符,那么该字符串就是" -"数字字符串。" +msgstr "如果字符串中的所有字符都是数字,并且字符串中至少有一个字符,那么该字符串就是数字字符串。" #: flwr.common.EventType.isidentifier:3 of #, fuzzy msgid "" "Call keyword.iskeyword(s) to test whether string s is a reserved " "identifier, such as \"def\" or \"class\"." -msgstr "调用 keyword.iskeyword(s) 测试字符串 s 是否为保留标识符,如 \"def \"或 " -"\"class\"。" +msgstr "调用 keyword.iskeyword(s) 测试字符串 s 是否为保留标识符,如 \"def \"或 \"class\"。" #: flwr.common.EventType.islower:3 of #, fuzzy msgid "" "A string is lowercase if all cased characters in the string are lowercase" " and there is at least one cased character in the string." -msgstr "如果字符串中的所有大小写字符都是小写,且字符串中至少有一个大小写字符,则该字" -"符串为小写字符串。" +msgstr "如果字符串中的所有大小写字符都是小写,且字符串中至少有一个大小写字符,则该字符串为小写字符串。" #: flwr.common.EventType.isnumeric:3 of #, fuzzy msgid "" "A string is numeric if all characters in the string are numeric and there" " is at least one character in the string." -msgstr "如果字符串中的所有字符都是数字,且字符串中至少有一个字符,则该字符串为数字字" -"符串。" +msgstr "如果字符串中的所有字符都是数字,且字符串中至少有一个字符,则该字符串为数字字符串。" #: flwr.common.EventType.isprintable:3 of #, fuzzy msgid "" "A string is printable if all of its characters are considered printable " "in repr() or if it is empty." -msgstr "如果字符串的所有字符在 repr() " -"中都被认为是可打印的,或者字符串为空,那么该字符串就是可打印的。" +msgstr "如果字符串的所有字符在 repr() 中都被认为是可打印的,或者字符串为空,那么该字符串就是可打印的。" #: flwr.common.EventType.isspace:3 of #, fuzzy @@ -10435,16 +10654,14 @@ msgstr "如果字符串中的所有字符都是空格,且字符串中至少有 msgid "" "In a title-cased string, upper- and title-case characters may only follow" " uncased characters and lowercase characters only cased ones." -msgstr "在标题大小写字符串中,大写和标题大小写字符只能跟在无大小写字符之后,小写字符" -"只能跟在有大小写字符之后。" +msgstr "在标题大小写字符串中,大写和标题大小写字符只能跟在无大小写字符之后,小写字符只能跟在有大小写字符之后。" #: flwr.common.EventType.isupper:3 of #, fuzzy msgid "" "A string is uppercase if all cased characters in the string are uppercase" " and there is at least one cased character in the string." -msgstr "如果字符串中所有带大小写的字符都是大写,并且字符串中至少有一个带大小写的字符" -",则该字符串为大写字符串。" +msgstr "如果字符串中所有带大小写的字符都是大写,并且字符串中至少有一个带大小写的字符,则该字符串为大写字符串。" #: flwr.common.EventType.join:3 of #, fuzzy @@ -10475,10 +10692,8 @@ msgid "" "same position in y. If there is a third argument, it must be a string, " "whose characters will be mapped to None in the result." msgstr "" -"如果只有一个参数,则必须是一个将 Unicode 序号(整数)或字符映射到 Unicode " -"序号、字符串或 None 的字典。字符键将被转换为序号。如果有两个参数,它们必须是" -"长度相等的字符串,在生成的字典中,x 中的每个字符将被映射到 y " -"中相同位置的字符。" +"如果只有一个参数,则必须是一个将 Unicode 序号(整数)或字符映射到 Unicode 序号、字符串或 None " +"的字典。字符键将被转换为序号。如果有两个参数,它们必须是长度相等的字符串,在生成的字典中,x 中的每个字符将被映射到 y 中相同位置的字符。" #: flwr.common.EventType.partition:3 of #, fuzzy @@ -10486,8 +10701,7 @@ msgid "" "This will search for the separator in the string. If the separator is " "found, returns a 3-tuple containing the part before the separator, the " "separator itself, and the part after it." -msgstr "它会在字符串中搜索分隔符。 如果找到分隔符,则返回一个包含分隔符前部分、" -"分隔符本身和分隔符后部分的 3 元组。" +msgstr "它会在字符串中搜索分隔符。 如果找到分隔符,则返回一个包含分隔符前部分、分隔符本身和分隔符后部分的 3 元组。" #: flwr.common.EventType.partition:7 of #, fuzzy @@ -10501,8 +10715,7 @@ msgstr "如果找不到分隔符,则返回一个包含原始字符串和两个 msgid "" "If the string starts with the prefix string, return string[len(prefix):]." " Otherwise, return a copy of the original string." -msgstr "如果字符串以前缀字符串开始,则返回 " -"string[len(prefix):]。否则,返回原始字符串的副本。" +msgstr "如果字符串以前缀字符串开始,则返回 string[len(prefix):]。否则,返回原始字符串的副本。" #: flwr.common.EventType.removesuffix:3 of #, fuzzy @@ -10510,8 +10723,7 @@ msgid "" "If the string ends with the suffix string and that suffix is not empty, " "return string[:-len(suffix)]. Otherwise, return a copy of the original " "string." -msgstr "如果字符串以后缀字符串结尾,且后缀不为空,则返回 " -"string[:-len(suffix)]。否则,返回原始字符串的副本。" +msgstr "如果字符串以后缀字符串结尾,且后缀不为空,则返回 string[:-len(suffix)]。否则,返回原始字符串的副本。" #: flwr.common.EventType.replace:5 of #, fuzzy @@ -10538,9 +10750,7 @@ msgid "" "Return the highest index in S where substring sub is found, such that sub" " is contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." -msgstr "" -"返回在 S 中找到子串 sub 且 sub 包含在 S[start:end] 中的最高索引。 可选参数 " -"start 和 end 按切分符号解释。" +msgstr "返回在 S 中找到子串 sub 且 sub 包含在 S[start:end] 中的最高索引。 可选参数 start 和 end 按切分符号解释。" #: flwr.common.EventType.rpartition:3 of #, fuzzy @@ -10548,8 +10758,7 @@ msgid "" "This will search for the separator in the string, starting at the end. If" " the separator is found, returns a 3-tuple containing the part before the" " separator, the separator itself, and the part after it." -msgstr "它会从字符串的末尾开始搜索分隔符。如果找到分隔符,则返回一个包含分隔符前部分" -"、分隔符本身和分隔符后部分的 3 元组。" +msgstr "它会从字符串的末尾开始搜索分隔符。如果找到分隔符,则返回一个包含分隔符前部分、分隔符本身和分隔符后部分的 3 元组。" #: flwr.common.EventType.rpartition:7 of #, fuzzy @@ -10574,9 +10783,7 @@ msgid "" "When set to None (the default value), will split on any whitespace " "character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" " empty strings from the result." -msgstr "" -"当设置为 \"无\"(默认值)时,将对任何空白字符(包括 \\n" -" \\r \\t \\f 和空格)进行分割,并从结果中剔除空字符串。" +msgstr "当设置为 \"无\"(默认值)时,将对任何空白字符(包括 \\n \\r \\t \\f 和空格)进行分割,并从结果中剔除空字符串。" #: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of #, fuzzy @@ -10601,8 +10808,7 @@ msgid "" "Note, str.split() is mainly useful for data that has been intentionally " "delimited. With natural text that includes punctuation, consider using " "the regular expression module." -msgstr "注意,str.split() 主要适用于有意分隔的数据。 " -"对于包含标点符号的自然文本,可以考虑使用正则表达式模块。" +msgstr "注意,str.split() 主要适用于有意分隔的数据。 对于包含标点符号的自然文本,可以考虑使用正则表达式模块。" #: flwr.common.EventType.splitlines:3 of #, fuzzy @@ -10619,8 +10825,8 @@ msgid "" "stop comparing S at that position. prefix can also be a tuple of strings " "to try." msgstr "" -"如果 S 以指定的前缀开始,则返回 True,否则返回 False。如果选择 start," -"则从该位置开始测试 S。如果使用可选的 end,则在该位置停止比较 S。" +"如果 S 以指定的前缀开始,则返回 True,否则返回 False。如果选择 start,则从该位置开始测试 S。如果使用可选的 " +"end,则在该位置停止比较 S。" #: flwr.common.EventType.title:3 of #, fuzzy @@ -10648,8 +10854,8 @@ msgid "" "dictionary or list. If this operation raises LookupError, the character " "is left untouched. Characters mapped to None are deleted." msgstr "" -"表必须通过 __getitem__ 实现查找/索引,例如字典或列表。 如果该操作引发 " -"LookupError,该字符将保持不变。 映射为 None 的字符将被删除。" +"表必须通过 __getitem__ 实现查找/索引,例如字典或列表。 如果该操作引发 LookupError,该字符将保持不变。 映射为 None" +" 的字符将被删除。" #: flwr.common.EventType.zfill:3 of #, fuzzy @@ -10863,9 +11069,8 @@ msgid "" "follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " "msg.meta.created_at)" msgstr "" -"该信息的有效时间(秒)。如果未设置,则将根据收到的信息过期前的剩余时间来设置" -"。其计算公式为:ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta." -"created_at)" +"该信息的有效时间(秒)。如果未设置,则将根据收到的信息过期前的剩余时间来设置。其计算公式为:ttl = msg.meta.ttl - " +"(reply.meta.created_at - msg.meta.created_at)" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of @@ -10874,8 +11079,7 @@ msgid "" "Time-to-live for this message in seconds. If unset, it will be set based " "on the remaining time for the received message before it expires. This " "follows the equation:" -msgstr "该信息的有效时间(秒)。如果未设置,则将根据接收到的信息过期前的剩余时间来设" -"置。其计算公式如下" +msgstr "该信息的有效时间(秒)。如果未设置,则将根据接收到的信息过期前的剩余时间来设置。其计算公式如下" #: flwr.common.message.Message.create_error_reply:9 #: flwr.common.message.Message.create_reply:13 of @@ -11379,51 +11583,29 @@ msgstr "parameters\\_to\\_ndarrays" msgid "server" msgstr "服务器" -#: ../../source/ref-api/flwr.server.rst:26::1 -#, fuzzy -msgid ":py:obj:`run_driver_api `\\ \\(\\)" -msgstr ":py:obj:`run_driver_api `\\ \\(\\)" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_driver_api:1 of -#, fuzzy -msgid "Run Flower server (Driver API)." -msgstr "flower-driver-api" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#, fuzzy -msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -msgstr ":py:obj:`run_fleet_api `\\ \\(\\)" - -#: ../../source/ref-api/flwr.server.rst:26::1 -#: flwr.server.app.run_fleet_api:1 of -#, fuzzy -msgid "Run Flower server (Fleet API)." -msgstr "Flower 服务器。" - -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #, fuzzy msgid ":py:obj:`run_server_app `\\ \\(\\)" msgstr ":py:obj:`run_server_app `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.run_serverapp.run_server_app:1 of #, fuzzy msgid "Run Flower server app." msgstr "Flower 服务器。" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #, fuzzy msgid ":py:obj:`run_superlink `\\ \\(\\)" msgstr ":py:obj:`run_superlink `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.run_superlink:1 of #, fuzzy msgid "Run Flower SuperLink (Driver API and Fleet API)." msgstr "运行 Flower 服务器(Driver API 和 Fleet API)。" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #, fuzzy msgid "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " @@ -11432,45 +11614,45 @@ msgstr "" ":py:obj:`start_server `\\ \\(\\*\\[\\, " "server\\_address\\, server\\, ...\\]\\)" -#: ../../source/ref-api/flwr.server.rst:26::1 +#: ../../source/ref-api/flwr.server.rst:24::1 #: flwr.server.app.start_server:1 of msgid "Start a Flower server using the gRPC transport layer." msgstr "使用 gRPC 传输层启动 Flower 服务器。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid ":py:obj:`ClientManager `\\ \\(\\)" msgstr ":py:obj:`ClientManager `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.ClientManager:1 of #, fuzzy msgid "Abstract base class for managing Flower clients." msgstr "Flower 客户端的抽象基类。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid ":py:obj:`Driver `\\ \\(\\)" msgstr ":py:obj:`run_driver_api `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.driver.driver.Driver:1 of #, fuzzy msgid "Abstract base Driver class for the Driver API." msgstr "Flower 客户端的抽象基类。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid ":py:obj:`History `\\ \\(\\)" msgstr ":py:obj:`History `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.history.History:1 of #, fuzzy msgid "History class for training and/or evaluation metrics collection." msgstr "**hist** -- 包含训练和评估指标的对象。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " @@ -11479,13 +11661,13 @@ msgstr "" ":py:obj:`LegacyContext `\\ \\(state\\[\\, " "config\\, strategy\\, ...\\]\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.compat.legacy_context.LegacyContext:1 of #, fuzzy msgid "Legacy Context." msgstr "传承背景。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " @@ -11494,20 +11676,20 @@ msgstr "" ":py:obj:`Server `\\ \\(\\*\\, client\\_manager\\[\\, " "strategy\\]\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`ServerApp `\\ \\(\\[server\\, config\\, " "strategy\\, ...\\]\\)" msgstr "server.strategy.Strategy" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_app.ServerApp:1 of #, fuzzy msgid "Flower ServerApp." msgstr "Flower 服务器。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid "" ":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," @@ -11517,39 +11699,39 @@ msgstr "" "config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " "...)``" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.server_config.ServerConfig:1 of #, fuzzy msgid "Flower server config." msgstr "Flower 服务器。" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #, fuzzy msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr ":py:obj:`SimpleClientManager `\\ \\(\\)" -#: ../../source/ref-api/flwr.server.rst:40::1 +#: ../../source/ref-api/flwr.server.rst:38::1 #: flwr.server.client_manager.SimpleClientManager:1 of #, fuzzy msgid "Provides a pool of available clients." msgstr "使用部分可用客户进行评估。" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #, fuzzy msgid ":py:obj:`flwr.server.strategy `\\" msgstr "server.strategy.Strategy" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.strategy:1 of msgid "Contains the strategy abstraction and different implementations." msgstr "包含策略抽象和不同的实现方法。" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #, fuzzy msgid ":py:obj:`flwr.server.workflow `\\" msgstr "server.strategy.Strategy" -#: ../../source/ref-api/flwr.server.rst:59::1 +#: ../../source/ref-api/flwr.server.rst:57::1 #: flwr.server.workflow:1 of #, fuzzy msgid "Workflows." @@ -11852,14 +12034,6 @@ msgstr "超时时间(秒)。如果指定,该方法将在此期限内等待 msgid "**replies** -- An iterable of reply messages received from the SuperLink." msgstr "**replies** -- 从超级链接收到的回复信息的迭代。" -#: flwr.server.driver.driver.Driver.send_and_receive:18 -#: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:53 -#: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 -#: of -#, fuzzy -msgid "Notes" -msgstr "无" - #: flwr.server.driver.driver.Driver.send_and_receive:19 of #, fuzzy msgid "" @@ -13548,13 +13722,6 @@ msgid "" "value of 1.0 or higher is recommended for strong privacy." msgstr "模型更新高斯机制的噪声乘数。建议使用 1.0 或更高的值,以获得较强的隐私性。" -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 -#: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 -#: of -#, fuzzy -msgid "The value of the clipping norm." -msgstr "削波法线的值。" - #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 #: of #, fuzzy @@ -13956,7 +14123,7 @@ msgstr "" "\\(num\\_available\\_clients\\)" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 -#: ../../source/ref-changelog.md:905 +#: ../../source/ref-changelog.md:997 msgid "FedAdagrad" msgstr "FedAdagrad" @@ -16107,8 +16274,8 @@ msgid "" "Bases: " ":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" -"基础: :py:class:`~flwr.server.workflow.secure_aggregation." -"secaggplus_workflow.SecAggPlusWorkflow`." +"基础: " +":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`." #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of #, fuzzy @@ -16125,13 +16292,10 @@ msgid "" "('parameters') from the client's `FitRes`. The server then aggregates " "these contributions to compute the weighted average of model parameters." msgstr "" -"SecAgg 协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向量" -"。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持私" -"密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保护" -"隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w, w * params]\"" -",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " -"\"FitRes \"中的模型参数(\"parameters\"" -")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" +"SecAgg " +"协议可确保对多方拥有的整数向量进行安全求和,而不会访问任何单个整数向量。该工作流程允许服务器计算所有客户端模型参数的加权平均值,确保个人贡献保持私密。这可以通过客户端同时发送加权因子和本地更新参数的加权版本来实现,为了保护隐私,两者都会被屏蔽。具体来说,每个客户端都会上传带掩码的\"[w," +" w * params]\",其中加权因子 \"w \"是示例数(\"num_examples\"),\"params \"代表客户端 " +"\"FitRes \"中的模型参数(\"parameters\")。然后,服务器会汇总这些贡献,计算模型参数的加权平均值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of #, fuzzy @@ -16139,9 +16303,7 @@ msgid "" "The protocol involves four main stages: - 'setup': Send SecAgg " "configuration to clients and collect their public keys. - 'share keys': " "Broadcast public keys among clients and collect encrypted secret" -msgstr "" -"协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg 配置并收集它们的公钥。-" -" 共享密钥\": 在客户端之间广播公钥并收集加密密钥。" +msgstr "协议包括四个主要阶段: - 设置\": 向客户端发送 SecAgg 配置并收集它们的公钥。- 共享密钥\": 在客户端之间广播公钥并收集加密密钥。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of #, fuzzy @@ -16166,8 +16328,8 @@ msgid "" "setting the security threshold relative to the number of selected " "clients." msgstr "" -"当 `reconstruction_threshold` 为浮点数时,它被解释为重建私钥所需的所有选定客" -"户端数量的比例。此功能可根据所选客户端的数量灵活设置安全阈值。" +"当 `reconstruction_threshold` " +"为浮点数时,它被解释为重建私钥所需的所有选定客户端数量的比例。此功能可根据所选客户端的数量灵活设置安全阈值。" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of #, fuzzy @@ -16188,8 +16350,9 @@ msgid "" "`\\ " "\\(driver\\, ...\\)" msgstr "" -":py:obj:`collect_masked_vectors_stage `\\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage " +"`\\(driver\\," +" ...\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of @@ -16198,8 +16361,9 @@ msgid "" ":py:obj:`setup_stage `\\" " \\(driver\\, context\\, state\\)" msgstr "" -":py:obj:`setup_stage `\\(" -"driver\\, context\\, state\\)" +":py:obj:`setup_stage " +"`\\(driver\\, context\\," +" state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of @@ -16209,8 +16373,9 @@ msgid "" "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" -"py:obj:`share_keys_stage `\\(driver\\, context\\, state\\)" +"py:obj:`share_keys_stage " +"`\\(driver\\, " +"context\\, state\\)" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of @@ -16220,8 +16385,9 @@ msgid "" "`\\ \\(driver\\, " "context\\, state\\)" msgstr "" -":py:obj:`unmask_stage `\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`unmask_stage " +"`\\ \\(driver\\, " +"context\\, state\\)" #: ../../source/ref-api/flwr.simulation.rst:2 #, fuzzy @@ -16234,8 +16400,8 @@ msgid "" ":py:obj:`start_simulation `\\ \\(\\*\\," " client\\_fn\\[\\, ...\\]\\)" msgstr "" -":py:obj:`start_simulation `\\ \\(\\*\\, " -"client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\," +" client\\_fn\\[\\, ...\\]\\)" #: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.app.start_simulation:1 of @@ -16248,8 +16414,8 @@ msgid "" ":py:obj:`run_simulation `\\ " "\\(server\\_app\\, client\\_app\\, ...\\)" msgstr "" -":py:obj:`run_simulation `\\ \\(server\\_app\\" -", client\\_app\\, ...\\)" +":py:obj:`run_simulation `\\ " +"\\(server\\_app\\, client\\_app\\, ...\\)" #: ../../source/ref-api/flwr.simulation.rst:18::1 #: flwr.simulation.run_simulation.run_simulation:1 of @@ -16267,8 +16433,7 @@ msgstr "运行模拟" msgid "" "The `ServerApp` to be executed. It will send messages to different " "`ClientApp` instances running on different (virtual) SuperNodes." -msgstr "要执行的 `ServerApp`。它将向运行在不同(虚拟)超级节点上的不同 " -"`ClientApp`实例发送消息。" +msgstr "要执行的 `ServerApp`。它将向运行在不同(虚拟)超级节点上的不同 `ClientApp`实例发送消息。" #: flwr.simulation.run_simulation.run_simulation:6 of #, fuzzy @@ -16283,8 +16448,7 @@ msgid "" "Number of nodes that run a ClientApp. They can be sampled by a Driver in " "the ServerApp and receive a Message describing what the ClientApp should " "perform." -msgstr "运行 ClientApp 的节点数。它们可被 ServerApp 中的驱动程序采样,并接收描述 " -"ClientApp 应执行的操作的信息。" +msgstr "运行 ClientApp 的节点数。它们可被 ServerApp 中的驱动程序采样,并接收描述 ClientApp 应执行的操作的信息。" #: flwr.simulation.run_simulation.run_simulation:13 of #, fuzzy @@ -16298,8 +16462,8 @@ msgid "" "configure a backend. Values supported in are those included by " "`flwr.common.typing.ConfigsRecordValues`." msgstr "" -"字典,例如 {\"\": , \"\": } 来配置后端。 " -"中支持的值是 `flwr.common.typing.ConfigsRecordValues`中包含的值。" +"字典,例如 {\"\": , \"\": } 来配置后端。 中支持的值是 " +"`flwr.common.typing.ConfigsRecordValues`中包含的值。" #: flwr.simulation.run_simulation.run_simulation:19 of #, fuzzy @@ -16312,20 +16476,17 @@ msgid "" "`tf.config.experimental.set_memory_growth()` works in the TensorFlow " "documentation: https://www.tensorflow.org/api/stable." msgstr "" -"布尔值,用于指示是否在主线程上启用 GPU 增长。如果您在 \"ServerApp \"上使用 " -"TensorFlow 模型,同时让 \"ClientApp \"在同一 GPU " -"上运行,则最好启用此选项。如果不启用此功能,您可能会遇到内存不足的错误,因为 " -"TensorFlow 默认会分配所有 GPU 内存。有关 `tf.config.experimental." -"set_memory_growth()` 如何工作的更多信息,请参阅 TensorFlow 文档:https://www." -"tensorflow.org/api/stable。" +"布尔值,用于指示是否在主线程上启用 GPU 增长。如果您在 \"ServerApp \"上使用 TensorFlow 模型,同时让 " +"\"ClientApp \"在同一 GPU 上运行,则最好启用此选项。如果不启用此功能,您可能会遇到内存不足的错误,因为 TensorFlow " +"默认会分配所有 GPU 内存。有关 `tf.config.experimental.set_memory_growth()` " +"如何工作的更多信息,请参阅 TensorFlow 文档:https://www.tensorflow.org/api/stable。" #: flwr.simulation.run_simulation.run_simulation:26 of #, fuzzy msgid "" "When diabled, only INFO, WARNING and ERROR log messages will be shown. If" " enabled, DEBUG-level logs will be displayed." -msgstr "启用后,将只显示 INFO、WARNING 和 ERROR 日志信息。启用后,将显示 DEBUG " -"级日志。" +msgstr "启用后,将只显示 INFO、WARNING 和 ERROR 日志信息。启用后,将显示 DEBUG 级日志。" #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 #, fuzzy @@ -16471,61 +16632,614 @@ msgid "Changelog" msgstr "更新日志" #: ../../source/ref-changelog.md:3 -msgid "Unreleased" -msgstr "尚未发布" - -#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:19 -#: ../../source/ref-changelog.md:83 ../../source/ref-changelog.md:176 -#: ../../source/ref-changelog.md:276 ../../source/ref-changelog.md:360 -#: ../../source/ref-changelog.md:424 ../../source/ref-changelog.md:482 -#: ../../source/ref-changelog.md:551 ../../source/ref-changelog.md:680 -#: ../../source/ref-changelog.md:722 ../../source/ref-changelog.md:789 -#: ../../source/ref-changelog.md:855 ../../source/ref-changelog.md:900 -#: ../../source/ref-changelog.md:939 ../../source/ref-changelog.md:972 -#: ../../source/ref-changelog.md:1022 -msgid "What's new?" -msgstr "有什么新内容?" +#, fuzzy +msgid "v1.9.0 (2024-06-10)" +msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:71 -#: ../../source/ref-changelog.md:146 ../../source/ref-changelog.md:258 -#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:412 -#: ../../source/ref-changelog.md:470 ../../source/ref-changelog.md:539 -#: ../../source/ref-changelog.md:601 ../../source/ref-changelog.md:620 -#: ../../source/ref-changelog.md:776 ../../source/ref-changelog.md:847 -#: ../../source/ref-changelog.md:884 ../../source/ref-changelog.md:927 -msgid "Incompatible changes" -msgstr "不兼容的更改" +#: ../../source/ref-changelog.md:5 ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:169 ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:362 ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:510 ../../source/ref-changelog.md:568 +#: ../../source/ref-changelog.md:637 ../../source/ref-changelog.md:706 +msgid "Thanks to our contributors" +msgstr "感谢我们的贡献者" -#: ../../source/ref-changelog.md:9 ../../source/ref-changelog.md:73 -#: ../../source/ref-changelog.md:350 ../../source/ref-changelog.md:414 -#: ../../source/ref-changelog.md:472 ../../source/ref-changelog.md:541 -#: ../../source/ref-changelog.md:603 -msgid "None" -msgstr "无" +#: ../../source/ref-changelog.md:7 ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:171 ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:364 ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:512 ../../source/ref-changelog.md:570 +msgid "" +"We would like to give our special thanks to all the contributors who made" +" the new version of Flower possible (in `git shortlog` order):" +msgstr "在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` 顺序排列):" -#: ../../source/ref-changelog.md:11 +#: ../../source/ref-changelog.md:9 #, fuzzy -msgid "v1.8.0 (2024-04-03)" -msgstr "v1.3.0 (2023-02-06)" +msgid "" +"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. " +"Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`," +" `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " +msgstr "" +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " -#: ../../source/ref-changelog.md:13 ../../source/ref-changelog.md:77 -#: ../../source/ref-changelog.md:170 ../../source/ref-changelog.md:270 -#: ../../source/ref-changelog.md:354 ../../source/ref-changelog.md:418 -#: ../../source/ref-changelog.md:476 ../../source/ref-changelog.md:545 -#: ../../source/ref-changelog.md:614 -msgid "Thanks to our contributors" -msgstr "感谢我们的贡献者" +#: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:175 ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:368 ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:516 ../../source/ref-changelog.md:574 +#: ../../source/ref-changelog.md:643 ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:814 ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:947 ../../source/ref-changelog.md:992 +#: ../../source/ref-changelog.md:1031 ../../source/ref-changelog.md:1064 +#: ../../source/ref-changelog.md:1114 +msgid "What's new?" +msgstr "有什么新内容?" -#: ../../source/ref-changelog.md:15 ../../source/ref-changelog.md:79 -#: ../../source/ref-changelog.md:172 ../../source/ref-changelog.md:272 -#: ../../source/ref-changelog.md:356 ../../source/ref-changelog.md:420 -#: ../../source/ref-changelog.md:478 +#: ../../source/ref-changelog.md:13 +#, fuzzy +msgid "" +"**Introduce built-in authentication (preview)** " +"([#2946](https://github.com/adap/flower/pull/2946), " +"[#3388](https://github.com/adap/flower/pull/3388), " +"[#2948](https://github.com/adap/flower/pull/2948), " +"[#2917](https://github.com/adap/flower/pull/2917), " +"[#3386](https://github.com/adap/flower/pull/3386), " +"[#3308](https://github.com/adap/flower/pull/3308), " +"[#3001](https://github.com/adap/flower/pull/3001), " +"[#3409](https://github.com/adap/flower/pull/3409), " +"[#2999](https://github.com/adap/flower/pull/2999), " +"[#2979](https://github.com/adap/flower/pull/2979), " +"[#3389](https://github.com/adap/flower/pull/3389), " +"[#3503](https://github.com/adap/flower/pull/3503), " +"[#3366](https://github.com/adap/flower/pull/3366), " +"[#3357](https://github.com/adap/flower/pull/3357))" +msgstr "" +"** 更新文档** ([#1494](https://github.com/adap/flower/pull/1494), " +"[#1496](https://github.com/adap/flower/pull/1496), " +"[#1500](https://github.com/adap/flower/pull/1500), " +"[#1503](https://github.com/adap/flower/pull/1503), " +"[#1505](https://github.com/adap/flower/pull/1505), " +"[#1524](https://github.com/adap/flower/pull/1524), " +"[#1518](https://github.com/adap/flower/pull/1518), " +"[#1519](https://github.com/adap/flower/pull/1519), " +"[#1515](https://github.com/adap/flower/pull/1515))" + +#: ../../source/ref-changelog.md:15 msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" -msgstr "在此,我们要特别感谢所有为 Flower 的新版本做出贡献的人员(按 `git shortlog` 顺序排列):" +"Flower 1.9 introduces the first build-in version of client node " +"authentication. In previous releases, users often wrote glue code to " +"connect Flower to external authentication systems. With this release, the" +" SuperLink can authenticate SuperNodes using a built-in authentication " +"system. A new [how-to guide](https://flower.ai/docs/framework/how-to-" +"authenticate-supernodes.html) and a new [code " +"example](https://github.com/adap/flower/tree/main/examples/flower-" +"authentication) help you to get started." +msgstr "" #: ../../source/ref-changelog.md:17 +msgid "" +"This is the first preview release of the Flower-native authentication " +"system. Many additional features are on the roadmap for upcoming Flower " +"releases - stay tuned." +msgstr "" + +#: ../../source/ref-changelog.md:19 +#, fuzzy +msgid "" +"**Introduce end-to-end Docker support** " +"([#3483](https://github.com/adap/flower/pull/3483), " +"[#3266](https://github.com/adap/flower/pull/3266), " +"[#3390](https://github.com/adap/flower/pull/3390), " +"[#3283](https://github.com/adap/flower/pull/3283), " +"[#3285](https://github.com/adap/flower/pull/3285), " +"[#3391](https://github.com/adap/flower/pull/3391), " +"[#3403](https://github.com/adap/flower/pull/3403), " +"[#3458](https://github.com/adap/flower/pull/3458), " +"[#3533](https://github.com/adap/flower/pull/3533), " +"[#3453](https://github.com/adap/flower/pull/3453), " +"[#3486](https://github.com/adap/flower/pull/3486), " +"[#3290](https://github.com/adap/flower/pull/3290))" +msgstr "" +"**引入(试验性)REST API** ([#1594](https://github.com/adap/flower/pull/1594), " +"[#1690](https://github.com/adap/flower/pull/1690), " +"[#1695](https://github.com/adap/flower/pull/1695), " +"[#1712](https://github.com/adap/flower/pull/1712), " +"[#1802](https://github.com/adap/flower/pull/1802), " +"[#1770](https://github.com/adap/flower/pull/1770), " +"[#1733](https://github.com/adap/flower/pull/1733))" + +#: ../../source/ref-changelog.md:21 +msgid "" +"Full Flower Next Docker support is here! With the release of Flower 1.9, " +"Flower provides stable Docker images for the Flower SuperLink, the Flower" +" SuperNode, and the Flower `ServerApp`. This set of images enables you to" +" run all Flower components in Docker. Check out the new [how-to " +"guide](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html) to get stated." +msgstr "" + +#: ../../source/ref-changelog.md:23 +#, fuzzy +msgid "" +"**Re-architect Flower Next simulation engine** " +"([#3307](https://github.com/adap/flower/pull/3307), " +"[#3355](https://github.com/adap/flower/pull/3355), " +"[#3272](https://github.com/adap/flower/pull/3272), " +"[#3273](https://github.com/adap/flower/pull/3273), " +"[#3417](https://github.com/adap/flower/pull/3417), " +"[#3281](https://github.com/adap/flower/pull/3281), " +"[#3343](https://github.com/adap/flower/pull/3343), " +"[#3326](https://github.com/adap/flower/pull/3326))" +msgstr "" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614)))" + +#: ../../source/ref-changelog.md:25 +msgid "" +"Flower Next simulations now use a new in-memory `Driver` that improves " +"the reliability of simulations, especially in notebook environments. This" +" is a significant step towards a complete overhaul of the Flower Next " +"simulation architecture." +msgstr "" + +#: ../../source/ref-changelog.md:27 +#, fuzzy +msgid "" +"**Upgrade simulation engine** " +"([#3354](https://github.com/adap/flower/pull/3354), " +"[#3378](https://github.com/adap/flower/pull/3378), " +"[#3262](https://github.com/adap/flower/pull/3262), " +"[#3435](https://github.com/adap/flower/pull/3435), " +"[#3501](https://github.com/adap/flower/pull/3501), " +"[#3482](https://github.com/adap/flower/pull/3482), " +"[#3494](https://github.com/adap/flower/pull/3494))" +msgstr "" +"** 更新文档** ([#1629](https://github.com/adap/flower/pull/1629), " +"[#1628](https://github.com/adap/flower/pull/1628), " +"[#1620](https://github.com/adap/flower/pull/1620), " +"[#1618](https://github.com/adap/flower/pull/1618), " +"[#1617](https://github.com/adap/flower/pull/1617), " +"[#1613](https://github.com/adap/flower/pull/1613), " +"[#1614](https://github.com/adap/flower/pull/1614)))" + +#: ../../source/ref-changelog.md:29 +msgid "" +"The Flower Next simulation engine comes with improved and configurable " +"logging. The Ray-based simulation backend in Flower 1.9 was updated to " +"use Ray 2.10." +msgstr "" + +#: ../../source/ref-changelog.md:31 +#, fuzzy +msgid "" +"**Introduce FedPFT baseline** " +"([#3268](https://github.com/adap/flower/pull/3268))" +msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" + +#: ../../source/ref-changelog.md:33 +msgid "" +"FedPFT allows you to perform one-shot Federated Learning by leveraging " +"widely available foundational models, dramatically reducing communication" +" costs while delivering high performing models. This is work led by Mahdi" +" Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " +"details in their paper: \"Parametric Feature Transfer: One-shot Federated" +" Learning with Foundation Models\" " +"([arxiv](https://arxiv.org/abs/2402.01862))" +msgstr "" + +#: ../../source/ref-changelog.md:35 +#, fuzzy +msgid "" +"**Launch additional** `flwr new` **templates for Apple MLX, Hugging Face " +"Transformers, scikit-learn and TensorFlow** " +"([#3291](https://github.com/adap/flower/pull/3291), " +"[#3139](https://github.com/adap/flower/pull/3139), " +"[#3284](https://github.com/adap/flower/pull/3284), " +"[#3251](https://github.com/adap/flower/pull/3251), " +"[#3376](https://github.com/adap/flower/pull/3376), " +"[#3287](https://github.com/adap/flower/pull/3287))" +msgstr "" +"**移除对 Python 3.7 的支持** " +"([#2280](https://github.com/adap/flower/pull/2280), " +"[#2299](https://github.com/adap/flower/pull/2299), " +"[#2304](https://github.com/adap/flower/pull/2304), " +"[#2306](https://github.com/adap/flower/pull/2306), " +"[#2355](https://github.com/adap/flower/pull/2355), " +"[#2356](https://github.com/adap/flower/pull/2356))" + +#: ../../source/ref-changelog.md:37 +msgid "" +"The `flwr` CLI's `flwr new` command is starting to become everone's " +"favorite way of creating new Flower projects. This release introduces " +"additional `flwr new` templates for Apple MLX, Hugging Face Transformers," +" scikit-learn and TensorFlow. In addition to that, existing templates " +"also received updates." +msgstr "" + +#: ../../source/ref-changelog.md:39 +#, fuzzy +msgid "" +"**Refine** `RecordSet` **API** " +"([#3209](https://github.com/adap/flower/pull/3209), " +"[#3331](https://github.com/adap/flower/pull/3331), " +"[#3334](https://github.com/adap/flower/pull/3334), " +"[#3335](https://github.com/adap/flower/pull/3335), " +"[#3375](https://github.com/adap/flower/pull/3375), " +"[#3368](https://github.com/adap/flower/pull/3368))" +msgstr "" +"**普通改进**([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), " +"[#1884](https://github.com/adap/flower/pull/1884), " +"[#1837](https://github.com/adap/flower/pull/1837), " +"[#1477](https://github.com/adap/flower/pull/1477), " +"[#2171](https://github.com/adap/flower/pull/2171))" + +#: ../../source/ref-changelog.md:41 +msgid "" +"`RecordSet` is part of the Flower Next low-level API preview release. In " +"Flower 1.9, `RecordSet` received a number of usability improvements that " +"make it easier to build `RecordSet`-based `ServerApp`s and `ClientApp`s." +msgstr "" + +#: ../../source/ref-changelog.md:43 +#, fuzzy +msgid "" +"**Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), " +"[#3430](https://github.com/adap/flower/pull/3430), " +"[#3461](https://github.com/adap/flower/pull/3461), " +"[#3360](https://github.com/adap/flower/pull/3360), " +"[#3433](https://github.com/adap/flower/pull/3433))" +msgstr "" +"** 更新 C++ SDK** ([#2537](https://github/com/adap/flower/pull/2537), " +"[#2528](https://github/com/adap/flower/pull/2528), " +"[#2523](https://github.com/adap/flower/pull/2523), " +"[#2522](https://github.com/adap/flower/pull/2522))" + +#: ../../source/ref-changelog.md:45 +msgid "" +"Logs received a substantial update. Not only are logs now much nicer to " +"look at, but they are also more configurable." +msgstr "" + +#: ../../source/ref-changelog.md:47 +#, fuzzy +msgid "" +"**Improve reliability** " +"([#3564](https://github.com/adap/flower/pull/3564), " +"[#3561](https://github.com/adap/flower/pull/3561), " +"[#3566](https://github.com/adap/flower/pull/3566), " +"[#3462](https://github.com/adap/flower/pull/3462), " +"[#3225](https://github.com/adap/flower/pull/3225), " +"[#3514](https://github.com/adap/flower/pull/3514), " +"[#3535](https://github.com/adap/flower/pull/3535), " +"[#3372](https://github.com/adap/flower/pull/3372))" +msgstr "" +"**改进教程** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), " +"[#1472](https://github.com/adap/flower/pull/1472), " +"[#1473](https://github.com/adap/flower/pull/1473), " +"[#1474](https://github.com/adap/flower/pull/1474), " +"[#1475](https://github.com/adap/flower/pull/1475)))" + +#: ../../source/ref-changelog.md:49 +msgid "" +"Flower 1.9 includes reliability improvements across many parts of the " +"system. One example is a much improved SuperNode shutdown procedure." +msgstr "" + +#: ../../source/ref-changelog.md:51 +#, fuzzy +msgid "" +"**Update Swift and C++ SDKs** " +"([#3321](https://github.com/adap/flower/pull/3321), " +"[#2763](https://github.com/adap/flower/pull/2763))" +msgstr "" +"** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), " +"[#1347](https://github.com/adap/flower/pull/1347))" + +#: ../../source/ref-changelog.md:53 +msgid "" +"In the C++ SDK, communication-related code is now separate from main " +"client logic. A new abstract class `Communicator` has been introduced " +"alongside a gRPC implementation of it." +msgstr "" + +#: ../../source/ref-changelog.md:55 +msgid "" +"**Improve testing, tooling and CI/CD infrastructure** " +"([#3294](https://github.com/adap/flower/pull/3294), " +"[#3282](https://github.com/adap/flower/pull/3282), " +"[#3311](https://github.com/adap/flower/pull/3311), " +"[#2878](https://github.com/adap/flower/pull/2878), " +"[#3333](https://github.com/adap/flower/pull/3333), " +"[#3255](https://github.com/adap/flower/pull/3255), " +"[#3349](https://github.com/adap/flower/pull/3349), " +"[#3400](https://github.com/adap/flower/pull/3400), " +"[#3401](https://github.com/adap/flower/pull/3401), " +"[#3399](https://github.com/adap/flower/pull/3399), " +"[#3346](https://github.com/adap/flower/pull/3346), " +"[#3398](https://github.com/adap/flower/pull/3398), " +"[#3397](https://github.com/adap/flower/pull/3397), " +"[#3347](https://github.com/adap/flower/pull/3347), " +"[#3502](https://github.com/adap/flower/pull/3502), " +"[#3387](https://github.com/adap/flower/pull/3387), " +"[#3542](https://github.com/adap/flower/pull/3542), " +"[#3396](https://github.com/adap/flower/pull/3396), " +"[#3496](https://github.com/adap/flower/pull/3496), " +"[#3465](https://github.com/adap/flower/pull/3465), " +"[#3473](https://github.com/adap/flower/pull/3473), " +"[#3484](https://github.com/adap/flower/pull/3484), " +"[#3521](https://github.com/adap/flower/pull/3521), " +"[#3363](https://github.com/adap/flower/pull/3363), " +"[#3497](https://github.com/adap/flower/pull/3497), " +"[#3464](https://github.com/adap/flower/pull/3464), " +"[#3495](https://github.com/adap/flower/pull/3495), " +"[#3478](https://github.com/adap/flower/pull/3478), " +"[#3271](https://github.com/adap/flower/pull/3271))" +msgstr "" + +#: ../../source/ref-changelog.md:57 +msgid "" +"As always, the Flower tooling, testing, and CI/CD infrastructure has " +"received many updates." +msgstr "" + +#: ../../source/ref-changelog.md:59 +msgid "" +"**Improve documentation** " +"([#3530](https://github.com/adap/flower/pull/3530), " +"[#3539](https://github.com/adap/flower/pull/3539), " +"[#3425](https://github.com/adap/flower/pull/3425), " +"[#3520](https://github.com/adap/flower/pull/3520), " +"[#3286](https://github.com/adap/flower/pull/3286), " +"[#3516](https://github.com/adap/flower/pull/3516), " +"[#3523](https://github.com/adap/flower/pull/3523), " +"[#3545](https://github.com/adap/flower/pull/3545), " +"[#3498](https://github.com/adap/flower/pull/3498), " +"[#3439](https://github.com/adap/flower/pull/3439), " +"[#3440](https://github.com/adap/flower/pull/3440), " +"[#3382](https://github.com/adap/flower/pull/3382), " +"[#3559](https://github.com/adap/flower/pull/3559), " +"[#3432](https://github.com/adap/flower/pull/3432), " +"[#3278](https://github.com/adap/flower/pull/3278), " +"[#3371](https://github.com/adap/flower/pull/3371), " +"[#3519](https://github.com/adap/flower/pull/3519), " +"[#3267](https://github.com/adap/flower/pull/3267), " +"[#3204](https://github.com/adap/flower/pull/3204), " +"[#3274](https://github.com/adap/flower/pull/3274))" +msgstr "" + +#: ../../source/ref-changelog.md:61 +msgid "" +"As always, the Flower documentation has received many updates. Notable " +"new pages include:" +msgstr "" + +#: ../../source/ref-changelog.md:63 +msgid "" +"[How-to upgrate to Flower Next (Flower Next migration " +"guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-" +"next.html)" +msgstr "" + +#: ../../source/ref-changelog.md:65 +#, fuzzy +msgid "" +"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-" +"run-flower-using-docker.html)" +msgstr "" +"`TensorFlow快速入门 (教程) `_" + +#: ../../source/ref-changelog.md:67 +msgid "" +"[Flower Mods reference](https://flower.ai/docs/framework/ref-" +"api/flwr.client.mod.html#module-flwr.client.mod)" +msgstr "" + +#: ../../source/ref-changelog.md:69 +#, fuzzy +msgid "" +"**General updates to Flower Examples** " +"([#3205](https://github.com/adap/flower/pull/3205), " +"[#3226](https://github.com/adap/flower/pull/3226), " +"[#3211](https://github.com/adap/flower/pull/3211), " +"[#3252](https://github.com/adap/flower/pull/3252), " +"[#3427](https://github.com/adap/flower/pull/3427), " +"[#3410](https://github.com/adap/flower/pull/3410), " +"[#3426](https://github.com/adap/flower/pull/3426), " +"[#3228](https://github.com/adap/flower/pull/3228), " +"[#3342](https://github.com/adap/flower/pull/3342), " +"[#3200](https://github.com/adap/flower/pull/3200), " +"[#3202](https://github.com/adap/flower/pull/3202), " +"[#3394](https://github.com/adap/flower/pull/3394), " +"[#3488](https://github.com/adap/flower/pull/3488), " +"[#3329](https://github.com/adap/flower/pull/3329), " +"[#3526](https://github.com/adap/flower/pull/3526), " +"[#3392](https://github.com/adap/flower/pull/3392), " +"[#3474](https://github.com/adap/flower/pull/3474), " +"[#3269](https://github.com/adap/flower/pull/3269))" +msgstr "" +"**更新文档** ([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), " +"[#1251](https://github.com/adap/flower/pull/1251), " +"[#1257](https://github.com/adap/flower/pull/1257), " +"[#1267](https://github.com/adap/flower/pull/1267), " +"[#1268](https://github.com/adap/flower/pull/1268), " +"[#1300](https://github.com/adap/flower/pull/1300), " +"[#1304](https://github.com/adap/flower/pull/1304), " +"[#1305](https://github.com/adap/flower/pull/1305), " +"[#1307](https://github.com/adap/flower/pull/1307))" + +#: ../../source/ref-changelog.md:71 +#, fuzzy +msgid "As always, Flower code examples have received many updates." +msgstr "许多 \"Flower \"代码示例得到了大幅更新。" + +#: ../../source/ref-changelog.md:73 +msgid "" +"**General improvements** " +"([#3532](https://github.com/adap/flower/pull/3532), " +"[#3318](https://github.com/adap/flower/pull/3318), " +"[#3565](https://github.com/adap/flower/pull/3565), " +"[#3296](https://github.com/adap/flower/pull/3296), " +"[#3305](https://github.com/adap/flower/pull/3305), " +"[#3246](https://github.com/adap/flower/pull/3246), " +"[#3224](https://github.com/adap/flower/pull/3224), " +"[#3475](https://github.com/adap/flower/pull/3475), " +"[#3297](https://github.com/adap/flower/pull/3297), " +"[#3317](https://github.com/adap/flower/pull/3317), " +"[#3429](https://github.com/adap/flower/pull/3429), " +"[#3196](https://github.com/adap/flower/pull/3196), " +"[#3534](https://github.com/adap/flower/pull/3534), " +"[#3240](https://github.com/adap/flower/pull/3240), " +"[#3365](https://github.com/adap/flower/pull/3365), " +"[#3407](https://github.com/adap/flower/pull/3407), " +"[#3563](https://github.com/adap/flower/pull/3563), " +"[#3344](https://github.com/adap/flower/pull/3344), " +"[#3330](https://github.com/adap/flower/pull/3330), " +"[#3436](https://github.com/adap/flower/pull/3436), " +"[#3300](https://github.com/adap/flower/pull/3300), " +"[#3327](https://github.com/adap/flower/pull/3327), " +"[#3254](https://github.com/adap/flower/pull/3254), " +"[#3253](https://github.com/adap/flower/pull/3253), " +"[#3419](https://github.com/adap/flower/pull/3419), " +"[#3289](https://github.com/adap/flower/pull/3289), " +"[#3208](https://github.com/adap/flower/pull/3208), " +"[#3245](https://github.com/adap/flower/pull/3245), " +"[#3319](https://github.com/adap/flower/pull/3319), " +"[#3203](https://github.com/adap/flower/pull/3203), " +"[#3423](https://github.com/adap/flower/pull/3423), " +"[#3352](https://github.com/adap/flower/pull/3352), " +"[#3292](https://github.com/adap/flower/pull/3292), " +"[#3261](https://github.com/adap/flower/pull/3261))" +msgstr "" + +#: ../../source/ref-changelog.md:75 ../../source/ref-changelog.md:1058 +msgid "Deprecations" +msgstr "停用" + +#: ../../source/ref-changelog.md:77 +#, fuzzy +msgid "**Deprecate Python 3.8 support**" +msgstr "** 过时的 Python 3.7**" + +#: ../../source/ref-changelog.md:79 +#, fuzzy +msgid "" +"Python 3.8 will stop receiving security fixes in [October " +"2024](https://devguide.python.org/versions/). Support for Python 3.8 is " +"now deprecated and will be removed in an upcoming release." +msgstr "由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并将在即将发布的版本中移除。" + +#: ../../source/ref-changelog.md:81 +#, fuzzy +msgid "" +"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-" +"api` ([#3416](https://github.com/adap/flower/pull/3416), " +"[#3420](https://github.com/adap/flower/pull/3420))" +msgstr "" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " +"[#2615](https://github.com/adap/flower/pull/2615))" + +#: ../../source/ref-changelog.md:83 +msgid "" +"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api`" +" and `flower-fleet-api`. Both commands will be removed in an upcoming " +"release. Use `flower-superlink` instead." +msgstr "" + +#: ../../source/ref-changelog.md:85 +#, fuzzy +msgid "" +"**Deprecate** `--server` **in favor of** `--superlink` " +"([#3518](https://github.com/adap/flower/pull/3518))" +msgstr "" +"**启用向** `start_simulation` 传递** `Server` 实例 " +"([#1281](https://github.com/adap/flower/pull/1281))" + +#: ../../source/ref-changelog.md:87 +msgid "" +"The commands `flower-server-app` and `flower-client-app` should use " +"`--superlink` instead of the now deprecated `--server`. Support for " +"`--server` will be removed in a future release." +msgstr "" + +#: ../../source/ref-changelog.md:89 ../../source/ref-changelog.md:163 +#: ../../source/ref-changelog.md:238 ../../source/ref-changelog.md:350 +#: ../../source/ref-changelog.md:440 ../../source/ref-changelog.md:504 +#: ../../source/ref-changelog.md:562 ../../source/ref-changelog.md:631 +#: ../../source/ref-changelog.md:693 ../../source/ref-changelog.md:712 +#: ../../source/ref-changelog.md:868 ../../source/ref-changelog.md:939 +#: ../../source/ref-changelog.md:976 ../../source/ref-changelog.md:1019 +msgid "Incompatible changes" +msgstr "不兼容的更改" + +#: ../../source/ref-changelog.md:91 +msgid "" +"**Replace** `flower-superlink` **CLI option** `--certificates` **with** " +"`--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` " +"([#3512](https://github.com/adap/flower/pull/3512), " +"[#3408](https://github.com/adap/flower/pull/3408))" +msgstr "" + +#: ../../source/ref-changelog.md:93 +msgid "" +"SSL-related `flower-superlink` CLI arguments were restructured in an " +"incompatible way. Instead of passing a single `--certificates` flag with " +"three values, you now need to pass three flags (`--ssl-ca-certfile`, " +"`--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the " +"[SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-" +"connections.html) documentation page for details." +msgstr "" + +#: ../../source/ref-changelog.md:95 +#, fuzzy +msgid "" +"**Remove SuperLink** `--vce` **option** " +"([#3513](https://github.com/adap/flower/pull/3513))" +msgstr "**重构文档**([#1387](https://github.com/adap/flower/pull/1387))" + +#: ../../source/ref-changelog.md:97 +msgid "" +"Instead of separately starting a SuperLink and a `ServerApp` for " +"simulation, simulations must now be started using the single `flower-" +"simulation` command." +msgstr "" + +#: ../../source/ref-changelog.md:99 +#, fuzzy +msgid "" +"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** " +"([#3527](https://github.com/adap/flower/pull/3527))" +msgstr "" +"**重新命名** `rnd` ** to** `server_round` " +"([#1321](https://github.com/adap/flower/pull/1321))" + +#: ../../source/ref-changelog.md:101 +msgid "" +"To simplify the usage of `flower-superlink`, previously separate sets of " +"CLI options for gRPC and REST were merged into one unified set of " +"options. Consult the [Flower CLI reference " +"documentation](https://flower.ai/docs/framework/ref-api-cli.html) for " +"details." +msgstr "" + +#: ../../source/ref-changelog.md:103 +#, fuzzy +msgid "v1.8.0 (2024-04-03)" +msgstr "v1.3.0 (2023-02-06)" + +#: ../../source/ref-changelog.md:109 #, fuzzy msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " @@ -16534,16 +17248,43 @@ msgid "" "`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " "`tabdar-khan` " msgstr "" -"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " -"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " -"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " -"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " - -#: ../../source/ref-changelog.md:21 -#, fuzzy -msgid "" -"**Introduce Flower Next high-level API (stable)** " +"`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `Heng Pan`, `Javier`, `Mahdi`, `Steven Hé (Sīchàng)`, `Taner " +"Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " + +#: ../../source/ref-changelog.md:113 +#, fuzzy +msgid "" +"**Introduce Flower Next high-level API (stable)** " +"([#3002](https://github.com/adap/flower/pull/3002), " +"[#2934](https://github.com/adap/flower/pull/2934), " +"[#2958](https://github.com/adap/flower/pull/2958), " +"[#3173](https://github.com/adap/flower/pull/3173), " +"[#3174](https://github.com/adap/flower/pull/3174), " +"[#2923](https://github.com/adap/flower/pull/2923), " +"[#2691](https://github.com/adap/flower/pull/2691), " +"[#3079](https://github.com/adap/flower/pull/3079), " +"[#2961](https://github.com/adap/flower/pull/2961), " +"[#2924](https://github.com/adap/flower/pull/2924), " +"[#3166](https://github.com/adap/flower/pull/3166), " +"[#3031](https://github.com/adap/flower/pull/3031), " +"[#3057](https://github.com/adap/flower/pull/3057), " +"[#3000](https://github.com/adap/flower/pull/3000), " +"[#3113](https://github.com/adap/flower/pull/3113), " +"[#2957](https://github.com/adap/flower/pull/2957), " +"[#3183](https://github.com/adap/flower/pull/3183), " +"[#3180](https://github.com/adap/flower/pull/3180), " +"[#3035](https://github.com/adap/flower/pull/3035), " +"[#3189](https://github.com/adap/flower/pull/3189), " +"[#3185](https://github.com/adap/flower/pull/3185), " +"[#3190](https://github.com/adap/flower/pull/3190), " +"[#3191](https://github.com/adap/flower/pull/3191), " +"[#3195](https://github.com/adap/flower/pull/3195), " +"[#3197](https://github.com/adap/flower/pull/3197))" +msgstr "" +"**介绍 Flower Next 高级应用程序接口(稳定版)** " "([#3002](https://github.com/adap/flower/pull/3002), " "[#2934](https://github.com/adap/flower/pull/2934), " "[#2958](https://github.com/adap/flower/pull/2958), " @@ -16569,27 +17310,8 @@ msgid "" "[#3191](https://github.com/adap/flower/pull/3191), " "[#3195](https://github.com/adap/flower/pull/3195), " "[#3197](https://github.com/adap/flower/pull/3197))" -msgstr "" -"**介绍 Flower Next 高级应用程序接口(稳定版)** ([#3002](https://github.com/" -"adap/flower/pull/3002), [#2934](https://github.com/adap/flower/pull/2934), " -"[#2958](https://github.com/adap/flower/pull/2958), [#3173](https://github." -"com/adap/flower/pull/3173), [#3174](https://github.com/adap/flower/pull/3174)" -", [#2923](https://github.com/adap/flower/pull/2923), [#2691](https://github." -"com/adap/flower/pull/2691), [#3079](https://github.com/adap/flower/pull/3079)" -", [#2961](https://github.com/adap/flower/pull/2961), [#2924](https://github." -"com/adap/flower/pull/2924), [#3166](https://github.com/adap/flower/pull/3166)" -", [#3031](https://github.com/adap/flower/pull/3031), [#3057](https://github." -"com/adap/flower/pull/3057), [#3000](https://github.com/adap/flower/pull/3000)" -", [#3113](https://github.com/adap/flower/pull/3113), [#2957](https://github." -"com/adap/flower/pull/2957), [#3183](https://github.com/adap/flower/pull/3183)" -", [#3180](https://github.com/adap/flower/pull/3180), [#3035](https://github." -"com/adap/flower/pull/3035), [#3189](https://github.com/adap/flower/pull/3189)" -", [#3185](https://github.com/adap/flower/pull/3185), [#3190](https://github." -"com/adap/flower/pull/3190), [#3191](https://github.com/adap/flower/pull/3191)" -", [#3195](https://github.com/adap/flower/pull/3195), [#3197](https://github." -"com/adap/flower/pull/3197))" -#: ../../source/ref-changelog.md:23 +#: ../../source/ref-changelog.md:115 #, fuzzy msgid "" "The Flower Next high-level API is stable! Flower Next is the future of " @@ -16603,15 +17325,13 @@ msgid "" " line of code. The best part? It's fully compatible with existing Flower " "projects that use `Strategy`, `NumPyClient` & co." msgstr "" -"Flower Next 高级应用程序接口已经稳定!Flower Next 是 Flower 的未来 - " -"所有新功能(如 Flower Mods)都将构建在它之上。您可以使用 `ServerApp` 和 " -"`ClientApp` 开始将现有项目迁移到 Flower Next(请查看 `quickstart-pytorch` 或 " -"`quickstart-tensorflow` ,详细的迁移指南将在不久后发布)。Flower Next 允许您" -"同时运行多个项目(我们称之为多重运行),并在模拟环境或部署环境中执行同一项目" -",而无需更改任何代码。最棒的是什么?它与使用 `Strategy`、`NumPyClient` " -"等的现有 Flower 项目完全兼容。" +"Flower Next 高级应用程序接口已经稳定!Flower Next 是 Flower 的未来 - 所有新功能(如 Flower " +"Mods)都将构建在它之上。您可以使用 `ServerApp` 和 `ClientApp` 开始将现有项目迁移到 Flower Next(请查看 " +"`quickstart-pytorch` 或 `quickstart-tensorflow` ,详细的迁移指南将在不久后发布)。Flower " +"Next 允许您同时运行多个项目(我们称之为多重运行),并在模拟环境或部署环境中执行同一项目,而无需更改任何代码。最棒的是什么?它与使用 " +"`Strategy`、`NumPyClient` 等的现有 Flower 项目完全兼容。" -#: ../../source/ref-changelog.md:25 +#: ../../source/ref-changelog.md:117 #, fuzzy msgid "" "**Introduce Flower Next low-level API (preview)** " @@ -16623,7 +17343,7 @@ msgstr "" "[#2390](https://github.com/adap/flower/pull/2390), " "[#2493](https://github.com/adap/flower/pull/2493))" -#: ../../source/ref-changelog.md:27 +#: ../../source/ref-changelog.md:119 #, fuzzy msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " @@ -16640,17 +17360,15 @@ msgid "" "metrics, stateful computations on the client node and implementations of " "custom SMPC protocols, to name just a few." msgstr "" -"除了使用 \"Strategy\"、\"NumPyClient \"等的 Flower Next 高级应用程序接口外," -"Flower 1.8 还提供了新的 Flower Next 低级应用程序接口的预览版。低级应用程序接" -"口允许通过向/从客户端节点发送/接收单个消息,对学习过程的各个方面进行细粒度控" -"制。新的 \"ServerApp \"支持注册一个自定义的 \"main \"函数" -",允许为异步FL、循环训练或联合分析等方法编写自定义训练循环。新的 \"ClientApp " -"\"支持注册 \"训练\"、\"评估 \"和 \"查询 \"函数,这些函数可以访问从 " -"\"ServerApp \"接收到的原始信息。新的抽象(如 \"RecordSet\"、\"Message \"和 " -"\"Context\")进一步支持发送多个模型、多套配置值和指标、" -"客户端节点上的有状态计算以及自定义 SMPC 协议的实现等。" +"除了使用 \"Strategy\"、\"NumPyClient \"等的 Flower Next 高级应用程序接口外,Flower 1.8 " +"还提供了新的 Flower Next " +"低级应用程序接口的预览版。低级应用程序接口允许通过向/从客户端节点发送/接收单个消息,对学习过程的各个方面进行细粒度控制。新的 " +"\"ServerApp \"支持注册一个自定义的 \"main \"函数,允许为异步FL、循环训练或联合分析等方法编写自定义训练循环。新的 " +"\"ClientApp \"支持注册 \"训练\"、\"评估 \"和 \"查询 \"函数,这些函数可以访问从 \"ServerApp " +"\"接收到的原始信息。新的抽象(如 \"RecordSet\"、\"Message \"和 " +"\"Context\")进一步支持发送多个模型、多套配置值和指标、客户端节点上的有状态计算以及自定义 SMPC 协议的实现等。" -#: ../../source/ref-changelog.md:29 +#: ../../source/ref-changelog.md:121 #, fuzzy msgid "" "**Introduce Flower Mods (preview)** " @@ -16662,7 +17380,7 @@ msgstr "" "[#2221](https://github.com/adap/flower/pull/2221), " "[#2248](https://github.com/adap/flower/pull/2248))" -#: ../../source/ref-changelog.md:31 +#: ../../source/ref-changelog.md:123 #, fuzzy msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " @@ -16674,13 +17392,12 @@ msgid "" "SecAgg+. The Flower Mods API is released as a preview, but researchers " "can already use it to experiment with arbirtrary SMPC protocols." msgstr "" -"Flower Modifiers(我们称之为 Mods)可以拦截信息,并直接对其进行分析、编辑或处" -"理。修改器可用于开发可在不同项目中使用的可插拔模块。Flower 1.8 已经包含了记录" -"信息大小、通过网络发送的参数数量、固定剪切和自适应剪切的差分隐私、" -"本地差分隐私以及安全聚合协议 SecAgg 和 SecAgg+ 的 Mods。Flower Mods API " -"作为预览版发布,但研究人员已经可以用它来试验任意的 SMPC 协议。" +"Flower Modifiers(我们称之为 " +"Mods)可以拦截信息,并直接对其进行分析、编辑或处理。修改器可用于开发可在不同项目中使用的可插拔模块。Flower 1.8 " +"已经包含了记录信息大小、通过网络发送的参数数量、固定剪切和自适应剪切的差分隐私、本地差分隐私以及安全聚合协议 SecAgg 和 SecAgg+ 的" +" Mods。Flower Mods API 作为预览版发布,但研究人员已经可以用它来试验任意的 SMPC 协议。" -#: ../../source/ref-changelog.md:33 +#: ../../source/ref-changelog.md:125 #, fuzzy msgid "" "**Fine-tune LLMs with LLM FlowerTune** " @@ -16699,7 +17416,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475)))" -#: ../../source/ref-changelog.md:35 +#: ../../source/ref-changelog.md:127 #, fuzzy msgid "" "We are introducing LLM FlowerTune, an introductory example that " @@ -16709,14 +17426,12 @@ msgid "" "Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" "-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." msgstr "" -"我们将介绍 LLM FlowerTune,这是一个介绍性示例,演示了在 Alpaca-GPT4 " -"数据集上对预先训练好的 Llama2 模型进行联合 LLM " -"微调。该示例可轻松调整以使用不同的模型和/或数据集。请阅读我们的博文 [LLM " -"FlowerTune: Federated LLM Fine-tuning with Flower](https://flower.ai/blog/" -"2024-03-14-llm-flowertune-federated-llm-finetuning-with-flower/) " -"了解更多详情。" +"我们将介绍 LLM FlowerTune,这是一个介绍性示例,演示了在 Alpaca-GPT4 数据集上对预先训练好的 Llama2 模型进行联合" +" LLM 微调。该示例可轻松调整以使用不同的模型和/或数据集。请阅读我们的博文 [LLM FlowerTune: Federated LLM " +"Fine-tuning with Flower](https://flower.ai/blog/2024-03-14-llm-" +"flowertune-federated-llm-finetuning-with-flower/) 了解更多详情。" -#: ../../source/ref-changelog.md:37 +#: ../../source/ref-changelog.md:129 #, fuzzy msgid "" "**Introduce built-in Differential Privacy (preview)** " @@ -16737,7 +17452,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:39 +#: ../../source/ref-changelog.md:131 #, fuzzy msgid "" "Built-in Differential Privacy is here! Flower supports both central and " @@ -16750,15 +17465,13 @@ msgid "" "the new Differential Privacy components](https://flower.ai/docs/framework" "/how-to-use-differential-privacy.html) in Flower." msgstr "" -"内置差分保密功能!Flower 支持中央和本地差分保密 " -"(DP)。中央差分隐私可配置为固定或自适应剪切。剪切可以发生在服务器端或客户端。" -"本地 DP " -"在客户端进行剪切和噪声处理。新的文档页面[解释差分隐私方法](https://flower.ai/" -"docs/framework/explanation-differential-privacy.html) " -"和新的操作指南[如何使用新的差分隐私组件](https://flower.ai/docs/framework/" -"how-to-use-differential-privacy.html) 介绍了 Flower 的使用方法。" +"内置差分保密功能!Flower 支持中央和本地差分保密 (DP)。中央差分隐私可配置为固定或自适应剪切。剪切可以发生在服务器端或客户端。本地 DP" +" 在客户端进行剪切和噪声处理。新的文档页面[解释差分隐私方法](https://flower.ai/docs/framework" +"/explanation-differential-privacy.html) " +"和新的操作指南[如何使用新的差分隐私组件](https://flower.ai/docs/framework/how-to-use-" +"differential-privacy.html) 介绍了 Flower 的使用方法。" -#: ../../source/ref-changelog.md:41 +#: ../../source/ref-changelog.md:133 #, fuzzy msgid "" "**Introduce built-in Secure Aggregation (preview)** " @@ -16770,7 +17483,7 @@ msgstr "" "[#2221](https://github.com/adap/flower/pull/2221), " "[#2248](https://github.com/adap/flower/pull/2248))" -#: ../../source/ref-changelog.md:43 +#: ../../source/ref-changelog.md:135 #, fuzzy msgid "" "Built-in Secure Aggregation is here! Flower now supports different secure" @@ -16783,14 +17496,12 @@ msgid "" "combine Federated Learning, Differential Privacy and Secure Aggregation " "in the same project." msgstr "" -"内置安全聚合功能!Flower " -"现在支持不同的安全聚合协议。最棒的是什么?只需几行代码," -"您就可以将安全聚合添加到 Flower 项目中。在这个初始版本中,我们包含了对 " -"SecAgg 和 SecAgg+ 的支持,但更多协议将很快实现。我们还将添加详细的文档," -"解释安全聚合以及如何在 Flower 中使用它。您可以查看新的代码示例,了解如何使用 " +"内置安全聚合功能!Flower 现在支持不同的安全聚合协议。最棒的是什么?只需几行代码,您就可以将安全聚合添加到 Flower " +"项目中。在这个初始版本中,我们包含了对 SecAgg 和 SecAgg+ " +"的支持,但更多协议将很快实现。我们还将添加详细的文档,解释安全聚合以及如何在 Flower 中使用它。您可以查看新的代码示例,了解如何使用 " "Flower 在同一项目中轻松结合联合学习、差分隐私和安全聚合。" -#: ../../source/ref-changelog.md:45 +#: ../../source/ref-changelog.md:137 #, fuzzy msgid "" "**Introduce** `flwr` **CLI (preview)** " @@ -16811,15 +17522,14 @@ msgstr "" "[#1477](https://github.com/adap/flower/pull/1477), " "[#2171](https://github.com/adap/flower/pull/2171))" -#: ../../source/ref-changelog.md:47 +#: ../../source/ref-changelog.md:139 #, fuzzy msgid "" "A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" " and then running them using the Simulation Engine (`flwr run`)." -msgstr "新的 `flwr` CLI 命令允许创建新的 Flower 项目(`flwr " -"new`),然后使用仿真引擎运行它们(`flwr run`)。" +msgstr "新的 `flwr` CLI 命令允许创建新的 Flower 项目(`flwr new`),然后使用仿真引擎运行它们(`flwr run`)。" -#: ../../source/ref-changelog.md:49 +#: ../../source/ref-changelog.md:141 #, fuzzy msgid "" "**Introduce Flower Next Simulation Engine** " @@ -16842,24 +17552,24 @@ msgstr "" "[#1770](https://github.com/adap/flower/pull/1770), " "[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:51 +#: ../../source/ref-changelog.md:143 #, fuzzy msgid "" "The Flower Simulation Engine can now run Flower Next projects. For " "notebook environments, there's also a new `run_simulation` function that " "can run `ServerApp` and `ClientApp`." msgstr "" -"Flower 模拟引擎现在可以运行 Flower Next 项目。对于笔记本环境,还有一个新的 " -"`run_simulation` 函数,可以运行 `ServerApp` 和 `ClientApp`。" +"Flower 模拟引擎现在可以运行 Flower Next 项目。对于笔记本环境,还有一个新的 `run_simulation` 函数,可以运行 " +"`ServerApp` 和 `ClientApp`。" -#: ../../source/ref-changelog.md:53 +#: ../../source/ref-changelog.md:145 #, fuzzy msgid "" "**Handle SuperNode connection errors** " "([#2969](https://github.com/adap/flower/pull/2969))" msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" -#: ../../source/ref-changelog.md:55 +#: ../../source/ref-changelog.md:147 #, fuzzy msgid "" "A SuperNode will now try to reconnect indefinitely to the SuperLink in " @@ -16870,12 +17580,11 @@ msgid "" "wait-time` defines the time before the SuperNode gives up trying to " "reconnect to the SuperLink." msgstr "" -"如果出现连接错误,超级节点现在会尝试无限期地重新连接超级链接。现在可以向 " -"`flower-client-app` 命令传递参数 `-ax-retries` 和 `-max-wait-time`。" -"最大重试次数 \"将定义客户端在放弃重新连接超级链接之前的重试次数,而 " -"\"最大等待时间 \"则定义超级节点放弃重新连接超级链接之前的等待时间。" +"如果出现连接错误,超级节点现在会尝试无限期地重新连接超级链接。现在可以向 `flower-client-app` 命令传递参数 `-ax-" +"retries` 和 `-max-wait-time`。最大重试次数 \"将定义客户端在放弃重新连接超级链接之前的重试次数,而 \"最大等待时间 " +"\"则定义超级节点放弃重新连接超级链接之前的等待时间。" -#: ../../source/ref-changelog.md:57 +#: ../../source/ref-changelog.md:149 #, fuzzy msgid "" "**General updates to Flower Baselines** " @@ -16890,7 +17599,7 @@ msgstr "" "[#1681](https://github.com/adap/flower/pull/1681), " "[#1679](https://github.com/adap/flower/pull/1679)" -#: ../../source/ref-changelog.md:59 +#: ../../source/ref-changelog.md:151 #, fuzzy msgid "" "There's a new [FedStar](https://flower.ai/docs/baselines/fedstar.html) " @@ -16899,7 +17608,7 @@ msgstr "" "有一条新的 [FedStar](https://flower.ai/docs/baselines/fedstar.html) " "基准线。其他几条基准线也已更新。" -#: ../../source/ref-changelog.md:61 +#: ../../source/ref-changelog.md:153 #, fuzzy msgid "" "**Improve documentation and translations** " @@ -16921,30 +17630,33 @@ msgid "" "[#2989](https://github.com/adap/flower/pull/2989))" msgstr "" "**改进文件和翻译** ([#3050](https://github.com/adap/flower/pull/3050), " -"[#3044](https://github.com/adap/flower/pull/3044), [#3043](https://github." -"com/adap/flower/pull/3043), [#2986](https://github.com/adap/flower/pull/2986)" -", [#3041](https://github.com/adap/flower/pull/3041), [#3046](https://github." -"com/adap/flower/pull/3046), [#3042](https://github.com/adap/flower/pull/3042)" -", [#2978](https://github.com/adap/flower/pull/2978), [#2952](https://github." -"com/adap/flower/pull/2952), [#3167](https://github.com/adap/flower/pull/3167)" -", [#2953](https://github.com/adap/flower/pull/2953), [#3045](https://github." -"com/adap/flower/pull/3045), [#2654](https://github.com/adap/flower/pull/2654)" -", [#3082](https://github.com/adap/flower/pull/3082), [#2990](https://github." -"com/adap/flower/pull/2990), [#2989](https://github.com/adap/flower/pull/" -"2989))" +"[#3044](https://github.com/adap/flower/pull/3044), " +"[#3043](https://github.com/adap/flower/pull/3043), " +"[#2986](https://github.com/adap/flower/pull/2986), " +"[#3041](https://github.com/adap/flower/pull/3041), " +"[#3046](https://github.com/adap/flower/pull/3046), " +"[#3042](https://github.com/adap/flower/pull/3042), " +"[#2978](https://github.com/adap/flower/pull/2978), " +"[#2952](https://github.com/adap/flower/pull/2952), " +"[#3167](https://github.com/adap/flower/pull/3167), " +"[#2953](https://github.com/adap/flower/pull/2953), " +"[#3045](https://github.com/adap/flower/pull/3045), " +"[#2654](https://github.com/adap/flower/pull/2654), " +"[#3082](https://github.com/adap/flower/pull/3082), " +"[#2990](https://github.com/adap/flower/pull/2990), " +"[#2989](https://github.com/adap/flower/pull/2989))" -#: ../../source/ref-changelog.md:63 +#: ../../source/ref-changelog.md:155 #, fuzzy msgid "" "As usual, we merged many smaller and larger improvements to the " "documentation. A special thank you goes to [Sebastian van der " "Voort](https://github.com/svdvoort) for landing a big documentation PR!" msgstr "" -"像往常一样,我们合并了许多对文档的较大和较小的改进。特别要感谢 [Sebastian " -"van der Voort](https://github.com/svdvoort),他为我们带来了一份重要的文档 " -"PR!" +"像往常一样,我们合并了许多对文档的较大和较小的改进。特别要感谢 [Sebastian van der " +"Voort](https://github.com/svdvoort),他为我们带来了一份重要的文档 PR!" -#: ../../source/ref-changelog.md:65 +#: ../../source/ref-changelog.md:157 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -16970,7 +17682,7 @@ msgstr "" "[#1519](https://github.com/adap/flower/pull/1519), " "[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:67 +#: ../../source/ref-changelog.md:159 #, fuzzy msgid "" "Two new examples show federated training of a Vision Transformer (ViT) " @@ -16979,12 +17691,11 @@ msgid "" " new Flower Next `ServerApp` and `ClientApp`. Many other examples " "received considerable updates as well." msgstr "" -"两个新示例展示了视觉转换器(ViT)的联合训练,以及使用流行的 MONAI " -"库在医疗环境中进行的联合学习。quickstart-pytorch \"和 \"quickstart-" -"tensorflow \"展示了新的 Flower Next \"ServerApp \"和 \"ClientApp\"" -"。许多其他示例也得到了大量更新。" +"两个新示例展示了视觉转换器(ViT)的联合训练,以及使用流行的 MONAI 库在医疗环境中进行的联合学习。quickstart-pytorch " +"\"和 \"quickstart-tensorflow \"展示了新的 Flower Next \"ServerApp \"和 " +"\"ClientApp\"。许多其他示例也得到了大量更新。" -#: ../../source/ref-changelog.md:69 +#: ../../source/ref-changelog.md:161 #, fuzzy msgid "" "**General improvements** " @@ -17063,62 +17774,91 @@ msgid "" "[#2954](https://github.com/adap/flower/pull/2954))" msgstr "" "**一般改进**([#3171](https://github.com/adap/flower/pull/3171), " -"[3099](https://github.com/adap/flower/pull/3099), [3003](https://github.com/" -"adap/flower/pull/3003), [3145](https://github.com/adap/flower/pull/3145), " -"[3017](https://github.com/adap/flower/pull/3017), [3085](https://github.com/" -"adap/flower/pull/3085), [3012](https://github.com/adap/flower/pull/3012), " -"[3119](https://github.com/adap/flower/pull/3119), [2991](https://github.com/" -"adap/flower/pull/2991), [2970](https://github.com/adap/flower/pull/2970), " -"[2980](https://github.com/adap/flower/pull/2980), [3086](https://github.com/" -"adap/flower/pull/3086), [2932](https://github.com/adap/flower/pull/2932), " -"[2928](https://github.com/adap/flower/pull/2928), [2941](https://github.com/" -"adap/flower/pull/2941), [2933](https://github.com/adap/flower/pull/2933), " -"[3181](https://github.com/adap/flower/pull/3181), [2973](https://github.com/" -"adap/flower/pull/2973), [2992](https://github.com/adap/flower/pull/2992), " -"[2915](https://github.com/adap/flower/pull/2915), [3040](https://github.com/" -"adap/flower/pull/3040), [3022](https://github.com/adap/flower/pull/3022), " -"[3032](https://github.com/adap/flower/pull/3032), [2902](https://github.com/" -"adap/flower/pull/2902), [2931](https://github.com/adap/flower/pull/2931), " -"[3005](https://github.com/adap/flower/pull/3005), [3132](https://github.com/" -"adap/flower/pull/3132), [3115](https://github.com/adap/flower/pull/3115), " -"[2944](https://github.com/adap/flower/pull/2944), [3064](https://github.com/" -"adap/flower/pull/3064), [3106](https://github.com/adap/flower/pull/3106), " -"[2974](https://github.com/adap/flower/pull/2974), [3178](https://github.com/" -"adap/flower/pull/3178), [2993](https://github.com/adap/flower/pull/2993), " -"[3186](https://github.com/adap/flower/pull/3186), [3091](https://github.com/" -"adap/flower/pull/3091), [3125](https://github.com/adap/flower/pull/3125), " -"[3093](https://github.com/adap/flower/pull/3093), [3013](https://github.com/" -"adap/flower/pull/3013), [3033](https://github.com/adap/flower/pull/3033), " -"[3133](https://github.com/adap/flower/pull/3133), [3068](https://github.com/" -"adap/flower/pull/3068), [2916](https://github.com/adap/flower/pull/2916), " -"[2975](https://github.com/adap/flower/pull/2975), [2984](https://github.com/" -"adap/flower/pull/2984), [2846](https://github.com/adap/flower/pull/2846), " -"[3077](https://github.com/adap/flower/pull/3077), [3143](https://github.com/" -"adap/flower/pull/3143), [2921](https://github.com/adap/flower/pull/2921), " -"[3101](https://github.com/adap/flower/pull/3101), [2927](https://github.com/" -"adap/flower/pull/2927), [2995](https://github.com/adap/flower/pull/2995), " -"[2972](https://github.com/adap/flower/pull/2972), [2912](https://github.com/" -"adap/flower/pull/2912), [3065](https://github.com/adap/flower/pull/3065), " -"[3028](https://github.com/adap/flower/pull/3028), [2922](https://github.com/" -"adap/flower/pull/2922), [2982](https://github.com/adap/flower/pull/2982), " -"[2914](https://github.com/adap/flower/pull/2914), [3179](https://github.com/" -"adap/flower/pull/3179), [3080](https://github.com/adap/flower/pull/3080), " -"[2994](https://github.com/adap/flower/pull/2994), [3187](https://github.com/" -"adap/flower/pull/3187), [2926](https://github.com/adap/flower/pull/2926), " -"[3018](https://github.com/adap/flower/pull/3018), [3144](https://github.com/" -"adap/flower/pull/3144), [3011](https://github.com/adap/flower/pull/3011), " -"[#3152](https://github.com/adap/flower/pull/3152), [#2836](https://github." -"com/adap/flower/pull/2836), [#2929](https://github.com/adap/flower/pull/2929)" -", [#2943](https://github.com/adap/flower/pull/2943), [#2955](https://github." -"com/adap/flower/pull/2955), [#2954](https://github.com/adap/flower/pull/" -"2954))" - -#: ../../source/ref-changelog.md:75 +"[3099](https://github.com/adap/flower/pull/3099), " +"[3003](https://github.com/adap/flower/pull/3003), " +"[3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), " +"[3085](https://github.com/adap/flower/pull/3085), " +"[3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), " +"[2991](https://github.com/adap/flower/pull/2991), " +"[2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), " +"[3086](https://github.com/adap/flower/pull/3086), " +"[2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), " +"[2941](https://github.com/adap/flower/pull/2941), " +"[2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), " +"[2973](https://github.com/adap/flower/pull/2973), " +"[2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), " +"[3040](https://github.com/adap/flower/pull/3040), " +"[3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), " +"[2902](https://github.com/adap/flower/pull/2902), " +"[2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), " +"[3132](https://github.com/adap/flower/pull/3132), " +"[3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), " +"[3064](https://github.com/adap/flower/pull/3064), " +"[3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), " +"[3178](https://github.com/adap/flower/pull/3178), " +"[2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), " +"[3091](https://github.com/adap/flower/pull/3091), " +"[3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), " +"[3013](https://github.com/adap/flower/pull/3013), " +"[3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), " +"[3068](https://github.com/adap/flower/pull/3068), " +"[2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), " +"[2984](https://github.com/adap/flower/pull/2984), " +"[2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), " +"[3143](https://github.com/adap/flower/pull/3143), " +"[2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), " +"[2927](https://github.com/adap/flower/pull/2927), " +"[2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), " +"[2912](https://github.com/adap/flower/pull/2912), " +"[3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), " +"[2922](https://github.com/adap/flower/pull/2922), " +"[2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), " +"[3179](https://github.com/adap/flower/pull/3179), " +"[3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), " +"[3187](https://github.com/adap/flower/pull/3187), " +"[2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), " +"[3144](https://github.com/adap/flower/pull/3144), " +"[3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), " +"[#2836](https://github.com/adap/flower/pull/2836), " +"[#2929](https://github.com/adap/flower/pull/2929), " +"[#2943](https://github.com/adap/flower/pull/2943), " +"[#2955](https://github.com/adap/flower/pull/2955), " +"[#2954](https://github.com/adap/flower/pull/2954))" + +#: ../../source/ref-changelog.md:165 ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:506 ../../source/ref-changelog.md:564 +#: ../../source/ref-changelog.md:633 ../../source/ref-changelog.md:695 +msgid "None" +msgstr "无" + +#: ../../source/ref-changelog.md:167 #, fuzzy msgid "v1.7.0 (2024-02-05)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:81 +#: ../../source/ref-changelog.md:173 #, fuzzy msgid "" "`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " @@ -17134,7 +17874,7 @@ msgstr "" "Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " -#: ../../source/ref-changelog.md:85 +#: ../../source/ref-changelog.md:177 #, fuzzy msgid "" "**Introduce stateful clients (experimental)** " @@ -17150,7 +17890,7 @@ msgstr "" "[#2327](https://github.com/adap/flower/pull/2327), " "[#2435](https://github.com/adap/flower/pull/2435))" -#: ../../source/ref-changelog.md:87 +#: ../../source/ref-changelog.md:179 #, fuzzy msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " @@ -17163,21 +17903,20 @@ msgid "" "different rounds of execution to enable stateful computations in a " "unified way across simulation and deployment." msgstr "" -"客户端 \"和 \"NumPyClient \"的子类现在可以存储保留在客户端上的本地状态" -"。让我们先从亮点开始:这一新功能与模拟客户端(通过 " -"`start_simulation`)和网络客户端(通过 `start_client`)兼容。这也是 `Context`" -" 和 `RecordSet` 等新抽象的首次预览。客户端可以通过 `state.RecordSet` 访问 " -"`RecordSet` 类型的状态: RecordSet = self.context.state`。对该 `RecordSet` " +"客户端 \"和 \"NumPyClient \"的子类现在可以存储保留在客户端上的本地状态。让我们先从亮点开始:这一新功能与模拟客户端(通过 " +"`start_simulation`)和网络客户端(通过 `start_client`)兼容。这也是 `Context` 和 " +"`RecordSet` 等新抽象的首次预览。客户端可以通过 `state.RecordSet` 访问 `RecordSet` 类型的状态: " +"RecordSet = self.context.state`。对该 `RecordSet` " "的更改会在不同轮执行中保留,以便在模拟和部署中以统一的方式进行有状态计算。" -#: ../../source/ref-changelog.md:89 +#: ../../source/ref-changelog.md:181 #, fuzzy msgid "" "**Improve performance** " "([#2293](https://github.com/adap/flower/pull/2293))" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" -#: ../../source/ref-changelog.md:91 +#: ../../source/ref-changelog.md:183 #, fuzzy msgid "" "Flower is faster than ever. All `FedAvg`-derived strategies now use in-" @@ -17186,11 +17925,10 @@ msgid "" "which results in significant speedups, especially when the client-side " "training time is short." msgstr "" -"Flower 的速度比以往更快。所有源于 `FedAvg` " -"的策略现在都使用就地聚合,以减少内存消耗。Flower 客户端序列化/解序列化已从头" -"开始重写,从而显著提高了速度,尤其是在客户端训练时间较短的情况下。" +"Flower 的速度比以往更快。所有源于 `FedAvg` 的策略现在都使用就地聚合,以减少内存消耗。Flower " +"客户端序列化/解序列化已从头开始重写,从而显著提高了速度,尤其是在客户端训练时间较短的情况下。" -#: ../../source/ref-changelog.md:93 +#: ../../source/ref-changelog.md:185 #, fuzzy msgid "" "**Support Federated Learning with Apple MLX and Flower** " @@ -17199,17 +17937,17 @@ msgstr "" "** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " "([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:95 +#: ../../source/ref-changelog.md:187 #, fuzzy msgid "" "Flower has official support for federated learning using [Apple " "MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " "example." msgstr "" -"通过新的 `quickstart-mlx` 代码示例,Flower 正式支持使用 [Apple MLX](https" -"://ml-explore.github.io/mlx)的联合学习。" +"通过新的 `quickstart-mlx` 代码示例,Flower 正式支持使用 [Apple MLX](https://ml-" +"explore.github.io/mlx)的联合学习。" -#: ../../source/ref-changelog.md:97 +#: ../../source/ref-changelog.md:189 #, fuzzy msgid "" "**Introduce new XGBoost cyclic strategy** " @@ -17219,7 +17957,7 @@ msgstr "" "**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:99 +#: ../../source/ref-changelog.md:191 #, fuzzy msgid "" "A new strategy called `FedXgbCyclic` supports a client-by-client style of" @@ -17228,27 +17966,25 @@ msgid "" "comprehensive` now also supports simulation mode. With this, Flower " "offers best-in-class XGBoost support." msgstr "" -"名为 `FedXgbCyclic` 的新策略支持逐个客户端的训练风格(通常称为循环" -")。xgboost-comprehensive \"代码示例展示了如何在一个完整的项目中使用它" -"。除此之外,`xgboost-comprehensive` 现在还支持模拟模式。由此,Flower " +"名为 `FedXgbCyclic` 的新策略支持逐个客户端的训练风格(通常称为循环)。xgboost-comprehensive " +"\"代码示例展示了如何在一个完整的项目中使用它。除此之外,`xgboost-comprehensive` 现在还支持模拟模式。由此,Flower " "提供了同类最佳的 XGBoost 支持。" -#: ../../source/ref-changelog.md:101 +#: ../../source/ref-changelog.md:193 #, fuzzy msgid "" "**Support Python 3.11** " "([#2394](https://github.com/adap/flower/pull/2394))" msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:103 +#: ../../source/ref-changelog.md:195 #, fuzzy msgid "" "Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " "ensure better support for users using more recent Python versions." -msgstr "框架测试现在可在 Python 3.8、3.9、3.10 和 3.11 上运行。这将确保为使用最新 " -"Python 版本的用户提供更好的支持。" +msgstr "框架测试现在可在 Python 3.8、3.9、3.10 和 3.11 上运行。这将确保为使用最新 Python 版本的用户提供更好的支持。" -#: ../../source/ref-changelog.md:105 +#: ../../source/ref-changelog.md:197 #, fuzzy msgid "" "**Update gRPC and ProtoBuf dependencies** " @@ -17257,14 +17993,14 @@ msgstr "" "**更新 REST API 以支持创建和删除节点** " "([#2283](https://github.com/adap/flower/pull/2283))" -#: ../../source/ref-changelog.md:107 +#: ../../source/ref-changelog.md:199 #, fuzzy msgid "" "The `grpcio` and `protobuf` dependencies were updated to their latest " "versions for improved security and performance." msgstr "为提高安全性和性能,\"grpcio \"和 \"protobuf \"依赖项已更新至最新版本。" -#: ../../source/ref-changelog.md:109 +#: ../../source/ref-changelog.md:201 #, fuzzy msgid "" "**Introduce Docker image for Flower server** " @@ -17285,7 +18021,7 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:111 +#: ../../source/ref-changelog.md:203 #, fuzzy msgid "" "The Flower server can now be run using an official Docker image. A new " @@ -17293,11 +18029,11 @@ msgid "" "Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" "docker.html). An official Flower client Docker image will follow." msgstr "" -"现在可以使用官方 Docker 映像运行 Flower 服务器了。新的操作指南介绍了 [" -"如何使用 Docker 运行 Flower](https://flower.ai/docs/framework/how-to-run-" -"flower-using-docker.html)。Flower 客户端 Docker 官方镜像将随后发布。" +"现在可以使用官方 Docker 映像运行 Flower 服务器了。新的操作指南介绍了 [如何使用 Docker 运行 " +"Flower](https://flower.ai/docs/framework/how-to-run-flower-using-" +"docker.html)。Flower 客户端 Docker 官方镜像将随后发布。" -#: ../../source/ref-changelog.md:113 +#: ../../source/ref-changelog.md:205 #, fuzzy msgid "" "**Introduce** `flower-via-docker-compose` **example** " @@ -17306,21 +18042,21 @@ msgstr "" "**介绍Flower Android SDK** " "([#2131](https://github.com/adap/flower/pull/2131))" -#: ../../source/ref-changelog.md:115 +#: ../../source/ref-changelog.md:207 #, fuzzy msgid "" "**Introduce** `quickstart-sklearn-tabular` **example** " "([#2719](https://github.com/adap/flower/pull/2719))" msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" -#: ../../source/ref-changelog.md:117 +#: ../../source/ref-changelog.md:209 #, fuzzy msgid "" "**Introduce** `custom-metrics` **example** " "([#1958](https://github.com/adap/flower/pull/1958))" msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" -#: ../../source/ref-changelog.md:119 +#: ../../source/ref-changelog.md:211 #, fuzzy msgid "" "**Update code examples to use Flower Datasets** " @@ -17334,15 +18070,14 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310)" -#: ../../source/ref-changelog.md:121 +#: ../../source/ref-changelog.md:213 #, fuzzy msgid "" "Several code examples were updated to use [Flower " "Datasets](https://flower.ai/docs/datasets/)." -msgstr "更新了多个代码示例,以使用 [Flower Datasets](https://flower.ai/docs/datasets/" -") 。" +msgstr "更新了多个代码示例,以使用 [Flower Datasets](https://flower.ai/docs/datasets/) 。" -#: ../../source/ref-changelog.md:123 +#: ../../source/ref-changelog.md:215 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -17367,16 +18102,16 @@ msgstr "" "[#1662](https://github.com/adap/flower/pull/1662), " "[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:125 +#: ../../source/ref-changelog.md:217 #, fuzzy msgid "Many Flower code examples received substantial updates." msgstr "许多 \"Flower \"代码示例得到了大幅更新。" -#: ../../source/ref-changelog.md:127 ../../source/ref-changelog.md:220 +#: ../../source/ref-changelog.md:219 ../../source/ref-changelog.md:312 msgid "**Update Flower Baselines**" msgstr "**更新 Flower Baselines**" -#: ../../source/ref-changelog.md:129 +#: ../../source/ref-changelog.md:221 #, fuzzy msgid "" "HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " @@ -17385,32 +18120,32 @@ msgstr "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " "[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:130 +#: ../../source/ref-changelog.md:222 #, fuzzy msgid "FedVSSL ([#2412](https://github.com/adap/flower/pull/2412))" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:131 +#: ../../source/ref-changelog.md:223 #, fuzzy msgid "FedNova ([#2179](https://github.com/adap/flower/pull/2179))" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:132 +#: ../../source/ref-changelog.md:224 #, fuzzy msgid "HeteroFL ([#2439](https://github.com/adap/flower/pull/2439))" msgstr "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" -#: ../../source/ref-changelog.md:133 +#: ../../source/ref-changelog.md:225 #, fuzzy msgid "FedAvgM ([#2246](https://github.com/adap/flower/pull/2246))" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:134 +#: ../../source/ref-changelog.md:226 #, fuzzy msgid "FedPara ([#2722](https://github.com/adap/flower/pull/2722))" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:136 +#: ../../source/ref-changelog.md:228 #, fuzzy msgid "" "**Improve documentation** " @@ -17429,7 +18164,7 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614)))" -#: ../../source/ref-changelog.md:138 +#: ../../source/ref-changelog.md:230 #, fuzzy msgid "" "**Improved testing and development infrastructure** " @@ -17463,36 +18198,44 @@ msgid "" "[#2661](https://github.com/adap/flower/pull/2661), " "[#2398](https://github.com/adap/flower/pull/2398))" msgstr "" -"**改进测试和开发基础设施** ([#2797](https://github.com/adap/flower/pull/2797)" -", [#2676](https://github.com/adap/flower/pull/2676), [#2644](https://github." -"com/adap/flower/pull/2644), [#2656](https://github.com/adap/flower/pull/2656)" -", [#2848](https://github.com/adap/flower/pull/2848), [#2675](https://github." -"com/adap/flower/pull/2675), [#2735](https://github.com/adap/flower/pull/2735)" -", [#2767](https://github.com/adap/flower/pull/2767), [#2732](https://github." -"com/adap/flower/pull/2732), [#2744](https://github.com/adap/flower/pull/2744)" -", [#2681](https://github.com/adap/flower/pull/2681), [#2699](https://github." -"com/adap/flower/pull/2699), [#2745](https://github.com/adap/flower/pull/2745)" -", [#2734](https://github.com/adap/flower/pull/2734), [#2731](https://github." -"com/adap/flower/pull/2731), [#2652](https://github.com/adap/flower/pull/2652)" -", [#2720](https://github.com/adap/flower/pull/2720), [#2721](https://github." -"com/adap/flower/pull/2721), [#2717](https://github.com/adap/flower/pull/2717)" -", [#2864](https://github.com/adap/flower/pull/2864), [#2694](https://github." -"com/adap/flower/pull/2694), [#2709](https://github.com/adap/flower/pull/2709)" -", [#2658](https://github.com/adap/flower/pull/2658), [#2796](https://github." -"com/adap/flower/pull/2796), [#2692](https://github.com/adap/flower/pull/2692)" -", [#2657](https://github.com/adap/flower/pull/2657), [#2813](https://github." -"com/adap/flower/pull/2813), [#2661](https://github.com/adap/flower/pull/2661)" -", [#2398](https://github.com/adap/flower/pull/2398))" - -#: ../../source/ref-changelog.md:140 +"**改进测试和开发基础设施** ([#2797](https://github.com/adap/flower/pull/2797), " +"[#2676](https://github.com/adap/flower/pull/2676), " +"[#2644](https://github.com/adap/flower/pull/2644), " +"[#2656](https://github.com/adap/flower/pull/2656), " +"[#2848](https://github.com/adap/flower/pull/2848), " +"[#2675](https://github.com/adap/flower/pull/2675), " +"[#2735](https://github.com/adap/flower/pull/2735), " +"[#2767](https://github.com/adap/flower/pull/2767), " +"[#2732](https://github.com/adap/flower/pull/2732), " +"[#2744](https://github.com/adap/flower/pull/2744), " +"[#2681](https://github.com/adap/flower/pull/2681), " +"[#2699](https://github.com/adap/flower/pull/2699), " +"[#2745](https://github.com/adap/flower/pull/2745), " +"[#2734](https://github.com/adap/flower/pull/2734), " +"[#2731](https://github.com/adap/flower/pull/2731), " +"[#2652](https://github.com/adap/flower/pull/2652), " +"[#2720](https://github.com/adap/flower/pull/2720), " +"[#2721](https://github.com/adap/flower/pull/2721), " +"[#2717](https://github.com/adap/flower/pull/2717), " +"[#2864](https://github.com/adap/flower/pull/2864), " +"[#2694](https://github.com/adap/flower/pull/2694), " +"[#2709](https://github.com/adap/flower/pull/2709), " +"[#2658](https://github.com/adap/flower/pull/2658), " +"[#2796](https://github.com/adap/flower/pull/2796), " +"[#2692](https://github.com/adap/flower/pull/2692), " +"[#2657](https://github.com/adap/flower/pull/2657), " +"[#2813](https://github.com/adap/flower/pull/2813), " +"[#2661](https://github.com/adap/flower/pull/2661), " +"[#2398](https://github.com/adap/flower/pull/2398))" + +#: ../../source/ref-changelog.md:232 #, fuzzy msgid "" "The Flower testing and development infrastructure has received " "substantial updates. This makes Flower 1.7 the most tested release ever." -msgstr "Flower 测试和开发基础架构已得到大幅更新。这使得 Flower 1.7 " -"成为有史以来经过最多测试的版本。" +msgstr "Flower 测试和开发基础架构已得到大幅更新。这使得 Flower 1.7 成为有史以来经过最多测试的版本。" -#: ../../source/ref-changelog.md:142 +#: ../../source/ref-changelog.md:234 #, fuzzy msgid "" "**Update dependencies** " @@ -17528,7 +18271,7 @@ msgstr "" "[#2225](https://github.com/adap/flower/pull/2225), " "[#2183](https://github.com/adap/flower/pull/2183))" -#: ../../source/ref-changelog.md:144 +#: ../../source/ref-changelog.md:236 #, fuzzy msgid "" "**General improvements** " @@ -17570,32 +18313,43 @@ msgid "" "[#2759](https://github.com/adap/flower/pull/2759))" msgstr "" "**一般改进** ([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." -"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/pull/2690)" -", [#2889](https://github.com/adap/flower/pull/2889), [#2874](https://github." -"com/adap/flower/pull/2874), [#2819](https://github.com/adap/flower/pull/2819)" -", [#2689](https://github.com/adap/flower/pull/2689), [#2457](https://github." -"com/adap/flower/pull/2457), [#2870](https://github.com/adap/flower/pull/2870)" -", [#2669](https://github.com/adap/flower/pull/2669), [#2876](https://github." -"com/adap/flower/pull/2876), [#2885](https://github.com/adap/flower/pull/2885)" -", [#2858](https://github.com/adap/flower/pull/2858), [#2867](https://github." -"com/adap/flower/pull/2867), [#2351](https://github.com/adap/flower/pull/2351)" -", [#2886](https://github.com/adap/flower/pull/2886), [#2860](https://github." -"com/adap/flower/pull/2860), [#2828](https://github.com/adap/flower/pull/2828)" -", [#2869](https://github.com/adap/flower/pull/2869), [#2875](https://github." -"com/adap/flower/pull/2875), [#2733](https://github.com/adap/flower/pull/2733)" -", [#2488](https://github.com/adap/flower/pull/2488), [#2646](https://github." -"com/adap/flower/pull/2646), [#2879](https://github.com/adap/flower/pull/2879)" -", [#2821](https://github.com/adap/flower/pull/2821), [#2855](https://github." -"com/adap/flower/pull/2855), [#2800](https://github.com/adap/flower/pull/2800)" -", [#2807](https://github.com/adap/flower/pull/2807), [#2801](https://github." -"com/adap/flower/pull/2801), [#2804](https://github.com/adap/flower/pull/2804)" -", [#2851](https://github.com/adap/flower/pull/2851), [#2787](https://github." -"com/adap/flower/pull/2787), [#2852](https://github.com/adap/flower/pull/2852)" -", [#2672](https://github.com/adap/flower/pull/2672), [#2759](https://github." -"com/adap/flower/pull/2759))" - -#: ../../source/ref-changelog.md:148 +"[#2847](https://github.com/adap/flower/pull/2847), " +"[#2877](https://github.com/adap/flower/pull/2877), " +"[#2690](https://github.com/adap/flower/pull/2690), " +"[#2889](https://github.com/adap/flower/pull/2889), " +"[#2874](https://github.com/adap/flower/pull/2874), " +"[#2819](https://github.com/adap/flower/pull/2819), " +"[#2689](https://github.com/adap/flower/pull/2689), " +"[#2457](https://github.com/adap/flower/pull/2457), " +"[#2870](https://github.com/adap/flower/pull/2870), " +"[#2669](https://github.com/adap/flower/pull/2669), " +"[#2876](https://github.com/adap/flower/pull/2876), " +"[#2885](https://github.com/adap/flower/pull/2885), " +"[#2858](https://github.com/adap/flower/pull/2858), " +"[#2867](https://github.com/adap/flower/pull/2867), " +"[#2351](https://github.com/adap/flower/pull/2351), " +"[#2886](https://github.com/adap/flower/pull/2886), " +"[#2860](https://github.com/adap/flower/pull/2860), " +"[#2828](https://github.com/adap/flower/pull/2828), " +"[#2869](https://github.com/adap/flower/pull/2869), " +"[#2875](https://github.com/adap/flower/pull/2875), " +"[#2733](https://github.com/adap/flower/pull/2733), " +"[#2488](https://github.com/adap/flower/pull/2488), " +"[#2646](https://github.com/adap/flower/pull/2646), " +"[#2879](https://github.com/adap/flower/pull/2879), " +"[#2821](https://github.com/adap/flower/pull/2821), " +"[#2855](https://github.com/adap/flower/pull/2855), " +"[#2800](https://github.com/adap/flower/pull/2800), " +"[#2807](https://github.com/adap/flower/pull/2807), " +"[#2801](https://github.com/adap/flower/pull/2801), " +"[#2804](https://github.com/adap/flower/pull/2804), " +"[#2851](https://github.com/adap/flower/pull/2851), " +"[#2787](https://github.com/adap/flower/pull/2787), " +"[#2852](https://github.com/adap/flower/pull/2852), " +"[#2672](https://github.com/adap/flower/pull/2672), " +"[#2759](https://github.com/adap/flower/pull/2759))" + +#: ../../source/ref-changelog.md:240 #, fuzzy msgid "" "**Deprecate** `start_numpy_client` " @@ -17605,7 +18359,7 @@ msgstr "" "TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " "[#2508](https://github.com/adap/flower/pull/2508))" -#: ../../source/ref-changelog.md:150 +#: ../../source/ref-changelog.md:242 #, fuzzy msgid "" "Until now, clients of type `NumPyClient` needed to be started via " @@ -17616,29 +18370,27 @@ msgid "" "object to `start_client`. The examples and the documentation have been " "updated accordingly." msgstr "" -"到目前为止,\"NumPyClient \"类型的客户端需要通过 \"start_numpy_client \"启动" -"。为了整合框架 API,我们引入了一些变化,现在所有客户端类型都应通过 " -"`start_client` 启动。要继续使用 `NumPyClient` 客户端,只需首先调用 `." -"to_client()` 方法,然后将返回的 `Client` 对象传递给 " +"到目前为止,\"NumPyClient \"类型的客户端需要通过 \"start_numpy_client \"启动。为了整合框架 " +"API,我们引入了一些变化,现在所有客户端类型都应通过 `start_client` 启动。要继续使用 `NumPyClient` " +"客户端,只需首先调用 `.to_client()` 方法,然后将返回的 `Client` 对象传递给 " "`start_client`。示例和文档已相应更新。" -#: ../../source/ref-changelog.md:152 +#: ../../source/ref-changelog.md:244 #, fuzzy msgid "" "**Deprecate legacy DP wrappers** " "([#2749](https://github.com/adap/flower/pull/2749))" msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:154 +#: ../../source/ref-changelog.md:246 #, fuzzy msgid "" "Legacy DP wrapper classes are deprecated, but still functional. This is " "in preparation for an all-new pluggable version of differential privacy " "support in Flower." -msgstr "传统的 DP 封装类已废弃,但仍可正常使用。这是为 Flower " -"中的全新可插拔差分隐私支持版本做准备。" +msgstr "传统的 DP 封装类已废弃,但仍可正常使用。这是为 Flower 中的全新可插拔差分隐私支持版本做准备。" -#: ../../source/ref-changelog.md:156 +#: ../../source/ref-changelog.md:248 #, fuzzy msgid "" "**Make optional arg** `--callable` **in** `flower-client` **a required " @@ -17647,7 +18399,7 @@ msgstr "" "**从** `start_client` 中移除** `rest` **实验参数 " "([#2324](https://github.com/adap/flower/pull/2324))" -#: ../../source/ref-changelog.md:158 +#: ../../source/ref-changelog.md:250 #, fuzzy msgid "" "**Rename** `certificates` **to** `root_certificates` **in** `Driver` " @@ -17656,7 +18408,7 @@ msgstr "" "**重新命名** `rnd` ** to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:160 +#: ../../source/ref-changelog.md:252 #, fuzzy msgid "" "**Drop experimental** `Task` **fields** " @@ -17666,7 +18418,7 @@ msgstr "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " "[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:162 +#: ../../source/ref-changelog.md:254 #, fuzzy msgid "" "Experimental fields `sa`, `legacy_server_message` and " @@ -17676,29 +18428,29 @@ msgstr "" "从 `Task` 消息中删除了试验性字段 `sa`、 `legacy_server_message` 和 " "`legacy_client_message`。删除的字段已被新的 `RecordSet` 抽象所取代。" -#: ../../source/ref-changelog.md:164 +#: ../../source/ref-changelog.md:256 #, fuzzy msgid "" "**Retire MXNet examples** " "([#2724](https://github.com/adap/flower/pull/2724))" msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:166 +#: ../../source/ref-changelog.md:258 #, fuzzy msgid "" "The development of the MXNet fremework has ended and the project is now " "[archived on GitHub](https://github.com/apache/mxnet). Existing MXNet " "examples won't receive updates." msgstr "" -"MXNet fremework 的开发工作已经结束,该项目现已[归档于 GitHub](https://github." -"com/apache/mxnet)。现有的 MXNet 示例不会收到更新。" +"MXNet fremework 的开发工作已经结束,该项目现已[归档于 " +"GitHub](https://github.com/apache/mxnet)。现有的 MXNet 示例不会收到更新。" -#: ../../source/ref-changelog.md:168 +#: ../../source/ref-changelog.md:260 #, fuzzy msgid "v1.6.0 (2023-11-28)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:174 +#: ../../source/ref-changelog.md:266 #, fuzzy msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " @@ -17707,15 +18459,15 @@ msgid "" " `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " "`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " "`cnxdeveloper`, `k3nfalt` " -msgstr "" -"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, `" -"Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel Mota`" -", `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, `Navin " -"Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " -"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " -"`k3nfalt` " +msgstr "" +"`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " +"`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," +" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " +"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " +"`cnxdeveloper`, `k3nfalt` " -#: ../../source/ref-changelog.md:178 +#: ../../source/ref-changelog.md:270 msgid "" "**Add experimental support for Python 3.12** " "([#2565](https://github.com/adap/flower/pull/2565))" @@ -17723,7 +18475,7 @@ msgstr "" "** 增加对 Python 3.12 的实验支持** " "([#2565](https://github.com/adap/flower/pull/2565))" -#: ../../source/ref-changelog.md:180 +#: ../../source/ref-changelog.md:272 #, fuzzy msgid "" "**Add new XGBoost examples** " @@ -17742,23 +18494,23 @@ msgstr "" "[#1551](https://github.com/adap/flower/pull/1551), " "[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:182 +#: ../../source/ref-changelog.md:274 #, fuzzy msgid "" "We have added a new `xgboost-quickstart` example alongside a new " "`xgboost-comprehensive` example that goes more in-depth." msgstr "" -"我们添加了一个新的 \"xgboost-quickstart \"示例和一个新的 \"xgboost-" -"comprehensive \"示例,后者更加深入。" +"我们添加了一个新的 \"xgboost-quickstart \"示例和一个新的 \"xgboost-comprehensive " +"\"示例,后者更加深入。" -#: ../../source/ref-changelog.md:184 +#: ../../source/ref-changelog.md:276 #, fuzzy msgid "" "**Add Vertical FL example** " "([#2598](https://github.com/adap/flower/pull/2598))" msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:186 +#: ../../source/ref-changelog.md:278 #, fuzzy msgid "" "We had many questions about Vertical Federated Learning using Flower, so " @@ -17766,17 +18518,17 @@ msgid "" "dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " "tutorial (in the README)." msgstr "" -"我们收到了许多关于使用 Flower 进行垂直联合学习的问题,因此我们决定在 [" -"Titanic 数据集](https://www.kaggle.com/competitions/titanic/data) " -"上添加一个简单的示例,并附上教程(在 README 中)。" +"我们收到了许多关于使用 Flower 进行垂直联合学习的问题,因此我们决定在 [Titanic " +"数据集](https://www.kaggle.com/competitions/titanic/data) 上添加一个简单的示例,并附上教程(在" +" README 中)。" -#: ../../source/ref-changelog.md:188 +#: ../../source/ref-changelog.md:280 msgid "" "**Support custom** `ClientManager` **in** `start_driver()` " "([#2292](https://github.com/adap/flower/pull/2292))" msgstr "**在***`start_driver()`中支持自定义***`ClientManager([#2292](https://github.com/adap/flower/pull/2292))" -#: ../../source/ref-changelog.md:190 +#: ../../source/ref-changelog.md:282 msgid "" "**Update REST API to support create and delete nodes** " "([#2283](https://github.com/adap/flower/pull/2283))" @@ -17784,7 +18536,7 @@ msgstr "" "**更新 REST API 以支持创建和删除节点** " "([#2283](https://github.com/adap/flower/pull/2283))" -#: ../../source/ref-changelog.md:192 +#: ../../source/ref-changelog.md:284 #, fuzzy msgid "" "**Update the Android SDK** " @@ -17793,12 +18545,12 @@ msgstr "" "**介绍Flower Android SDK** " "([#2131](https://github.com/adap/flower/pull/2131))" -#: ../../source/ref-changelog.md:194 +#: ../../source/ref-changelog.md:286 #, fuzzy msgid "Add gRPC request-response capability to the Android SDK." msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" -#: ../../source/ref-changelog.md:196 +#: ../../source/ref-changelog.md:288 #, fuzzy msgid "" "**Update the C++ SDK** " @@ -17812,11 +18564,11 @@ msgstr "" "[#2523](https://github.com/adap/flower/pull/2523), " "[#2522](https://github.com/adap/flower/pull/2522))" -#: ../../source/ref-changelog.md:198 +#: ../../source/ref-changelog.md:290 msgid "Add gRPC request-response capability to the C++ SDK." msgstr "为 C++ SDK 添加 gRPC 请求-响应功能。" -#: ../../source/ref-changelog.md:200 +#: ../../source/ref-changelog.md:292 #, fuzzy msgid "" "**Make HTTPS the new default** " @@ -17826,7 +18578,7 @@ msgstr "" "Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " "[#2400](https://github.com/adap/flower/pull/2400)" -#: ../../source/ref-changelog.md:202 +#: ../../source/ref-changelog.md:294 #, fuzzy msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " @@ -17836,12 +18588,11 @@ msgid "" "an HTTPS-enabled server or requires opt-out via passing `--insecure` to " "enable insecure HTTP connections." msgstr "" -"Flower 默认使用 HTTPS。新的 \"flower-server \"需要通过\"--证书\"," -"但用户可以启用\"--不安全 \"来使用 HTTP 进行原型开发。这同样适用于 `flower-" -"client`,它可以使用用户提供的凭证或 gRPC 绑定证书连接到支持 HTTPS 的服务器," -"也可以通过传递 `--insecure`来启用不安全的 HTTP 连接。" +"Flower 默认使用 HTTPS。新的 \"flower-server \"需要通过\"--证书\",但用户可以启用\"--不安全 \"来使用 " +"HTTP 进行原型开发。这同样适用于 `flower-client`,它可以使用用户提供的凭证或 gRPC 绑定证书连接到支持 HTTPS " +"的服务器,也可以通过传递 `--insecure`来启用不安全的 HTTP 连接。" -#: ../../source/ref-changelog.md:204 +#: ../../source/ref-changelog.md:296 #, fuzzy msgid "" "For backward compatibility, `start_client()` and `start_numpy_client()` " @@ -17849,10 +18600,9 @@ msgid "" "insecure connections will require user opt-in by passing `insecure=True`." msgstr "" "为了向后兼容,`start_client()` 和 `start_numpy_client()` " -"默认仍以不安全模式启动。在未来的版本中,不安全连接将需要用户通过传递 " -"`insecure=True` 进行选择。" +"默认仍以不安全模式启动。在未来的版本中,不安全连接将需要用户通过传递 `insecure=True` 进行选择。" -#: ../../source/ref-changelog.md:206 +#: ../../source/ref-changelog.md:298 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " "[#2390](https://github.com/adap/flower/pull/2390), " @@ -17862,7 +18612,7 @@ msgstr "" "[#2390](https://github.com/adap/flower/pull/2390), " "[#2493](https://github.com/adap/flower/pull/2493))" -#: ../../source/ref-changelog.md:208 +#: ../../source/ref-changelog.md:300 #, fuzzy msgid "" "Using the `client_fn`, Flower clients can interchangeably run as " @@ -17874,7 +18624,7 @@ msgstr "" "使用 `client_fn`,Flower 客户端可以作为独立进程(即通过 `start_client`)或在模拟中(即通过 " "`start_simulation`)交替运行,而无需更改客户端类的定义和实例化方式。调用 `start_numpy_client` 现已过时。" -#: ../../source/ref-changelog.md:210 +#: ../../source/ref-changelog.md:302 msgid "" "**Add new** `Bulyan` **strategy** " "([#1817](https://github.com/adap/flower/pull/1817), " @@ -17884,20 +18634,20 @@ msgstr "" "\"**策略**([#1817](https://github.com/adap/flower/pull/1817), " "[#1891](https://github.com/adap/flower/pull/1891)" -#: ../../source/ref-changelog.md:212 +#: ../../source/ref-changelog.md:304 msgid "" "The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " "2018](https://arxiv.org/abs/1802.07927)" msgstr "新的 \"Bulyan\"策略通过[El Mhamdi 等人,2018](https://arxiv.org/abs/1802.07927)实现" -#: ../../source/ref-changelog.md:214 +#: ../../source/ref-changelog.md:306 #, fuzzy msgid "" "**Add new** `XGB Bagging` **strategy** " "([#2611](https://github.com/adap/flower/pull/2611))" msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:216 ../../source/ref-changelog.md:218 +#: ../../source/ref-changelog.md:308 ../../source/ref-changelog.md:310 #, fuzzy msgid "" "**Introduce `WorkloadState`** " @@ -17907,7 +18657,7 @@ msgstr "" "**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822)" -#: ../../source/ref-changelog.md:222 +#: ../../source/ref-changelog.md:314 msgid "" "FedProx ([#2210](https://github.com/adap/flower/pull/2210), " "[#2286](https://github.com/adap/flower/pull/2286), " @@ -17917,7 +18667,7 @@ msgstr "" "[#2286](https://github.com/adap/flower/pull/2286), " "[#2509](https://github.com/adap/flower/pull/2509))" -#: ../../source/ref-changelog.md:224 +#: ../../source/ref-changelog.md:316 msgid "" "Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " "[#2400](https://github.com/adap/flower/pull/2400))" @@ -17925,7 +18675,7 @@ msgstr "" "Baselines文档([#2290](https://github.com/adap/flower/pull/2290), " "[#2400](https://github.com/adap/flower/pull/2400)" -#: ../../source/ref-changelog.md:226 +#: ../../source/ref-changelog.md:318 msgid "" "FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " "[#2507](https://github.com/adap/flower/pull/2507))" @@ -17933,7 +18683,7 @@ msgstr "" "FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " "[#2507](https://github.com/adap/flower/pull/2507))" -#: ../../source/ref-changelog.md:228 +#: ../../source/ref-changelog.md:320 msgid "" "TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " "[#2508](https://github.com/adap/flower/pull/2508))" @@ -17941,35 +18691,35 @@ msgstr "" "TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " "[#2508](https://github.com/adap/flower/pull/2508))" -#: ../../source/ref-changelog.md:230 +#: ../../source/ref-changelog.md:322 msgid "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" msgstr "FedMeta [#2438](https://github.com/adap/flower/pull/2438)" -#: ../../source/ref-changelog.md:232 +#: ../../source/ref-changelog.md:324 msgid "FjORD [#2431](https://github.com/adap/flower/pull/2431)" msgstr "FjORD [#2431](https://github.com/adap/flower/pull/2431)" -#: ../../source/ref-changelog.md:234 +#: ../../source/ref-changelog.md:326 msgid "MOON [#2421](https://github.com/adap/flower/pull/2421)" msgstr "MOON [#2421](https://github.com/adap/flower/pull/2421)" -#: ../../source/ref-changelog.md:236 +#: ../../source/ref-changelog.md:328 msgid "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" msgstr "DepthFL [#2295](https://github.com/adap/flower/pull/2295)" -#: ../../source/ref-changelog.md:238 +#: ../../source/ref-changelog.md:330 msgid "FedPer [#2266](https://github.com/adap/flower/pull/2266)" msgstr "FedPer [#2266](https://github.com/adap/flower/pull/2266)" -#: ../../source/ref-changelog.md:240 +#: ../../source/ref-changelog.md:332 msgid "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" msgstr "FedWav2vec [#2551](https://github.com/adap/flower/pull/2551)" -#: ../../source/ref-changelog.md:242 +#: ../../source/ref-changelog.md:334 msgid "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" msgstr "niid-Bench [#2428](https://github.com/adap/flower/pull/2428)" -#: ../../source/ref-changelog.md:244 +#: ../../source/ref-changelog.md:336 msgid "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " "[#2615](https://github.com/adap/flower/pull/2615))" @@ -17977,7 +18727,7 @@ msgstr "" "FedBN ([#2608](https://github.com/adap/flower/pull/2608), " "[#2615](https://github.com/adap/flower/pull/2615))" -#: ../../source/ref-changelog.md:246 +#: ../../source/ref-changelog.md:338 #, fuzzy msgid "" "**General updates to Flower Examples** " @@ -17992,7 +18742,7 @@ msgstr "" "[#2523](https://github.com/adap/flower/pull/2523), " "[#2522](https://github.com/adap/flower/pull/2522))" -#: ../../source/ref-changelog.md:248 +#: ../../source/ref-changelog.md:340 #, fuzzy msgid "" "**General updates to Flower Baselines** " @@ -18020,7 +18770,7 @@ msgstr "" "[#2446](https://github.com/adap/flower/pull/2446) " "[#2561](https://github.com/adap/flower/pull/2561))" -#: ../../source/ref-changelog.md:250 +#: ../../source/ref-changelog.md:342 #, fuzzy msgid "" "**General updates to the simulation engine** " @@ -18033,7 +18783,7 @@ msgstr "" "[#2447](https://github.com/adap/flower/pull/2447), " "[#2448](https://github.com/adap/flower/pull/2448))" -#: ../../source/ref-changelog.md:252 +#: ../../source/ref-changelog.md:344 #, fuzzy msgid "" "**General updates to Flower SDKs** " @@ -18052,7 +18802,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475)))" -#: ../../source/ref-changelog.md:254 +#: ../../source/ref-changelog.md:346 #, fuzzy msgid "" "**General improvements** " @@ -18085,32 +18835,40 @@ msgid "" "[#2596](https://github.com/adap/flower/pull/2596))" msgstr "" "**一般改进** ([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." -"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/pull/2316)" -", [#2317](https://github.com/adap/flower/pull/2317), [#2349](https://github." -"com/adap/flower/pull/2349), [#2360](https://github.com/adap/flower/pull/2360)" -", [#2402](https://github.com/adap/flower/pull/2402), [#2446](https://github." -"com/adap/flower/pull/2446), [#2561](https://github.com/adap/flower/pull/2561)" -", [#2273](https://github.com/adap/flower/pull/2273), [#2267](https://github." -"com/adap/flower/pull/2267), [#2274](https://github.com/adap/flower/pull/2274)" -", [#2275](https://github.com/adap/flower/pull/2275), [#2432](https://github." -"com/adap/flower/pull/2432), [#2251](https://github.com/adap/flower/pull/2251)" -", [#2321](https://github.com/adap/flower/pull/2321), [#1936](https://github." -"com/adap/flower/pull/1936), [#2408](https://github.com/adap/flower/pull/2408)" -", [#2413](https://github.com/adap/flower/pull/2413), [#2401](https://github." -"com/adap/flower/pull/2401), [#2531](https://github.com/adap/flower/pull/2531)" -", [#2534](https://github.com/adap/flower/pull/2534), [#2535](https://github." -"com/adap/flower/pull/2535), [#2521](https://github.com/adap/flower/pull/2521)" -", [#2553](https://github.com/adap/flower/pull/2553), [#2596](https://github." -"com/adap/flower/pull/2596))" - -#: ../../source/ref-changelog.md:256 ../../source/ref-changelog.md:346 -#: ../../source/ref-changelog.md:410 ../../source/ref-changelog.md:464 -#: ../../source/ref-changelog.md:531 +"[#2310](https://github.com/adap/flower/pull/2310), " +"[#2313](https://github.com/adap/flower/pull/2313), " +"[#2316](https://github.com/adap/flower/pull/2316), " +"[#2317](https://github.com/adap/flower/pull/2317), " +"[#2349](https://github.com/adap/flower/pull/2349), " +"[#2360](https://github.com/adap/flower/pull/2360), " +"[#2402](https://github.com/adap/flower/pull/2402), " +"[#2446](https://github.com/adap/flower/pull/2446), " +"[#2561](https://github.com/adap/flower/pull/2561), " +"[#2273](https://github.com/adap/flower/pull/2273), " +"[#2267](https://github.com/adap/flower/pull/2267), " +"[#2274](https://github.com/adap/flower/pull/2274), " +"[#2275](https://github.com/adap/flower/pull/2275), " +"[#2432](https://github.com/adap/flower/pull/2432), " +"[#2251](https://github.com/adap/flower/pull/2251), " +"[#2321](https://github.com/adap/flower/pull/2321), " +"[#1936](https://github.com/adap/flower/pull/1936), " +"[#2408](https://github.com/adap/flower/pull/2408), " +"[#2413](https://github.com/adap/flower/pull/2413), " +"[#2401](https://github.com/adap/flower/pull/2401), " +"[#2531](https://github.com/adap/flower/pull/2531), " +"[#2534](https://github.com/adap/flower/pull/2534), " +"[#2535](https://github.com/adap/flower/pull/2535), " +"[#2521](https://github.com/adap/flower/pull/2521), " +"[#2553](https://github.com/adap/flower/pull/2553), " +"[#2596](https://github.com/adap/flower/pull/2596))" + +#: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:502 ../../source/ref-changelog.md:556 +#: ../../source/ref-changelog.md:623 msgid "Flower received many improvements under the hood, too many to list here." msgstr "Flower 进行了许多改进,这里就不一一列举了。" -#: ../../source/ref-changelog.md:260 +#: ../../source/ref-changelog.md:352 msgid "" "**Remove support for Python 3.7** " "([#2280](https://github.com/adap/flower/pull/2280), " @@ -18128,13 +18886,13 @@ msgstr "" "[#2355](https://github.com/adap/flower/pull/2355), " "[#2356](https://github.com/adap/flower/pull/2356))" -#: ../../source/ref-changelog.md:262 +#: ../../source/ref-changelog.md:354 msgid "" "Python 3.7 support was deprecated in Flower 1.5, and this release removes" " support. Flower now requires Python 3.8." msgstr "在 Flower 1.5 中,Python 3.7 支持已被弃用,本版本将删除该支持。Flower 现在需要 Python 3.8。" -#: ../../source/ref-changelog.md:264 +#: ../../source/ref-changelog.md:356 msgid "" "**Remove experimental argument** `rest` **from** `start_client` " "([#2324](https://github.com/adap/flower/pull/2324))" @@ -18142,7 +18900,7 @@ msgstr "" "**从** `start_client` 中移除** `rest` **实验参数 " "([#2324](https://github.com/adap/flower/pull/2324))" -#: ../../source/ref-changelog.md:266 +#: ../../source/ref-changelog.md:358 msgid "" "The (still experimental) argument `rest` was removed from `start_client` " "and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " @@ -18151,11 +18909,11 @@ msgstr "" "删除了 `start_client` 和 `start_numpy_client` 中的参数 `rest`(仍属试验性质)。请使用 " "`transport=\"rest\"` 来选择使用试验性 REST API。" -#: ../../source/ref-changelog.md:268 +#: ../../source/ref-changelog.md:360 msgid "v1.5.0 (2023-08-31)" msgstr "v1.5.0 (2023-08-31)" -#: ../../source/ref-changelog.md:274 +#: ../../source/ref-changelog.md:366 msgid "" "`Adam Narozniak`, `Anass Anhari`, `Charles Beauville`, `Dana-Farber`, " "`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " @@ -18169,7 +18927,7 @@ msgstr "" "Topal`, `achiverram28`, `danielnugraha`, `eunchung`, `ruthgal` " -#: ../../source/ref-changelog.md:278 +#: ../../source/ref-changelog.md:370 msgid "" "**Introduce new simulation engine** " "([#1969](https://github.com/adap/flower/pull/1969), " @@ -18180,7 +18938,7 @@ msgstr "" "[#2221](https://github.com/adap/flower/pull/2221), " "[#2248](https://github.com/adap/flower/pull/2248))" -#: ../../source/ref-changelog.md:280 +#: ../../source/ref-changelog.md:372 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " "remains fully backwards compatible. It offers much improved stability and" @@ -18191,7 +18949,7 @@ msgstr "" "新的模拟引擎从头开始重新编写,但仍完全向后兼容。它的稳定性和内存处理能力大大提高,尤其是在使用 GPU 时。仿真可透明地适应不同的设置,以在仅 " "CPU、CPU+GPU、多 GPU 或多节点多 GPU 环境中扩展模拟。" -#: ../../source/ref-changelog.md:282 +#: ../../source/ref-changelog.md:374 msgid "" "Comprehensive documentation includes a new [how-to run " "simulations](https://flower.ai/docs/framework/how-to-run-" @@ -18208,7 +18966,7 @@ msgstr "" "tensorflow.html) notebooks, and a new [YouTube tutorial " "series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)。" -#: ../../source/ref-changelog.md:284 +#: ../../source/ref-changelog.md:376 msgid "" "**Restructure Flower Docs** " "([#1824](https://github.com/adap/flower/pull/1824), " @@ -18267,7 +19025,7 @@ msgstr "" "[#2243](https://github.com/adap/flower/pull/2243), " "[#2227](https://github.com/adap/flower/pull/2227))" -#: ../../source/ref-changelog.md:286 +#: ../../source/ref-changelog.md:378 #, fuzzy msgid "" "Much effort went into a completely restructured Flower docs experience. " @@ -18278,7 +19036,7 @@ msgstr "" "Flower 文档体验的全面重构耗费了大量精力。现在,[flower.ai/docs](flower.ai/docs)上的文档分为 Flower " "Framework、Flower Baselines、Flower Android SDK、Flower iOS SDK 和代码示例项目。" -#: ../../source/ref-changelog.md:288 +#: ../../source/ref-changelog.md:380 msgid "" "**Introduce Flower Swift SDK** " "([#1858](https://github.com/adap/flower/pull/1858), " @@ -18288,7 +19046,7 @@ msgstr "" "([#1858](https://github.com/adap/flower/pull/1858), " "[#1897](https://github.com/adap/flower/pull/1897))" -#: ../../source/ref-changelog.md:290 +#: ../../source/ref-changelog.md:382 msgid "" "This is the first preview release of the Flower Swift SDK. Flower support" " on iOS is improving, and alongside the Swift SDK and code example, there" @@ -18297,7 +19055,7 @@ msgstr "" "这是 Flower Swift SDK 的首个预览版。Flower 对 iOS 的支持正在不断改进,除了 Swift SDK " "和代码示例外,现在还有 iOS 快速入门教程。" -#: ../../source/ref-changelog.md:292 +#: ../../source/ref-changelog.md:384 msgid "" "**Introduce Flower Android SDK** " "([#2131](https://github.com/adap/flower/pull/2131))" @@ -18305,7 +19063,7 @@ msgstr "" "**介绍Flower Android SDK** " "([#2131](https://github.com/adap/flower/pull/2131))" -#: ../../source/ref-changelog.md:294 +#: ../../source/ref-changelog.md:386 msgid "" "This is the first preview release of the Flower Kotlin SDK. Flower " "support on Android is improving, and alongside the Kotlin SDK and code " @@ -18314,7 +19072,7 @@ msgstr "" "这是 Flower Kotlin SDK 的首个预览版。Flower 对 Android 的支持正在不断改进,除了 Kotlin SDK " "和代码示例,现在还有 Android 快速入门教程。" -#: ../../source/ref-changelog.md:296 +#: ../../source/ref-changelog.md:388 msgid "" "**Introduce new end-to-end testing infrastructure** " "([#1842](https://github.com/adap/flower/pull/1842), " @@ -18353,23 +19111,23 @@ msgstr "" "[#2137](https://github.com/adap/flower/pull/2137), " "[#2165](https://github.com/adap/flower/pull/2165))" -#: ../../source/ref-changelog.md:298 +#: ../../source/ref-changelog.md:390 msgid "" "A new testing infrastructure ensures that new changes stay compatible " "with existing framework integrations or strategies." msgstr "新的测试设施可确保新的变更与现有的框架集成或策略保持兼容。" -#: ../../source/ref-changelog.md:300 +#: ../../source/ref-changelog.md:392 msgid "**Deprecate Python 3.7**" msgstr "** 过时的 Python 3.7**" -#: ../../source/ref-changelog.md:302 +#: ../../source/ref-changelog.md:394 msgid "" "Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" " Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "由于 Python 3.7 已于 2023-06-27 弃用 (EOL),对 Python 3.7 的支持现已废弃,并将在即将发布的版本中移除。" -#: ../../source/ref-changelog.md:304 +#: ../../source/ref-changelog.md:396 msgid "" "**Add new** `FedTrimmedAvg` **strategy** " "([#1769](https://github.com/adap/flower/pull/1769), " @@ -18378,7 +19136,7 @@ msgstr "" "**添加新的**`FedTrimmedAvg`**策略**([#1769](https://github.com/adap/flower/pull/1769)," " [#1853](https://github.com/adap/flower/pull/1853)" -#: ../../source/ref-changelog.md:306 +#: ../../source/ref-changelog.md:398 msgid "" "The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " "2018](https://arxiv.org/abs/1803.01498)." @@ -18386,13 +19144,13 @@ msgstr "" "新的 \"FedTrimmedAvg \"策略实现了[Dong Yin, " "2018](https://arxiv.org/abs/1803.01498)的 \"Trimmed Mean\"。" -#: ../../source/ref-changelog.md:308 +#: ../../source/ref-changelog.md:400 msgid "" "**Introduce start_driver** " "([#1697](https://github.com/adap/flower/pull/1697))" msgstr "**引入 start_driver**([#1697](https://github.com/adap/flower/pull/1697))" -#: ../../source/ref-changelog.md:310 +#: ../../source/ref-changelog.md:402 msgid "" "In addition to `start_server` and using the raw Driver API, there is a " "new `start_driver` function that allows for running `start_server` " @@ -18404,7 +19162,7 @@ msgstr "" "`start_server` 脚本作为 Flower 驱动程序运行。请查看 `mt-pytorch` 代码示例,了解使用 " "`start_driver` 的工作示例。" -#: ../../source/ref-changelog.md:312 +#: ../../source/ref-changelog.md:404 msgid "" "**Add parameter aggregation to** `mt-pytorch` **code example** " "([#1785](https://github.com/adap/flower/pull/1785))" @@ -18412,7 +19170,7 @@ msgstr "" "为 `mt-pytorch` **代码示例**添加参数聚合 " "([#1785](https://github.com/adap/flower/pull/1785))" -#: ../../source/ref-changelog.md:314 +#: ../../source/ref-changelog.md:406 msgid "" "The `mt-pytorch` example shows how to aggregate parameters when writing a" " driver script. The included `driver.py` and `server.py` have been " @@ -18422,7 +19180,7 @@ msgstr "" "`mt-pytorch`示例展示了如何在编写驱动程序脚本时聚合参数。附带的 `driver.py` 和 `server.py` " "已经进行了调整,以演示构建服务器端逻辑的低级方法和高级方法。" -#: ../../source/ref-changelog.md:316 +#: ../../source/ref-changelog.md:408 msgid "" "**Migrate experimental REST API to Starlette** " "([2171](https://github.com/adap/flower/pull/2171))" @@ -18430,7 +19188,7 @@ msgstr "" "**将实验性 REST API 移植到 Starlette** " "([2171](https://github.com/adap/flower/pull/2171))" -#: ../../source/ref-changelog.md:318 +#: ../../source/ref-changelog.md:410 msgid "" "The (experimental) REST API used to be implemented in " "[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" @@ -18439,13 +19197,13 @@ msgstr "" "REST API(试验性)曾在 [FastAPI](https://fastapi.tiangolo.com/) 中实现,但现在已迁移到直接使用 " "[Starlette](https://www.starlette.io/) 。" -#: ../../source/ref-changelog.md:320 +#: ../../source/ref-changelog.md:412 msgid "" "Please note: The REST request-response API is still experimental and will" " likely change significantly over time." msgstr "请注意:REST 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:322 +#: ../../source/ref-changelog.md:414 msgid "" "**Introduce experimental gRPC request-response API** " "([#1867](https://github.com/adap/flower/pull/1867), " @@ -18455,7 +19213,7 @@ msgstr "" "([#1867](https://github.com/adap/flower/pull/1867), " "[#1901](https://github.com/adap/flower/pull/1901)" -#: ../../source/ref-changelog.md:324 +#: ../../source/ref-changelog.md:416 msgid "" "In addition to the existing gRPC API (based on bidirectional streaming) " "and the experimental REST API, there is now a new gRPC API that uses a " @@ -18464,13 +19222,13 @@ msgstr "" "除了现有的 gRPC 应用程序接口(基于双向流)和试验性 REST 应用程序接口外,现在还有一个新的 gRPC " "应用程序接口,它使用请求-响应模型与客户端节点通信。" -#: ../../source/ref-changelog.md:326 +#: ../../source/ref-changelog.md:418 msgid "" "Please note: The gRPC request-response API is still experimental and will" " likely change significantly over time." msgstr "请注意:gRPC 请求-响应 API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:328 +#: ../../source/ref-changelog.md:420 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " "`start_client(transport=\"rest\")` " @@ -18480,7 +19238,7 @@ msgstr "" "`start_client(rest=True)` " "([#1880](https://github.com/adap/flower/pull/1880))" -#: ../../source/ref-changelog.md:330 +#: ../../source/ref-changelog.md:422 msgid "" "The (experimental) `start_client` argument `rest` was deprecated in " "favour of a new argument `transport`. `start_client(transport=\"rest\")` " @@ -18491,13 +19249,13 @@ msgstr "" "已废弃(试验性的)`start_client`参数`rest`,改用新参数`transport`。`start_client(transport=\"rest\")`将产生与以前的`start_client(rest=True)`相同的行为。所有代码都应迁移到新参数" " `transport`。过时的参数 `rest` 将在今后的版本中删除。" -#: ../../source/ref-changelog.md:332 +#: ../../source/ref-changelog.md:424 msgid "" "**Add a new gRPC option** " "([#2197](https://github.com/adap/flower/pull/2197))" msgstr "** 添加一个新的 gRPC 选项**([#2197](https://github.com/adap/flower/pull/2197))" -#: ../../source/ref-changelog.md:334 +#: ../../source/ref-changelog.md:426 msgid "" "We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" " option set to 0 by default. This prevents the clients from sending " @@ -18506,17 +19264,17 @@ msgstr "" "现在我们启动一个 gRPC 服务器,并将 `grpc.keepalive_permit_without_calls` 选项默认设置为 " "0。这将防止客户端在没有未处理数据流时发送 keepalive pings。" -#: ../../source/ref-changelog.md:336 +#: ../../source/ref-changelog.md:428 msgid "" "**Improve example notebooks** " "([#2005](https://github.com/adap/flower/pull/2005))" msgstr "**改进示例笔记** ([#2005](https://github.com/adap/flower/pull/2005))" -#: ../../source/ref-changelog.md:338 +#: ../../source/ref-changelog.md:430 msgid "There's a new 30min Federated Learning PyTorch tutorial!" msgstr "有一个新的 30 分钟的联邦学习 PyTorch 教程!" -#: ../../source/ref-changelog.md:340 +#: ../../source/ref-changelog.md:432 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " "[#1873](https://github.com/adap/flower/pull/1873), " @@ -18542,7 +19300,7 @@ msgstr "" "[#2225](https://github.com/adap/flower/pull/2225), " "[#2183](https://github.com/adap/flower/pull/2183))" -#: ../../source/ref-changelog.md:342 +#: ../../source/ref-changelog.md:434 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " @@ -18554,7 +19312,7 @@ msgstr "" "TensorFlow 示例的 macOS 兼容性,以及模拟代码示例。一项重大升级是所有代码示例现在都有了 " "\"requirements.txt\"(除 \"pyproject.toml \"外)。" -#: ../../source/ref-changelog.md:344 +#: ../../source/ref-changelog.md:436 msgid "" "**General improvements** " "([#1872](https://github.com/adap/flower/pull/1872), " @@ -18571,11 +19329,11 @@ msgstr "" "[#1477](https://github.com/adap/flower/pull/1477), " "[#2171](https://github.com/adap/flower/pull/2171))" -#: ../../source/ref-changelog.md:352 +#: ../../source/ref-changelog.md:444 msgid "v1.4.0 (2023-04-21)" msgstr "v1.4.0 (2023-04-21)" -#: ../../source/ref-changelog.md:358 +#: ../../source/ref-changelog.md:450 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " @@ -18591,7 +19349,7 @@ msgstr "" "Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " "`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" -#: ../../source/ref-changelog.md:362 +#: ../../source/ref-changelog.md:454 msgid "" "**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " "example)** ([#1694](https://github.com/adap/flower/pull/1694), " @@ -18609,7 +19367,7 @@ msgstr "" "[#1763](https://github.com/adap/flower/pull/1763), " "[#1795](https://github.com/adap/flower/pull/1795))" -#: ../../source/ref-changelog.md:364 +#: ../../source/ref-changelog.md:456 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " "gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" @@ -18623,7 +19381,7 @@ msgstr "" "\"FedXgbNnAvg\"[策略](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)和一个[代码示例](https://github.com/adap/flower/tree/main/examples" "/xgboost-quickstart),演示如何在 XGBoost 项目中使用这个新策略。" -#: ../../source/ref-changelog.md:366 +#: ../../source/ref-changelog.md:458 msgid "" "**Introduce iOS SDK (preview)** " "([#1621](https://github.com/adap/flower/pull/1621), " @@ -18632,7 +19390,7 @@ msgstr "" "**介绍 iOS SDK(预览版)** ([#1621](https://github.com/adap/flower/pull/1621), " "[#1764](https://github.com/adap/flower/pull/1764))" -#: ../../source/ref-changelog.md:368 +#: ../../source/ref-changelog.md:460 msgid "" "This is a major update for anyone wanting to implement Federated Learning" " on iOS mobile devices. We now have a swift iOS SDK present under " @@ -18647,7 +19405,7 @@ msgstr "" " 下提供了一个迅捷的 iOS SDK,这将大大方便应用程序的创建过程。为了展示其使用情况,我们还更新了 [iOS " "示例](https://github.com/adap/flower/tree/main/examples/ios)!" -#: ../../source/ref-changelog.md:370 +#: ../../source/ref-changelog.md:462 msgid "" "**Introduce new \"What is Federated Learning?\" tutorial** " "([#1657](https://github.com/adap/flower/pull/1657), " @@ -18657,7 +19415,7 @@ msgstr "" "\"什么是联邦学习?\"教程**([#1657](https://github.com/adap/flower/pull/1657), " "[#1721](https://github.com/adap/flower/pull/1721)" -#: ../../source/ref-changelog.md:372 +#: ../../source/ref-changelog.md:464 msgid "" "A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" "what-is-federated-learning.html) in our documentation explains the basics" @@ -18669,7 +19427,7 @@ msgstr "" "federated-learning.html),解释了联邦学习的基础知识。它让任何不熟悉联邦学习的人都能开始 Flower " "之旅。请转发给对联邦学习感兴趣的人!" -#: ../../source/ref-changelog.md:374 +#: ../../source/ref-changelog.md:466 msgid "" "**Introduce new Flower Baseline: FedProx MNIST** " "([#1513](https://github.com/adap/flower/pull/1513), " @@ -18683,7 +19441,7 @@ msgstr "" "[#1681](https://github.com/adap/flower/pull/1681), " "[#1679](https://github.com/adap/flower/pull/1679)" -#: ../../source/ref-changelog.md:376 +#: ../../source/ref-changelog.md:468 msgid "" "This new baseline replicates the MNIST+CNN task from the paper [Federated" " Optimization in Heterogeneous Networks (Li et al., " @@ -18694,7 +19452,7 @@ msgstr "" "al., 2018)](https://arxiv.org/abs/1812.06127)中的 MNIST+CNN 任务。它使用 " "\"FedProx \"策略,旨在使收敛在异构环境中更加稳健。" -#: ../../source/ref-changelog.md:378 +#: ../../source/ref-changelog.md:470 msgid "" "**Introduce new Flower Baseline: FedAvg FEMNIST** " "([#1655](https://github.com/adap/flower/pull/1655))" @@ -18702,7 +19460,7 @@ msgstr "" "**引入新的 Flower Baseline: FedAvg FEMNIST** " "([#1655](https://github.com/adap/flower/pull/1655))" -#: ../../source/ref-changelog.md:380 +#: ../../source/ref-changelog.md:472 msgid "" "This new baseline replicates an experiment evaluating the performance of " "the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " @@ -18712,7 +19470,7 @@ msgstr "" "这一新Baseline复现了论文[LEAF: A Benchmark for Federated Settings(Caldas 等人,2018 " "年)](https://arxiv.org/abs/1812.01097)中评估 FedAvg 算法在 FEMNIST 数据集上性能的实验。" -#: ../../source/ref-changelog.md:382 +#: ../../source/ref-changelog.md:474 msgid "" "**Introduce (experimental) REST API** " "([#1594](https://github.com/adap/flower/pull/1594), " @@ -18731,20 +19489,20 @@ msgstr "" "[#1770](https://github.com/adap/flower/pull/1770), " "[#1733](https://github.com/adap/flower/pull/1733))" -#: ../../source/ref-changelog.md:384 +#: ../../source/ref-changelog.md:476 msgid "" "A new REST API has been introduced as an alternative to the gRPC-based " "communication stack. In this initial version, the REST API only supports " "anonymous clients." msgstr "作为基于 gRPC 的通信栈的替代方案,我们引入了新的 REST API。在初始版本中,REST API 仅支持匿名客户端。" -#: ../../source/ref-changelog.md:386 +#: ../../source/ref-changelog.md:478 msgid "" "Please note: The REST API is still experimental and will likely change " "significantly over time." msgstr "请注意:REST API 仍处于试验阶段,随着时间的推移可能会发生重大变化。" -#: ../../source/ref-changelog.md:388 +#: ../../source/ref-changelog.md:480 msgid "" "**Improve the (experimental) Driver API** " "([#1663](https://github.com/adap/flower/pull/1663), " @@ -18767,7 +19525,7 @@ msgstr "" "[#1662](https://github.com/adap/flower/pull/1662), " "[#1794](https://github.com/adap/flower/pull/1794))" -#: ../../source/ref-changelog.md:390 +#: ../../source/ref-changelog.md:482 msgid "" "The Driver API is still an experimental feature, but this release " "introduces some major upgrades. One of the main improvements is the " @@ -18780,20 +19538,20 @@ msgstr "" "数据库,将服务器状态存储在磁盘上(而不是内存中)。另一项改进是,已交付的任务(指令或结果)现在将被删除。这大大提高了长期运行的 Flower " "服务器的内存效率。" -#: ../../source/ref-changelog.md:392 +#: ../../source/ref-changelog.md:484 msgid "" "**Fix spilling issues related to Ray during simulations** " "([#1698](https://github.com/adap/flower/pull/1698))" msgstr "**修复模拟过程中与Ray有关的溢出问题** ([#1698](https://github.com/adap/flower/pull/1698))" -#: ../../source/ref-changelog.md:394 +#: ../../source/ref-changelog.md:486 msgid "" "While running long simulations, `ray` was sometimes spilling huge amounts" " of data that would make the training unable to continue. This is now " "fixed! 🎉" msgstr "在运行长时间模拟时,`ray` 有时会溢出大量数据,导致训练无法继续。现在这个问题已经解决!🎉" -#: ../../source/ref-changelog.md:396 +#: ../../source/ref-changelog.md:488 msgid "" "**Add new example using** `TabNet` **and Flower** " "([#1725](https://github.com/adap/flower/pull/1725))" @@ -18801,7 +19559,7 @@ msgstr "" "** 添加使用** `TabNet` ** 的新示例** " "([#1725](https://github.com/adap/flower/pull/1725))" -#: ../../source/ref-changelog.md:398 +#: ../../source/ref-changelog.md:490 msgid "" "TabNet is a powerful and flexible framework for training machine learning" " models on tabular data. We now have a federated example using Flower: " @@ -18812,19 +19570,19 @@ msgstr "" "tabnet](https://github.com/adap/flower/tree/main/examples/quickstart-" "tabnet)。" -#: ../../source/ref-changelog.md:400 +#: ../../source/ref-changelog.md:492 msgid "" "**Add new how-to guide for monitoring simulations** " "([#1649](https://github.com/adap/flower/pull/1649))" msgstr "** 添加新的模拟监控指南** ([#1649](https://github.com/adap/flower/pull/1649))" -#: ../../source/ref-changelog.md:402 +#: ../../source/ref-changelog.md:494 msgid "" "We now have a documentation guide to help users monitor their performance" " during simulations." msgstr "我们现在有一份文档指南,可帮助用户在模拟过程中监控其性能。" -#: ../../source/ref-changelog.md:404 +#: ../../source/ref-changelog.md:496 msgid "" "**Add training metrics to** `History` **object during simulations** " "([#1696](https://github.com/adap/flower/pull/1696))" @@ -18832,7 +19590,7 @@ msgstr "" "**在模拟过程中为***`历史`***对象添加训练指标*** " "([#1696](https://github.com/adap/flower/pull/1696))" -#: ../../source/ref-changelog.md:406 +#: ../../source/ref-changelog.md:498 msgid "" "The `fit_metrics_aggregation_fn` can be used to aggregate training " "metrics, but previous releases did not save the results in the `History` " @@ -18841,7 +19599,7 @@ msgstr "" "`fit_metrics_aggregation_fn`可用于汇总训练指标,但以前的版本不会将结果保存在 \"History " "\"对象中。现在可以了!" -#: ../../source/ref-changelog.md:408 +#: ../../source/ref-changelog.md:500 msgid "" "**General improvements** " "([#1659](https://github.com/adap/flower/pull/1659), " @@ -18944,11 +19702,11 @@ msgstr "" "[#1804](https://github.com/adap/flower/pull/1804), " "[#1805](https://github.com/adap/flower/pull/1805))" -#: ../../source/ref-changelog.md:416 +#: ../../source/ref-changelog.md:508 msgid "v1.3.0 (2023-02-06)" msgstr "v1.3.0 (2023-02-06)" -#: ../../source/ref-changelog.md:422 +#: ../../source/ref-changelog.md:514 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" @@ -18956,7 +19714,7 @@ msgstr "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " "`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" -#: ../../source/ref-changelog.md:426 +#: ../../source/ref-changelog.md:518 msgid "" "**Add support for** `workload_id` **and** `group_id` **in Driver API** " "([#1595](https://github.com/adap/flower/pull/1595))" @@ -18964,7 +19722,7 @@ msgstr "" "**在驱动程序应用程序接口中添加对** `workload_id` **和** `group_id` **的支持** " "([#1595](https://github.com/adap/flower/pull/1595))" -#: ../../source/ref-changelog.md:428 +#: ../../source/ref-changelog.md:520 msgid "" "The (experimental) Driver API now supports a `workload_id` that can be " "used to identify which workload a task belongs to. It also supports a new" @@ -18976,7 +19734,7 @@ msgstr "" "`group_id`,例如,可用于指示当前的训练轮次。通过 `workload_id` 和 `group_id` " "客户端节点可以决定是否要处理某个任务。" -#: ../../source/ref-changelog.md:430 +#: ../../source/ref-changelog.md:522 msgid "" "**Make Driver API and Fleet API address configurable** " "([#1637](https://github.com/adap/flower/pull/1637))" @@ -18984,7 +19742,7 @@ msgstr "" "**使Driver API 和Fleet " "API地址可配置**([#1637](https://github.com/adap/flower/pull/1637))" -#: ../../source/ref-changelog.md:432 +#: ../../source/ref-changelog.md:524 msgid "" "The (experimental) long-running Flower server (Driver API and Fleet API) " "can now configure the server address of both Driver API (via `--driver-" @@ -18993,7 +19751,7 @@ msgstr "" "长期运行的 Flower 服务器(Driver API 和 Fleet API)现在可以在启动时配置 Driver API(通过 " "`--driver-api-address`)和 Fleet API(通过 `-fleet-api-address`)的服务器地址:" -#: ../../source/ref-changelog.md:434 +#: ../../source/ref-changelog.md:526 #, fuzzy msgid "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " @@ -19002,11 +19760,11 @@ msgstr "" "`flower-server --driver-api-address \"0.0.0.0:8081\" --fleet-api-address " "\"0.0.0.0:8086\"`" -#: ../../source/ref-changelog.md:436 +#: ../../source/ref-changelog.md:528 msgid "Both IPv4 and IPv6 addresses are supported." msgstr "支持 IPv4 和 IPv6 地址。" -#: ../../source/ref-changelog.md:438 +#: ../../source/ref-changelog.md:530 msgid "" "**Add new example of Federated Learning using fastai and Flower** " "([#1598](https://github.com/adap/flower/pull/1598))" @@ -19014,7 +19772,7 @@ msgstr "" "** 添加使用 fastai 和 Flower 进行联邦学习的新示例** " "([#1598](https://github.com/adap/flower/pull/1598))" -#: ../../source/ref-changelog.md:440 +#: ../../source/ref-changelog.md:532 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " @@ -19026,7 +19784,7 @@ msgstr "" "fastai](https://github.com/adap/flower/tree/main/examples/quickstart-" "fastai)。" -#: ../../source/ref-changelog.md:442 +#: ../../source/ref-changelog.md:534 msgid "" "**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" " versions of Android** " @@ -19035,7 +19793,7 @@ msgstr "" "**使安卓示例兼容** `flwr >= 1.0.0` **和最新版本的安卓** " "([#1603](https://github.com/adap/flower/pull/1603))" -#: ../../source/ref-changelog.md:444 +#: ../../source/ref-changelog.md:536 msgid "" "The Android code example has received a substantial update: the project " "is compatible with Flower 1.0 (and later), the UI received a full " @@ -19045,13 +19803,13 @@ msgstr "" "Android 代码示例已进行了大幅更新:项目兼容 Flower 1.0(及更高版本),用户界面已全面刷新,项目已更新为兼容较新的 Android" " 工具。" -#: ../../source/ref-changelog.md:446 +#: ../../source/ref-changelog.md:538 msgid "" "**Add new `FedProx` strategy** " "([#1619](https://github.com/adap/flower/pull/1619))" msgstr "**添加新的`FedProx`策略** ([#1619](https://github.com/adap/flower/pull/1619))" -#: ../../source/ref-changelog.md:448 +#: ../../source/ref-changelog.md:540 msgid "" "This " "[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" @@ -19065,25 +19823,25 @@ msgstr "" "该[策略](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)与[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)几乎相同,但可以帮助用户复现本[论文](https://arxiv.org/abs/1812.06127)中的描述。它的本质是添加一个名为" " `proximal_mu`的参数,使局部模型与全局模型正则化。" -#: ../../source/ref-changelog.md:450 +#: ../../source/ref-changelog.md:542 msgid "" "**Add new metrics to telemetry events** " "([#1640](https://github.com/adap/flower/pull/1640))" msgstr "**为遥测事件添加新指标**([#1640](https://github.com/adap/flower/pull/1640))" -#: ../../source/ref-changelog.md:452 +#: ../../source/ref-changelog.md:544 msgid "" "An updated event structure allows, for example, the clustering of events " "within the same workload." msgstr "例如,更新后的事件结构可以将同一工作负载中的事件集中在一起。" -#: ../../source/ref-changelog.md:454 +#: ../../source/ref-changelog.md:546 msgid "" "**Add new custom strategy tutorial section** " "[#1623](https://github.com/adap/flower/pull/1623)" msgstr "**添加新的自定义策略教程部分** [#1623](https://github.com/adap/flower/pull/1623)" -#: ../../source/ref-changelog.md:456 +#: ../../source/ref-changelog.md:548 msgid "" "The Flower tutorial now has a new section that covers implementing a " "custom strategy from scratch: [Open in " @@ -19094,13 +19852,13 @@ msgstr "" "中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" "/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" -#: ../../source/ref-changelog.md:458 +#: ../../source/ref-changelog.md:550 msgid "" "**Add new custom serialization tutorial section** " "([#1622](https://github.com/adap/flower/pull/1622))" msgstr "** 添加新的自定义序列化教程部分** ([#1622](https://github.com/adap/flower/pull/1622))" -#: ../../source/ref-changelog.md:460 +#: ../../source/ref-changelog.md:552 msgid "" "The Flower tutorial now has a new section that covers custom " "serialization: [Open in " @@ -19111,7 +19869,7 @@ msgstr "" "中打开](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" "/tutorial-customize-the-client-pytorch.ipynb)" -#: ../../source/ref-changelog.md:462 +#: ../../source/ref-changelog.md:554 msgid "" "**General improvements** " "([#1638](https://github.com/adap/flower/pull/1638), " @@ -19182,7 +19940,7 @@ msgstr "" "[#1572](https://github.com/adap/flower/pull/1572), " "[#1586](https://github.com/adap/flower/pull/1586))" -#: ../../source/ref-changelog.md:466 +#: ../../source/ref-changelog.md:558 msgid "" "**Updated documentation** " "([#1629](https://github.com/adap/flower/pull/1629), " @@ -19201,18 +19959,18 @@ msgstr "" "[#1613](https://github.com/adap/flower/pull/1613), " "[#1614](https://github.com/adap/flower/pull/1614)))" -#: ../../source/ref-changelog.md:468 ../../source/ref-changelog.md:535 +#: ../../source/ref-changelog.md:560 ../../source/ref-changelog.md:627 msgid "" "As usual, the documentation has improved quite a bit. It is another step " "in our effort to make the Flower documentation the best documentation of " "any project. Stay tuned and as always, feel free to provide feedback!" msgstr "和往常一样,我们的文档有了很大的改进。这是我们努力使 Flower 文档成为所有项目中最好文档的又一步骤。请继续关注,并随时提供反馈意见!" -#: ../../source/ref-changelog.md:474 +#: ../../source/ref-changelog.md:566 msgid "v1.2.0 (2023-01-13)" msgstr "v1.2.0 (2023-01-13)" -#: ../../source/ref-changelog.md:480 +#: ../../source/ref-changelog.md:572 msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." " Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" @@ -19220,7 +19978,7 @@ msgstr "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." " Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" -#: ../../source/ref-changelog.md:484 +#: ../../source/ref-changelog.md:576 msgid "" "**Introduce new Flower Baseline: FedAvg MNIST** " "([#1497](https://github.com/adap/flower/pull/1497), " @@ -19230,7 +19988,7 @@ msgstr "" "([#1497](https://github.com/adap/flower/pull/1497), " "[#1552](https://github.com/adap/flower/pull/1552))" -#: ../../source/ref-changelog.md:486 +#: ../../source/ref-changelog.md:578 msgid "" "Over the coming weeks, we will be releasing a number of new reference " "implementations useful especially to FL newcomers. They will typically " @@ -19245,13 +20003,13 @@ msgstr "" "的总体了解。今天发布的是该系列中的第一篇。[阅读全文](https://flower.ai/blog/2023-01-12-fl-starter-" "pack-fedavg-mnist-cnn/)" -#: ../../source/ref-changelog.md:488 +#: ../../source/ref-changelog.md:580 msgid "" "**Improve GPU support in simulations** " "([#1555](https://github.com/adap/flower/pull/1555))" msgstr "**改进模拟中的 GPU 支持**([#1555](https://github.com/adap/flower/pull/1555))" -#: ../../source/ref-changelog.md:490 +#: ../../source/ref-changelog.md:582 msgid "" "The Ray-based Virtual Client Engine (`start_simulation`) has been updated" " to improve GPU support. The update includes some of the hard-earned " @@ -19261,7 +20019,7 @@ msgstr "" "基于 Ray 的虚拟客户端引擎 (`start_simulation`)已更新,以改进对 GPU 的支持。此次更新包含了在 GPU " "集群环境中扩展模拟的一些经验教训。新的默认设置使基于 GPU 的模拟运行更加稳健。" -#: ../../source/ref-changelog.md:492 +#: ../../source/ref-changelog.md:584 msgid "" "**Improve GPU support in Jupyter Notebook tutorials** " "([#1527](https://github.com/adap/flower/pull/1527), " @@ -19271,7 +20029,7 @@ msgstr "" "([#1527](https://github.com/adap/flower/pull/1527), " "[#1558](https://github.com/adap/flower/pull/1558))" -#: ../../source/ref-changelog.md:494 +#: ../../source/ref-changelog.md:586 msgid "" "Some users reported that Jupyter Notebooks have not always been easy to " "use on GPU instances. We listened and made improvements to all of our " @@ -19280,7 +20038,7 @@ msgstr "" "一些用户报告说,在 GPU 实例上使用 Jupyter 笔记本并不是很方便。我们听取了他们的意见,并对所有 Jupyter " "笔记本进行了改进!点击这里查看更新后的笔记本:" -#: ../../source/ref-changelog.md:496 +#: ../../source/ref-changelog.md:588 msgid "" "[An Introduction to Federated Learning](https://flower.ai/docs/framework" "/tutorial-get-started-with-flower-pytorch.html)" @@ -19288,7 +20046,7 @@ msgstr "" "[联邦学习简介](https://flower.ai/docs/framework/tutorial-get-started-with-" "flower-pytorch.html)" -#: ../../source/ref-changelog.md:497 +#: ../../source/ref-changelog.md:589 msgid "" "[Strategies in Federated Learning](https://flower.ai/docs/framework" "/tutorial-use-a-federated-learning-strategy-pytorch.html)" @@ -19296,7 +20054,7 @@ msgstr "" "[联邦学习策略](https://flower.ai/docs/framework/tutorial-use-a-federated-" "learning-strategy-pytorch.html)" -#: ../../source/ref-changelog.md:498 +#: ../../source/ref-changelog.md:590 msgid "" "[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" "-strategy-from-scratch-pytorch.html)" @@ -19304,7 +20062,7 @@ msgstr "" "[制定策略](https://flower.ai/docs/framework/tutorial-build-a-strategy-from-" "scratch-pytorch.html)" -#: ../../source/ref-changelog.md:499 +#: ../../source/ref-changelog.md:591 msgid "" "[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" "customize-the-client-pytorch.html)" @@ -19312,7 +20070,7 @@ msgstr "" "[客户端和 NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" "the-client-pytorch.html)" -#: ../../source/ref-changelog.md:501 +#: ../../source/ref-changelog.md:593 msgid "" "**Introduce optional telemetry** " "([#1533](https://github.com/adap/flower/pull/1533), " @@ -19323,7 +20081,7 @@ msgstr "" "[#1544](https://github.com/adap/flower/pull/1544), " "[#1584](https://github.com/adap/flower/pull/1584)" -#: ../../source/ref-changelog.md:503 +#: ../../source/ref-changelog.md:595 msgid "" "After a [request for " "feedback](https://github.com/adap/flower/issues/1534) from the community," @@ -19336,7 +20094,7 @@ msgstr "" "开放源码项目引入了可选的*匿名*使用指标收集,以便在充分知情的情况下做出改进 Flower 的决定。这样做能让 Flower 团队了解 " "Flower 的使用情况以及用户可能面临的挑战。" -#: ../../source/ref-changelog.md:505 +#: ../../source/ref-changelog.md:597 msgid "" "**Flower is a friendly framework for collaborative AI and data science.**" " Staying true to this statement, Flower makes it easy to disable " @@ -19346,7 +20104,7 @@ msgstr "" "**Flower 是一个用于协作式人工智能和数据科学的友好框架。** Flower " "遵循这一声明,让不想分享匿名使用指标的用户可以轻松禁用遥测技术。[阅读全文](https://flower.ai/docs/telemetry.html)。" -#: ../../source/ref-changelog.md:507 +#: ../../source/ref-changelog.md:599 msgid "" "**Introduce (experimental) Driver API** " "([#1520](https://github.com/adap/flower/pull/1520), " @@ -19365,7 +20123,7 @@ msgstr "" "[#1551](https://github.com/adap/flower/pull/1551), " "[#1567](https://github.com/adap/flower/pull/1567))" -#: ../../source/ref-changelog.md:509 +#: ../../source/ref-changelog.md:601 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " @@ -19377,7 +20135,7 @@ msgstr "" "API),它将支持完全可编程、异步和多租户的联邦学习(Federated Learning)和联邦分析(Federated " "Analytics)应用程序。展望未来,Driver API 将成为许多即将推出的功能的抽象基础,您现在就可以开始构建这些功能。" -#: ../../source/ref-changelog.md:511 +#: ../../source/ref-changelog.md:603 msgid "" "The Driver API also enables a new execution mode in which the server runs" " indefinitely. Multiple individual workloads can run concurrently and " @@ -19387,19 +20145,19 @@ msgstr "" "驱动程序应用程序接口还支持一种新的执行模式,在这种模式下,服务器可无限期运行。多个单独的工作负载可以同时运行,并独立于服务器启动和停止执行。这对于希望在生产中部署" " Flower 的用户来说尤其有用。" -#: ../../source/ref-changelog.md:513 +#: ../../source/ref-changelog.md:605 msgid "" "To learn more, check out the `mt-pytorch` code example. We look forward " "to you feedback!" msgstr "要了解更多信息,请查看 `mt-pytorch` 代码示例。我们期待您的反馈!" -#: ../../source/ref-changelog.md:515 +#: ../../source/ref-changelog.md:607 msgid "" "Please note: *The Driver API is still experimental and will likely change" " significantly over time.*" msgstr "请注意:Driver API仍处于试验阶段,随着时间的推移可能会发生重大变化。*" -#: ../../source/ref-changelog.md:517 +#: ../../source/ref-changelog.md:609 msgid "" "**Add new Federated Analytics with Pandas example** " "([#1469](https://github.com/adap/flower/pull/1469), " @@ -19409,7 +20167,7 @@ msgstr "" "的联邦分析示例**([#1469](https://github.com/adap/flower/pull/1469), " "[#1535](https://github.com/adap/flower/pull/1535)" -#: ../../source/ref-changelog.md:519 +#: ../../source/ref-changelog.md:611 msgid "" "A new code example (`quickstart-pandas`) demonstrates federated analytics" " with Pandas and Flower. You can find it here: [quickstart-" @@ -19420,7 +20178,7 @@ msgstr "" "[quickstart-pandas](https://github.com/adap/flower/tree/main/examples" "/quickstart-pandas)。" -#: ../../source/ref-changelog.md:521 +#: ../../source/ref-changelog.md:613 msgid "" "**Add new strategies: Krum and MultiKrum** " "([#1481](https://github.com/adap/flower/pull/1481))" @@ -19428,7 +20186,7 @@ msgstr "" "**添加新策略: Krum 和 MultiKrum** " "([#1481](https://github.com/adap/flower/pull/1481))" -#: ../../source/ref-changelog.md:523 +#: ../../source/ref-changelog.md:615 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " "contributed a new `Krum` strategy that enables users to easily use Krum " @@ -19437,7 +20195,7 @@ msgstr "" "罗马萨皮恩扎大学(Sapienza University)计算机科学专业的学生埃多尔多(Edoardo)提出了一种新的 \"Krum " "\"策略,使用户能够在其工作负载中轻松使用 Krum 和 MultiKrum。" -#: ../../source/ref-changelog.md:525 +#: ../../source/ref-changelog.md:617 msgid "" "**Update C++ example to be compatible with Flower v1.2.0** " "([#1495](https://github.com/adap/flower/pull/1495))" @@ -19445,13 +20203,13 @@ msgstr "" "** 更新 C++ 示例,与 Flower v1.2.0 兼容** " "([#1495](https://github.com/adap/flower/pull/1495))" -#: ../../source/ref-changelog.md:527 +#: ../../source/ref-changelog.md:619 msgid "" "The C++ code example has received a substantial update to make it " "compatible with the latest version of Flower." msgstr "为了与最新版本的 Flower 兼容,C++ 示例代码进行了大幅更新。" -#: ../../source/ref-changelog.md:529 +#: ../../source/ref-changelog.md:621 msgid "" "**General improvements** " "([#1491](https://github.com/adap/flower/pull/1491), " @@ -19482,7 +20240,7 @@ msgstr "" "[#1564](https://github.com/adap/flower/pull/1564), " "[#1566](https://github.com/adap/flower/pull/1566))" -#: ../../source/ref-changelog.md:533 +#: ../../source/ref-changelog.md:625 msgid "" "**Updated documentation** " "([#1494](https://github.com/adap/flower/pull/1494), " @@ -19505,7 +20263,7 @@ msgstr "" "[#1519](https://github.com/adap/flower/pull/1519), " "[#1515](https://github.com/adap/flower/pull/1515))" -#: ../../source/ref-changelog.md:537 +#: ../../source/ref-changelog.md:629 msgid "" "One highlight is the new [first time contributor " "guide](https://flower.ai/docs/first-time-contributors.html): if you've " @@ -19514,17 +20272,17 @@ msgstr "" "其中一个亮点是新的[首次贡献者指南](https://flower.ai/docs/first-time-" "contributors.html):如果你以前从未在 GitHub 上做过贡献,这将是一个完美的开始!" -#: ../../source/ref-changelog.md:543 +#: ../../source/ref-changelog.md:635 msgid "v1.1.0 (2022-10-31)" msgstr "v1.1.0 (2022-10-31)" -#: ../../source/ref-changelog.md:547 +#: ../../source/ref-changelog.md:639 msgid "" "We would like to give our **special thanks** to all the contributors who " "made the new version of Flower possible (in `git shortlog` order):" msgstr "在此,我们向所有促成 Flower 新版本的贡献者致以**特别的谢意(按 \"git shortlog \"顺序排列):" -#: ../../source/ref-changelog.md:549 +#: ../../source/ref-changelog.md:641 msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " @@ -19536,7 +20294,7 @@ msgstr "" "Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " "`danielnugraha`, `edogab33`" -#: ../../source/ref-changelog.md:553 +#: ../../source/ref-changelog.md:645 msgid "" "**Introduce Differential Privacy wrappers (preview)** " "([#1357](https://github.com/adap/flower/pull/1357), " @@ -19545,7 +20303,7 @@ msgstr "" "**引入差分隐私包装器(预览)** ([#1357](https://github.com/adap/flower/pull/1357), " "[#1460](https://github.com/adap/flower/pull/1460))" -#: ../../source/ref-changelog.md:555 +#: ../../source/ref-changelog.md:647 msgid "" "The first (experimental) preview of pluggable Differential Privacy " "wrappers enables easy configuration and usage of differential privacy " @@ -19556,13 +20314,13 @@ msgstr "" "可插拔差分隐私封装器的首个(实验性)预览版可轻松配置和使用差分隐私(DP)。可插拔的差分隐私封装器可实现客户端差分隐私和服务器端差分隐私的框架无关**以及**策略无关的使用。请访问" " Flower 文档,新的解释器会提供更多细节。" -#: ../../source/ref-changelog.md:557 +#: ../../source/ref-changelog.md:649 msgid "" "**New iOS CoreML code example** " "([#1289](https://github.com/adap/flower/pull/1289))" msgstr "**新的 iOS CoreML 代码示例**([#1289](https://github.com/adap/flower/pull/1289))" -#: ../../source/ref-changelog.md:559 +#: ../../source/ref-changelog.md:651 msgid "" "Flower goes iOS! A massive new code example shows how Flower clients can " "be built for iOS. The code example contains both Flower iOS SDK " @@ -19572,13 +20330,13 @@ msgstr "" "Flower 进入 iOS!大量新代码示例展示了如何为 iOS 构建 Flower 客户端。该代码示例包含可用于多种任务的 Flower iOS " "SDK 组件,以及在 CoreML 上运行的一个任务示例。" -#: ../../source/ref-changelog.md:561 +#: ../../source/ref-changelog.md:653 msgid "" "**New FedMedian strategy** " "([#1461](https://github.com/adap/flower/pull/1461))" msgstr "**新的联邦医疗策略** ([#1461](https://github.com/adap/flower/pull/1461))" -#: ../../source/ref-changelog.md:563 +#: ../../source/ref-changelog.md:655 msgid "" "The new `FedMedian` strategy implements Federated Median (FedMedian) by " "[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." @@ -19586,27 +20344,27 @@ msgstr "" "新的 \"FedMedian \"战略实现了[Yin " "等人,2018]的联邦中值(FedMedian)(https://arxiv.org/pdf/1803.01498v1.pdf)。" -#: ../../source/ref-changelog.md:565 +#: ../../source/ref-changelog.md:657 msgid "" "**Log** `Client` **exceptions in Virtual Client Engine** " "([#1493](https://github.com/adap/flower/pull/1493))" msgstr "**虚拟客户端引擎中的**日志**`客户端`**异常([#1493](https://github.com/adap/flower/pull/1493))" -#: ../../source/ref-changelog.md:567 +#: ../../source/ref-changelog.md:659 msgid "" "All `Client` exceptions happening in the VCE are now logged by default " "and not just exposed to the configured `Strategy` (via the `failures` " "argument)." msgstr "VCE 中发生的所有 \"客户端 \"异常现在都会被默认记录下来,而不只是暴露给配置的 `Strategy`(通过 `failures`参数)。" -#: ../../source/ref-changelog.md:569 +#: ../../source/ref-changelog.md:661 msgid "" "**Improve Virtual Client Engine internals** " "([#1401](https://github.com/adap/flower/pull/1401), " "[#1453](https://github.com/adap/flower/pull/1453))" msgstr "**改进虚拟客户端引擎内部**([#1401](https://github.com/adap/flower/pull/1401)、[#1453](https://github.com/adap/flower/pull/1453))" -#: ../../source/ref-changelog.md:571 +#: ../../source/ref-changelog.md:663 msgid "" "Some internals of the Virtual Client Engine have been revamped. The VCE " "now uses Ray 2.0 under the hood, the value type of the `client_resources`" @@ -19616,19 +20374,19 @@ msgstr "" "虚拟客户端引擎的部分内部结构已进行了修改。VCE 现在使用 Ray 2.0,\"client_resources \"字典的值类型改为 " "\"float\",以允许分配分数资源。" -#: ../../source/ref-changelog.md:573 +#: ../../source/ref-changelog.md:665 msgid "" "**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " "Client Engine**" msgstr "**支持虚拟客户端引擎中的可选** `Client`**/**`NumPyClient` **方法**" -#: ../../source/ref-changelog.md:575 +#: ../../source/ref-changelog.md:667 msgid "" "The Virtual Client Engine now has full support for optional `Client` (and" " `NumPyClient`) methods." msgstr "虚拟客户端引擎现在完全支持可选的 `Client`(和 `NumPyClient`)方法。" -#: ../../source/ref-changelog.md:577 +#: ../../source/ref-changelog.md:669 msgid "" "**Provide type information to packages using** `flwr` " "([#1377](https://github.com/adap/flower/pull/1377))" @@ -19636,7 +20394,7 @@ msgstr "" "**使用** `flwr`向软件包提供类型信息 " "([#1377](https://github.com/adap/flower/pull/1377))" -#: ../../source/ref-changelog.md:579 +#: ../../source/ref-changelog.md:671 msgid "" "The package `flwr` is now bundled with a `py.typed` file indicating that " "the package is typed. This enables typing support for projects or " @@ -19646,7 +20404,7 @@ msgstr "" "软件包 `flwr` 现在捆绑了一个 `py.typed` 文件,表明该软件包是类型化的。这样,使用 `flwr` 的项目或软件包就可以使用 " "`mypy` 等静态类型检查器改进代码,从而获得类型支持。" -#: ../../source/ref-changelog.md:581 +#: ../../source/ref-changelog.md:673 msgid "" "**Updated code example** " "([#1344](https://github.com/adap/flower/pull/1344), " @@ -19655,13 +20413,13 @@ msgstr "" "** 更新代码示例** ([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" -#: ../../source/ref-changelog.md:583 +#: ../../source/ref-changelog.md:675 msgid "" "The code examples covering scikit-learn and PyTorch Lightning have been " "updated to work with the latest version of Flower." msgstr "涵盖 scikit-learn 和 PyTorch Lightning 的代码示例已更新,以便与最新版本的 Flower 配合使用。" -#: ../../source/ref-changelog.md:585 +#: ../../source/ref-changelog.md:677 msgid "" "**Updated documentation** " "([#1355](https://github.com/adap/flower/pull/1355), " @@ -19700,32 +20458,32 @@ msgstr "" "[#1465](https://github.com/adap/flower/pull/1465), " "[#1467](https://github.com/adap/flower/pull/1467))" -#: ../../source/ref-changelog.md:587 +#: ../../source/ref-changelog.md:679 msgid "" "There have been so many documentation updates that it doesn't even make " "sense to list them individually." msgstr "文档更新的数量之多,甚至没有必要逐一列出。" -#: ../../source/ref-changelog.md:589 +#: ../../source/ref-changelog.md:681 msgid "" "**Restructured documentation** " "([#1387](https://github.com/adap/flower/pull/1387))" msgstr "**重构文档**([#1387](https://github.com/adap/flower/pull/1387))" -#: ../../source/ref-changelog.md:591 +#: ../../source/ref-changelog.md:683 msgid "" "The documentation has been restructured to make it easier to navigate. " "This is just the first step in a larger effort to make the Flower " "documentation the best documentation of any project ever. Stay tuned!" msgstr "我们对文档进行了重组,使其更易于浏览。这只是让 Flower 文档成为所有项目中最好文档的第一步。敬请期待!" -#: ../../source/ref-changelog.md:593 +#: ../../source/ref-changelog.md:685 msgid "" "**Open in Colab button** " "([#1389](https://github.com/adap/flower/pull/1389))" msgstr "**在 Colab 中打开按钮** ([#1389](https://github.com/adap/flower/pull/1389))" -#: ../../source/ref-changelog.md:595 +#: ../../source/ref-changelog.md:687 msgid "" "The four parts of the Flower Federated Learning Tutorial now come with a " "new `Open in Colab` button. No need to install anything on your local " @@ -19735,7 +20493,7 @@ msgstr "" "Flower 联邦学习教程的四个部分现在都带有一个新的 \"在 Colab 中打开 " "\"按钮。现在,您无需在本地计算机上安装任何软件,只需点击一下,就可以在浏览器中使用和学习 Flower。" -#: ../../source/ref-changelog.md:597 +#: ../../source/ref-changelog.md:689 msgid "" "**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," " [#1470](https://github.com/adap/flower/pull/1470), " @@ -19751,7 +20509,7 @@ msgstr "" "[#1474](https://github.com/adap/flower/pull/1474), " "[#1475](https://github.com/adap/flower/pull/1475)))" -#: ../../source/ref-changelog.md:599 +#: ../../source/ref-changelog.md:691 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " @@ -19761,33 +20519,33 @@ msgstr "" "Flower 联邦学习教程有两个全新的部分,涉及自定义策略(仍处于 WIP 阶段)和 `Client` 与 `NumPyClient` " "之间的区别。现有的第一和第二部分也得到了改进(许多小改动和修正)。" -#: ../../source/ref-changelog.md:605 +#: ../../source/ref-changelog.md:697 msgid "v1.0.0 (2022-07-28)" msgstr "v1.0.0 (2022-07-28)" -#: ../../source/ref-changelog.md:607 +#: ../../source/ref-changelog.md:699 msgid "Highlights" msgstr "亮点" -#: ../../source/ref-changelog.md:609 +#: ../../source/ref-changelog.md:701 msgid "Stable **Virtual Client Engine** (accessible via `start_simulation`)" msgstr "稳定的**虚拟客户端引擎**(可通过`start_simulation`访问)" -#: ../../source/ref-changelog.md:610 +#: ../../source/ref-changelog.md:702 msgid "All `Client`/`NumPyClient` methods are now optional" msgstr "所有 `Client`/`NumPyClient` 方法现在都是可选的了" -#: ../../source/ref-changelog.md:611 +#: ../../source/ref-changelog.md:703 msgid "Configurable `get_parameters`" msgstr "可配置的`get_parameters`" -#: ../../source/ref-changelog.md:612 +#: ../../source/ref-changelog.md:704 msgid "" "Tons of small API cleanups resulting in a more coherent developer " "experience" msgstr "对大量小型应用程序接口进行了清理,使开发人员的体验更加一致" -#: ../../source/ref-changelog.md:616 +#: ../../source/ref-changelog.md:708 msgid "" "We would like to give our **special thanks** to all the contributors who " "made Flower 1.0 possible (in reverse [GitHub " @@ -19796,7 +20554,7 @@ msgstr "" "在此,我们谨向所有促成 Flower 1.0 的贡献者致以**特别的谢意(按[GitHub " "贡献者](https://github.com/adap/flower/graphs/contributors) 倒序排列):" -#: ../../source/ref-changelog.md:618 +#: ../../source/ref-changelog.md:710 msgid "" "[@rtaiello](https://github.com/rtaiello), " "[@g-pichler](https://github.com/g-pichler), [@rob-" @@ -19872,13 +20630,13 @@ msgstr "" "[@tanertopal](https://github.com/tanertopal), " "[@danieljanes](https://github.com/danieljanes)." -#: ../../source/ref-changelog.md:622 +#: ../../source/ref-changelog.md:714 msgid "" "**All arguments must be passed as keyword arguments** " "([#1338](https://github.com/adap/flower/pull/1338))" msgstr "** 所有参数必须作为关键字参数传递** ([#1338](https://github.com/adap/flower/pull/1338))" -#: ../../source/ref-changelog.md:624 +#: ../../source/ref-changelog.md:716 msgid "" "Pass all arguments as keyword arguments, positional arguments are not " "longer supported. Code that uses positional arguments (e.g., " @@ -19891,7 +20649,7 @@ msgstr "" "FlowerClient())`)必须为每个位置参数添加关键字(例如,`start_client(server_address=\"127.0.0.1:8080\"," " client=FlowerClient())`)。" -#: ../../source/ref-changelog.md:626 +#: ../../source/ref-changelog.md:718 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " "**and** `start_simulation` " @@ -19900,7 +20658,7 @@ msgstr "" "**在*** `start_server` ***和*** `start_simulation` 中引入配置对象*** " "`ServerConfig` ([#1317](https://github.com/adap/flower/pull/1317))" -#: ../../source/ref-changelog.md:628 +#: ../../source/ref-changelog.md:720 msgid "" "Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " "600.0}`, `start_server` and `start_simulation` now expect a configuration" @@ -19913,37 +20671,37 @@ msgstr "" "`flwr.server.ServerConfig`的配置对象。`ServerConfig`接收的参数与之前的 config dict " "相同,但它使编写类型安全代码变得更容易,默认参数值也更加透明。" -#: ../../source/ref-changelog.md:630 +#: ../../source/ref-changelog.md:722 msgid "" "**Rename built-in strategy parameters for clarity** " "([#1334](https://github.com/adap/flower/pull/1334))" msgstr "**重新命名内置策略参数,使其更加清晰** ([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:632 +#: ../../source/ref-changelog.md:724 msgid "" "The following built-in strategy parameters were renamed to improve " "readability and consistency with other API's:" msgstr "以下内置策略参数已重新命名,以提高可读性并与其他 API 保持一致:" -#: ../../source/ref-changelog.md:634 +#: ../../source/ref-changelog.md:726 msgid "`fraction_eval` --> `fraction_evaluate`" msgstr "`fraction_eval` --> `fraction_evaluate`" -#: ../../source/ref-changelog.md:635 +#: ../../source/ref-changelog.md:727 msgid "`min_eval_clients` --> `min_evaluate_clients`" msgstr "`min_eval_clients` --> `min_evaluate_clients`" -#: ../../source/ref-changelog.md:636 +#: ../../source/ref-changelog.md:728 msgid "`eval_fn` --> `evaluate_fn`" msgstr "`eval_fn` --> `evaluate_fn`" -#: ../../source/ref-changelog.md:638 +#: ../../source/ref-changelog.md:730 msgid "" "**Update default arguments of built-in strategies** " "([#1278](https://github.com/adap/flower/pull/1278))" msgstr "**更新内置策略的默认参数** ([#1278](https://github.com/adap/flower/pull/1278))" -#: ../../source/ref-changelog.md:640 +#: ../../source/ref-changelog.md:732 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " "`fraction_evaluate=1.0`, which means they select *all* currently " @@ -19954,11 +20712,11 @@ msgstr "" "所有内置策略现在都使用 \"fraction_fit=1.0 \"和 " "\"fraction_evaluate=1.0\",这意味着它们会选择*所有*当前可用的客户端进行训练和评估。依赖以前默认值的项目可以通过以下方式初始化策略,获得以前的行为:" -#: ../../source/ref-changelog.md:642 +#: ../../source/ref-changelog.md:734 msgid "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" msgstr "`strategy = FedAvg(fraction_fit=0.1, fraction_evaluate=0.1)`" -#: ../../source/ref-changelog.md:644 +#: ../../source/ref-changelog.md:736 msgid "" "**Add** `server_round` **to** `Strategy.evaluate` " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -19966,13 +20724,13 @@ msgstr "" "**添加*** `server_round` ***到*** `Strategy.evaluate` " "([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:646 +#: ../../source/ref-changelog.md:738 msgid "" "The `Strategy` method `evaluate` now receives the current round of " "federated learning/evaluation as the first parameter." msgstr "`Strategy`的`evaluate` 方法现在会接收当前一轮联邦学习/评估作为第一个参数。" -#: ../../source/ref-changelog.md:648 +#: ../../source/ref-changelog.md:740 msgid "" "**Add** `server_round` **and** `config` **parameters to** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" @@ -19980,7 +20738,7 @@ msgstr "" "**将*** `server_round` **和*** `config` **参数添加到*** `evaluate_fn` " "([#1334](https://github.com/adap/flower/pull/1334))" -#: ../../source/ref-changelog.md:650 +#: ../../source/ref-changelog.md:742 msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " @@ -19990,7 +20748,7 @@ msgstr "" "传递给内置策略(如 `FedAvg`)的 `evaluate_fn` 现在需要三个参数:(1) 当前一轮联邦学习/评估 " "(`server_round`),(2) 要评估的模型参数 (`parameters`),(3) 配置字典 (`config`)。" -#: ../../source/ref-changelog.md:652 +#: ../../source/ref-changelog.md:744 msgid "" "**Rename** `rnd` **to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" @@ -19998,7 +20756,7 @@ msgstr "" "**重新命名** `rnd` ** to** `server_round` " "([#1321](https://github.com/adap/flower/pull/1321))" -#: ../../source/ref-changelog.md:654 +#: ../../source/ref-changelog.md:746 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " @@ -20010,7 +20768,7 @@ msgstr "" "方法和函数(`evaluate_fn`、`configure_fit`、`aggregate_fit`、`configure_evaluate`、`aggregate_evaluate`)的第一个参数是当前一轮的联邦学习/评估。为提高可重复性并避免与" " *random* 混淆,该参数已从 `rnd` 更名为 `server_round`。" -#: ../../source/ref-changelog.md:656 +#: ../../source/ref-changelog.md:748 msgid "" "**Move** `flwr.dataset` **to** `flwr_baselines` " "([#1273](https://github.com/adap/flower/pull/1273))" @@ -20018,23 +20776,23 @@ msgstr "" "**移动*** `flwr.dataset` **到*** `flwr_baselines` " "([#1273](https://github.com/adap/flower/pull/1273))" -#: ../../source/ref-changelog.md:658 +#: ../../source/ref-changelog.md:750 msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "实验软件包 `flwr.dataset` 已迁移至 Flower Baselines。" -#: ../../source/ref-changelog.md:660 +#: ../../source/ref-changelog.md:752 msgid "" "**Remove experimental strategies** " "([#1280](https://github.com/adap/flower/pull/1280))" msgstr "**删除实验策略** ([#1280](https://github.com/adap/flower/pull/1280))" -#: ../../source/ref-changelog.md:662 +#: ../../source/ref-changelog.md:754 msgid "" "Remove unmaintained experimental strategies (`FastAndSlow`, `FedFSv0`, " "`FedFSv1`)." msgstr "移除未维护的试验性策略(`FastAndSlow`、`FedFSv0`、`FedFSv1`)。" -#: ../../source/ref-changelog.md:664 +#: ../../source/ref-changelog.md:756 msgid "" "**Rename** `Weights` **to** `NDArrays` " "([#1258](https://github.com/adap/flower/pull/1258), " @@ -20044,13 +20802,13 @@ msgstr "" "([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:666 +#: ../../source/ref-changelog.md:758 msgid "" "`flwr.common.Weights` was renamed to `flwr.common.NDArrays` to better " "capture what this type is all about." msgstr "flwr.common.Weights \"更名为 \"flwr.common.NDArrays\",以更好地反映该类型的含义。" -#: ../../source/ref-changelog.md:668 +#: ../../source/ref-changelog.md:760 msgid "" "**Remove antiquated** `force_final_distributed_eval` **from** " "`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " @@ -20060,7 +20818,7 @@ msgstr "" "([#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" -#: ../../source/ref-changelog.md:670 +#: ../../source/ref-changelog.md:762 msgid "" "The `start_server` parameter `force_final_distributed_eval` has long been" " a historic artefact, in this release it is finally gone for good." @@ -20068,7 +20826,7 @@ msgstr "" "start_server \"参数 \"force_final_distributed_eval " "\"长期以来一直是个历史遗留问题,在此版本中终于永远消失了。" -#: ../../source/ref-changelog.md:672 +#: ../../source/ref-changelog.md:764 msgid "" "**Make** `get_parameters` **configurable** " "([#1242](https://github.com/adap/flower/pull/1242))" @@ -20076,7 +20834,7 @@ msgstr "" "**使** `get_parameters` **可配置** " "([#1242](https://github.com/adap/flower/pull/1242))" -#: ../../source/ref-changelog.md:674 +#: ../../source/ref-changelog.md:766 msgid "" "The `get_parameters` method now accepts a configuration dictionary, just " "like `get_properties`, `fit`, and `evaluate`." @@ -20084,7 +20842,7 @@ msgstr "" "现在,\"get_parameters \"方法与 \"get_properties\"、\"fit \"和 \"evaluate " "\"一样,都接受配置字典。" -#: ../../source/ref-changelog.md:676 +#: ../../source/ref-changelog.md:768 msgid "" "**Replace** `num_rounds` **in** `start_simulation` **with new** `config` " "**parameter** ([#1281](https://github.com/adap/flower/pull/1281))" @@ -20092,7 +20850,7 @@ msgstr "" "**用新的** `config` 参数** 替换** `num_rounds` ** in** `start_simulation` ** " "([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:678 +#: ../../source/ref-changelog.md:770 msgid "" "The `start_simulation` function now accepts a configuration dictionary " "`config` instead of the `num_rounds` integer. This improves the " @@ -20102,19 +20860,19 @@ msgstr "" "现在,`start_simulation`(开始模拟)` 函数接受配置字典 `config` 而不是 `num_rounds` 整数。这改进了 " "`start_simulation` 和 `start_server` 之间的一致性,并使两者之间的转换更容易。" -#: ../../source/ref-changelog.md:682 +#: ../../source/ref-changelog.md:774 msgid "" "**Support Python 3.10** " "([#1320](https://github.com/adap/flower/pull/1320))" msgstr "** 支持 Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" -#: ../../source/ref-changelog.md:684 +#: ../../source/ref-changelog.md:776 msgid "" "The previous Flower release introduced experimental support for Python " "3.10, this release declares Python 3.10 support as stable." msgstr "上一个 Flower 版本引入了对 Python 3.10 的实验支持,而本版本则宣布对 Python 3.10 的支持为稳定支持。" -#: ../../source/ref-changelog.md:686 +#: ../../source/ref-changelog.md:778 msgid "" "**Make all** `Client` **and** `NumPyClient` **methods optional** " "([#1260](https://github.com/adap/flower/pull/1260), " @@ -20124,7 +20882,7 @@ msgstr "" "([#1260](https://github.com/adap/flower/pull/1260), " "[#1277](https://github.com/adap/flower/pull/1277))" -#: ../../source/ref-changelog.md:688 +#: ../../source/ref-changelog.md:780 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " "`fit`, and `evaluate` are all optional. This enables writing clients that" @@ -20135,7 +20893,7 @@ msgstr "" "\"evaluate \"方法都是可选的。这样就可以编写只实现 `fit` 而不实现其他方法的客户端。使用集中评估时,无需实现 " "`evaluate`!" -#: ../../source/ref-changelog.md:690 +#: ../../source/ref-changelog.md:782 msgid "" "**Enable passing a** `Server` **instance to** `start_simulation` " "([#1281](https://github.com/adap/flower/pull/1281))" @@ -20143,7 +20901,7 @@ msgstr "" "**启用向** `start_simulation` 传递** `Server` 实例 " "([#1281](https://github.com/adap/flower/pull/1281))" -#: ../../source/ref-changelog.md:692 +#: ../../source/ref-changelog.md:784 msgid "" "Similar to `start_server`, `start_simulation` now accepts a full `Server`" " instance. This enables users to heavily customize the execution of " @@ -20153,7 +20911,7 @@ msgstr "" "与 `start_server` 类似,`start_simulation` 现在也接受一个完整的 `Server` " "实例。这使得用户可以对实验的执行进行大量自定义,并为使用虚拟客户端引擎运行异步 FL 等打开了大门。" -#: ../../source/ref-changelog.md:694 +#: ../../source/ref-changelog.md:786 msgid "" "**Update code examples** " "([#1291](https://github.com/adap/flower/pull/1291), " @@ -20164,43 +20922,43 @@ msgstr "" "[#1286](https://github.com/adap/flower/pull/1286), " "[#1282](https://github.com/adap/flower/pull/1282))" -#: ../../source/ref-changelog.md:696 +#: ../../source/ref-changelog.md:788 msgid "" "Many code examples received small or even large maintenance updates, " "among them are" msgstr "许多代码示例都进行了小规模甚至大规模的维护更新,其中包括" -#: ../../source/ref-changelog.md:698 +#: ../../source/ref-changelog.md:790 msgid "`scikit-learn`" msgstr "`scikit-learn`" -#: ../../source/ref-changelog.md:699 +#: ../../source/ref-changelog.md:791 msgid "`simulation_pytorch`" msgstr "`simulation_pytorch`" -#: ../../source/ref-changelog.md:700 +#: ../../source/ref-changelog.md:792 msgid "`quickstart_pytorch`" msgstr "`quickstart_pytorch`" -#: ../../source/ref-changelog.md:701 +#: ../../source/ref-changelog.md:793 msgid "`quickstart_simulation`" msgstr "`quickstart_simulation`" -#: ../../source/ref-changelog.md:702 +#: ../../source/ref-changelog.md:794 msgid "`quickstart_tensorflow`" msgstr "`quickstart_tensorflow`" -#: ../../source/ref-changelog.md:703 +#: ../../source/ref-changelog.md:795 msgid "`advanced_tensorflow`" msgstr "`advanced_tensorflow`" -#: ../../source/ref-changelog.md:705 +#: ../../source/ref-changelog.md:797 msgid "" "**Remove the obsolete simulation example** " "([#1328](https://github.com/adap/flower/pull/1328))" msgstr "**删除过时的模拟示例** ([#1328](https://github.com/adap/flower/pull/1328))" -#: ../../source/ref-changelog.md:707 +#: ../../source/ref-changelog.md:799 msgid "" "Removes the obsolete `simulation` example and renames " "`quickstart_simulation` to `simulation_tensorflow` so it fits withs the " @@ -20209,7 +20967,7 @@ msgstr "" "删除过时的 \"simulation \"示例,并将 \"quickstart_simulation \"重命名为 " "\"simulation_tensorflow\",使其与 \"simulation_pytorch \"的命名一致" -#: ../../source/ref-changelog.md:709 +#: ../../source/ref-changelog.md:801 msgid "" "**Update documentation** " "([#1223](https://github.com/adap/flower/pull/1223), " @@ -20234,7 +20992,7 @@ msgstr "" "[#1305](https://github.com/adap/flower/pull/1305), " "[#1307](https://github.com/adap/flower/pull/1307))" -#: ../../source/ref-changelog.md:711 +#: ../../source/ref-changelog.md:803 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " @@ -20247,18 +21005,18 @@ msgstr "" "`flwr.common` 模块,包含了对基于 markdown 的文档的支持,将更新日志从 `.rst` 移植到了 " "`.md`,并修复了一些较小的细节!" -#: ../../source/ref-changelog.md:713 ../../source/ref-changelog.md:768 -#: ../../source/ref-changelog.md:837 ../../source/ref-changelog.md:876 +#: ../../source/ref-changelog.md:805 ../../source/ref-changelog.md:860 +#: ../../source/ref-changelog.md:929 ../../source/ref-changelog.md:968 msgid "**Minor updates**" msgstr "**小规模更新**" -#: ../../source/ref-changelog.md:715 +#: ../../source/ref-changelog.md:807 msgid "" "Add round number to fit and evaluate log messages " "([#1266](https://github.com/adap/flower/pull/1266))" msgstr "添加四舍五入数字,以适应和评估日志信息([#1266](https://github.com/adap/flower/pull/1266))" -#: ../../source/ref-changelog.md:716 +#: ../../source/ref-changelog.md:808 msgid "" "Add secure gRPC connection to the `advanced_tensorflow` code example " "([#847](https://github.com/adap/flower/pull/847))" @@ -20266,7 +21024,7 @@ msgstr "" "为 `advanced_tensorflow` 代码示例添加安全 gRPC 连接 " "([#847](https://github.com/adap/flower/pull/847))" -#: ../../source/ref-changelog.md:717 +#: ../../source/ref-changelog.md:809 msgid "" "Update developer tooling " "([#1231](https://github.com/adap/flower/pull/1231), " @@ -20279,7 +21037,7 @@ msgstr "" "[#1301](https://github.com/adap/flower/pull/1301), " "[#1310](https://github.com/adap/flower/pull/1310)" -#: ../../source/ref-changelog.md:718 +#: ../../source/ref-changelog.md:810 msgid "" "Rename ProtoBuf messages to improve consistency " "([#1214](https://github.com/adap/flower/pull/1214), " @@ -20290,11 +21048,11 @@ msgstr "" "[#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259)" -#: ../../source/ref-changelog.md:720 +#: ../../source/ref-changelog.md:812 msgid "v0.19.0 (2022-05-18)" msgstr "v0.19.0 (2022-05-18)" -#: ../../source/ref-changelog.md:724 +#: ../../source/ref-changelog.md:816 msgid "" "**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " "([#919](https://github.com/adap/flower/pull/919), " @@ -20306,7 +21064,7 @@ msgstr "" "[#1127](https://github.com/adap/flower/pull/1127), " "[#914](https://github.com/adap/flower/pull/914))" -#: ../../source/ref-changelog.md:726 +#: ../../source/ref-changelog.md:818 #, fuzzy msgid "" "The first preview release of Flower Baselines has arrived! We're " @@ -20323,13 +21081,13 @@ msgstr "" "baselines.html)。在首次发布预览版时,我们还邀请社区成员[贡献自己的Baselines](https://flower.ai/docs" "/contributing-baselines.html)。" -#: ../../source/ref-changelog.md:728 +#: ../../source/ref-changelog.md:820 msgid "" "**C++ client SDK (preview) and code example** " "([#1111](https://github.com/adap/flower/pull/1111))" msgstr "**C++客户端SDK(预览版)和代码示例**([#1111](https://github.com/adap/flower/pull/1111))" -#: ../../source/ref-changelog.md:730 +#: ../../source/ref-changelog.md:822 msgid "" "Preview support for Flower clients written in C++. The C++ preview " "includes a Flower client SDK and a quickstart code example that " @@ -20338,7 +21096,7 @@ msgstr "" "预览版支持用 C++ 编写的 Flower 客户端。C++ 预览版包括一个 Flower 客户端 SDK 和一个快速入门代码示例,使用 SDK " "演示了一个简单的 C++ 客户端。" -#: ../../source/ref-changelog.md:732 +#: ../../source/ref-changelog.md:824 msgid "" "**Add experimental support for Python 3.10 and Python 3.11** " "([#1135](https://github.com/adap/flower/pull/1135))" @@ -20346,7 +21104,7 @@ msgstr "" "** 增加对 Python 3.10 和 Python 3.11 的实验支持** " "([#1135](https://github.com/adap/flower/pull/1135))" -#: ../../source/ref-changelog.md:734 +#: ../../source/ref-changelog.md:826 msgid "" "Python 3.10 is the latest stable release of Python and Python 3.11 is due" " to be released in October. This Flower release adds experimental support" @@ -20355,13 +21113,13 @@ msgstr "" "Python 3.10 是 Python 的最新稳定版本,Python 3.11 将于 10 月份发布。Flower 版本增加了对这两个 " "Python 版本的实验支持。" -#: ../../source/ref-changelog.md:736 +#: ../../source/ref-changelog.md:828 msgid "" "**Aggregate custom metrics through user-provided functions** " "([#1144](https://github.com/adap/flower/pull/1144))" msgstr "**通过用户提供的函数聚合自定义指标**([#1144](https://github.com/adap/flower/pull/1144))" -#: ../../source/ref-changelog.md:738 +#: ../../source/ref-changelog.md:830 msgid "" "Custom metrics (e.g., `accuracy`) can now be aggregated without having to" " customize the strategy. Built-in strategies support two new arguments, " @@ -20371,13 +21129,13 @@ msgstr "" "现在无需定制策略即可聚合自定义度量(如`准确度`)。内置策略支持两个新参数:`fit_metrics_aggregation_fn` " "和`evaluate_metrics_aggregation_fn`,允许传递自定义度量聚合函数。" -#: ../../source/ref-changelog.md:740 +#: ../../source/ref-changelog.md:832 msgid "" "**User-configurable round timeout** " "([#1162](https://github.com/adap/flower/pull/1162))" msgstr "**用户可配置的回合超时**([#1162](https://github.com/adap/flower/pull/1162))" -#: ../../source/ref-changelog.md:742 +#: ../../source/ref-changelog.md:834 msgid "" "A new configuration value allows the round timeout to be set for " "`start_server` and `start_simulation`. If the `config` dictionary " @@ -20388,7 +21146,7 @@ msgstr "" "新的配置值允许为 `start_server` 和 `start_simulation` 设置回合超时。如果 `config` 字典中包含一个 " "`round_timeout` 键(以秒为单位的 `float`值),服务器将至少等待 ** `round_timeout` 秒后才关闭连接。" -#: ../../source/ref-changelog.md:744 +#: ../../source/ref-changelog.md:836 msgid "" "**Enable both federated evaluation and centralized evaluation to be used " "at the same time in all built-in strategies** " @@ -20397,7 +21155,7 @@ msgstr "" "**允许在所有内置策略中同时使用联邦评价和集中评估** " "([#1091](https://github.com/adap/flower/pull/1091))" -#: ../../source/ref-changelog.md:746 +#: ../../source/ref-changelog.md:838 msgid "" "Built-in strategies can now perform both federated evaluation (i.e., " "client-side) and centralized evaluation (i.e., server-side) in the same " @@ -20407,7 +21165,7 @@ msgstr "" "内置策略现在可以在同一轮中同时执行联邦评估(即客户端)和集中评估(即服务器端)。可以通过将 `fraction_eval` 设置为 " "`0.0`来禁用联邦评估。" -#: ../../source/ref-changelog.md:748 +#: ../../source/ref-changelog.md:840 msgid "" "**Two new Jupyter Notebook tutorials** " "([#1141](https://github.com/adap/flower/pull/1141))" @@ -20415,13 +21173,13 @@ msgstr "" "**两本新的 Jupyter Notebook 教程** " "([#1141](https://github.com/adap/flower/pull/1141))" -#: ../../source/ref-changelog.md:750 +#: ../../source/ref-changelog.md:842 msgid "" "Two Jupyter Notebook tutorials (compatible with Google Colab) explain " "basic and intermediate Flower features:" msgstr "两本 Jupyter Notebook 教程(与 Google Colab 兼容)介绍了 Flower 的基本和中级功能:" -#: ../../source/ref-changelog.md:752 +#: ../../source/ref-changelog.md:844 msgid "" "*An Introduction to Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" @@ -20431,7 +21189,7 @@ msgstr "" "中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" "-Intro-to-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:754 +#: ../../source/ref-changelog.md:846 msgid "" "*Using Strategies in Federated Learning*: [Open in " "Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" @@ -20441,7 +21199,7 @@ msgstr "" "中打开](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" "-Strategies-in-FL-PyTorch.ipynb)" -#: ../../source/ref-changelog.md:756 +#: ../../source/ref-changelog.md:848 msgid "" "**New FedAvgM strategy (Federated Averaging with Server Momentum)** " "([#1076](https://github.com/adap/flower/pull/1076))" @@ -20449,25 +21207,25 @@ msgstr "" "**新的 FedAvgM 策略(带服务器动量的联邦平均)** " "([#1076](https://github.com/adap/flower/pull/1076))" -#: ../../source/ref-changelog.md:758 +#: ../../source/ref-changelog.md:850 msgid "" "The new `FedAvgM` strategy implements Federated Averaging with Server " "Momentum \\[Hsu et al., 2019\\]." msgstr "新的 \"FedAvgM \"策略实现了带服务器动量的联邦平均[Hsu et al., 2019\\]." -#: ../../source/ref-changelog.md:760 +#: ../../source/ref-changelog.md:852 msgid "" "**New advanced PyTorch code example** " "([#1007](https://github.com/adap/flower/pull/1007))" msgstr "**新的 PyTorch 高级代码示例** ([#1007](https://github.com/adap/flower/pull/1007))" -#: ../../source/ref-changelog.md:762 +#: ../../source/ref-changelog.md:854 msgid "" "A new code example (`advanced_pytorch`) demonstrates advanced Flower " "concepts with PyTorch." msgstr "新代码示例 (`advanced_pytorch`) 演示了 PyTorch 的高级 Flower 概念。" -#: ../../source/ref-changelog.md:764 +#: ../../source/ref-changelog.md:856 msgid "" "**New JAX code example** " "([#906](https://github.com/adap/flower/pull/906), " @@ -20476,13 +21234,13 @@ msgstr "" "**新的 JAX 代码示例**([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143)" -#: ../../source/ref-changelog.md:766 +#: ../../source/ref-changelog.md:858 msgid "" "A new code example (`jax_from_centralized_to_federated`) shows federated " "learning with JAX and Flower." msgstr "新代码示例(`jax_from_centralized_to_federated`)展示了使用 JAX 和 Flower 的联邦学习。" -#: ../../source/ref-changelog.md:770 +#: ../../source/ref-changelog.md:862 msgid "" "New option to keep Ray running if Ray was already initialized in " "`start_simulation` ([#1177](https://github.com/adap/flower/pull/1177))" @@ -20490,7 +21248,7 @@ msgstr "" "新增选项,用于在 \"start_simulation\"(开始模拟)中已初始化 Ray 的情况下保持 Ray " "运行([#1177](https://github.com/adap/flower/pull/1177))" -#: ../../source/ref-changelog.md:771 +#: ../../source/ref-changelog.md:863 msgid "" "Add support for custom `ClientManager` as a `start_simulation` parameter " "([#1171](https://github.com/adap/flower/pull/1171))" @@ -20498,7 +21256,7 @@ msgstr "" "添加对自定义 \"客户端管理器 \"作为 \"start_simulation " "\"参数的支持([#1171](https://github.com/adap/flower/pull/1171))" -#: ../../source/ref-changelog.md:772 +#: ../../source/ref-changelog.md:864 msgid "" "New documentation for [implementing " "strategies](https://flower.ai/docs/framework/how-to-implement-" @@ -20509,13 +21267,13 @@ msgstr "" " 的新文件([#1097](https://github.com/adap/flower/pull/1097), " "[#1175](https://github.com/adap/flower/pull/1175)" -#: ../../source/ref-changelog.md:773 +#: ../../source/ref-changelog.md:865 msgid "" "New mobile-friendly documentation theme " "([#1174](https://github.com/adap/flower/pull/1174))" msgstr "新的移动友好型文档主题 ([#1174](https://github.com/adap/flower/pull/1174))" -#: ../../source/ref-changelog.md:774 +#: ../../source/ref-changelog.md:866 msgid "" "Limit version range for (optional) `ray` dependency to include only " "compatible releases (`>=1.9.2,<1.12.0`) " @@ -20524,25 +21282,25 @@ msgstr "" "限制(可选)`ray`依赖的版本范围,使其仅包含兼容版本(`>=1.9.2,<1.12.0`) " "([#1205](https://github.com/adap/flower/pull/1205))" -#: ../../source/ref-changelog.md:778 +#: ../../source/ref-changelog.md:870 msgid "" "**Remove deprecated support for Python 3.6** " "([#871](https://github.com/adap/flower/pull/871))" msgstr "**删除对 Python 3.6 的过时支持** ([#871](https://github.com/adap/flower/pull/871))" -#: ../../source/ref-changelog.md:779 +#: ../../source/ref-changelog.md:871 msgid "" "**Remove deprecated KerasClient** " "([#857](https://github.com/adap/flower/pull/857))" msgstr "**移除过时的 KerasClient**([#857](https://github.com/adap/flower/pull/857))" -#: ../../source/ref-changelog.md:780 +#: ../../source/ref-changelog.md:872 msgid "" "**Remove deprecated no-op extra installs** " "([#973](https://github.com/adap/flower/pull/973))" msgstr "**移除过时的不操作额外安装** ([#973](https://github.com/adap/flower/pull/973))" -#: ../../source/ref-changelog.md:781 +#: ../../source/ref-changelog.md:873 msgid "" "**Remove deprecated proto fields from** `FitRes` **and** `EvaluateRes` " "([#869](https://github.com/adap/flower/pull/869))" @@ -20550,7 +21308,7 @@ msgstr "" "**从** `FitRes` **和** `EvaluateRes` 中移除已废弃的 proto 字段 " "([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:782 +#: ../../source/ref-changelog.md:874 msgid "" "**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " "([#1107](https://github.com/adap/flower/pull/1107))" @@ -20558,7 +21316,7 @@ msgstr "" "**移除过时的 QffedAvg 策略(由 QFedAvg 取代)** " "([#1107](https://github.com/adap/flower/pull/1107))" -#: ../../source/ref-changelog.md:783 +#: ../../source/ref-changelog.md:875 msgid "" "**Remove deprecated DefaultStrategy strategy** " "([#1142](https://github.com/adap/flower/pull/1142))" @@ -20566,7 +21324,7 @@ msgstr "" "**删除过时的 DefaultStrategy 策略** " "([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:784 +#: ../../source/ref-changelog.md:876 msgid "" "**Remove deprecated support for eval_fn accuracy return value** " "([#1142](https://github.com/adap/flower/pull/1142))" @@ -20574,7 +21332,7 @@ msgstr "" "**删除已过时的对 eval_fn 返回值准确性的支持** " "([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:785 +#: ../../source/ref-changelog.md:877 msgid "" "**Remove deprecated support for passing initial parameters as NumPy " "ndarrays** ([#1142](https://github.com/adap/flower/pull/1142))" @@ -20582,11 +21340,11 @@ msgstr "" "**移除对以 NumPy ndarrays 传递初始参数的过时支持** " "([#1142](https://github.com/adap/flower/pull/1142))" -#: ../../source/ref-changelog.md:787 +#: ../../source/ref-changelog.md:879 msgid "v0.18.0 (2022-02-28)" msgstr "v0.18.0 (2022-02-28)" -#: ../../source/ref-changelog.md:791 +#: ../../source/ref-changelog.md:883 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " "Google Colab** ([#866](https://github.com/adap/flower/pull/866), " @@ -20600,7 +21358,7 @@ msgstr "" "[#833](https://github.com/adap/flower/pull/833), " "[#1036](https://github.com/adap/flower/pull/1036))" -#: ../../source/ref-changelog.md:793 +#: ../../source/ref-changelog.md:885 msgid "" "Simulations (using the Virtual Client Engine through `start_simulation`) " "now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " @@ -20611,7 +21369,7 @@ msgstr "" "`simulation` (`pip install flwr[simulation]`)后,模拟(通过 `start_simulation` " "使用虚拟客户端引擎)现在可以更流畅地运行。" -#: ../../source/ref-changelog.md:795 +#: ../../source/ref-changelog.md:887 msgid "" "**New Jupyter Notebook code example** " "([#833](https://github.com/adap/flower/pull/833))" @@ -20619,7 +21377,7 @@ msgstr "" "**新的 Jupyter Notebook 代码示例** " "([#833](https://github.com/adap/flower/pull/833))" -#: ../../source/ref-changelog.md:797 +#: ../../source/ref-changelog.md:889 msgid "" "A new code example (`quickstart_simulation`) demonstrates Flower " "simulations using the Virtual Client Engine through Jupyter Notebook " @@ -20628,25 +21386,25 @@ msgstr "" "新代码示例(`quickstart_simulation`)通过 Jupyter Notebook(包括 Google " "Colab)演示了使用虚拟客户端引擎进行 Flower 模拟。" -#: ../../source/ref-changelog.md:799 +#: ../../source/ref-changelog.md:891 msgid "" "**Client properties (feature preview)** " "([#795](https://github.com/adap/flower/pull/795))" msgstr "**客户端属性(功能预览)** ([#795](https://github.com/adap/flower/pull/795))" -#: ../../source/ref-changelog.md:801 +#: ../../source/ref-changelog.md:893 msgid "" "Clients can implement a new method `get_properties` to enable server-side" " strategies to query client properties." msgstr "客户端可以实现一个新方法 `get_properties`,以启用服务器端策略来查询客户端属性。" -#: ../../source/ref-changelog.md:803 +#: ../../source/ref-changelog.md:895 msgid "" "**Experimental Android support with TFLite** " "([#865](https://github.com/adap/flower/pull/865))" msgstr "** 使用 TFLite 实验性支持安卓系统** ([#865](https://github.com/adap/flower/pull/865))" -#: ../../source/ref-changelog.md:805 +#: ../../source/ref-changelog.md:897 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " @@ -20656,7 +21414,7 @@ msgstr "" "`main`终于支持 Android 了!Flower 的设计与客户端和框架无关。我们可以集成任意客户端平台,有了这个版本,在安卓系统上使用 " "Flower 就变得更容易了。" -#: ../../source/ref-changelog.md:807 +#: ../../source/ref-changelog.md:899 msgid "" "The example uses TFLite on the client side, along with a new " "`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " @@ -20668,7 +21426,7 @@ msgstr "" "`FedAvgAndroid`仍处于试验阶段,但这是向成熟的 Android SDK 和集成了 `FedAvgAndroid`新功能的统一 " "`FedAvg`实现迈出的第一步。" -#: ../../source/ref-changelog.md:809 +#: ../../source/ref-changelog.md:901 msgid "" "**Make gRPC keepalive time user-configurable and decrease default " "keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" @@ -20676,7 +21434,7 @@ msgstr "" "**使 gRPC 保持连接时间可由用户配置,并缩短默认保持连接时间** " "([#1069](https://github.com/adap/flower/pull/1069))" -#: ../../source/ref-changelog.md:811 +#: ../../source/ref-changelog.md:903 msgid "" "The default gRPC keepalive time has been reduced to increase the " "compatibility of Flower with more cloud environments (for example, " @@ -20686,7 +21444,7 @@ msgstr "" "为提高 Flower 与更多云环境(如 Microsoft Azure)的兼容性,缩短了默认 gRPC 保持时间。用户可以根据具体要求配置 " "keepalive 时间,自定义 gRPC 堆栈。" -#: ../../source/ref-changelog.md:813 +#: ../../source/ref-changelog.md:905 msgid "" "**New differential privacy example using Opacus and PyTorch** " "([#805](https://github.com/adap/flower/pull/805))" @@ -20694,13 +21452,13 @@ msgstr "" "**使用 Opacus 和 PyTorch 的新差分隐私示例** " "([#805](https://github.com/adap/flower/pull/805))" -#: ../../source/ref-changelog.md:815 +#: ../../source/ref-changelog.md:907 msgid "" "A new code example (`opacus`) demonstrates differentially-private " "federated learning with Opacus, PyTorch, and Flower." msgstr "一个新的代码示例(\"opacus\")演示了使用 Opacus、PyTorch 和 Flower 进行差分隐私的联邦学习。" -#: ../../source/ref-changelog.md:817 +#: ../../source/ref-changelog.md:909 msgid "" "**New Hugging Face Transformers code example** " "([#863](https://github.com/adap/flower/pull/863))" @@ -20708,13 +21466,13 @@ msgstr "" "**新的Hugging Face Transformers代码示例** " "([#863](https://github.com/adap/flower/pull/863))" -#: ../../source/ref-changelog.md:819 +#: ../../source/ref-changelog.md:911 msgid "" "A new code example (`quickstart_huggingface`) demonstrates usage of " "Hugging Face Transformers with Flower." msgstr "新的代码示例(`quickstart_huggingface`)证明了结合Flower和Hugging Face Transformers的实用性。" -#: ../../source/ref-changelog.md:821 +#: ../../source/ref-changelog.md:913 msgid "" "**New MLCube code example** " "([#779](https://github.com/adap/flower/pull/779), " @@ -20727,13 +21485,13 @@ msgstr "" "[#1065](https://github.com/adap/flower/pull/1065), " "[#1090](https://github.com/adap/flower/pull/1090))" -#: ../../source/ref-changelog.md:823 +#: ../../source/ref-changelog.md:915 msgid "" "A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " "with Flower." msgstr "新代码示例(\"quickstart_mlcube\")演示了 MLCube 与 Flower 的用法。" -#: ../../source/ref-changelog.md:825 +#: ../../source/ref-changelog.md:917 msgid "" "**SSL-enabled server and client** " "([#842](https://github.com/adap/flower/pull/842), " @@ -20750,14 +21508,14 @@ msgstr "" "[#993](https://github.com/adap/flower/pull/993), " "[#994](https://github.com/adap/flower/pull/994))" -#: ../../source/ref-changelog.md:827 +#: ../../source/ref-changelog.md:919 msgid "" "SSL enables secure encrypted connections between clients and servers. " "This release open-sources the Flower secure gRPC implementation to make " "encrypted communication channels accessible to all Flower users." msgstr "SSL 可实现客户端与服务器之间的安全加密连接。该版本开源了 Flower 安全 gRPC 实现,使所有 Flower 用户都能访问加密通信通道。" -#: ../../source/ref-changelog.md:829 +#: ../../source/ref-changelog.md:921 msgid "" "**Updated** `FedAdam` **and** `FedYogi` **strategies** " "([#885](https://github.com/adap/flower/pull/885), " @@ -20767,13 +21525,13 @@ msgstr "" "([#885](https://github.com/adap/flower/pull/885), " "[#895](https://github.com/adap/flower/pull/895))" -#: ../../source/ref-changelog.md:831 +#: ../../source/ref-changelog.md:923 msgid "" "`FedAdam` and `FedAdam` match the latest version of the Adaptive " "Federated Optimization paper." msgstr "FedAdam \"和 \"FedAdam \"与最新版本的 \"自适应联邦优化 \"论文相匹配。" -#: ../../source/ref-changelog.md:833 +#: ../../source/ref-changelog.md:925 msgid "" "**Initialize** `start_simulation` **with a list of client IDs** " "([#860](https://github.com/adap/flower/pull/860))" @@ -20781,7 +21539,7 @@ msgstr "" "**初始化** `start_simulation` **使用客户端 ID 列表** " "([#860](https://github.com/adap/flower/pull/860))" -#: ../../source/ref-changelog.md:835 +#: ../../source/ref-changelog.md:927 msgid "" "`start_simulation` can now be called with a list of client IDs " "(`clients_ids`, type: `List[str]`). Those IDs will be passed to the " @@ -20793,7 +21551,7 @@ msgstr "" "`start_simulation`。每当需要初始化客户端时,这些 ID 就会被传递到 `client_fn` 中,这样就能更轻松地加载无法通过 " "`int` 标识符访问的数据分区。" -#: ../../source/ref-changelog.md:839 +#: ../../source/ref-changelog.md:931 msgid "" "Update `num_examples` calculation in PyTorch code examples in " "([#909](https://github.com/adap/flower/pull/909))" @@ -20801,7 +21559,7 @@ msgstr "" "更新 PyTorch 代码示例中的 \"num_examples \"计算 " "([#909](https://github.com/adap/flower/pull/909))" -#: ../../source/ref-changelog.md:840 +#: ../../source/ref-changelog.md:932 msgid "" "Expose Flower version through `flwr.__version__` " "([#952](https://github.com/adap/flower/pull/952))" @@ -20809,7 +21567,7 @@ msgstr "" "通过 `flwr.__version__` 公开 Flower 版本 " "([#952](https://github.com/adap/flower/pull/952))" -#: ../../source/ref-changelog.md:841 +#: ../../source/ref-changelog.md:933 msgid "" "`start_server` in `app.py` now returns a `History` object containing " "metrics from training ([#974](https://github.com/adap/flower/pull/974))" @@ -20817,7 +21575,7 @@ msgstr "" "`app.py`中的 `start_server`现在会返回一个 `History` " "对象,其中包含训练中的指标([#974](https://github.com/adap/flower/pull/974))" -#: ../../source/ref-changelog.md:842 +#: ../../source/ref-changelog.md:934 msgid "" "Make `max_workers` (used by `ThreadPoolExecutor`) configurable " "([#978](https://github.com/adap/flower/pull/978))" @@ -20825,25 +21583,25 @@ msgstr "" "使 `max_workers`(由 " "`ThreadPoolExecutor`使用)可配置([#978](https://github.com/adap/flower/pull/978))" -#: ../../source/ref-changelog.md:843 +#: ../../source/ref-changelog.md:935 msgid "" "Increase sleep time after server start to three seconds in all code " "examples ([#1086](https://github.com/adap/flower/pull/1086))" msgstr "在所有代码示例中,将服务器启动后的休眠时间延长至三秒([#1086](https://github.com/adap/flower/pull/1086))" -#: ../../source/ref-changelog.md:844 +#: ../../source/ref-changelog.md:936 msgid "" "Added a new FAQ section to the documentation " "([#948](https://github.com/adap/flower/pull/948))" msgstr "在文档中添加了新的常见问题部分 ([#948](https://github.com/adap/flower/pull/948))" -#: ../../source/ref-changelog.md:845 +#: ../../source/ref-changelog.md:937 msgid "" "And many more under-the-hood changes, library updates, documentation " "changes, and tooling improvements!" msgstr "还有更多底层更改、库更新、文档更改和工具改进!" -#: ../../source/ref-changelog.md:849 +#: ../../source/ref-changelog.md:941 msgid "" "**Removed** `flwr_example` **and** `flwr_experimental` **from release " "build** ([#869](https://github.com/adap/flower/pull/869))" @@ -20851,7 +21609,7 @@ msgstr "" "**从发布版中删除**`flwr_example`**和**`flwr_experimental`** " "([#869](https://github.com/adap/flower/pull/869))" -#: ../../source/ref-changelog.md:851 +#: ../../source/ref-changelog.md:943 msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " @@ -20863,11 +21621,11 @@ msgstr "" "Flower 的发布版本中。相关的额外包(`baseline`, `examples-pytorch`, `examples-" "tensorflow`, `http-logger`, `ops`)现在已不再使用,并将在即将发布的版本中移除。" -#: ../../source/ref-changelog.md:853 +#: ../../source/ref-changelog.md:945 msgid "v0.17.0 (2021-09-24)" msgstr "v0.17.0 (2021-09-24)" -#: ../../source/ref-changelog.md:857 +#: ../../source/ref-changelog.md:949 msgid "" "**Experimental virtual client engine** " "([#781](https://github.com/adap/flower/pull/781) " @@ -20878,7 +21636,7 @@ msgstr "" "[#790](https://github.com/adap/flower/pull/790) " "[#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:859 +#: ../../source/ref-changelog.md:951 msgid "" "One of Flower's goals is to enable research at scale. This release " "enables a first (experimental) peek at a major new feature, codenamed the" @@ -20891,7 +21649,7 @@ msgstr "" "\"的重要新功能。虚拟客户端可以在单台机器或计算集群上对大量客户端进行模拟。测试新功能的最简单方法是查看名为 " "\"quickstart_simulation \"和 \"simulation_pytorch \"的两个新代码示例。" -#: ../../source/ref-changelog.md:861 +#: ../../source/ref-changelog.md:953 msgid "" "The feature is still experimental, so there's no stability guarantee for " "the API. It's also not quite ready for prime time and comes with a few " @@ -20901,7 +21659,7 @@ msgstr "" "该功能仍处于试验阶段,因此无法保证 API " "的稳定性。此外,它还没有完全准备好进入黄金时间,并有一些已知的注意事项。不过,我们鼓励好奇的用户尝试使用并分享他们的想法。" -#: ../../source/ref-changelog.md:863 +#: ../../source/ref-changelog.md:955 msgid "" "**New built-in strategies** " "([#828](https://github.com/adap/flower/pull/828) " @@ -20910,19 +21668,19 @@ msgstr "" "**新的内置策略**([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822)" -#: ../../source/ref-changelog.md:865 +#: ../../source/ref-changelog.md:957 msgid "" "FedYogi - Federated learning strategy using Yogi on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "FedYogi - 在服务器端使用 Yogi 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" -#: ../../source/ref-changelog.md:866 +#: ../../source/ref-changelog.md:958 msgid "" "FedAdam - Federated learning strategy using Adam on server-side. " "Implementation based on https://arxiv.org/abs/2003.00295" msgstr "FedAdam - 在服务器端使用 Adam 的联邦学习策略。基于 https://arxiv.org/abs/2003.00295 实现" -#: ../../source/ref-changelog.md:868 +#: ../../source/ref-changelog.md:960 msgid "" "**New PyTorch Lightning code example** " "([#617](https://github.com/adap/flower/pull/617))" @@ -20930,31 +21688,31 @@ msgstr "" "**新的 PyTorch Lightning 代码示例** " "([#617](https://github.com/adap/flower/pull/617))" -#: ../../source/ref-changelog.md:870 +#: ../../source/ref-changelog.md:962 msgid "" "**New Variational Auto-Encoder code example** " "([#752](https://github.com/adap/flower/pull/752))" msgstr "**新的变分自动编码器代码示例** ([#752](https://github.com/adap/flower/pull/752))" -#: ../../source/ref-changelog.md:872 +#: ../../source/ref-changelog.md:964 msgid "" "**New scikit-learn code example** " "([#748](https://github.com/adap/flower/pull/748))" msgstr "**新的 scikit-learn 代码示例** ([#748](https://github.com/adap/flower/pull/748))" -#: ../../source/ref-changelog.md:874 +#: ../../source/ref-changelog.md:966 msgid "" "**New experimental TensorBoard strategy** " "([#789](https://github.com/adap/flower/pull/789))" msgstr "**新的实验性 TensorBoard 策略**([#789](https://github.com/adap/flower/pull/789))" -#: ../../source/ref-changelog.md:878 +#: ../../source/ref-changelog.md:970 msgid "" "Improved advanced TensorFlow code example " "([#769](https://github.com/adap/flower/pull/769))" msgstr "改进的高级 TensorFlow 代码示例([#769](https://github.com/adap/flower/pull/769)" -#: ../../source/ref-changelog.md:879 +#: ../../source/ref-changelog.md:971 msgid "" "Warning when `min_available_clients` is misconfigured " "([#830](https://github.com/adap/flower/pull/830))" @@ -20962,31 +21720,31 @@ msgstr "" "当 `min_available_clients` 配置错误时发出警告 " "([#830](https://github.com/adap/flower/pull/830))" -#: ../../source/ref-changelog.md:880 +#: ../../source/ref-changelog.md:972 msgid "" "Improved gRPC server docs " "([#841](https://github.com/adap/flower/pull/841))" msgstr "改进了 gRPC 服务器文档([#841](https://github.com/adap/flower/pull/841))" -#: ../../source/ref-changelog.md:881 +#: ../../source/ref-changelog.md:973 msgid "" "Improved error message in `NumPyClient` " "([#851](https://github.com/adap/flower/pull/851))" msgstr "改进了 `NumPyClient` 中的错误信息 ([#851](https://github.com/adap/flower/pull/851))" -#: ../../source/ref-changelog.md:882 +#: ../../source/ref-changelog.md:974 msgid "" "Improved PyTorch quickstart code example " "([#852](https://github.com/adap/flower/pull/852))" msgstr "改进的 PyTorch 快速启动代码示例 ([#852](https://github.com/adap/flower/pull/852))" -#: ../../source/ref-changelog.md:886 +#: ../../source/ref-changelog.md:978 msgid "" "**Disabled final distributed evaluation** " "([#800](https://github.com/adap/flower/pull/800))" msgstr "**禁用最终分布式评价** ([#800](https://github.com/adap/flower/pull/800))" -#: ../../source/ref-changelog.md:888 +#: ../../source/ref-changelog.md:980 msgid "" "Prior behaviour was to perform a final round of distributed evaluation on" " all connected clients, which is often not required (e.g., when using " @@ -20996,13 +21754,13 @@ msgstr "" "之前的行为是在所有连接的客户端上执行最后一轮分布式评估,而这通常是不需要的(例如,在使用服务器端评估时)。可以通过向 `start_server`" " 传递 `force_final_distributed_eval=True` 来启用之前的行为。" -#: ../../source/ref-changelog.md:890 +#: ../../source/ref-changelog.md:982 msgid "" "**Renamed q-FedAvg strategy** " "([#802](https://github.com/adap/flower/pull/802))" msgstr "**更名为 q-FedAvg 策略** ([#802](https://github.com/adap/flower/pull/802))" -#: ../../source/ref-changelog.md:892 +#: ../../source/ref-changelog.md:984 msgid "" "The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " "the notation given in the original paper (q-FFL is the optimization " @@ -21013,7 +21771,7 @@ msgstr "" "名为 `QffedAvg` 的策略已更名为 `QFedAvg`,以更好地反映原始论文中给出的符号(q-FFL 是优化目标,q-FedAvg " "是建议的求解器)。请注意,出于兼容性原因,原始(现已废弃)的 `QffedAvg` 类仍然可用(它将在未来的版本中移除)。" -#: ../../source/ref-changelog.md:894 +#: ../../source/ref-changelog.md:986 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " "`simulation_pytorch_legacy` " @@ -21022,7 +21780,7 @@ msgstr "" "**删除并重命名代码示例**`simulation_pytorch`**为**`simulation_pytorch_legacy` " "([#791](https://github.com/adap/flower/pull/791))" -#: ../../source/ref-changelog.md:896 +#: ../../source/ref-changelog.md:988 msgid "" "This example has been replaced by a new example. The new example is based" " on the experimental virtual client engine, which will become the new " @@ -21033,27 +21791,27 @@ msgstr "" "该示例已被新示例取代。新示例基于试验性虚拟客户端引擎,它将成为在 Flower " "中进行大多数类型大规模模拟的新的默认方式。现有示例将作为参考保留,但将来可能会删除。" -#: ../../source/ref-changelog.md:898 +#: ../../source/ref-changelog.md:990 msgid "v0.16.0 (2021-05-11)" msgstr "v0.16.0 (2021-05-11)" -#: ../../source/ref-changelog.md:902 +#: ../../source/ref-changelog.md:994 msgid "" "**New built-in strategies** " "([#549](https://github.com/adap/flower/pull/549))" msgstr "**新的内置策略** ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:904 +#: ../../source/ref-changelog.md:996 msgid "(abstract) FedOpt" msgstr "(摘要) FedOpt" -#: ../../source/ref-changelog.md:907 +#: ../../source/ref-changelog.md:999 msgid "" "**Custom metrics for server and strategies** " "([#717](https://github.com/adap/flower/pull/717))" msgstr "**服务器和策略的自定义指标** ([#717](https://github.com/adap/flower/pull/717))" -#: ../../source/ref-changelog.md:909 +#: ../../source/ref-changelog.md:1001 msgid "" "The Flower server is now fully task-agnostic, all remaining instances of " "task-specific metrics (such as `accuracy`) have been replaced by custom " @@ -21064,7 +21822,7 @@ msgstr "" "Flower 服务器现在完全与任务无关,所有剩余的任务特定度量(如 \"准确度\")都已被自定义度量字典取代。Flower 0.15 " "引入了从客户端向服务器传递包含自定义指标的字典的功能。从本版本开始,自定义指标将取代服务器上的特定任务指标。" -#: ../../source/ref-changelog.md:911 +#: ../../source/ref-changelog.md:1003 msgid "" "Custom metric dictionaries are now used in two user-facing APIs: they are" " returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " @@ -21077,7 +21835,7 @@ msgstr "" "返回,还可使传递给内置策略(通过 `eval_fn`)的评估函数返回两个以上的评估度量。策略甚至可以返回 *aggregated* " "指标字典,以便服务器跟踪。" -#: ../../source/ref-changelog.md:913 +#: ../../source/ref-changelog.md:1005 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " @@ -21088,19 +21846,19 @@ msgstr "" "方法迁移到新的返回类型(例如,只需返回空的 `{}`),服务器端评估函数应从 `return loss, accuracy` 迁移到 " "`return loss, {\"accuracy\": accuracy}`。" -#: ../../source/ref-changelog.md:915 +#: ../../source/ref-changelog.md:1007 msgid "" "Flower 0.15-style return types are deprecated (but still supported), " "compatibility will be removed in a future release." msgstr "Flower 0.15 风格的返回类型已被弃用(但仍受支持),兼容性将在未来的版本中移除。" -#: ../../source/ref-changelog.md:917 +#: ../../source/ref-changelog.md:1009 msgid "" "**Migration warnings for deprecated functionality** " "([#690](https://github.com/adap/flower/pull/690))" msgstr "** 过时功能的迁移警告** ([#690](https://github.com/adap/flower/pull/690))" -#: ../../source/ref-changelog.md:919 +#: ../../source/ref-changelog.md:1011 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " "maintaining compatibility with legacy APIs. This release introduces " @@ -21111,7 +21869,7 @@ msgstr "" "Flower 早期版本通常会迁移到新的应用程序接口,同时保持与旧版应用程序接口的兼容。如果检测到使用了过时的 " "API,本版本将引入详细的警告信息。新的警告信息通常会详细说明如何迁移到更新的 API,从而简化从一个版本到另一个版本的过渡。" -#: ../../source/ref-changelog.md:921 +#: ../../source/ref-changelog.md:1013 msgid "" "Improved docs and docstrings " "([#691](https://github.com/adap/flower/pull/691) " @@ -21122,11 +21880,11 @@ msgstr "" "[#692](https://github.com/adap/flower/pull/692) " "[#713](https://github.com/adap/flower/pull/713))" -#: ../../source/ref-changelog.md:923 +#: ../../source/ref-changelog.md:1015 msgid "MXNet example and documentation" msgstr "MXNet 示例和文档" -#: ../../source/ref-changelog.md:925 +#: ../../source/ref-changelog.md:1017 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " "([#696](https://github.com/adap/flower/pull/696) " @@ -21138,13 +21896,13 @@ msgstr "" "[#702](https://github.com/adap/flower/pull/702) " "[#705](https://github.com/adap/flower/pull/705))" -#: ../../source/ref-changelog.md:929 +#: ../../source/ref-changelog.md:1021 msgid "" "**Serialization-agnostic server** " "([#721](https://github.com/adap/flower/pull/721))" msgstr "**序列化无关服务器** ([#721](https://github.com/adap/flower/pull/721))" -#: ../../source/ref-changelog.md:931 +#: ../../source/ref-changelog.md:1023 msgid "" "The Flower server is now fully serialization-agnostic. Prior usage of " "class `Weights` (which represents parameters as deserialized NumPy " @@ -21158,7 +21916,7 @@ msgstr "" "`Parameters` 类取代(例如在 `Strategy`中)。参数 " "\"对象与序列化完全无关,它以字节数组的形式表示参数,\"tensor_type \"属性表示如何解释这些字节数组(例如,用于序列化/反序列化)。" -#: ../../source/ref-changelog.md:933 +#: ../../source/ref-changelog.md:1025 msgid "" "Built-in strategies implement this approach by handling serialization and" " deserialization to/from `Weights` internally. Custom/3rd-party Strategy " @@ -21170,7 +21928,7 @@ msgstr "" "内置策略通过在内部处理序列化和反序列化到/从`Weights`来实现这种方法。自定义/第三方策略实现应更新为稍有改动的策略方法定义。策略作者可查阅" " PR [#721](https://github.com/adap/flower/pull/721) 以了解如何将策略轻松迁移到新格式。" -#: ../../source/ref-changelog.md:935 +#: ../../source/ref-changelog.md:1027 msgid "" "Deprecated `flwr.server.Server.evaluate`, use " "`flwr.server.Server.evaluate_round` instead " @@ -21179,17 +21937,17 @@ msgstr "" "已弃用 `flwr.server.Server.evaluate`,改用 " "`flwr.server.Server.evaluate_round`([#717](https://github.com/adap/flower/pull/717)" -#: ../../source/ref-changelog.md:937 +#: ../../source/ref-changelog.md:1029 msgid "v0.15.0 (2021-03-12)" msgstr "v0.15.0 (2021-03-12)" -#: ../../source/ref-changelog.md:941 +#: ../../source/ref-changelog.md:1033 msgid "" "**Server-side parameter initialization** " "([#658](https://github.com/adap/flower/pull/658))" msgstr "**服务器端参数初始化** ([#658](https://github.com/adap/flower/pull/658))" -#: ../../source/ref-changelog.md:943 +#: ../../source/ref-changelog.md:1035 msgid "" "Model parameters can now be initialized on the server-side. Server-side " "parameter initialization works via a new `Strategy` method called " @@ -21198,7 +21956,7 @@ msgstr "" "现在可以在服务器端初始化模型参数。服务器端参数初始化通过名为 \"initialize_parameters \"的新 \"Strategy " "\"方法进行。" -#: ../../source/ref-changelog.md:945 +#: ../../source/ref-changelog.md:1037 msgid "" "Built-in strategies support a new constructor argument called " "`initial_parameters` to set the initial parameters. Built-in strategies " @@ -21208,7 +21966,7 @@ msgstr "" "内置策略支持名为 \"initial_parameters " "\"的新构造函数参数,用于设置初始参数。内置策略会在启动时向服务器提供这些初始参数,然后删除它们以释放内存。" -#: ../../source/ref-changelog.md:964 +#: ../../source/ref-changelog.md:1056 msgid "" "If no initial parameters are provided to the strategy, the server will " "continue to use the current behaviour (namely, it will ask one of the " @@ -21216,11 +21974,7 @@ msgid "" "parameters)." msgstr "如果没有向策略提供初始参数,服务器将继续使用当前行为(即向其中一个已连接的客户端询问参数,并将这些参数用作初始全局参数)。" -#: ../../source/ref-changelog.md:966 -msgid "Deprecations" -msgstr "停用" - -#: ../../source/ref-changelog.md:968 +#: ../../source/ref-changelog.md:1060 msgid "" "Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " "`flwr.server.strategy.FedAvg`, which is equivalent)" @@ -21228,11 +21982,11 @@ msgstr "" "停用 `flwr.server.strategy.DefaultStrategy`(迁移到等价的 " "`flwr.server.strategy.FedAvg`)" -#: ../../source/ref-changelog.md:970 +#: ../../source/ref-changelog.md:1062 msgid "v0.14.0 (2021-02-18)" msgstr "v0.14.0 (2021-02-18)" -#: ../../source/ref-changelog.md:974 +#: ../../source/ref-changelog.md:1066 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " "([#610](https://github.com/adap/flower/pull/610) " @@ -21244,7 +21998,7 @@ msgstr "" "[#572](https://github.com/adap/flower/pull/572) " "[#633](https://github.com/adap/flower/pull/633))" -#: ../../source/ref-changelog.md:976 +#: ../../source/ref-changelog.md:1068 msgid "" "Clients can now return an additional dictionary mapping `str` keys to " "values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " @@ -21255,7 +22009,7 @@ msgstr "" "bool`、`bytes`、`float`、`int`、`str`。这意味着我们可以从 `fit`/`evaluate` " "返回几乎任意的值,并在服务器端使用它们!" -#: ../../source/ref-changelog.md:978 +#: ../../source/ref-changelog.md:1070 msgid "" "This improvement also allowed for more consistent return types between " "`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " @@ -21265,7 +22019,7 @@ msgstr "" "这一改进还使 `fit` 和 `evaluate` 之间的返回类型更加一致:`evaluate` 现在应返回一个元组`(float, int, " "dict)`,代表损失、示例数和一个包含特定问题任意值(如准确度)的字典。" -#: ../../source/ref-changelog.md:980 +#: ../../source/ref-changelog.md:1072 msgid "" "In case you wondered: this feature is compatible with existing projects, " "the additional dictionary return value is optional. New code should " @@ -21278,13 +22032,13 @@ msgstr "" "版本兼容(`fit`: `List[np.ndarray], int, Dict[str, Scalar]`,`evaluate`: " "`float, int, Dict[str, Scalar]`)。详见下面的示例。" -#: ../../source/ref-changelog.md:982 +#: ../../source/ref-changelog.md:1074 msgid "" "*Code example:* note the additional dictionary return values in both " "`FlwrClient.fit` and `FlwrClient.evaluate`:" msgstr "*代码示例:* 注意 `FlwrClient.fit` 和 `FlwrClient.evaluate` 中的附加字典返回值:" -#: ../../source/ref-changelog.md:997 +#: ../../source/ref-changelog.md:1089 msgid "" "**Generalized** `config` **argument in** `Client.fit` **and** " "`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" @@ -21292,7 +22046,7 @@ msgstr "" "**在**`Client.fit` " "**和**`Client.evaluate`中泛化**`config`参数([#595](https://github.com/adap/flower/pull/595))" -#: ../../source/ref-changelog.md:999 +#: ../../source/ref-changelog.md:1091 msgid "" "The `config` argument used to be of type `Dict[str, str]`, which means " "that dictionary values were expected to be strings. The new release " @@ -21302,7 +22056,7 @@ msgstr "" "`config`参数曾是 \"字典[str, str]\"类型,这意味着字典值应是字符串。新版本将其扩展为以下类型的值: " "bool`、`bytes`、`float`、`int`、`str`。" -#: ../../source/ref-changelog.md:1001 +#: ../../source/ref-changelog.md:1093 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " "using the `config` dictionary. Yay, no more `str(epochs)` on the server-" @@ -21311,51 +22065,51 @@ msgstr "" "这意味着现在可以使用 `config` 字典向 `fit`/`evaluate` 传递几乎任意的值。耶,服务器端不再需要 " "`str(epochs)`,客户端不再需要 `int(config[\"epochs\"])`!" -#: ../../source/ref-changelog.md:1003 +#: ../../source/ref-changelog.md:1095 msgid "" "*Code example:* note that the `config` dictionary now contains non-`str` " "values in both `Client.fit` and `Client.evaluate`:" msgstr "*代码示例:* 注意 `config` 字典现在在 `Client.fit` 和 `Client.evaluate` 中都包含非 `str` 值:" -#: ../../source/ref-changelog.md:1020 +#: ../../source/ref-changelog.md:1112 msgid "v0.13.0 (2021-01-08)" msgstr "v0.13.0 (2021-01-08)" -#: ../../source/ref-changelog.md:1024 +#: ../../source/ref-changelog.md:1116 msgid "" "New example: PyTorch From Centralized To Federated " "([#549](https://github.com/adap/flower/pull/549))" msgstr "新示例: PyTorch 从集中到联邦 ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:1025 +#: ../../source/ref-changelog.md:1117 msgid "Improved documentation" msgstr "改进文档" -#: ../../source/ref-changelog.md:1026 +#: ../../source/ref-changelog.md:1118 msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "新文档主题 ([#551](https://github.com/adap/flower/pull/551))" -#: ../../source/ref-changelog.md:1027 +#: ../../source/ref-changelog.md:1119 msgid "New API reference ([#554](https://github.com/adap/flower/pull/554))" msgstr "新的 API 参考 ([#554](https://github.com/adap/flower/pull/554))" -#: ../../source/ref-changelog.md:1028 +#: ../../source/ref-changelog.md:1120 msgid "" "Updated examples documentation " "([#549](https://github.com/adap/flower/pull/549))" msgstr "更新了示例文档 ([#549](https://github.com/adap/flower/pull/549))" -#: ../../source/ref-changelog.md:1029 +#: ../../source/ref-changelog.md:1121 msgid "" "Removed obsolete documentation " "([#548](https://github.com/adap/flower/pull/548))" msgstr "删除了过时的文档 ([#548](https://github.com/adap/flower/pull/548))" -#: ../../source/ref-changelog.md:1031 +#: ../../source/ref-changelog.md:1123 msgid "Bugfix:" msgstr "错误修正:" -#: ../../source/ref-changelog.md:1033 +#: ../../source/ref-changelog.md:1125 msgid "" "`Server.fit` does not disconnect clients when finished, disconnecting the" " clients is now handled in `flwr.server.start_server` " @@ -21366,21 +22120,21 @@ msgstr "" "\"中处理的([#553](https://github.com/adap/flower/pull/553) " "[#540](https://github.com/adap/flower/issues/540))。" -#: ../../source/ref-changelog.md:1035 +#: ../../source/ref-changelog.md:1127 msgid "v0.12.0 (2020-12-07)" msgstr "v0.12.0 (2020-12-07)" -#: ../../source/ref-changelog.md:1037 ../../source/ref-changelog.md:1053 +#: ../../source/ref-changelog.md:1129 ../../source/ref-changelog.md:1145 msgid "Important changes:" msgstr "重要变更:" -#: ../../source/ref-changelog.md:1039 +#: ../../source/ref-changelog.md:1131 msgid "" "Added an example for embedded devices " "([#507](https://github.com/adap/flower/pull/507))" msgstr "添加了嵌入式设备示例 ([#507](https://github.com/adap/flower/pull/507))" -#: ../../source/ref-changelog.md:1040 +#: ../../source/ref-changelog.md:1132 msgid "" "Added a new NumPyClient (in addition to the existing KerasClient) " "([#504](https://github.com/adap/flower/pull/504) " @@ -21390,7 +22144,7 @@ msgstr "" "之外)([#504](https://github.com/adap/flower/pull/504) " "[#508](https://github.com/adap/flower/pull/508)" -#: ../../source/ref-changelog.md:1041 +#: ../../source/ref-changelog.md:1133 msgid "" "Deprecated `flwr_example` package and started to migrate examples into " "the top-level `examples` directory " @@ -21401,15 +22155,15 @@ msgstr "" "([#494](https://github.com/adap/flower/pull/494) " "[#512](https://github.com/adap/flower/pull/512))" -#: ../../source/ref-changelog.md:1043 +#: ../../source/ref-changelog.md:1135 msgid "v0.11.0 (2020-11-30)" msgstr "v0.11.0 (2020-11-30)" -#: ../../source/ref-changelog.md:1045 +#: ../../source/ref-changelog.md:1137 msgid "Incompatible changes:" msgstr "不兼容的更改:" -#: ../../source/ref-changelog.md:1047 +#: ../../source/ref-changelog.md:1139 msgid "" "Renamed strategy methods " "([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " @@ -21422,23 +22176,23 @@ msgstr "" "API 的命名。其他公共方法/函数(例如 `Client` 中的每个方法,以及 `Strategy.evaluate`)不使用 `on_` " "前缀,这就是我们从 Strategy 中的四个方法中移除它的原因。迁移时,请相应地重命名以下 `Strategy` 方法:" -#: ../../source/ref-changelog.md:1048 +#: ../../source/ref-changelog.md:1140 msgid "`on_configure_evaluate` => `configure_evaluate`" msgstr "`on_configure_evaluate` => `configure_evaluate`" -#: ../../source/ref-changelog.md:1049 +#: ../../source/ref-changelog.md:1141 msgid "`on_aggregate_evaluate` => `aggregate_evaluate`" msgstr "`on_aggregate_evaluate` => `aggregate_evaluate`" -#: ../../source/ref-changelog.md:1050 +#: ../../source/ref-changelog.md:1142 msgid "`on_configure_fit` => `configure_fit`" msgstr "`on_configure_fit` => `configure_fit`" -#: ../../source/ref-changelog.md:1051 +#: ../../source/ref-changelog.md:1143 msgid "`on_aggregate_fit` => `aggregate_fit`" msgstr "`on_aggregate_fit` => `aggregate_fit`" -#: ../../source/ref-changelog.md:1055 +#: ../../source/ref-changelog.md:1147 msgid "" "Deprecated `DefaultStrategy` " "([#479](https://github.com/adap/flower/pull/479)). To migrate use " @@ -21447,13 +22201,13 @@ msgstr "" "已废弃的 `DefaultStrategy` ([#479](https://github.com/adap/flower/pull/479)) " "。迁移时请使用 `FedAvg`。" -#: ../../source/ref-changelog.md:1056 +#: ../../source/ref-changelog.md:1148 msgid "" "Simplified examples and baselines " "([#484](https://github.com/adap/flower/pull/484))." msgstr "简化示例和baselines([#484](https://github.com/adap/flower/pull/484))。" -#: ../../source/ref-changelog.md:1057 +#: ../../source/ref-changelog.md:1149 msgid "" "Removed presently unused `on_conclude_round` from strategy interface " "([#483](https://github.com/adap/flower/pull/483))." @@ -21461,7 +22215,7 @@ msgstr "" "删除了策略界面中目前未使用的 " "\"on_conclude_round\"([#483](https://github.com/adap/flower/pull/483))。" -#: ../../source/ref-changelog.md:1058 +#: ../../source/ref-changelog.md:1150 msgid "" "Set minimal Python version to 3.6.1 instead of 3.6.9 " "([#471](https://github.com/adap/flower/pull/471))." @@ -21469,7 +22223,7 @@ msgstr "" "将最小 Python 版本设为 3.6.1,而不是 3.6.9 " "([#471](https://github.com/adap/flower/pull/471))." -#: ../../source/ref-changelog.md:1059 +#: ../../source/ref-changelog.md:1151 msgid "" "Improved `Strategy` docstrings " "([#470](https://github.com/adap/flower/pull/470))." @@ -22805,11 +23559,10 @@ msgid "" "training set for each partition ID defined in the :code:`--partition-id` " "argument." msgstr "" -"在本地训练之前,我们需要加载 MNIST " -"数据集(一个用于机器学习的流行手写数字图像分类数据集),并对数据集进行 FL " -"分区。使用 \"Flower Datasets `" -"_\"可以方便地实现这一点。:code:`FederatedDataset.load_partition()` 方法为 " -":code:`--partition-id` 参数中定义的每个分区 ID 加载分区训练集。" +"在本地训练之前,我们需要加载 MNIST 数据集(一个用于机器学习的流行手写数字图像分类数据集),并对数据集进行 FL 分区。使用 " +"\"Flower Datasets " +"`_\"可以方便地实现这一点。:code:`FederatedDataset.load_partition()`" +" 方法为 :code:`--partition-id` 参数中定义的每个分区 ID 加载分区训练集。" #: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" @@ -23400,17 +24153,16 @@ msgid "" "XGBoost trees will be passed to the next client as an initialised model " "for next round's boosting." msgstr "" -"除了袋式聚合,我们还提供了一种循环训练方案,它以逐个客户端的方式执行 FL。在循" -"环训练方案中,每轮只有一个客户端参与训练,而不是多个客户端聚合在一起。" -"训练好的本地 XGBoost 树将传递给下一个客户端,作为下一轮提升的初始化模型。" +"除了袋式聚合,我们还提供了一种循环训练方案,它以逐个客户端的方式执行 " +"FL。在循环训练方案中,每轮只有一个客户端参与训练,而不是多个客户端聚合在一起。训练好的本地 XGBoost " +"树将传递给下一个客户端,作为下一轮提升的初始化模型。" #: ../../source/tutorial-quickstart-xgboost.rst:609 #, fuzzy msgid "" "To do this, we first customise a :code:`ClientManager` in " ":code:`server_utils.py`:" -msgstr "为此,我们首先要在 :code:`server_utils.py` 中自定义一个 " -":code:`ClientManager`:" +msgstr "为此,我们首先要在 :code:`server_utils.py` 中自定义一个 :code:`ClientManager`:" #: ../../source/tutorial-quickstart-xgboost.rst:649 #, fuzzy @@ -23422,10 +24174,9 @@ msgid "" "select only one client in given round and pass the received model to next" " client." msgstr "" -"定制的 :code:`ClientManager` 会根据连接服务器的顺序,在每轮 FL " -"中对所有可用客户端进行采样。然后,我们在 :code:`flwr.server.strategy." -"fedxgb_cyclic.py`\"中定义了一个新策略 :code:`FedXgbCyclic`,以便在给定回合中" -"按顺序只选择一个客户端,并将接收到的模型传递给下一个客户端。" +"定制的 :code:`ClientManager` 会根据连接服务器的顺序,在每轮 FL 中对所有可用客户端进行采样。然后,我们在 " +":code:`flwr.server.strategy.fedxgb_cyclic.py`\"中定义了一个新策略 " +":code:`FedXgbCyclic`,以便在给定回合中按顺序只选择一个客户端,并将接收到的模型传递给下一个客户端。" #: ../../source/tutorial-quickstart-xgboost.rst:690 #, fuzzy @@ -23434,8 +24185,8 @@ msgid "" "Instead, we just make a copy of the received client model as global model" " by overriding :code:`aggregate_fit`." msgstr "" -"与最初的 :code:`FedAvg` 不同,我们在这里不执行聚合。相反,我们只是通过覆盖 " -":code:`aggregate_fit` 将接收到的客户端模型复制为全局模型。" +"与最初的 :code:`FedAvg` 不同,我们在这里不执行聚合。相反,我们只是通过覆盖 :code:`aggregate_fit` " +"将接收到的客户端模型复制为全局模型。" #: ../../source/tutorial-quickstart-xgboost.rst:693 #, fuzzy @@ -23443,8 +24194,8 @@ msgid "" "Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" " methods ensure the clients to be sequentially selected given FL round:" msgstr "" -"此外,定制的 :code:`configure_fit` 和 :code:`configure_evaluate` " -"方法可确保在 FL 轮中按顺序选择客户:" +"此外,定制的 :code:`configure_fit` 和 :code:`configure_evaluate` 方法可确保在 FL " +"轮中按顺序选择客户:" #: ../../source/tutorial-quickstart-xgboost.rst:757 msgid "Customised data partitioning" @@ -23504,9 +24255,7 @@ msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " "capabilities of Flower to simulate federated XGBoost training on either a" " single machine or a cluster of machines." -msgstr "" -"我们还提供了一个示例代码(:code:`sim.py`),用于使用 Flower " -"的模拟功能在单台机器或机器集群上模拟联合 XGBoost 训练。" +msgstr "我们还提供了一个示例代码(:code:`sim.py`),用于使用 Flower 的模拟功能在单台机器或机器集群上模拟联合 XGBoost 训练。" #: ../../source/tutorial-quickstart-xgboost.rst:866 #, fuzzy @@ -23521,8 +24270,7 @@ msgid "" "We first load the dataset and perform data partitioning, and the pre-" "processed data is stored in a :code:`list`. After the simulation begins, " "the clients won't need to pre-process their partitions again." -msgstr "我们首先加载数据集并执行数据分区,预处理后的数据存储在 :code:`list` " -"中。模拟开始后,客户端就不需要再预处理分区了。" +msgstr "我们首先加载数据集并执行数据分区,预处理后的数据存储在 :code:`list` 中。模拟开始后,客户端就不需要再预处理分区了。" #: ../../source/tutorial-quickstart-xgboost.rst:924 #, fuzzy @@ -24325,8 +25073,7 @@ msgid "" "``DataLoader``:" msgstr "" "现在,让我们从 ``flwr-datasets`` 中创建 Federated Dataset 抽象,以分割 " -"CIFAR-10。我们将为每个边缘设备创建小型训练集和测试集,并将它们分别封装到 " -"PyTorch ``DataLoader`` 中:" +"CIFAR-10。我们将为每个边缘设备创建小型训练集和测试集,并将它们分别封装到 PyTorch ``DataLoader`` 中:" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 #, fuzzy @@ -25069,9 +25816,8 @@ msgid "" msgstr "在机器学习中,我们有一个模型和数据。模型可以是一个神经网络(如图所示),也可以是其他东西,比如经典的线性回归。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 -#, fuzzy -msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" -msgstr "|d8bf04f23d9b46d8a23cc6f4887d7873|" +msgid "|93b02017c78049bbbd5ae456dcb2c91b|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 msgid "Model and data" @@ -25085,9 +25831,8 @@ msgid "" msgstr "我们使用数据来训练模型,以完成一项有用的任务。任务可以是检测图像中的物体、转录音频或玩围棋等游戏。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 -#, fuzzy -msgid "|5aa1711387d74d0f8b9c499e1a51627e|" -msgstr "|5aa1711387d74d0f8b9c499e1a51627e|" +msgid "|01471150fd5144c080a176b43e92a3ff|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 msgid "Train model using data" @@ -25107,9 +25852,8 @@ msgid "" msgstr "它源于智能手机上用户与应用程序的交互、汽车上传感器数据的收集、笔记本电脑上键盘输入的接收,或者智能扬声器上某人试着唱的歌。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 -#, fuzzy -msgid "|2bc8e069228d4873804061ff4a95048c|" -msgstr "|2bc8e069228d4873804061ff4a95048c|" +msgid "|9bc21c7dbd17444a8f070c60786e3484|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 msgid "Data on a phone" @@ -25126,9 +25870,8 @@ msgstr "" "\"通常不只是一个地方,而是很多地方。它可能是多个运行同一应用程序的设备。但也可能是多个组织,都在为同一任务生成数据。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 -#, fuzzy -msgid "|c258488766324dc9a6807f0e7c4fd5f4|" -msgstr "|c258488766324dc9a6807f0e7c4fd5f4|" +msgid "|3047bbce54b34099ae559963d0420d79|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 msgid "Data is on many devices" @@ -25143,9 +25886,8 @@ msgid "" msgstr "因此,要使用机器学习或任何类型的数据分析,过去使用的方法是在中央服务器上收集所有数据。这个服务器可以在数据中心的某个地方,也可以在云端的某个地方。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 -#, fuzzy -msgid "|d5f962c3f4ec48529efda980868c14b0|" -msgstr "|d5f962c3f4ec48529efda980868c14b0|" +msgid "|e9f8ce948593444fb838d2f354c7ec5d|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 msgid "Central data collection" @@ -25159,9 +25901,8 @@ msgid "" msgstr "一旦所有数据都收集到一处,我们最终就可以使用机器学习算法在数据上训练我们的模型。这就是我们基本上一直依赖的机器学习方法。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 -#, fuzzy -msgid "|a5eccea18d4c43a68b54b65043cabef8|" -msgstr "|a5eccea18d4c43a68b54b65043cabef8|" +msgid "|c24c1478b30e4f74839208628a842d1e|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 msgid "Central model training" @@ -25180,9 +25921,8 @@ msgid "" msgstr "我们刚刚看到的经典机器学习方法可以在某些情况下使用。很好的例子包括对假日照片进行分类或分析网络流量。在这些案例中,所有数据自然都可以在中央服务器上获得。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 -#, fuzzy -msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" -msgstr "|f17662f7df2d42f68cac70a1fdeda8a7|" +msgid "|1b3613d7a58847b59e1d3180802dbc09|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 msgid "Centralized possible" @@ -25196,9 +25936,8 @@ msgid "" msgstr "但这种方法并不适用于许多其他情况。例如,集中服务器上没有数据,或者一台服务器上的数据不足以训练出一个好的模型。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 -#, fuzzy -msgid "|241fc906441a4f038c625a19d30d01b2|" -msgstr "|241fc906441a4f038c625a19d30d01b2|" +msgid "|9980b5213db547d0b8024a50992b9e3f|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 msgid "Centralized impossible" @@ -25345,9 +26084,8 @@ msgid "" msgstr "我们首先在服务器上初始化模型。这与经典的集中式学习完全相同:我们随机或从先前保存的检查点初始化模型参数。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 -#, fuzzy -msgid "|0aa5aa05810b44b6a835cecce28f3137|" -msgstr "|0aa5aa05810b44b6a835cecce28f3137|" +msgid "|c7afb4c92d154bfaa5e8cb9a150e17f1|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:307 msgid "Initialize global model" @@ -25370,9 +26108,8 @@ msgid "" msgstr "接下来,我们会将全局模型的参数发送到连接的客户端节点(如智能手机等边缘设备或企业的服务器)。这是为了确保每个参与节点都使用相同的模型参数开始本地训练。我们通常只使用几个连接节点,而不是所有节点。这样做的原因是,选择越来越多的客户端节点会导致收益递减。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 -#, fuzzy -msgid "|c742940dd4bf4de09d8d0d5e8d179638|" -msgstr "|c742940dd4bf4de09d8d0d5e8d179638|" +msgid "|032eb6fed6924ac387b9f13854919196|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:309 msgid "Send global model" @@ -25397,9 +26134,8 @@ msgstr "" "(mini-batches)。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 -#, fuzzy -msgid "|1f169ab4601a47e1a226f1628f4ebddb|" -msgstr "|1f169ab4601a47e1a226f1628f4ebddb|" +msgid "|fbf225add7fd4df5a9bf25a95597d954|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:311 msgid "Train on local data" @@ -25421,9 +26157,8 @@ msgid "" msgstr "经过本地训练后,每个客户节点最初收到的模型参数都会略有不同。参数之所以不同,是因为每个客户端节点的本地数据集中都有不同的数据。然后,客户端节点将这些模型更新发回服务器。它们发送的模型更新既可以是完整的模型参数,也可以只是本地训练过程中积累的梯度。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 -#, fuzzy -msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" -msgstr "|12cfa9cde14440ecb8c8f6c1d7185bec|" +msgid "|7efbe3d29d8349b89594e8947e910525|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:313 msgid "Send model updates" @@ -25468,9 +26203,8 @@ msgstr "" " 100 个示例的 10 倍。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 -#, fuzzy -msgid "|72939caf6e294b0986fee6dde96614d7|" -msgstr "|72939caf6e294b0986fee6dde96614d7|" +msgid "|329fb3c04c744eda83bb51fa444c2266|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:315 msgid "Aggregate model updates" @@ -25576,9 +26310,8 @@ msgstr "" "为联邦学习、分析和评估提供了一种统一的方法。它允许用户联邦化任何工作负载、任何 ML 框架和任何编程语言。" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 -#, fuzzy -msgid "|83a8daee45da4a98b8d6f24ae098fc50|" -msgstr "|83a8daee45da4a98b8d6f24ae098fc50|" +msgid "|c00bf2750bc24d229737a0fe1395f0fc|" +msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" @@ -27698,3 +28431,226 @@ msgstr "" #~ msgid "|ff726bc5505e432388ee2fdd6ef420b9|" #~ msgstr "" + +#~ msgid "" +#~ "Currently, Flower provides two images, a" +#~ " ``base`` image and a ``superlink`` " +#~ "image. The base image, as the name" +#~ " suggests, contains basic dependencies that" +#~ " the SuperLink needs. This includes " +#~ "system dependencies, Python and Python " +#~ "tools. The SuperLink image is based " +#~ "on the base image, but it " +#~ "additionally installs the SuperLink using " +#~ "``pip``." +#~ msgstr "" +#~ "目前,Flower " +#~ "提供两个镜像,一个基础镜像和一个服务器镜像。不久还将推出客户端镜像。基础镜像,顾名思义,包含服务器和客户端都需要的基本依赖项。其中包括系统依赖项、Python" +#~ " 和 Python 工具。服务器镜像基于基础镜像,但它会使用 ``pip`` 额外安装" +#~ " Flower 服务器。" + +#~ msgid "``3.11``" +#~ msgstr "``1.0.0rc1``" + +#~ msgid "Defaults to ``22.04``." +#~ msgstr "默认为 ``22.04``。" + +#~ msgid "Building the SuperLink image" +#~ msgstr "启动服务器" + +#~ msgid "Defaults to ``flwr/base``." +#~ msgstr "默认为 ``flwr/server``。" + +#~ msgid "The Python version of the base image." +#~ msgstr "基础镜像的存储库名称。" + +#~ msgid "Defaults to ``py3.11``." +#~ msgstr "默认为 ``22.04``。" + +#~ msgid "Defaults to ``ubuntu22.04``." +#~ msgstr "默认为 ``py3.11-ubuntu22.04``。" + +#~ msgid "Defaults to ``flwr``." +#~ msgstr "默认为 ``flwr/server``。" + +#~ msgid "" +#~ "The name of image is ``flwr_superlink``" +#~ " and the tag ``0.1.0``. Remember that" +#~ " the build arguments as well as " +#~ "the name and tag can be adapted" +#~ " to your needs. These values serve" +#~ " as examples only." +#~ msgstr "图像名称为 ``flwr_server``,标记为 ``0.1.0``。请记住,编译参数以及名称和标记都可以根据需要进行调整。这些值仅供参考。" + +#~ msgid "Creating New Messages" +#~ msgstr "创建新信息" + +#~ msgid "" +#~ "This is a simple guide for " +#~ "creating a new type of message " +#~ "between the server and clients in " +#~ "Flower." +#~ msgstr "这是一个如何用Flower在服务器和客户端之间创建新类型的信息的简要指导。" + +#~ msgid "" +#~ "Let's suppose we have the following " +#~ "example functions in :code:`server.py` and " +#~ ":code:`numpy_client.py`..." +#~ msgstr "假设我们在脚本code:`server.py`和code:`numpy_client.py`中有以下的示例函数..." + +#~ msgid "Server's side:" +#~ msgstr "在服务器端:" + +#~ msgid "Client's side:" +#~ msgstr "在客户端:" + +#~ msgid "" +#~ "Let's now see what we need to " +#~ "implement in order to get this " +#~ "simple function between the server and" +#~ " client to work!" +#~ msgstr "现在让我们来看看,为了让服务器和客户端之间的这个简单的函数正常工作,我们需要实现哪些功能!" + +#~ msgid "Message Types for Protocol Buffers" +#~ msgstr "协议缓冲区的信息类型" + +#~ msgid "" +#~ "The first thing we need to do " +#~ "is to define a message type for" +#~ " the RPC system in :code:`transport.proto`." +#~ " Note that we have to do it " +#~ "for both the request and response " +#~ "messages. For more details on the " +#~ "syntax of proto3, please see the " +#~ "`official documentation `_." +#~ msgstr "" +#~ "我们需要做的第一件事是在脚本code:`transport.proto`中定义 RPC " +#~ "系统的消息类型。请注意,我们必须对请求信息和响应信息都这样做。有关 proto3 语法的更多详情,请参阅官方文档" +#~ " `_。" + +#~ msgid "Within the :code:`ServerMessage` block:" +#~ msgstr "在 :code:`ServerMessage` 代码块中:" + +#~ msgid "Within the ClientMessage block:" +#~ msgstr "在 ClientMessage 代码块中:" + +#~ msgid "" +#~ "Make sure to also add a field " +#~ "of the newly created message type " +#~ "in :code:`oneof msg`." +#~ msgstr "确保在 :code:`oneof msg` 中也添加一个新创建的消息类型字段。" + +#~ msgid "Once that is done, we will compile the file with:" +#~ msgstr "完成后,我们将使用:" + +#~ msgid "If it compiles successfully, you should see the following message:" +#~ msgstr "如果编译成功,你应该会看到以下信息:" + +#~ msgid "Serialization and Deserialization Functions" +#~ msgstr "序列化和反序列化函数" + +#~ msgid "" +#~ "Our next step is to add functions" +#~ " to serialize and deserialize Python " +#~ "datatypes to or from our defined " +#~ "RPC message types. You should add " +#~ "these functions in :code:`serde.py`." +#~ msgstr "" +#~ "下一步是添加函数,以便将 Python 数据类型序列化和反序列化为我们定义的 RPC " +#~ "消息类型或从我们定义的 RPC 消息类型反序列化和反序列化 Python 数据类型。您应该在" +#~ " :code:`serde.py` 中添加这些函数。" + +#~ msgid "The four functions:" +#~ msgstr "四种函数:" + +#~ msgid "Sending the Message from the Server" +#~ msgstr "从服务器发送信息" + +#~ msgid "" +#~ "Now write the request function in " +#~ "your Client Proxy class (e.g., " +#~ ":code:`grpc_client_proxy.py`) using the serde " +#~ "functions you just created:" +#~ msgstr "现在,在客户端代理类(例如 :code:`grpc_client_proxy.py`)中使用刚才创建的 serde 函数编写请求函数:" + +#~ msgid "Receiving the Message by the Client" +#~ msgstr "由客户端接收信息" + +#~ msgid "" +#~ "Last step! Modify the code in " +#~ ":code:`message_handler.py` to check the field" +#~ " of your message and call the " +#~ ":code:`example_response` function. Remember to " +#~ "use the serde functions!" +#~ msgstr "" +#~ "最后一步 修改 :code:`message_handler.py` 中的代码,检查信息的字段并调用" +#~ " :code:`example_response` 函数。记住使用 serde 函数!" + +#~ msgid "Within the handle function:" +#~ msgstr "在句柄函数内:" + +#~ msgid "And add a new function:" +#~ msgstr "并增加一个新函数:" + +#~ msgid "Hopefully, when you run your program you will get the intended result!" +#~ msgstr "希望您在运行程序时能得到预期的结果!" + +#~ msgid ":py:obj:`run_driver_api `\\ \\(\\)" +#~ msgstr ":py:obj:`run_driver_api `\\ \\(\\)" + +#~ msgid "Run Flower server (Driver API)." +#~ msgstr "flower-driver-api" + +#~ msgid ":py:obj:`run_fleet_api `\\ \\(\\)" +#~ msgstr ":py:obj:`run_fleet_api `\\ \\(\\)" + +#~ msgid "Run Flower server (Fleet API)." +#~ msgstr "Flower 服务器。" + +#~ msgid "Unreleased" +#~ msgstr "尚未发布" + +#~ msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" +#~ msgstr "|d8bf04f23d9b46d8a23cc6f4887d7873|" + +#~ msgid "|5aa1711387d74d0f8b9c499e1a51627e|" +#~ msgstr "|5aa1711387d74d0f8b9c499e1a51627e|" + +#~ msgid "|2bc8e069228d4873804061ff4a95048c|" +#~ msgstr "|2bc8e069228d4873804061ff4a95048c|" + +#~ msgid "|c258488766324dc9a6807f0e7c4fd5f4|" +#~ msgstr "|c258488766324dc9a6807f0e7c4fd5f4|" + +#~ msgid "|d5f962c3f4ec48529efda980868c14b0|" +#~ msgstr "|d5f962c3f4ec48529efda980868c14b0|" + +#~ msgid "|a5eccea18d4c43a68b54b65043cabef8|" +#~ msgstr "|a5eccea18d4c43a68b54b65043cabef8|" + +#~ msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" +#~ msgstr "|f17662f7df2d42f68cac70a1fdeda8a7|" + +#~ msgid "|241fc906441a4f038c625a19d30d01b2|" +#~ msgstr "|241fc906441a4f038c625a19d30d01b2|" + +#~ msgid "|0aa5aa05810b44b6a835cecce28f3137|" +#~ msgstr "|0aa5aa05810b44b6a835cecce28f3137|" + +#~ msgid "|c742940dd4bf4de09d8d0d5e8d179638|" +#~ msgstr "|c742940dd4bf4de09d8d0d5e8d179638|" + +#~ msgid "|1f169ab4601a47e1a226f1628f4ebddb|" +#~ msgstr "|1f169ab4601a47e1a226f1628f4ebddb|" + +#~ msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" +#~ msgstr "|12cfa9cde14440ecb8c8f6c1d7185bec|" + +#~ msgid "|72939caf6e294b0986fee6dde96614d7|" +#~ msgstr "|72939caf6e294b0986fee6dde96614d7|" + +#~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +#~ msgstr "|83a8daee45da4a98b8d6f24ae098fc50|" + From 64682df42168d7cfa7f4fb32bde30db0d3496855 Mon Sep 17 00:00:00 2001 From: Chong Shen Ng Date: Mon, 17 Jun 2024 22:12:24 +0100 Subject: [PATCH 086/124] feat(framework) Update proto files for SuperExec logstream (#3622) --- src/proto/flwr/proto/exec.proto | 5 ++++ src/py/flwr/proto/exec_pb2.py | 10 +++++--- src/py/flwr/proto/exec_pb2.pyi | 23 +++++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.py | 34 ++++++++++++++++++++++++++ src/py/flwr/proto/exec_pb2_grpc.pyi | 14 +++++++++++ src/py/flwr/superexec/exec_servicer.py | 13 +++++++++- 6 files changed, 95 insertions(+), 4 deletions(-) diff --git a/src/proto/flwr/proto/exec.proto b/src/proto/flwr/proto/exec.proto index 05885c9ceed3..8e5f53b02ca8 100644 --- a/src/proto/flwr/proto/exec.proto +++ b/src/proto/flwr/proto/exec.proto @@ -20,7 +20,12 @@ package flwr.proto; service Exec { // Start run upon request rpc StartRun(StartRunRequest) returns (StartRunResponse) {} + + // Start log stream upon request + rpc StreamLogs(StreamLogsRequest) returns (stream StreamLogsResponse) {} } message StartRunRequest { bytes fab_file = 1; } message StartRunResponse { sint64 run_id = 1; } +message StreamLogsRequest { sint64 run_id = 1; } +message StreamLogsResponse { string log_output = 1; } diff --git a/src/py/flwr/proto/exec_pb2.py b/src/py/flwr/proto/exec_pb2.py index a1d1f24af7d0..7b037a9454c0 100644 --- a/src/py/flwr/proto/exec_pb2.py +++ b/src/py/flwr/proto/exec_pb2.py @@ -14,7 +14,7 @@ -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\"#\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\x32O\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x62\x06proto3') +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15\x66lwr/proto/exec.proto\x12\nflwr.proto\"#\n\x0fStartRunRequest\x12\x10\n\x08\x66\x61\x62_file\x18\x01 \x01(\x0c\"\"\n\x10StartRunResponse\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"#\n\x11StreamLogsRequest\x12\x0e\n\x06run_id\x18\x01 \x01(\x12\"(\n\x12StreamLogsResponse\x12\x12\n\nlog_output\x18\x01 \x01(\t2\xa0\x01\n\x04\x45xec\x12G\n\x08StartRun\x12\x1b.flwr.proto.StartRunRequest\x1a\x1c.flwr.proto.StartRunResponse\"\x00\x12O\n\nStreamLogs\x12\x1d.flwr.proto.StreamLogsRequest\x1a\x1e.flwr.proto.StreamLogsResponse\"\x00\x30\x01\x62\x06proto3') _globals = globals() _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) @@ -25,6 +25,10 @@ _globals['_STARTRUNREQUEST']._serialized_end=72 _globals['_STARTRUNRESPONSE']._serialized_start=74 _globals['_STARTRUNRESPONSE']._serialized_end=108 - _globals['_EXEC']._serialized_start=110 - _globals['_EXEC']._serialized_end=189 + _globals['_STREAMLOGSREQUEST']._serialized_start=110 + _globals['_STREAMLOGSREQUEST']._serialized_end=145 + _globals['_STREAMLOGSRESPONSE']._serialized_start=147 + _globals['_STREAMLOGSRESPONSE']._serialized_end=187 + _globals['_EXEC']._serialized_start=190 + _globals['_EXEC']._serialized_end=350 # @@protoc_insertion_point(module_scope) diff --git a/src/py/flwr/proto/exec_pb2.pyi b/src/py/flwr/proto/exec_pb2.pyi index 8a0122062dcf..466812808da8 100644 --- a/src/py/flwr/proto/exec_pb2.pyi +++ b/src/py/flwr/proto/exec_pb2.pyi @@ -5,6 +5,7 @@ isort:skip_file import builtins import google.protobuf.descriptor import google.protobuf.message +import typing import typing_extensions DESCRIPTOR: google.protobuf.descriptor.FileDescriptor @@ -30,3 +31,25 @@ class StartRunResponse(google.protobuf.message.Message): ) -> None: ... def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ... global___StartRunResponse = StartRunResponse + +class StreamLogsRequest(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + RUN_ID_FIELD_NUMBER: builtins.int + run_id: builtins.int + def __init__(self, + *, + run_id: builtins.int = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["run_id",b"run_id"]) -> None: ... +global___StreamLogsRequest = StreamLogsRequest + +class StreamLogsResponse(google.protobuf.message.Message): + DESCRIPTOR: google.protobuf.descriptor.Descriptor + LOG_OUTPUT_FIELD_NUMBER: builtins.int + log_output: typing.Text + def __init__(self, + *, + log_output: typing.Text = ..., + ) -> None: ... + def ClearField(self, field_name: typing_extensions.Literal["log_output",b"log_output"]) -> None: ... +global___StreamLogsResponse = StreamLogsResponse diff --git a/src/py/flwr/proto/exec_pb2_grpc.py b/src/py/flwr/proto/exec_pb2_grpc.py index 349148eb9926..8cf4ce52a300 100644 --- a/src/py/flwr/proto/exec_pb2_grpc.py +++ b/src/py/flwr/proto/exec_pb2_grpc.py @@ -19,6 +19,11 @@ def __init__(self, channel): request_serializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.SerializeToString, response_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString, ) + self.StreamLogs = channel.unary_stream( + '/flwr.proto.Exec/StreamLogs', + request_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString, + response_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString, + ) class ExecServicer(object): @@ -31,6 +36,13 @@ def StartRun(self, request, context): context.set_details('Method not implemented!') raise NotImplementedError('Method not implemented!') + def StreamLogs(self, request, context): + """Start log stream upon request + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + def add_ExecServicer_to_server(servicer, server): rpc_method_handlers = { @@ -39,6 +51,11 @@ def add_ExecServicer_to_server(servicer, server): request_deserializer=flwr_dot_proto_dot_exec__pb2.StartRunRequest.FromString, response_serializer=flwr_dot_proto_dot_exec__pb2.StartRunResponse.SerializeToString, ), + 'StreamLogs': grpc.unary_stream_rpc_method_handler( + servicer.StreamLogs, + request_deserializer=flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.FromString, + response_serializer=flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.SerializeToString, + ), } generic_handler = grpc.method_handlers_generic_handler( 'flwr.proto.Exec', rpc_method_handlers) @@ -65,3 +82,20 @@ def StartRun(request, flwr_dot_proto_dot_exec__pb2.StartRunResponse.FromString, options, channel_credentials, insecure, call_credentials, compression, wait_for_ready, timeout, metadata) + + @staticmethod + def StreamLogs(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_stream(request, target, '/flwr.proto.Exec/StreamLogs', + flwr_dot_proto_dot_exec__pb2.StreamLogsRequest.SerializeToString, + flwr_dot_proto_dot_exec__pb2.StreamLogsResponse.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/src/py/flwr/proto/exec_pb2_grpc.pyi b/src/py/flwr/proto/exec_pb2_grpc.pyi index 6cab594babd9..20da3a53f4a8 100644 --- a/src/py/flwr/proto/exec_pb2_grpc.pyi +++ b/src/py/flwr/proto/exec_pb2_grpc.pyi @@ -5,6 +5,7 @@ isort:skip_file import abc import flwr.proto.exec_pb2 import grpc +import typing class ExecStub: def __init__(self, channel: grpc.Channel) -> None: ... @@ -13,6 +14,11 @@ class ExecStub: flwr.proto.exec_pb2.StartRunResponse] """Start run upon request""" + StreamLogs: grpc.UnaryStreamMultiCallable[ + flwr.proto.exec_pb2.StreamLogsRequest, + flwr.proto.exec_pb2.StreamLogsResponse] + """Start log stream upon request""" + class ExecServicer(metaclass=abc.ABCMeta): @abc.abstractmethod @@ -23,5 +29,13 @@ class ExecServicer(metaclass=abc.ABCMeta): """Start run upon request""" pass + @abc.abstractmethod + def StreamLogs(self, + request: flwr.proto.exec_pb2.StreamLogsRequest, + context: grpc.ServicerContext, + ) -> typing.Iterator[flwr.proto.exec_pb2.StreamLogsResponse]: + """Start log stream upon request""" + pass + def add_ExecServicer_to_server(servicer: ExecServicer, server: grpc.Server) -> None: ... diff --git a/src/py/flwr/superexec/exec_servicer.py b/src/py/flwr/superexec/exec_servicer.py index aa8172c18704..e5ef2bd59a79 100644 --- a/src/py/flwr/superexec/exec_servicer.py +++ b/src/py/flwr/superexec/exec_servicer.py @@ -16,7 +16,7 @@ from logging import ERROR, INFO -from typing import Dict +from typing import Any, Dict, Generator import grpc @@ -25,6 +25,8 @@ from flwr.proto.exec_pb2 import ( # pylint: disable=E0611 StartRunRequest, StartRunResponse, + StreamLogsRequest, + StreamLogsResponse, ) from .executor import Executor, RunTracker @@ -52,3 +54,12 @@ def StartRun( self.runs[run.run_id] = run return StartRunResponse(run_id=run.run_id) + + def StreamLogs( + self, request: StreamLogsRequest, context: grpc.ServicerContext + ) -> Generator[StreamLogsResponse, Any, None]: + """Get logs.""" + logs = ["a", "b", "c"] + while context.is_active(): + for i in range(len(logs)): # pylint: disable=C0200 + yield StreamLogsResponse(log_output=logs[i]) From 461ed3945cc1f66427e1910b77cb372e942a090c Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Tue, 18 Jun 2024 16:35:13 +0200 Subject: [PATCH 087/124] ci(*:skip) Simplify nightly release CI (#3599) Signed-off-by: Robert Steiner Co-authored-by: Taner Topal --- .github/workflows/release-nightly.yml | 13 ++++--------- dev/publish-nightly.sh | 8 ++------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/.github/workflows/release-nightly.yml b/.github/workflows/release-nightly.yml index 939a9581871c..2b72190bede5 100644 --- a/.github/workflows/release-nightly.yml +++ b/.github/workflows/release-nightly.yml @@ -3,7 +3,6 @@ name: Release nightly on: schedule: - cron: "0 23 * * *" - - cron: "30 23 * * *" env: FLWR_TELEMETRY_ENABLED: 0 @@ -25,15 +24,11 @@ jobs: id: bootstrap uses: ./.github/actions/bootstrap - name: Release nightly - if: github.event.schedule == '0 23 * * *' + id: release env: PYPI_TOKEN: ${{ secrets.PYPI_TOKEN }} - run: ./dev/publish-nightly.sh - - name: Read nightly version and name - if: github.event.schedule == '30 23 * * *' - id: release run: | - RESULT=$(./dev/publish-nightly.sh --skip-publish) + RESULT=$(./dev/publish-nightly.sh) if [ "$RESULT" == "There were no commits in the last 24 hours." ]; then echo "skip=true" >> $GITHUB_OUTPUT fi @@ -45,7 +40,7 @@ jobs: build-docker-base-images: name: Build nightly base images - if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' && github.event.schedule == '30 23 * * *' + if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' uses: ./.github/workflows/_docker-build.yml needs: release-nightly with: @@ -65,7 +60,7 @@ jobs: build-docker-binary-images: name: Build nightly binary images - if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' && github.event.schedule == '30 23 * * *' + if: github.repository == 'adap/flower' && needs.release-nightly.outputs.skip != 'true' uses: ./.github/workflows/_docker-build.yml needs: [release-nightly, build-docker-base-images] strategy: diff --git a/dev/publish-nightly.sh b/dev/publish-nightly.sh index a42af1f17cfc..0c03cdda9f49 100755 --- a/dev/publish-nightly.sh +++ b/dev/publish-nightly.sh @@ -24,16 +24,12 @@ cd "$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/../ # The version name in the pyproject.toml will be appended with "-dev" and the current date. # The result will be a release on PyPi of the package "flwr-nightly" of version e.g. # "0.1.1.dev20200716" as seen at https://pypi.org/project/flwr-nightly/ -# If the script is called with the flag `--skip-publish`, the name and version are changed -# in the pyproject.toml but the package won't be published. if [[ $(git log --since="24 hours ago" --pretty=oneline) ]]; then sed -i -E "s/^name = \"(.+)\"/name = \"\1-nightly\"/" pyproject.toml sed -i -E "s/^version = \"(.+)\"/version = \"\1.dev$(date '+%Y%m%d')\"/" pyproject.toml - if [ "$1" != "--skip-publish" ]; then - python -m poetry build - python -m poetry publish -u __token__ -p $PYPI_TOKEN - fi + python -m poetry build + python -m poetry publish -u __token__ -p $PYPI_TOKEN else echo "There were no commits in the last 24 hours." fi From 0e007b42cb45fef10baa099f62669c1e9bc4fc94 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Tue, 18 Jun 2024 16:47:07 +0100 Subject: [PATCH 088/124] refactor(framework:skip) Introduce `Run` class and update `State` accordingly (#3639) --- src/py/flwr/common/typing.py | 9 +++++++++ .../fleet/message_handler/message_handler.py | 6 +++--- .../flwr/server/superlink/fleet/vce/vce_api_test.py | 3 ++- .../flwr/server/superlink/state/in_memory_state.py | 13 ++++++++----- src/py/flwr/server/superlink/state/sqlite_state.py | 9 ++++++--- src/py/flwr/server/superlink/state/state.py | 9 +++++---- src/py/flwr/server/superlink/state/state_test.py | 9 +++++---- 7 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/py/flwr/common/typing.py b/src/py/flwr/common/typing.py index d6b2ec9b158c..f51830955679 100644 --- a/src/py/flwr/common/typing.py +++ b/src/py/flwr/common/typing.py @@ -185,3 +185,12 @@ class ClientMessage: get_parameters_res: Optional[GetParametersRes] = None fit_res: Optional[FitRes] = None evaluate_res: Optional[EvaluateRes] = None + + +@dataclass +class Run: + """Run details.""" + + run_id: int + fab_id: str + fab_version: str diff --git a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py index 4c796502436b..dceb18cab453 100644 --- a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +++ b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py @@ -112,6 +112,6 @@ def get_run( request: GetRunRequest, state: State # pylint: disable=W0613 ) -> GetRunResponse: """Get run information.""" - run_id, fab_id, fab_version = state.get_run(request.run_id) - run = Run(run_id=run_id, fab_id=fab_id, fab_version=fab_version) - return GetRunResponse(run=run) + run = state.get_run(request.run_id) + run_proto = None if run is None else Run(**vars(run)) + return GetRunResponse(run=run_proto) diff --git a/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py b/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py index 1da726f88f1e..df9f2cc96f95 100644 --- a/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py +++ b/src/py/flwr/server/superlink/fleet/vce/vce_api_test.py @@ -37,6 +37,7 @@ ) from flwr.common.recordset_compat import getpropertiesins_to_recordset from flwr.common.serde import message_from_taskres, message_to_taskins +from flwr.common.typing import Run from flwr.server.superlink.fleet.vce.vce_api import ( NodeToPartitionMapping, _register_nodes, @@ -81,7 +82,7 @@ def register_messages_into_state( ) -> Dict[UUID, float]: """Register `num_messages` into the state factory.""" state: InMemoryState = state_factory.state() # type: ignore - state.run_ids[run_id] = ("Mock/mock", "v1.0.0") + state.run_ids[run_id] = Run(run_id=run_id, fab_id="Mock/mock", fab_version="v1.0.0") # Artificially add TaskIns to state so they can be processed # by the Simulation Engine logic nodes_cycle = cycle(nodes_mapping.keys()) # we have more messages than supernodes diff --git a/src/py/flwr/server/superlink/state/in_memory_state.py b/src/py/flwr/server/superlink/state/in_memory_state.py index f86bf79d9dfa..e03260355db9 100644 --- a/src/py/flwr/server/superlink/state/in_memory_state.py +++ b/src/py/flwr/server/superlink/state/in_memory_state.py @@ -23,6 +23,7 @@ from uuid import UUID, uuid4 from flwr.common import log, now +from flwr.common.typing import Run from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611 from flwr.server.superlink.state.state import State from flwr.server.utils import validate_task_ins_or_res @@ -40,7 +41,7 @@ def __init__(self) -> None: self.public_key_to_node_id: Dict[bytes, int] = {} # Map run_id to (fab_id, fab_version) - self.run_ids: Dict[int, Tuple[str, str]] = {} + self.run_ids: Dict[int, Run] = {} self.task_ins_store: Dict[UUID, TaskIns] = {} self.task_res_store: Dict[UUID, TaskRes] = {} @@ -281,7 +282,9 @@ def create_run(self, fab_id: str, fab_version: str) -> int: run_id: int = int.from_bytes(os.urandom(8), "little", signed=True) if run_id not in self.run_ids: - self.run_ids[run_id] = (fab_id, fab_version) + self.run_ids[run_id] = Run( + run_id=run_id, fab_id=fab_id, fab_version=fab_version + ) return run_id log(ERROR, "Unexpected run creation failure.") return 0 @@ -319,13 +322,13 @@ def get_client_public_keys(self) -> Set[bytes]: """Retrieve all currently stored `client_public_keys` as a set.""" return self.client_public_keys - def get_run(self, run_id: int) -> Tuple[int, str, str]: + def get_run(self, run_id: int) -> Optional[Run]: """Retrieve information about the run with the specified `run_id`.""" with self.lock: if run_id not in self.run_ids: log(ERROR, "`run_id` is invalid") - return 0, "", "" - return run_id, *self.run_ids[run_id] + return None + return self.run_ids[run_id] def acknowledge_ping(self, node_id: int, ping_interval: float) -> bool: """Acknowledge a ping received from a node, serving as a heartbeat.""" diff --git a/src/py/flwr/server/superlink/state/sqlite_state.py b/src/py/flwr/server/superlink/state/sqlite_state.py index acf2054f08b6..b9672757b0e6 100644 --- a/src/py/flwr/server/superlink/state/sqlite_state.py +++ b/src/py/flwr/server/superlink/state/sqlite_state.py @@ -24,6 +24,7 @@ from uuid import UUID, uuid4 from flwr.common import log, now +from flwr.common.typing import Run from flwr.proto.node_pb2 import Node # pylint: disable=E0611 from flwr.proto.recordset_pb2 import RecordSet # pylint: disable=E0611 from flwr.proto.task_pb2 import Task, TaskIns, TaskRes # pylint: disable=E0611 @@ -680,15 +681,17 @@ def get_client_public_keys(self) -> Set[bytes]: result: Set[bytes] = {row["public_key"] for row in rows} return result - def get_run(self, run_id: int) -> Tuple[int, str, str]: + def get_run(self, run_id: int) -> Optional[Run]: """Retrieve information about the run with the specified `run_id`.""" query = "SELECT * FROM run WHERE run_id = ?;" try: row = self.query(query, (run_id,))[0] - return run_id, row["fab_id"], row["fab_version"] + return Run( + run_id=run_id, fab_id=row["fab_id"], fab_version=row["fab_version"] + ) except sqlite3.IntegrityError: log(ERROR, "`run_id` does not exist.") - return 0, "", "" + return None def acknowledge_ping(self, node_id: int, ping_interval: float) -> bool: """Acknowledge a ping received from a node, serving as a heartbeat.""" diff --git a/src/py/flwr/server/superlink/state/state.py b/src/py/flwr/server/superlink/state/state.py index a72062f2a938..d1fc9465c9f2 100644 --- a/src/py/flwr/server/superlink/state/state.py +++ b/src/py/flwr/server/superlink/state/state.py @@ -16,9 +16,10 @@ import abc -from typing import List, Optional, Set, Tuple +from typing import List, Optional, Set from uuid import UUID +from flwr.common.typing import Run from flwr.proto.task_pb2 import TaskIns, TaskRes # pylint: disable=E0611 @@ -160,7 +161,7 @@ def create_run(self, fab_id: str, fab_version: str) -> int: """Create a new run for the specified `fab_id` and `fab_version`.""" @abc.abstractmethod - def get_run(self, run_id: int) -> Tuple[int, str, str]: + def get_run(self, run_id: int) -> Optional[Run]: """Retrieve information about the run with the specified `run_id`. Parameters @@ -170,8 +171,8 @@ def get_run(self, run_id: int) -> Tuple[int, str, str]: Returns ------- - Tuple[int, str, str] - A tuple containing three elements: + Optional[Run] + A dataclass instance containing three elements if `run_id` is valid: - `run_id`: The identifier of the run, same as the specified `run_id`. - `fab_id`: The identifier of the FAB used in the specified run. - `fab_version`: The version of the FAB used in the specified run. diff --git a/src/py/flwr/server/superlink/state/state_test.py b/src/py/flwr/server/superlink/state/state_test.py index 9b0153ca548a..81307d938400 100644 --- a/src/py/flwr/server/superlink/state/state_test.py +++ b/src/py/flwr/server/superlink/state/state_test.py @@ -55,12 +55,13 @@ def test_create_and_get_run(self) -> None: run_id = state.create_run("Mock/mock", "v1.0.0") # Execute - actual_run_id, fab_id, fab_version = state.get_run(run_id) + run = state.get_run(run_id) # Assert - assert actual_run_id == run_id - assert fab_id == "Mock/mock" - assert fab_version == "v1.0.0" + assert run is not None + assert run.run_id == run_id + assert run.fab_id == "Mock/mock" + assert run.fab_version == "v1.0.0" def test_get_task_ins_empty(self) -> None: """Validate that a new state has no TaskIns.""" From 2cf54b0c574fa6344222a0ceaba489c699a3953f Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Tue, 18 Jun 2024 21:14:41 +0100 Subject: [PATCH 089/124] feat(framework) Add `GrpcAdapter` class (#3536) --- .../client/grpc_adapter_client/__init__.py | 15 ++ .../client/grpc_adapter_client/connection.py | 94 +++++++++++++ src/py/flwr/client/grpc_client/connection.py | 6 +- .../client/grpc_rere_client/connection.py | 9 +- .../client/grpc_rere_client/grpc_adapter.py | 133 ++++++++++++++++++ .../grpc_rere_client/grpc_adapter_test.py | 38 +++++ src/py/flwr/client/rest_client/connection.py | 10 +- src/py/flwr/common/constant.py | 4 + 8 files changed, 306 insertions(+), 3 deletions(-) create mode 100644 src/py/flwr/client/grpc_adapter_client/__init__.py create mode 100644 src/py/flwr/client/grpc_adapter_client/connection.py create mode 100644 src/py/flwr/client/grpc_rere_client/grpc_adapter.py create mode 100644 src/py/flwr/client/grpc_rere_client/grpc_adapter_test.py diff --git a/src/py/flwr/client/grpc_adapter_client/__init__.py b/src/py/flwr/client/grpc_adapter_client/__init__.py new file mode 100644 index 000000000000..5900e2dc2d06 --- /dev/null +++ b/src/py/flwr/client/grpc_adapter_client/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Client-side part of the GrpcAdapter transport layer.""" diff --git a/src/py/flwr/client/grpc_adapter_client/connection.py b/src/py/flwr/client/grpc_adapter_client/connection.py new file mode 100644 index 000000000000..e4e32b3accd0 --- /dev/null +++ b/src/py/flwr/client/grpc_adapter_client/connection.py @@ -0,0 +1,94 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Contextmanager for a GrpcAdapter channel to the Flower server.""" + + +from contextlib import contextmanager +from logging import ERROR +from typing import Callable, Iterator, Optional, Tuple, Union + +from cryptography.hazmat.primitives.asymmetric import ec + +from flwr.client.grpc_rere_client.connection import grpc_request_response +from flwr.client.grpc_rere_client.grpc_adapter import GrpcAdapter +from flwr.common import GRPC_MAX_MESSAGE_LENGTH +from flwr.common.logger import log +from flwr.common.message import Message +from flwr.common.retry_invoker import RetryInvoker + + +@contextmanager +def grpc_adapter( # pylint: disable=R0913 + server_address: str, + insecure: bool, + retry_invoker: RetryInvoker, + max_message_length: int = GRPC_MAX_MESSAGE_LENGTH, # pylint: disable=W0613 + root_certificates: Optional[Union[bytes, str]] = None, + authentication_keys: Optional[ # pylint: disable=unused-argument + Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey] + ] = None, +) -> Iterator[ + Tuple[ + Callable[[], Optional[Message]], + Callable[[Message], None], + Optional[Callable[[], None]], + Optional[Callable[[], None]], + Optional[Callable[[int], Tuple[str, str]]], + ] +]: + """Primitives for request/response-based interaction with a server via GrpcAdapter. + + Parameters + ---------- + server_address : str + The IPv6 address of the server with `http://` or `https://`. + If the Flower server runs on the same machine + on port 8080, then `server_address` would be `"http://[::]:8080"`. + insecure : bool + Starts an insecure gRPC connection when True. Enables HTTPS connection + when False, using system certificates if `root_certificates` is None. + retry_invoker: RetryInvoker + `RetryInvoker` object that will try to reconnect the client to the server + after gRPC errors. If None, the client will only try to + reconnect once after a failure. + max_message_length : int + Ignored, only present to preserve API-compatibility. + root_certificates : Optional[Union[bytes, str]] (default: None) + Path of the root certificate. If provided, a secure + connection using the certificates will be established to an SSL-enabled + Flower server. Bytes won't work for the REST API. + authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None) + Client authentication is not supported for this transport type. + + Returns + ------- + receive : Callable + send : Callable + create_node : Optional[Callable] + delete_node : Optional[Callable] + get_run : Optional[Callable] + """ + if authentication_keys is not None: + log(ERROR, "Client authentication is not supported for this transport type.") + with grpc_request_response( + server_address=server_address, + insecure=insecure, + retry_invoker=retry_invoker, + max_message_length=max_message_length, + root_certificates=root_certificates, + authentication_keys=None, # Authentication is not supported + adapter_cls=GrpcAdapter, + ) as conn: + yield conn diff --git a/src/py/flwr/client/grpc_client/connection.py b/src/py/flwr/client/grpc_client/connection.py index 6e5227cf5e5f..8c049861c672 100644 --- a/src/py/flwr/client/grpc_client/connection.py +++ b/src/py/flwr/client/grpc_client/connection.py @@ -17,7 +17,7 @@ import uuid from contextlib import contextmanager -from logging import DEBUG +from logging import DEBUG, ERROR from pathlib import Path from queue import Queue from typing import Callable, Iterator, Optional, Tuple, Union, cast @@ -101,6 +101,8 @@ def grpc_connection( # pylint: disable=R0913, R0915 The PEM-encoded root certificates as a byte string or a path string. If provided, a secure connection using the certificates will be established to an SSL-enabled Flower server. + authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None) + Client authentication is not supported for this transport type. Returns ------- @@ -123,6 +125,8 @@ def grpc_connection( # pylint: disable=R0913, R0915 """ if isinstance(root_certificates, str): root_certificates = Path(root_certificates).read_bytes() + if authentication_keys is not None: + log(ERROR, "Client authentication is not supported for this transport type.") channel = create_channel( server_address=server_address, diff --git a/src/py/flwr/client/grpc_rere_client/connection.py b/src/py/flwr/client/grpc_rere_client/connection.py index 52d0cc58b2bb..b1c268d51d55 100644 --- a/src/py/flwr/client/grpc_rere_client/connection.py +++ b/src/py/flwr/client/grpc_rere_client/connection.py @@ -55,6 +55,7 @@ from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611 from .client_interceptor import AuthenticateClientInterceptor +from .grpc_adapter import GrpcAdapter def on_channel_state_change(channel_connectivity: str) -> None: @@ -72,7 +73,7 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915 authentication_keys: Optional[ Tuple[ec.EllipticCurvePrivateKey, ec.EllipticCurvePublicKey] ] = None, - adapter_cls: Optional[Type[FleetStub]] = None, + adapter_cls: Optional[Union[Type[FleetStub], Type[GrpcAdapter]]] = None, ) -> Iterator[ Tuple[ Callable[[], Optional[Message]], @@ -106,6 +107,11 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915 Path of the root certificate. If provided, a secure connection using the certificates will be established to an SSL-enabled Flower server. Bytes won't work for the REST API. + authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None) + Tuple containing the elliptic curve private key and public key for + authentication from the cryptography library. + Source: https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/ + Used to establish an authenticated connection with the server. Returns ------- @@ -113,6 +119,7 @@ def grpc_request_response( # pylint: disable=R0913, R0914, R0915 send : Callable create_node : Optional[Callable] delete_node : Optional[Callable] + get_run : Optional[Callable] """ if isinstance(root_certificates, str): root_certificates = Path(root_certificates).read_bytes() diff --git a/src/py/flwr/client/grpc_rere_client/grpc_adapter.py b/src/py/flwr/client/grpc_rere_client/grpc_adapter.py new file mode 100644 index 000000000000..77c3d601020d --- /dev/null +++ b/src/py/flwr/client/grpc_rere_client/grpc_adapter.py @@ -0,0 +1,133 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""GrpcAdapter implementation.""" + + +import sys +from logging import DEBUG +from typing import Any, Type, TypeVar, cast + +import grpc +from google.protobuf.message import Message as GrpcMessage + +from flwr.common import log +from flwr.common.constant import ( + GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY, + GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY, +) +from flwr.common.version import package_version +from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611 + CreateNodeRequest, + CreateNodeResponse, + DeleteNodeRequest, + DeleteNodeResponse, + PingRequest, + PingResponse, + PullTaskInsRequest, + PullTaskInsResponse, + PushTaskResRequest, + PushTaskResResponse, +) +from flwr.proto.grpcadapter_pb2 import MessageContainer # pylint: disable=E0611 +from flwr.proto.grpcadapter_pb2_grpc import GrpcAdapterStub +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 + +T = TypeVar("T", bound=GrpcMessage) + + +class GrpcAdapter: + """Adapter class to send and receive gRPC messages via the ``GrpcAdapterStub``. + + This class utilizes the ``GrpcAdapterStub`` to send and receive gRPC messages + which are defined and used by the Fleet API, as defined in ``fleet.proto``. + """ + + def __init__(self, channel: grpc.Channel) -> None: + self.stub = GrpcAdapterStub(channel) + + def _send_and_receive( + self, request: GrpcMessage, response_type: Type[T], **kwargs: Any + ) -> T: + # Serialize request + container_req = MessageContainer( + metadata={GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY: package_version}, + grpc_message_name=request.__class__.__qualname__, + grpc_message_content=request.SerializeToString(), + ) + + # Send via the stub + container_res = cast( + MessageContainer, self.stub.SendReceive(container_req, **kwargs) + ) + + # Handle control message + should_exit = ( + container_res.metadata.get(GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY, "false") + == "true" + ) + if should_exit: + log( + DEBUG, + 'Received shutdown signal: exit flag is set to ``"true"``. Exiting...', + ) + sys.exit(0) + + # Check the grpc_message_name of the response + if container_res.grpc_message_name != response_type.__qualname__: + raise ValueError( + f"Invalid grpc_message_name. Expected {response_type.__qualname__}" + f", but got {container_res.grpc_message_name}." + ) + + # Deserialize response + response = response_type() + response.ParseFromString(container_res.grpc_message_content) + return response + + def CreateNode( # pylint: disable=C0103 + self, request: CreateNodeRequest, **kwargs: Any + ) -> CreateNodeResponse: + """.""" + return self._send_and_receive(request, CreateNodeResponse, **kwargs) + + def DeleteNode( # pylint: disable=C0103 + self, request: DeleteNodeRequest, **kwargs: Any + ) -> DeleteNodeResponse: + """.""" + return self._send_and_receive(request, DeleteNodeResponse, **kwargs) + + def Ping( # pylint: disable=C0103 + self, request: PingRequest, **kwargs: Any + ) -> PingResponse: + """.""" + return self._send_and_receive(request, PingResponse, **kwargs) + + def PullTaskIns( # pylint: disable=C0103 + self, request: PullTaskInsRequest, **kwargs: Any + ) -> PullTaskInsResponse: + """.""" + return self._send_and_receive(request, PullTaskInsResponse, **kwargs) + + def PushTaskRes( # pylint: disable=C0103 + self, request: PushTaskResRequest, **kwargs: Any + ) -> PushTaskResResponse: + """.""" + return self._send_and_receive(request, PushTaskResResponse, **kwargs) + + def GetRun( # pylint: disable=C0103 + self, request: GetRunRequest, **kwargs: Any + ) -> GetRunResponse: + """.""" + return self._send_and_receive(request, GetRunResponse, **kwargs) diff --git a/src/py/flwr/client/grpc_rere_client/grpc_adapter_test.py b/src/py/flwr/client/grpc_rere_client/grpc_adapter_test.py new file mode 100644 index 000000000000..e62111e084bc --- /dev/null +++ b/src/py/flwr/client/grpc_rere_client/grpc_adapter_test.py @@ -0,0 +1,38 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Tests for the GrpcAdapter class.""" + + +import inspect + +from flwr.proto.fleet_pb2_grpc import FleetServicer + +from .grpc_adapter import GrpcAdapter + + +def test_grpc_adapter_methods() -> None: + """Test if GrpcAdapter implements all required methods.""" + # Prepare + methods = { + name for name, ref in inspect.getmembers(GrpcAdapter) if inspect.isfunction(ref) + } + expected_methods = { + name + for name, ref in inspect.getmembers(FleetServicer) + if inspect.isfunction(ref) + } + + # Assert + assert expected_methods.issubset(methods) diff --git a/src/py/flwr/client/rest_client/connection.py b/src/py/flwr/client/rest_client/connection.py index 7383eae3d22b..5f5e153f9d8d 100644 --- a/src/py/flwr/client/rest_client/connection.py +++ b/src/py/flwr/client/rest_client/connection.py @@ -117,10 +117,16 @@ def http_request_response( # pylint: disable=,R0913, R0914, R0915 Path of the root certificate. If provided, a secure connection using the certificates will be established to an SSL-enabled Flower server. Bytes won't work for the REST API. + authentication_keys : Optional[Tuple[PrivateKey, PublicKey]] (default: None) + Client authentication is not supported for this transport type. Returns ------- - receive, send : Callable, Callable + receive : Callable + send : Callable + create_node : Optional[Callable] + delete_node : Optional[Callable] + get_run : Optional[Callable] """ log( WARN, @@ -145,6 +151,8 @@ def http_request_response( # pylint: disable=,R0913, R0914, R0915 "For the REST API, the root certificates " "must be provided as a string path to the client.", ) + if authentication_keys is not None: + log(ERROR, "Client authentication is not supported for this transport type.") # Shared variables for inner functions metadata: Optional[Metadata] = None diff --git a/src/py/flwr/common/constant.py b/src/py/flwr/common/constant.py index 1548694858fe..ac35549d2051 100644 --- a/src/py/flwr/common/constant.py +++ b/src/py/flwr/common/constant.py @@ -51,6 +51,10 @@ FLWR_HOME = "FLWR_HOME" +GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version" +GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit" + + class MessageType: """Message type.""" From ce6daf09c6868a005e042509de3ba788b4d3a741 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Wed, 19 Jun 2024 13:22:23 +0100 Subject: [PATCH 090/124] feat(framework) Add `GrpcAdapterServicer` (#3538) --- .../superlink/fleet/grpc_adapter/__init__.py | 15 ++ .../grpc_adapter/grpc_adapter_servicer.py | 131 ++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py create mode 100644 src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py diff --git a/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py b/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py new file mode 100644 index 000000000000..cf875a1b9666 --- /dev/null +++ b/src/py/flwr/server/superlink/fleet/grpc_adapter/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Server-side part of the GrpcAdapter transport layer.""" diff --git a/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py b/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py new file mode 100644 index 000000000000..9325041061ac --- /dev/null +++ b/src/py/flwr/server/superlink/fleet/grpc_adapter/grpc_adapter_servicer.py @@ -0,0 +1,131 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Fleet API gRPC adapter servicer.""" + + +from logging import DEBUG, INFO +from typing import Callable, Type, TypeVar + +import grpc +from google.protobuf.message import Message as GrpcMessage + +from flwr.common.logger import log +from flwr.proto import grpcadapter_pb2_grpc # pylint: disable=E0611 +from flwr.proto.fleet_pb2 import ( # pylint: disable=E0611 + CreateNodeRequest, + CreateNodeResponse, + DeleteNodeRequest, + DeleteNodeResponse, + PingRequest, + PingResponse, + PullTaskInsRequest, + PullTaskInsResponse, + PushTaskResRequest, + PushTaskResResponse, +) +from flwr.proto.grpcadapter_pb2 import MessageContainer # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 +from flwr.server.superlink.fleet.message_handler import message_handler +from flwr.server.superlink.state import StateFactory + +T = TypeVar("T", bound=GrpcMessage) + + +def _handle( + msg_container: MessageContainer, + request_type: Type[T], + handler: Callable[[T], GrpcMessage], +) -> MessageContainer: + req = request_type.FromString(msg_container.grpc_message_content) + res = handler(req) + return MessageContainer( + metadata={}, + grpc_message_name=res.__class__.__qualname__, + grpc_message_content=res.SerializeToString(), + ) + + +class GrpcAdapterServicer(grpcadapter_pb2_grpc.GrpcAdapterServicer): + """Fleet API via GrpcAdapter servicer.""" + + def __init__(self, state_factory: StateFactory) -> None: + self.state_factory = state_factory + + def SendReceive( + self, request: MessageContainer, context: grpc.ServicerContext + ) -> MessageContainer: + """.""" + log(DEBUG, "GrpcAdapterServicer.SendReceive") + if request.grpc_message_name == CreateNodeRequest.__qualname__: + return _handle(request, CreateNodeRequest, self._create_node) + if request.grpc_message_name == DeleteNodeRequest.__qualname__: + return _handle(request, DeleteNodeRequest, self._delete_node) + if request.grpc_message_name == PingRequest.__qualname__: + return _handle(request, PingRequest, self._ping) + if request.grpc_message_name == PullTaskInsRequest.__qualname__: + return _handle(request, PullTaskInsRequest, self._pull_task_ins) + if request.grpc_message_name == PushTaskResRequest.__qualname__: + return _handle(request, PushTaskResRequest, self._push_task_res) + if request.grpc_message_name == GetRunRequest.__qualname__: + return _handle(request, GetRunRequest, self._get_run) + raise ValueError(f"Invalid grpc_message_name: {request.grpc_message_name}") + + def _create_node(self, request: CreateNodeRequest) -> CreateNodeResponse: + """.""" + log(INFO, "GrpcAdapter.CreateNode") + return message_handler.create_node( + request=request, + state=self.state_factory.state(), + ) + + def _delete_node(self, request: DeleteNodeRequest) -> DeleteNodeResponse: + """.""" + log(INFO, "GrpcAdapter.DeleteNode") + return message_handler.delete_node( + request=request, + state=self.state_factory.state(), + ) + + def _ping(self, request: PingRequest) -> PingResponse: + """.""" + log(DEBUG, "GrpcAdapter.Ping") + return message_handler.ping( + request=request, + state=self.state_factory.state(), + ) + + def _pull_task_ins(self, request: PullTaskInsRequest) -> PullTaskInsResponse: + """Pull TaskIns.""" + log(INFO, "GrpcAdapter.PullTaskIns") + return message_handler.pull_task_ins( + request=request, + state=self.state_factory.state(), + ) + + def _push_task_res(self, request: PushTaskResRequest) -> PushTaskResResponse: + """Push TaskRes.""" + log(INFO, "GrpcAdapter.PushTaskRes") + return message_handler.push_task_res( + request=request, + state=self.state_factory.state(), + ) + + def _get_run(self, request: GetRunRequest) -> GetRunResponse: + """Get run information.""" + log(INFO, "GrpcAdapter.GetRun") + return message_handler.get_run( + request=request, + state=self.state_factory.state(), + ) From 1e9a1c7234f55bb3174d63a4699807e65eff96c2 Mon Sep 17 00:00:00 2001 From: Javier Date: Wed, 19 Jun 2024 14:32:44 +0200 Subject: [PATCH 091/124] ci(*:skip) Update CODEOWNERS for `flwr new` templates (#3642) --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0b8702a8360c..5270bf89ae33 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -15,6 +15,9 @@ README.md @jafermarq @tanertopal @danieljanes # Flower Examples /examples @jafermarq @tanertopal @danieljanes +# Flower Templates +/src/py/flwr/cli/new/templates @jafermarq @tanertopal @danieljanes + # Changelog /doc/source/ref-changelog.md @jafermarq @tanertopal @danieljanes From 86d204766dddf87cd57ae9c2ba020600265655c6 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Wed, 19 Jun 2024 14:39:55 +0200 Subject: [PATCH 092/124] ci(framework:skip) Add test and format for `__init__.__all__` (#3644) --- dev/format.sh | 1 + src/py/flwr/client/__init__.py | 2 +- src/py/flwr/client/mod/__init__.py | 6 +-- src/py/flwr/common/__init__.py | 24 ++++----- src/py/flwr/common/record/__init__.py | 2 +- src/py/flwr/server/__init__.py | 4 +- src/py/flwr/server/strategy/__init__.py | 4 +- src/py/flwr/simulation/__init__.py | 5 +- src/py/flwr_tool/init_py_check.py | 72 +++++++++++++++++++++++-- src/py/flwr_tool/init_py_fix.py | 69 ++++++++++++++++++++++++ 10 files changed, 163 insertions(+), 26 deletions(-) create mode 100755 src/py/flwr_tool/init_py_fix.py diff --git a/dev/format.sh b/dev/format.sh index 05248b5eed3d..b9e3b00dffe1 100755 --- a/dev/format.sh +++ b/dev/format.sh @@ -3,6 +3,7 @@ set -e cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../ # Python +python -m flwr_tool.init_py_fix src/py/flwr python -m isort --skip src/py/flwr/proto src/py python -m black -q --exclude src/py/flwr/proto src/py python -m docformatter -i -r src/py/flwr -e src/py/flwr/proto diff --git a/src/py/flwr/client/__init__.py b/src/py/flwr/client/__init__.py index b4da71302cb4..58fd94448586 100644 --- a/src/py/flwr/client/__init__.py +++ b/src/py/flwr/client/__init__.py @@ -28,8 +28,8 @@ "Client", "ClientApp", "ClientFn", - "mod", "NumPyClient", + "mod", "run_client_app", "run_supernode", "start_client", diff --git a/src/py/flwr/client/mod/__init__.py b/src/py/flwr/client/mod/__init__.py index 1774e4b8ca0a..0b4cf6488421 100644 --- a/src/py/flwr/client/mod/__init__.py +++ b/src/py/flwr/client/mod/__init__.py @@ -22,12 +22,12 @@ from .utils import make_ffn __all__ = [ + "LocalDpMod", "adaptiveclipping_mod", "fixedclipping_mod", - "LocalDpMod", "make_ffn", - "secagg_mod", - "secaggplus_mod", "message_size_mod", "parameters_size_mod", + "secagg_mod", + "secaggplus_mod", ] diff --git a/src/py/flwr/common/__init__.py b/src/py/flwr/common/__init__.py index 2fb98c82dd6f..bbdf48425e0a 100644 --- a/src/py/flwr/common/__init__.py +++ b/src/py/flwr/common/__init__.py @@ -63,43 +63,34 @@ __all__ = [ "Array", - "array_from_numpy", - "bytes_to_ndarray", "ClientMessage", "Code", "Config", "ConfigsRecord", - "configure", "Context", + "DEFAULT_TTL", "DisconnectRes", + "Error", "EvaluateIns", "EvaluateRes", - "event", "EventType", "FitIns", "FitRes", - "Error", + "GRPC_MAX_MESSAGE_LENGTH", "GetParametersIns", "GetParametersRes", "GetPropertiesIns", "GetPropertiesRes", - "GRPC_MAX_MESSAGE_LENGTH", - "log", "Message", "MessageType", "MessageTypeLegacy", - "DEFAULT_TTL", "Metadata", "Metrics", "MetricsAggregationFn", "MetricsRecord", - "ndarray_to_bytes", - "now", "NDArray", "NDArrays", - "ndarrays_to_parameters", "Parameters", - "parameters_to_ndarrays", "ParametersRecord", "Properties", "ReconnectIns", @@ -107,4 +98,13 @@ "Scalar", "ServerMessage", "Status", + "array_from_numpy", + "bytes_to_ndarray", + "configure", + "event", + "log", + "ndarray_to_bytes", + "ndarrays_to_parameters", + "now", + "parameters_to_ndarrays", ] diff --git a/src/py/flwr/common/record/__init__.py b/src/py/flwr/common/record/__init__.py index 60bc54b8552a..88eef5f7aea1 100644 --- a/src/py/flwr/common/record/__init__.py +++ b/src/py/flwr/common/record/__init__.py @@ -22,9 +22,9 @@ __all__ = [ "Array", - "array_from_numpy", "ConfigsRecord", "MetricsRecord", "ParametersRecord", "RecordSet", + "array_from_numpy", ] diff --git a/src/py/flwr/server/__init__.py b/src/py/flwr/server/__init__.py index 19c6034bcaa1..546ce263e2d5 100644 --- a/src/py/flwr/server/__init__.py +++ b/src/py/flwr/server/__init__.py @@ -34,12 +34,12 @@ "Driver", "History", "LegacyContext", - "run_server_app", - "run_superlink", "Server", "ServerApp", "ServerConfig", "SimpleClientManager", + "run_server_app", + "run_superlink", "start_server", "strategy", "workflow", diff --git a/src/py/flwr/server/strategy/__init__.py b/src/py/flwr/server/strategy/__init__.py index b7de9a946fff..e5bc30009819 100644 --- a/src/py/flwr/server/strategy/__init__.py +++ b/src/py/flwr/server/strategy/__init__.py @@ -53,9 +53,10 @@ "DPFedAvgAdaptive", "DPFedAvgFixed", "DifferentialPrivacyClientSideAdaptiveClipping", - "DifferentialPrivacyServerSideAdaptiveClipping", "DifferentialPrivacyClientSideFixedClipping", + "DifferentialPrivacyServerSideAdaptiveClipping", "DifferentialPrivacyServerSideFixedClipping", + "FaultTolerantFedAvg", "FedAdagrad", "FedAdam", "FedAvg", @@ -69,7 +70,6 @@ "FedXgbCyclic", "FedXgbNnAvg", "FedYogi", - "FaultTolerantFedAvg", "Krum", "QFedAvg", "Strategy", diff --git a/src/py/flwr/simulation/__init__.py b/src/py/flwr/simulation/__init__.py index 57b0b01eb319..3d648b14edba 100644 --- a/src/py/flwr/simulation/__init__.py +++ b/src/py/flwr/simulation/__init__.py @@ -36,4 +36,7 @@ def start_simulation(*args, **kwargs): # type: ignore raise ImportError(RAY_IMPORT_ERROR) -__all__ = ["start_simulation", "run_simulation"] +__all__ = [ + "run_simulation", + "start_simulation", +] diff --git a/src/py/flwr_tool/init_py_check.py b/src/py/flwr_tool/init_py_check.py index 67425139f991..1fb08513bb6a 100755 --- a/src/py/flwr_tool/init_py_check.py +++ b/src/py/flwr_tool/init_py_check.py @@ -6,15 +6,19 @@ """ +import ast import os import re import sys +from pathlib import Path +from typing import List, Tuple -def check_missing_init_files(absolute_path: str) -> None: - """Search absolute_path and look for missing __init__.py files.""" +def get_init_dir_list_and_warnings(absolute_path: str) -> Tuple[List[str], List[str]]: + """Search given path and return list of dirs containing __init__.py files.""" path = os.walk(absolute_path) warning_list = [] + dir_list = [] ignore_list = ["__pycache__$", ".pytest_cache.*$", "dist", "flwr.egg-info$"] for dir_path, _, files_in_dir in path: @@ -26,6 +30,14 @@ def check_missing_init_files(absolute_path: str) -> None: if not any(filename == "__init__.py" for filename in files_in_dir): warning_message = "- " + dir_path warning_list.append(warning_message) + else: + dir_list.append(dir_path) + return warning_list, dir_list + + +def check_missing_init_files(absolute_path: str) -> List[str]: + """Search absolute_path and look for missing __init__.py files.""" + warning_list, dir_list = get_init_dir_list_and_warnings(absolute_path) if len(warning_list) > 0: print("Could not find '__init__.py' in the following directories:") @@ -33,12 +45,64 @@ def check_missing_init_files(absolute_path: str) -> None: print(warning) sys.exit(1) + return dir_list + + +def get_all_var_list(init_dir: str) -> Tuple[Path, List[str], List[str]]: + """Get the __all__ list of a __init__.py file. + + The function returns the path of the '__init__.py' file of the given dir, as well as + the list itself, and the list of lines corresponding to the list. + """ + init_file = Path(init_dir) / "__init__.py" + all_lines = [] + all_list = [] + capture = False + for line in init_file.read_text().splitlines(): + stripped_line = line.strip() + if stripped_line.startswith("__all__"): + capture = True + if capture: + all_lines.append(line) + if stripped_line.endswith("]"): + capture = False + break + + if all_lines: + all_string = "".join(all_lines) + all_list = ast.literal_eval(all_string.split("=", 1)[1].strip()) + + return init_file, all_list, all_lines + + +def check_all_init_files(dir_list: List[str]) -> None: + """Check if __all__ is in alphabetical order in __init__.py files.""" + warning_list = [] + + for init_dir in dir_list: + init_file, all_list, _ = get_all_var_list(init_dir) + + if all_list and not all_list == sorted(all_list): + warning_message = "- " + str(init_file) + warning_list.append(warning_message) + + if len(warning_list) > 0: + print( + "'__all__' lists in the following '__init__.py' files are " + "incorrectly sorted:" + ) + for warning in warning_list: + print(warning) + sys.exit(1) + if __name__ == "__main__": if len(sys.argv) == 0: raise Exception( # pylint: disable=W0719 - "Please provide at least one directory path relative to your current working directory." + "Please provide at least one directory path relative " + "to your current working directory." ) for i, _ in enumerate(sys.argv): abs_path: str = os.path.abspath(os.path.join(os.getcwd(), sys.argv[i])) - check_missing_init_files(abs_path) + init_dirs = check_missing_init_files(abs_path) + check_all_init_files(init_dirs) diff --git a/src/py/flwr_tool/init_py_fix.py b/src/py/flwr_tool/init_py_fix.py new file mode 100755 index 000000000000..5ad27829ae8e --- /dev/null +++ b/src/py/flwr_tool/init_py_fix.py @@ -0,0 +1,69 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +"""Fix provided directory and sub-directories for unsorted __all__ in __init__.py files. + +Example: + python -m flwr_tool.init_py_fix src/py/flwr +""" + + +import os +import sys +from typing import List + +import black + +from flwr_tool.init_py_check import get_all_var_list, get_init_dir_list_and_warnings + + +def fix_all_init_files(dir_list: List[str]) -> None: + """Sort the __all__ variables that are in __init__.py files.""" + warning_list = [] + + for init_dir in dir_list: + init_file, all_list, all_lines = get_all_var_list(init_dir) + + if all_list: + sorted_all_list = sorted(all_list) + if not all_list == sorted_all_list: + warning_message = "- " + str(init_dir) + warning_list.append(warning_message) + + old_all_lines = "\n".join(all_lines) + new_all_lines = ( + old_all_lines.split("=", 1)[0] + + "= " + + str(sorted_all_list)[:-1] + + ",]" + ) + + new_content = init_file.read_text().replace( + old_all_lines, new_all_lines + ) + + # Write the fixed content back to the file + init_file.write_text(new_content) + + # Format the file with black + black.format_file_in_place( + init_file, + fast=False, + mode=black.FileMode(), + write_back=black.WriteBack.YES, + ) + + if len(warning_list) > 0: + print("'__all__' lists in the following '__init__.py' files have been sorted:") + for warning in warning_list: + print(warning) + + +if __name__ == "__main__": + if len(sys.argv) == 0: + raise Exception( # pylint: disable=W0719 + "Please provide at least one directory path relative " + "to your current working directory." + ) + for i, _ in enumerate(sys.argv): + abs_path: str = os.path.abspath(os.path.join(os.getcwd(), sys.argv[i])) + warnings, init_dirs = get_init_dir_list_and_warnings(abs_path) + fix_all_init_files(init_dirs) From 8816a23cc4a2530275ecec85c9d823b421fab982 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Wed, 19 Jun 2024 14:32:37 +0100 Subject: [PATCH 093/124] refactor(framework) Reload the module and its dependencies in `load_app` (#3597) --- src/py/flwr/client/supernode/app.py | 2 +- src/py/flwr/common/object_ref.py | 44 ++++++++++++++++--- src/py/flwr/server/run_serverapp.py | 4 +- .../server/superlink/fleet/vce/vce_api.py | 2 +- src/py/flwr/superexec/app.py | 2 +- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 97951f2a3279..362b09c5d5b5 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -230,7 +230,7 @@ def _load(fab_id: str, fab_version: str) -> ClientApp: "Loading ClientApp `%s`", client_app_ref, ) - client_app = load_app(client_app_ref, LoadClientAppError) + client_app = load_app(client_app_ref, LoadClientAppError, sys_path) if not isinstance(client_app, ClientApp): raise LoadClientAppError( diff --git a/src/py/flwr/common/object_ref.py b/src/py/flwr/common/object_ref.py index b56c69a4f36b..ac52be160c2e 100644 --- a/src/py/flwr/common/object_ref.py +++ b/src/py/flwr/common/object_ref.py @@ -17,8 +17,13 @@ import ast import importlib +import sys from importlib.util import find_spec -from typing import Any, Optional, Tuple, Type +from logging import WARN +from pathlib import Path +from typing import Any, Optional, Tuple, Type, Union + +from .logger import log OBJECT_REF_HELP_STR = """ \n\nThe object reference string should have the form :. Valid @@ -77,9 +82,10 @@ def validate( ) -def load_app( +def load_app( # pylint: disable= too-many-branches module_attribute_str: str, error_type: Type[Exception], + project_dir: Optional[Union[str, Path]] = None, ) -> Any: """Return the object specified in a module attribute string. @@ -95,11 +101,39 @@ def load_app( module_str, _, attributes_str = module_attribute_str.partition(":") try: - module = importlib.import_module(module_str) - except ModuleNotFoundError: + if module_str not in sys.modules: + module = importlib.import_module(module_str) + # Hack: `tabnet` does not work with `importlib.reload` + elif "tabnet" in sys.modules: + log( + WARN, + "Cannot reload module `%s` from disk due to compatibility issues " + "with the `tabnet` library. The module will be loaded from the " + "cache instead. If you experience issues, consider restarting " + "the application.", + module_str, + ) + module = sys.modules[module_str] + else: + module = sys.modules[module_str] + if project_dir is None: + path: Optional[str] = getattr(module, "__file__", None) + if path is not None: + project_dir = str(Path(path).parent) + else: + project_dir = str(Path(project_dir).absolute()) + + # Reload cached modules in the project directory + if project_dir is not None: + for m in list(sys.modules.values()): + path = getattr(m, "__file__", None) + if path is not None and path.startswith(project_dir): + importlib.reload(m) + + except ModuleNotFoundError as err: raise error_type( f"Unable to load module {module_str}{OBJECT_REF_HELP_STR}", - ) from None + ) from err # Recursively load attribute attribute = module diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index fd0214a040bc..efd3f6846264 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -50,7 +50,9 @@ def run( # Load ServerApp if needed def _load() -> ServerApp: if server_app_attr: - server_app: ServerApp = load_app(server_app_attr, LoadServerAppError) + server_app: ServerApp = load_app( + server_app_attr, LoadServerAppError, server_app_dir + ) if not isinstance(server_app, ServerApp): raise LoadServerAppError( diff --git a/src/py/flwr/server/superlink/fleet/vce/vce_api.py b/src/py/flwr/server/superlink/fleet/vce/vce_api.py index dcd37aba09c0..3c9628a6d2a3 100644 --- a/src/py/flwr/server/superlink/fleet/vce/vce_api.py +++ b/src/py/flwr/server/superlink/fleet/vce/vce_api.py @@ -325,7 +325,7 @@ def _load() -> ClientApp: if app_dir is not None: sys.path.insert(0, app_dir) - app: ClientApp = load_app(client_app_attr, LoadClientAppError) + app: ClientApp = load_app(client_app_attr, LoadClientAppError, app_dir) if not isinstance(app, ClientApp): raise LoadClientAppError( diff --git a/src/py/flwr/superexec/app.py b/src/py/flwr/superexec/app.py index e1cb4f609e9c..fa89e83b5e75 100644 --- a/src/py/flwr/superexec/app.py +++ b/src/py/flwr/superexec/app.py @@ -164,7 +164,7 @@ def _load_executor( if not valid and error_msg: raise LoadExecutorError(error_msg) from None - executor = load_app(executor_ref, LoadExecutorError) + executor = load_app(executor_ref, LoadExecutorError, args.executor_dir) if not isinstance(executor, Executor): raise LoadExecutorError( From 31afc932da503ae3fce90e0ea2a7a50e179eb9dc Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Wed, 19 Jun 2024 17:58:39 +0200 Subject: [PATCH 094/124] ci(*:skip) Allow amend to be use as a valid verb for title (#3651) --- dev/changelog_config.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/dev/changelog_config.toml b/dev/changelog_config.toml index 898f9bfdb221..c5ff1bcdd1c1 100644 --- a/dev/changelog_config.toml +++ b/dev/changelog_config.toml @@ -44,6 +44,7 @@ allowed_verbs=[ "Align", "Allow", "Alter", + "Amend", "Analyse", "Analyze", "Anchor", From 88b08f49da20f983b6ab5c62bfee4e3b565b091e Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Wed, 19 Jun 2024 18:26:32 +0100 Subject: [PATCH 095/124] feat(framework) Add `grpc-adapter` transport (#3540) --- src/py/flwr/client/app.py | 4 ++ src/py/flwr/client/supernode/app.py | 31 +++++++++-- src/py/flwr/common/constant.py | 4 ++ src/py/flwr/server/app.py | 54 ++++++++++++++++--- .../superlink/fleet/grpc_bidi/grpc_server.py | 4 ++ 5 files changed, 86 insertions(+), 11 deletions(-) diff --git a/src/py/flwr/client/app.py b/src/py/flwr/client/app.py index cdb7b25cbf6b..1226a0d7bc21 100644 --- a/src/py/flwr/client/app.py +++ b/src/py/flwr/client/app.py @@ -31,6 +31,7 @@ from flwr.common.address import parse_address from flwr.common.constant import ( MISSING_EXTRA_REST, + TRANSPORT_TYPE_GRPC_ADAPTER, TRANSPORT_TYPE_GRPC_BIDI, TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_REST, @@ -41,6 +42,7 @@ from flwr.common.message import Error from flwr.common.retry_invoker import RetryInvoker, RetryState, exponential +from .grpc_adapter_client.connection import grpc_adapter from .grpc_client.connection import grpc_connection from .grpc_rere_client.connection import grpc_request_response from .message_handler.message_handler import handle_control_message @@ -600,6 +602,8 @@ def _init_connection(transport: Optional[str], server_address: str) -> Tuple[ connection, error_type = http_request_response, RequestsConnectionError elif transport == TRANSPORT_TYPE_GRPC_RERE: connection, error_type = grpc_request_response, RpcError + elif transport == TRANSPORT_TYPE_GRPC_ADAPTER: + connection, error_type = grpc_adapter, RpcError elif transport == TRANSPORT_TYPE_GRPC_BIDI: connection, error_type = grpc_connection, RpcError else: diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 362b09c5d5b5..742281f5c011 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -30,6 +30,11 @@ from flwr.client.client_app import ClientApp, LoadClientAppError from flwr.common import EventType, event from flwr.common.config import get_flwr_dir, get_project_config, get_project_dir +from flwr.common.constant import ( + TRANSPORT_TYPE_GRPC_ADAPTER, + TRANSPORT_TYPE_GRPC_RERE, + TRANSPORT_TYPE_REST, +) from flwr.common.exit_handlers import register_exit_handlers from flwr.common.logger import log, warn_deprecated_feature from flwr.common.object_ref import load_app, validate @@ -56,7 +61,7 @@ def run_supernode() -> None: _start_client_internal( server_address=args.superlink, load_client_app_fn=load_fn, - transport="rest" if args.rest else "grpc-rere", + transport=args.transport, root_certificates=root_certificates, insecure=args.insecure, authentication_keys=authentication_keys, @@ -87,7 +92,7 @@ def run_client_app() -> None: _start_client_internal( server_address=args.superlink, load_client_app_fn=load_fn, - transport="rest" if args.rest else "grpc-rere", + transport=args.transport, root_certificates=root_certificates, insecure=args.insecure, authentication_keys=authentication_keys, @@ -295,9 +300,27 @@ def _parse_args_common(parser: argparse.ArgumentParser) -> None: help="Run the client without HTTPS. By default, the client runs with " "HTTPS enabled. Use this flag only if you understand the risks.", ) - parser.add_argument( + ex_group = parser.add_mutually_exclusive_group() + ex_group.add_argument( + "--grpc-rere", + action="store_const", + dest="transport", + const=TRANSPORT_TYPE_GRPC_RERE, + default=TRANSPORT_TYPE_GRPC_RERE, + help="Use grpc-rere as a transport layer for the client.", + ) + ex_group.add_argument( + "--grpc-adapter", + action="store_const", + dest="transport", + const=TRANSPORT_TYPE_GRPC_ADAPTER, + help="Use grpc-adapter as a transport layer for the client.", + ) + ex_group.add_argument( "--rest", - action="store_true", + action="store_const", + dest="transport", + const=TRANSPORT_TYPE_REST, help="Use REST as a transport layer for the client.", ) parser.add_argument( diff --git a/src/py/flwr/common/constant.py b/src/py/flwr/common/constant.py index ac35549d2051..193f000ca42e 100644 --- a/src/py/flwr/common/constant.py +++ b/src/py/flwr/common/constant.py @@ -27,6 +27,7 @@ TRANSPORT_TYPE_GRPC_BIDI = "grpc-bidi" TRANSPORT_TYPE_GRPC_RERE = "grpc-rere" +TRANSPORT_TYPE_GRPC_ADAPTER = "grpc-adapter" TRANSPORT_TYPE_REST = "rest" TRANSPORT_TYPE_VCE = "vce" TRANSPORT_TYPES = [ @@ -45,6 +46,9 @@ PING_RANDOM_RANGE = (-0.1, 0.1) PING_MAX_INTERVAL = 1e300 +GRPC_ADAPTER_METADATA_FLOWER_VERSION_KEY = "flower-version" +GRPC_ADAPTER_METADATA_SHOULD_EXIT_KEY = "should-exit" + # Constants for FAB APP_DIR = "apps" FAB_CONFIG_FILE = "pyproject.toml" diff --git a/src/py/flwr/server/app.py b/src/py/flwr/server/app.py index 1574ec46f968..822defdb5b13 100644 --- a/src/py/flwr/server/app.py +++ b/src/py/flwr/server/app.py @@ -36,6 +36,7 @@ from flwr.common.address import parse_address from flwr.common.constant import ( MISSING_EXTRA_REST, + TRANSPORT_TYPE_GRPC_ADAPTER, TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_REST, ) @@ -48,6 +49,7 @@ from flwr.proto.fleet_pb2_grpc import ( # pylint: disable=E0611 add_FleetServicer_to_server, ) +from flwr.proto.grpcadapter_pb2_grpc import add_GrpcAdapterServicer_to_server from .client_manager import ClientManager from .history import History @@ -55,6 +57,7 @@ from .server_config import ServerConfig from .strategy import Strategy from .superlink.driver.driver_grpc import run_driver_api_grpc +from .superlink.fleet.grpc_adapter.grpc_adapter_servicer import GrpcAdapterServicer from .superlink.fleet.grpc_bidi.grpc_server import ( generic_create_grpc_server, start_grpc_server, @@ -218,11 +221,13 @@ def run_superlink() -> None: grpc_servers = [driver_server] bckg_threads = [] if not args.fleet_api_address: - args.fleet_api_address = ( - ADDRESS_FLEET_API_GRPC_RERE - if args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE - else ADDRESS_FLEET_API_REST - ) + if args.fleet_api_type in [ + TRANSPORT_TYPE_GRPC_RERE, + TRANSPORT_TYPE_GRPC_ADAPTER, + ]: + args.fleet_api_address = ADDRESS_FLEET_API_GRPC_RERE + elif args.fleet_api_type == TRANSPORT_TYPE_REST: + args.fleet_api_address = ADDRESS_FLEET_API_REST fleet_address, host, port = _format_address(args.fleet_api_address) @@ -293,6 +298,13 @@ def run_superlink() -> None: interceptors=interceptors, ) grpc_servers.append(fleet_server) + elif args.fleet_api_type == TRANSPORT_TYPE_GRPC_ADAPTER: + fleet_server = _run_fleet_api_grpc_adapter( + address=fleet_address, + state_factory=state_factory, + certificates=certificates, + ) + grpc_servers.append(fleet_server) else: raise ValueError(f"Unknown fleet_api_type: {args.fleet_api_type}") @@ -419,7 +431,7 @@ def _try_obtain_certificates( log(WARN, "Option `--insecure` was set. Starting insecure HTTP server.") return None # Check if certificates are provided - if args.fleet_api_type == TRANSPORT_TYPE_GRPC_RERE: + if args.fleet_api_type in [TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_GRPC_ADAPTER]: if args.ssl_certfile and args.ssl_keyfile and args.ssl_ca_certfile: if not isfile(args.ssl_ca_certfile): sys.exit("Path argument `--ssl-ca-certfile` does not point to a file.") @@ -491,6 +503,30 @@ def _run_fleet_api_grpc_rere( return fleet_grpc_server +def _run_fleet_api_grpc_adapter( + address: str, + state_factory: StateFactory, + certificates: Optional[Tuple[bytes, bytes, bytes]], +) -> grpc.Server: + """Run Fleet API (GrpcAdapter).""" + # Create Fleet API gRPC server + fleet_servicer = GrpcAdapterServicer( + state_factory=state_factory, + ) + fleet_add_servicer_to_server_fn = add_GrpcAdapterServicer_to_server + fleet_grpc_server = generic_create_grpc_server( + servicer_and_add_fn=(fleet_servicer, fleet_add_servicer_to_server_fn), + server_address=address, + max_message_length=GRPC_MAX_MESSAGE_LENGTH, + certificates=certificates, + ) + + log(INFO, "Flower ECE: Starting Fleet API (GrpcAdapter) on %s", address) + fleet_grpc_server.start() + + return fleet_grpc_server + + # pylint: disable=import-outside-toplevel,too-many-arguments def _run_fleet_api_rest( host: str, @@ -606,7 +642,11 @@ def _add_args_fleet_api(parser: argparse.ArgumentParser) -> None: "--fleet-api-type", default=TRANSPORT_TYPE_GRPC_RERE, type=str, - choices=[TRANSPORT_TYPE_GRPC_RERE, TRANSPORT_TYPE_REST], + choices=[ + TRANSPORT_TYPE_GRPC_RERE, + TRANSPORT_TYPE_GRPC_ADAPTER, + TRANSPORT_TYPE_REST, + ], help="Start a gRPC-rere or REST (experimental) Fleet API server.", ) parser.add_argument( diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py index 6aeaa7ef413f..ae685fda91a7 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py @@ -29,6 +29,9 @@ ) from flwr.server.client_manager import ClientManager from flwr.server.superlink.driver.driver_servicer import DriverServicer +from flwr.server.superlink.fleet.grpc_adapter.grpc_adapter_servicer import ( + GrpcAdapterServicer, +) from flwr.server.superlink.fleet.grpc_bidi.flower_service_servicer import ( FlowerServiceServicer, ) @@ -154,6 +157,7 @@ def start_grpc_server( # pylint: disable=too-many-arguments def generic_create_grpc_server( # pylint: disable=too-many-arguments servicer_and_add_fn: Union[ Tuple[FleetServicer, AddServicerToServerFn], + Tuple[GrpcAdapterServicer, AddServicerToServerFn], Tuple[FlowerServiceServicer, AddServicerToServerFn], Tuple[DriverServicer, AddServicerToServerFn], ], From 0a16d99eb3213b928df1ed8636b2fa7a3add2f49 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 20 Jun 2024 07:35:45 +0200 Subject: [PATCH 096/124] docs(framework) Add `flwr` cli docs (#3384) --- doc/source/conf.py | 1 + doc/source/ref-api-cli.rst | 9 +++++++++ pyproject.toml | 1 + src/py/flwr/cli/app.py | 3 +++ src/py/flwr/cli/build.py | 10 +++------- src/py/flwr/cli/run/run.py | 5 ++++- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/doc/source/conf.py b/doc/source/conf.py index 85bfe9404521..1452f9c9a7b0 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -108,6 +108,7 @@ "sphinxcontrib.youtube", "sphinx_reredirects", "nbsphinx", + "sphinx_click", ] # Generate .rst files diff --git a/doc/source/ref-api-cli.rst b/doc/source/ref-api-cli.rst index 296c2219a065..4397ae056941 100644 --- a/doc/source/ref-api-cli.rst +++ b/doc/source/ref-api-cli.rst @@ -1,6 +1,15 @@ Flower CLI reference ==================== +.. _flwr-apiref: + +flwr CLI +~~~~~~~~ + +.. click:: flwr.cli.app:typer_click_object + :prog: flwr + :nested: full + .. _flower-simulation-apiref: flower-simulation diff --git a/pyproject.toml b/pyproject.toml index 2dd592050468..dbab703c7671 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,6 +105,7 @@ rope = "==1.11.0" semver = "==3.0.2" sphinx = "==6.2.1" sphinx-intl = "==2.2.0" +sphinx-click = "==5.1.0" myst-parser = "==1.0.0" sphinx-design = "==0.5.0" sphinx-copybutton = "==0.5.2" diff --git a/src/py/flwr/cli/app.py b/src/py/flwr/cli/app.py index 477b990bf1da..d1b270026cd7 100644 --- a/src/py/flwr/cli/app.py +++ b/src/py/flwr/cli/app.py @@ -15,6 +15,7 @@ """Flower command line interface.""" import typer +from typer.main import get_command from .build import build from .example import example @@ -37,5 +38,7 @@ app.command()(build) app.command()(install) +typer_click_object = get_command(app) + if __name__ == "__main__": app() diff --git a/src/py/flwr/cli/build.py b/src/py/flwr/cli/build.py index 2981eacf925d..4a9b54f9223f 100644 --- a/src/py/flwr/cli/build.py +++ b/src/py/flwr/cli/build.py @@ -36,13 +36,9 @@ def build( ) -> str: """Build a Flower project into a Flower App Bundle (FAB). - You can run `flwr build` without any argument to bundle the current directory: - - `flwr build` - - You can also build a specific directory: - - `flwr build --directory ./projects/flower-hello-world` + You can run ``flwr build`` without any arguments to bundle the current directory, + or you can use ``--directory`` to build a specific directory: + ``flwr build --directory ./projects/flower-hello-world``. """ if directory is None: directory = Path.cwd() diff --git a/src/py/flwr/cli/run/run.py b/src/py/flwr/cli/run/run.py index 7577d9efbd8c..28fa67f9d4f6 100644 --- a/src/py/flwr/cli/run/run.py +++ b/src/py/flwr/cli/run/run.py @@ -41,7 +41,10 @@ class Engine(str, Enum): def run( engine: Annotated[ Optional[Engine], - typer.Option(case_sensitive=False, help="The execution engine to run the app"), + typer.Option( + case_sensitive=False, + help="The engine to run FL with (currently only simulation is supported).", + ), ] = None, use_superexec: Annotated[ bool, From 1b72bafa98c0146f08d89e67bf8c8327ef80b45b Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:27:15 +0200 Subject: [PATCH 097/124] fix(datasets) Fix sorting in `__all__` (#3655) --- datasets/flwr_datasets/__init__.py | 5 +++-- datasets/flwr_datasets/partitioner/__init__.py | 12 ++++++------ datasets/flwr_datasets/preprocessor/__init__.py | 2 +- datasets/flwr_datasets/visualization/__init__.py | 2 +- datasets/flwr_datasets/visualization/bar_plot.py | 1 - datasets/flwr_datasets/visualization/heatmap_plot.py | 2 -- 6 files changed, 11 insertions(+), 13 deletions(-) diff --git a/datasets/flwr_datasets/__init__.py b/datasets/flwr_datasets/__init__.py index d084780102ce..bd68fa43c606 100644 --- a/datasets/flwr_datasets/__init__.py +++ b/datasets/flwr_datasets/__init__.py @@ -23,11 +23,12 @@ __all__ = [ "FederatedDataset", - "partitioner", "metrics", - "visualization", + "partitioner", "preprocessor", "utils", + "visualization", ] + __version__ = _package_version diff --git a/datasets/flwr_datasets/partitioner/__init__.py b/datasets/flwr_datasets/partitioner/__init__.py index 0d1edbfcb04a..1fc00ed90323 100644 --- a/datasets/flwr_datasets/partitioner/__init__.py +++ b/datasets/flwr_datasets/partitioner/__init__.py @@ -27,14 +27,14 @@ from .square_partitioner import SquarePartitioner __all__ = [ + "DirichletPartitioner", + "ExponentialPartitioner", "IidPartitioner", - "Partitioner", + "InnerDirichletPartitioner", + "LinearPartitioner", "NaturalIdPartitioner", - "DirichletPartitioner", + "Partitioner", + "ShardPartitioner", "SizePartitioner", - "LinearPartitioner", - "InnerDirichletPartitioner", "SquarePartitioner", - "ShardPartitioner", - "ExponentialPartitioner", ] diff --git a/datasets/flwr_datasets/preprocessor/__init__.py b/datasets/flwr_datasets/preprocessor/__init__.py index bab5d82a2035..67b2aaadc3d2 100644 --- a/datasets/flwr_datasets/preprocessor/__init__.py +++ b/datasets/flwr_datasets/preprocessor/__init__.py @@ -20,7 +20,7 @@ from .preprocessor import Preprocessor __all__ = [ + "Divider", "Merger", "Preprocessor", - "Divider", ] diff --git a/datasets/flwr_datasets/visualization/__init__.py b/datasets/flwr_datasets/visualization/__init__.py index 801a38dcafc6..b55e406c71db 100644 --- a/datasets/flwr_datasets/visualization/__init__.py +++ b/datasets/flwr_datasets/visualization/__init__.py @@ -19,6 +19,6 @@ from .label_distribution import plot_label_distributions __all__ = [ - "plot_label_distributions", "plot_comparison_label_distribution", + "plot_label_distributions", ] diff --git a/datasets/flwr_datasets/visualization/bar_plot.py b/datasets/flwr_datasets/visualization/bar_plot.py index 6326b24a9695..339ff0967906 100644 --- a/datasets/flwr_datasets/visualization/bar_plot.py +++ b/datasets/flwr_datasets/visualization/bar_plot.py @@ -38,7 +38,6 @@ def _plot_bar( plot_kwargs: Optional[Dict[str, Any]], legend_kwargs: Optional[Dict[str, Any]], ) -> Axes: - if axis is None: if figsize is None: figsize = _initialize_figsize( diff --git a/datasets/flwr_datasets/visualization/heatmap_plot.py b/datasets/flwr_datasets/visualization/heatmap_plot.py index 2e593a79368e..3c87de7693ae 100644 --- a/datasets/flwr_datasets/visualization/heatmap_plot.py +++ b/datasets/flwr_datasets/visualization/heatmap_plot.py @@ -39,7 +39,6 @@ def _plot_heatmap( plot_kwargs: Optional[Dict[str, Any]], legend_kwargs: Optional[Dict[str, Any]], ) -> Axes: - if axis is None: if figsize is None: figsize = _initialize_figsize( @@ -92,7 +91,6 @@ def _initialize_figsize( num_partitions: int, num_labels: int, ) -> Tuple[float, float]: - figsize = (0.0, 0.0) if partition_id_axis == "x": figsize = (3 * np.sqrt(num_partitions), np.sqrt(num_labels)) From 2ede64758dbc8fc5bcadada8e2fddefa693c5633 Mon Sep 17 00:00:00 2001 From: Mohammad Naseri Date: Thu, 20 Jun 2024 13:43:11 +0200 Subject: [PATCH 098/124] feat(examples) Add Tabular Dataset Example (#3568) Co-authored-by: jafermarq --- README.md | 1 + examples/fl-tabular/README.md | 39 +++++++++++ examples/fl-tabular/client.py | 38 ++++++++++ examples/fl-tabular/pyproject.toml | 20 ++++++ examples/fl-tabular/server.py | 24 +++++++ examples/fl-tabular/task.py | 108 +++++++++++++++++++++++++++++ 6 files changed, 230 insertions(+) create mode 100644 examples/fl-tabular/README.md create mode 100644 examples/fl-tabular/client.py create mode 100644 examples/fl-tabular/pyproject.toml create mode 100644 examples/fl-tabular/server.py create mode 100644 examples/fl-tabular/task.py diff --git a/README.md b/README.md index a010abfcb2f5..16cb7f1cfaf6 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples): - [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter) - [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus) - [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy) +- [Flower with a Tabular Dataset] (https://github.com/adap/flower/tree/main/examples/fl-tabular) ## Community diff --git a/examples/fl-tabular/README.md b/examples/fl-tabular/README.md new file mode 100644 index 000000000000..58afd1080b70 --- /dev/null +++ b/examples/fl-tabular/README.md @@ -0,0 +1,39 @@ +# Flower Example on Adult Census Income Tabular Dataset + +This code exemplifies a federated learning setup using the Flower framework on the ["Adult Census Income"](https://huggingface.co/datasets/scikit-learn/adult-census-income) tabular dataset. The "Adult Census Income" dataset contains demographic information such as age, education, occupation, etc., with the target attribute being income level (\<=50K or >50K). The dataset is partitioned into subsets, simulating a federated environment with 5 clients, each holding a distinct portion of the data. Categorical variables are one-hot encoded, and the data is split into training and testing sets. Federated learning is conducted using the FedAvg strategy for 5 rounds. + +This example uses [Flower Datasets](https://flower.ai/docs/datasets/) to download, partition and preprocess the dataset. + +## Environments Setup + +Start by cloning the example. We prepared a single-line command that you can copy into your shell which will checkout the example for you: + +```shell +git clone --depth=1 https://github.com/adap/flower.git && mv flower/examples/fl-tabular . && rm -rf flower && cd fl-tabular +``` + +This will create a new directory called `fl-tabular` containing the following files: + +```shell +-- pyproject.toml +-- client.py +-- server.py +-- task.py +-- README.md +``` + +### Installing dependencies + +Project dependencies are defined in `pyproject.toml`. Install them with: + +```shell +pip install . +``` + +## Running Code + +### Federated Using Flower Simulation + +```bash +flower-simulation --server-app server:app --client-app client:app --num-supernodes 5 +``` diff --git a/examples/fl-tabular/client.py b/examples/fl-tabular/client.py new file mode 100644 index 000000000000..228183f4edc4 --- /dev/null +++ b/examples/fl-tabular/client.py @@ -0,0 +1,38 @@ +from flwr.client import Client, ClientApp, NumPyClient +from flwr_datasets import FederatedDataset +from task import set_weights, get_weights, train, evaluate, IncomeClassifier, load_data + +NUMBER_OF_CLIENTS = 5 + + +class FlowerClient(NumPyClient): + def __init__(self, net, trainloader, testloader): + self.net = net + self.trainloader = trainloader + self.testloader = testloader + + def fit(self, parameters, config): + set_weights(self.net, parameters) + train(self.net, self.trainloader) + return get_weights(self.net), len(self.trainloader), {} + + def evaluate(self, parameters, config): + set_weights(self.net, parameters) + loss, accuracy = evaluate(self.net, self.testloader) + return loss, len(self.testloader), {"accuracy": accuracy} + + +def get_client_fn(dataset: FederatedDataset): + def client_fn(cid: str) -> Client: + train_loader, test_loader = load_data(partition_id=int(cid), fds=dataset) + net = IncomeClassifier(14) + return FlowerClient(net, train_loader, test_loader).to_client() + + return client_fn + + +fds = FederatedDataset( + dataset="scikit-learn/adult-census-income", + partitioners={"train": NUMBER_OF_CLIENTS}, +) +app = ClientApp(client_fn=get_client_fn(fds)) diff --git a/examples/fl-tabular/pyproject.toml b/examples/fl-tabular/pyproject.toml new file mode 100644 index 000000000000..07ff226d5d06 --- /dev/null +++ b/examples/fl-tabular/pyproject.toml @@ -0,0 +1,20 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "fl-tabular" +version = "0.1.0" +description = "Adult Census Income Tabular Dataset and Federated Learning in Flower" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +dependencies = [ + "flwr[simulation]>=1.9.0,<2.0", + "flwr-datasets>=0.1.0,<1.0.0", + "torch==2.1.1", + "scikit-learn==1.4.2", +] + +[tool.hatch.build.targets.wheel] +packages = ["."] diff --git a/examples/fl-tabular/server.py b/examples/fl-tabular/server.py new file mode 100644 index 000000000000..376726f832f7 --- /dev/null +++ b/examples/fl-tabular/server.py @@ -0,0 +1,24 @@ +from flwr.common import ndarrays_to_parameters +from flwr.server import ServerApp, ServerConfig +from flwr.server.strategy import FedAvg +from task import IncomeClassifier, get_weights + +net = IncomeClassifier(input_dim=14) +params = ndarrays_to_parameters(get_weights(net)) + + +def weighted_average(metrics): + accuracies = [num_examples * m["accuracy"] for num_examples, m in metrics] + examples = [num_examples for num_examples, _ in metrics] + + return {"accuracy": sum(accuracies) / sum(examples)} + + +strategy = FedAvg( + initial_parameters=params, + evaluate_metrics_aggregation_fn=weighted_average, +) +app = ServerApp( + strategy=strategy, + config=ServerConfig(num_rounds=5), +) diff --git a/examples/fl-tabular/task.py b/examples/fl-tabular/task.py new file mode 100644 index 000000000000..b07365c733d6 --- /dev/null +++ b/examples/fl-tabular/task.py @@ -0,0 +1,108 @@ +import torch +import torch.nn as nn +import torch.optim as optim +from torch.utils.data import TensorDataset, DataLoader +from sklearn.model_selection import train_test_split +from sklearn.preprocessing import StandardScaler, OrdinalEncoder +from sklearn.compose import ColumnTransformer +from sklearn.pipeline import Pipeline +from collections import OrderedDict +from flwr_datasets import FederatedDataset + + +def load_data(partition_id: int, fds: FederatedDataset): + dataset = fds.load_partition(partition_id, "train").with_format("pandas")[:] + + dataset.dropna(inplace=True) + + categorical_cols = dataset.select_dtypes(include=["object"]).columns + ordinal_encoder = OrdinalEncoder() + dataset[categorical_cols] = ordinal_encoder.fit_transform(dataset[categorical_cols]) + + X = dataset.drop("income", axis=1) + y = dataset["income"] + + X_train, X_test, y_train, y_test = train_test_split( + X, y, test_size=0.2, random_state=42 + ) + + numeric_features = X.select_dtypes(include=["float64", "int64"]).columns + numeric_transformer = Pipeline(steps=[("scaler", StandardScaler())]) + + preprocessor = ColumnTransformer( + transformers=[("num", numeric_transformer, numeric_features)] + ) + + X_train = preprocessor.fit_transform(X_train) + X_test = preprocessor.transform(X_test) + + X_train_tensor = torch.tensor(X_train, dtype=torch.float32) + X_test_tensor = torch.tensor(X_test, dtype=torch.float32) + y_train_tensor = torch.tensor(y_train.values, dtype=torch.float32).view(-1, 1) + y_test_tensor = torch.tensor(y_test.values, dtype=torch.float32).view(-1, 1) + + train_dataset = TensorDataset(X_train_tensor, y_train_tensor) + test_dataset = TensorDataset(X_test_tensor, y_test_tensor) + train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) + test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) + + return train_loader, test_loader + + +class IncomeClassifier(nn.Module): + def __init__(self, input_dim: int): + super(IncomeClassifier, self).__init__() + self.layer1 = nn.Linear(input_dim, 128) + self.layer2 = nn.Linear(128, 64) + self.output = nn.Linear(64, 1) + self.relu = nn.ReLU() + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + x = self.relu(self.layer1(x)) + x = self.relu(self.layer2(x)) + x = self.sigmoid(self.output(x)) + return x + + +def train(model, train_loader, num_epochs=1): + criterion = nn.BCELoss() + optimizer = optim.Adam(model.parameters(), lr=0.001) + model.train() + for epoch in range(num_epochs): + for X_batch, y_batch in train_loader: + optimizer.zero_grad() + outputs = model(X_batch) + loss = criterion(outputs, y_batch) + loss.backward() + optimizer.step() + + +def evaluate(model, test_loader): + model.eval() + criterion = nn.BCELoss() + loss = 0.0 + correct = 0 + total = 0 + with torch.no_grad(): + for X_batch, y_batch in test_loader: + outputs = model(X_batch) + batch_loss = criterion(outputs, y_batch) + loss += batch_loss.item() + predicted = (outputs > 0.5).float() + total += y_batch.size(0) + correct += (predicted == y_batch).sum().item() + accuracy = correct / total + loss = loss / len(test_loader) + return loss, accuracy + + +def set_weights(net, parameters): + params_dict = zip(net.state_dict().keys(), parameters) + state_dict = OrderedDict({k: torch.tensor(v) for k, v in params_dict}) + net.load_state_dict(state_dict, strict=True) + + +def get_weights(net): + ndarrays = [val.cpu().numpy() for _, val in net.state_dict().items()] + return ndarrays From 02fe0519b9be4124ef6a244c3d85a7a1eaef40d6 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 20 Jun 2024 12:55:50 +0100 Subject: [PATCH 099/124] feat(framework) Implement DriverAPI `GetRun` (#3580) Co-authored-by: Daniel J. Beutel Co-authored-by: Javier --- src/py/flwr/server/compat/app_utils.py | 2 +- src/py/flwr/server/driver/driver.py | 6 + src/py/flwr/server/driver/grpc_driver.py | 146 ++++++++++-------- src/py/flwr/server/driver/grpc_driver_test.py | 87 ++++------- src/py/flwr/server/driver/inmemory_driver.py | 54 +++---- .../server/driver/inmemory_driver_test.py | 58 ++++--- src/py/flwr/server/run_serverapp.py | 19 ++- .../superlink/driver/driver_servicer.py | 16 +- src/py/flwr/simulation/run_simulation.py | 23 ++- 9 files changed, 232 insertions(+), 179 deletions(-) diff --git a/src/py/flwr/server/compat/app_utils.py b/src/py/flwr/server/compat/app_utils.py index 1cdf1efbffb9..baff27307b88 100644 --- a/src/py/flwr/server/compat/app_utils.py +++ b/src/py/flwr/server/compat/app_utils.py @@ -91,7 +91,7 @@ def _update_client_manager( node_id=node_id, driver=driver, anonymous=False, - run_id=driver.run_id, # type: ignore + run_id=driver.run.run_id, ) if client_manager.register(client_proxy): registered_nodes[node_id] = client_proxy diff --git a/src/py/flwr/server/driver/driver.py b/src/py/flwr/server/driver/driver.py index b95cec95ab47..4f888323e586 100644 --- a/src/py/flwr/server/driver/driver.py +++ b/src/py/flwr/server/driver/driver.py @@ -19,11 +19,17 @@ from typing import Iterable, List, Optional from flwr.common import Message, RecordSet +from flwr.common.typing import Run class Driver(ABC): """Abstract base Driver class for the Driver API.""" + @property + @abstractmethod + def run(self) -> Run: + """Run information.""" + @abstractmethod def create_message( # pylint: disable=too-many-arguments self, diff --git a/src/py/flwr/server/driver/grpc_driver.py b/src/py/flwr/server/driver/grpc_driver.py index d339f1b232f9..2016d54b655a 100644 --- a/src/py/flwr/server/driver/grpc_driver.py +++ b/src/py/flwr/server/driver/grpc_driver.py @@ -17,7 +17,7 @@ import time import warnings from logging import DEBUG, ERROR, WARNING -from typing import Iterable, List, Optional, Tuple +from typing import Iterable, List, Optional, Tuple, cast import grpc @@ -25,6 +25,7 @@ from flwr.common.grpc import create_channel from flwr.common.logger import log from flwr.common.serde import message_from_taskres, message_to_taskins +from flwr.common.typing import Run from flwr.proto.driver_pb2 import ( # pylint: disable=E0611 CreateRunRequest, CreateRunResponse, @@ -37,6 +38,7 @@ ) from flwr.proto.driver_pb2_grpc import DriverStub # pylint: disable=E0611 from flwr.proto.node_pb2 import Node # pylint: disable=E0611 +from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 from flwr.proto.task_pb2 import TaskIns # pylint: disable=E0611 from .driver import Driver @@ -46,13 +48,24 @@ ERROR_MESSAGE_DRIVER_NOT_CONNECTED = """ [Driver] Error: Not connected. -Call `connect()` on the `GrpcDriverHelper` instance before calling any of the other -`GrpcDriverHelper` methods. +Call `connect()` on the `GrpcDriverStub` instance before calling any of the other +`GrpcDriverStub` methods. """ -class GrpcDriverHelper: - """`GrpcDriverHelper` provides access to the gRPC Driver API/service.""" +class GrpcDriverStub: + """`GrpcDriverStub` provides access to the gRPC Driver API/service. + + Parameters + ---------- + driver_service_address : Optional[str] + The IPv4 or IPv6 address of the Driver API server. + Defaults to `"[::]:9091"`. + root_certificates : Optional[bytes] (default: None) + The PEM-encoded root certificates as a byte string. + If provided, a secure connection using the certificates will be + established to an SSL-enabled Flower server. + """ def __init__( self, @@ -64,6 +77,10 @@ def __init__( self.channel: Optional[grpc.Channel] = None self.stub: Optional[DriverStub] = None + def is_connected(self) -> bool: + """Return True if connected to the Driver API server, otherwise False.""" + return self.channel is not None + def connect(self) -> None: """Connect to the Driver API.""" event(EventType.DRIVER_CONNECT) @@ -95,18 +112,29 @@ def create_run(self, req: CreateRunRequest) -> CreateRunResponse: # Check if channel is open if self.stub is None: log(ERROR, ERROR_MESSAGE_DRIVER_NOT_CONNECTED) - raise ConnectionError("`GrpcDriverHelper` instance not connected") + raise ConnectionError("`GrpcDriverStub` instance not connected") # Call Driver API res: CreateRunResponse = self.stub.CreateRun(request=req) return res + def get_run(self, req: GetRunRequest) -> GetRunResponse: + """Get run information.""" + # Check if channel is open + if self.stub is None: + log(ERROR, ERROR_MESSAGE_DRIVER_NOT_CONNECTED) + raise ConnectionError("`GrpcDriverStub` instance not connected") + + # Call gRPC Driver API + res: GetRunResponse = self.stub.GetRun(request=req) + return res + def get_nodes(self, req: GetNodesRequest) -> GetNodesResponse: """Get client IDs.""" # Check if channel is open if self.stub is None: log(ERROR, ERROR_MESSAGE_DRIVER_NOT_CONNECTED) - raise ConnectionError("`GrpcDriverHelper` instance not connected") + raise ConnectionError("`GrpcDriverStub` instance not connected") # Call gRPC Driver API res: GetNodesResponse = self.stub.GetNodes(request=req) @@ -117,7 +145,7 @@ def push_task_ins(self, req: PushTaskInsRequest) -> PushTaskInsResponse: # Check if channel is open if self.stub is None: log(ERROR, ERROR_MESSAGE_DRIVER_NOT_CONNECTED) - raise ConnectionError("`GrpcDriverHelper` instance not connected") + raise ConnectionError("`GrpcDriverStub` instance not connected") # Call gRPC Driver API res: PushTaskInsResponse = self.stub.PushTaskIns(request=req) @@ -128,7 +156,7 @@ def pull_task_res(self, req: PullTaskResRequest) -> PullTaskResResponse: # Check if channel is open if self.stub is None: log(ERROR, ERROR_MESSAGE_DRIVER_NOT_CONNECTED) - raise ConnectionError("`GrpcDriverHelper` instance not connected") + raise ConnectionError("`GrpcDriverStub` instance not connected") # Call Driver API res: PullTaskResResponse = self.stub.PullTaskRes(request=req) @@ -140,56 +168,52 @@ class GrpcDriver(Driver): Parameters ---------- - driver_service_address : Optional[str] - The IPv4 or IPv6 address of the Driver API server. - Defaults to `"[::]:9091"`. - certificates : bytes (default: None) - Tuple containing root certificate, server certificate, and private key - to start a secure SSL-enabled server. The tuple is expected to have - three bytes elements in the following order: - - * CA certificate. - * server certificate. - * server private key. - fab_id : str (default: None) - The identifier of the FAB used in the run. - fab_version : str (default: None) - The version of the FAB used in the run. + run_id : int + The identifier of the run. + stub : Optional[GrpcDriverStub] (default: None) + The ``GrpcDriverStub`` instance used to communicate with the SuperLink. + If None, an instance connected to "[::]:9091" will be created. """ - def __init__( + def __init__( # pylint: disable=too-many-arguments self, - driver_service_address: str = DEFAULT_SERVER_ADDRESS_DRIVER, - root_certificates: Optional[bytes] = None, - fab_id: Optional[str] = None, - fab_version: Optional[str] = None, + run_id: int, + stub: Optional[GrpcDriverStub] = None, ) -> None: - self.addr = driver_service_address - self.root_certificates = root_certificates - self.driver_helper: Optional[GrpcDriverHelper] = None - self.run_id: Optional[int] = None - self.fab_id = fab_id if fab_id is not None else "" - self.fab_version = fab_version if fab_version is not None else "" + self._run_id = run_id + self._run: Optional[Run] = None + self.stub = stub if stub is not None else GrpcDriverStub() self.node = Node(node_id=0, anonymous=True) - def _get_grpc_driver_helper_and_run_id(self) -> Tuple[GrpcDriverHelper, int]: - # Check if the GrpcDriverHelper is initialized - if self.driver_helper is None or self.run_id is None: - # Connect and create run - self.driver_helper = GrpcDriverHelper( - driver_service_address=self.addr, - root_certificates=self.root_certificates, + @property + def run(self) -> Run: + """Run information.""" + self._get_stub_and_run_id() + return Run(**vars(cast(Run, self._run))) + + def _get_stub_and_run_id(self) -> Tuple[GrpcDriverStub, int]: + # Check if is initialized + if self._run is None: + # Connect + if not self.stub.is_connected(): + self.stub.connect() + # Get the run info + req = GetRunRequest(run_id=self._run_id) + res = self.stub.get_run(req) + if not res.HasField("run"): + raise RuntimeError(f"Cannot find the run with ID: {self._run_id}") + self._run = Run( + run_id=res.run.run_id, + fab_id=res.run.fab_id, + fab_version=res.run.fab_version, ) - self.driver_helper.connect() - req = CreateRunRequest(fab_id=self.fab_id, fab_version=self.fab_version) - res = self.driver_helper.create_run(req) - self.run_id = res.run_id - return self.driver_helper, self.run_id + + return self.stub, self._run.run_id def _check_message(self, message: Message) -> None: # Check if the message is valid if not ( - message.metadata.run_id == self.run_id + message.metadata.run_id == cast(Run, self._run).run_id and message.metadata.src_node_id == self.node.node_id and message.metadata.message_id == "" and message.metadata.reply_to_message == "" @@ -210,7 +234,7 @@ def create_message( # pylint: disable=too-many-arguments This method constructs a new `Message` with given content and metadata. The `run_id` and `src_node_id` will be set automatically. """ - _, run_id = self._get_grpc_driver_helper_and_run_id() + _, run_id = self._get_stub_and_run_id() if ttl: warnings.warn( "A custom TTL was set, but note that the SuperLink does not enforce " @@ -234,9 +258,9 @@ def create_message( # pylint: disable=too-many-arguments def get_node_ids(self) -> List[int]: """Get node IDs.""" - grpc_driver_helper, run_id = self._get_grpc_driver_helper_and_run_id() - # Call GrpcDriverHelper method - res = grpc_driver_helper.get_nodes(GetNodesRequest(run_id=run_id)) + stub, run_id = self._get_stub_and_run_id() + # Call GrpcDriverStub method + res = stub.get_nodes(GetNodesRequest(run_id=run_id)) return [node.node_id for node in res.nodes] def push_messages(self, messages: Iterable[Message]) -> Iterable[str]: @@ -245,7 +269,7 @@ def push_messages(self, messages: Iterable[Message]) -> Iterable[str]: This method takes an iterable of messages and sends each message to the node specified in `dst_node_id`. """ - grpc_driver_helper, _ = self._get_grpc_driver_helper_and_run_id() + stub, _ = self._get_stub_and_run_id() # Construct TaskIns task_ins_list: List[TaskIns] = [] for msg in messages: @@ -255,10 +279,8 @@ def push_messages(self, messages: Iterable[Message]) -> Iterable[str]: taskins = message_to_taskins(msg) # Add to list task_ins_list.append(taskins) - # Call GrpcDriverHelper method - res = grpc_driver_helper.push_task_ins( - PushTaskInsRequest(task_ins_list=task_ins_list) - ) + # Call GrpcDriverStub method + res = stub.push_task_ins(PushTaskInsRequest(task_ins_list=task_ins_list)) return list(res.task_ids) def pull_messages(self, message_ids: Iterable[str]) -> Iterable[Message]: @@ -267,9 +289,9 @@ def pull_messages(self, message_ids: Iterable[str]) -> Iterable[Message]: This method is used to collect messages from the SuperLink that correspond to a set of given message IDs. """ - grpc_driver, _ = self._get_grpc_driver_helper_and_run_id() + stub, _ = self._get_stub_and_run_id() # Pull TaskRes - res = grpc_driver.pull_task_res( + res = stub.pull_task_res( PullTaskResRequest(node=self.node, task_ids=message_ids) ) # Convert TaskRes to Message @@ -308,8 +330,8 @@ def send_and_receive( def close(self) -> None: """Disconnect from the SuperLink if connected.""" - # Check if GrpcDriverHelper is initialized - if self.driver_helper is None: + # Check if `connect` was called before + if not self.stub.is_connected(): return # Disconnect - self.driver_helper.disconnect() + self.stub.disconnect() diff --git a/src/py/flwr/server/driver/grpc_driver_test.py b/src/py/flwr/server/driver/grpc_driver_test.py index fbead0e3043d..60ab79002f85 100644 --- a/src/py/flwr/server/driver/grpc_driver_test.py +++ b/src/py/flwr/server/driver/grpc_driver_test.py @@ -27,6 +27,7 @@ PullTaskResRequest, PushTaskInsRequest, ) +from flwr.proto.run_pb2 import Run # pylint: disable=E0611 from flwr.proto.task_pb2 import Task, TaskRes # pylint: disable=E0611 from .grpc_driver import GrpcDriver @@ -36,58 +37,36 @@ class TestGrpcDriver(unittest.TestCase): """Tests for `GrpcDriver` class.""" def setUp(self) -> None: - """Initialize mock GrpcDriverHelper and Driver instance before each test.""" - mock_response = Mock() - mock_response.run_id = 61016 - self.mock_grpc_driver_helper = Mock() - self.mock_grpc_driver_helper.create_run.return_value = mock_response - self.patcher = patch( - "flwr.server.driver.grpc_driver.GrpcDriverHelper", - return_value=self.mock_grpc_driver_helper, + """Initialize mock GrpcDriverStub and Driver instance before each test.""" + mock_response = Mock( + run=Run(run_id=61016, fab_id="mock/mock", fab_version="v1.0.0") ) - self.patcher.start() - self.driver = GrpcDriver() - - def tearDown(self) -> None: - """Cleanup after each test.""" - self.patcher.stop() - - def test_check_and_init_grpc_driver_already_initialized(self) -> None: - """Test that GrpcDriverHelper doesn't initialize if run is created.""" - # Prepare - self.driver.driver_helper = self.mock_grpc_driver_helper - self.driver.run_id = 61016 - - # Execute - # pylint: disable-next=protected-access - self.driver._get_grpc_driver_helper_and_run_id() + self.mock_grpc_driver_stub = Mock() + self.mock_grpc_driver_stub.get_run.return_value = mock_response + self.mock_grpc_driver_stub.HasField.return_value = True + self.driver = GrpcDriver(run_id=61016, stub=self.mock_grpc_driver_stub) + def test_init_grpc_driver(self) -> None: + """Test GrpcDriverStub initialization.""" # Assert - self.mock_grpc_driver_helper.connect.assert_not_called() - - def test_check_and_init_grpc_driver_needs_initialization(self) -> None: - """Test GrpcDriverHelper initialization when run is not created.""" - # Execute - # pylint: disable-next=protected-access - self.driver._get_grpc_driver_helper_and_run_id() - - # Assert - self.mock_grpc_driver_helper.connect.assert_called_once() - self.assertEqual(self.driver.run_id, 61016) + self.assertEqual(self.driver.run.run_id, 61016) + self.assertEqual(self.driver.run.fab_id, "mock/mock") + self.assertEqual(self.driver.run.fab_version, "v1.0.0") + self.mock_grpc_driver_stub.get_run.assert_called_once() def test_get_nodes(self) -> None: """Test retrieval of nodes.""" # Prepare mock_response = Mock() mock_response.nodes = [Mock(node_id=404), Mock(node_id=200)] - self.mock_grpc_driver_helper.get_nodes.return_value = mock_response + self.mock_grpc_driver_stub.get_nodes.return_value = mock_response # Execute node_ids = self.driver.get_node_ids() - args, kwargs = self.mock_grpc_driver_helper.get_nodes.call_args + args, kwargs = self.mock_grpc_driver_stub.get_nodes.call_args # Assert - self.mock_grpc_driver_helper.connect.assert_called_once() + self.mock_grpc_driver_stub.get_run.assert_called_once() self.assertEqual(len(args), 1) self.assertEqual(len(kwargs), 0) self.assertIsInstance(args[0], GetNodesRequest) @@ -98,7 +77,7 @@ def test_push_messages_valid(self) -> None: """Test pushing valid messages.""" # Prepare mock_response = Mock(task_ids=["id1", "id2"]) - self.mock_grpc_driver_helper.push_task_ins.return_value = mock_response + self.mock_grpc_driver_stub.push_task_ins.return_value = mock_response msgs = [ self.driver.create_message(RecordSet(), "", 0, "", DEFAULT_TTL) for _ in range(2) @@ -106,10 +85,10 @@ def test_push_messages_valid(self) -> None: # Execute msg_ids = self.driver.push_messages(msgs) - args, kwargs = self.mock_grpc_driver_helper.push_task_ins.call_args + args, kwargs = self.mock_grpc_driver_stub.push_task_ins.call_args # Assert - self.mock_grpc_driver_helper.connect.assert_called_once() + self.mock_grpc_driver_stub.get_run.assert_called_once() self.assertEqual(len(args), 1) self.assertEqual(len(kwargs), 0) self.assertIsInstance(args[0], PushTaskInsRequest) @@ -121,7 +100,7 @@ def test_push_messages_invalid(self) -> None: """Test pushing invalid messages.""" # Prepare mock_response = Mock(task_ids=["id1", "id2"]) - self.mock_grpc_driver_helper.push_task_ins.return_value = mock_response + self.mock_grpc_driver_stub.push_task_ins.return_value = mock_response msgs = [ self.driver.create_message(RecordSet(), "", 0, "", DEFAULT_TTL) for _ in range(2) @@ -145,16 +124,16 @@ def test_pull_messages_with_given_message_ids(self) -> None: ), TaskRes(task=Task(ancestry=["id3"], error=error_to_proto(Error(code=0)))), ] - self.mock_grpc_driver_helper.pull_task_res.return_value = mock_response + self.mock_grpc_driver_stub.pull_task_res.return_value = mock_response msg_ids = ["id1", "id2", "id3"] # Execute msgs = self.driver.pull_messages(msg_ids) reply_tos = {msg.metadata.reply_to_message for msg in msgs} - args, kwargs = self.mock_grpc_driver_helper.pull_task_res.call_args + args, kwargs = self.mock_grpc_driver_stub.pull_task_res.call_args # Assert - self.mock_grpc_driver_helper.connect.assert_called_once() + self.mock_grpc_driver_stub.get_run.assert_called_once() self.assertEqual(len(args), 1) self.assertEqual(len(kwargs), 0) self.assertIsInstance(args[0], PullTaskResRequest) @@ -165,14 +144,14 @@ def test_send_and_receive_messages_complete(self) -> None: """Test send and receive all messages successfully.""" # Prepare mock_response = Mock(task_ids=["id1"]) - self.mock_grpc_driver_helper.push_task_ins.return_value = mock_response + self.mock_grpc_driver_stub.push_task_ins.return_value = mock_response # The response message must include either `content` (i.e. a recordset) or # an `Error`. We choose the latter in this case error_proto = error_to_proto(Error(code=0)) mock_response = Mock( task_res_list=[TaskRes(task=Task(ancestry=["id1"], error=error_proto))] ) - self.mock_grpc_driver_helper.pull_task_res.return_value = mock_response + self.mock_grpc_driver_stub.pull_task_res.return_value = mock_response msgs = [self.driver.create_message(RecordSet(), "", 0, "", DEFAULT_TTL)] # Execute @@ -187,9 +166,9 @@ def test_send_and_receive_messages_timeout(self) -> None: # Prepare sleep_fn = time.sleep mock_response = Mock(task_ids=["id1"]) - self.mock_grpc_driver_helper.push_task_ins.return_value = mock_response + self.mock_grpc_driver_stub.push_task_ins.return_value = mock_response mock_response = Mock(task_res_list=[]) - self.mock_grpc_driver_helper.pull_task_res.return_value = mock_response + self.mock_grpc_driver_stub.pull_task_res.return_value = mock_response msgs = [self.driver.create_message(RecordSet(), "", 0, "", DEFAULT_TTL)] # Execute @@ -204,19 +183,21 @@ def test_send_and_receive_messages_timeout(self) -> None: def test_del_with_initialized_driver(self) -> None: """Test cleanup behavior when Driver is initialized.""" # Prepare - # pylint: disable-next=protected-access - self.driver._get_grpc_driver_helper_and_run_id() + self.mock_grpc_driver_stub.is_connected.return_value = True # Execute self.driver.close() # Assert - self.mock_grpc_driver_helper.disconnect.assert_called_once() + self.mock_grpc_driver_stub.disconnect.assert_called_once() def test_del_with_uninitialized_driver(self) -> None: """Test cleanup behavior when Driver is not initialized.""" + # Prepare + self.mock_grpc_driver_stub.is_connected.return_value = False + # Execute self.driver.close() # Assert - self.mock_grpc_driver_helper.disconnect.assert_not_called() + self.mock_grpc_driver_stub.disconnect.assert_not_called() diff --git a/src/py/flwr/server/driver/inmemory_driver.py b/src/py/flwr/server/driver/inmemory_driver.py index 8c71b1067293..53406796750f 100644 --- a/src/py/flwr/server/driver/inmemory_driver.py +++ b/src/py/flwr/server/driver/inmemory_driver.py @@ -17,11 +17,12 @@ import time import warnings -from typing import Iterable, List, Optional +from typing import Iterable, List, Optional, cast from uuid import UUID from flwr.common import DEFAULT_TTL, Message, Metadata, RecordSet from flwr.common.serde import message_from_taskres, message_to_taskins +from flwr.common.typing import Run from flwr.proto.node_pb2 import Node # pylint: disable=E0611 from flwr.server.superlink.state import StateFactory @@ -33,30 +34,27 @@ class InMemoryDriver(Driver): Parameters ---------- + run_id : int + The identifier of the run. state_factory : StateFactory A StateFactory embedding a state that this driver can interface with. - fab_id : str (default: None) - The identifier of the FAB used in the run. - fab_version : str (default: None) - The version of the FAB used in the run. """ def __init__( self, + run_id: int, state_factory: StateFactory, - fab_id: Optional[str] = None, - fab_version: Optional[str] = None, ) -> None: - self.run_id: Optional[int] = None - self.fab_id = fab_id if fab_id is not None else "" - self.fab_version = fab_version if fab_version is not None else "" - self.node = Node(node_id=0, anonymous=True) + self._run_id = run_id + self._run: Optional[Run] = None self.state = state_factory.state() + self.node = Node(node_id=0, anonymous=True) def _check_message(self, message: Message) -> None: + self._init_run() # Check if the message is valid if not ( - message.metadata.run_id == self.run_id + message.metadata.run_id == cast(Run, self._run).run_id and message.metadata.src_node_id == self.node.node_id and message.metadata.message_id == "" and message.metadata.reply_to_message == "" @@ -64,16 +62,20 @@ def _check_message(self, message: Message) -> None: ): raise ValueError(f"Invalid message: {message}") - def _get_run_id(self) -> int: - """Return run_id. - - If unset, create a new run. - """ - if self.run_id is None: - self.run_id = self.state.create_run( - fab_id=self.fab_id, fab_version=self.fab_version - ) - return self.run_id + def _init_run(self) -> None: + """Initialize the run.""" + if self._run is not None: + return + run = self.state.get_run(self._run_id) + if run is None: + raise RuntimeError(f"Cannot find the run with ID: {self._run_id}") + self._run = run + + @property + def run(self) -> Run: + """Run ID.""" + self._init_run() + return Run(**vars(cast(Run, self._run))) def create_message( # pylint: disable=too-many-arguments self, @@ -88,7 +90,7 @@ def create_message( # pylint: disable=too-many-arguments This method constructs a new `Message` with given content and metadata. The `run_id` and `src_node_id` will be set automatically. """ - run_id = self._get_run_id() + self._init_run() if ttl: warnings.warn( "A custom TTL was set, but note that the SuperLink does not enforce " @@ -99,7 +101,7 @@ def create_message( # pylint: disable=too-many-arguments ttl_ = DEFAULT_TTL if ttl is None else ttl metadata = Metadata( - run_id=run_id, + run_id=cast(Run, self._run).run_id, message_id="", # Will be set by the server src_node_id=self.node.node_id, dst_node_id=dst_node_id, @@ -112,8 +114,8 @@ def create_message( # pylint: disable=too-many-arguments def get_node_ids(self) -> List[int]: """Get node IDs.""" - run_id = self._get_run_id() - return list(self.state.get_nodes(run_id)) + self._init_run() + return list(self.state.get_nodes(cast(Run, self._run).run_id)) def push_messages(self, messages: Iterable[Message]) -> Iterable[str]: """Push messages to specified node IDs. diff --git a/src/py/flwr/server/driver/inmemory_driver_test.py b/src/py/flwr/server/driver/inmemory_driver_test.py index 95c2a0b277af..55d52d848dfd 100644 --- a/src/py/flwr/server/driver/inmemory_driver_test.py +++ b/src/py/flwr/server/driver/inmemory_driver_test.py @@ -31,8 +31,9 @@ message_to_taskres, recordset_to_proto, ) +from flwr.common.typing import Run from flwr.proto.task_pb2 import Task, TaskRes # pylint: disable=E0611 -from flwr.server.superlink.state import StateFactory +from flwr.server.superlink.state import InMemoryState, SqliteState, StateFactory from .inmemory_driver import InMemoryDriver @@ -79,12 +80,24 @@ def setUp(self) -> None: """ # Create driver self.num_nodes = 42 - self.driver = InMemoryDriver(StateFactory("")) - self.driver.state = MagicMock() - self.driver.state.get_nodes.return_value = [ + self.state = MagicMock() + self.state.get_nodes.return_value = [ int.from_bytes(os.urandom(8), "little", signed=True) for _ in range(self.num_nodes) ] + self.state.get_run.return_value = Run( + run_id=61016, fab_id="mock/mock", fab_version="v1.0.0" + ) + state_factory = MagicMock(state=lambda: self.state) + self.driver = InMemoryDriver(run_id=61016, state_factory=state_factory) + self.driver.state = self.state + + def test_get_run(self) -> None: + """Test the InMemoryDriver starting with run_id.""" + # Assert + self.assertEqual(self.driver.run.run_id, 61016) + self.assertEqual(self.driver.run.fab_id, "mock/mock") + self.assertEqual(self.driver.run.fab_version, "v1.0.0") def test_get_nodes(self) -> None: """Test retrieval of nodes.""" @@ -104,7 +117,7 @@ def test_push_messages_valid(self) -> None: ] taskins_ids = [uuid4() for _ in range(num_messages)] - self.driver.state.store_task_ins.side_effect = taskins_ids # type: ignore + self.state.store_task_ins.side_effect = taskins_ids # Execute msg_ids = list(self.driver.push_messages(msgs)) @@ -141,7 +154,7 @@ def test_pull_messages_with_given_message_ids(self) -> None: task=Task(ancestry=[msg_ids[1]], error=error_to_proto(Error(code=0))) ), ] - self.driver.state.get_task_res.return_value = task_res_list # type: ignore + self.state.get_task_res.return_value = task_res_list # Execute pulled_msgs = list(self.driver.pull_messages(msg_ids)) @@ -167,8 +180,8 @@ def test_send_and_receive_messages_complete(self) -> None: task=Task(ancestry=[msg_ids[1]], error=error_to_proto(Error(code=0))) ), ] - self.driver.state.store_task_ins.side_effect = msg_ids # type: ignore - self.driver.state.get_task_res.return_value = task_res_list # type: ignore + self.state.store_task_ins.side_effect = msg_ids + self.state.get_task_res.return_value = task_res_list # Execute ret_msgs = list(self.driver.send_and_receive(msgs)) @@ -193,8 +206,8 @@ def test_send_and_receive_messages_timeout(self) -> None: task=Task(ancestry=[msg_ids[1]], error=error_to_proto(Error(code=0))) ), ] - self.driver.state.store_task_ins.side_effect = msg_ids # type: ignore - self.driver.state.get_task_res.return_value = task_res_list # type: ignore + self.state.store_task_ins.side_effect = msg_ids + self.state.get_task_res.return_value = task_res_list # Execute with patch("time.sleep", side_effect=lambda t: time.sleep(t * 0.01)): @@ -208,19 +221,23 @@ def test_send_and_receive_messages_timeout(self) -> None: def test_task_store_consistency_after_push_pull_sqlitestate(self) -> None: """Test tasks are deleted in sqlite state once messages are pulled.""" # Prepare - self.driver = InMemoryDriver(StateFactory("")) + state = StateFactory("").state() + self.driver = InMemoryDriver( + state.create_run("", ""), MagicMock(state=lambda: state) + ) msg_ids, node_id = push_messages(self.driver, self.num_nodes) + assert isinstance(state, SqliteState) # Check recorded - task_ins = self.driver.state.query("SELECT * FROM task_ins;") # type: ignore + task_ins = state.query("SELECT * FROM task_ins;") self.assertEqual(len(task_ins), len(list(msg_ids))) # Prepare: create replies reply_tos = get_replies(self.driver, msg_ids, node_id) # Query number of task_ins and task_res in State - task_res = self.driver.state.query("SELECT * FROM task_res;") # type: ignore - task_ins = self.driver.state.query("SELECT * FROM task_ins;") # type: ignore + task_res = state.query("SELECT * FROM task_res;") + task_ins = state.query("SELECT * FROM task_ins;") # Assert self.assertEqual(reply_tos, msg_ids) @@ -230,18 +247,19 @@ def test_task_store_consistency_after_push_pull_sqlitestate(self) -> None: def test_task_store_consistency_after_push_pull_inmemory_state(self) -> None: """Test tasks are deleted in in-memory state once messages are pulled.""" # Prepare - self.driver = InMemoryDriver(StateFactory(":flwr-in-memory-state:")) + state_factory = StateFactory(":flwr-in-memory-state:") + state = state_factory.state() + self.driver = InMemoryDriver(state.create_run("", ""), state_factory) msg_ids, node_id = push_messages(self.driver, self.num_nodes) + assert isinstance(state, InMemoryState) # Check recorded - self.assertEqual( - len(self.driver.state.task_ins_store), len(list(msg_ids)) # type: ignore - ) + self.assertEqual(len(state.task_ins_store), len(list(msg_ids))) # Prepare: create replies reply_tos = get_replies(self.driver, msg_ids, node_id) # Assert self.assertEqual(reply_tos, msg_ids) - self.assertEqual(len(self.driver.state.task_res_store), 0) # type: ignore - self.assertEqual(len(self.driver.state.task_ins_store), 0) # type: ignore + self.assertEqual(len(state.task_res_store), 0) + self.assertEqual(len(state.task_ins_store), 0) diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index efd3f6846264..63ffc4a1caae 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -24,8 +24,10 @@ from flwr.common import Context, EventType, RecordSet, event from flwr.common.logger import log, update_console_handler, warn_deprecated_feature from flwr.common.object_ref import load_app +from flwr.proto.driver_pb2 import CreateRunRequest # pylint: disable=E0611 -from .driver import Driver, GrpcDriver +from .driver import Driver +from .driver.grpc_driver import GrpcDriver, GrpcDriverStub from .server_app import LoadServerAppError, ServerApp ADDRESS_DRIVER_API = "0.0.0.0:9091" @@ -149,13 +151,16 @@ def run_server_app() -> None: server_app_dir = args.dir server_app_attr = getattr(args, "server-app") - # Initialize GrpcDriver - driver = GrpcDriver( - driver_service_address=args.superlink, - root_certificates=root_certificates, - fab_id=args.fab_id, - fab_version=args.fab_version, + # Create run + stub = GrpcDriverStub( + driver_service_address=args.superlink, root_certificates=root_certificates ) + stub.connect() + req = CreateRunRequest(fab_id=args.fab_id, fab_version=args.fab_version) + res = stub.create_run(req) + + # Initialize GrpcDriver + driver = GrpcDriver(run_id=res.run_id, stub=stub) # Run the ServerApp with the Driver run(driver=driver, server_app_dir=server_app_dir, server_app_attr=server_app_attr) diff --git a/src/py/flwr/server/superlink/driver/driver_servicer.py b/src/py/flwr/server/superlink/driver/driver_servicer.py index e808616af778..30d2e883dc63 100644 --- a/src/py/flwr/server/superlink/driver/driver_servicer.py +++ b/src/py/flwr/server/superlink/driver/driver_servicer.py @@ -35,7 +35,11 @@ PushTaskInsResponse, ) from flwr.proto.node_pb2 import Node # pylint: disable=E0611 -from flwr.proto.run_pb2 import GetRunRequest, GetRunResponse # pylint: disable=E0611 +from flwr.proto.run_pb2 import ( # pylint: disable=E0611 + GetRunRequest, + GetRunResponse, + Run, +) from flwr.proto.task_pb2 import TaskRes # pylint: disable=E0611 from flwr.server.superlink.state import State, StateFactory from flwr.server.utils.validator import validate_task_ins_or_res @@ -134,7 +138,15 @@ def GetRun( self, request: GetRunRequest, context: grpc.ServicerContext ) -> GetRunResponse: """Get run information.""" - raise NotImplementedError + log(DEBUG, "DriverServicer.GetRun") + + # Init state + state: State = self.state_factory.state() + + # Retrieve run information + run = state.get_run(request.run_id) + run_proto = None if run is None else Run(**vars(run)) + return GetRunResponse(run=run_proto) def _raise_if(validation_error: bool, detail: str) -> None: diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index 3532c5a4e877..a3de1401d252 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -27,7 +27,7 @@ from flwr.client import ClientApp from flwr.common import EventType, event, log from flwr.common.logger import set_logger_propagation, update_console_handler -from flwr.common.typing import ConfigsRecordValues +from flwr.common.typing import ConfigsRecordValues, Run from flwr.server.driver import Driver, InMemoryDriver from flwr.server.run_serverapp import run from flwr.server.server_app import ServerApp @@ -169,11 +169,14 @@ def server_th_with_start_checks( # type: ignore return serverapp_th -def _init_run_id(driver: InMemoryDriver, state: StateFactory, run_id: int) -> None: - """Create a run with a given `run_id`.""" +def _override_run_id(state: StateFactory, run_id_to_replace: int, run_id: int) -> None: + """Override the run_id of an existing Run.""" log(DEBUG, "Pre-registering run with id %s", run_id) - state.state().run_ids[run_id] = ("", "") # type: ignore - driver.run_id = run_id + # Remove run + run_info: Run = state.state().run_ids.pop(run_id_to_replace) # type: ignore + # Update with new run_id and insert back in state + run_info.run_id = run_id + state.state().run_ids[run_id] = run_info # type: ignore # pylint: disable=too-many-locals @@ -201,11 +204,15 @@ def _main_loop( f_stop = asyncio.Event() serverapp_th = None try: - # Initialize Driver - driver = InMemoryDriver(state_factory) + # Create run (with empty fab_id and fab_version) + run_id_ = state_factory.state().create_run("", "") if run_id: - _init_run_id(driver, state_factory, run_id) + _override_run_id(state_factory, run_id_to_replace=run_id_, run_id=run_id) + run_id_ = run_id + + # Initialize Driver + driver = InMemoryDriver(run_id=run_id_, state_factory=state_factory) # Get and run ServerApp thread serverapp_th = run_serverapp_th( From 85918cb3784c76bfbd87eb978d58867f20615fea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 20 Jun 2024 12:03:41 +0000 Subject: [PATCH 100/124] chore(deps): bump scikit-learn from 1.4.2 to 1.5.0 in /examples/fl-tabular (#3656) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- examples/fl-tabular/pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fl-tabular/pyproject.toml b/examples/fl-tabular/pyproject.toml index 07ff226d5d06..21498f73a4f3 100644 --- a/examples/fl-tabular/pyproject.toml +++ b/examples/fl-tabular/pyproject.toml @@ -13,7 +13,7 @@ dependencies = [ "flwr[simulation]>=1.9.0,<2.0", "flwr-datasets>=0.1.0,<1.0.0", "torch==2.1.1", - "scikit-learn==1.4.2", + "scikit-learn==1.5.0", ] [tool.hatch.build.targets.wheel] From 7a77ff20b4f071278981d05cb116815dcba0e0e3 Mon Sep 17 00:00:00 2001 From: Yan Gao Date: Thu, 20 Jun 2024 20:17:48 +0800 Subject: [PATCH 101/124] feat(*:skip) Initialize FlowerTune LLM Leaderboard (#3541) Co-authored-by: jafermarq --- benchmarks/flowertune-llm/README.md | 61 ++++++++++++++++++ .../flowertune-llm/_static/flower_llm.jpg | Bin 0 -> 1627444 bytes 2 files changed, 61 insertions(+) create mode 100644 benchmarks/flowertune-llm/README.md create mode 100644 benchmarks/flowertune-llm/_static/flower_llm.jpg diff --git a/benchmarks/flowertune-llm/README.md b/benchmarks/flowertune-llm/README.md new file mode 100644 index 000000000000..0cb69e7ff9c7 --- /dev/null +++ b/benchmarks/flowertune-llm/README.md @@ -0,0 +1,61 @@ +![](_static/flower_llm.jpg) + +# FlowerTune LLM Leaderboard + +This repository guides you through the process of federated LLM instruction tuning with a +pre-trained [Mistral-7B](https://huggingface.co/mistralai/Mistral-7B-v0.3) model across 4 domains --- general NLP, finance, medical and code. + +Please follow the instructions to run and evaluate the federated LLMs. + +## Create a new project + +As the first step, please register a Flower account on [Flower website](https://flower.ai/login). +Assuming `flwr` package is already installed on your system (check [here](https://flower.ai/docs/framework/how-to-install-flower.html) for `flwr` installation). +We provide a single-line command to create a new project directory based on your selected challenge: + +```shell +flwr new --framework=flwrtune --username=your_flower_account +``` + +Then you will see a prompt to ask your project name and the choice of LLM challenges from the set of general NLP, finance, medical and code. +Type your project name and select your preferred challenge, +and then a new project directory will be generated automatically. + +### Structure + +After running `flwr new`, you will see a new directory generated with the following structure: + +```bash + + ├── README.md # <- Instructions + ├── pyproject.toml # <- Environment dependencies + └── + ├── app.py # <- Flower ClientApp/ServerApp build + ├── client.py # <- Flower client constructor + ├── server.py # <- Sever-related functions + ├── models.py # <- Model build + ├── dataset.py # <- Dataset and tokenizer build + ├── conf/config.yaml # <- User configuration + └── conf/static_config.yaml # <- Static configuration +``` + +This can serve as the starting point for you to build up your own federated LLM fine-tuning methods. +Please note that any modification to the content of `conf/static_config.yaml` is strictly prohibited for those who wish to participate in the [LLM Leaderboard](https://flower.ai/benchmarks/llm-leaderboard). +Otherwise, the submission will not be considered. + +## Run FlowerTune LLM challenges + +With a new project directory created, running a baseline challenge can be done by: + +1. Navigate inside the directory that you just created. + + +2. Follow the `Environments setup` section of `README.md` in the project directory to install project dependencies. + + +3. Run the challenge as indicated in the `Running the challenge` section in the `README.md`. + +## Evaluate pre-trained LLMs + +After the LLM fine-tuning finished, evaluate the performance of your pre-trained LLMs +following the `README.md` in `evaluation` directory. diff --git a/benchmarks/flowertune-llm/_static/flower_llm.jpg b/benchmarks/flowertune-llm/_static/flower_llm.jpg new file mode 100644 index 0000000000000000000000000000000000000000..96081d9c2ad1990ae72819f3f5eb69d969ebe971 GIT binary patch literal 1627444 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%0A7{5F5BYxauj^MH64Xh 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

uYG7s(h)Kq}}$!(Op@jR>4UQ@p(|Jln0WvIY;Cu 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%0A{S1D=bu=GUZukc`_7bEiJ^v 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

WByN7-JQ9khI$HWT5(Fyx23#yG>%PvDF2 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 z z?qy$$8QScXymrV|LptB(xSr|=)~PPZHIf~)ww<`t7St+q6P*;!zhc_utR-tJ+G&r{MqEUw(UEX7nr7W;o6zxJ1ftylBtUs%TO2~#MNyu@$ zcc+PjFS4oLzdG0|BCy{PwW4L>%5f~vXB=1XgZPnt4|&mSKAjLTH%zid?S%GwDe zLq)r;7-&Mudi9G_45d}T$C994q{%Sx(|I!)l}VqKLl3;QY67eA4wa@(%vZStJZmJP zu*@mRv}&VMWp375#TF>qHowswE)*$nRW74MP;aXIzy&<J154&5%& zH9g&}#aC=sv~nB?nKETL54h?}$Jtn!j_b62>tp@r7b~1f+yNPho>g#vG7$Bs$)mT)n&*5fHFerEuKk-;vC+4EgV~pGSsf>HKzM6oZ}JHlPi3R zFG}ajQFStr-^-HiVZTb_?WHL;#`EJ4hg8tGEEU7?L12cFD}vMm0BDY-)Xr0EX+Y_Z z`lrbf&9+~cWfKUVS5-$2lxtbBUwI(UH#&|n5B%Z`=_yp>qT%g{nW)V$MNx$)sX8Ms zCFa}V%5s{OM5zIA0=WMGiw?s^QCTzO$PA+pF~?|eh@D*%N|fzuL|VK|&4fdKsWX+F zqG4mlIVX(m9r;!XOOihtMIPEFi_&P#G0BM6RZ>k2F-}xpjaq+4wzO5VuEm;#hQv2g z>Gh)?PNa1s3}acJD6&G1m#0*o7&KSfZbvix_PCCfrQNGm^KRPJe zZVquvOOR$oW1;|}T$DZ0OEm*^k*&?H8^v4!GU}d4R~yN-hEB}o*Ls5lqrgk8U`DiO zhM`fa7?o3RpkNb>M!8nfQWZ;P5rhDk?X^0Kc7-7~L&h&<7oM>K$^QU3x)D|7 ztHF(YR+HX$ieA)(U6o=w>~#I5`yFuT9&koc97-zB`~@2qJ2GMpkh%$tGB7vN7dXw(IhaRf_q|4oa$e zQ#q6+Qw)v5lUT3xoX+Arcv8%HPdNctG5dHp^<}w=*%-Hz-mVD-hIGeMV`AF$2=u9L zNTY?KYU5HU)9a%fKZ_nrv9H1|x!HBXi4!%$8*wgW4pFhq1%?BBAifHkuQtY1Gdi2(Nbnz%^ts&y3jU^M}*sb zm;eLZ9Px`S3Z^wxTFcjo#a1mFq)t>!(E)_%w8*2kAx_XMH|@4lS*%3TVoV^)0gJpM%Bn#F`O3Rud!_B+mU4Y1CM#c)AJs~~ zGp5bVC(23H79}TM+d7)}Gt!A`UkP!!I|q_Hrc9p`Vax(Jo1QY`lN933RP-#BWLkkJ z%vkm`m*YCR>Jh#epP-zh9ztUuSe1KBYE6J0fG1IRGPkTzB+35(RVujTLdKQOoT=7D zFgYs6Y@ED%-4XNJlBm?5TDan;5wUVO?!8I_)R<9S$0KgSfS-k2nLZUhnU*DTv}4JQ zsA9CG%pO;vAe2dTH#}}iCSR4vf@36{x#wU>?YmYWv!mRqwN*X!uBu8xTbJEv@~jb7 zr4x-hNO9R?$a3_fs>zm{<5nO|)q||n26|>j_>{T#3%QFEk`%%esEJ6MTHj=DO}VwX z!X;$eIpQl~w=lYrX0?{4HM;TgGJM%3#VUCdfSPnt8i!_;QHmYVqGSZHqBg*1caWh) z1Lr@vp0*t5{cO11NbYBDgPJY`2L%1!CfFxtUr-%uD8urLSqK+HAF;H>+mM`e+8hO&xsy04se1$}&bjB20XmT2MPXAW5%& z=~8v5T0JjH2X7usnI|Kel1QO6xQu)bs}-N`R0hfJZlH)L@n&hi94!&&YHbQQv7|c$ zaY(&vfa)^mJF}JeZduKe>>9;Tl=xb#Av)cmQ1w2m;(n}1ll5_*2#G7Ot2NQ$tv zxfXm;<*Px6i7^0~>IEy2BN-Vw$ClKU9m}fJ!j(kpw2<qXQ5Bw8mT*Vkvtg+NC z-1KiV$R0!S)l*RXW-@(m?4=vXa(^#hZm|iqV1qX9)R|CfWBZuLp(Kf!-xBSp989U~738I?vz-}jTG52WL1R-w=yb4I$QJ;HSJg_Z zji=30kXGfM(QBm1ok}wUvXl({q7N!4m|#;P7)BDKwIj=QFpQ4KKepmv)4PUYdU`s_ zmA>83tfnFH_pLPbLKechEnn3_Y8SBOLj%;O!jF;B&)e6 zajK2WteC4NF|zo?eTN;y!T$C$e$cLAjuNFT9o49jqII&Ogf&Nbzf-wtC0SCVs*FP9#uwx^Mlq!|JtgsjSq3zU{{W;VHsu|zT8T1Ittm=3 zsp)(uVlHbr`L{GcbFZO0qs+*?44}Ufl_tkiK+_ zjlif8)S^1AJ|ns&HCn-vD7=KRMJXyLb4`%2O7cS7k%dYT$y1T8ausn+#uoR&fU<-vRkK}%fCID-X`FY5U!pK>q8q$X^Oriy;Q&f&9qmT)6 zs}$o{vEfE*Xz~d6=T#)0(9B1fOYv`dD(t_u!m*H5dGV*ljM9xZ>jEh{P(5qN#dyUX zQM{XHTzn$%oO1E?a85Irp8Vi7`(B=aok{1(A;I=dXE@G%$}`jCx}22KXHmvA1N%5u z;CSS>Pf4nBK3lRgn8b+9kZt@~@ttyP+ ztq`ildbK~Rs3M5|MO#Dn80{L#ksz@JaK@$H=V6(x<;uUTZY;)qo-<7Qky-3(1GxQq(Qt~1$SVy8l3FxIF^5E{mf1{ z>D#{`0u!fiQSr`4YQb#QSYF#6NXU3(u#sch>&4Tv*_3v%$b}aB8`PeZLaigm zSry|#RCt+zKCx3u+98H;*(yFY^4RH|{VPrueZ>2WntN4tt-r9XAygQuy`LU%qtmg0 z6OwHiJE>K-DcsVq8WBIV=%QvgnBSz|j>XitH$-_bc_VDDD}2EwwG5}YHg*A!G1#s* zE-qwei4aOH4y#TxM;&>d^Pyun&nrVA*p(wW$jA$)mm!;5<6I0Su#Vu$dMjLfSh4jM zZs2j!E`Jbdg1uqab;`^*8oyjN@t)(SDt9G_Mn0VNv1RIH#<$`pxP!TaNihvn%$CjM z@$5ljQx#UK$vo!M6M9Os>8aN8Xf3IYCmKR~XAY?8Bmtk)iYXxw(r6V#nvI1+vdM~~ z<5i;kI1^v0&4wUj2}T*iE_S$v``S>`KQXIAGA~Jy38zj$h1WbVWIh&wFLu|=&mF~@ z({=1g=MJH(nj;F$*6s$ixtj+etYWQ3m_!cBxe7qbXwG{6lZ=dUytyKZ2AeU}@hAl( zbs;#$w!`l(J`9%`Bx?!CHPRx}N<>hJ(S7089CFr^(i|h7tin_yTCO8AE*!cXLAB$f z-NRYkLrrGdDJ<#@3$f0*F0Rh7R|-}08x!6u#yXPSw|eM-d-m~k#w9!rje4f@9pUlh zV`eGUT>N|hgxN|Cd9qbo8w!+9NCX0jr@ ziG8aG7iGnGJE@SXhbms0uI5)+9J!%RjB=Qj6Za8f7L7YCMkE2*PV>UcLB79FFYWTuZJfT&_+OjEZhD_hfsmi*E zcSx&L*t9_B6+(OCnpz|a-9)-*x{t(>BnPGnr-HRVZ&|vtfoUOX0-rc$s*l9Tzf@x% z)Hci3;R0`x+_cFKze*=iVea{RYfrLVWsT2J{St=aCT6j%n3E%C;Hya7Kt006V|Heo zD^)Wt9m3=!o^#4VD;jJzjIial@hdjf^jBvIguTJSVG`oKHwi?YOe+$Ci^XCD#J%MR z+arlJj&Zoia`~ketSOj?(wiOb(FVq!2-;xeK>#c$?n#}H1IL{i?-uw(IA%mZ(Jwka z10sGVZ3e7eF^Pje%k?r9$sfkGXMn8oi!&tzrE2lCO4Az{%w;baO{KHBiL#kjZU~6s z_^Vul79N3UqE$S)tCwfwCqwcK(*!jrhzp5n6gvt}Ic5*C95UQx#{IcC;~f3^rj?c0 zhK!X&)+;D_aYcxxWl3bj+(co`)5j8da2ty^^TyU&)fsX8!&4oaS@N_B4d`$tk>h?jRz51QM*Khp9H2RCI^w5YmyJn zCfe8K%9z+mHRPj|Dd@Fevn``mE5~LHGCU~sHO&Nt6 zoQIKAv4-ejRh^j`=1QvosHh1VZrN0&OM-ROStOxNYMh`RS_lhqLz~%>0SqEpyY;cB=6s?(#-8R_;M{ys#&UjQD?ho&4JnQs95TH zQcg6eOv8iDZ&6hM2&hWGiL6#WO^>B}bvV|u;3;Iu6eoIANlh_`jwKjZWbbV@>)z!veB?X6I7pNO=Y^ zceiTWluxK}oUaW=Jb`HIQ#5-i&Or@ZU9Q*C9vb76al@*+)zi5G3N-l~g2?kN6yq9E zLvgl7Z{sS;jI2D}3)~)-EO~JstXQ6YTR(JY>6h^)5spsdh=Z>piJ8U(PW!-!#(!kH z($N=#1xIW1+NTdj8&#^@N55CyJ1SUYu_t0@FjCm^Y4EXcg@-V^fot=4wld zRBB+|)mdaV`}VXFkqGoFxZX^(M(%%*%!w^j zCn>`_1d5%?uD)%cs)cOu@-B+Rqa+>82%g0hRGMnRxVt3jY{8n?Ntwr!H#{<{s*!t` z+K8hiOC_V;i9FT~mv5;iN)4;mj zI`{Z-y;b=6hn$m~V{(a^{FKr{3c{I)}nC-m`Qi`#qs=CNrqk3{cedsw$O7@?c;^lUC;MA>kK4j1 zm-)?N@Z`>;Qm-V=Gcj7~f(j;U*`(T&I?zP4-l&!z*#auND<}1OnqC<*kzUq&&{9N& z0_r}MZ&490Ab6Av)-H}YZw~OnMM<>%7}2Q^tITsAV%iLxxmhfc!NBpZv)#nKMIP9``_sKCgQux@pfIU|%xS}2!Jn2OCns&z!GMHyT<>vz?Tw3P=Q z8m|dDt)hf!)+mbkfY%)vHQR)DW!j zbKp@M=+0boC+VznBJ(hUwLENORaSDvX4@r$*f}s91jbmx@#T(Z9Q>Jwdu?)iF(+Pd zBU+WEobi?-66^Ud+-o+0&g%N@txqzRuz^PgB+?OWnFFgoR-(?luiRRaO*BKu z0dLmoTreOSsfNgbGX5QaIT~ zDIeUaCFurA%s500em)sWuVz_1OT~S`;(CEp`DNw3LoOi2mnN9qi&97~Ct)+3o#yt? zvQ`4}@`yVI(`EUnmAsPT4x=WVX9ulOWkjK%WD!cy8P*Y?6L)FUB=o#OGr!7BJdw@< zax8)qe%b~cYiSuET6Fmk$uD@11CNxhD=C<1(~QP+-YCbBK(6uMOJmLMFXJ-ECHTOx zlM|2?WO&ebbkx-cO8F)25St~ZO=bBNnruD<)SUkS!P6rqOqltsS!f+|Sf9&{P_)BT z6;vKjq}--AD>qZ47F3FJnC`MHvO5KRL@S$a==S1$YKp*M#LTyP?5x6xPC76slT}ur zf^w0Wztlt5^IQS+DP$zuGdOXTLs@_yOjh#_f`tN)x)15UN@K03(%FZ7as)2%1BXOxzV^X9ECHHhgS; zm^D?4BIg9usGPbE9uoWw0C5^USnyITUW`9*${3P-S8~6X=_?z-l_Qws_SuAS?oWC_r6u-@ z3-M64kfrBB zX!?)aqZJOP=7(K!%B&dkuW^&5o=!ZFj6KIp%*B^zo+f6KUaTsJa<>p3n8vYXGm5LH zI&xt4iiw${G0hoC&NmA|sWP6+F5~`6rDbQ5IeH*uYdkPfsshPki?bxSMxL z8 zM>0-baG8_>r$n1b(dA$?-6Ga>L`~|<%NekFtjyRW6)cAupirn;UB|e1O;mW3NR(OB za!m49k`x&5k$!(wxCG_HplkL?fO%93_pKbsJGpgH!M@E@^?FIwNfb4-lKiFYG${oX z4zVo;8Z8M0hM3WHYiOL=tr_y;#)xrO#&so=_w7aLCSwiXPSG+9A&#BT zp9nF>C*?6Zb<>UX%j-A(GdXMaQ~soX)gQ3A7MBvAczA!Pju#dp;15v$0M5w!XZ0Tx zPt9Y1;l{2iV>-|#2!-dLSRFKdSv+9T+mhZ1yRIB~Dr{{UaF znEwEX@V{;RS^DNIkucVLj(6F8N$PDM-8SEhf5JRtyYJUC>kqF;d;5lX{QDXE%0Kv5{;yw#`o-(8 zdY@C&^**Pm>U~dB)cT&MuWEg`^#iv*(;dDDUThct03jO3k%RvK00)o%0JNX3N7=t2 zKQrIgQvM|N{k^}skD1{={4xIk(e?Nr)&BtLx7vTJ@6#{dpVN1}7HR0;c0G;izTM+` zg=Q+=-uEI2`k%AC*T}=7I5$$VQWVjS z0#U)io7!VKO}t+;Q=F=@DL*}7{#H-8$Z)M>h|tu;?vN2&-zT^RV^JnVhm}hs+H+S5 z{%0?@nSB(meKitZMQHDeUszFp(2VliQfNZ*! z#u>W{9AU$fRy<&i4nEwPJi&OobC*2yY+|ZSC=rtnxF){b!th=;?J3%K0w9YOZD|^b zwXyO!JXohMpUS+rJZ?M>KcC8_X*Grl{9;Ec~W5fK` zAvF=i@Ubxy=DVswwX%!RcbSN+mc%!c93O9w#pN&wlhiPfW1JoF;%9z0$l|{&d#m-y z`YiS@H<#&t=>1gwpS>H_8Co2lO~2kRU{}>AN&*k>_&i^5UYsd{tNqnGb@FCq8gsaR zgg=SB^2eJO@YlV`jH#GW?DIhty$oCs_Ely~L}TJa{H4NskK!-Ty}n?*$LrqH9z^4e zdziSVDzjsh4aSOuxc0?pwX}O1^`-hd`-jX=O7>ssr|bv0J$C%cad^Iw>0fs}n*On2 zRf_)r*?JRttobzKE%_X9*GQSUrkn1xPp13d;jiK^XOU<3f5ZO!54SNbH|+C3?Yg;; z8JxPgBYHTZHL23{Ueox8^pDgQ2=?Etdu*9>6*}JCW^!3XQd^z(RhSNYr0X50>TN|^ zk=MyyPZ@uyQYiIcsjKWrX<~hTS;Go1_my=WdnRM_>SGRhh(0Lv%wA1%B4bI{C3r8T z+Lbc-e1t|5oWUJQ8G8^ry0gxB+EZR;WQ7|yiJ3=Wteva9g3yy%rt$4)m43YySCek7 zl@lpH6lHQo$|Qv8hm2!2E0vH7flBT~HoHVwicb=u7|}TM42Cbq40sD;aTik)GkzAj zhV)_rcOoJWqmU0my_hRPhknRJ5ruWNHR3uZ}=4|)UqbsJ+1R6 zJIFS>Q*027?7e+~wguhM?gkWhld&b^P!_c?SHKvT|vt>lFSK5Na90$}cSB zQGAoGBGcsGY^6csjZiSeP|Wi2Jm}(B;p8zG(R|@Qu#|T$^e|vKnPMVV*8Z6(qw4DK z6`IY2UQ_J1Ys`mXK!J~1MVKm-P$rGDtFihMlcF%ZiAW_YK^0J6V_7d*m*oO*U#r5+Bh(&TaL%1(@khSuHbAywSHla9o0 z{{SigXZgwkKG|fJkz9wuXNjrClAh6tH{bW6UH6$FCT9q=oLf*<_7!7%c6)6`&t?5f z2@xtG8CkeTKQv;^X~s23I6DOES`$Pn@?(~Ivcw~g{ND9BBNEb{ss-~>WvDun_|eSp z2t;Eu$j#uA>703@4sB+VzA{*LxSb8wVh?zA;u5||J_I>*iowTHzSFOVB@q~{uL4j5 zf)!nJsy@Z7lndnSV>TSQFwR9d&B)-K0TUH-Zr_ICEP{xI%e;k{d;9N~y7&rSUgP_v>zoc5 z_XBZxPNDfegXw%u9}ChwF|?O&3(#fBcu$kb2M0K~s3{{Xdm@xM#;uhjaUr>XTlPgCl8o~P9HJ$o5O6-WDp0RI5%2mW8Kgr-tc z9}0bN3U@O;xDx*WsVDyc#gXoB{{URSXutk#>K|Q)_*OUiz9aXm{{ZNE;lEw~0P=QU z_{Xo%{{V`ixA^b1}zl(n!WX+HG$M}L; zwilUOaSk98uLbzRuZ-FAfgF^dZT<+1EBI^l8GLeK_U28#H4e+MHk~FP8MdSC5|ZQy zsxGec={c$zXs6| zrU0-f5eUGNW}jDF9u83efN5Udh)i(it|)bWyswfP3zdCYtm=O zYBZ=?Wjk$MOFZ;dNU2r$)wH!nt^GmbD4f|cDYi#CMqzk}mCnt;$)?m?!t&eQqC?0l zIF=-)QIjs{@f=Y?RPl#8Ry!hPcDk}fD)_pxQ;jDHhhiCNKD)b?1(em5Rf;oFTSZnM zE{SkSoI6=CsY#t4AGTKu@bXZ^g%dNoaH~wM@?Sw8L3yQ1d8HdqfjJT^}tBm3tg!gr6DVjxO@~-a(3Ov*x za@oU#((9&Rp8W1LH>VbBEy3+7CaBk=X^Fl(lHF6?8E$A9j@)ZD*P~){1T86*)bb4B;K>M#{sJh9Z6(8MTn_;uZU< zq@SDebXT z>sGq}TyEi)<7asQ&yy~S{+>j2YM31>-$oYIYe`fm@aMuZy2uEkw+^@k~^AlP#GLgA(ZMwP_}CRRz1!IB;=XRP&s6< zGj5Tu?;NSC_aVQSBo}J4MVb3tE0igk*q~({$7nEI8`>00K**SxZHsaw+sL2{bWkez zDk{4X*s4+{b!R2CZ!i6YAOy&UY=}dRpFV$MDLKE@=UAl739yTKJ>|!jE)uZhSv&9c z%`4L6tuc3yfIIF=6A&9}5Ec~63Pjc98%Um$K`T;YWp;`)Y!v7S3$fM4xmjrT^N$c{ zBnQpu!P?Tc}72}JuZ^U^No01#@ z6OZgk{Ds#6n|Yjg&axbusIMv#VyNzlcN0-s>nef|onM?OQ<^c(Y^qGI-Ac?me~EG) z;7OClS-kC!O@2uZ`BX`t^&RKD+p9Hc&Q3QfRyt|@hx8$W_6*p8oMgg<1eh>uO2m&f z9BLQV>dMxaEVAYd-YCa7;hZr2!uZAD^;oo>%oka`Cb18?v}+)Y^Xj)8IVDI>9D`;= z%6dG)n7UBK*YKOirOLNhjc>|m; zyItW*bU-D(F+1m?2T*vLc~NyF=9AGm^>K&<67b=E>PpM_FQg5lM(C-bZ1DOkhE zV;IKOUkZmMC3$EgEE`Fq#7$%}Psn$--dH(t>c$ROTZZC>G^aw6RGB43Ni!3nH{2); z?9CKsR95&{Mz*L3X3HJCx}7d`F^iHa7ZpcG03M+{_(mWg%Jkwr7YDHEHr zqpLdE+gyj=Mm&8yn)cesQY$|)g{DInxtOG~EW19?iQ^}ZnBJyhE4?3&8xxw%p;B5U z>M_f#OdB1O+;Qa@9z)JynhRC8WZ4VJ#K$6t%^WQg#Y+Guke>lqwKJbKM20+hBIu(` zk(QFJHMQr7s&V<$qM{5i!G)7NeMe|YB=FhTLtacGy17u-tn991Fvc{eCO39@ zwH~z;r6GU&ab#7f+-l^jmhgPJ8m<$>jdM;jYDs)F5j?mowmcMc&y9^v(Lp&(XKNyw z`*5l$%e)~39wK8BRj4tLA2jLBZDoOgA!ulbw4C&ANaPwM>Jg^bnz3)&ZU9tL7b&A| zimT*|NJ)!i{9+KK)kjn)HpS+HQgU+@gO+)!$B~@h^)uYWPtlt~kRK`&-7Y#Zq8+PV z)yWL0+D)ffIy0dasCxEA9+wrmiXbaZ92N&xX4!@jp=1+~imW*c+^VNkbpT{hHG80l zkMXHf5`JtrezxG?$x!ab4NDIF(go!Hk>=^CS@8Es$vny=GaAbMR(hFn9)Y1 ze4gbwhsX~hvWH$mEb7}>e&TY8oi9Yt&V~Bejz3y317^VMI_#y1V@6gv#auIxu9V+k zMwqF9h-zw3OJys^gj3RS;+$&+N%ud~7lwgw8(PT~Cf5T+>I4})yr9LsswY0lJuIco zCaRr#0;^2PVt1~KMVQXMOvOr|qbqTeVB*aNX85<-Rc0cE{fTNK^QX!2UjXPH-VyI9QH z{9wRn633nw9%JnB7B4Q%q;tWW00YbTH z5)h>sLhEQQq-nYu_u!fc0++#sZ?HyL= z73Cf7Pt`$I7J^-j>IF#>iUp1JG0(d8{XkC1)J#pI@ZLo2HJEYYtRl5&O2nYf^emN% zOtLb-%?L?b;bsmLkedP*Wi(~V{{UIcxn(So;!8mk{GEZap8o*pkDMrGsY5Y2TS2jt z1mu$n1?0CAFHdm-W!AlgV&AfN-UsBOO&YX*Jf{=NM3IOQ4N1~$!HJvdROzV9=auSZ z(C9L9Pq=>B961W$-Db@Yl=3q7efR$Wt(G19y)QY!qb^s69y#{|L$oyb-Yczdh>c{o zZc4TqHL+4wZDNR7%~+tD!;v}}=4MA`XA~{~+JRZbnX+e;lJVasEJ}OC$KMj&WEv78 z5kgWV#2ZdK62zktxW*iMlLFDj_tliWge5*JBp|$|J4RMe>Bym2EaVYQX(R`f+-i_! zlxG750JGN*ty-ZYE5D_y79>T{{WARZRQbx5BC3Mr%)+rM!PtgLHa6WJ;6u%e+cb0HvQO!(wlcf5 zwX7qxtaOLQpg@O43C9NxBsHWcb#2NIy__lk0Fot4MA|yVwn^w#uY{3KpC&wULId)Q z)e%R`=E}W?$2!f5C&HG=iX%BDH;tu^_FUX5)kL!+ej*9fUxrn!7?O@S$DXqXDuh%T zW3vMJuQE;h69v7)UGlPw`l<3wjJ(>FLrVloVP?+kt2S1WmMR@f>Z#(dqB}Rs&O;OK z6yuCCXdYSLkA2B⁡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®bRa+qB-04B@F~}n6 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¬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

    R#OR54wM^e^&Lu&-GYv{Y!!R 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

    iCGyJ^G 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 *{sjmWybGI{zbsdSB(T2)>_7DhWSg}9Dx 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 T|Z6CSeRgY3%C{o3Z z)-l$vzj$K~(#;r82Q@I{Rf<3ArpoQF`Qbm-AQuhSXClP>?U4>}iYH4?=k&v)&iM+m z%{i3vQrCQ^OwNSM%>8eJu)r=v((|d6hKe6SNnWe70PJnJ=Y88qeU29VB11Gb+VB@K z=(*=^r@HKMx!NLGirlwJ;DmE&d<9C(gYnNlGF7sYn)bh^#d&awalanv=-8Q&IkjN4<#tg zja@yoC5$R(3M=PgA*O%m^EKsxz-hw{LV@g~%rT8zO5G4Bb9nTqz*?Pw_14mGHbs}^ zyTGz~&a<2#doKm)x0D!8IWR#gHP*0^f|~|YSZkr-@_=P<`+CT6WTN{`C2YpRTy9dKbT>T~3!|&gK+!J(u^|LIdTb`=0)Jp9=~>eje+?e} z$dwo-!1uE0?aTx8ED~`kH2nRE06CJ@lgF^0mX34kl+5JVa*!X!D->sQ;>K81%cDR_ z@9IwsroY{P-Y3bPTYHOM&QvAZiEDj^jqIpph;2&a7~*CU|6WnPhKQx(kaP~ZdVOA8 zG6(?&TH#{-e`);aa%3FD>4K&5d+1mGoBv6S&d;ilY#H>k)rparaP4uv{AkX4-TX3{ zFMN#yS+Z6#mV{7EA&iEnDov|`JBOoo64HE=$>Ce_5-@$gD22#p!;)VV%9xE4P@f%m zD#Vj#NEX=8@I0cpRYAPv*n%0x9SLBRFWY8G74It5myI5pOMM|&($o{HK_o~_u*%S_ zH@?uQ`#XYr9c=kfh!)1V;aQ1D)gGBidawBfU0S1#FOkyO`G&4QiH-Op6kkc*YOFTC z&@7fti=I_0T|^PHtn6WQ&}*GY9mh?}#g=oCp?DEhE%8D6R_i5a`V|Y0S*W_BKw(}h z%*Smd<%B%dAHXiV6<1%F+w}|%g~QKxBI>+%crBN->59gIUt&3k+M^S=)_>)YQ@;I37ZYid9_bSUuPjTB;F3X$ZHwP)A47#Vw1jmcMya%efh7!jDId^wuuYlZ6G$Q4torv&h3MbZ;M z5hn&)9qo(#YGdjXuU1{&po<=zD>+U6CMzAxp6F3EZ({kuadj>#KjpI_!nUda`{;&X zyqRD_*f(hLAulwemtulvT%PufqQ%mFZj`))^7+lB2CksxVC?JG&}KdFX^u7*?sFp3 zWGym2d&MHSYT%5eL{|Ce%&Cm8^Kph)PJup3(o=9|EDHYDgx_yB~l~hhzyC$J>Ch zwwx$y;~iuxb?!u_8c0Nuljmrm9fpAFoPOkIqW2=XvIDM6tc0k}uaQ3rg0s*~YSm-o zL=q;SxD|c9V1drJBVRRp3j4?!o=aJuH3l3g&dH7x>7PEQ*Yu%tX;UDjJtOvgQgoz9 zQAAoh!r?f`F(o<6eO~n}nRXP`*F7PZCfL>BY0VY!r~%(=}ROxUn%KxsJo17SZcz zu{+)P_b=NXsUg%;oPHK4NG-}tDQ0ajIUUKK36mPADo(%dhLSy;Ghf7}k-lp3;^GjD z@mM+&^%)t2N1~O+Gwci(6l5T)Gs!igwTs14?2NJqQMT}RenM2LRnZG<8~R^K^v?PG zi2Jk5lXm!1eif!SEysgKF7T!V2?M3D-|;zOpsVnZ0TTb9r-6TY4M>uXg-^LVt@Mxm zjT2SSj`4;1ZqO(BaE_GzlZ)J(N>q-$=?R5UF_?7&)WVP0Er4A0zdE?xeyK!J{DtzS z@ZWw+vJa@7^lySr3kh*v`2vsTd02Lp#!1_9){n1x#I55{sj&@uQzwY^?C^b`uAkBt z^3~k0<~en>H@#|5(Skf3yI47RVaJRpQ|_;v05!XbNDhkfYft@)_34lY6^A2!a zn+0g5-|*Blk#Y7lP;=GS8W^lOC$)hD1bJ}r3R%q^5*<+BW%1@}UN7X4RqarWonaWq zSoYO(ez!Burif+fsqq3Vye+B#7M)^a7a%4ic&-wQt)9`ES=xE`Fla8Z=l%Ah?>B;? zXmH#~B`)}gPi4*Kc8H|xArh|jfeWLC3cmh6?|Ep1ZvO75U4F;{>z|f9@>!y?4M=*U z{`#iz#o=FvxoygC+3p?+wyJHSsbbNHrLrX%)KvI!ln^zDBvsii z{#2ur%VqT2y1DfUb(cHyI-jJ+-t`Z=6l+S`H^x@?vE}G3*mPtgXN3M?rbTx4AvpMPaLks9N!$w$vk+*kgfEq-amL{|)HRhhEr zm56jk2WF&VYgs(Al_j2<>`?H$ofPX5ajZl zeoV2#`lEi=VV%pXI@eick_-E)si|`DxulRoB|vMR6hU@-gEjo2OE$-yv}gf!^cVh| zj#1R5YinxIv^^_fZ4_Rb+SL?w`~w-loTkdnqV4q5fu$=*avPXutde8>^OfpAk5z-^e3yp|?I69IqGRz^4kzyBYjL+2X~NxuHS3s}j}!Aj|KZrk zg|QBUL`%NMQQxzEE#AEZIRa(qS7j(-Gm5a$Njxz_-&mer&ch#W^RF)&=n(B3W@_j= zuaZVep>`d5;%$~lM{%r4wCx5(sf$@gKgQ|SP4>L|T#GXwl4B*b3ovT_iOIr|XJ^S0 zwUO}(4<+^l_-2v`5SZ0`Ksk+r2DDl~g#tb7N1l8=lOj+N=&@{1#-}46&0sp&p;e~u z9)h@%&BXDP&~~}FWbwVmOIQ~F!xl`WNh--WA2M(}r!p=Ef>D+C}% z&b$P&I~doR&{p5SBb)W{DJh1|N#!9r|5px=rso+8e@obT0fpnA<;U4#l0N0Xo&RvU zP?XHwM*d0sebwFmoA|G3V5&1k=dt{k6IJ z{C^;OmCaqrXjL2r=IPB{{Xe*1{GVknWW)v^@lqLo`_M6#^!?#R?nV87INyTXv=;05 zJ$}0)JPldD+_OB~!}{v~hqHX-chIi+)-Pcb$o%Dca_HZB;ML?}PT+~z|2~KZ=RdFD zrJ>XG+qS>DKb3*}59@h-*7D|iAb3Ud>}%`l=DT~pwcvVeLW*a?#{BkuXu|l%CwG&L zg|>_6zqqf}uiTv8I;TYb<4E~%eYE)Mch8##Xxq2HW59>yD)?~zrmg2c93uMjH$VQv zq5luZ<*(!e0&i*K=sxziGlmo!=H}+c>6WjAe_{*KZ z2Q}<(^Ly`qj5q$VLvJhJG0eW-XMGWAeG=I+Y_&e+gqt@anR3E@p!~V$%hF=cKc`!U zUu#~C3}p`oYow^4&w)WQdLx8UjEhpW6|?P#AA&!zkE~?RQ4#{-NFvc0R+@LZ=fi z1rCuot+|##kpM$T0NV<3=Ijtcl3?AV$~eea?8f0GO~Sq4WX?erO$}f^5+h#v>w28| zQrh!4l?$*^#*JKk;p9 z9(C@i)GHd%CNO9*=uzubggCumX10^bC{?a8)Ge+swJ}DzudL@I+jr^lRUXPOP zLX)ix$KOps8f_3QT6!FY%~ECCuHvIDQ$u7Cf?HT)24)Dpg^5ubNv!0>ZmDIqXXW`? z1*en-pj?OT5qOR~aoDkeqoGmKC6hV&LUd{eY7S*f@Yv1HSdg6YTbdoR9m)H+pS1C- z1!k@sE26A?Bu{-F(=3V{*xUGZ=tP^?J!qioKMwA^&3_8{?%juZX!|$QdG=_BS60s{ET(@46#$>f#Ecc!~&q!Q9@+i^7q z4n>g$qW7SNs9+grUGfU*y>VsroEaqK*(XOX0o)d}1>j3%gfn>=y-5HIdzE0id6uNJCYJ;Cpp);OtpL~sWw=1e>7z74dUr68XCOWomjmFM?iREq zp=lKrY|q$?l0wf7*i6HXYGjh1u<aAdjx84#i;-ui)JhwwrW5_4m zh$IJMkju}WXz;dr|48AzAU8$ARNj-z4A>>Q#RD#+3oDe>?Pl4o>_&25UWOgv8%t5x zi8)3tL{T}w=U&sjbY2e-xLn!~H@-fFO#y8U z18tRq*^dd~jEAX0i*EwT?x()2EM$m8P2B9_9lsv!gB($Mxu&sOSvpSuIjZu$@X5=z z#ACr{EI3F}r%V!Pdxt6<(c4+)6Q79*NLxWZ$lep6#;VD@rP_GW2UVMw#>KYH85 z@-2vG=JfmB=>9xD@r?`CZ%E9GBIetHRcoD>+2yWpJZizD{{0qGp&dHwkENUxGaJ`> zZ62y%JCT?YfDRCsv_I?BC9aGOGHY#Nn%o=uJL%VWn1;T2cVtYguBQ?nP-rZ$5_4|9vgkr zVH?*zA?bFZgv9o@V>SX?2hFO@pE7)!X!1Ja@76imhP3hMcSjQ49-A3uLiwt~NwT!& z)V?k=Dv5tLWa}EYNpqBnz-LQtrw}P9P~Mf{D|AMtRB=;c-L6y0Ii2_?=w5hG>q(8g zvyR+|y>4}teXX}_HaaV?HHv4iq-s9f?HVsJ+a$%Pw)QiTg4Qan1jzl`y<)_+IW$an z;ydrl(pkVoU}M! zU6G(tEGC$LE)7yKeNAr@Cf^5=nRMA@{#^I-Yx~5886%rX;4bQ>f1CI=#dTy3OyB;y z$uB2^^`7J#(cHwl(84fnYCeS*gQ$3c%9X8H=j=OyY(sUy_|h69^q+4Jt#kR`x&^Xd zD8rdsV4^3KT5U}>u#Dk3&ZJH)+FEG`oIPiRf%pp!s9~R8`YB1r1I1~M2%w|_?aebw zT^tG&8$KNlksRL=i4G$A_G!oF5K zcPSahp@atYWR2H58=mA=q}I64@&V8!qNr+RfwCx&MR7b&VIBAZzY}?GjdR{S$YPf( zK^E1F0(iFDyubjo@wud%~XDjJnh=~bJ#A_^ai->tLJSs3@c=(d2 zU2t6NXg1{R$<1uV!BmGwvyeu9DB5~(acK4tgPXu>nt9$4i5P|GXt(SNLGD%_buIyl z0R2Lws?{gs+AOZ?N8fs{Wwd1UidQvW%f`hW6jyo*5)&y#^J=b^al>KH#JvQ0HLQ$` zJWC=ZnchRZCRjeq?NMnTU^%yWCzv>AAg#bG$I37Ok;6?XOw|QYQk@+tWW=W8hMP}Q zb!(euPoxfIk9~2c6W6f#elSR1ku&#$0MD^4h@MVyXTVDA3((3nwsoT}VvlR!Zz;HD zx}71R>3HWvxfE9^Vm6Pm&WQrPj<_&YZ*h+gLXZHCj;Ydkh!5QUHd8^y6&BrTJPWBM zp8B>QjIq}S>uwoc$ zAzi6p#*X&Mh=yD`?bEP3+o<_9y+qaOebr-M4@UnBM;1>XXkqn=Eun9~)$u>3ulTAh`#!V*q8U%2bW6FN?es@2hIPeE$+^%Jrz`tv>~Tgm#F>^ z$3r6s%OSkF#{?Y6xg_N(o2a9M_*wBqT^y6h8;t zSLdiSf6e!B!Tg8wy6sA)KR}Q@nmq9xFh+sG!RfM*86d$oBzgQ0xzy(a_g5 zlGi|aO3u^2n>qc{YB75NmhM8rHtU<@AL;=*u^J{U$A?8gcl9Bew|nQmZd1{+x)G`2 zM7F}-wa)<#TnvT7LbfB**B;5pyI%AG4LPE!4EF|QNj?J7F&L_dhj*-JUU;XtM%bya z5wfV)>qddTrr+r;>}c$pB0P;|E)A%*XfzOi+B!u^8&?5HF=3j+otPGZLaA-ZzeCt!XqW3_k2OOv`*QYj+}(gk?72H;fM? z3SXhKIcgg$oV=mq<5!|90<@ntvW`}THrERrX8f}8}U0v`nyAB?%IiqAJ zp8c_p^6ey&nfhN!9KWAw1LSdmVMV&bfgBek_l$jd(18e=JaAqwVen06|6TtKvZ{#itd9Ba2nbw}KCIFoX(vNrsXYnEl zyuOPG>8NCa6(7EPj-1(B79`|A#0XmPRtXIy==3MhE0YptDt!sQDGGLi31DNL&<-(N zo}o|X3%AV8Gdw#vqFFdAU!_w*i9h0s9a@bnYZHt zIRA=SV5%bggi*5YAgPk#^0>X|^^Ax@FdAIp-q)8l>?lzVu#Iz5Szj zxv*E761VbBpHi6fg|`Ddxvc3x(qk)jCRWV!srRsxgoFWf)_gCOS8hOy2VQRp@{Xp3 za_x^I*txgCf<~+esKV^8eUJNyGW+__7mY4aiI19IEDxAq5S^1 z^ofvl(>i+bI`?+ZV94{iLsa~Le6IPN$JjVW!;8NSbp^7MGOzx_aXkga(GWfZ#!{{8 zbJ{5fZyvmVh~X3oVnHAJ+jUBYEVLF#$N+5Wju;c|oy*ODj&=dMSXRTEt_3M$zj{Bn zFW(ebn)AW>o^+)PF>Y*h9>pI6ncpU{j#U4sF3{KOTb06-#o+ z>IxAl4xQTq!6pTRU18%E*$?7mADQgt3y(ILs%3&E4=!VLi(bJDLA`>^;vSeIphiiJmsOTAtSk z7qf@eE5vb2_2~cl4`-wr&Q2;Xs3^9}rCr_5^~jEwbpncx(B@`tciU>w5=~@^%i$Wg z!kI>q>QmA}b!7d|imj4w`{d^aa^!~RwduVc0rnSp8P-(|8-eEu>Qf}ub%hi}y2;ZNhQNjq^^uWXxf`Acf$ zM~jz{G8fT1xnO_BRGsLcOY_xCf@<$5Wdy?Xvlkp+%)({lwd%A>IG#+s8EkOCFJj}M z2Lpj{b+I?Kn!Mx%GLaQ$xVe$UN1l89{3DHQpgNqZs$%=8g z?Dcx4^Xx=}x?8w*@m5u7h5&xuj}t!ERS?Y!O8pchNI!+Est#7^nX#BQ;VsYSf_sbm zC9H_aNdXTW)hpV}p;?Xz2?55bpW98m>-6Pq#3r4FA+2k=A`OQ;tg=}AuIQ!LbK&jB zXFdS)9NSYzrDrhqgpblyx%rhy{qQ%iN_*j%(YV{pm&(2G)xxDi6!&*i6(3J4HOETH z&2^@Zv|o@d2_2$PbPw*ZA%0ZDA@8J_%(O}CkO`PBN_(TtfeTq!uxBhn_mRFiCrw-5 z(G%eC?g)Zh(5yVGuq^@!?!Hy#lYYm>@zJJS_=0DkXD8k&s3x{K-pj}4J~u%AsF5_0VI` zr)N{Trk{q9O~gOtKb&fFX(FN7IBEZSY^_|4s~x2)D1Km3$Ewt??5zf?t*@-wBgUMh zrmNVC*90$-Ng?mEs2q{31ds9HRsIdAzH{5``b?7#67dRAGD>dI7)_4y_%990Ez9#x zg1lj$lUax#cTC6s6)s;Ezjv-&IW)TU=<1e50iaR{d_eJs zGP8o^kI{!9d%B92&uuSE6o;H1S#qCw$3&)&v}2trbUme0(KJ<|A2`%(l}fqJngI3* zdym$V=A&U%6-lY+X4CTZ*%l;z%$V_|J$J2Vmi1u=1Vg8aVQ{u6!z7D6e_%igi3j=p z{fQ>6SzFS-dfD26_7H1U6QPXffE@Qqb32{-!2r*O-gpPJ^DDSY&)Z>C^0`b7(u}EK z=3>f=TyAiFxDB%gq}W; zX>Z^JgkXy?;cZ9}Hd9#NN+HyUIP(}ZLZSP0m8XZla?j>QFhi7jLL_R57xd`>{xae(~%*#|!r+lQUheQENS3;(Dyi{zr z&CkDVcM}ck`p2nfj6H-I!F6>O(`FTMRV;^@@$xI5{1$bJgw@mr3ap1GDckR*`F@}3hTd`6&Sh~U4A;!4hn+nkzXVmu*2jD= zxN2E~tULx*-z{`5Q(WmkP(6TF{Q2m9(!=v()ACA=1jD;{-(ZC;6gqJ}yMZx65;5hn zVxv0ybNT5F92XF(`^!m3;E^~8!l?wv@y_Sad3E!urMMQ9mF_frx~16v*3vf*XeKQ3 zDNDrzJV?0agt0j7QRAzI%PNzFqR5_>!9(|UXp=onBU+X) zH|-({awMw&KOWawZdwa$fnV*r*awVYbcG6vH#F^xL?{fN6q$e9gVv-fe5)P=rGHa-oI1M?6n5_L#`?~D~~R^x)x44UGh1`w5Q6{Y`%og+aJ{eb^qSh@vkLzDOXImgkako)2X&`~ zhEcp2$t2HMkqBJ%dAkxmvfMPG(0Vtf;k_dkWi{@dAt;^I9+*rx)s=@zgx-GfCly%y%5|T(W6GxFb7diHy+vOdZ z(LBA&qM3_LPejE0p^0)-M{i})C<|$-8W!Csq#d`{eW=3fyS(P!a`+a}2_BW|#2i0U zj?1c91^%k%^3;g)E~NxBohWUb01TDU)gJt|>=j}ZT91aZ2AzgJB18#t>MkT~N-2!J zBVblzpI#2z{!C*cfU6u@VnxGvOWUTPlfklwDx0YzYOAiQNN!M2iW#IZr>wXXVD$w> zewxVkU6b8Ytxq)njcz_15PO~a**Xn50#-}jkmppIJJ~Dbi!}uk3oPpL-FXNkt}Ts( zq?OcG8|r;w!_#DW!xCSdJvd)z>8Q50c<3AU1oSf7Gg>dHjT5xXHJ@v%VYv0nY&DcQ zR)7wTw`2I6rZAmLOgUL83LAuGH{13;H4|wIKY!-YL;bFIRT4R=N4Ust;wz(3?jZmw@}_!^W|+jt?A*;;MqwdeO{1z z$+m;h4Z_Fa-~?2rTUzcon)1P$W3!Z3Jk6}dOWp|4C|s!NdQYgjlIilesh|v_Z1hLa zTq|&=cuCxh%O+$x;X_7(n5|~PySdd^SJ7Z@ z6lME%i7rQ6K;TkJZUn6}dfnO`3~8~b{V}rty#l^4@p_~vSOwm7h1q_i@x|8eQY zRIy`tY$&YJB?_?+>czNMtX1b!j_Fq^3Svr{y`E(wGEdcsE`exqe2GI6JLws$;9hLl zOjnF(F^>-Nc$*T7PTPgPbnPJRV*vFj^M6|Uv~P$BEQh_(Y*PMd@G;}f{N93G7&miQ zz{6gShVmaTX1*m?+dXDzE_`+}VQ2@ID=5T^DTQ@ZC0eUWwwbKg40&rddVA;V9}$s% z3S2ULapKcn$VVqBWodlRMO9DdpUc{)%pn6$86!qayCAHjweTw3c{Fpr!|J$HXA+r`Pq-Ty&L( z6@NZ2lpj>T983|iHl5>W;j$KT=(1t6gHQzg8|wJAw(=WIHYL9QyWz`C;%cKQJ!WAw z&^xW2Rr5*NtGGU3w@M>SYSE>X@--b7*FuR(a88q=dB$O7gt*~ckz`m?8Rn}pOxX39 zex841y(EBVdr*A@$&f6Gdex)L3C>_<@_O~_>M&e__RVFLVtm_yNJbV|c!`TRMC>5z z`dQ2IlCzvay^769cF*_6pR@bWu>)`lSUly7j%j7JQhgW&*4k9M4J=j@5Fil@<0Uwb z)2%Mgumy(KborJOih+EZXTh#)x-svVD)(=u1)7~eejAID-!8d6lW@x6djFWh!c}3(<(g! zr?7O3W8udxNo_&L9gRfIZ0KJ9v1Qc?Ihr(_-5>sUl#c~K0hgiz13+QMom6iwZu};} z)m9(S2ktr8kDbsX1>RzG`fiBMcUGf9U@QB#3Q%NgY@=)R$5Y99RI}$&J#~6eB-40v zw}(x*d_ITf{dS&5>^@I{9K8fEW1MsU^KaCQAXRiqsgQnWP0`@F@l}Q=OiPl7z}qnN z!N9@q=kcOEnzR1cmTPwppVoF!X%!MR!5y}kv-R&Oa_HqLr|IMi^mMLzLX&#^c=Rq( zsMPK4&V8(%)0eWf$vcj=((e031vQOzvS~x+h)N@$X4XqZib61lA)mma?V>v_2?j!P z1!AWMs$yFSk#aR>f3>9tbYtV;aSjV)v_mynaOkR}fmg;=M(QTj+$G&*nd*#XZonHB*8=e)0@n7psJS)Ad z8j!k1;l&yfE?R3+aC?>lX~ZxRU(`0gf84Qlvhd@#A}UB3z0Cw}+3j_!htVcPDPisd zz0JLBb#p4a-d$4{IU@rqfLa^&SC1$L$vC6 zGMrTH(D;6en_k)-^(#Up2^pLIRKSsCg#AzPk;5}ZLKd#pSh@wlk=`Ee`vE4p{3=$y z0^z9g4wWkR4j8h zean8wS}buh9f}xe*sUJ4QPZX9(u@ji6e#Rc{84#*CR1}*UY=Hh7&(kqq2Q1X$uXJE zHK?T)r9f)P12Eyn2sxF>*9ak{4Xtm;e~mBNgrDr`gTOT9p{Q~FqRx}{mK z;3w2Pek1nSJyaE&aS$sXzhI#J@N#VbGG>~xGXz!~s>`Wre6+_)SL%p5L$BWRMM!6N zB(h5BrpeI|L^q89Hcq^vX+`mM!2mgtl9mz)j#GcR*r01X-*DzQ%veG&+Gog{T!diX zBrZ(c&sF0MH5^}P^leCSgU93_Q+RoMsy)cFdm+_h``BQ6B!@ahvDAkUrU~-wt(J;( z{6w+@0yS+2jxfKR3_z81R{Ne>k#PEd1}@D!dm|mev(7Omawu$f2Xdi|wl%+w0aY0& zLw|Kw`;g)R*%eFKl<86PLxgW^(udr#(v>OvNQJE>v9u?YA(T$3K^%3u-#B(AWBo@t z*&jKa3u+E>{PDcZiMEVcQ0!^<+~oMiXH_DPdZm2ww-+r)Q}I~LB3?`U;vz?jIXpXi zv?n#K*rS(SC?k|Am3bc7%&dRnro^IS^MUq2Z7DGS7u#l1r*o_T<6J%^o-#9(8~#X2 zEY3%N>Gd%5_s6zWP1VB}8r;iZyHaH}Th(np+@4kn?9~2fX??;c;qhjNP`7%c3!h#RnY&rlN6P@z2<*CamQ8E?T#Gk#!F4AA-b9Z#`wgqPd3Q^~xA8lse zm2NA$>b0jSe$~L9+@fj? zUd!2EZL@#xixPL$-{mj1yD&!M^Sg{0o_CvF&TYBQn^KFieRTU&W%zWx&KWJ|b!U zbM#PWQUySHXZS%=_&QrUUvf2GwPOo$4!YWXT5j;9zWmTulpk@KNq-78OczPDeKgMd z(PhqdoOdSJbaeESOZKF0?NIN&q?lGC+~UcanXjAS%9{kb#S)E3ZHmA;%D)F4z)v*g zsCiykw7Zi3PduCY`3~(!OYAUPhP6`T%s(8C_7a1Sk4CN9aBB6>?=S&`wD#?4rOCXl zrylq}1a!6uh{josq3L=^`lmY;7$*r*!SFa$uAh%ub0$O6V8wl=21qx43Kwh_cgF(# z`m}05ds;*0yvs`c=a)C9zwwXSH+29m@#G_^hS(r_b@aP0&3B`OPXoXs3s=-Bobv`F z%;#QDpA6!&o9k^<2nw{FC+2Ad#Hn~Z-134taJR{Z=3sxUd*eh+arHe+Q_`CaZ>KUW z=F?$ANfP+6<~M-M+`qwaX1;eck`(n2Y=X5#REgLuh3eiw?E0P+Ns!B|QNxCgDgYjj zNvPx{*CSgjF>S0-m*XDQZBJoh7v@!JswizT-qTyamp#U2IO}9|Uc5q&`Y2dq< z6U3KXsQ7;Vx8y<CE{l3Sa<4*~sxK zk9E8&_kDyZlGz$EKu`=#sc`8ljWkO^J{?w$%Ygd$?1~&>D1ZFNft!X!4<@KFf-BaX z22W;$;9rE|YrUVx#W-G6J>Z`8^fX6j zlIaWbNVN=ONf)sB=xuWO2vW`zo(aPsJ-KZ^Lsmgc2lRh^W2ehb8p3Jq)lD~MgL*%$ z=J2WKY66~e3NEi_9Nt$94d3+hIA7+2;WnsAqPrFO_e8b{tZP{rHQbXiwj`+eV)<(4 z53|UdgPxNNxg5bP8ZOUgjiZ^SGLWy5gpF4Fb_SMwAJ!cEk>S8k#k;YriYtx{g*1#N z^+CbOKGJ8=&>O-1mAQpnJfFc(LJP)}#GR2DjC0siTB93~fTtOH-h+JH{Eon&iDn_d zl%Yw4)5t$MHQ%V3cb+tLKH{WN#^>`toLF1_WcwSV627>)s$bY@r>vlM;Btb}@`!2p zIOmh-_a?W#5xoNan)+gF&n9#-$!wG%mTYRx?VdLvbIsb@$zl^;;Y>hhod)wD-)RoR z7Rt5Zpc>;pQSH12b%BeMR*fU*z~+UE`4iWdyZR}Zne^XVuQiya{!85ZKJZq_hkoIc z(YqTnvWqMLonw;;)Z1LX(SI!4u$_5vrIp{DT!S#_S?K3ARjsMlQeqF+=SB6BbbY|% z#`1M0Tb(dSisYGfgcU#H)iH z9w{bY9{$5YvtWgdlx1GM=ls@`f-ccji$V=NySus0zv z4@YyE%q0{Gyq)yyo^4I#>EHl!md9u`17axSozp|+pLY%PIcY?`__<*?;VE)KP+d62 z{@EduZ=o>>Fdxy*Il9w5)(?G2(sHj`?kH6l(nlz_4c6`KN9)@3T)le`@x1;OvXisXVG+S3-bKqr2nhS%|i*3_Ih_b#PA0ZfBA1Q}FJ~4R!(Y z)Ln|$NwKWLPlFT{)$8Fl)83DLNn56-YN`esVSfsqc_zt=ewqsKMb<<#`I+V}oK-Jz zyqF>#^Pz(QH~A(3))>}`GM+R22r!!{?ar8=@N0?uH+u&2AFA~+2yRQ+1+?yDN3575 zA@yqQX>*TYM`a<`+8}v0ML^>5vW9xRdF%m2mHj#88(Im;u1;%Cl%BJ153kFKY8B39 z=RtsSs2N3+cGva91vRoxAA7olK(ZzI_VxGcFO>^RZhPmgpw70fP32(uQ4O3DjLEy|C7F@Vd`(g`>1KiG^$*VVx%% z73Z^9TcHN6OFQL};2SS#Ea)7Wg%_iQzuhJis&_@!`+aw4w`2m!MW=G?sF64&GHaj2 z1OMzTu;CQu!1xiLdqQ{C+x#nczNzRe{xKNZaWJlI@pCIos2tlnPN>FlLLSROKgi0k(u{WIM_OYa;zN0z2x4o4*dy+)$Sy6*HGZnm+lju)B_W^%nXk`QjW?=LKAze^@$ln4 z_1bAv;f>z!5r~QQ>`cc<3iNHeQ`S>BM%7kT?|8ogh42>Pg0E_nqsq~+9YB=&3OJ$0 z)hrl9T=PYB=Ys78vZEii25aAM-^Z3*T`T*wjwgk1gSc3?0ZXfHFKksSLrp^T`Pn+l zX5P|3>`fU5V38B!$id-Pg?5YRs`*f9f;XDUH0B@UsH<0aEaHVLW80y2aCNqne2&T+ z?w9OOXR_(Bw&IZfVB21Lu% zBBc(Mtig#md{Pw0HB3YcCAK9AM*Kg5uOb`XB8r7n=sMMz;>&n_Zz~A3-C+{&pnz&q zm88@eWQv1EikI`@m(gQlFWMc3Aubav)6ea9XQ!^ggN(C&)(LiXN`^gQZQSfyqEzl{T{>vBsy;uQ(d z((<9?Mu3lHo6*0%S^2x{xa)r^s_cQ`N?25gz@mwL+}2{b2qL zLvj8O?n{&>xc>36dHm!sBhxP`aVG77x}b{m(s{eSQf;aD(I}l zmm+fHV~Z!z=B#sNK)f%>lEdv|mF~LITFZn^!24N8)F4jx9MK{9elQg{Z;crRD}3{P z@YesuP!FZD5*vM=LzGVA5l5xRU@Dw-+f*h{e)D0iDJi@Zb3=pd^MvLVSITe1~-JeNjTw`zeeo2wYuwIyZyh_VMEG4Nej@0LQ zgmnIuV$X!D9y4A4N}JFZqc2_=4SmZLw_Bwr1dC>uJWfLyUpk zLMG`fKPHNCMW_M{=UGaU+bk<_s4hP0)m|*~C6(EX#@UXhibg%iVnNJM$(BLpp(?%> zAMt8b=Oz@U*18MeUOJL2`N9iv?%EqOu(NwfZ}MNkTSgupyGKy}GFo3sDQLdaVD)(P zGmcB~314nLViIhu1!dB<_|NMmPAl#C#v3`cZMY*}K=OEub4?~Ae)r9R)7N9F)3a+? z)(?IZDbM)iIMU@K<(MIaA$1dcyQcM;_4Z0%SRz`CzUUqy>l?#fy{qG|;P8uj@FBaNC4A~JCJ?GPIh@yQ z|4b}Z((EJn%{}#nKf>pvcvW($o|F0e1@C+jsZFlJ3EQgq{Gc6+L-&yHO3sR)w4F$m zWiQ?0e7?u7sOz_ATLst?KJU`$0*i+KIJSltMw#TIja}?Ixa@fJlXiLi#^IKd8Ky#X zv1%gf<cw;^!h6`K@3rcKoU4mJ0EWx`GUR`^7>o?Z zLYxjU$fUJ9Yx4u*xr0*!uh9kRWU>X`vih!8*MRz$ySKEvV-MIr75n$migjDCLZ*g1 zVX<->30F}tVU&}gSX*x?=1SzCeLGZB0q~D?uaEFXj`+P zLlO>14kjK@*P&YOkJl=32TN(UqR#d7gM0^-IUpnybdc#(9l9S41B-FDyhe2uFer@tq2-Sa0kV#u;=Ms+zQgS8v$L}QQOZ*|Y@s!yv z3BVnn0`_7VeGssxKjZXzgxJ`&;`$Yw_0#EoyCPPXt9}O91U$ICt58v>cM{cV6sQt* z+WItmD3V_^7f2xjsI5Aw6v6vE+1@YFAUv6V0`N1 z&}rM&Ij;`N_~+>spQ0wSQZ-EXm69ik1D>SfW2vbm1-it&0~8F-9s}%-{|Hm23TEYQTM zX2&R)`I4BN)(m|MKI882uk`m%b8Xm$myeH#XdGgqF&-(-Xm7_UX(84q z-RZSR9kBLD;~qr@&cn=Ihh8@td2PRX`tm2S+iCeI?JukzQjoj(u3+{WxuK|MO!@nF zFt7q0@y8)wMSNU~5qh3VFZy^ob*E*ko5?{hJ?wmy?mt5nX)ci=(jn?p?phH6?UnWJ z83s)SbaUT&q1ECnNQ#St8}aoCs@y1oJ$ENzq(ksc6TeCO?1IQnp-5Mu+d(4{;5~2Y z3&KfzosWXlzDgT1;sD8X_^Ha4bULAYMXd0R3qtNSSJPibSWsXBkf<{4f*^%P?PvjV zKULGV1^hhK-aZ^`9v^lflfF}A>M)@fA#8SB1J`szb4lrptb3i=-grui?9p-2oAnin zdABhWpSI3C^|e!xGH7V{yp7g(&D-U&TN53z=u-DI5`Y-^TAOsQiKpWzlrRMJXh&Lb@?EW!=YwCXD7;)Qe#e3}g;`^w z75CmNy%;qq`yB5mz2J!HyQ@K;5wP?Z|(l4+n zNyt1vmB-k*mvS>sr>&8&tILgb{FAA87XRhgM0XefRPnM-#~QgzbCme<+UGsU9Hblc zBtO$lXlFotBh0ZVGkFIugB8*%vQjob|5#=0kx#S$LGiJsP{eq%y9JL(Ql-c)D+c&{ zZIwNQhkjT4-nU(NW~mTm|?RENZLn ztps1-sq@(5-M*C2+X%lZB1j}u^R0<}ZOhD>pxRhb!N4|t) z!JfvSmsO8t3&FUFYSh0vMO!FA_Ku3<#Eo|-wnA2;tjmZL`Z;r7!z#BE`53}RYdRfO z!}5$|DN~~swi2(N3kdsA05@wCGDR-Za@5S7hH-K+bBr-_z=SX#KsqZ4LEfGLm*Gb6uYmPHMHW~sjgkbqQAC85 z{Ra!dH#wf3gjQWL3uC1>CFGx4U~~4n)fJ*?WvcL8G@irDwcV*1FbzbW&dt(Cpu;oYr>+ysN690%422XYkO5y9J6pE@oO_WH6 z3TC$p|GC2M{x_rg=sg*91g3j34*0e&z5~P_@=VV*APoZ90T6%TnbZ;|);E4=KAU+j z{?Ie0uBs9b(uSZQLyLv=X`VZ*H>48vjK}0ECWB-RD@D~AvU$<*Q%Ni*I>vNNZM@~> zFMBhu@N-4o86q=p+}$Y=K&(C+{rQsQfctfHiLFzrox}D^Z~GvP30{rBF$n>W{a5Qc+~FM6HT5_GsZ$50=^#mI5bdI)2*HAl zhlPazZ}vol9N=+|K}_Chnsus%IqcFB zf5so86to9|=d2?{+lC_S-{t^T?0!`S6>qNDV)=TRbgPG81)l33;*M?HQVG3D#d7#G0M z59c|s5mWF4i!S-BXQ@lbGRIX2^v9s$OtxWKFmQ3n+Se97^>p{mDhqNOwvCo6FESfd77d6<&Cjt8= zqOKy$g?$vs{EE`}(H@_$%X(-f|;!QZUH$~n5!#E4!A&KND1w-!WGC2zizzUQo(78|fNRWRaH8~fA zS{^ZW{q4Ke$GvhdS>^6&!IujXae^hvb1FPAF zn={%XERqS zp5d>UfI6Ei+II~J=}C~s*S{om36WhDBDk@sFG$$A8{NRC%M;z^I;WlecvzA=_*j)G z(z*7RZuOpds<;bk9z8s>!%NDOm(JJRG^vxAn^2cqHM7IAQ^C$`W0VF_*09^)!_uli zoZiDW_Bh<@#^wmUcMK(gB`)TGk*tW{j-8J)1cnNGdKZkJ8oHT1>r?}%TmVm;I_P4% zr^XuA2JeZ`M|+Zvts+sU+p1uCyh@@(UJV0!r1mWLHe;mhU7(-}`G%jR8b@W3*7he# zspVCxH%8%+;&jdVZ=*MFE35|KLauXF<1Z*{uO}e}YM8}xN{Mm@vytA#aj7C^$q_&9 ze>joRD}1f(--EABx`q})c)}UqOI1Cm)*)c`Eq^yYgu(8#k*)i(b2jmPstzr`iyo|m z)Yc=(*8E%rtI4*1yh-hko)@7DoE#-To+Nwc zys_CybAqhfWsliWml71QEb($@ALOCbU%S;#2euzVUTaVkw`%-`u!Y^gGc^tUvh zEu%I1$v@5)HDwyJ%-QwBGp7rUqDr?E-FJ%REvx&uWP@N}r!yy^Awo(>rphSis)&>zT?IC#QYc8a~VVYJG4RSwItM z`@w76>qqrRsSahNuMtBpL$SjI;X-G+NfSB)ya-L5p^#zYB2ud4wtSAmU_Zv4sG+S; zuSbw8&K1Ce`RPzr?XLn$IxPgU?wQrKfvEs>$y3OH~%|I=MT?S37?<*Gf&62M-4+gBUkiCAUL{ zggkl<2A@G)0W(?&;KmHLyOTDvG!do@>EF4JOk6FIV1jkhk&zFOsTeC-dif%S*7wUg z{_wATbB&_x?Z%YB?S+yf^Tr1%$1<778n|pB;u837wy1t%g^e{i{N0cmzwyS6ASw_TZbU-~J6R!0ww0q9HO#SQ=Us)E+tG{-a z?bdB;mL;j;8<1FP4y%ney9AMrDjM;6gU<|BclNazclgO$XuR7|c|EKQ)sHeUYSb@K zaq{INKPF0J>#C+fMN$pgc;-Q^BKk-i+G1BGQ&OfW$|6RrOR+dew4+Erq)uCF@}IYU|v; zbV>01ouw9ycX>QnQ9qJz))TLK$r~{J5692d?7bm2xm$rL(n^<8nQ1GWp*T|3d9Eu| zO3}j$f*Q32w`ZhRr;nx;WQxLu*)0ZfwR)cL=NvqPpY#bl9SOzy(ZR$Ds)V0LeIA>t zUcuv`YXBN9pme;x$G3S>9-rCFVzRORX~AUk@iSbyi}3qGM?yExSMG9LslX|oH5zaa zcYOasPtV|dAK#zx=*%k(-wZ<|o)@@$zS{4ACA#2w-yC9q33;j+mqq%;6C@ER`_VY9 z4JWXPTx2v&mUN0+o5vD8YhcibJVjNGbYq@$I6XS8W*eM<-dZgbY5OdTQ>r96PiX9a zJIygW=F9LEHNAYtwy%|jx7_HS`I5VuOVAeGw5+y67LWrq91dgO6^!Ev2B#dHLtg7G z=Ive~D46JC5denepr4y*&d2_Xk{1d5%F zgvy6TB z@T=z{NX$^I$Y_2x`=UCB4C-Wnn_0nS6-&L2%1e)jIvk8fOO8jlR!vM#?K3}9{zS5Y zQ^xckX5Cdg*cY9+eIGSIa1yL@=^SSoZ1<7vkwxNDPN^AG_jo&x1PR!!moch3>c7QD z=2>j@KiZQY%5KFmHcy1u-N;|5tK@5Ol`h>od0GzgkgWphz1}uEZnb$yZZd7^i9RjQ zL*tB5dS%x0Nu)DjtA8v#`{cw&UvT279A5w`?UHHkA#C-~SSVG7Jt%1VUp@%}zam#Q zOzO4#R+*D*kxn%ev^1^RtmG)6*islS(1F-&gU@VaML1d;R`)|A^f#AUZNs@fTpxb%G%Q=Gi4I0^4L^+v#dKQr9B`uv_4P!*dW zF5i94K=Vv>P{(oaMuU`4$wHxK55A=8L*NP3jhZ50V4qHGps}_9RDII@D?T@v{D+To zvqkch?R&iP`23Z`e_iGyr6L=kGiQV*7yUZhI>!Jbg^+^5!Ko3&K^T=968I z`3vD)fyFBV6vH1|n@y{RSO-=SQVf~PP4X&qV^Mn;uVj9dHmI#SeJcDZkkgHrs!(I= zSnM?d(K8X;(NMWukBFk2_Nx1jvPZ_bkpPPjLyPJLiTU7 z5f=?K8Xgu@2&J%hASH%BUv7s5@r>wzxv9Z+!{*Uq0p zOwdK&OUsa*DC563@#5@0q_c)z5_d}jabEbk$eKQlk-Xn)?|@d)Yxe<73(k`sOYmSTkZ&h~BD zluutrtv~mV1DzuP&kIJZo@+yNhfi)ES9op76ykn~tU#rO10HGPQ7_}v3GNizBhCop zjkiM;FHI6t%ymJ}kE(}0YUrg(M>1lQgG3CL_`ku` zBuL{vsRg@YVveJ-)ePs``JQju@@03%e<_oV&l1-53|093eQf6y3JKD*1SCM&Wc(qqZ|1Tr}WQ5tFwgyvue1V)y<#q_?Y*td-ypr*nyeYN(lLANNZ}zyC~xuV zj64i-hIBWl1cOfBN77I@s<9 z2dPHbe}CA|i>Wz;S&|~~d!PNoVSRRedl=6#l~R4XYh`8axxuwG6o&Phlk6_|EBDIc z?RC_5f8jr@e~Y9nFr^eb2*2mYTpa!%da_JlG7;69F} zl*}|&v(&o{L5uXFowe6+dkGz8i02&MA~F-{9S@5nGj)#0Z=s~5F2nu1yrM1ngSSDc zPIuqNtuehU8WRNhmQJT<)g$xA{$MBeHM3?=RGpWb&C04_2%+_+ezsxfetWViC5YSrQa*d`95LA}#qHzbruAzuk~AJBP} zs+mPH6W|#=NnO*ClXsB@4(8tjNB3nS9s>+w94*KFya}pw^+tr+TIVOri%uD(7hW@E zPKv+3$m7Gj8jsM3B#FFX__fRN9KL|UyrF2jisYL4K7yy?o**t|N+}()=5|W1=_a96 z50Dw=B$Ux8;EXpNI0|@0*q~PYjTBn`;Xs(%U6V&&dloG^}bOaQeAs{ z@fjhuam}yVRlJgcq;`*FghebE_S&~p_MW|>F=XC(Xc=;SF66$p#QrjHtnp!bN}bKY zp6V)G9l@%8??Bpl`>}Nb?6W&oF;qQ!NBKH%`|-m*qjhW4PCe@Tr(em7%GNG7zJDaR z#M&z}pY%KB)Fz7VWdOaNuvv&K{{=GIO$hS&LAWhR_b8-9J3f}7Akk%84s#zDc&uX5 z+QVcwb!fN^!c?FIhm+qb=Lj3r^lP;EjZ-h{STcnsclAx3PQlKs2LjBfFvVXqa%DgO zhYCErJwjLINh^~*>(#BHKlAQeDiB}f&ZSX*I2Z@;h*+atdG|ADP~n=!C}7A zZ0e^dzjSIC$(g2x4uX0p6dz!bOASU6F1k9ygZTA~u|AVW@w$|KZ6`td&j3^z zXn*q(w}g;frzTYFXgUf-sXC%#souq6&~B9eUbx_2?U$m&UDDd;A!` zz%xBCq4SFi7!CvjDW)?&H-76n#B1#=)i!5?^Se>W` z>IUA=Cql+Xckq;jNxG{c1DC=|C1tQ0+Q8Dr$>@76+Oz&960v3U;;V_ZF@AZN;!ctn zFZHza`0x$ba>jGyXA8bgSDRmi?F|}Hp&L#88#rK>Sdn0AY+m>)rT&fTK)btP3i

    5;P;_a|2ii*Hqmr)%C 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 literal 0 HcmV?d00001 From 2f888007498542cde99e04af7ea1e6f747a49740 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 20 Jun 2024 13:23:53 +0100 Subject: [PATCH 102/124] refactor(framework:skip) Append the doc string of `StateFactory` (#3648) --- src/py/flwr/server/superlink/state/state_factory.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/py/flwr/server/superlink/state/state_factory.py b/src/py/flwr/server/superlink/state/state_factory.py index 62a00d910828..51f5bf5e2ee2 100644 --- a/src/py/flwr/server/superlink/state/state_factory.py +++ b/src/py/flwr/server/superlink/state/state_factory.py @@ -26,7 +26,16 @@ class StateFactory: - """Factory class that creates State instances.""" + """Factory class that creates State instances. + + Parameters + ---------- + database : str + A string representing the path to the database file that will be opened. + Note that passing ':memory:' will open a connection to a database that is + in RAM, instead of on disk. For more information on special in-memory + databases, please refer to https://sqlite.org/inmemorydb.html. + """ def __init__(self, database: str) -> None: self.database = database From 0fc8e36f329bbc0413ee567ce63cbf26b191be55 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 20 Jun 2024 15:32:12 +0200 Subject: [PATCH 103/124] fix(framework:skip) Display correct folder upon flwr new (#3646) --- src/py/flwr/cli/new/new.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/cli/new/new.py b/src/py/flwr/cli/new/new.py index 9bbc016de1a8..94da99dce36e 100644 --- a/src/py/flwr/cli/new/new.py +++ b/src/py/flwr/cli/new/new.py @@ -190,7 +190,7 @@ def new( ) print( typer.style( - f" cd {project_name}\n" + " pip install -e .\n flwr run\n", + f" cd {package_name}\n" + " pip install -e .\n flwr run\n", fg=typer.colors.BRIGHT_CYAN, bold=True, ) From 6c91366f8fa367322cbfdcfd0de7c9303354a4f1 Mon Sep 17 00:00:00 2001 From: Robert Steiner Date: Thu, 20 Jun 2024 16:11:25 +0200 Subject: [PATCH 104/124] docs(framework:skip) Update flwr version in Docker docs (#3592) --- ...contributor-how-to-build-docker-images.rst | 8 +-- doc/source/how-to-run-flower-using-docker.rst | 53 +++++++++---------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/doc/source/contributor-how-to-build-docker-images.rst b/doc/source/contributor-how-to-build-docker-images.rst index 2efc739f54f0..4c178f439a07 100644 --- a/doc/source/contributor-how-to-build-docker-images.rst +++ b/doc/source/contributor-how-to-build-docker-images.rst @@ -65,7 +65,7 @@ Building the base image * - ``FLWR_VERSION`` - Version of Flower to be installed. - Yes - - ``1.8.0`` + - ``1.9.0`` * - ``FLWR_PACKAGE`` - The Flower package to be installed. - No @@ -73,14 +73,14 @@ Building the base image The following example creates a base Ubuntu/Alpine image with Python 3.11.0, pip 23.0.1, -setuptools 69.0.2 and Flower 1.8.0: +setuptools 69.0.2 and Flower 1.9.0: .. code-block:: bash $ cd src/docker/base/ $ docker build \ --build-arg PYTHON_VERSION=3.11.0 \ - --build-arg FLWR_VERSION=1.8.0 \ + --build-arg FLWR_VERSION=1.9.0 \ --build-arg PIP_VERSION=23.0.1 \ --build-arg SETUPTOOLS_VERSION=69.0.2 \ -t flwr_base:0.1.0 . @@ -106,7 +106,7 @@ Building the SuperLink/SuperNode or ServerApp image * - ``BASE_IMAGE`` - The Tag of the Flower base image. - Yes - - ``1.8.0-py3.10-ubuntu22.04`` + - ``1.9.0-py3.10-ubuntu22.04`` The following example creates a SuperLink/SuperNode or ServerApp image with the official Flower base image: diff --git a/doc/source/how-to-run-flower-using-docker.rst b/doc/source/how-to-run-flower-using-docker.rst index 54079968d417..7d9ec883960a 100644 --- a/doc/source/how-to-run-flower-using-docker.rst +++ b/doc/source/how-to-run-flower-using-docker.rst @@ -38,10 +38,10 @@ If you're looking to try out Flower, you can use the following command: .. code-block:: bash - $ docker run --rm -p 9091:9091 -p 9092:9092 flwr/superlink:1.8.0 --insecure + $ docker run --rm -p 9091:9091 -p 9092:9092 flwr/superlink:1.9.0 --insecure -The command pulls the Docker image with the tag ``1.8.0`` from Docker Hub. The tag specifies -the Flower version. In this case, Flower 1.8.0. The ``--rm`` flag tells Docker to remove the +The command pulls the Docker image with the tag ``1.9.0`` from Docker Hub. The tag specifies +the Flower version. In this case, Flower 1.9.0. The ``--rm`` flag tells Docker to remove the container after it exits. .. note:: @@ -66,7 +66,7 @@ You can use ``--help`` to view all available flags that the SuperLink supports: .. code-block:: bash - $ docker run --rm flwr/superlink:1.8.0 --help + $ docker run --rm flwr/superlink:1.9.0 --help Mounting a volume to store the state on the host system ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -88,7 +88,7 @@ container. Furthermore, we use the flag ``--database`` to specify the name of th $ mkdir state $ sudo chown -R 49999:49999 state $ docker run --rm \ - -p 9091:9091 -p 9092:9092 --volume ./state/:/app/state flwr/superlink:1.8.0 \ + -p 9091:9091 -p 9092:9092 --volume ./state/:/app/state flwr/superlink:1.9.0 \ --insecure \ --database state.db @@ -118,7 +118,7 @@ with the ``--ssl-ca-certfile``, ``--ssl-certfile`` and ``--ssl-keyfile`` flag. $ docker run --rm \ -p 9091:9091 -p 9092:9092 \ - --volume ./certificates/:/app/certificates/:ro flwr/superlink:nightly \ + --volume ./certificates/:/app/certificates/:ro flwr/superlink:1.9.0 \ --ssl-ca-certfile certificates/ca.crt \ --ssl-certfile certificates/server.pem \ --ssl-keyfile certificates/server.key @@ -136,14 +136,6 @@ Flower SuperNode The SuperNode Docker image comes with a pre-installed version of Flower and serves as a base for building your own SuperNode image. -.. important:: - - The SuperNode Docker image currently works only with the 1.9.0-nightly release. A stable version - will be available when Flower 1.9.0 (stable) gets released (ETA: May). A SuperNode nightly image - must be paired with the corresponding SuperLink and ServerApp nightly images released on the same - day. To ensure the versions are in sync, using the concrete tag, e.g., ``1.9.0.dev20240501`` - instead of ``nightly`` is recommended. - We will use the ``quickstart-pytorch`` example, which you can find in the Flower repository, to illustrate how you can dockerize your ClientApp. @@ -204,7 +196,7 @@ The ``Dockerfile.supernode`` contains the instructions that assemble the SuperNo .. code-block:: dockerfile - FROM flwr/supernode:nightly + FROM flwr/supernode:1.9.0 WORKDIR /app @@ -214,7 +206,7 @@ The ``Dockerfile.supernode`` contains the instructions that assemble the SuperNo COPY client.py ./ ENTRYPOINT ["flower-client-app", "client:app"] -In the first two lines, we instruct Docker to use the SuperNode image tagged ``nightly`` as a base +In the first two lines, we instruct Docker to use the SuperNode image tagged ``1.9.0`` as a base image and set our working directory to ``/app``. The following instructions will now be executed in the ``/app`` directory. Next, we install the ClientApp dependencies by copying the ``requirements.txt`` file into the image and run ``pip install``. In the last two lines, @@ -275,7 +267,7 @@ To see all available flags that the SuperNode supports, run: .. code-block:: bash - $ docker run --rm flwr/supernode:nightly --help + $ docker run --rm flwr/supernode:1.9.0 --help Enabling SSL for secure connections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -325,14 +317,14 @@ The ``Dockerfile.serverapp`` contains the instructions that assemble the ServerA .. code-block:: dockerfile - FROM flwr/serverapp:1.8.0 + FROM flwr/serverapp:1.9.0 WORKDIR /app COPY server.py ./ ENTRYPOINT ["flower-server-app", "server:app"] -In the first two lines, we instruct Docker to use the ServerApp image tagged ``1.8.0`` as a base +In the first two lines, we instruct Docker to use the ServerApp image tagged ``1.9.0`` as a base image and set our working directory to ``/app``. The following instructions will now be executed in the ``/app`` directory. In the last two lines, we copy the ``server.py`` module into the image and set the entry point to ``flower-server-app`` with the argument ``server:app``. @@ -391,7 +383,7 @@ To see all available flags that the ServerApp supports, run: .. code-block:: bash - $ docker run --rm flwr/serverapp:1.8.0 --help + $ docker run --rm flwr/serverapp:1.9.0 --help Enabling SSL for secure connections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -425,7 +417,7 @@ Run the Docker image with the ``-u`` flag and specify ``root`` as the username: .. code-block:: bash - $ docker run --rm -u root flwr/superlink:1.8.0 + $ docker run --rm -u root flwr/superlink:1.9.0 This command will run the Docker container with root user privileges. @@ -436,7 +428,7 @@ missing system dependencies, you can use the ``USER root`` directive within your .. code-block:: dockerfile - FROM flwr/supernode:1.8.0 + FROM flwr/supernode:1.9.0 # Switch to root user USER root @@ -456,6 +448,13 @@ Using a different Flower version If you want to use a different version of Flower, for example Flower nightly, you can do so by changing the tag. All available versions are on `Docker Hub `__. +.. important:: + + When using Flower nightly, the SuperLink nightly image must be paired with the corresponding + SuperNode and ServerApp nightly images released on the same day. To ensure the versions are + in sync, using the concrete tag, e.g., ``1.10.0.dev20240610`` instead of ``nightly`` is + recommended. + Pinning a Docker image to a specific version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -464,19 +463,19 @@ updates of system dependencies that should not change the functionality of Flowe want to ensure that you always use the same image, you can specify the hash of the image instead of the tag. -The following command returns the current image hash referenced by the ``superlink:1.8.0`` tag: +The following command returns the current image hash referenced by the ``superlink:1.9.0`` tag: .. code-block:: bash - $ docker inspect --format='{{index .RepoDigests 0}}' flwr/superlink:1.8.0 - flwr/superlink@sha256:1b855d1fa4e344e4d95db99793f2bb35d8c63f6a1decdd736863bfe4bb0fe46c + $ docker inspect --format='{{index .RepoDigests 0}}' flwr/superlink:1.9.0 + flwr/superlink@sha256:985c24b2b337ab7f15a554fde9d860cede95079bcaa244fda8f12c0805e34c7d Next, we can pin the hash when running a new SuperLink container: .. code-block:: bash $ docker run \ - --rm flwr/superlink@sha256:1b855d1fa4e344e4d95db99793f2bb35d8c63f6a1decdd736863bfe4bb0fe46c \ + --rm flwr/superlink@sha256:985c24b2b337ab7f15a554fde9d860cede95079bcaa244fda8f12c0805e34c7d \ --insecure Setting environment variables @@ -487,4 +486,4 @@ To set a variable inside a Docker container, you can use the ``-e = .. code-block:: bash $ docker run -e FLWR_TELEMETRY_ENABLED=0 \ - --rm flwr/superlink:1.8.0 --insecure + --rm flwr/superlink:1.9.0 --insecure From 540b4c5aa45b00ba9924882f1e51eaa8660f7de2 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 20 Jun 2024 16:18:15 +0200 Subject: [PATCH 105/124] fix(framework:skip) Fix copyright notices (#3649) --- src/py/flwr/client/app_test.py | 2 +- src/py/flwr/client/client_app.py | 2 +- src/py/flwr/client/client_test.py | 2 +- src/py/flwr/client/dpfedavg_numpy_client.py | 2 +- src/py/flwr/client/grpc_rere_client/__init__.py | 2 +- .../grpc_rere_client/client_interceptor_test.py | 2 +- src/py/flwr/client/grpc_rere_client/connection.py | 2 +- src/py/flwr/client/message_handler/__init__.py | 2 +- .../flwr/client/message_handler/message_handler.py | 2 +- .../client/message_handler/message_handler_test.py | 2 +- src/py/flwr/client/mod/__init__.py | 2 +- .../flwr/client/mod/secure_aggregation/__init__.py | 2 +- src/py/flwr/client/mod/utils.py | 2 +- src/py/flwr/client/mod/utils_test.py | 2 +- src/py/flwr/client/numpy_client_test.py | 2 +- src/py/flwr/client/rest_client/__init__.py | 2 +- src/py/flwr/client/rest_client/connection.py | 2 +- src/py/flwr/common/address.py | 2 +- src/py/flwr/common/address_test.py | 2 +- src/py/flwr/common/constant.py | 2 +- src/py/flwr/common/date.py | 2 +- src/py/flwr/common/dp.py | 2 +- src/py/flwr/common/grpc.py | 2 +- src/py/flwr/common/message_test.py | 2 +- src/py/flwr/common/secure_aggregation/__init__.py | 2 +- .../common/secure_aggregation/crypto/__init__.py | 2 +- .../common/secure_aggregation/crypto/shamir.py | 2 +- .../crypto/symmetric_encryption.py | 2 +- .../secure_aggregation/ndarrays_arithmetic.py | 2 +- .../flwr/common/secure_aggregation/quantization.py | 2 +- .../secure_aggregation/secaggplus_constants.py | 2 +- .../common/secure_aggregation/secaggplus_utils.py | 2 +- src/py/flwr/common/serde_test.py | 2 +- src/py/flwr/common/version.py | 14 ++++++++++++++ src/py/flwr/server/client_proxy_test.py | 2 +- src/py/flwr/server/compat/app.py | 2 +- src/py/flwr/server/compat/driver_client_proxy.py | 2 +- .../flwr/server/compat/driver_client_proxy_test.py | 2 +- src/py/flwr/server/driver/grpc_driver.py | 2 +- src/py/flwr/server/driver/grpc_driver_test.py | 2 +- src/py/flwr/server/driver/inmemory_driver_test.py | 2 +- src/py/flwr/server/history_test.py | 2 +- src/py/flwr/server/server_app_test.py | 2 +- src/py/flwr/server/strategy/bulyan.py | 2 +- src/py/flwr/server/strategy/bulyan_test.py | 2 +- src/py/flwr/server/strategy/dpfedavg_adaptive.py | 2 +- src/py/flwr/server/strategy/dpfedavg_fixed.py | 2 +- src/py/flwr/server/strategy/fedadagrad.py | 2 +- src/py/flwr/server/strategy/fedadagrad_test.py | 2 +- src/py/flwr/server/strategy/fedadam.py | 2 +- src/py/flwr/server/strategy/fedavg_android.py | 2 +- src/py/flwr/server/strategy/fedavgm.py | 2 +- src/py/flwr/server/strategy/fedavgm_test.py | 2 +- src/py/flwr/server/strategy/fedmedian.py | 2 +- src/py/flwr/server/strategy/fedmedian_test.py | 2 +- src/py/flwr/server/strategy/fedopt.py | 2 +- src/py/flwr/server/strategy/fedprox.py | 2 +- src/py/flwr/server/strategy/fedxgb_bagging.py | 2 +- src/py/flwr/server/strategy/fedxgb_cyclic.py | 2 +- src/py/flwr/server/strategy/fedxgb_nn_avg.py | 2 +- src/py/flwr/server/strategy/fedyogi.py | 2 +- src/py/flwr/server/strategy/krum.py | 2 +- src/py/flwr/server/strategy/krum_test.py | 2 +- src/py/flwr/server/strategy/multikrum_test.py | 2 +- src/py/flwr/server/strategy/qfedavg.py | 2 +- src/py/flwr/server/superlink/driver/__init__.py | 2 +- src/py/flwr/server/superlink/driver/driver_grpc.py | 2 +- .../server/superlink/driver/driver_servicer.py | 2 +- .../superlink/driver/driver_servicer_test.py | 2 +- src/py/flwr/server/superlink/fleet/__init__.py | 2 +- .../server/superlink/fleet/grpc_bidi/__init__.py | 2 +- .../fleet/grpc_bidi/flower_service_servicer.py | 2 +- .../grpc_bidi/flower_service_servicer_test.py | 2 +- .../superlink/fleet/grpc_bidi/grpc_bridge.py | 2 +- .../superlink/fleet/grpc_bidi/grpc_bridge_test.py | 2 +- .../superlink/fleet/grpc_bidi/grpc_client_proxy.py | 2 +- .../fleet/grpc_bidi/grpc_client_proxy_test.py | 2 +- .../superlink/fleet/grpc_bidi/grpc_server.py | 2 +- .../superlink/fleet/grpc_bidi/grpc_server_test.py | 2 +- .../server/superlink/fleet/grpc_rere/__init__.py | 2 +- .../superlink/fleet/grpc_rere/fleet_servicer.py | 2 +- .../superlink/fleet/message_handler/__init__.py | 2 +- .../fleet/message_handler/message_handler.py | 2 +- .../fleet/message_handler/message_handler_test.py | 2 +- .../server/superlink/fleet/rest_rere/__init__.py | 2 +- .../server/superlink/fleet/rest_rere/rest_api.py | 2 +- src/py/flwr/server/superlink/state/__init__.py | 2 +- .../flwr/server/superlink/state/in_memory_state.py | 2 +- src/py/flwr/server/superlink/state/sqlite_state.py | 2 +- .../server/superlink/state/sqlite_state_test.py | 2 +- src/py/flwr/server/superlink/state/state.py | 2 +- .../flwr/server/superlink/state/state_factory.py | 2 +- src/py/flwr/server/superlink/state/state_test.py | 2 +- src/py/flwr/server/utils/__init__.py | 2 +- src/py/flwr/server/utils/tensorboard.py | 2 +- src/py/flwr/server/utils/tensorboard_test.py | 2 +- src/py/flwr/simulation/__init__.py | 2 +- src/py/flwr/simulation/app.py | 2 +- src/py/flwr/simulation/ray_transport/__init__.py | 2 +- .../simulation/ray_transport/ray_client_proxy.py | 2 +- 100 files changed, 113 insertions(+), 99 deletions(-) diff --git a/src/py/flwr/client/app_test.py b/src/py/flwr/client/app_test.py index 56d6308a0fe2..74ade03f973a 100644 --- a/src/py/flwr/client/app_test.py +++ b/src/py/flwr/client/app_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/client_app.py b/src/py/flwr/client/client_app.py index 82539834eaad..2e810f6560f2 100644 --- a/src/py/flwr/client/client_app.py +++ b/src/py/flwr/client/client_app.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/client_test.py b/src/py/flwr/client/client_test.py index 373c676e5edc..343b6cf093b2 100644 --- a/src/py/flwr/client/client_test.py +++ b/src/py/flwr/client/client_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/dpfedavg_numpy_client.py b/src/py/flwr/client/dpfedavg_numpy_client.py index ab31a289d29b..c592d10936d5 100644 --- a/src/py/flwr/client/dpfedavg_numpy_client.py +++ b/src/py/flwr/client/dpfedavg_numpy_client.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/grpc_rere_client/__init__.py b/src/py/flwr/client/grpc_rere_client/__init__.py index 93903e725776..e7c9408c0047 100644 --- a/src/py/flwr/client/grpc_rere_client/__init__.py +++ b/src/py/flwr/client/grpc_rere_client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py b/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py index cc35ffef46db..9607dac5679e 100644 --- a/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py +++ b/src/py/flwr/client/grpc_rere_client/client_interceptor_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/grpc_rere_client/connection.py b/src/py/flwr/client/grpc_rere_client/connection.py index b1c268d51d55..34dc0e417383 100644 --- a/src/py/flwr/client/grpc_rere_client/connection.py +++ b/src/py/flwr/client/grpc_rere_client/connection.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/message_handler/__init__.py b/src/py/flwr/client/message_handler/__init__.py index 653563963de5..a345b4af3ef2 100644 --- a/src/py/flwr/client/message_handler/__init__.py +++ b/src/py/flwr/client/message_handler/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/message_handler/message_handler.py b/src/py/flwr/client/message_handler/message_handler.py index e5acbe0cc9d0..68326852970f 100644 --- a/src/py/flwr/client/message_handler/message_handler.py +++ b/src/py/flwr/client/message_handler/message_handler.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/message_handler/message_handler_test.py b/src/py/flwr/client/message_handler/message_handler_test.py index 8a2db1804e4a..40907942513d 100644 --- a/src/py/flwr/client/message_handler/message_handler_test.py +++ b/src/py/flwr/client/message_handler/message_handler_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/mod/__init__.py b/src/py/flwr/client/mod/__init__.py index 0b4cf6488421..35d1fa81805c 100644 --- a/src/py/flwr/client/mod/__init__.py +++ b/src/py/flwr/client/mod/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/mod/secure_aggregation/__init__.py b/src/py/flwr/client/mod/secure_aggregation/__init__.py index 8892d8c03935..a64bc89e62c9 100644 --- a/src/py/flwr/client/mod/secure_aggregation/__init__.py +++ b/src/py/flwr/client/mod/secure_aggregation/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/mod/utils.py b/src/py/flwr/client/mod/utils.py index 4c3c32944f01..c8fb21379783 100644 --- a/src/py/flwr/client/mod/utils.py +++ b/src/py/flwr/client/mod/utils.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/mod/utils_test.py b/src/py/flwr/client/mod/utils_test.py index 4676a2c02c4b..035e41639b10 100644 --- a/src/py/flwr/client/mod/utils_test.py +++ b/src/py/flwr/client/mod/utils_test.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/numpy_client_test.py b/src/py/flwr/client/numpy_client_test.py index 526098798e45..06a0deafe2c9 100644 --- a/src/py/flwr/client/numpy_client_test.py +++ b/src/py/flwr/client/numpy_client_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/rest_client/__init__.py b/src/py/flwr/client/rest_client/__init__.py index c3485483ad35..a24d822a6d75 100644 --- a/src/py/flwr/client/rest_client/__init__.py +++ b/src/py/flwr/client/rest_client/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/client/rest_client/connection.py b/src/py/flwr/client/rest_client/connection.py index 5f5e153f9d8d..db5bd7eb6770 100644 --- a/src/py/flwr/client/rest_client/connection.py +++ b/src/py/flwr/client/rest_client/connection.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/address.py b/src/py/flwr/common/address.py index 71b6d684597f..1c6481b80a74 100644 --- a/src/py/flwr/common/address.py +++ b/src/py/flwr/common/address.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/address_test.py b/src/py/flwr/common/address_test.py index 420b89871d69..d5901ed640b1 100644 --- a/src/py/flwr/common/address_test.py +++ b/src/py/flwr/common/address_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/constant.py b/src/py/flwr/common/constant.py index 193f000ca42e..ce29b3edb30e 100644 --- a/src/py/flwr/common/constant.py +++ b/src/py/flwr/common/constant.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/date.py b/src/py/flwr/common/date.py index f47ad5470106..7f30f5e0591a 100644 --- a/src/py/flwr/common/date.py +++ b/src/py/flwr/common/date.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/dp.py b/src/py/flwr/common/dp.py index 83a72b8ce749..527805c8ef42 100644 --- a/src/py/flwr/common/dp.py +++ b/src/py/flwr/common/dp.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/grpc.py b/src/py/flwr/common/grpc.py index ead0329ca79c..ec8fe823a7eb 100644 --- a/src/py/flwr/common/grpc.py +++ b/src/py/flwr/common/grpc.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/message_test.py b/src/py/flwr/common/message_test.py index 19f8aeb1eb63..daee57896903 100644 --- a/src/py/flwr/common/message_test.py +++ b/src/py/flwr/common/message_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/__init__.py b/src/py/flwr/common/secure_aggregation/__init__.py index b4e0acc0c148..77e1ea3842d7 100644 --- a/src/py/flwr/common/secure_aggregation/__init__.py +++ b/src/py/flwr/common/secure_aggregation/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/crypto/__init__.py b/src/py/flwr/common/secure_aggregation/crypto/__init__.py index 2cb34493f7d0..3788dbc0ca15 100644 --- a/src/py/flwr/common/secure_aggregation/crypto/__init__.py +++ b/src/py/flwr/common/secure_aggregation/crypto/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/crypto/shamir.py b/src/py/flwr/common/secure_aggregation/crypto/shamir.py index e56e21b89371..688bfa2153ea 100644 --- a/src/py/flwr/common/secure_aggregation/crypto/shamir.py +++ b/src/py/flwr/common/secure_aggregation/crypto/shamir.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py b/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py index 1d004a398ea8..59ca84d604b8 100644 --- a/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py +++ b/src/py/flwr/common/secure_aggregation/crypto/symmetric_encryption.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py b/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py index e926a9531bea..207c15b61518 100644 --- a/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py +++ b/src/py/flwr/common/secure_aggregation/ndarrays_arithmetic.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/quantization.py b/src/py/flwr/common/secure_aggregation/quantization.py index 56c25e2bd59c..7946276b6a4f 100644 --- a/src/py/flwr/common/secure_aggregation/quantization.py +++ b/src/py/flwr/common/secure_aggregation/quantization.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/secaggplus_constants.py b/src/py/flwr/common/secure_aggregation/secaggplus_constants.py index 8a15908c13c5..545507eb44ed 100644 --- a/src/py/flwr/common/secure_aggregation/secaggplus_constants.py +++ b/src/py/flwr/common/secure_aggregation/secaggplus_constants.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/secure_aggregation/secaggplus_utils.py b/src/py/flwr/common/secure_aggregation/secaggplus_utils.py index c373573477b9..cf6ac3bfb003 100644 --- a/src/py/flwr/common/secure_aggregation/secaggplus_utils.py +++ b/src/py/flwr/common/secure_aggregation/secaggplus_utils.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/serde_test.py b/src/py/flwr/common/serde_test.py index f9969426fc36..afb11b6956f2 100644 --- a/src/py/flwr/common/serde_test.py +++ b/src/py/flwr/common/serde_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/common/version.py b/src/py/flwr/common/version.py index 6808c66606b1..ac13f70d8a88 100644 --- a/src/py/flwr/common/version.py +++ b/src/py/flwr/common/version.py @@ -1,3 +1,17 @@ +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== """Flower package version helper.""" import importlib.metadata as importlib_metadata diff --git a/src/py/flwr/server/client_proxy_test.py b/src/py/flwr/server/client_proxy_test.py index 685698558e3a..6ca37052a87d 100644 --- a/src/py/flwr/server/client_proxy_test.py +++ b/src/py/flwr/server/client_proxy_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/compat/app.py b/src/py/flwr/server/compat/app.py index 4bb23b846ab7..e978359fa828 100644 --- a/src/py/flwr/server/compat/app.py +++ b/src/py/flwr/server/compat/app.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/compat/driver_client_proxy.py b/src/py/flwr/server/compat/driver_client_proxy.py index 150803786f98..7190786784ec 100644 --- a/src/py/flwr/server/compat/driver_client_proxy.py +++ b/src/py/flwr/server/compat/driver_client_proxy.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/compat/driver_client_proxy_test.py b/src/py/flwr/server/compat/driver_client_proxy_test.py index d9e3d3bc0824..31b917fa869b 100644 --- a/src/py/flwr/server/compat/driver_client_proxy_test.py +++ b/src/py/flwr/server/compat/driver_client_proxy_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/driver/grpc_driver.py b/src/py/flwr/server/driver/grpc_driver.py index 2016d54b655a..e614df659e3f 100644 --- a/src/py/flwr/server/driver/grpc_driver.py +++ b/src/py/flwr/server/driver/grpc_driver.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/driver/grpc_driver_test.py b/src/py/flwr/server/driver/grpc_driver_test.py index 60ab79002f85..72efc5f8b2c6 100644 --- a/src/py/flwr/server/driver/grpc_driver_test.py +++ b/src/py/flwr/server/driver/grpc_driver_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/driver/inmemory_driver_test.py b/src/py/flwr/server/driver/inmemory_driver_test.py index 55d52d848dfd..eff38f548826 100644 --- a/src/py/flwr/server/driver/inmemory_driver_test.py +++ b/src/py/flwr/server/driver/inmemory_driver_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/history_test.py b/src/py/flwr/server/history_test.py index adb9d697e409..b53357149623 100644 --- a/src/py/flwr/server/history_test.py +++ b/src/py/flwr/server/history_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/server_app_test.py b/src/py/flwr/server/server_app_test.py index 38c0d6240d90..0751a0cb2bc5 100644 --- a/src/py/flwr/server/server_app_test.py +++ b/src/py/flwr/server/server_app_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/bulyan.py b/src/py/flwr/server/strategy/bulyan.py index 1e4f97530ab7..a81406c255ad 100644 --- a/src/py/flwr/server/strategy/bulyan.py +++ b/src/py/flwr/server/strategy/bulyan.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/bulyan_test.py b/src/py/flwr/server/strategy/bulyan_test.py index 299ed49066fb..93a9ebda3783 100644 --- a/src/py/flwr/server/strategy/bulyan_test.py +++ b/src/py/flwr/server/strategy/bulyan_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/dpfedavg_adaptive.py b/src/py/flwr/server/strategy/dpfedavg_adaptive.py index a908679ed668..423ddddeb379 100644 --- a/src/py/flwr/server/strategy/dpfedavg_adaptive.py +++ b/src/py/flwr/server/strategy/dpfedavg_adaptive.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/dpfedavg_fixed.py b/src/py/flwr/server/strategy/dpfedavg_fixed.py index c54379fc7087..d122f0688922 100644 --- a/src/py/flwr/server/strategy/dpfedavg_fixed.py +++ b/src/py/flwr/server/strategy/dpfedavg_fixed.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedadagrad.py b/src/py/flwr/server/strategy/fedadagrad.py index 4a8f52d98e18..f13c5358da25 100644 --- a/src/py/flwr/server/strategy/fedadagrad.py +++ b/src/py/flwr/server/strategy/fedadagrad.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedadagrad_test.py b/src/py/flwr/server/strategy/fedadagrad_test.py index 0c966442ecaf..b43a4c75d123 100644 --- a/src/py/flwr/server/strategy/fedadagrad_test.py +++ b/src/py/flwr/server/strategy/fedadagrad_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedadam.py b/src/py/flwr/server/strategy/fedadam.py index 8a47cf0dd8ac..dc90e90c7568 100644 --- a/src/py/flwr/server/strategy/fedadam.py +++ b/src/py/flwr/server/strategy/fedadam.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedavg_android.py b/src/py/flwr/server/strategy/fedavg_android.py index 6678b7ced114..2f49cf8784c9 100644 --- a/src/py/flwr/server/strategy/fedavg_android.py +++ b/src/py/flwr/server/strategy/fedavg_android.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedavgm.py b/src/py/flwr/server/strategy/fedavgm.py index fb9261abe89d..ab3d37249db6 100644 --- a/src/py/flwr/server/strategy/fedavgm.py +++ b/src/py/flwr/server/strategy/fedavgm.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedavgm_test.py b/src/py/flwr/server/strategy/fedavgm_test.py index a0e942171627..39da5f4b82c4 100644 --- a/src/py/flwr/server/strategy/fedavgm_test.py +++ b/src/py/flwr/server/strategy/fedavgm_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedmedian.py b/src/py/flwr/server/strategy/fedmedian.py index 17e979d92beb..e7cba5324fa8 100644 --- a/src/py/flwr/server/strategy/fedmedian.py +++ b/src/py/flwr/server/strategy/fedmedian.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedmedian_test.py b/src/py/flwr/server/strategy/fedmedian_test.py index 57cf08d8c01d..3960ad70b145 100644 --- a/src/py/flwr/server/strategy/fedmedian_test.py +++ b/src/py/flwr/server/strategy/fedmedian_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedopt.py b/src/py/flwr/server/strategy/fedopt.py index be5f260d96fa..c581d4797123 100644 --- a/src/py/flwr/server/strategy/fedopt.py +++ b/src/py/flwr/server/strategy/fedopt.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedprox.py b/src/py/flwr/server/strategy/fedprox.py index d20f578b193d..f15271e06060 100644 --- a/src/py/flwr/server/strategy/fedprox.py +++ b/src/py/flwr/server/strategy/fedprox.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedxgb_bagging.py b/src/py/flwr/server/strategy/fedxgb_bagging.py index a8e8adddafbb..a74ee81976a6 100644 --- a/src/py/flwr/server/strategy/fedxgb_bagging.py +++ b/src/py/flwr/server/strategy/fedxgb_bagging.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedxgb_cyclic.py b/src/py/flwr/server/strategy/fedxgb_cyclic.py index 2605daab29f4..75025a89728b 100644 --- a/src/py/flwr/server/strategy/fedxgb_cyclic.py +++ b/src/py/flwr/server/strategy/fedxgb_cyclic.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedxgb_nn_avg.py b/src/py/flwr/server/strategy/fedxgb_nn_avg.py index 8dedc925f350..4562663287ae 100644 --- a/src/py/flwr/server/strategy/fedxgb_nn_avg.py +++ b/src/py/flwr/server/strategy/fedxgb_nn_avg.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/fedyogi.py b/src/py/flwr/server/strategy/fedyogi.py index 7c77aab7ae73..c7b2ebb51667 100644 --- a/src/py/flwr/server/strategy/fedyogi.py +++ b/src/py/flwr/server/strategy/fedyogi.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/krum.py b/src/py/flwr/server/strategy/krum.py index 16eb5212940e..074d018c35a3 100644 --- a/src/py/flwr/server/strategy/krum.py +++ b/src/py/flwr/server/strategy/krum.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/krum_test.py b/src/py/flwr/server/strategy/krum_test.py index 653dc9a8475d..b34982325b39 100644 --- a/src/py/flwr/server/strategy/krum_test.py +++ b/src/py/flwr/server/strategy/krum_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/multikrum_test.py b/src/py/flwr/server/strategy/multikrum_test.py index f874dc2f9800..7a1a4c3ecf38 100644 --- a/src/py/flwr/server/strategy/multikrum_test.py +++ b/src/py/flwr/server/strategy/multikrum_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2022 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/strategy/qfedavg.py b/src/py/flwr/server/strategy/qfedavg.py index 758e8e608e9f..26a397d4cf8c 100644 --- a/src/py/flwr/server/strategy/qfedavg.py +++ b/src/py/flwr/server/strategy/qfedavg.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/driver/__init__.py b/src/py/flwr/server/superlink/driver/__init__.py index 2bfe63e6065f..58fbc479478f 100644 --- a/src/py/flwr/server/superlink/driver/__init__.py +++ b/src/py/flwr/server/superlink/driver/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/driver/driver_grpc.py b/src/py/flwr/server/superlink/driver/driver_grpc.py index f74000bc59c4..782935481945 100644 --- a/src/py/flwr/server/superlink/driver/driver_grpc.py +++ b/src/py/flwr/server/superlink/driver/driver_grpc.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/driver/driver_servicer.py b/src/py/flwr/server/superlink/driver/driver_servicer.py index 30d2e883dc63..03128f02158e 100644 --- a/src/py/flwr/server/superlink/driver/driver_servicer.py +++ b/src/py/flwr/server/superlink/driver/driver_servicer.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/driver/driver_servicer_test.py b/src/py/flwr/server/superlink/driver/driver_servicer_test.py index 99f7cc007a89..394d6be7ee6a 100644 --- a/src/py/flwr/server/superlink/driver/driver_servicer_test.py +++ b/src/py/flwr/server/superlink/driver/driver_servicer_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/__init__.py b/src/py/flwr/server/superlink/fleet/__init__.py index d3c3ef90163d..c236ed06ae1c 100644 --- a/src/py/flwr/server/superlink/fleet/__init__.py +++ b/src/py/flwr/server/superlink/fleet/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py index bae8bc431edd..6b2c2bf3ffec 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py index 6f94ea844e38..79f1a8f9902b 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer_test.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer_test.py index bd93554a6a32..03e8555f8ecf 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer_test.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/flower_service_servicer_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py index d5b4a915c609..5fe0396696ab 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge_test.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge_test.py index f7c236acd7a1..f9b6b97030f0 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge_test.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_bridge_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py index ac62ad014950..03497743becd 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy_test.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy_test.py index e7077dfd39ae..6d3eb4f67e30 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy_test.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_client_proxy_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py index ae685fda91a7..1b4286c87b92 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server_test.py b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server_test.py index 8afa37515950..7ff730b17afa 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server_test.py +++ b/src/py/flwr/server/superlink/fleet/grpc_bidi/grpc_server_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py b/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py index 61ab71d91400..03c8ded2423a 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py +++ b/src/py/flwr/server/superlink/fleet/grpc_rere/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py b/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py index 13e024eb31e4..89342a46eb48 100644 --- a/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py +++ b/src/py/flwr/server/superlink/fleet/grpc_rere/fleet_servicer.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/message_handler/__init__.py b/src/py/flwr/server/superlink/fleet/message_handler/__init__.py index 18b0f11fa6c5..3db0ef5d1611 100644 --- a/src/py/flwr/server/superlink/fleet/message_handler/__init__.py +++ b/src/py/flwr/server/superlink/fleet/message_handler/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py index dceb18cab453..b70cd54035fe 100644 --- a/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py +++ b/src/py/flwr/server/superlink/fleet/message_handler/message_handler.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/message_handler/message_handler_test.py b/src/py/flwr/server/superlink/fleet/message_handler/message_handler_test.py index c135f6fb7b61..ec521b328eb8 100644 --- a/src/py/flwr/server/superlink/fleet/message_handler/message_handler_test.py +++ b/src/py/flwr/server/superlink/fleet/message_handler/message_handler_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py b/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py index a926f9ca0bfc..f24db2a2e12f 100644 --- a/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py +++ b/src/py/flwr/server/superlink/fleet/rest_rere/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py b/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py index c7ff496d39bf..1ed67e5eb0aa 100644 --- a/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py +++ b/src/py/flwr/server/superlink/fleet/rest_rere/rest_api.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/__init__.py b/src/py/flwr/server/superlink/state/__init__.py index 7f260d733bbe..9d3bd220403b 100644 --- a/src/py/flwr/server/superlink/state/__init__.py +++ b/src/py/flwr/server/superlink/state/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/in_memory_state.py b/src/py/flwr/server/superlink/state/in_memory_state.py index e03260355db9..da9c754c3115 100644 --- a/src/py/flwr/server/superlink/state/in_memory_state.py +++ b/src/py/flwr/server/superlink/state/in_memory_state.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/sqlite_state.py b/src/py/flwr/server/superlink/state/sqlite_state.py index b9672757b0e6..4df9470ded62 100644 --- a/src/py/flwr/server/superlink/state/sqlite_state.py +++ b/src/py/flwr/server/superlink/state/sqlite_state.py @@ -1,4 +1,4 @@ -# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/sqlite_state_test.py b/src/py/flwr/server/superlink/state/sqlite_state_test.py index 20927df1cf12..10e12da96bd5 100644 --- a/src/py/flwr/server/superlink/state/sqlite_state_test.py +++ b/src/py/flwr/server/superlink/state/sqlite_state_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/state.py b/src/py/flwr/server/superlink/state/state.py index d1fc9465c9f2..65e2c63cab69 100644 --- a/src/py/flwr/server/superlink/state/state.py +++ b/src/py/flwr/server/superlink/state/state.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/state_factory.py b/src/py/flwr/server/superlink/state/state_factory.py index 51f5bf5e2ee2..96c8d445c16e 100644 --- a/src/py/flwr/server/superlink/state/state_factory.py +++ b/src/py/flwr/server/superlink/state/state_factory.py @@ -1,4 +1,4 @@ -# Copyright 2022 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/superlink/state/state_test.py b/src/py/flwr/server/superlink/state/state_test.py index 81307d938400..373202d5cde6 100644 --- a/src/py/flwr/server/superlink/state/state_test.py +++ b/src/py/flwr/server/superlink/state/state_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/utils/__init__.py b/src/py/flwr/server/utils/__init__.py index c370716adaac..8994374c4d08 100644 --- a/src/py/flwr/server/utils/__init__.py +++ b/src/py/flwr/server/utils/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/utils/tensorboard.py b/src/py/flwr/server/utils/tensorboard.py index 3e8d1e62411e..5d38fc159657 100644 --- a/src/py/flwr/server/utils/tensorboard.py +++ b/src/py/flwr/server/utils/tensorboard.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/server/utils/tensorboard_test.py b/src/py/flwr/server/utils/tensorboard_test.py index 1827a42cf6e6..689755c6da16 100644 --- a/src/py/flwr/server/utils/tensorboard_test.py +++ b/src/py/flwr/server/utils/tensorboard_test.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/simulation/__init__.py b/src/py/flwr/simulation/__init__.py index 3d648b14edba..5db90a352e3f 100644 --- a/src/py/flwr/simulation/__init__.py +++ b/src/py/flwr/simulation/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/simulation/app.py b/src/py/flwr/simulation/app.py index 4b4b7249ccd3..856d6fc45e22 100644 --- a/src/py/flwr/simulation/app.py +++ b/src/py/flwr/simulation/app.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/simulation/ray_transport/__init__.py b/src/py/flwr/simulation/ray_transport/__init__.py index 0e82b75bb4b3..ed4971935a15 100644 --- a/src/py/flwr/simulation/ray_transport/__init__.py +++ b/src/py/flwr/simulation/ray_transport/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/py/flwr/simulation/ray_transport/ray_client_proxy.py b/src/py/flwr/simulation/ray_transport/ray_client_proxy.py index 5e344eb087ee..d3d103bb377a 100644 --- a/src/py/flwr/simulation/ray_transport/ray_client_proxy.py +++ b/src/py/flwr/simulation/ray_transport/ray_client_proxy.py @@ -1,4 +1,4 @@ -# Copyright 2020 Flower Labs GmbH. All Rights Reserved. +# Copyright 2021 Flower Labs GmbH. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. From cd330e2bec026d910a86e146377a64783c3f5e2f Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 20 Jun 2024 16:24:41 +0200 Subject: [PATCH 106/124] ci(framework:skip) Check copyright notices correctness (#3657) --- .github/workflows/framework.yml | 2 + dev/format.sh | 1 + dev/test.sh | 4 ++ src/py/flwr_tool/check_copyright.py | 76 +++++++++++++++++++++++++++++ src/py/flwr_tool/fix_copyright.py | 59 ++++++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100755 src/py/flwr_tool/check_copyright.py create mode 100755 src/py/flwr_tool/fix_copyright.py diff --git a/.github/workflows/framework.yml b/.github/workflows/framework.yml index 784f04750c5e..feb08229be06 100644 --- a/.github/workflows/framework.yml +++ b/.github/workflows/framework.yml @@ -31,6 +31,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Bootstrap uses: ./.github/actions/bootstrap with: diff --git a/dev/format.sh b/dev/format.sh index b9e3b00dffe1..71edf9c6065a 100755 --- a/dev/format.sh +++ b/dev/format.sh @@ -3,6 +3,7 @@ set -e cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../ # Python +python -m flwr_tool.check_copyright src/py/flwr python -m flwr_tool.init_py_fix src/py/flwr python -m isort --skip src/py/flwr/proto src/py python -m black -q --exclude src/py/flwr/proto src/py diff --git a/dev/test.sh b/dev/test.sh index 7cabf35abf41..5b827380bc50 100755 --- a/dev/test.sh +++ b/dev/test.sh @@ -58,6 +58,10 @@ echo "- All Markdown checks passed" echo "- Start license checks" +echo "- copyright: start" +python -m flwr_tool.check_copyright src/py/flwr +echo "- copyright: done" + echo "- licensecheck: start" python -m licensecheck -u poetry --fail-licenses gpl --zero echo "- licensecheck: done" diff --git a/src/py/flwr_tool/check_copyright.py b/src/py/flwr_tool/check_copyright.py new file mode 100755 index 000000000000..96870ba67bd0 --- /dev/null +++ b/src/py/flwr_tool/check_copyright.py @@ -0,0 +1,76 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +"""Check if copyright notices are present in all Python files. + +Example: + python -m flwr_tool.check_copyright src/py/flwr +""" + + +import os +import subprocess +import sys +from pathlib import Path +from typing import List + +from flwr_tool.init_py_check import get_init_dir_list_and_warnings + +COPYRIGHT_FORMAT = """# Copyright {} Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ==============================================================================""" + + +def _get_file_creation_year(filepath: str) -> str: + result = subprocess.run( + ["git", "log", "--diff-filter=A", "--format=%ai", "--", filepath], + stdout=subprocess.PIPE, + text=True, + check=True, + ) + date_str = result.stdout.splitlines()[-1] # Get the first commit date + creation_year = date_str.split("-")[0] # Extract the year + return creation_year + + +def _check_copyright(dir_list: List[str]) -> None: + warning_list = [] + for valid_dir in dir_list: + if "proto" in valid_dir: + continue + + dir_path = Path(valid_dir) + for py_file in dir_path.glob("*.py"): + creation_year = _get_file_creation_year(str(py_file.absolute())) + expected_copyright = COPYRIGHT_FORMAT.format(creation_year) + + if expected_copyright not in py_file.read_text(): + warning_message = "- " + str(py_file) + warning_list.append(warning_message) + + if len(warning_list) > 0: + print("Missing or incorrect copyright notice in the following files:") + for warning in warning_list: + print(warning) + sys.exit(1) + + +if __name__ == "__main__": + if len(sys.argv) == 0: + raise Exception( # pylint: disable=W0719 + "Please provide at least one directory path relative " + "to your current working directory." + ) + for i, _ in enumerate(sys.argv): + abs_path: str = os.path.abspath(os.path.join(os.getcwd(), sys.argv[i])) + __, init_dirs = get_init_dir_list_and_warnings(abs_path) + _check_copyright(init_dirs) diff --git a/src/py/flwr_tool/fix_copyright.py b/src/py/flwr_tool/fix_copyright.py new file mode 100755 index 000000000000..a5bbbdf616f7 --- /dev/null +++ b/src/py/flwr_tool/fix_copyright.py @@ -0,0 +1,59 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +"""Fix copyright notices in all Python files of a given directory. + +Example: + python -m flwr_tool.fix_copyright src/py/flwr +""" + + +import os +import sys +from pathlib import Path +from typing import List + +from flwr_tool.check_copyright import COPYRIGHT_FORMAT, _get_file_creation_year +from flwr_tool.init_py_check import get_init_dir_list_and_warnings + + +def _insert_or_edit_copyright(py_file: Path) -> None: + contents = py_file.read_text() + lines = contents.splitlines() + creation_year = _get_file_creation_year(str(py_file.absolute())) + expected_copyright = COPYRIGHT_FORMAT.format(creation_year) + + if expected_copyright not in contents: + if "Copyright" in lines[0]: + end_index = 0 + for idx, line in enumerate(lines): + if ( + line.strip() + == COPYRIGHT_FORMAT.rsplit("\n", maxsplit=1)[-1].strip() + ): + end_index = idx + 1 + break + lines = lines[end_index:] + + lines.insert(0, expected_copyright) + py_file.write_text("\n".join(lines) + "\n") + + +def _fix_copyright(dir_list: List[str]) -> None: + for valid_dir in dir_list: + if "proto" in valid_dir: + continue + + dir_path = Path(valid_dir) + for py_file in dir_path.glob("*.py"): + _insert_or_edit_copyright(py_file) + + +if __name__ == "__main__": + if len(sys.argv) == 0: + raise Exception( # pylint: disable=W0719 + "Please provide at least one directory path relative " + "to your current working directory." + ) + for i, _ in enumerate(sys.argv): + abs_path: str = os.path.abspath(os.path.join(os.getcwd(), sys.argv[i])) + __, init_dirs = get_init_dir_list_and_warnings(abs_path) + _fix_copyright(init_dirs) From 83fefc1f151f2c741a68473bdacd6ddbd2b8fddb Mon Sep 17 00:00:00 2001 From: Jiahao Tan Date: Thu, 20 Jun 2024 22:36:03 +0800 Subject: [PATCH 107/124] docs(framework) Fix pip command of installing `flwr[simulation]` (#3641) --- doc/source/how-to-install-flower.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/how-to-install-flower.rst b/doc/source/how-to-install-flower.rst index 725a7468090c..b00e2ae803ab 100644 --- a/doc/source/how-to-install-flower.rst +++ b/doc/source/how-to-install-flower.rst @@ -20,7 +20,7 @@ Stable releases are available on `PyPI `_:: For simulations that use the Virtual Client Engine, ``flwr`` should be installed with the ``simulation`` extra:: - python -m pip install flwr[simulation] + python -m pip install "flwr[simulation]" Using conda (or mamba) From f80dfa5cebc8579437d2bd4305668d865920482b Mon Sep 17 00:00:00 2001 From: Gustavo Bertoli Date: Thu, 20 Jun 2024 16:42:47 +0200 Subject: [PATCH 108/124] docs(examples:skip) Fix minor typos (#3636) --- .../contributor-tutorial-get-started-as-a-contributor.rst | 4 ++-- doc/source/how-to-use-differential-privacy.rst | 2 +- doc/source/how-to-use-strategies.rst | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/source/contributor-tutorial-get-started-as-a-contributor.rst b/doc/source/contributor-tutorial-get-started-as-a-contributor.rst index 43f9739987ac..d7d647996a3d 100644 --- a/doc/source/contributor-tutorial-get-started-as-a-contributor.rst +++ b/doc/source/contributor-tutorial-get-started-as-a-contributor.rst @@ -17,8 +17,8 @@ supports `PEP 517 `_. Developer Machine Setup ----------------------- -Preliminarities -~~~~~~~~~~~~~~~ +Preliminaries +~~~~~~~~~~~~~ Some system-wide dependencies are needed. For macOS diff --git a/doc/source/how-to-use-differential-privacy.rst b/doc/source/how-to-use-differential-privacy.rst index c8901bd906cc..5d4fa3dca1a4 100644 --- a/doc/source/how-to-use-differential-privacy.rst +++ b/doc/source/how-to-use-differential-privacy.rst @@ -9,7 +9,7 @@ This guide explains how you can utilize differential privacy in the Flower frame Central Differential Privacy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This approach consists of two seprate phases: clipping of the updates and adding noise to the aggregated model. +This approach consists of two separate phases: clipping of the updates and adding noise to the aggregated model. For the clipping phase, Flower framework has made it possible to decide whether to perform clipping on the server side or the client side. - **Server-side Clipping**: This approach has the advantage of the server enforcing uniform clipping across all clients' updates and reducing the communication overhead for clipping values. However, it also has the disadvantage of increasing the computational load on the server due to the need to perform the clipping operation for all clients. diff --git a/doc/source/how-to-use-strategies.rst b/doc/source/how-to-use-strategies.rst index d0e2cd63a091..8ac120124951 100644 --- a/doc/source/how-to-use-strategies.rst +++ b/doc/source/how-to-use-strategies.rst @@ -72,7 +72,7 @@ It must return a dictionary of arbitrary configuration values :code:`client.fit ) fl.server.start_server(config=fl.server.ServerConfig(num_rounds=3), strategy=strategy) -The :code:`on_fit_config_fn` can be used to pass arbitrary configuration values from server to client, and poetentially change these values each round, for example, to adjust the learning rate. +The :code:`on_fit_config_fn` can be used to pass arbitrary configuration values from server to client, and potentially change these values each round, for example, to adjust the learning rate. The client will receive the dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client.fit()` function. Similar to :code:`on_fit_config_fn`, there is also :code:`on_evaluate_config_fn` to customize the configuration sent to :code:`client.evaluate()` From e2d51638b1f2b90202e86ef362f5a59dc4acddb0 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Thu, 20 Jun 2024 15:53:25 +0100 Subject: [PATCH 109/124] fix(framework:skip) Fix the help message for `flwr-dir` arg in `flower-supernode` (#3660) --- src/py/flwr/client/supernode/app.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/py/flwr/client/supernode/app.py b/src/py/flwr/client/supernode/app.py index 742281f5c011..c9a16edeaf15 100644 --- a/src/py/flwr/client/supernode/app.py +++ b/src/py/flwr/client/supernode/app.py @@ -267,7 +267,7 @@ def _parse_args_run_supernode() -> argparse.ArgumentParser: "--flwr-dir", default=None, help="""The path containing installed Flower Apps. - By default, this value isequal to: + By default, this value is equal to: - `$FLWR_HOME/` if `$FLWR_HOME` is defined - `$XDG_DATA_HOME/.flwr/` if `$XDG_DATA_HOME` is defined From 72e88672f84714ac726419eb2b4137f9b54b2230 Mon Sep 17 00:00:00 2001 From: Yan Gao Date: Thu, 20 Jun 2024 23:48:35 +0800 Subject: [PATCH 110/124] feat(framework) Read `backend_config` from config when running simulation via `flwr run` (#3581) --- src/py/flwr/cli/run/run.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/py/flwr/cli/run/run.py b/src/py/flwr/cli/run/run.py index 28fa67f9d4f6..4c95a4041c05 100644 --- a/src/py/flwr/cli/run/run.py +++ b/src/py/flwr/cli/run/run.py @@ -90,12 +90,16 @@ def run( if engine == Engine.SIMULATION: num_supernodes = config["flower"]["engine"]["simulation"]["supernode"]["num"] + backend_config = config["flower"]["engine"]["simulation"].get( + "backend_config", None + ) typer.secho("Starting run... ", fg=typer.colors.BLUE) _run_simulation( server_app_attr=server_app_ref, client_app_attr=client_app_ref, num_supernodes=num_supernodes, + backend_config=backend_config, ) else: typer.secho( From 9899354002ed9dd27890938708da1151389aa308 Mon Sep 17 00:00:00 2001 From: Charles Beauville Date: Thu, 20 Jun 2024 18:56:14 +0200 Subject: [PATCH 111/124] feat(framework:skip) Add argument to `get_flwr_dir` (#3661) --- src/py/flwr/common/config.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/py/flwr/common/config.py b/src/py/flwr/common/config.py index 95bf8ce31c45..20de00a6fba9 100644 --- a/src/py/flwr/common/config.py +++ b/src/py/flwr/common/config.py @@ -24,14 +24,16 @@ from flwr.common.constant import APP_DIR, FAB_CONFIG_FILE, FLWR_HOME -def get_flwr_dir() -> Path: +def get_flwr_dir(provided_path: Optional[str] = None) -> Path: """Return the Flower home directory based on env variables.""" - return Path( - os.getenv( - FLWR_HOME, - f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", + if provided_path is None or not Path(provided_path).is_dir(): + return Path( + os.getenv( + FLWR_HOME, + f"{os.getenv('XDG_DATA_HOME', os.getenv('HOME'))}/.flwr", + ) ) - ) + return Path(provided_path).absolute() def get_project_dir( From a730466946ee81c59c7cdbea3398f0e9ee28ac62 Mon Sep 17 00:00:00 2001 From: Heng Pan Date: Fri, 21 Jun 2024 12:37:33 +0100 Subject: [PATCH 112/124] feat(framework) Allow `flower-server-app` to start with `run_id` (#3658) Co-authored-by: Daniel J. Beutel --- src/py/flwr/server/run_serverapp.py | 78 +++++++++++++++++++++-------- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/src/py/flwr/server/run_serverapp.py b/src/py/flwr/server/run_serverapp.py index 63ffc4a1caae..3505ebfdb0a9 100644 --- a/src/py/flwr/server/run_serverapp.py +++ b/src/py/flwr/server/run_serverapp.py @@ -22,6 +22,7 @@ from typing import Optional from flwr.common import Context, EventType, RecordSet, event +from flwr.common.config import get_flwr_dir, get_project_config, get_project_dir from flwr.common.logger import log, update_console_handler, warn_deprecated_feature from flwr.common.object_ref import load_app from flwr.proto.driver_pb2 import CreateRunRequest # pylint: disable=E0611 @@ -43,7 +44,7 @@ def run( if not (server_app_attr is None) ^ (loaded_server_app is None): raise ValueError( "Either `server_app_attr` or `loaded_server_app` should be set " - "but not both. " + "but not both." ) if server_app_dir is not None: @@ -76,7 +77,7 @@ def _load() -> ServerApp: log(DEBUG, "ServerApp finished running.") -def run_server_app() -> None: +def run_server_app() -> None: # pylint: disable=too-many-branches """Run Flower server app.""" event(EventType.RUN_SERVER_APP_ENTER) @@ -136,11 +137,43 @@ def run_server_app() -> None: cert_path, ) - log( - DEBUG, - "Flower will load ServerApp `%s`", - getattr(args, "server-app"), + server_app_attr: Optional[str] = getattr(args, "server-app") + if not (server_app_attr is None) ^ (args.run_id is None): + raise sys.exit( + "Please provide either a ServerApp reference or a Run ID, but not both. " + "For more details, use: ``flower-server-app -h``" + ) + + stub = GrpcDriverStub( + driver_service_address=args.superlink, root_certificates=root_certificates ) + if args.run_id is not None: + # User provided `--run-id`, but not `server-app` + run_id = args.run_id + else: + # User provided `server-app`, but not `--run-id` + # Create run if run_id is not provided + stub.connect() + req = CreateRunRequest(fab_id=args.fab_id, fab_version=args.fab_version) + res = stub.create_run(req) + run_id = res.run_id + + # Initialize GrpcDriver + driver = GrpcDriver(run_id=run_id, stub=stub) + + # Dynamically obtain ServerApp path based on run_id + if args.run_id is not None: + # User provided `--run-id`, but not `server-app` + flwr_dir = get_flwr_dir(args.flwr_dir) + run_ = driver.run + server_app_dir = str(get_project_dir(run_.fab_id, run_.fab_version, flwr_dir)) + config = get_project_config(server_app_dir) + server_app_attr = config["flower"]["components"]["serverapp"] + else: + # User provided `server-app`, but not `--run-id` + server_app_dir = str(Path(args.dir).absolute()) + + log(DEBUG, "Flower will load ServerApp `%s` in %s", server_app_attr, server_app_dir) log( DEBUG, @@ -148,20 +181,6 @@ def run_server_app() -> None: root_certificates, ) - server_app_dir = args.dir - server_app_attr = getattr(args, "server-app") - - # Create run - stub = GrpcDriverStub( - driver_service_address=args.superlink, root_certificates=root_certificates - ) - stub.connect() - req = CreateRunRequest(fab_id=args.fab_id, fab_version=args.fab_version) - res = stub.create_run(req) - - # Initialize GrpcDriver - driver = GrpcDriver(run_id=res.run_id, stub=stub) - # Run the ServerApp with the Driver run(driver=driver, server_app_dir=server_app_dir, server_app_attr=server_app_attr) @@ -179,6 +198,8 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser: parser.add_argument( "server-app", + nargs="?", + default=None, help="For example: `server:app` or `project.package.module:wrapper.app`", ) parser.add_argument( @@ -228,5 +249,22 @@ def _parse_args_run_server_app() -> argparse.ArgumentParser: type=str, help="The version of the FAB used in the run.", ) + parser.add_argument( + "--run-id", + default=None, + type=int, + help="The identifier of the run.", + ) + parser.add_argument( + "--flwr-dir", + default=None, + help="""The path containing installed Flower Apps. + By default, this value is equal to: + + - `$FLWR_HOME/` if `$FLWR_HOME` is defined + - `$XDG_DATA_HOME/.flwr/` if `$XDG_DATA_HOME` is defined + - `$HOME/.flwr/` in all other cases + """, + ) return parser From ccfef792e9308c03f91b80f345091b8658b63afc Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Fri, 21 Jun 2024 14:22:06 +0200 Subject: [PATCH 113/124] feat(datasets) Add telemetry (#3479) --- datasets/doc/source/index.rst | 4 + datasets/doc/source/ref-telemetry.md | 66 ++++++ datasets/flwr_datasets/common/__init__.py | 9 + datasets/flwr_datasets/common/telemetry.py | 224 ++++++++++++++++++ .../flwr_datasets/common/telemetry_test.py | 115 +++++++++ datasets/flwr_datasets/federated_dataset.py | 36 ++- .../comparison_label_distribution.py | 8 + .../visualization/label_distribution.py | 7 + 8 files changed, 467 insertions(+), 2 deletions(-) create mode 100644 datasets/doc/source/ref-telemetry.md create mode 100644 datasets/flwr_datasets/common/telemetry.py create mode 100644 datasets/flwr_datasets/common/telemetry_test.py diff --git a/datasets/doc/source/index.rst b/datasets/doc/source/index.rst index 2144c527f8cd..df248969a849 100644 --- a/datasets/doc/source/index.rst +++ b/datasets/doc/source/index.rst @@ -47,7 +47,11 @@ Information-oriented API reference and other reference material. flwr_datasets +.. toctree:: + :maxdepth: 1 + :caption: Reference docs + ref-telemetry Main features ------------- diff --git a/datasets/doc/source/ref-telemetry.md b/datasets/doc/source/ref-telemetry.md new file mode 100644 index 000000000000..a4fc9b6b0061 --- /dev/null +++ b/datasets/doc/source/ref-telemetry.md @@ -0,0 +1,66 @@ +# Telemetry + +The Flower Datasets open-source project collects **anonymous** usage metrics to make well-informed decisions to improve Flower Datasets. Doing this enables the Flower team to understand how Flower Datasets is used and what challenges users might face. + +**Flower is a friendly framework for collaborative AI and data science.** Staying true to this statement, Flower makes it easy to disable telemetry for users that do not want to share anonymous usage metrics. + +## Principles + +We follow strong principles guarding anonymous usage metrics collection: + +- **Optional:** You will always be able to disable telemetry; read on to learn “[How to opt-out](#how-to-opt-out)”. +- **Anonymous:** The reported usage metrics are anonymous and do not contain any personally identifiable information (PII). See “[Collected metrics](#collected-metrics)” to understand what metrics are being reported. +- **Transparent:** You can easily inspect what anonymous metrics are being reported; see the section “[How to inspect what is being reported](#how-to-inspect-what-is-being-reported)” +- **Open for feedback:** You can always reach out to us if you have feedback; see the section “[How to contact us](#how-to-contact-us)” for details. + +## How to opt-out + +When Flower Datasets starts, it will check for an environment variable called `FLWR_TELEMETRY_ENABLED`. Telemetry can easily be disabled by setting `FLWR_TELEMETRY_ENABLED=0`. Assuming you are using Flower Datasets in a Flower server or client, simply do so by prepending your command as in: + +```bash +FLWR_TELEMETRY_ENABLED=0 python server.py # or client.py +``` + +Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `.bashrc` (or whatever configuration file applies to your environment) to disable Flower Datasets telemetry permanently. + +## Collected metrics + +Flower telemetry collects the following metrics: + +**Flower version.** Understand which versions of Flower Datasets are currently being used. This helps us to decide whether we should invest effort into releasing a patch version for an older version of Flower Datasets or instead use the bandwidth to build new features. + +**Operating system.** Enables us to answer questions such as: *Should we create more guides for Linux, macOS, or Windows?* + +**Python version.** Knowing the Python version helps us, for example, to decide whether we should invest effort into supporting old versions of Python or stop supporting them and start taking advantage of new Python features. + +**Hardware properties.** Understanding the hardware environment that Flower Datasets is being used in helps to decide whether we should, for example, put more effort into supporting low-resource environments. + +**Dataset and Partitioners names.** Knowing what datasets and Partitioners are used enables us to provide more detailed code examples and tutorials and better prioritize work on development and support for them. + +**Cluster.** Flower telemetry assigns a random in-memory cluster ID each time a Flower workload starts. This allows us to understand which device types not only start Flower workloads but also successfully complete them. + +**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/source` the first time a telemetry event is generated. The source ID is important to identify whether an issue is recurring or whether an issue is triggered by multiple clusters running concurrently (which often happens in simulation). For example, if a device runs multiple workloads at the same time, and this results in an issue, then, in order to reproduce the issue, multiple workloads must be started at the same time. + +You may delete the source ID at any time. If you wish for all events logged under a specific source ID to be deleted, you can send a deletion request mentioning the source ID to `telemetry@flower.ai`. All events related to that source ID will then be permanently deleted. + +We will not collect any personally identifiable information. If you think any of the metrics collected could be misused in any way, please [get in touch with us](#how-to-contact-us). We will update this page to reflect any changes to the metrics collected and publish changes in the changelog. + +If you think other metrics would be helpful for us to better guide our decisions, please let us know! We will carefully review them; if we are confident that they do not compromise user privacy, we may add them. + +## How to inspect what is being reported + +We wanted to make it very easy for you to inspect what anonymous usage metrics are reported. You can view all the reported telemetry information by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is disabled by default. You may use logging independently from `FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature without sending any metrics. + +```bash +FLWR_TELEMETRY_LOGGING=1 python server.py # or client.py +``` + +The inspect Flower telemetry without sending any anonymous usage metrics, use both environment variables: + +```bash +FLWR_TELEMETRY_ENABLED=0 FLWR_TELEMETRY_LOGGING=1 python server.py # or client.py +``` + +## How to contact us + +We want to hear from you. If you have any feedback or ideas on how to improve the way we handle anonymous usage metrics, reach out to us via [Slack](https://flower.ai/join-slack/) (channel `#telemetry`) or email (`telemetry@flower.ai`). diff --git a/datasets/flwr_datasets/common/__init__.py b/datasets/flwr_datasets/common/__init__.py index b4f12f8641b3..efb4eaf55b70 100644 --- a/datasets/flwr_datasets/common/__init__.py +++ b/datasets/flwr_datasets/common/__init__.py @@ -13,3 +13,12 @@ # limitations under the License. # ============================================================================== """Common components in Flower Datasets.""" + + +from .telemetry import EventType as EventType +from .telemetry import event as event + +__all__ = [ + "EventType", + "event", +] diff --git a/datasets/flwr_datasets/common/telemetry.py b/datasets/flwr_datasets/common/telemetry.py new file mode 100644 index 000000000000..ca484fdda73f --- /dev/null +++ b/datasets/flwr_datasets/common/telemetry.py @@ -0,0 +1,224 @@ +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Flower telemetry.""" + + +import datetime +import json +import logging +import os +import platform +import urllib.request +import uuid +from concurrent.futures import Future, ThreadPoolExecutor +from enum import Enum, auto +from pathlib import Path +from typing import Any, Dict, List, Optional, Union, cast + +from flwr_datasets.common.version import package_name, package_version + +FLWR_TELEMETRY_ENABLED = os.getenv("FLWR_TELEMETRY_ENABLED", "1") +FLWR_TELEMETRY_LOGGING = os.getenv("FLWR_TELEMETRY_LOGGING", "0") + +TELEMETRY_EVENTS_URL = "https://telemetry.flower.ai/api/v1/event" + +LOGGER_NAME = "flwr-datasets-telemetry" +LOGGER_LEVEL = logging.DEBUG + + +def _configure_logger(log_level: int) -> None: + console_handler = logging.StreamHandler() + console_handler.setLevel(log_level) + console_handler.setFormatter( + logging.Formatter( + "%(levelname)s %(name)s %(asctime)s | %(filename)s:%(lineno)d | %(message)s" + ) + ) + + logger = logging.getLogger(LOGGER_NAME) + logger.setLevel(log_level) + logger.addHandler(console_handler) + + +_configure_logger(LOGGER_LEVEL) + + +def log(msg: Union[str, Exception]) -> None: + """Log message using logger at DEBUG level.""" + logging.getLogger(LOGGER_NAME).log(LOGGER_LEVEL, msg) + + +def _get_home() -> Path: + return Path().home() + + +def _get_source_id() -> str: + """Get existing or new source ID.""" + source_id = "unavailable" + # Check if .flwr in home exists + try: + home = _get_home() + except RuntimeError: + # If the home directory can’t be resolved, RuntimeError is raised. + return source_id + + flwr_dir = home.joinpath(".flwr") + # Create .flwr directory if it does not exist yet. + try: + flwr_dir.mkdir(parents=True, exist_ok=True) + except PermissionError: + return source_id + + source_file = flwr_dir.joinpath("source") + + # If no source_file exists create one and write it + if not source_file.exists(): + try: + source_file.touch(exist_ok=True) + source_file.write_text(str(uuid.uuid4()), encoding="utf-8") + except PermissionError: + return source_id + + source_id = source_file.read_text(encoding="utf-8").strip() + + try: + uuid.UUID(source_id) + except ValueError: + source_id = "invalid" + + return source_id + + +# Using str as first base type to make it JSON serializable as +# otherwise the following exception will be thrown when serializing +# the event dict: +# TypeError: Object of type EventType is not JSON serializable +class EventType(str, Enum): + """Types of telemetry events.""" + + # This method combined with auto() will set the property value to + # the property name e.g. + # `START_CLIENT = auto()` becomes `START_CLIENT = "START_CLIENT"` + # The type signature is not compatible with mypy, pylint and flake8 + # so each of those needs to be disabled for this line. + # pylint: disable-next=no-self-argument,arguments-differ,line-too-long + def _generate_next_value_(name: str, start: int, count: int, last_values: List[Any]) -> Any: # type: ignore # noqa: E501 + return name + + PING = auto() + + LOAD_PARTITION_CALLED = auto() + LOAD_SPLIT_CALLED = auto() + PLOT_LABEL_DISTRIBUTION_CALLED = auto() + PLOT_COMPARISON_LABEL_DISTRIBUTION_CALLED = auto() + + +# Use the ThreadPoolExecutor with max_workers=1 to have a queue +# and also ensure that telemetry calls are not blocking. +state: Dict[str, Union[Optional[str], Optional[ThreadPoolExecutor]]] = { + # Will be assigned ThreadPoolExecutor(max_workers=1) + # in event() the first time it's required + "executor": None, + "source": None, + "cluster": None, +} + + +# In Python 3.7 pylint will throw an error stating that +# "Value 'Future' is unsubscriptable". +# This pylint disable line can be remove when dropping support +# for Python 3.7 +# pylint: disable-next=unsubscriptable-object +def event( + event_type: EventType, + event_details: Optional[Dict[str, Any]] = None, +) -> Future: # type: ignore + """Submit create_event to ThreadPoolExecutor to avoid blocking.""" + if state["executor"] is None: + state["executor"] = ThreadPoolExecutor(max_workers=1) + + executor: ThreadPoolExecutor = cast(ThreadPoolExecutor, state["executor"]) + + result = executor.submit(create_event, event_type, event_details) + return result + + +def create_event(event_type: EventType, event_details: Optional[Dict[str, Any]]) -> str: + """Create telemetry event.""" + if state["source"] is None: + state["source"] = _get_source_id() + + if state["cluster"] is None: + state["cluster"] = str(uuid.uuid4()) + + if event_details is None: + event_details = {} + + date = datetime.datetime.now(tz=datetime.timezone.utc).isoformat() + context = { + "source": state["source"], + "cluster": state["cluster"], + "date": date, + "package": { + "package_name": package_name, + "package_version": package_version, + }, + "hw": { + "cpu_count": os.cpu_count(), + }, + "platform": { + "system": platform.system(), + "release": platform.release(), + "platform": platform.platform(), + "python_implementation": platform.python_implementation(), + "python_version": platform.python_version(), + "machine": platform.machine(), + "architecture": platform.architecture(), + "version": platform.uname().version, + }, + } + payload = { + "event_type": event_type, + "event_details": event_details, + "context": context, + } + payload_json = json.dumps(payload) + if FLWR_TELEMETRY_LOGGING == "1": + log(" - ".join([date, "POST", payload_json])) + + # If telemetry is not disabled with setting FLWR_TELEMETRY_ENABLED=0 + # create a request and send it to the telemetry backend + if FLWR_TELEMETRY_ENABLED == "1": + request = urllib.request.Request( + url=TELEMETRY_EVENTS_URL, + data=payload_json.encode("utf-8"), + headers={ + "User-Agent": f"{package_name}/{package_version}", + "Content-Type": "application/json", + }, + method="POST", + ) + try: + with urllib.request.urlopen(request, timeout=60) as response: + result = response.read() + + response_json: str = result.decode("utf-8") + + return response_json + except urllib.error.URLError as ex: + if FLWR_TELEMETRY_LOGGING == "1": + log(ex) + + return "disabled" diff --git a/datasets/flwr_datasets/common/telemetry_test.py b/datasets/flwr_datasets/common/telemetry_test.py new file mode 100644 index 000000000000..f46b7b9a2ddf --- /dev/null +++ b/datasets/flwr_datasets/common/telemetry_test.py @@ -0,0 +1,115 @@ +# Copyright 2023 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Telemetry tests.""" + + +import time +import unittest +from typing import Callable +from unittest import mock + +from flwr_datasets.common.telemetry import EventType, _get_source_id, event + + +class TelemetryTest(unittest.TestCase): + """Tests for the telemetry module.""" + + @mock.patch("flwr_datasets.common.telemetry.FLWR_TELEMETRY_ENABLED", "1") + def test_event(self) -> None: + """Test if sending works against the actual API.""" + # Prepare + expected = '{\n "status": "created"\n}' + + # Execute + future = event(EventType.PING) + actual = future.result() + + # Assert + self.assertEqual(actual, expected) + + @mock.patch("flwr_datasets.common.telemetry.FLWR_TELEMETRY_ENABLED", "1") + def test_not_blocking(self) -> None: + """Test if the code is blocking. + + If the code does not block duration_actual should be less than + 0.001s. + """ + # Prepare + # Use 0.1ms as any blocking networked call would take longer. + duration_max = 0.001 + start = time.time() + + # Execute + event(EventType.PING) + duration_actual = time.time() - start + + # Assert + self.assertLess(duration_actual, duration_max) + + @mock.patch("flwr_datasets.common.telemetry.FLWR_TELEMETRY_ENABLED", "0") + def test_telemetry_disabled(self) -> None: + """Test opt-out.""" + # Prepare + expected = "disabled" + + # Execute + future = event(EventType.PING) + actual = future.result() + + # Assert + self.assertEqual(actual, expected) + + def test_get_source_id(self) -> None: + """Test if _get_source_id returns an ID successfully. + + This test might fail if the UNIX user invoking the test has no home directory. + """ + # Prepare + # nothing to prepare + + # Execute + source_id = _get_source_id() + + # Assert + # source_id should be len 36 as it's a uuid4 in the current + # implementation + self.assertIsNotNone(source_id) + self.assertEqual(len(source_id), 36) + + def test_get_source_id_no_home(self) -> None: + """Test if _get_source_id returns unavailable without a home dir.""" + + # Prepare + def new_callable() -> Callable[[], None]: + def _new_failing_get_home() -> None: + raise RuntimeError + + return _new_failing_get_home + + except_value = "unavailable" + + # Execute + with mock.patch( + "flwr_datasets.common.telemetry._get_home", + new_callable=new_callable, + ): + source_id = _get_source_id() + + # Assert + self.assertEqual(source_id, except_value) + + +if __name__ == "__main__": + unittest.main() diff --git a/datasets/flwr_datasets/federated_dataset.py b/datasets/flwr_datasets/federated_dataset.py index 5d98d01d4941..bbc6e99b651e 100644 --- a/datasets/flwr_datasets/federated_dataset.py +++ b/datasets/flwr_datasets/federated_dataset.py @@ -19,6 +19,7 @@ import datasets from datasets import Dataset, DatasetDict +from flwr_datasets.common import EventType, event from flwr_datasets.partitioner import Partitioner from flwr_datasets.preprocessor import Preprocessor from flwr_datasets.utils import ( @@ -102,6 +103,9 @@ def __init__( self._dataset: Optional[DatasetDict] = None # Indicate if the dataset is prepared for `load_partition` or `load_split` self._dataset_prepared: bool = False + self._event = { + "load_partition": {split: False for split in self._partitioners}, + } def load_partition( self, @@ -141,7 +145,20 @@ def load_partition( self._check_if_split_possible_to_federate(split) partitioner: Partitioner = self._partitioners[split] self._assign_dataset_to_partitioner(split) - return partitioner.load_partition(partition_id) + partition = partitioner.load_partition(partition_id) + if not self._event["load_partition"][split]: + event( + EventType.LOAD_PARTITION_CALLED, + { + "federated_dataset_id": id(self), + "dataset_name": self._dataset_name, + "split": split, + "partitioner": partitioner.__class__.__name__, + "num_partitions": partitioner.num_partitions, + }, + ) + self._event["load_partition"][split] = True + return partition def load_split(self, split: str) -> Dataset: """Load the full split of the dataset. @@ -164,7 +181,20 @@ def load_split(self, split: str) -> Dataset: if self._dataset is None: raise ValueError("Dataset is not loaded yet.") self._check_if_split_present(split) - return self._dataset[split] + dataset_split = self._dataset[split] + + if not self._event["load_split"][split]: + event( + EventType.LOAD_SPLIT_CALLED, + { + "federated_dataset_id": id(self), + "dataset_name": self._dataset_name, + "split": split, + }, + ) + self._event["load_split"][split] = True + + return dataset_split @property def partitioners(self) -> Dict[str, Partitioner]: @@ -246,6 +276,8 @@ def _prepare_dataset(self) -> None: self._dataset = self._dataset.shuffle(seed=self._seed) if self._preprocessor: self._dataset = self._preprocessor(self._dataset) + available_splits = list(self._dataset.keys()) + self._event["load_split"] = {split: False for split in available_splits} self._dataset_prepared = True def _check_if_no_split_keyword_possible(self) -> None: diff --git a/datasets/flwr_datasets/visualization/comparison_label_distribution.py b/datasets/flwr_datasets/visualization/comparison_label_distribution.py index d59f8c47986d..554f6d78d59a 100644 --- a/datasets/flwr_datasets/visualization/comparison_label_distribution.py +++ b/datasets/flwr_datasets/visualization/comparison_label_distribution.py @@ -23,6 +23,7 @@ from matplotlib.axes import Axes from matplotlib.figure import Figure +from flwr_datasets.common import EventType, event from flwr_datasets.partitioner import Partitioner from flwr_datasets.visualization.constants import PLOT_TYPES from flwr_datasets.visualization.label_distribution import plot_label_distributions @@ -132,6 +133,13 @@ def plot_comparison_label_distribution( >>> titles=[f"Concentration = {alpha}" for alpha in alpha_list], >>> ) """ + event( + EventType.PLOT_COMPARISON_LABEL_DISTRIBUTION_CALLED, + { + "num_compare": len(partitioner_list), + "plot_type": plot_type, + }, + ) num_partitioners = len(partitioner_list) if isinstance(label_name, str): label_name = [label_name] * num_partitioners diff --git a/datasets/flwr_datasets/visualization/label_distribution.py b/datasets/flwr_datasets/visualization/label_distribution.py index 940b0e8f91bd..0c47bd204a17 100644 --- a/datasets/flwr_datasets/visualization/label_distribution.py +++ b/datasets/flwr_datasets/visualization/label_distribution.py @@ -22,6 +22,7 @@ from matplotlib.axes import Axes from matplotlib.figure import Figure +from flwr_datasets.common import EventType, event from flwr_datasets.metrics.utils import compute_counts, compute_frequencies from flwr_datasets.partitioner import Partitioner from flwr_datasets.visualization.bar_plot import _plot_bar @@ -191,6 +192,12 @@ def plot_label_distributions( You can also visualize the returned DataFrame in Jupyter Notebook >>> dataframe.style.background_gradient(axis=None) """ + event( + EventType.PLOT_LABEL_DISTRIBUTION_CALLED, + { + "plot_type": plot_type, + }, + ) _validate_parameters(plot_type, size_unit, partition_id_axis) dataframe = pd.DataFrame() From 7424b6264cb12be3c26e2885dcb9ff0c0497fb78 Mon Sep 17 00:00:00 2001 From: Yan Gao Date: Fri, 21 Jun 2024 22:42:31 +0800 Subject: [PATCH 114/124] feat(framework) Add FlowerTune templates to `flwr new` (#3587) Co-authored-by: Javier Co-authored-by: Daniel J. Beutel --- src/py/flwr/cli/new/new.py | 130 ++++++++++++++---- .../templates/app/README.flowertune.md.tpl | 56 ++++++++ .../templates/app/code/flwr_tune/__init__.py | 15 ++ .../templates/app/code/flwr_tune/app.py.tpl | 86 ++++++++++++ .../app/code/flwr_tune/client.py.tpl | 124 +++++++++++++++++ .../app/code/flwr_tune/config.yaml.tpl | 34 +++++ .../app/code/flwr_tune/dataset.py.tpl | 57 ++++++++ .../app/code/flwr_tune/models.py.tpl | 59 ++++++++ .../app/code/flwr_tune/server.py.tpl | 48 +++++++ .../app/code/flwr_tune/static_config.yaml.tpl | 11 ++ .../app/pyproject.flowertune.toml.tpl | 42 ++++++ 11 files changed, 635 insertions(+), 27 deletions(-) create mode 100644 src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl create mode 100644 src/py/flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl create mode 100644 src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl diff --git a/src/py/flwr/cli/new/new.py b/src/py/flwr/cli/new/new.py index 94da99dce36e..9367cf6c9ffb 100644 --- a/src/py/flwr/cli/new/new.py +++ b/src/py/flwr/cli/new/new.py @@ -41,6 +41,16 @@ class MlFramework(str, Enum): HUGGINGFACE = "HF" MLX = "MLX" SKLEARN = "sklearn" + FLOWERTUNE = "FlowerTune" + + +class LlmChallengeName(str, Enum): + """Available LLM challenges.""" + + GENERALNLP = "GeneralNLP" + FINANCE = "Finance" + MEDICAL = "Medical" + CODE = "Code" class TemplateNotFound(Exception): @@ -81,6 +91,7 @@ def render_and_create(file_path: str, template: str, context: Dict[str, str]) -> create_file(file_path, content) +# pylint: disable=too-many-locals,too-many-branches,too-many-statements def new( project_name: Annotated[ Optional[str], @@ -125,6 +136,19 @@ def new( framework_str = framework_str.lower() + if framework_str == "flowertune": + llm_challenge_value = prompt_options( + "Please select LLM challenge by typing in the number", + sorted([challenge.value for challenge in LlmChallengeName]), + ) + selected_value = [ + name + for name, value in vars(LlmChallengeName).items() + if value == llm_challenge_value + ] + llm_challenge_str = selected_value[0] + llm_challenge_str = llm_challenge_str.lower() + print( typer.style( f"\n🔨 Creating Flower project {project_name}...", @@ -139,33 +163,6 @@ def new( import_name = package_name.replace("-", "_") project_dir = os.path.join(cwd, package_name) - # List of files to render - files = { - ".gitignore": {"template": "app/.gitignore.tpl"}, - "README.md": {"template": "app/README.md.tpl"}, - "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"}, - f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"}, - f"{import_name}/server.py": { - "template": f"app/code/server.{framework_str}.py.tpl" - }, - f"{import_name}/client.py": { - "template": f"app/code/client.{framework_str}.py.tpl" - }, - } - - # Depending on the framework, generate task.py file - frameworks_with_tasks = [ - MlFramework.PYTORCH.value.lower(), - MlFramework.JAX.value.lower(), - MlFramework.HUGGINGFACE.value.lower(), - MlFramework.MLX.value.lower(), - MlFramework.TENSORFLOW.value.lower(), - ] - if framework_str in frameworks_with_tasks: - files[f"{import_name}/task.py"] = { - "template": f"app/code/task.{framework_str}.py.tpl" - } - context = { "project_name": project_name, "package_name": package_name, @@ -173,6 +170,85 @@ def new( "username": username, } + # List of files to render + if framework_str == "flowertune": + files = { + ".gitignore": {"template": "app/.gitignore.tpl"}, + "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"}, + "README.md": {"template": f"app/README.{framework_str}.md.tpl"}, + f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"}, + f"{import_name}/server.py": { + "template": "app/code/flwr_tune/server.py.tpl" + }, + f"{import_name}/client.py": { + "template": "app/code/flwr_tune/client.py.tpl" + }, + f"{import_name}/app.py": {"template": "app/code/flwr_tune/app.py.tpl"}, + f"{import_name}/models.py": { + "template": "app/code/flwr_tune/models.py.tpl" + }, + f"{import_name}/dataset.py": { + "template": "app/code/flwr_tune/dataset.py.tpl" + }, + f"{import_name}/conf/config.yaml": { + "template": "app/code/flwr_tune/config.yaml.tpl" + }, + f"{import_name}/conf/static_config.yaml": { + "template": "app/code/flwr_tune/static_config.yaml.tpl" + }, + } + + # Challenge specific context + fraction_fit = "0.2" if llm_challenge_str == "code" else "0.1" + if llm_challenge_str == "generalnlp": + challenge_name = "General NLP" + num_clients = "20" + dataset_name = "vicgalle/alpaca-gpt4" + elif llm_challenge_str == "finance": + challenge_name = "Finance" + num_clients = "50" + dataset_name = "FinGPT/fingpt-sentiment-train" + elif llm_challenge_str == "medical": + challenge_name = "Medical" + num_clients = "20" + dataset_name = "medalpaca/medical_meadow_medical_flashcards" + else: + challenge_name = "Code" + num_clients = "10" + dataset_name = "lucasmccabe-lmi/CodeAlpaca-20k" + + context["llm_challenge_str"] = llm_challenge_str + context["fraction_fit"] = fraction_fit + context["challenge_name"] = challenge_name + context["num_clients"] = num_clients + context["dataset_name"] = dataset_name + else: + files = { + ".gitignore": {"template": "app/.gitignore.tpl"}, + "README.md": {"template": "app/README.md.tpl"}, + "pyproject.toml": {"template": f"app/pyproject.{framework_str}.toml.tpl"}, + f"{import_name}/__init__.py": {"template": "app/code/__init__.py.tpl"}, + f"{import_name}/server.py": { + "template": f"app/code/server.{framework_str}.py.tpl" + }, + f"{import_name}/client.py": { + "template": f"app/code/client.{framework_str}.py.tpl" + }, + } + + # Depending on the framework, generate task.py file + frameworks_with_tasks = [ + MlFramework.PYTORCH.value.lower(), + MlFramework.JAX.value.lower(), + MlFramework.HUGGINGFACE.value.lower(), + MlFramework.MLX.value.lower(), + MlFramework.TENSORFLOW.value.lower(), + ] + if framework_str in frameworks_with_tasks: + files[f"{import_name}/task.py"] = { + "template": f"app/code/task.{framework_str}.py.tpl" + } + for file_path, value in files.items(): render_and_create( file_path=os.path.join(project_dir, file_path), diff --git a/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl b/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl new file mode 100644 index 000000000000..2b59937e4130 --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/README.flowertune.md.tpl @@ -0,0 +1,56 @@ +# FlowerTune LLM on $challenge_name Dataset + +This directory conducts federated instruction tuning with a pretrained [Mistral-7B](https://huggingface.co/mistralai/Mistral-7B-v0.3) model on a [$challenge_name dataset](https://huggingface.co/datasets/$dataset_name). +We use [Flower Datasets](https://flower.dev/docs/datasets/) to download, partition and preprocess the dataset. +Flower's Simulation Engine is used to simulate the LLM fine-tuning process in federated way, +which allows users to perform the training on a single GPU. + + +## Methodology + +This baseline performs federated LLM fine-tuning with [LoRA](https://arxiv.org/pdf/2106.09685) using the [🤗PEFT](https://huggingface.co/docs/peft/en/index) library. +The clients' models are aggregated with FedAvg strategy. +This provides a baseline performance for the leaderboard of $challenge_name challenge. + + +## Environments setup + +Project dependencies are defined in `pyproject.toml`. Install them in an activated Python environment with: + +```shell +pip install -e . +``` + +## Experimental setup + +The dataset is partitioned into $num_clients shards with IID fashion serving as clients. +We randomly sample $fraction_fit clients to be available for each round, +and the federated fine-tuning lasts for `200` rounds. +All settings are defined in `$project_name/conf/static_config.yaml`, which is not allowed to be modified for fair competition if you plan to participated in the [LLM leaderboard](https://flower.ai/benchmarks/llm-leaderboard). + + +## Running the challenge + +First make sure that you have got the access to [Mistral-7B](https://huggingface.co/mistralai/Mistral-7B-v0.3) model with your Hugging-Face account. You can request access directly from the Hugging-Face website. +Then, follow the instruction [here](https://huggingface.co/docs/huggingface_hub/en/quick-start#login-command) to log in your account. Note you only need to complete this stage once in your development machine: + +```bash +huggingface-cli login +``` + +Run the challenge with default config values. +The configs are in `$project_name/conf/config.yaml` and `$project_name/conf/static_config.yaml`, and are loaded automatically. + +```bash +flwr run +``` + +## VRAM consumption + +We use Mistral-7B model with 4-bit quantization as default. The estimated VRAM consumption per client for each challenge is shown below: + +| Challenges | GeneralNLP | Finance | Medical | Code | +| :--------: | :--------: | :--------: | :--------: | :--------: | +| VRAM | ~25.50 GB | ~17.30 GB | ~22.80 GB | ~17.40 GB | + +You can adjust the CPU/GPU resources you assign to each of the clients based on your device, which is specified with `flower.engine.simulation` in `pyproject.toml`. diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py b/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py new file mode 100644 index 000000000000..6d886f216bc9 --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/__init__.py @@ -0,0 +1,15 @@ +# Copyright 2024 Flower Labs GmbH. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============================================================================== +"""Flower CLI `new` command app / code / flwr_tune templates.""" diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl new file mode 100644 index 000000000000..ecb87bd71e3f --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/app.py.tpl @@ -0,0 +1,86 @@ +"""$project_name: A Flower / FlowerTune app.""" + +import os +import warnings +from datetime import datetime + +from flwr_datasets import FederatedDataset +from hydra import compose, initialize +from hydra.utils import instantiate + +from flwr.client import ClientApp +from flwr.common import ndarrays_to_parameters +from flwr.server import ServerApp, ServerConfig + +from $import_name.client import gen_client_fn, get_parameters +from $import_name.dataset import get_tokenizer_and_data_collator_and_propt_formatting +from $import_name.models import get_model +from $import_name.server import fit_weighted_average, get_evaluate_fn, get_on_fit_config + +# Avoid warnings +warnings.filterwarnings("ignore", category=UserWarning) +os.environ["TOKENIZERS_PARALLELISM"] = "true" +os.environ["RAY_DISABLE_DOCKER_CPU_WARNING"] = "1" + +# Initialise regular config +with initialize(config_path="conf", version_base="1.1"): + cfg = compose(config_name="config") + +# Initialise static config +with initialize(config_path="conf", version_base="1.1"): + cfg_static = compose(config_name="static_config") + +cfg.train.num_rounds = cfg_static.num_rounds + +# Create output directory given current timestamp +current_time = datetime.now() +folder_name = current_time.strftime("%Y-%m-%d_%H-%M-%S") +save_path = os.path.join(os.getcwd(), f"results/{folder_name}") +os.makedirs(save_path, exist_ok=True) + +# Partition dataset and get dataloaders +partitioner = instantiate(cfg_static.partitioner) +fds = FederatedDataset( + dataset=cfg_static.dataset.name, partitioners={"train": partitioner} +) +( + tokenizer, + data_collator, + formatting_prompts_func, +) = get_tokenizer_and_data_collator_and_propt_formatting(cfg.model.name) + +# ClientApp for Flower Next +client = ClientApp( + client_fn=gen_client_fn( + fds, + tokenizer, + formatting_prompts_func, + data_collator, + cfg.model, + cfg.train, + save_path, + ), +) + +# Get initial model weights +init_model = get_model(cfg.model) +init_model_parameters = get_parameters(init_model) +init_model_parameters = ndarrays_to_parameters(init_model_parameters) + +# Instantiate strategy according to config. Here we pass other arguments +# that are only defined at runtime. +strategy = instantiate( + cfg.strategy, + on_fit_config_fn=get_on_fit_config(), + fit_metrics_aggregation_fn=fit_weighted_average, + initial_parameters=init_model_parameters, + evaluate_fn=get_evaluate_fn( + cfg.model, cfg.train.save_every_round, cfg_static.num_rounds, save_path + ), +) + +# ServerApp for Flower Next +server = ServerApp( + config=ServerConfig(num_rounds=cfg_static.num_rounds), + strategy=strategy, +) diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl new file mode 100644 index 000000000000..c0d5842964fd --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/client.py.tpl @@ -0,0 +1,124 @@ +"""$project_name: A Flower / FlowerTune app.""" + +from collections import OrderedDict +from typing import Callable, Dict, Tuple + +import torch +from omegaconf import DictConfig +from peft import get_peft_model_state_dict, set_peft_model_state_dict +from transformers import TrainingArguments +from trl import SFTTrainer + +from flwr.client import NumPyClient +from flwr.common.typing import NDArrays, Scalar +from $import_name.dataset import reformat +from $import_name.models import cosine_annealing, get_model + + +# pylint: disable=too-many-arguments +# pylint: disable=too-many-instance-attributes +class FlowerClient(NumPyClient): + """Standard Flower client for CNN training.""" + + def __init__( + self, + model_cfg: DictConfig, + train_cfg: DictConfig, + trainset, + tokenizer, + formatting_prompts_func, + data_collator, + save_path, + ): # pylint: disable=too-many-arguments + self.device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") + self.train_cfg = train_cfg + self.training_argumnets = TrainingArguments(**train_cfg.training_arguments) + self.tokenizer = tokenizer + self.formatting_prompts_func = formatting_prompts_func + self.data_collator = data_collator + self.save_path = save_path + + # instantiate model + self.model = get_model(model_cfg) + + self.trainset = trainset + + def fit( + self, parameters: NDArrays, config: Dict[str, Scalar] + ) -> Tuple[NDArrays, int, Dict]: + """Implement distributed fit function for a given client.""" + set_parameters(self.model, parameters) + + new_lr = cosine_annealing( + int(config["current_round"]), + self.train_cfg.num_rounds, + self.train_cfg.learning_rate_max, + self.train_cfg.learning_rate_min, + ) + + self.training_argumnets.learning_rate = new_lr + self.training_argumnets.output_dir = self.save_path + + # Construct trainer + trainer = SFTTrainer( + model=self.model, + tokenizer=self.tokenizer, + args=self.training_argumnets, + max_seq_length=self.train_cfg.seq_length, + train_dataset=self.trainset, + formatting_func=self.formatting_prompts_func, + data_collator=self.data_collator, + ) + + # Do local training + results = trainer.train() + + return ( + get_parameters(self.model), + len(self.trainset), + {"train_loss": results.training_loss}, + ) + + +def set_parameters(model, parameters: NDArrays) -> None: + """Change the parameters of the model using the given ones.""" + peft_state_dict_keys = get_peft_model_state_dict(model).keys() + params_dict = zip(peft_state_dict_keys, parameters) + state_dict = OrderedDict({k: torch.Tensor(v) for k, v in params_dict}) + set_peft_model_state_dict(model, state_dict) + + +def get_parameters(model) -> NDArrays: + """Return the parameters of the current net.""" + state_dict = get_peft_model_state_dict(model) + return [val.cpu().numpy() for _, val in state_dict.items()] + + +def gen_client_fn( + fds, + tokenizer, + formatting_prompts_func, + data_collator, + model_cfg: DictConfig, + train_cfg: DictConfig, + save_path: str, +) -> Callable[[str], FlowerClient]: # pylint: disable=too-many-arguments + """Generate the client function that creates the Flower Clients.""" + + def client_fn(cid: str) -> FlowerClient: + """Create a Flower client representing a single organization.""" + # Let's get the partition corresponding to the i-th client + client_trainset = fds.load_partition(int(cid), "train") + client_trainset = reformat(client_trainset, llm_task="$llm_challenge_str") + + return FlowerClient( + model_cfg, + train_cfg, + client_trainset, + tokenizer, + formatting_prompts_func, + data_collator, + save_path, + ).to_client() + + return client_fn diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl new file mode 100644 index 000000000000..9f700dd5b8da --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/config.yaml.tpl @@ -0,0 +1,34 @@ +# Federated Instruction Tuning +--- +model: + name: "mistralai/Mistral-7B-v0.3" + quantization: 4 # 8 or 4 if you want to do quantization with BitsAndBytes + gradient_checkpointing: True + lora: + peft_lora_r: 32 + peft_lora_alpha: 64 + +train: + num_rounds: null + save_every_round: 5 + learning_rate_max: 5e-5 + learning_rate_min: 1e-6 + seq_length: 512 + training_arguments: + output_dir: null # to be set by hydra + learning_rate: null # to be set by the client + per_device_train_batch_size: 16 + gradient_accumulation_steps: 1 + logging_steps: 10 + num_train_epochs: 3 + max_steps: 10 + report_to: null + save_steps: 1000 + save_total_limit: 10 + gradient_checkpointing: True + lr_scheduler_type: "constant" + +strategy: + _target_: flwr.server.strategy.FedAvg + fraction_fit: $fraction_fit + fraction_evaluate: 0.0 # no client evaluation diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl new file mode 100644 index 000000000000..1b3691d7cf3c --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/dataset.py.tpl @@ -0,0 +1,57 @@ +"""$project_name: A Flower / FlowerTune app.""" + +from transformers import AutoTokenizer +from trl import DataCollatorForCompletionOnlyLM + + +def formatting_prompts_func(example): + """Construct prompts.""" + output_texts = [] + # Constructing a standard Alpaca + # (https://github.com/tatsu-lab/stanford_alpaca#data-release) prompt + mssg = ( + "Below is an instruction that describes a task. " + "Write a response that appropriately completes the request." + ) + for i in range(len(example["instruction"])): + text = ( + f"{mssg}\n### Instruction:\n{example['instruction'][i]}\n" + f"### Response: {example['response'][i]}" + ) + output_texts.append(text) + return output_texts + + +def get_tokenizer_and_data_collator_and_propt_formatting(model_name: str): + """Get tokenizer, data_collator and prompt formatting.""" + # From: https://huggingface.co/docs/trl/en/sft_trainer + tokenizer = AutoTokenizer.from_pretrained( + model_name, use_fast=True, padding_side="right" + ) + tokenizer.pad_token = tokenizer.eos_token + response_template_with_context = "\n### Response:" # alpaca response tag + response_template_ids = tokenizer.encode( + response_template_with_context, add_special_tokens=False + )[2:] + data_collator = DataCollatorForCompletionOnlyLM( + response_template_ids, tokenizer=tokenizer + ) + + return tokenizer, data_collator, formatting_prompts_func + + +def formatting(dataset): + """Format dataset.""" + dataset["instruction"] = dataset["instruction"] + " " + dataset["input"] + return dataset + + +def reformat(dataset, llm_task): + """Reformat datasets.""" + dataset = dataset.rename_column("output", "response") + if llm_task == "finance" or llm_task == "code": + dataset = dataset.map(formatting, remove_columns=["input"]) + if llm_task == "medical": + dataset = dataset.remove_columns(["instruction"]) + dataset = dataset.rename_column("input", "instruction") + return dataset diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl new file mode 100644 index 000000000000..a2794f35518c --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/models.py.tpl @@ -0,0 +1,59 @@ +"""$project_name: A Flower / FlowerTune app.""" + +import math + +import torch +from omegaconf import DictConfig +from peft import LoraConfig, get_peft_model +from peft.utils import prepare_model_for_kbit_training +from transformers import AutoModelForCausalLM, BitsAndBytesConfig + + +def cosine_annealing( + current_round: int, + total_round: int, + lrate_max: float = 0.001, + lrate_min: float = 0.0, +) -> float: + """Implement cosine annealing learning rate schedule.""" + cos_inner = math.pi * current_round / total_round + return lrate_min + 0.5 * (lrate_max - lrate_min) * (1 + math.cos(cos_inner)) + + +def get_model(model_cfg: DictConfig): + """Load model with appropriate quantization config and other optimizations. + + Please refer to this example for `peft + BitsAndBytes`: + https://github.com/huggingface/peft/blob/main/examples/fp4_finetuning/finetune_fp4_opt_bnb_peft.py + """ + if model_cfg.quantization == 4: + quantization_config = BitsAndBytesConfig(load_in_4bit=True) + elif model_cfg.quantization == 8: + quantization_config = BitsAndBytesConfig(load_in_8bit=True) + else: + raise ValueError( + f"Use 4-bit or 8-bit quantization. You passed: {model_cfg.quantization}/" + ) + + model = AutoModelForCausalLM.from_pretrained( + model_cfg.name, + quantization_config=quantization_config, + torch_dtype=torch.bfloat16, + low_cpu_mem_usage=True, + ) + + model = prepare_model_for_kbit_training( + model, use_gradient_checkpointing=model_cfg.gradient_checkpointing + ) + + peft_config = LoraConfig( + r=model_cfg.lora.peft_lora_r, + lora_alpha=model_cfg.lora.peft_lora_alpha, + lora_dropout=0.075, + task_type="CAUSAL_LM", + ) + + if model_cfg.gradient_checkpointing: + model.config.use_cache = False + + return get_peft_model(model, peft_config) diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl new file mode 100644 index 000000000000..19223148bca5 --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/server.py.tpl @@ -0,0 +1,48 @@ +"""$project_name: A Flower / FlowerTune app.""" + +from $import_name.client import set_parameters +from $import_name.models import get_model + + +# Get function that will be executed by the strategy's evaluate() method +# Here we use it to save global model checkpoints +def get_evaluate_fn(model_cfg, save_every_round, total_round, save_path): + """Return an evaluation function for saving global model.""" + + def evaluate(server_round: int, parameters, config): + # Save model + if server_round != 0 and ( + server_round == total_round or server_round % save_every_round == 0 + ): + # Init model + model = get_model(model_cfg) + set_parameters(model, parameters) + + model.save_pretrained(f"{save_path}/peft_{server_round}") + + return 0.0, {} + + return evaluate + + +def get_on_fit_config(): + """ + Return a function that will be used to construct the config + that the client's fit() method will receive. + """ + + def fit_config_fn(server_round: int): + fit_config = {"current_round": server_round} + return fit_config + + return fit_config_fn + + +def fit_weighted_average(metrics): + """Aggregate (federated) evaluation metrics.""" + # Multiply accuracy of each client by number of examples used + losses = [num_examples * m["train_loss"] for num_examples, m in metrics] + examples = [num_examples for num_examples, _ in metrics] + + # Aggregate and return custom metric (weighted average) + return {"train_loss": sum(losses) / sum(examples)} diff --git a/src/py/flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl b/src/py/flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl new file mode 100644 index 000000000000..a8a4039fc831 --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/code/flwr_tune/static_config.yaml.tpl @@ -0,0 +1,11 @@ +# Federated Instruction Tuning (static) +--- +dataset: + name: $dataset_name + +# FL experimental settings +num_clients: $num_clients # total number of clients +num_rounds: 200 +partitioner: + _target_: flwr_datasets.partitioner.IidPartitioner + num_partitions: $num_clients diff --git a/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl b/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl new file mode 100644 index 000000000000..2ed6bd36fd89 --- /dev/null +++ b/src/py/flwr/cli/new/templates/app/pyproject.flowertune.toml.tpl @@ -0,0 +1,42 @@ +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[project] +name = "$package_name" +version = "1.0.0" +description = "" +authors = [ + { name = "The Flower Authors", email = "hello@flower.ai" }, +] +license = { text = "Apache License (2.0)" } +dependencies = [ + "flwr[simulation]>=1.9.0,<2.0", + "flwr-datasets>=0.1.0,<1.0.0", + "hydra-core==1.3.2", + "trl==0.8.1", + "bitsandbytes==0.43.0", + "scipy==1.13.0", + "peft==0.6.2", + "transformers==4.39.3", + "sentencepiece==0.2.0", +] + +[tool.hatch.build.targets.wheel] +packages = ["."] + +[flower] +publisher = "$username" + +[flower.components] +serverapp = "$import_name.app:server" +clientapp = "$import_name.app:client" + +[flower.engine] +name = "simulation" + +[flower.engine.simulation.supernode] +num = $num_clients + +[flower.engine.simulation] +backend_config = { client_resources = { num_cpus = 8, num_gpus = 1.0 } } From 0c9fe5e3734e876f37d94cbbe2f633353a07d099 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Fri, 21 Jun 2024 16:55:58 +0200 Subject: [PATCH 115/124] Disable telemetry in datasets.yml workflow (#3667) --- .github/workflows/datasets.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/datasets.yml b/.github/workflows/datasets.yml index 47e9f2aed926..80cece262754 100644 --- a/.github/workflows/datasets.yml +++ b/.github/workflows/datasets.yml @@ -16,6 +16,9 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref == 'refs/heads/main' && github.run_id || github.event.pull_request.number || github.ref }} cancel-in-progress: true +env: + FLWR_TELEMETRY_ENABLED: 0 + defaults: run: working-directory: datasets From 5480b6ac2020ce8ef150c872da990bdb10806d07 Mon Sep 17 00:00:00 2001 From: Mohammad Naseri Date: Fri, 21 Jun 2024 17:52:01 +0200 Subject: [PATCH 116/124] Remove extra space (#3669) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 16cb7f1cfaf6..5f61d616775b 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ Other [examples](https://github.com/adap/flower/tree/main/examples): - [Flower with KaplanMeierFitter from the lifelines library](https://github.com/adap/flower/tree/main/examples/federated-kaplan-meier-fitter) - [Sample Level Privacy with Opacus](https://github.com/adap/flower/tree/main/examples/opacus) - [Sample Level Privacy with TensorFlow-Privacy](https://github.com/adap/flower/tree/main/examples/tensorflow-privacy) -- [Flower with a Tabular Dataset] (https://github.com/adap/flower/tree/main/examples/fl-tabular) +- [Flower with a Tabular Dataset](https://github.com/adap/flower/tree/main/examples/fl-tabular) ## Community From 87a305cd68babca4c6c6f0c72798e68a9e52fbf9 Mon Sep 17 00:00:00 2001 From: Sebastian van der Voort Date: Fri, 21 Jun 2024 22:03:39 +0200 Subject: [PATCH 117/124] feat(framework) Parse initialization arguments to `ray` (#3543) Co-authored-by: svdvoort <23049683+Svdvoort@users.noreply.github.com> Co-authored-by: jafermarq --- dev/test.sh | 2 +- .../superlink/fleet/vce/backend/raybackend.py | 69 ++++++++++++------- .../fleet/vce/backend/raybackend_test.py | 33 +++++++++ .../simulation/ray_transport/ray_actor.py | 6 -- src/py/flwr/simulation/run_simulation.py | 54 +++++++++------ 5 files changed, 111 insertions(+), 53 deletions(-) diff --git a/dev/test.sh b/dev/test.sh index 5b827380bc50..8cbe88c9298b 100755 --- a/dev/test.sh +++ b/dev/test.sh @@ -23,7 +23,7 @@ python -m flwr_tool.init_py_check src/py/flwr src/py/flwr_tool echo "- init_py_check: done" echo "- docformatter: start" -python -m docformatter -c -r src/py/flwr e2e -e src/py/flwr/proto +python -m docformatter -c -r src/py/flwr e2e -e src/py/flwr/proto echo "- docformatter: done" echo "- ruff: start" diff --git a/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py b/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py index 93aca583af9c..8a21393db590 100644 --- a/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py +++ b/src/py/flwr/server/superlink/fleet/vce/backend/raybackend.py @@ -15,7 +15,7 @@ """Ray backend for the Fleet API using the Simulation Engine.""" import pathlib -from logging import DEBUG, ERROR, WARNING +from logging import DEBUG, ERROR from typing import Callable, Dict, List, Tuple, Union import ray @@ -24,16 +24,15 @@ from flwr.common.context import Context from flwr.common.logger import log from flwr.common.message import Message -from flwr.simulation.ray_transport.ray_actor import ( - BasicActorPool, - ClientAppActor, - init_ray, -) +from flwr.common.typing import ConfigsRecordValues +from flwr.simulation.ray_transport.ray_actor import BasicActorPool, ClientAppActor from flwr.simulation.ray_transport.utils import enable_tf_gpu_growth from .backend import Backend, BackendConfig ClientResourcesDict = Dict[str, Union[int, float]] +ActorArgsDict = Dict[str, Union[int, float, Callable[[], None]]] +RunTimeEnvDict = Dict[str, Union[str, List[str]]] class RayBackend(Backend): @@ -51,40 +50,29 @@ def __init__( if not pathlib.Path(work_dir).exists(): raise ValueError(f"Specified work_dir {work_dir} does not exist.") - # Init ray and append working dir if needed - runtime_env = ( - self._configure_runtime_env(work_dir=work_dir) if work_dir else None - ) - - if backend_config.get("mute_logging", False): - init_ray( - logging_level=WARNING, log_to_driver=False, runtime_env=runtime_env - ) - elif backend_config.get("silent", False): - init_ray(logging_level=WARNING, log_to_driver=True, runtime_env=runtime_env) - else: - init_ray(runtime_env=runtime_env) + # Initialise ray + self.init_args_key = "init_args" + self.init_ray(backend_config, work_dir) # Validate client resources self.client_resources_key = "client_resources" + client_resources = self._validate_client_resources(config=backend_config) # Create actor pool - use_tf = backend_config.get("tensorflow", False) - actor_kwargs = {"on_actor_init_fn": enable_tf_gpu_growth} if use_tf else {} + actor_kwargs = self._validate_actor_arguments(config=backend_config) - client_resources = self._validate_client_resources(config=backend_config) self.pool = BasicActorPool( actor_type=ClientAppActor, client_resources=client_resources, actor_kwargs=actor_kwargs, ) - def _configure_runtime_env(self, work_dir: str) -> Dict[str, Union[str, List[str]]]: + def _configure_runtime_env(self, work_dir: str) -> RunTimeEnvDict: """Return list of files/subdirectories to exclude relative to work_dir. Without this, Ray will push everything to the Ray Cluster. """ - runtime_env: Dict[str, Union[str, List[str]]] = {"working_dir": work_dir} + runtime_env: RunTimeEnvDict = {"working_dir": work_dir} excludes = [] path = pathlib.Path(work_dir) @@ -125,6 +113,37 @@ def _validate_client_resources(self, config: BackendConfig) -> ClientResourcesDi return client_resources + def _validate_actor_arguments(self, config: BackendConfig) -> ActorArgsDict: + actor_args_config = config.get("actor", False) + actor_args: ActorArgsDict = {} + if actor_args_config: + use_tf = actor_args.get("tensorflow", False) + if use_tf: + actor_args["on_actor_init_fn"] = enable_tf_gpu_growth + return actor_args + + def init_ray(self, backend_config: BackendConfig, work_dir: str) -> None: + """Intialises Ray if not already initialised.""" + if not ray.is_initialized(): + # Init ray and append working dir if needed + runtime_env = ( + self._configure_runtime_env(work_dir=work_dir) if work_dir else None + ) + + ray_init_args: Dict[ + str, + Union[ConfigsRecordValues, RunTimeEnvDict], + ] = {} + + if backend_config.get(self.init_args_key): + for k, v in backend_config[self.init_args_key].items(): + ray_init_args[k] = v + + if runtime_env is not None: + ray_init_args["runtime_env"] = runtime_env + + ray.init(**ray_init_args) + @property def num_workers(self) -> int: """Return number of actors in pool.""" @@ -152,7 +171,7 @@ async def process_message( partition_id = message.metadata.partition_id try: - # Submite a task to the pool + # Submit a task to the pool future = await self.pool.submit( lambda a, a_fn, mssg, cid, state: a.run.remote(a_fn, mssg, cid, state), (app, message, str(partition_id), context), diff --git a/src/py/flwr/server/superlink/fleet/vce/backend/raybackend_test.py b/src/py/flwr/server/superlink/fleet/vce/backend/raybackend_test.py index dcac0b81d666..57c952cc9310 100644 --- a/src/py/flwr/server/superlink/fleet/vce/backend/raybackend_test.py +++ b/src/py/flwr/server/superlink/fleet/vce/backend/raybackend_test.py @@ -38,6 +38,7 @@ ) from flwr.common.object_ref import load_app from flwr.common.recordset_compat import getpropertiesins_to_recordset +from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig from flwr.server.superlink.fleet.vce.backend.raybackend import RayBackend @@ -215,3 +216,35 @@ def test_backend_creation_submit_and_termination_existing_client_app_unsetworkdi workdir="/?&%$^#%@$!", ) self.addAsyncCleanup(self.on_cleanup) + + def test_backend_creation_with_init_arguments(self) -> None: + """Testing whether init args are properly parsed to Ray.""" + backend_config_4: BackendConfig = { + "init_args": {"num_cpus": 4}, + "client_resources": {"num_cpus": 1, "num_gpus": 0}, + } + + backend_config_2: BackendConfig = { + "init_args": {"num_cpus": 2}, + "client_resources": {"num_cpus": 1, "num_gpus": 0}, + } + + RayBackend( + backend_config=backend_config_4, + work_dir="", + ) + nodes = ray.nodes() + + assert nodes[0]["Resources"]["CPU"] == backend_config_4["init_args"]["num_cpus"] + + ray.shutdown() + + RayBackend( + backend_config=backend_config_2, + work_dir="", + ) + nodes = ray.nodes() + + assert nodes[0]["Resources"]["CPU"] == backend_config_2["init_args"]["num_cpus"] + + self.addAsyncCleanup(self.on_cleanup) diff --git a/src/py/flwr/simulation/ray_transport/ray_actor.py b/src/py/flwr/simulation/ray_transport/ray_actor.py index 9caf0fc3e6c0..7afffb865334 100644 --- a/src/py/flwr/simulation/ray_transport/ray_actor.py +++ b/src/py/flwr/simulation/ray_transport/ray_actor.py @@ -399,12 +399,6 @@ def get_client_result( return self._fetch_future_result(cid) -def init_ray(*args: Any, **kwargs: Any) -> None: - """Intialises Ray if not already initialised.""" - if not ray.is_initialized(): - ray.init(*args, **kwargs) - - class BasicActorPool: """A basic actor pool.""" diff --git a/src/py/flwr/simulation/run_simulation.py b/src/py/flwr/simulation/run_simulation.py index a3de1401d252..7c7a412a245b 100644 --- a/src/py/flwr/simulation/run_simulation.py +++ b/src/py/flwr/simulation/run_simulation.py @@ -22,16 +22,17 @@ import traceback from logging import DEBUG, ERROR, INFO, WARNING from time import sleep -from typing import Dict, Optional +from typing import Optional from flwr.client import ClientApp from flwr.common import EventType, event, log from flwr.common.logger import set_logger_propagation, update_console_handler -from flwr.common.typing import ConfigsRecordValues, Run +from flwr.common.typing import Run from flwr.server.driver import Driver, InMemoryDriver from flwr.server.run_serverapp import run from flwr.server.server_app import ServerApp from flwr.server.superlink.fleet import vce +from flwr.server.superlink.fleet.vce.backend.backend import BackendConfig from flwr.server.superlink.state import StateFactory from flwr.simulation.ray_transport.utils import ( enable_tf_gpu_growth as enable_gpu_growth, @@ -66,7 +67,7 @@ def run_simulation( client_app: ClientApp, num_supernodes: int, backend_name: str = "ray", - backend_config: Optional[Dict[str, ConfigsRecordValues]] = None, + backend_config: Optional[BackendConfig] = None, enable_tf_gpu_growth: bool = False, verbose_logging: bool = False, ) -> None: @@ -90,9 +91,12 @@ def run_simulation( backend_name : str (default: ray) A simulation backend that runs `ClientApp`s. - backend_config : Optional[Dict[str, ConfigsRecordValues]] - 'A dictionary, e.g {"": , "": } to configure a - backend. Values supported in are those included by + backend_config : Optional[BackendConfig] + 'A dictionary to configure a backend. Separate dictionaries to configure + different elements of backend. Supported top-level keys are `init_args` + for values parsed to initialisation of backend, `client_resources` + to define the resources for clients, and `actor` to define the actor + parameters. Values supported in are those included by `flwr.common.typing.ConfigsRecordValues`. enable_tf_gpu_growth : bool (default: False) @@ -104,7 +108,7 @@ def run_simulation( works in the TensorFlow documentation: https://www.tensorflow.org/api/stable. verbose_logging : bool (default: False) - When diabled, only INFO, WARNING and ERROR log messages will be shown. If + When disabled, only INFO, WARNING and ERROR log messages will be shown. If enabled, DEBUG-level logs will be displayed. """ _run_simulation( @@ -133,7 +137,7 @@ def run_serverapp_th( def server_th_with_start_checks( # type: ignore tf_gpu_growth: bool, stop_event: asyncio.Event, **kwargs ) -> None: - """Run SeverApp, after check if GPU memory grouwth has to be set. + """Run SeverApp, after check if GPU memory growth has to be set. Upon exception, trigger stop event for Simulation Engine. """ @@ -194,7 +198,7 @@ def _main_loop( ) -> None: """Launch SuperLink with Simulation Engine, then ServerApp on a separate thread. - Everything runs on the main thread or a separate one, depening on whether the main + Everything runs on the main thread or a separate one, depending on whether the main thread already contains a running Asyncio event loop. This is the case if running the Simulation Engine on a Jupyter/Colab notebook. """ @@ -259,7 +263,7 @@ def _run_simulation( client_app: Optional[ClientApp] = None, server_app: Optional[ServerApp] = None, backend_name: str = "ray", - backend_config: Optional[Dict[str, ConfigsRecordValues]] = None, + backend_config: Optional[BackendConfig] = None, client_app_attr: Optional[str] = None, server_app_attr: Optional[str] = None, app_dir: str = "", @@ -286,9 +290,12 @@ def _run_simulation( backend_name : str (default: ray) A simulation backend that runs `ClientApp`s. - backend_config : Optional[Dict[str, ConfigsRecordValues]] - 'A dictionary, e.g {"":, "":} to configure a - backend. Values supported in are those included by + backend_config : Optional[BackendConfig] + 'A dictionary to configure a backend. Separate dictionaries to configure + different elements of backend. Supported top-level keys are `init_args` + for values parsed to initialisation of backend, `client_resources` + to define the resources for clients, and `actor` to define the actor + parameters. Values supported in are those included by `flwr.common.typing.ConfigsRecordValues`. client_app_attr : str @@ -310,30 +317,34 @@ def _run_simulation( A boolean to indicate whether to enable GPU growth on the main thread. This is desirable if you make use of a TensorFlow model on your `ServerApp` while having your `ClientApp` running on the same GPU. Without enabling this, you - might encounter an out-of-memory error becasue TensorFlow by default allocates + might encounter an out-of-memory error because TensorFlow by default allocates all GPU memory. Read mor about how `tf.config.experimental.set_memory_growth()` works in the TensorFlow documentation: https://www.tensorflow.org/api/stable. verbose_logging : bool (default: False) - When diabled, only INFO, WARNING and ERROR log messages will be shown. If + When disabled, only INFO, WARNING and ERROR log messages will be shown. If enabled, DEBUG-level logs will be displayed. """ if backend_config is None: backend_config = {} + if "init_args" not in backend_config: + backend_config["init_args"] = {} + # Set logging level logger = logging.getLogger("flwr") if verbose_logging: update_console_handler(level=DEBUG, timestamps=True, colored=True) else: - backend_config["silent"] = True + backend_config["init_args"]["logging_level"] = WARNING + backend_config["init_args"]["log_to_driver"] = True if enable_tf_gpu_growth: # Check that Backend config has also enabled using GPU growth - use_tf = backend_config.get("tensorflow", False) + use_tf = backend_config.get("actor", {}).get("tensorflow", False) if not use_tf: log(WARNING, "Enabling GPU growth for your backend.") - backend_config["tensorflow"] = True + backend_config["actor"]["tensorflow"] = True # Convert config to original JSON-stream format backend_config_stream = json.dumps(backend_config) @@ -352,7 +363,7 @@ def _run_simulation( server_app_attr, ) # Detect if there is an Asyncio event loop already running. - # If yes, run everything on a separate thread. In environmnets + # If yes, run everything on a separate thread. In environments # like Jupyter/Colab notebooks, there is an event loop present. run_in_thread = False try: @@ -364,7 +375,7 @@ def _run_simulation( run_in_thread = True except RuntimeError: - log(DEBUG, "No asyncio event loop runnig") + log(DEBUG, "No asyncio event loop running") finally: if run_in_thread: @@ -409,7 +420,8 @@ def _parse_args_run_simulation() -> argparse.ArgumentParser: parser.add_argument( "--backend-config", type=str, - default='{"client_resources": {"num_cpus":2, "num_gpus":0.0}, "tensorflow": 0}', + default='{"client_resources": {"num_cpus":2, "num_gpus":0.0},' + '"actor": {"tensorflow": 0}}', help='A JSON formatted stream, e.g \'{"":, "":}\' to ' "configure a backend. Values supported in are those included by " "`flwr.common.typing.ConfigsRecordValues`. ", From b025d8ec35337f35791f97e5a464f582cdb00f10 Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sat, 22 Jun 2024 12:58:01 +0200 Subject: [PATCH 118/124] docs(framework) Add latest Hosted Weblate translation updates (#3671) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 박태현 --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 1993 +++++++++++++----- 1 file changed, 1497 insertions(+), 496 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 9c8d2f5ff19b..74cb5f00589f 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -8,15 +8,16 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-06-17 16:09+0200\n" -"PO-Revision-Date: 2024-06-16 09:09+0000\n" +"PO-Revision-Date: 2024-06-22 10:52+0000\n" "Last-Translator: 박태현 \n" +"Language-Team: Korean \n" "Language: ko\n" -"Language-Team: Korean \n" -"Plural-Forms: nplurals=1; plural=0;\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"X-Generator: Weblate 5.6-rc\n" "Generated-By: Babel 2.15.0\n" #: ../../source/contributor-explanation-architecture.rst:2 @@ -58,7 +59,6 @@ msgid "How to build Docker Flower images locally" msgstr "Docker Flower 이미지를 Locally 구축하는 방법" #: ../../source/contributor-how-to-build-docker-images.rst:4 -#, fuzzy msgid "" "Flower provides pre-made docker images on `Docker Hub " "`_ that include all necessary dependencies" @@ -68,11 +68,12 @@ msgid "" " this guide, we will explain what images exist and how to build them " "locally." msgstr "" -"Flower는 'Docker Hub '_에서 미리 만들어진 Docker " -"이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 ServerApp을 실행하는 데 필요한 모든 " -"dependencies를 포함합니다. 필요한 경우 다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해" -" 처음부터 사용자 정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 이미지들과 이들을 로컬에서 빌드하는 " -"방법에 대해 설명하겠습니다." +"Flower는 'Docker Hub '_에서 미리 만들어진 " +"Docker 이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 " +"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 " +"다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 " +"정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 " +"이미지들과 이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." #: ../../source/contributor-how-to-build-docker-images.rst:10 msgid "" @@ -108,7 +109,6 @@ msgstr "" "디렉토리에서 찾을 수 있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:28 -#, fuzzy msgid "" "Flower Docker images are configured via build arguments. Through build " "arguments, we can make the creation of images more flexible. For example," @@ -118,10 +118,12 @@ msgid "" "available build arguments for each image are listed in one of the tables " "below." msgstr "" -"base 이미지와 SuperLink 이미지 둘 다 빌드 argument들을 통해 구성됩니다. 빌드 argument들을 통해, 빌드를" -" 더 유연하게 만들 수 있습니다. 예를 들어, base 이미지에서 \"PYTHON_VERSION\" 빌드 argument를 사용하여" -" Python 버전을 지정할 수 있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 합니다. 각 " -"이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 있습니다." +"Flower Docker는 빌드 argument를 통해 구성됩니다. 빌드 argument들을 통해, " +"이미지를 보다 유연하게 생성할 수 있습니다. 예를 들어, base 이미지에서 " +"\"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 수 " +"있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 " +"합니다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 " +"있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:35 msgid "Building the base image" @@ -149,12 +151,11 @@ msgstr "예시" #: ../../source/contributor-how-to-build-docker-images.rst:45 msgid "``DISTRO``" -msgstr "" +msgstr "``DISTRO``" #: ../../source/contributor-how-to-build-docker-images.rst:46 -#, fuzzy msgid "The Linux distribution to use as the base image." -msgstr "base 이미지의 Ubuntu 버전." +msgstr "base 이미지 사용을 위한 Linux 배포판." #: ../../source/contributor-how-to-build-docker-images.rst:47 #: ../../source/contributor-how-to-build-docker-images.rst:51 @@ -162,26 +163,23 @@ msgstr "base 이미지의 Ubuntu 버전." #: ../../source/contributor-how-to-build-docker-images.rst:71 #: ../../source/contributor-how-to-build-docker-images.rst:104 msgid "No" -msgstr "" +msgstr "아니오" #: ../../source/contributor-how-to-build-docker-images.rst:48 -#, fuzzy msgid "``ubuntu``" -msgstr "``UBUNTU_VERSION``" +msgstr "``ubuntu``" #: ../../source/contributor-how-to-build-docker-images.rst:49 -#, fuzzy msgid "``DISTRO_VERSION``" -msgstr "``PIP_VERSION``" +msgstr "``DISTRO_VERSION``" #: ../../source/contributor-how-to-build-docker-images.rst:50 msgid "Version of the Linux distribution." -msgstr "" +msgstr "Linux 배포판 버전." #: ../../source/contributor-how-to-build-docker-images.rst:52 -#, fuzzy msgid "``22.04``" -msgstr "``23.0.1``" +msgstr "``22.04``" #: ../../source/contributor-how-to-build-docker-images.rst:53 msgid "``PYTHON_VERSION``" @@ -193,7 +191,7 @@ msgstr "설치 된 ``python`` 버전." #: ../../source/contributor-how-to-build-docker-images.rst:56 msgid "``3.11`` or ``3.11.1``" -msgstr "" +msgstr "``3.11`` 또는 ``3.11.1``" #: ../../source/contributor-how-to-build-docker-images.rst:57 msgid "``PIP_VERSION``" @@ -243,20 +241,20 @@ msgid "``FLWR_PACKAGE``" msgstr "``FLWR_PACKAGE``" #: ../../source/contributor-how-to-build-docker-images.rst:70 -#, fuzzy msgid "The Flower package to be installed." -msgstr "설치 할 PyPI 패키지." +msgstr "설치 할 Flower 패키지." #: ../../source/contributor-how-to-build-docker-images.rst:72 msgid "``flwr`` or ``flwr-nightly``" -msgstr "" +msgstr "``flwr`` 또는 ``flwr-nightly``" #: ../../source/contributor-how-to-build-docker-images.rst:75 -#, fuzzy msgid "" "The following example creates a base Ubuntu/Alpine image with Python " "3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" -msgstr "다음 예시에서는 Python 3.11.0, pip 23.0.1 그리고 setuptools 69.0.2의 base 이미지를 만듭니다:" +msgstr "" +"다음 예시에서는 Python 3.11.0, pip 23.0.1, setuptools 및 Flower 1.8.0으로 " +"기본 Ubuntu/Alpine 이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "" @@ -268,9 +266,8 @@ msgstr "" " 태그도 정할 수 있습니다. 이 값들은 예시일 뿐입니다." #: ../../source/contributor-how-to-build-docker-images.rst:92 -#, fuzzy msgid "Building the SuperLink/SuperNode or ServerApp image" -msgstr "SuperLink 이미지 빌드" +msgstr "SuperLink/SuperNode 또는 ServerApp 이미지 빌드" #: ../../source/contributor-how-to-build-docker-images.rst:102 msgid "``BASE_REPOSITORY``" @@ -281,42 +278,36 @@ msgid "The repository name of the base image." msgstr "base 이미지의 리포지토리 이름." #: ../../source/contributor-how-to-build-docker-images.rst:105 -#, fuzzy msgid "``flwr/base``" -msgstr "``FLWR_PACKAGE``" +msgstr "``flwr/base``" #: ../../source/contributor-how-to-build-docker-images.rst:106 -#, fuzzy msgid "``BASE_IMAGE``" -msgstr "``BASE_REPOSITORY``" +msgstr "``BASE_IMAGE``" #: ../../source/contributor-how-to-build-docker-images.rst:107 -#, fuzzy msgid "The Tag of the Flower base image." -msgstr "base 이미지의 리포지토리 이름." +msgstr "Flower 기본 이미지의 태그." #: ../../source/contributor-how-to-build-docker-images.rst:109 msgid "``1.8.0-py3.10-ubuntu22.04``" -msgstr "" +msgstr "``1.8.0-py3.10-ubuntu22.04``" #: ../../source/contributor-how-to-build-docker-images.rst:111 -#, fuzzy msgid "" "The following example creates a SuperLink/SuperNode or ServerApp image " "with the official Flower base image:" -msgstr "" -"다음 예시에서는 py3.11-ubuntu22.04 및 Flower 1.8.0의 공식 Flower base 이미지로 SuperLink" -" 이미지를 만듭니다:" +msgstr "다음 예시에서는 공식 Flower 기본 이미지로 SuperLink/SuperNode 또는 " +"ServerApp이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:122 -#, fuzzy msgid "" "If you want to use your own base image instead of the official Flower " "base image, all you need to do is set the ``BASE_REPOSITORY`` build " "argument." msgstr "" -"공식 Flower base 이미지 대신 자체 base 이미지를 사용 하길 원한다면, ``BASE_REPOSITORY``, " -"``PYTHON_VERSION`` 및 ``UBUNTU_VERSION`` 빌드 argument들을 설정해야 합니다." +"공식 Flower 기본 이미지 대신 자체 기본 이미지를 사용 하길 원한다면, " +"``BASE_REPOSITORY`` 빌드 argument들을 설정해야 합니다." #: ../../source/contributor-how-to-build-docker-images.rst:133 msgid "After creating the image, we can test whether the image is working:" @@ -818,15 +809,18 @@ msgid "" "This will create a draft release on GitHub containing the correct " "artifacts and the relevant part of the changelog." msgstr "" +"pull request가 병합되면, PR이 병합되는 즉시 버전 번호로 릴리즈 커밋에 태그를 " +"지정합니다:``git tag v`` (버전 번호 앞에 ``v``가 추가된 것을 " +"확인), 그 다음 ``git push --tags``. 이렇게 하면 올바른 아티팩트와 변경 " +"로그의 관련 부분이 포함된 초안 릴리즈가 GitHub에 생성됩니다." #: ../../source/contributor-how-to-release-flower.rst:14 msgid "Check the draft release on GitHub, and if everything is good, publish it." -msgstr "" +msgstr "GitHub에서 릴리즈 초안을 확인하고, 모든 것이 양호하면 게시하세요." #: ../../source/contributor-how-to-release-flower.rst:15 -#, fuzzy msgid "Trigger the CI for building the Docker images." -msgstr "공식 Ubuntu Docker 이미지 버전." +msgstr "Docker 이미지 빌드를 위해 CI를 트리거합니다." #: ../../source/contributor-how-to-release-flower.rst:17 msgid "" @@ -835,124 +829,136 @@ msgid "" "through the UI or via the GitHub CLI. The event requires only one input, " "the Flower version, to be released." msgstr "" +"워크플로우를 트리거하려면 공동 작업자가 GitHub CI에서 ``workflow_dispatch``" +"를 생성해야 합니다. 이 작업은 UI 또는 GitHub CLI 를 통해 수행할 수 있습니다. " +"이벤트는 Flower 버전 한 가지 입력만 필요합니다." #: ../../source/contributor-how-to-release-flower.rst:21 msgid "**Via the UI**" -msgstr "" +msgstr "**UI를 통해서**" #: ../../source/contributor-how-to-release-flower.rst:23 msgid "" "Go to the ``Build docker images`` workflow `page " "`_." msgstr "" +"``Build docker images`` 워크플로우 `페이지 `_로 이동합니다." #: ../../source/contributor-how-to-release-flower.rst:24 msgid "" "Click on the ``Run workflow`` button and type the new version of Flower " "in the ``Version of Flower`` input field." -msgstr "" +msgstr "``Run workflow`` 버튼을 누르고 ``Version of Flower``에 Flower의 새버전을 " +"입력합니다." #: ../../source/contributor-how-to-release-flower.rst:25 msgid "Click on the **green** ``Run workflow`` button." -msgstr "" +msgstr "**초록색**의 ``Run workflow``버튼을 클릭합니다." #: ../../source/contributor-how-to-release-flower.rst:29 msgid "**Via the GitHub CI**" -msgstr "" +msgstr "**GitHub CI를 통해서**" #: ../../source/contributor-how-to-release-flower.rst:31 msgid "" "Make sure you are logged in via ``gh auth login`` and that the current " "working directory is the root of the Flower repository." -msgstr "" +msgstr "``gh auth login``을 통해 로그인 했는지, 현재 작업 디렉토리가 Flower " +"리포지토리의 root인지 확인하세요." #: ../../source/contributor-how-to-release-flower.rst:32 msgid "" "Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" "version=``." msgstr "" +"``gh workflow run docker-images.yml -f flwr-version=``을 통해 " +"워크플로우 를 트리거합니다." #: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" -msgstr "" +msgstr "릴리즈 후에" #: ../../source/contributor-how-to-release-flower.rst:37 msgid "Create a pull request which contains the following changes:" -msgstr "" +msgstr "다음 변경 사항이 포함된 pull request를 만듭니다:" #: ../../source/contributor-how-to-release-flower.rst:39 msgid "Increase the minor version in ``pyproject.toml`` by one." -msgstr "" +msgstr "``pyproject.toml``의 마이너 버전을 하나씩 늘립니다." #: ../../source/contributor-how-to-release-flower.rst:40 msgid "Update all files which contain the current version number if necessary." -msgstr "" +msgstr "필요한 경우 현재 버전 번호가 포함된 모든 파일을 업데이트합니다." #: ../../source/contributor-how-to-release-flower.rst:41 msgid "Add a new ``Unreleased`` section in ``changelog.md``." -msgstr "" +msgstr "``changelog.md``에 ``Unreleased`` 섹션을 새로 추가합니다." #: ../../source/contributor-how-to-release-flower.rst:43 msgid "" "Merge the pull request on the same day (i.e., before a new nightly " "release gets published to PyPI)." -msgstr "" +msgstr "pull request를 같은 날(즉, 새로운 nightly 릴리즈가 PyPI에 게시되기 전에) " +"병합하세요." #: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" -msgstr "" +msgstr "사전 릴리즈 게시" #: ../../source/contributor-how-to-release-flower.rst:49 msgid "Pre-release naming" -msgstr "" +msgstr "사전 릴리즈 이름" #: ../../source/contributor-how-to-release-flower.rst:51 msgid "" "PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" " MUST use one of the following naming patterns:" msgstr "" +"PyPI는 사전 릴리즈(알파, 베타, 릴리스 후보)를 지원합니다. 사전 릴리즈는 " +"반드시 다음 명명 패턴 중 하나를 사용해야 합니다:" #: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" -msgstr "" +msgstr "Alpha: ``MAJOR.MINOR.PATCHaN``" #: ../../source/contributor-how-to-release-flower.rst:54 msgid "Beta: ``MAJOR.MINOR.PATCHbN``" -msgstr "" +msgstr "Beta: ``MAJOR.MINOR.PATCHbN``" #: ../../source/contributor-how-to-release-flower.rst:55 msgid "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" -msgstr "" +msgstr "Release candidate (RC): ``MAJOR.MINOR.PATCHrcN``" #: ../../source/contributor-how-to-release-flower.rst:57 msgid "Examples include:" -msgstr "" +msgstr "예시:" #: ../../source/contributor-how-to-release-flower.rst:59 msgid "``1.0.0a0``" -msgstr "" +msgstr "``1.0.0a0``" #: ../../source/contributor-how-to-release-flower.rst:60 msgid "``1.0.0b0``" -msgstr "" +msgstr "``1.0.0b0``" #: ../../source/contributor-how-to-release-flower.rst:61 msgid "``1.0.0rc0``" -msgstr "" +msgstr "``1.0.0rc0``" #: ../../source/contributor-how-to-release-flower.rst:62 msgid "``1.0.0rc1``" -msgstr "" +msgstr "``1.0.0rc1``" #: ../../source/contributor-how-to-release-flower.rst:64 msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" -msgstr "" +msgstr "이는 PEP-440 및 Python Packaging Authority (PyPA)의 권장 사항과 일치합니다:" #: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" -msgstr "" +msgstr "`PEP-440 `_" #: ../../source/contributor-how-to-release-flower.rst:68 msgid "" @@ -960,6 +966,8 @@ msgid "" "`_" msgstr "" +"`PyPA 버전 관리 체계 선택하기 `_" #: ../../source/contributor-how-to-release-flower.rst:70 msgid "" @@ -968,14 +976,17 @@ msgid "" "`_ (specifically item " "11 on precedence)." msgstr "" +"PyPA에서 정의한 접근 방식은 SemVer 2.0.0 사양과 호환되지 않으며, 자세한 " +"내용은`Semantic Versioning 관리 사양 `_ (특히 항목 11이 우선순위)을 참조하세요." #: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" -msgstr "" +msgstr "사전 릴리즈 분류" #: ../../source/contributor-how-to-release-flower.rst:75 msgid "Should the next pre-release be called alpha, beta, or release candidate?" -msgstr "" +msgstr "다음 사전 릴리를 알파, 베타 또는 릴리스 후보라고 불러야 하나요?" #: ../../source/contributor-how-to-release-flower.rst:77 msgid "" @@ -983,18 +994,20 @@ msgid "" "classified as \"won't fix\" for the next stable release) - if no issues " "surface this will become the next stable release" msgstr "" +"RC: 기능 완료, 알려진 문제 없음(다음 stable 릴리즈에서 \"수정되지 않음\"으로 " +"분류된 문제 제외) - 문제가 나타나지 않으면 다음 stable 릴리즈가 됩니다" #: ../../source/contributor-how-to-release-flower.rst:78 msgid "Beta: feature complete, allowed to have known issues" -msgstr "" +msgstr "베타: 기능 완료, 알려진 문제 발생 가능" #: ../../source/contributor-how-to-release-flower.rst:79 msgid "Alpha: not feature complete, allowed to have known issues" -msgstr "" +msgstr "알파: 기능 미완성, 알려진 문제가 있을 수 있음" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:2 msgid "Set up a virtual env" -msgstr "" +msgstr "가상 환경 설정" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:4 msgid "" @@ -1003,10 +1016,13 @@ msgid "" "environment with pyenv virtualenv, poetry, or Anaconda. You can follow " "the instructions or choose your preferred setup." msgstr "" +"가상 환경 내에서 파이썬 설정을 실행하는 것이 좋습니다. 이 가이드에서는 pyenv " +"virtualenv, poetry 또는 Anaconda를 사용하여 가상 환경을 만드는 세 가지 " +"예제를 보여줍니다. 안내를 따르거나 원하는 설정을 선택할 수 있습니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 msgid "Python Version" -msgstr "" +msgstr "Python 버전" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 @@ -1015,6 +1031,8 @@ msgid "" "but `Python 3.10 `_ or above is " "recommended." msgstr "" +"Flower는 `Python 3.8 `_이상이 필요하지만, `" +"Python 3.10 `_이상을 권장합니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 msgid "" @@ -1023,10 +1041,13 @@ msgid "" "most `Python 3.11 `_ for running Flower " "simulations." msgstr "" +"`Ray `__와 호환되지 않는 것으로 알려져 " +"있으므로, 현재 Flower 시뮬레이션을 실행할 때는 최대 `Python 3.11 " +"`_을 사용하는 것이 좋습니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 msgid "Virtualenv with Pyenv/Virtualenv" -msgstr "" +msgstr "Pyenv/Virtualenv를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" @@ -1035,24 +1056,30 @@ msgid "" "/pyenv-virtualenv>`_. Please see `Flower examples " "`_ for details." msgstr "" +"권장 가상 환경 중 하나는 `pyenv `_/`" +"virtualenv `_입니다. 자세한 " +"내용은 `Flower examples `" +"_를 참조하세요." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " "`_ or above:" msgstr "" +"Pyenv가 설정되면 이를 사용하여 'Python 버전 3.10 `_ 이상'을 설치할 수 있습니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:29 msgid "Create the virtualenv with:" -msgstr "" +msgstr "가상 환경을 만듭니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:36 msgid "Activate the virtualenv by running the following command:" -msgstr "" +msgstr "다음 명령을 실행하여 가상 환경을 활성화합니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:44 msgid "Virtualenv with Poetry" -msgstr "" +msgstr "Poetry를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" @@ -1060,16 +1087,20 @@ msgid "" "poetry.org/docs/>`_ to manage dependencies. After installing Poetry you " "simply create a virtual environment with:" msgstr "" +"Flower examples은 dependencies을 관리하기 위해 `Poetry `_를 기반으로 합니다. Poetry를 설치한 후 가상 환경을 생성하기만 " +"하면 됩니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" "If you open a new terminal you can activate the previously created " "virtual environment with the following command:" -msgstr "" +msgstr "새 터미널을 열면 다음 명령을 사용하여 이전에 생성한 가상 환경을 활성화할 수 " +"있습니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 msgid "Virtualenv with Anaconda" -msgstr "" +msgstr "Anaconda를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" @@ -1078,28 +1109,33 @@ msgid "" "/user-guide/install/index.html>`_ package. After setting it up you can " "create a virtual environment with:" msgstr "" +"가상 환경에서 Anaconda를 사용하려면 `conda `_ 패키지를 설치 및 " +"설정하세요. 설정 후 다음을 사용하여 가상 환경을 만들 수 있습니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:68 msgid "and activate the virtual environment with:" -msgstr "" +msgstr "그 후 가상 환경을 활성화합니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:76 msgid "And then?" -msgstr "" +msgstr "그다음은?" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" "As soon as you created your virtual environment you clone one of the " "`Flower examples `_." msgstr "" +"가상 환경을 생성하자마자 'Flower examples `_ 중 하나를 클론합니다." #: ../../source/contributor-how-to-write-documentation.rst:2 msgid "Write documentation" -msgstr "" +msgstr "문서 작성" #: ../../source/contributor-how-to-write-documentation.rst:6 msgid "Project layout" -msgstr "" +msgstr "프로젝트 레이아웃" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" @@ -1107,6 +1143,9 @@ msgid "" " documentation system supports both reStructuredText (``.rst`` files) and" " Markdown (``.md`` files)." msgstr "" +"Flower 문서는 ``doc`` 디렉토리에 있습니다. Sphinx 기반 문서 시스템은 " +"reStructuredText 텍스트(``.rst`` 파일)와 Markdown(``.md`` 파일)을 모두 " +"지원합니다." #: ../../source/contributor-how-to-write-documentation.rst:10 #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 @@ -1116,44 +1155,47 @@ msgid "" "`_ needs to be installed on the " "system." msgstr "" +"로컬에서 문서를 작성하려면(아래 설명과 같이 ``poetry run make html``로) `" +"Pandoc `_이 시스템에 설치되어 있어야 " +"합니다." #: ../../source/contributor-how-to-write-documentation.rst:14 msgid "Edit an existing page" -msgstr "" +msgstr "기존 페이지 편집" #: ../../source/contributor-how-to-write-documentation.rst:16 msgid "Edit an existing ``.rst`` (or ``.md``) file under ``doc/source/``" -msgstr "" +msgstr "doc/source/``에서 기존 ``.rst``(또는 ``.md``) 파일을 편집합니다" #: ../../source/contributor-how-to-write-documentation.rst:17 #: ../../source/contributor-how-to-write-documentation.rst:27 msgid "Compile the docs: ``cd doc``, then ``poetry run make html``" -msgstr "" +msgstr "문서를 컴파일합니다: ``cd doc``, ``poetry run make html`` 순으로 컴파일합니다" #: ../../source/contributor-how-to-write-documentation.rst:18 #: ../../source/contributor-how-to-write-documentation.rst:28 msgid "Open ``doc/build/html/index.html`` in the browser to check the result" -msgstr "" +msgstr "브라우저에서 ``doc/build/html/index.html``을 열어 결과를 확인합니다" #: ../../source/contributor-how-to-write-documentation.rst:22 msgid "Create a new page" -msgstr "" +msgstr "새 페이지 만들기" #: ../../source/contributor-how-to-write-documentation.rst:24 msgid "Add new ``.rst`` file under ``doc/source/``" -msgstr "" +msgstr "``doc/source/`에 새 ``.rst`` 을 추가합니다" #: ../../source/contributor-how-to-write-documentation.rst:25 msgid "Add content to the new ``.rst`` file" -msgstr "" +msgstr "새 '.rst' 파일에 내용을 추가합니다" #: ../../source/contributor-how-to-write-documentation.rst:26 msgid "Link to the new rst from ``index.rst``" -msgstr "" +msgstr "``index.rst``에서 새 rst로 연결합니다" #: ../../source/contributor-ref-good-first-contributions.rst:2 msgid "Good first contributions" -msgstr "" +msgstr "좋은 첫 번째 기여" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" @@ -1162,10 +1204,13 @@ msgid "" "where to start to increase your chances of getting your PR accepted into " "the Flower codebase." msgstr "" +"Flower에 대한 기여를 환영합니다! 하지만 어디서부터 시작해야 할지 알기란 쉽지 " +"않습니다. 그래서 저희는 여러분의 PR이 Flower 코드베이스에 채택될 가능성을 " +"높이기 위해 어디서부터 시작해야 하는지 몇 가지 권장 사항을 정리해 보았습니다." #: ../../source/contributor-ref-good-first-contributions.rst:11 msgid "Where to start" -msgstr "" +msgstr "시작 위치" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" @@ -1173,22 +1218,25 @@ msgid "" "accepted if they only touch non-core areas of the codebase. Good " "candidates to get started are:" msgstr "" +"Flower 코어 라이브러리가 완성될 때까지는 코드베이스의 비핵심 영역만 건드리는 " +"것이 PR을 승인받기가 더 쉬울 것입니다. 시작하기에 좋은 후보자는 다음과 " +"같습니다:" #: ../../source/contributor-ref-good-first-contributions.rst:17 msgid "Documentation: What's missing? What could be expressed more clearly?" -msgstr "" +msgstr "문서: 무엇이 누락되었나요? 무엇을 더 명확하게 표현할 수 있을까요?" #: ../../source/contributor-ref-good-first-contributions.rst:18 msgid "Baselines: See below." -msgstr "" +msgstr "Baselines: 아래를 참조하세요." #: ../../source/contributor-ref-good-first-contributions.rst:19 msgid "Examples: See below." -msgstr "" +msgstr "예시: 아래를 참조하세요." #: ../../source/contributor-ref-good-first-contributions.rst:23 msgid "Request for Flower Baselines" -msgstr "" +msgstr "Flower Baselines 요청" #: ../../source/contributor-ref-good-first-contributions.rst:25 msgid "" @@ -1196,6 +1244,8 @@ msgid "" "out our `contributing guide for baselines " "`_." msgstr "" +"Flower Baseline에 익숙하지 않다면 ' Baseline 기여 가이드 `_를 확인해보세요." #: ../../source/contributor-ref-good-first-contributions.rst:27 msgid "" @@ -1205,16 +1255,21 @@ msgid "" " and that has no assignees, feel free to assign it to yourself and start " "working on it!" msgstr "" +"그런 다음 오픈 된 `이슈 `_에서 baseline " +"요청을 확인해야 합니다. 작업하고 싶은 기준선을 찾았지만 담당자가 없는 경우, " +"자유롭게 자신에게 할당하고 작업을 시작하세요!" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" "Otherwise, if you don't find a baseline you'd like to work on, be sure to" " open a new issue with the baseline request template!" -msgstr "" +msgstr "그렇지 않으면 작업하고 싶은 baseline을 찾지 못하면 baseline 요청 템플릿으로 " +"새 이슈를 열어야 합니다!" #: ../../source/contributor-ref-good-first-contributions.rst:34 msgid "Request for examples" -msgstr "" +msgstr "예시 요청" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" @@ -1222,22 +1277,25 @@ msgid "" "help users to get started with building what they want to build. Here are" " a few ideas where we'd be happy to accept a PR:" msgstr "" +"사용 예시는 사용자가 원하는 것을 구축하는 데 도움이 된다고 생각하기 때문에 " +"더 많은 시간을 할애하여 작성할 수 있었으면 합니다. 다음은 저희가 기꺼이 PR을 " +"수락할 수 있는 몇 가지 아이디어입니다:" #: ../../source/contributor-ref-good-first-contributions.rst:40 msgid "Llama 2 fine-tuning, with Hugging Face Transformers and PyTorch" -msgstr "" +msgstr "Llama 2 미세 조정, Hugging Face Transformer와 파이토치 포함" #: ../../source/contributor-ref-good-first-contributions.rst:41 msgid "XGBoost" -msgstr "" +msgstr "XGBoost" #: ../../source/contributor-ref-good-first-contributions.rst:42 msgid "Android ONNX on-device training" -msgstr "" +msgstr "Android ONNX 온디바이스 훈련" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:2 msgid "Secure Aggregation Protocols" -msgstr "" +msgstr "Secure Aggregation 프로토콜" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" @@ -1246,10 +1304,14 @@ msgid "" " not be accurate in practice. The SecAgg protocol can be considered as a " "special case of the SecAgg+ protocol." msgstr "" +"SecAgg, SecAgg+, LightSecAgg 프로토콜을 포함합니다. LightSecAgg 프로토콜은 " +"아직 구현되지 않았기 때문에 다이어그램과 추상화가 실제로는 정확하지 않을 수 " +"있습니다. SecAgg 프로토콜은 SecAgg+ 프로토콜의 특수한 경우로 간주할 수 " +"있습니다." #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 msgid "The :code:`SecAgg+` abstraction" -msgstr "" +msgstr "The :code:`SecAgg+` 추상화" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:10 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 @@ -1258,31 +1320,35 @@ msgid "" "(int) for secure aggregation, and thus many python dictionaries used have" " keys of int type rather than ClientProxy type." msgstr "" +"구현에서는 각 클라이언트에 secure aggregation를 위한 고유 인덱스(int)가 " +"할당되므로 사용되는 많은 파이썬 dictionaries에는 ClientProxy 타입이 아닌 int " +"타입의 키가 있습니다." #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" "The Flower server will execute and process received results in the " "following order:" -msgstr "" +msgstr "Flower 서버는 수신된 결과를 다음 순서로 실행하고 처리합니다:" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 msgid "The :code:`LightSecAgg` abstraction" -msgstr "" +msgstr "The :code:`LightSecAgg` 추상" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:271 msgid "Types" -msgstr "" +msgstr "타입" #: ../../source/contributor-tutorial-contribute-on-github.rst:2 msgid "Contribute on GitHub" -msgstr "" +msgstr "GitHub에서 기여하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" "This guide is for people who want to get involved with Flower, but who " "are not used to contributing to GitHub projects." -msgstr "" +msgstr "이 가이드는 Flower에 참여하고 싶지만 GitHub 프로젝트에 기여하는 데 익숙하지 " +"않은 분들을 위한 것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:6 msgid "" @@ -1290,14 +1356,16 @@ msgid "" "directly checkout our :doc:`getting started guide for contributors " "`." msgstr "" +"깃허브에서 기여하는 방식에 익숙하다면 :doc:`기여자를 위한 시작 가이드" +"`를 직접 확인하세요." #: ../../source/contributor-tutorial-contribute-on-github.rst:10 msgid "Setting up the repository" -msgstr "" +msgstr "레포지토리 설정하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:21 msgid "**Create a GitHub account and setup Git**" -msgstr "" +msgstr "**GitHub 계정을 만들고 Git을 설정합니다**" #: ../../source/contributor-tutorial-contribute-on-github.rst:13 msgid "" @@ -1307,6 +1375,10 @@ msgid "" "follow this `guide `_ to set it up." msgstr "" +"Git은 분산 버전 관리 도구입니다. 이를 통해 전체 코드베이스의 히스토리와 모든 " +"개발자의 컴퓨터를 저장할 수 있습니다. 로컬 컴퓨터에 설치해야 하는 " +"소프트웨어로, 이 `가이드 `_를 따라 설정할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" @@ -1314,12 +1386,15 @@ msgid "" "collaboration. It allows for everyone to collaborate and work from " "anywhere on remote repositories." msgstr "" +"GitHub는 그 자체로 버전 관리 및 협업을 위한 코드 호스팅 플랫폼입니다. 누구나 " +"원격 레포지토리에서 어디서든 협업하고 작업할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:18 msgid "" "If you haven't already, you will need to create an account on `GitHub " "`_." -msgstr "" +msgstr "아직 계정을 만들지 않았다면 `GitHub `_에서 계정을 " +"만들어야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" @@ -1328,10 +1403,13 @@ msgid "" "locally and keep track of them using Git and then you upload your new " "history back to GitHub." msgstr "" +"일반적인 Git 및 GitHub 워크플로우의 기본 개념은 다음과 같이 요약됩니다. " +"GitHub의 원격 레포지토리에서 코드를 다운로드하고 로컬에서 변경한 후 Git을 " +"사용하여 추적한 다음 새 기록을 다시 GitHub에 업로드하는 것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:32 msgid "**Forking the Flower repository**" -msgstr "" +msgstr "**Flower 레포지토리 포크하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 msgid "" @@ -1340,6 +1418,9 @@ msgid "" "connected to your GitHub account) and click the ``Fork`` button situated " "on the top right of the page." msgstr "" +"포크는 GitHub 리포지토리의 개인 복사본입니다. Flower용 포크를 만들려면 " +"``_로 이동하여(GitHub 계정에 연결된 상태에서)" +" 페이지 오른쪽 상단에 있는 ``포크`` 버튼을 클릭해야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" @@ -1348,10 +1429,13 @@ msgid "" "(i.e., in your own list of repositories). Once created, you should see on" " the top left corner that you are looking at your own version of Flower." msgstr "" +"원하는 경우 이름을 변경할 수 있지만, 이 버전의 Flower는 자신의 계정(즉, " +"자신의 리포지토리 목록)에 위치하게 되므로 변경할 필요는 없습니다. 만들기가 " +"완료되면 왼쪽 상단에Flower 버전이 표시되는 것을 볼 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "**Cloning your forked repository**" -msgstr "" +msgstr "**포크된 레포지토리 클론하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" @@ -1360,26 +1444,31 @@ msgid "" "first click on the ``Code`` button on the right, this will give you the " "ability to copy the HTTPS link of the repository." msgstr "" +"다음 단계는 컴퓨터에서 포크된 레포지토리를 변경할 수 있도록 다운로드하는 " +"것입니다. 포크된 포지토리 페이지에서 먼저 오른쪽의 ``Code`` 버튼을 클릭하면 " +"레포지토리의 HTTPS 링크를 복사할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:41 msgid "" "Once you copied the \\, you can open a terminal on your machine, " "navigate to the place you want to download the repository to and type:" -msgstr "" +msgstr "\\를 복사한 후에는 컴퓨터에서 터미널을 열고 레포지토리를 다운로드할 " +"위치로 이동하여 입력하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "" "This will create a ``flower/`` (or the name of your fork if you renamed " "it) folder in the current working directory." -msgstr "" +msgstr "현재 작업 디렉터리에``flower/``(또는 포크 이름을 변경한 경우 포크 이름) " +"폴더가 생성됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:66 msgid "**Add origin**" -msgstr "" +msgstr "**origin 추가**" #: ../../source/contributor-tutorial-contribute-on-github.rst:50 msgid "You can then go into the repository folder:" -msgstr "" +msgstr "그런 다음 레포지토리 폴더로 이동할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" @@ -1388,26 +1477,30 @@ msgid "" "previously mentioned by going to our fork repository on our GitHub " "account and copying the link." msgstr "" +"여기에 레포지토리에 origin을 추가해야 합니다. origin은 원격 포크 " +"레포지토리의 \\입니다. origin을 얻으려면 앞서 설명한 대로 GitHub " +"계정의 포크 레포지토리로 이동하여 링크를 복사하면 됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:61 msgid "" "Once the \\ is copied, we can type the following command in our " "terminal:" -msgstr "" +msgstr "\\ 이 복사되면 터미널에 다음 명령을 입력하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:90 msgid "**Add upstream**" -msgstr "" +msgstr "**Upstream 추가하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:69 msgid "" "Now we will add an upstream address to our repository. Still in the same " "directory, we must run the following command:" -msgstr "" +msgstr "이제 레포지토리에 upstream 주소를 추가하겠습니다. 여전히 같은 디렉터리에서 " +"다음 명령을 실행해야 합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 msgid "The following diagram visually explains what we did in the previous steps:" -msgstr "" +msgstr "다음 다이어그램은 이전 단계에서 수행한 작업을 시각적으로 설명합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" @@ -1417,16 +1510,21 @@ msgid "" "remote address of the forked repository we created, i.e. the copy (fork) " "in our own account." msgstr "" +"upstream은 부모 레포지토리(이 경우 Flower)의 GitHub 원격 주소, 즉 우리가 " +"최종적으로 기여하고 싶고 따라서 최신 기록이 필요한 레포지토리입니다. " +"origin은 우리가 만든 포크된 레포지토리의 GitHub 원격 주소, 즉 우리 계정에 " +"있는 사본(포크)입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:84 msgid "" "To make sure our local version of the fork is up-to-date with the latest " "changes from the Flower repository, we can execute the following command:" -msgstr "" +msgstr "로컬 버전의 포크가 Flower 레포지토리의 최신 변경 사항으로 최신 상태인지 " +"확인하려면 다음 명령을 실행하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:93 msgid "Setting up the coding environment" -msgstr "" +msgstr "코딩 환경 설정" #: ../../source/contributor-tutorial-contribute-on-github.rst:95 msgid "" @@ -1435,49 +1533,53 @@ msgid "" "that you won't need to clone the repository). Once you are able to write " "code and test it, you can finally start making changes!" msgstr "" +":doc:'기여자를 위한 시작 가이드 '를 참조하세요(리포지토리를 복제할 필요는 없습니다). 코드를 " +"작성하고 테스트할 수 있게 되면 드디어 변경을 시작할 수 있습니다!" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 msgid "Making changes" -msgstr "" +msgstr "변경하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" "Before making any changes make sure you are up-to-date with your " "repository:" -msgstr "" +msgstr "변경하기 전에 레포지토리를 최신 상태로 유지하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 msgid "And with Flower's repository:" -msgstr "" +msgstr "Flower의 레포지토리도 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:122 msgid "**Create a new branch**" -msgstr "" +msgstr "**새 브랜치 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" "To make the history cleaner and easier to work with, it is good practice " "to create a new branch for each feature/project that needs to be " "implemented." -msgstr "" +msgstr "히스토리를 더 깔끔하고 작업하기 쉽게 만들려면 구현해야 하는 각 기능/" +"프로젝트에 대해 새 브랜치를 만드는 것이 좋습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" "To do so, just run the following command inside the repository's " "directory:" -msgstr "" +msgstr "이렇게 하려면 레포지토리 디렉토리에서 다음 명령을 실행하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 msgid "**Make changes**" -msgstr "" +msgstr "**변경하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 msgid "Write great code and create wonderful changes using your favorite editor!" -msgstr "" +msgstr "선호하 편집기를 사용하여 멋진 코드를 작성하고 훌륭한 변화를 만들어 보세요!" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 msgid "**Test and format your code**" -msgstr "" +msgstr "**코드 테스트 및 서식 지정**" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" @@ -1485,24 +1587,28 @@ msgid "" "able to be merged into the Flower repository. This is done so the " "codebase stays consistent and easy to understand." msgstr "" +"코드를 테스트하고 서식을 지정하는 것을 잊지 마세요! 그렇지 않으면 코드를 " +"Flower 레포지토리에 병합할 수 없습니다. 이는 코드베이스가 일관성을 유지하고 " +"이해하기 쉽도록 하기 위한 것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:131 msgid "To do so, we have written a few scripts that you can execute:" -msgstr "" +msgstr "이를 위해 실행할 수 있는 몇 가지 스크립트를 작성했습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:150 msgid "**Stage changes**" -msgstr "" +msgstr "**Stage 변경**" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" "Before creating a commit that will update your history, you must specify " "to Git which files it needs to take into account." -msgstr "" +msgstr "기록을 업데이트할 커밋을 만들기 전에 어떤 파일을 고려해야 하는지 Git에 " +"지정해야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:143 msgid "This can be done with:" -msgstr "" +msgstr "이 작업을 수행할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" @@ -1510,16 +1616,20 @@ msgid "" "(last commit) and to see which files are staged for commit, you can use " "the :code:`git status` command." msgstr "" +"마지막 버전(마지막 커밋)과 비교하여 수정된 파일을 확인하고 커밋을 위해 " +"스테이징된 파일을 확인하려면 :code:`git status` 명령을 사용하면 됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:160 msgid "**Commit changes**" -msgstr "" +msgstr "**Commit 변경**" #: ../../source/contributor-tutorial-contribute-on-github.rst:153 msgid "" "Once you have added all the files you wanted to commit using :code:`git " "add`, you can finally create your commit using this command:" msgstr "" +":code:`git add`를 사용하여 커밋하려는 모든 파일을 추가한 후, 마지막으로 이 " +"명령을 사용하여 커밋을 생성할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" @@ -1527,10 +1637,13 @@ msgid "" "does. It should be written in an imperative style and be concise. An " "example would be :code:`git commit -m \"Add images to README\"`." msgstr "" +"커밋의 내용을 다른 사람에게 설명하기 위해 \\가 있습니다. " +"명령형 스타일로 작성해야 하며 간결해야 합니다. 예를 들면 :code:`git commit -" +"m \"Add images to README\"`." #: ../../source/contributor-tutorial-contribute-on-github.rst:171 msgid "**Push the changes to the fork**" -msgstr "" +msgstr "**변경 사항을 포크에 푸시**" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" @@ -1538,40 +1651,44 @@ msgid "" " history, but GitHub has no way of knowing this unless we push our " "changes to our origin's remote address:" msgstr "" +"변경 사항을 커밋하면 로컬 히스토리를 효과적으로 업데이트한 것이지만, 변경 " +"사항을 원본의 원격 주소로 푸시하지 않는 한 GitHub는 이를 알 방법이 없습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 msgid "" "Once this is done, you will see on the GitHub that your forked repo was " "updated with the changes you have made." -msgstr "" +msgstr "이 작업이 완료되면 변경한 내용으로 포크된 레포지토리가 업데이트된 것을 " +"GitHub에서 확인할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:174 msgid "Creating and merging a pull request (PR)" -msgstr "" +msgstr "pull request(PR) 만들기 및 병합하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:206 msgid "**Create the PR**" -msgstr "" +msgstr "**PR 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" "Once you have pushed changes, on the GitHub webpage of your repository " "you should see the following message:" -msgstr "" +msgstr "변경 사항을 푸시하고 나면 레포지토리의 GitHub 웹페이지에 다음 메시지가 " +"표시됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 msgid "Otherwise you can always find this option in the ``Branches`` page." -msgstr "" +msgstr "그렇지 않으면 언제든지 ``Branches`` 페이지에서 이 옵션을 찾을 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:183 msgid "" "Once you click the ``Compare & pull request`` button, you should see " "something similar to this:" -msgstr "" +msgstr "``Compare & pull request`` 버튼을 클릭하면 이와 비슷한 화면이 표시됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 msgid "At the top you have an explanation of which branch will be merged where:" -msgstr "" +msgstr "상단에는 어느 지점이 어디에 병합될 것인지에 대한 설명이 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" @@ -1579,6 +1696,8 @@ msgid "" "``doc-fixes`` from my forked repository to branch ``main`` from the " "Flower repository." msgstr "" +"이 예제에서는 내 포크된 레포지토리의 ``doc-fixes`` 브랜치를 Flower " +"레포지토리의 ``main`` 브랜치에 병합하라는 요청을 볼 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" @@ -1586,6 +1705,9 @@ msgid "" "guidelines, otherwise it won't be possible to merge the PR. So in this " "case, a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" +"제목은 :ref:`pr_title_format` 가이드라인을 준수하도록 변경해야 하며, 그렇지 " +"않으면 PR을 병합할 수 없습니다. 따라서 이 경우 올바른 제목은 " +"``docs(framework:skip) Fix typos``이 될 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" @@ -1594,10 +1716,13 @@ msgid "" "won't be rendered once the PR is opened) to guide you through the " "process." msgstr "" +"가운데에 있는 입력 상자는 PR의 기능을 설명하고 기존 이슈에 연결할 수 있는 " +"곳입니다. 프로세스를 안내하기 위해 코멘트(PR이 열리면 렌더링되지 않음)를 " +"배치했습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:199 msgid "It is important to follow the instructions described in comments." -msgstr "" +msgstr "코멘트에 설명된 지침을 따르는 것이 중요합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" @@ -1605,155 +1730,176 @@ msgid "" "reviewers that a new PR has been opened and that they should look over it" " to merge or to request changes." msgstr "" +"하단에는 PR을 여는 버튼이 있습니다. 이렇게 하면 검토자에게 새 PR이 열렸으며 " +"병합하거나 변경을 요청하기 위해 검토해야 함을 알립니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" "If your PR is not yet ready for review, and you don't want to notify " "anyone, you have the option to create a draft pull request:" msgstr "" +"PR이 아직 검토할 준비가 되지 않았고 다른 사람에게 알리고 싶지 않은 경우 pull " +"request 초안을 만드는 옵션이 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "**Making new changes**" -msgstr "" +msgstr "**new changes 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " "commits to it the same way we did before, by making changes to the branch" " associated with the PR." -msgstr "" +msgstr "PR이 초안으로 열렸든 아니든, PR과 연결된 브랜치를 변경하여 이전과 같은 " +"방식으로 새 커밋을 푸시할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" -msgstr "" +msgstr "**PR 검토하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" "Once the PR has been opened or once the draft PR has been marked as " "ready, a review from code owners will be automatically requested:" -msgstr "" +msgstr "PR이 열리거나 초안 PR이 준비됨으로 표시되면 코드 소유자의 검토가 자동으로 " +"요청됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" "Code owners will then look into the code, ask questions, request changes " "or validate the PR." -msgstr "" +msgstr "그러면 코드 소유자는 코드를 살펴보고, 질문하고, 변경을 요청하거나 PR의 " +"유효성을 검사합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." -msgstr "" +msgstr "진행 중인 변경 요청이 있는 경우 병합이 차단됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" "To resolve them, just push the necessary changes to the branch associated" " with the PR:" -msgstr "" +msgstr "이를 해결하려면 PR과 연결된 브랜치에 필요한 변경 사항을 푸시하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" -msgstr "" +msgstr "그리고 소통을 통해 해결하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" "Once all the conversations have been resolved, you can re-request a " "review." -msgstr "" +msgstr "모든 대화가 해결되면 검토를 다시 요청할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:251 msgid "**Once the PR is merged**" -msgstr "" +msgstr "**PR이 병합되면**" #: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" "If all the automatic tests have passed and reviewers have no more changes" " to request, they can approve the PR and merge it." -msgstr "" +msgstr "모든 자동 테스트가 통과되고 검토자가 더 이상 요청할 변경 사항이 없는 경우 " +"PR을 승인하고 병합할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" -msgstr "" +msgstr "병합이 완료되면 GitHub에서 브랜치를 삭제할 수 있으며(삭제 버튼이 표시되어야 " +"함), 로컬에서도 삭제할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:245 msgid "Then you should update your forked repository by doing:" -msgstr "" +msgstr "그런 다음 다음을 수행하여 포크된 레포지토리를 업데이트해야 합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:254 msgid "Example of first contribution" -msgstr "" +msgstr "첫 번째 기여의 예" #: ../../source/contributor-tutorial-contribute-on-github.rst:257 msgid "Problem" -msgstr "" +msgstr "문제" #: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" "For our documentation, we've started to use the `Diàtaxis framework " "`_." -msgstr "" +msgstr "저희 문서에는 'Diàtaxis 프레임워크 `_'를 사용하기 " +"시작했습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" "Our \"How to\" guides should have titles that continue the sentence \"How" " to …\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" +"'How to' 가이드의 제목은 \"How to …\"라는 문장을 이어가는 제목이어야 " +"합니다(예: \"How to upgrade to Flower 1.0\")." #: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." -msgstr "" +msgstr "대부분의 가이드는 아직 이 새로운 형식을 따르지 않으며, 안타깝게도 제목을 " +"변경하는 작업은 생각보다 복잡합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" "This issue is about changing the title of a doc from present continuous " "to present simple." -msgstr "" +msgstr "이번 이슈는 문서 제목을 현재 연속형에서 현재 단순형으로 변경하는 것에 관한 " +"것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:267 msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" msgstr "" +"\"How to saving progress\"을 \"How to save progress\"으로 변경한 예를 들어 " +"보겠습니다. 이것이 우리의 점검을 통과했나요?" #: ../../source/contributor-tutorial-contribute-on-github.rst:269 msgid "Before: \"How to saving progress\" ❌" -msgstr "" +msgstr "Before: \"How to saving progress\" ❌" #: ../../source/contributor-tutorial-contribute-on-github.rst:271 msgid "After: \"How to save progress\" ✅" -msgstr "" +msgstr "After: \"How to save progress\" ✅" #: ../../source/contributor-tutorial-contribute-on-github.rst:274 msgid "Solution" -msgstr "" +msgstr "해결법" #: ../../source/contributor-tutorial-contribute-on-github.rst:276 msgid "" "This is a tiny change, but it'll allow us to test your end-to-end setup. " "After cloning and setting up the Flower repo, here's what you should do:" msgstr "" +"이것은 사소한 변경이지만 end-to-end 설정을 테스트할 수 있습니다. Flower " +"포지토리를 복제하고 설정한 후에는 다음과 같이 하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:278 msgid "Find the source file in ``doc/source``" -msgstr "" +msgstr "``doc/source``에서 소스 파일을 찾습니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:279 msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " "should be the same length as the title itself)" -msgstr "" +msgstr "``.rst`` 파일에서 변경합니다(제목 아래의 대시는 제목 자체의 길이와 같아야 " +"합니다)" #: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" "Build the docs and `check the result `_" msgstr "" +"문서를 빌드하고 '결과 확인 `_'합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:283 msgid "Rename file" -msgstr "" +msgstr "파일 이름 바꾸기" #: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" @@ -1762,28 +1908,33 @@ msgid "" "is **very important** to avoid that, breaking links can harm our search " "engine ranking." msgstr "" +"파일 이름에 여전히 이전 문구가 반영되어 있는 것을 보셨을 것입니다. 파일만 " +"변경하면 파일에 대한 기존 링크가 모두 끊어지는데, 링크를 끊으면 검색 엔진 " +"순위에 영향을 줄 수 있으므로 이를 방지하는 것이 **매우 중요**합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:288 msgid "Here's how to change the file name:" -msgstr "" +msgstr "파일 이름을 변경하는 방법은 다음과 같습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:290 msgid "Change the file name to ``save-progress.rst``" -msgstr "" +msgstr "파일 이름을 ``save-progress.rst``로 변경합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:291 msgid "Add a redirect rule to ``doc/source/conf.py``" -msgstr "" +msgstr "'doc/source/conf.py'에 리디렉션 규칙을 추가합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" "This will cause a redirect from ``saving-progress.html`` to ``save-" "progress.html``, old links will continue to work." msgstr "" +"이렇게 하면 ``saving-progress.html``에서 ``save-progress.html``로 " +"리디렉션되며, 이전 링크는 계속 작동합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" -msgstr "" +msgstr "인덱스 파일에 변경 사항 적용" #: ../../source/contributor-tutorial-contribute-on-github.rst:298 msgid "" @@ -1791,38 +1942,42 @@ msgid "" "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." msgstr "" +"횡방향 내비게이션 바가 제대로 작동하려면 ``index.rst`` 파일도 업데이트하는 " +"것이 매우 중요합니다. 이 파일은 탐색 모음의 전체 배열을 정의하는 곳입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:301 msgid "Find and modify the file name in ``index.rst``" -msgstr "" +msgstr "``index.rst``에서 파일 이름을 찾아 수정합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:304 msgid "Open PR" -msgstr "" +msgstr "PR 열기" #: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" "Commit the changes (commit messages are always imperative: \"Do " "something\", in this case \"Change …\")" msgstr "" +"변경 사항을 커밋합니다(커밋 메시지는 항상 필수 메시지입니다:\"Do something\"(" +"이 경우 는 \"Change …\" )" #: ../../source/contributor-tutorial-contribute-on-github.rst:307 msgid "Push the changes to your fork" -msgstr "" +msgstr "변경 사항을 포크에 푸시합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 msgid "" "Open a PR (as shown above) with title ``docs(framework) Update how-to " "guide title``" -msgstr "" +msgstr "``docs(framework) Update how-to guide title`` 제목으로 PR(위와 같이)을 엽니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" -msgstr "" +msgstr "승인될 때까지 기다리세요!" #: ../../source/contributor-tutorial-contribute-on-github.rst:310 msgid "Congrats! 🥳 You're now officially a Flower contributor!" -msgstr "" +msgstr "축하합니다! 이제 공식적으로 Flower 기여자가 되셨습니다!" #: ../../source/contributor-tutorial-contribute-on-github.rst:314 #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:548 @@ -1831,13 +1986,13 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:713 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:367 msgid "Next steps" -msgstr "" +msgstr "다음 단계" #: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" "Once you have made your first PR, and want to contribute more, be sure to" " check out the following :" -msgstr "" +msgstr "첫 번째 PR을 작성하고 더 많은 기여를 하고 싶다면 다음 을 확인하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" @@ -1845,25 +2000,28 @@ msgid "" "contributions>`, where you should particularly look into the " ":code:`baselines` contributions." msgstr "" +":doc:`훌륭한 첫 번째 기여 `, 특히 " +":code:`baselines` 기여를 살펴봐야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 msgid "Appendix" -msgstr "" +msgstr "부록" #: ../../source/contributor-tutorial-contribute-on-github.rst:327 msgid "PR title format" -msgstr "" +msgstr "PR 제목 형식" #: ../../source/contributor-tutorial-contribute-on-github.rst:329 msgid "We enforce the following PR title format:" -msgstr "" +msgstr "다음과 같은 PR 제목 형식을 적용합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" "(or ``(:skip) `` to ignore the PR in the " "changelog)" -msgstr "" +msgstr "(또는 ``(:skip) ``를 사용하면 변경 로그에서 PR을 " +"무시합니다.)" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" @@ -1873,77 +2031,81 @@ msgid "" "':skip' flag to be used}``, and ```` starts with a capitalised " "verb in the imperative mood." msgstr "" +"여기서 ````은 ``{ci, fix, feat, docs, refactor, break}``, ````" +"는 ``{framework, baselines, datasets, examples, or '*' ':skip' 플래그를 " +"사용해야 하는 여러 프로젝트를 수정하는 경우}``로 입력해야 하며, ````" +"는 대문자로 시작해야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:341 msgid "Valid examples:" -msgstr "" +msgstr "유효한 예시입니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:343 msgid "``feat(framework) Add flwr build CLI command``" -msgstr "" +msgstr "``feat(framework) Add flwr build CLI command``" #: ../../source/contributor-tutorial-contribute-on-github.rst:344 msgid "``refactor(examples:skip) Improve quickstart-pytorch logging``" -msgstr "" +msgstr "``refactor(examples:skip) Improve quickstart-pytorch logging``" #: ../../source/contributor-tutorial-contribute-on-github.rst:345 msgid "``ci(*:skip) Enforce PR title format``" -msgstr "" +msgstr "``ci(*:skip) Enforce PR title format``" #: ../../source/contributor-tutorial-contribute-on-github.rst:347 msgid "Invalid examples:" -msgstr "" +msgstr "잘못된 예제입니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:349 msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" -msgstr "" +msgstr "``feat(framework): Add flwr build CLI command`` ( ``:``제외)" #: ../../source/contributor-tutorial-contribute-on-github.rst:350 msgid "" "``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " "``*``)" -msgstr "" +msgstr "``feat(*) Add flwr build CLI command`` (``skip`` flag와 함께 ``*``누락)" #: ../../source/contributor-tutorial-contribute-on-github.rst:351 msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" -msgstr "" +msgstr "``feat(skip) Add flwr build CLI command`` (````누락)" #: ../../source/contributor-tutorial-contribute-on-github.rst:352 msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" -msgstr "" +msgstr "``feat(framework) add flwr build CLI command`` (대문자로 표기되지 않은 동사)" #: ../../source/contributor-tutorial-contribute-on-github.rst:353 msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" -msgstr "" +msgstr "``feat(framework) Add flwr build CLI command.`` (끝에 마침표)" #: ../../source/contributor-tutorial-contribute-on-github.rst:354 msgid "``Add flwr build CLI command.`` (missing ``()``)" -msgstr "" +msgstr "``Add flwr build CLI command.`` ( ``()``누락)" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:2 msgid "Get started as a contributor" -msgstr "" +msgstr "기여자로 시작하기" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:5 #: ../../source/how-to-run-flower-using-docker.rst:153 msgid "Prerequisites" -msgstr "" +msgstr "전제 조건" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:7 msgid "`Python 3.8 `_ or above" -msgstr "" +msgstr "Python 3.8 `_ 이상" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:8 msgid "`Poetry 1.3 `_ or above" -msgstr "" +msgstr "`Poetry 1.3 `_ _ 이상" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:9 msgid "(Optional) `pyenv `_" -msgstr "" +msgstr "(선택 사항) `pyenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 msgid "(Optional) `pyenv-virtualenv `_" -msgstr "" +msgstr "(선택 사항) `pyenv-virtualenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 msgid "" @@ -1951,54 +2113,62 @@ msgid "" "development tools (the ones which support it). Poetry is a build tool " "which supports `PEP 517 `_." msgstr "" +"Flower는 dependencies을 관리하고 개발 도구(이를 지원하는 도구)를 구성하기 " +"위해 :code:`pyproject.toml`을 사용합니다. Poetry는 `PEP 517 `_을 지원하는 빌드 도구입니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 msgid "Developer Machine Setup" -msgstr "" +msgstr "개발자 머신 설정" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:21 msgid "Preliminarities" -msgstr "" +msgstr "사전 준비" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:22 msgid "Some system-wide dependencies are needed." -msgstr "" +msgstr "일부 시스템 전체에 대한 dependencies이 필요합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:25 msgid "For macOS" -msgstr "" +msgstr "macOS의 경우" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 msgid "" "Install `homebrew `_. Don't forget the post-" "installation actions to add `brew` to your PATH." msgstr "" +"`homebrew `_를 설치합니다. 설치 후 `brew`를 PATH에 " +"추가하는 작업을 잊지 마세요." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 msgid "" "Install `xz` (to install different Python versions) and `pandoc` to build" " the docs::" -msgstr "" +msgstr "xz`(다른 Python 버전을 설치하려면)와 `pandoc`을 설치하여 문서를 빌드합니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 msgid "For Ubuntu" -msgstr "" +msgstr "Ubuntu의 경우" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 msgid "" "Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " "necessary packages::" -msgstr "" +msgstr "시스템(우분투 22.04 이상)이 최신 상태이고 필요한 패키지가 모두 설치되어 " +"있는지 확인하세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 msgid "Create Flower Dev Environment" -msgstr "" +msgstr "Flower 개발 환경 만들기" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:46 msgid "" "1. Clone the `Flower repository `_ from " "GitHub::" msgstr "" +"1. GitHub: 에서 ``Flower 레포지토리 `_를 " +"복제합니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 msgid "" @@ -2008,6 +2178,10 @@ msgid "" "environment, activate and skip to the last point where all packages are " "installed." msgstr "" +"Flower의 모든 것을 위한 파이썬 환경을 만들어 보겠습니다.:code:`pyenv`를 " +"사용하고자 하는 경우 사용할 수 있는 두 가지 편의 스크립트를 " +"제공합니다.:code:`pyenv`가 아닌 다른 것을 사용하려면 새 환경을 생성하고 " +"활성화한 후 모든 패키지가 설치된 마지막 지점으로 건너뛰세요." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 msgid "" @@ -2015,6 +2189,8 @@ msgid "" " install it, set it up, and create the virtual environment (with " ":code:`Python 3.8.17` by default)::" msgstr "" +":code:`pyenv`가 설치되어 있지 않은 경우 다음 스크립트를 사용하여 설치, 설정 " +"및 가상 환경을 생성합니다(기본적으로 :code:`Python 3.8.17` 사용):" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 msgid "" @@ -2022,16 +2198,21 @@ msgid "" "virtualenv` plugin), you can use the following convenience script (with " ":code:`Python 3.8.17` by default)::" msgstr "" +":code:`pyenv`가 이미 설치되어 있는 경우( :code:`pyenv-virtualenv` 플러그인과 " +"함께) 다음과 같은 편의 스크립트를 사용할 수 있습니다(기본적으로 코드:`Python " +"3.8.17` 사용):" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 msgid "" "3. Install the Flower package in development mode (think :code:`pip " "install -e`) along with all necessary dependencies::" msgstr "" +"3. 필요한 모든 dependencies와 함께 개발 모드에서 Flower 패키지를 " +"설치합니다(예:code:`pip install -e`)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 msgid "Convenience Scripts" -msgstr "" +msgstr "편의 스크립트" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" @@ -2040,26 +2221,29 @@ msgid "" ":code:`/dev` subdirectory for a full list. The following scripts are " "amongst the most important ones:" msgstr "" +"Flower 레포지토리에는 반복적인 개발 작업을 더 쉽고 오류를 줄이기 위한 여러 " +"가지 편의 스크립트가 포함되어 있습니다. 전체 목록은 :code:`/dev` 하위 " +"디렉터리를 참조하세요. 다음 스크립트는 가장 중요한 스크립트 중 하나입니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 msgid "Create/Delete Virtual Environment" -msgstr "" +msgstr "가상 환경 생성/삭제" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:85 msgid "Compile ProtoBuf Definitions" -msgstr "" +msgstr "ProtoBuf 정의 컴파일" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:92 msgid "Auto-Format Code" -msgstr "" +msgstr "자동 포맷 코드" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:99 msgid "Run Linters and Tests" -msgstr "" +msgstr "린터 및 테스트 실행" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:106 msgid "Add a pre-commit hook" -msgstr "" +msgstr "사전 커밋 훅 추가" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 msgid "" @@ -2068,26 +2252,30 @@ msgid "" "commit hook is configured to execute two primary operations: " "``./dev/format.sh`` and ``./dev/test.sh`` scripts." msgstr "" +"개발자는 `pre-commit `_ 라이브러리를 " +"사용하여 사전 커밋 훅을 워크플로에 통합할 수 있습니다. 사전 커밋 훅은 두 " +"가지 기본 작업을 실행하도록 구성됩니다:``./dev/format.sh`` 및 ``./dev/test." +"sh`` 스크립트." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 msgid "There are multiple ways developers can use this:" -msgstr "" +msgstr "개발자가 이것을 사용할 수 있는 여러가지 방법이 있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 msgid "Install the pre-commit hook to your local git directory by simply running:" -msgstr "" +msgstr "간단하게 실행하여 로컬 git 디렉터리에 사전 커밋 훅을 설치하세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 msgid "" "Each ``git commit`` will trigger the execution of formatting and " "linting/test scripts." -msgstr "" +msgstr "각 ``git 커밋``은 포맷 및 린팅/테스트 스크립트의 실행을 트리거합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 msgid "" "If in a hurry, bypass the hook using ``--no-verify`` with the ``git " "commit`` command. ::" -msgstr "" +msgstr "급한 경우 ``git commit`` 명령과 함께 `--no-verify``를 사용하여 훅을 넘기세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 msgid "" @@ -2095,16 +2283,19 @@ msgid "" "possible to execute a one-time check prior to committing changes by using" " the following command:" msgstr "" +"훅을 영구적으로 설치하지 않으려는 개발자의 경우 다음 명령을 사용하여 변경 " +"사항을 커밋하기 전에 일회성 검사를 실행할 수 있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 msgid "" "This executes the formatting and linting checks/tests on all the files " "without modifying the default behavior of ``git commit``." -msgstr "" +msgstr "이렇게 하면 ``git commit``의 기본 동작을 수정하지 않고 모든 파일에 대해 포맷 " +"및 린팅 검사/테스트를 실행합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 msgid "Run Github Actions (CI) locally" -msgstr "" +msgstr "로컬에서 Github Action(CI) 실행하기" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 msgid "" @@ -2113,32 +2304,38 @@ msgid "" "Please refer to the installation instructions under the linked repository" " and run the next command under Flower main cloned repository folder::" msgstr "" +"개발자는 `Act `_를 사용하여 로컬 환경에서 " +"전체 Github Actions 워크플로우 세트를 실행할 수 있습니다. 링크된 레포지토리 " +"아래의 설치 지침을 참조하여 Flower 메인 클론 레포지토리 폴더 아래에서 다음 " +"명령을 실행하세요::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 msgid "" "The Flower default workflow would run by setting up the required Docker " "machines underneath." -msgstr "" +msgstr "Flower 기본 워크플로우는 아래에 필요한 Docker 머신을 설정하여 실행합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:147 msgid "Build Release" -msgstr "" +msgstr "릴리즈 빌드" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" "Flower uses Poetry to build releases. The necessary command is wrapped in" " a simple script::" -msgstr "" +msgstr "Flower는 Poetry를 사용하여 릴리즈를 빌드합니다. 필요한 명령은 간단한 " +"스크립트로 래핑됩니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" "The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" " the :code:`/dist` subdirectory." -msgstr "" +msgstr "결과물인 :code:`.whl` 및 :code:`.tar.gz` 릴리즈는 :code:`/dist` 하위 " +"디렉터리에 저장됩니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 msgid "Build Documentation" -msgstr "" +msgstr "문서 빌드" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" @@ -2146,14 +2343,17 @@ msgid "" "There's no convenience script to re-build the documentation yet, but it's" " pretty easy::" msgstr "" +"Flower의 문서는 `Sphinx `_를 사용합니다. 아직 " +"문서를 다시 작성할 수 있는 편리한 스크립트는 없지만 다음과 같이 쉽게 작성할 " +"수 있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 msgid "This will generate HTML documentation in ``doc/build/html``." -msgstr "" +msgstr "그러면 ``doc/build/html``에 HTML 문서가 생성됩니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:2 msgid "Example: FedBN in PyTorch - From Centralized To Federated" -msgstr "" +msgstr "예시: PyTorch에서 FedBN - Centralize에서 Federated으로" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 msgid "" @@ -2166,11 +2366,18 @@ msgid "" "PyTorch - From Centralized To Federated `." msgstr "" +"이 튜토리얼에서는 non-iid data를 위해 설계된 federated 훈련 전략인 `FedBN " +"`_으로 기존 머신러닝 워크로드의 federated " +"버전을 구축하기 위해 Flower를 사용하는 방법을 보여드립니다. 우리는 PyTorch를 " +"사용하여 CIFAR-10 데이터 세트에서 컨볼루션 신경망(일괄 정규화 레이어 포함)을 " +"훈련하고 있습니다. FedBN을 적용할 때, :doc:`예제: 파이토치 -Centralized에서 " +"Federated으로 ` 와 비교했을 " +"때 몇 가지 사항만 변경 하면 됩니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 #: ../../source/example-pytorch-from-centralized-to-federated.rst:10 msgid "Centralized Training" -msgstr "" +msgstr "Centralized 훈련" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 msgid "" @@ -2179,17 +2386,21 @@ msgid "" "thing to do is modifying the file called :code:`cifar.py`, revised part " "is shown below:" msgstr "" +"모든 파일은 :doc:`예제: 파이토치 - Centralized에서 Federated으로 `를 기반으로 수정합니다. :code:`cifar." +"py`라는 파일을 수정하기만 하면 되며, 수정된 부분은 아래와 같습니다:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:13 msgid "" "The model architecture defined in class Net() is added with Batch " "Normalization layers accordingly." -msgstr "" +msgstr "Net() 클래스에 정의된 모델 아키텍처는 그에 따라 배치 정규화 레이어가 " +"추가됩니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:41 #: ../../source/example-pytorch-from-centralized-to-federated.rst:157 msgid "You can now run your machine learning workload:" -msgstr "" +msgstr "이제 머신 러닝 워크로드를 실행할 수 있습니다:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 msgid "" @@ -2198,11 +2409,14 @@ msgid "" "federated learning system within FedBN, the system consists of one server" " and two clients." msgstr "" +"지금까지는 파이토치를 사용해 본 적이 있다면 상당히 익숙하게 보일 것입니다. " +"다음 단계로 넘어가서 우리가 구축한 것을 사용하여 FedBN 내에서 하나의 서버와 " +"두 개의 클라이언트로 구성된 federated 학습 시스템을 만들어 보겠습니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 #: ../../source/example-pytorch-from-centralized-to-federated.rst:167 msgid "Federated Training" -msgstr "" +msgstr "Federated 훈련" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:53 msgid "" @@ -2213,12 +2427,21 @@ msgid "" ":doc:`Example: PyTorch - From Centralized To Federated `. first." msgstr "" +":doc:`예제: 파이토치 - Centralized에서 Federated으로 `를 읽었다면, 다음 부분은 쉽게 따라할 수 있으며 " +":code:`client.py`의 :code:`get_parameters`와 :code:`set_parameters` 함수만 " +"수정해야 합니다. 그렇지 않은 경우 :doc:`예제: 파이토치 - Centralized에서 " +"Federated으로 `를 먼저 " +"읽어보세요." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" "Our example consists of one *server* and two *clients*. In FedBN, " ":code:`server.py` keeps unchanged, we can start the server directly." msgstr "" +"이 예제는 하나의 *서버*와 두 개의 *클라이언트*로 구성됩니다. FedBN에서 " +":code:`server.py`는 변경되지 않고 그대로 유지되므로 서버를 바로 시작할 수 " +"있습니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" @@ -2227,10 +2450,14 @@ msgid "" "we will exclude batch normalization parameters from model parameter list " "when sending to or receiving from the server." msgstr "" +"마지막으로, :code:`client.py`에서 :code:`get_parameters` 및 " +":code:`set_parameters`를 변경하여 *client* 로직을 수정할 것입니다. 서버로 " +"보내거나 서버에서 받을 때 모델 파라미터 목록에서 배치 정규화 파라미터를 " +"제외할 수 있습니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 msgid "Now, you can now open two additional terminal windows and run" -msgstr "" +msgstr "이제 두 개의 터미널 창을 추가로 열고 다음을 실행할 수 있습니다" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" @@ -2238,13 +2465,16 @@ msgid "" "so) and see your (previously centralized) PyTorch project run federated " "learning with FedBN strategy across two clients. Congratulations!" msgstr "" +"를 입력하고(클릭하기 전에 서버가 계속 실행 중인지 확인하세요), (이전에 " +"centralized된) PyTorch 프로젝트가 두 클라이언트에서 FedBN으로 federated " +"학습을 실행하는 것을 확인합니다. 축하합니다!" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 #: ../../source/example-pytorch-from-centralized-to-federated.rst:310 #: ../../source/tutorial-quickstart-jax.rst:283 msgid "Next Steps" -msgstr "" +msgstr "다음 단계" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" @@ -2256,10 +2486,16 @@ msgid "" "using different subsets of CIFAR-10 on each client? How about adding more" " clients?" msgstr "" +"이 예제의 전체 소스 코드는 '여기 `_'에서 확인할 수 있습니다. " +"물론 이 예제는 두 클라이언트가 완전히 동일한 데이터 세트를 로드하기 때문에 " +"다소 지나치게 단순화되어 있으며, 이는 현실적이지 않습니다. 이제 이 주제를 더 " +"자세히 살펴볼 준비가 되셨습니다. 각 클라이언트에서 서로 다른 CIFAR-10의 하위 " +"집합을 사용해 보는 것은 어떨까요? 클라이언트를 더 추가하는 것은 어떨까요?" #: ../../source/example-jax-from-centralized-to-federated.rst:2 msgid "Example: JAX - Run JAX Federated" -msgstr "" +msgstr "예시: JAX - JAX Federated 실행" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 @@ -2275,6 +2511,15 @@ msgid "" " tutorial`. Then, we build upon the centralized training code to run the " "training in a federated fashion." msgstr "" +"이 튜토리얼에서는 Flower를 사용하여 기존 JAX 워크로드의 federated 버전을 " +"구축하는 방법을 보여드립니다. JAX를 사용해 scikit-learn 데이터 세트에서 선형 " +"회귀 모델을 훈련하고 있습니다. 예제는 '파이토치 - Centralized에서 " +"Federated으로 `_ 워크스루와 유사하게 구성하겠습니다. 먼저, `" +"JAX를 사용한 선형 회귀 `_ 튜토리얼`을 기반으로 centralized 학습 접근 " +"방식을 구축합니다. 그런 다음 centralized 트레이닝 코드를 기반으로 federated " +"방식으로 트레이닝을 실행합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 @@ -2282,11 +2527,13 @@ msgid "" "Before we start building our JAX example, we need install the packages " ":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" +"JAX 예제 빌드를 시작하기 전에 :code:`jax`, :code:`jaxlib`, :code:`scikit-" +"learn`, :code:`flwr` 패키지를 설치해야 합니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:18 #: ../../source/tutorial-quickstart-jax.rst:24 msgid "Linear Regression with JAX" -msgstr "" +msgstr "JAX를 사용한 선형 회귀" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 @@ -2296,6 +2543,9 @@ msgid "" "explanation of what's going on then have a look at the official `JAX " "documentation `_." msgstr "" +"먼저 :code:`선형 회귀` 모델을 기반으로 하는 centralized 훈련 코드에 대한 " +"간략한 설명부터 시작하겠습니다. 더 자세한 설명을 원하시면 공식 `JAX 문서 " +"`_를 참조하세요." #: ../../source/example-jax-from-centralized-to-federated.rst:23 #: ../../source/tutorial-quickstart-jax.rst:29 @@ -2309,20 +2559,28 @@ msgid "" "not yet import the :code:`flwr` package for federated learning. This will" " be done later." msgstr "" +"전통적인(centralized) 선형 회귀 훈련에 필요한 모든 구성 요소가 포함된 " +":code:`jax_training.py`라는 새 파일을 생성해 보겠습니다. 먼저, JAX 패키지인 " +":code:`jax`와 :code:`jaxlib`를 가져와야 합니다. 또한 데이터 세트에 " +":code:`make_regression`을 사용하고 데이터 세트를 학습 및 테스트 세트로 " +"분할하기 위해 :code:`train_test_split`을 사용하므로 :code:`sklearn`을 " +"가져와야 합니다. 연합 학습을 위해 아직 :code:`flwr` 패키지를 가져오지 않은 " +"것을 볼 수 있습니다. 이 작업은 나중에 수행됩니다." #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" "The :code:`load_data()` function loads the mentioned training and test " "sets." -msgstr "" +msgstr "code:`load_data()` 함수는 앞서 언급한 트레이닝 및 테스트 세트를 로드합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" "The model architecture (a very simple :code:`Linear Regression` model) is" " defined in :code:`load_model()`." -msgstr "" +msgstr "모델 아키텍처(매우 간단한 :code:`선형 회귀` 모델)는 :code:`load_model()`에 " +"정의되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 @@ -2333,6 +2591,10 @@ msgid "" " is separate since JAX takes derivatives with a :code:`grad()` function " "(defined in the :code:`main()` function and called in :code:`train()`)." msgstr "" +"이제 훈련 집합을 반복하고 각 훈련 예제 배치에 대해 손실을 측정하는(함수 " +":code:`loss_fn()`) 훈련(함수 :code:`train()`)을 정의해야 합니다. JAX는 " +":code:`grad()` 함수(:code:`main()` 함수에 정의되고 :code:`train()`에서 " +"호출됨)로 파생물을 취하므로 손실 함수는 분리되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 @@ -2341,6 +2603,8 @@ msgid "" ":code:`evaluation()`. The function takes all test examples and measures " "the loss of the linear regression model." msgstr "" +"모델의 평가는 :code:`evaluation()` 함수에 정의되어 있습니다. 이 함수는 모든 " +"테스트 예제를 가져와 선형 회귀 모델의 손실을 측정합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:88 #: ../../source/tutorial-quickstart-jax.rst:94 @@ -2350,11 +2614,14 @@ msgid "" "As already mentioned, the :code:`jax.grad()` function is defined in " ":code:`main()` and passed to :code:`train()`." msgstr "" +"데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으므로 이제 모든 것을 " +"종합하여 JAX를 사용 모델을 훈련할 수 있습니다. 이미 언급했듯이 :code:`jax." +"grad()` 함수는 :code:`main()`에 정의되어 :code:`train()`에 전달됩니다." #: ../../source/example-jax-from-centralized-to-federated.rst:105 #: ../../source/tutorial-quickstart-jax.rst:111 msgid "You can now run your (centralized) JAX linear regression workload:" -msgstr "" +msgstr "이제 (centralized) JAX 선형 회귀 워크로드를 실행할 수 있습니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 @@ -2363,11 +2630,14 @@ msgid "" "Let's take the next step and use what we've built to create a simple " "federated learning system consisting of one server and two clients." msgstr "" +"지금까지는 JAX를 사용해 본 적이 있다면 이 모든 것이 상당히 익숙해 보일 " +"것입니다. 다음 단계로 넘어가서 우리가 구축한 것을 사용하여 하나의 서버와 두 " +"개의 클라이언트로 구성된 간단한 연합 학습 시스템을 만들어 보겠습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:115 #: ../../source/tutorial-quickstart-jax.rst:121 msgid "JAX meets Flower" -msgstr "" +msgstr "JAX와 Flower의 만남" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 @@ -2381,6 +2651,13 @@ msgid "" "parameter updates. This describes one round of the federated learning " "process, and we repeat this for multiple rounds." msgstr "" +"기존 워크로드를 federating하는 개념은 항상 동일하고 이해하기 쉽습니다. 서버*" +"를 시작한 다음 *서버*에 연결된 *클라이언트*에 대해 :code:`jax_training.py`의 " +"코드를 사용해야 합니다. *서버*는 모델 파라미터를 클라이언트로 전송합니다. " +"클라이언트는 학습을 실행하고 파라미터를 업데이트합니다. 업데이트된 " +"파라미터는 *서버*로 다시 전송되며, 수신된 모든 파라미터 업데이트의 평균을 " +"구합니다. 이는 federated 학습 프로세스의 한 라운드를 설명하며, 이 과정을 " +"여러 라운드에 걸쳐 반복합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:123 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 @@ -2391,12 +2668,16 @@ msgid "" ":code:`flwr`. Next, we use the :code:`start_server` function to start a " "server and tell it to perform three rounds of federated learning." msgstr "" +"이 예제는 하나의 *서버*와 두 개의 *클라이언트*로 구성됩니다. 먼저 " +":code:`server.py`를 설정해 보겠습니다. *server*는 Flower 패키지 :code:`flwr`" +"를 가져와야 합니다. 다음으로, :code:`start_server` 함수를 사용하여 서버를 " +"시작하고 세 차례의 federated 학습을 수행하도록 지시합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:133 #: ../../source/example-pytorch-from-centralized-to-federated.rst:191 #: ../../source/tutorial-quickstart-jax.rst:139 msgid "We can already start the *server*:" -msgstr "" +msgstr "이미 *서버*를 시작할 수 있습니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 @@ -2406,6 +2687,10 @@ msgid "" " *client* needs to import :code:`flwr`, but also :code:`jax` and " ":code:`jaxlib` to update the parameters on our JAX model:" msgstr "" +"마지막으로, :code:`client.py`에서 *client* 로직을 정의하고 " +":code:`jax_training.py`에서 이전에 정의한 JAX 교육을 기반으로 빌드합니다. " +"*클라이언트*는 :code:`flwr`을 가져와야 하며, JAX 모델의 파라미터를 " +"업데이트하기 위해 :code:`jax` 및 :code:`jaxlib`도 가져와야 합니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 @@ -2421,11 +2706,20 @@ msgid "" "parameters, one method for training the model, and one method for testing" " the model:" msgstr "" +"Flower *클라이언트*를 구현한다는 것은 기본적으로 :code:`flwr.client.Client` " +"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 " +"의미합니다. 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, 이를 " +":code:`FlowerClient`라고 부를 것입니다. :code:`NumPyClient`는 필요한 일부 " +"보일러플레이를 피할 수 있기 때문에 NumPy 상호 운용성이 좋은 프레임워크(예: " +"JAX)를 사용하는 경우 :code:`Client`보다 구현하기가 약간 더 쉽습니다. " +"code:`FlowerClient`는 모델 매개변수를 가져오거나 설정하는 메서드 2개, 모델 " +"학습을 위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 총 4개의 메서드를 " +"구현해야 합니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:161 #: ../../source/tutorial-quickstart-jax.rst:167 msgid ":code:`set_parameters (optional)`" -msgstr "" +msgstr ":code:`set_parameters (선택사항)`" #: ../../source/example-jax-from-centralized-to-federated.rst:160 #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 @@ -2433,12 +2727,12 @@ msgstr "" msgid "" "set the model parameters on the local model that are received from the " "server" -msgstr "" +msgstr "서버에서 수신한 로컬 모델의 모델 파라미터를 설정합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:161 #: ../../source/tutorial-quickstart-jax.rst:167 msgid "transform parameters to NumPy :code:`ndarray`'s" -msgstr "" +msgstr "매개 변수를 NumPy :code:`ndarray`로 변환" #: ../../source/example-jax-from-centralized-to-federated.rst:162 #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 @@ -2446,7 +2740,8 @@ msgstr "" msgid "" "loop over the list of model parameters received as NumPy " ":code:`ndarray`'s (think list of neural network layers)" -msgstr "" +msgstr "(신경망 레이어 목록으로 생각하면 됩니다) NumPy :code:`ndarray`로 받은 모델 " +"파라미터 목록에 대해 반복합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:163 #: ../../source/example-pytorch-from-centralized-to-federated.rst:221 @@ -2454,7 +2749,7 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:155 #: ../../source/tutorial-quickstart-scikitlearn.rst:118 msgid ":code:`get_parameters`" -msgstr "" +msgstr ":code:`get_parameters`" #: ../../source/example-jax-from-centralized-to-federated.rst:164 #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 @@ -2463,6 +2758,8 @@ msgid "" "get the model parameters and return them as a list of NumPy " ":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" +"모델 매개변수를 가져와서 NumPy :code:`ndarray`의 목록으로 반환합니다(이는 " +":code:`flwr.client.NumPyClient`가 기대하는 바와 같습니다)" #: ../../source/example-jax-from-centralized-to-federated.rst:167 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 @@ -2470,7 +2767,7 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:161 #: ../../source/tutorial-quickstart-scikitlearn.rst:125 msgid ":code:`fit`" -msgstr "" +msgstr ":code:`fit`" #: ../../source/example-jax-from-centralized-to-federated.rst:166 #: ../../source/example-jax-from-centralized-to-federated.rst:170 @@ -2481,18 +2778,18 @@ msgstr "" msgid "" "update the parameters of the local model with the parameters received " "from the server" -msgstr "" +msgstr "서버에서 받은 파라미터로 로컬 모델의 파라미터를 업데이트합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:167 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 #: ../../source/tutorial-quickstart-jax.rst:173 msgid "train the model on the local training set" -msgstr "" +msgstr "로컬 훈련 세트에서 모델을 훈련합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:168 #: ../../source/tutorial-quickstart-jax.rst:174 msgid "get the updated local model parameters and return them to the server" -msgstr "" +msgstr "업데이트된 로컬 모델 파라미터를 가져와 서버로 반환합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:172 #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 @@ -2500,18 +2797,18 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:164 #: ../../source/tutorial-quickstart-scikitlearn.rst:128 msgid ":code:`evaluate`" -msgstr "" +msgstr ":code:`evaluate`" #: ../../source/example-jax-from-centralized-to-federated.rst:171 #: ../../source/example-pytorch-from-centralized-to-federated.rst:229 #: ../../source/tutorial-quickstart-jax.rst:177 msgid "evaluate the updated model on the local test set" -msgstr "" +msgstr "로컬 테스트 세트에서 업데이트된 모델을 평가합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:172 #: ../../source/tutorial-quickstart-jax.rst:178 msgid "return the local loss to the server" -msgstr "" +msgstr "로컬 손실을 서버로 반환합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 @@ -2520,6 +2817,8 @@ msgid "" ":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" " `NumPyClient`." msgstr "" +"어려운 부분은 JAX 모델 매개변수를 :code:`DeviceArray`에서 :code:`NumPy " +"ndarray`로 변환하여 `NumPyClient`와 호환되도록 하는 것입니다." #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 @@ -2532,11 +2831,17 @@ msgid "" "annotations to give you a better understanding of the data types that get" " passed around." msgstr "" +"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전에 " +":code:`jax_training.py`에 정의된 함수 :code:`train()`과 :code:`evaluate()`를 " +"사용합니다. 따라서 여기서 우리가 실제로 하는 일은 이미 정의된 함수 중 훈련과 " +"평가를 위해 호출할 함수를 :code:`NumPyClient` 서브클래스를 통해 Flower에게 " +"알려주는 것입니다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 유형 type " +"annotation을 포함했습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:245 #: ../../source/tutorial-quickstart-jax.rst:251 msgid "Having defined the federation process, we can run it." -msgstr "" +msgstr "federation 프로세스를 정의했으면 이제 실행할 수 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:268 #: ../../source/example-pytorch-from-centralized-to-federated.rst:301 @@ -2551,6 +2856,8 @@ msgid "" "so) and see your JAX project run federated learning across two clients. " "Congratulations!" msgstr "" +"를 입력하고(그 전에 서버가 계속 실행 중인지 확인하세요) 두 클라이언트에서 " +"federated 학습을 실행하는 JAX 프로젝트를 확인합니다. 축하합니다!" #: ../../source/example-jax-from-centralized-to-federated.rst:279 #: ../../source/tutorial-quickstart-jax.rst:285 @@ -2560,6 +2867,10 @@ msgid "" "/quickstart-jax>`_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" +"이 예제의 소스 코드는 시간이 지남에 따라 개선되었으며 여기에서 확인할 수 " +"있습니다: 'Quickstart JAX `_. 두 클라이언트가 동일한 데이터 세트를 로드하기 때문에 이 " +"예제는 다소 단순화되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 @@ -2568,10 +2879,13 @@ msgid "" " sophisticated model or using a different dataset? How about adding more " "clients?" msgstr "" +"이제 이 주제를 더 자세히 살펴볼 준비가 되었습니다. 더 정교한 모델을 " +"사용하거나 다른 데이터 집합을 사용해 보는 것은 어떨까요? 클라이언트를 더 " +"추가하는 것은 어떨까요?" #: ../../source/example-pytorch-from-centralized-to-federated.rst:2 msgid "Example: PyTorch - From Centralized To Federated" -msgstr "" +msgstr "예제: 파이토치 - 중앙 Centralized에서 Federated으로" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" @@ -2584,6 +2898,13 @@ msgid "" "tutorial. Then, we build upon the centralized training code to run the " "training in a federated fashion." msgstr "" +"이 튜토리얼에서는 Flower를 사용해 기존 머신 러닝 워크로드의 federated 버전을 " +"구축하는 방법을 보여드립니다. 여기서는 PyTorch를 사용해 CIFAR-10 데이터 " +"세트에서 컨볼루션 신경망을 훈련합니다. 먼저, 'PyTorch로 딥 러닝 " +"`_ " +"튜토리얼을 기반으로 centralized 학습 접근 방식을 사용하여 이 머신 러닝 " +"작업을 소개합니다. 그런 다음 centralized 훈련 코드를 기반으로 federated 방식 " +"훈련을 실행합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" @@ -2592,6 +2913,10 @@ msgid "" "look at the official `PyTorch tutorial " "`_." msgstr "" +"centralized CNN 트레이닝 코드에 대한 간략한 설명부터 시작하겠습니다. 무슨 " +"일이 일어나고 있는지 더 자세히 설명하려면 공식 `PyTorch 튜토리얼 " +"`_을 " +"참조하세요." #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" @@ -2602,6 +2927,12 @@ msgid "" "federated learning. You can keep all these imports as they are even when " "we add the federated learning components at a later point." msgstr "" +"CIFAR-10에 대한 기존 (centralized) 교육에 필요한 모든 구성 요소가 포함된 " +":code:`cifar.py`라는 새 파일을 생성해 보겠습니다. 먼저, 필요한 모든 " +"패키지(예: :code:`torch` 및 :code:`torchvision`)를 가져와야 합니다. " +"federated 학습을 위한 패키지를 가져오지 않는 것을 확인 할 수 있습니. 나중에 " +"federated 학습 구성 요소를 추가할 때에도 이러한 모든 가져오기를 그대로 " +"유지할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" @@ -2609,12 +2940,17 @@ msgid "" "learning workload. The model architecture (a very simple Convolutional " "Neural Network) is defined in :code:`class Net()`." msgstr "" +"이미 언급했듯이 이 머신 러닝 워크로드에는 CIFAR-10 데이터 세트를 사용합니다. " +"모델 아키텍처(매우 간단한 컨볼루션 신경망)는 :code:`class Net()`에 정의되어 " +"있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" "The :code:`load_data()` function loads the CIFAR-10 training and test " "sets. The :code:`transform` normalized the data after loading." msgstr "" +":code:`load_data()` 함수는 CIFAR-10 훈련 및 테스트 세트를 로드합니다. " +":code:`transform`은 로드 후 데이터를 정규화합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" @@ -2622,6 +2958,9 @@ msgid "" " over the training set, measures the loss, backpropagates it, and then " "takes one optimizer step for each batch of training examples." msgstr "" +"이제 학습 집합을 반복하고, 손실을 측정하고, 이를 역전파한 다음 각 학습 예제 " +"배치에 대해 하나의 최적화 단계를 수행하는 학습(함수 :code:`train()`)을 " +"정의해야 합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" @@ -2629,12 +2968,15 @@ msgid "" "The function loops over all test samples and measures the loss of the " "model based on the test dataset." msgstr "" +"모델 평가는 :code:`test()` 함수에 정의되어 있습니다. 이 함수는 모든 테스트 " +"샘플을 반복하고 테스트 데이터 세트에 따라 모델의 손실을 측정합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " "evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "" +msgstr "데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으면 모든 것을 종합하여 " +"CIFAR-10에서 CNN을 훈련할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" @@ -2643,6 +2985,9 @@ msgid "" "simple federated learning system consisting of one server and two " "clients." msgstr "" +"지금까지는 파이토치를 사용해 본 적이 있다면 상당히 익숙하게 보일 것입니다. " +"다음 단계로 넘어가서 구축한 것을 사용하여 하나의 서버와 두 개의 클라이언트로 " +"구성된 간단한 연합 학습 시스템을 만들어 보겠습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" @@ -2654,12 +2999,19 @@ msgid "" "a federated fashion, then you'd have to change most of your code and set " "everything up from scratch. This can be a considerable effort." msgstr "" +"이전 섹션에서 설명한 간단한 머신 러닝 프로젝트는 단일 데이터 세트(CIFAR-10)" +"로 모델을 학습시키는데, 이를 centralized 학습이라고 부릅니다. 이전 섹션에서 " +"설명한 centralized 학습의 개념은 대부분 알고 계실 것이며, 많은 분들이 이전에 " +"사용해 보셨을 것입니다. 일반적으로 머신 러닝 워크로드를 federated 방식으로 " +"실행하려면 대부분의 코드를 변경하고 모든 것을 처음부터 다시 설정해야 합니다. " +"이는 상당한 노력이 필요할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" "However, with Flower you can evolve your pre-existing code into a " "federated learning setup without the need for a major rewrite." -msgstr "" +msgstr "하지만 Flower를 사용하면 대대적인 재작성 없이도 기존 코드를 연합 학습 " +"설정으로 발전시킬 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" @@ -2671,6 +3023,12 @@ msgid "" "parameter updates. This describes one round of the federated learning " "process and we repeat this for multiple rounds." msgstr "" +"개념은 이해하기 쉽습니다. *서버*를 시작한 다음 *서버*에 연결된 *클라이언트*" +"에 대해 :code:`cifar.py`의 코드를 사용해야 합니다. *서버*는 모델 파라미터를 " +"클라이언트로 전송합니다. *클라이언트*는 학습을 실행하고 파라미터를 " +"업데이트합니다. 업데이트된 파라미터는 *서버*로 다시 전송되며, *서버*는 " +"수신된 모든 파라미터 업데이트의 평균을 구합니다. 이것은 federated 학습 " +"프로세스의 한 라운드를 설명하며 여러 라운드에 걸쳐 이 과정을 반복합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" @@ -2679,6 +3037,10 @@ msgid "" "Our *client* needs to import :code:`flwr`, but also :code:`torch` to " "update the parameters on our PyTorch model:" msgstr "" +"마지막으로, :code:`client.py`에서 *client* 로직을 정의하고 :code:`cifar.py`" +"에서 이전에 정의한 centralized 학습을 기반으로 구축합니다. *클라이언트*는 " +":code:`flwr`을 가져와야 하며, PyTorch 모델의 파라미터를 업데이트하기 위해 " +":code:`torch`도 가져와야 합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" @@ -2693,18 +3055,27 @@ msgid "" "getting/setting model parameters, one method for training the model, and " "one method for testing the model:" msgstr "" +"Flower *클라이언트*를 구현한다는 것은 기본적으로 :code:`flwr.client.Client` " +"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 " +"의미합니다. 우리의 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, " +"이를 :code:`CifarClient`라고 부를 것입니다. :code:`NumPyClient`는 파이토치나 " +"텐서플로우/Keras처럼 NumPy 상호운용성이 좋은 프레임워크를 사용하는 경우 " +"필요한 일부 보일러플레이트를 피하기 때문에 :code:`Client`보다 구현하기가 " +"조금 더 쉽습니다. code:`CifarClient`는 모델 파라미터를 가져오거나 설정하는 " +"메서드 2개, 모델 학습을 위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 네 " +"가지 메서드를 구현해야 합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 msgid ":code:`set_parameters`" -msgstr "" +msgstr ":code:`set_parameters`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:226 msgid "get the updated local model weights and return them to the server" -msgstr "" +msgstr "업데이트된 로컬 모델 가중치를 가져와 서버로 반환합니다" #: ../../source/example-pytorch-from-centralized-to-federated.rst:230 msgid "return the local loss and accuracy to the server" -msgstr "" +msgstr "로컬 손실 및 정확도를 서버에 반환합니다" #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" @@ -2716,6 +3087,12 @@ msgid "" "annotations to give you a better understanding of the data types that get" " passed around." msgstr "" +"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전에 " +":code:`cifar.py`에 정의된 함수인 :code:`train()`과 :code:`test()`를 " +"활용합니다. 따라서 여기서 실제로 하는 일은 :code:`NumPyClient` 서브클래스를 " +"통해 이미 정의된 함수 중 훈련과 평가를 위해 호출할 함수를 Flower에 알려주는 " +"것입니다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 type annotations을 " +"포함했습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" @@ -2725,6 +3102,11 @@ msgid "" "with the function :code:`fl.client.start_client()` by pointing it at the " "same IP address we used in :code:`server.py`:" msgstr "" +"이제 모델과 데이터를 모두 로드하는 함수를 정의하고, :code:`CifarClient`를 " +"생성하고, 이 클라이언트를 시작하는 작업만 남았습니다. 코드:`cifar.py`를 " +"사용하여 데이터와 모델을 로드합니다. :code:`server.py`에서 사용한 것과 " +"동일한 IP 주소를 지정하여 :code:`fl.client.start_client()` 함수로 " +":code:`CifarClient`를 시작합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" @@ -2732,6 +3114,9 @@ msgid "" "and see your (previously centralized) PyTorch project run federated " "learning across two clients. Congratulations!" msgstr "" +"를 입력하고(그 전에 서버가 실행 중인지 확인하세요) (이전에는centralized) " +"PyTorch 프로젝트가 두 클라이언트에서 federated 학습을 실행하는 것을 " +"확인합니다. 축하합니다!" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" @@ -2743,12 +3128,19 @@ msgid "" " further. How about using different subsets of CIFAR-10 on each client? " "How about adding more clients?" msgstr "" +"이 예제의 전체 소스 코드: `파이토치: 중앙 Centralized에서 Federated으로 " +"(코드) `_. 물론 이 예제는 두 클라이언트가 완전히 동일한 " +"데이터 세트를 로드하기 때문에 다소 지나치게 단순화되어 있으며, 이는 " +"현실적이지 않습니다. 이제 이 주제를 더 자세히 살펴볼 준비가 되셨습니다. 각 " +"클라이언트에서 서로 다른 CIFAR-10의 하위 집합을 사용해 보는 것은 어떨까요? " +"클라이언트를 더 추가하는 것은 어떨까요?" #: ../../source/explanation-differential-privacy.rst:2 #: ../../source/explanation-differential-privacy.rst:11 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:303 msgid "Differential Privacy" -msgstr "" +msgstr "차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:3 msgid "" @@ -2758,6 +3150,10 @@ msgid "" "data is also sensitive and there is a risk of compromising individual " "privacy." msgstr "" +"의료, 금융 거래, 사용자 선호도 등과 같은 데이터 세트의 정보는 가치 있고 " +"과학적 혁신의 잠재력을 지니고 있으며 중요한 비즈니스 인사이트를 제공합니다. " +"그러나 이러한 데이터는 또한 민감한 정보이며 개인의 프라이버시를 침해할 " +"위험이 있습니다." #: ../../source/explanation-differential-privacy.rst:6 msgid "" @@ -2766,6 +3162,9 @@ msgid "" "differential privacy comes in. It provides the possibility of analyzing " "data while ensuring the privacy of individuals." msgstr "" +"익명화와 같은 기존 방법만으로는 재식별 및 데이터 연결과 같은 공격으로 인해 " +"효과가 없습니다. 그래서 차분 프라이버시가 등장했습니다. 차등 개인정보 보호는 " +"개인의 프라이버시를 보장하면서 데이터를 분석할 수 있는 가능성을 제공합니다." #: ../../source/explanation-differential-privacy.rst:12 msgid "" @@ -2776,10 +3175,15 @@ msgid "" "preserves group patterns while obscuring individual details, ensuring the" " individual's information remains hidden in the crowd." msgstr "" +"하나의 레코드(예: 앨리스의 데이터)를 제외하고는 동일한 두 개의 데이터 세트가 " +"있다고 상상해 보세요. 차분 프라이버(DP)는 평균 소득 계산과 같은 모든 분석(M)" +"이 두 데이터 세트에 대해 거의 동일한 결과를 산출하도록 보장합니다(O와 O' 는 " +"비슷할 것입니다). 이렇게 하면 그룹 패턴은 보존하면서 개별 세부 정보는 가려져 " +"개인의 정보가 군중 속에 숨겨집니다." #: ../../source/explanation-differential-privacy.rst:-1 msgid "DP Intro" -msgstr "" +msgstr "DP 소개" #: ../../source/explanation-differential-privacy.rst:22 msgid "" @@ -2788,10 +3192,13 @@ msgid "" "individual in the data while preserving the overall accuracy of the " "analysis." msgstr "" +"DP를 달성하기 위해 가장 일반적으로 사용되는 메커니즘 중 하나는 분석의 " +"전반적인 정확도를 유지하면서 데이터에서 각 개인의 기여도를 가릴 수 있도록 " +"분석 결과에 충분한 노이즈를 추가하는 것입니다." #: ../../source/explanation-differential-privacy.rst:25 msgid "Formal Definition" -msgstr "" +msgstr "공식 정의" #: ../../source/explanation-differential-privacy.rst:26 msgid "" @@ -2804,12 +3211,20 @@ msgid "" "databases, D :sub:`1` and D :sub:`2`, that differ in only a single " "record, and for all possible outputs S ⊆ Range(A):" msgstr "" +"차분 프라이버시(DP)는 공격자가 무작위 알고리즘의 출력을 통해 유추할 수 있는 " +"정보에 대해 통계적 보장을 제공합니다. 이는 노이즈를 추가하여 알고리즘의 " +"출력에 대한 한 개인의 영향력에 대한 무조건적인 상한선을 제공합니다[1]. " +"무작위 메커니즘 M은 하나의 레코드만 다른 두 개의 인접 데이터베이스인 " +"D:sub:`1`과 D:sub:`2`의 경우, 가능한 모든 출력 S ⊆ Range(A)에 대해 (:math:`" +"\\epsilon`, :math:`\\delta`)-차분 프라이버시를 제공합니다:" #: ../../source/explanation-differential-privacy.rst:32 msgid "" "\\small\n" "P[M(D_{1} \\in A)] \\leq e^{\\delta} P[M(D_{2} \\in A)] + \\delta" msgstr "" +"\\small\n" +"P[M(D_{1} \\in A)] \\leq e^{\\delta} P[M(D_{2} \\in A)] + \\delta" #: ../../source/explanation-differential-privacy.rst:38 msgid "" @@ -2822,10 +3237,17 @@ msgid "" "proportional to the sensitivity of the output, which measures the maximum" " change in the output due to the inclusion or removal of a single record." msgstr "" +"프라이버시 예산이라고도 하는 :math:`\\epsilon` 매개변수는 프라이버시 손실을 " +"측정하는 지표입니다. 이 매개변수는 프라이버시와 효용의 균형을 제어하며, " +":math:`\\epsilon` 값이 낮을수록 프라이버시 수준이 높지만 효용도 감소할 " +"가능성이 높습니다. math:`\\delta` 매개변수는 상한값인 :math:`\\epsilon`이 " +"적용되지 않는 작은 확률을 설명합니다. 차분 프라이버시를 달성하는 데 필요한 " +"노이즈의 양은 출력의 감도에 비례하며, 이는 단일 레코드의 포함 또는 제거로 " +"인한 출력의 최대 변화를 측정합니다." #: ../../source/explanation-differential-privacy.rst:45 msgid "Differential Privacy in Machine Learning" -msgstr "" +msgstr "머신 러닝의 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:46 msgid "" @@ -2841,10 +3263,18 @@ msgid "" "model training. Additionally, such noise can be incorporated into the " "model's output." msgstr "" +"머신 러닝에서 DP를 활용하여 학습 데이터의 개인정보를 보호할 수 있습니다. " +"차분 비공개 머신 러닝 알고리즘은 알고리즘이 개별 데이터 포인트에 대한 특정 " +"정보를 학습하지 못하도록 하여 모델이 민감한 정보를 노출하지 않도록 하는 " +"방식으로 설계되었습니다. 노이즈가 도입되는 단계에 따라 머신 러닝 알고리즘에 " +"DP를 적용하는 다양한 방법이 존재합니다. 한 가지 방법은 학습 데이터(특징 또는 " +"레이블)에 노이즈를 추가하는 것이고, 다른 방법은 모델 학습 중에 손실 함수의 " +"기울기에 노이즈를 주입하는 것입니다. 또한 이러한 노이즈를 모델의 출력에 " +"통합할 수도 있습니다." #: ../../source/explanation-differential-privacy.rst:53 msgid "Differential Privacy in Federated Learning" -msgstr "" +msgstr "Federated 학습의 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:54 msgid "" @@ -2856,12 +3286,19 @@ msgid "" "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" +"Federated 학습은 여러 당사자가 원시 데이터를 공유하지 않고도 공동으로 모델을 " +"학습할 수 있는 데이터 최소화 접근 방식입니다. 그러나 연합 학습은 새로운 " +"개인정보 보호 문제를 야기하기도 합니다. 당사자와 중앙 서버 간의 모델 " +"업데이트는 로컬 데이터에 대한 정보를 유출할 수 있습니다. 이러한 유출은 " +"멤버십 추론 및 속성 추론 공격이나 모델 반전 공격과 같은 공격에 악용될 수 " +"있습니다." #: ../../source/explanation-differential-privacy.rst:58 msgid "" "DP can play a crucial role in federated learning to provide privacy for " "the clients' data." -msgstr "" +msgstr "DP는 federated학습에서 클라이언트의 데이터에 대한 개인 정보 보호를 제공하는 " +"데 중요한 역할을 할 수 있습니다." #: ../../source/explanation-differential-privacy.rst:60 msgid "" @@ -2871,6 +3308,10 @@ msgid "" " learning based on where the noise is added: at the server (also known as" " the center) or at the client (also known as the local)." msgstr "" +"개인 정보 제공의 세분성 또는 노이즈 추가 위치에 따라 federated 학습에는 " +"다양한 형태의 DP가 존재합니다. 이 설명에서는 노이즈가 추가되는 위치에 따라 " +"서버(중앙이라고도 함) 또는 클라이언트(로컬이라고도 함)에서의 federated " +"학습에서 DP를 활용하는 두 가지 접근 방식에 중점을 둡니다." #: ../../source/explanation-differential-privacy.rst:63 msgid "" @@ -2878,6 +3319,8 @@ msgid "" "goal is to prevent the aggregated model from leaking information about " "each client's data." msgstr "" +"**중앙 차분 프라이버시**: DP는 서버에서 적용되며 집계된 모델이 각 " +"클라이언트의 데이터에 대한 정보를 유출하는 것을 방지하는 것이 목표입니다." #: ../../source/explanation-differential-privacy.rst:65 msgid "" @@ -2886,12 +3329,15 @@ msgid "" "updates that are sent to the server from leaking any information about " "the client's data." msgstr "" +"**로컬 차분 개인정보 보호**: DP는 정보를 서버로 보내기 전에 클라이언트 " +"측에서 적용되며, 서버로 전송되는 업데이트가 클라이언트 데이터에 대한 정보를 " +"유출하는 것을 방지하는 것이 목표입니다." #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:68 #: ../../source/how-to-use-differential-privacy.rst:11 msgid "Central Differential Privacy" -msgstr "" +msgstr "중앙 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:69 msgid "" @@ -2899,6 +3345,9 @@ msgid "" "server is responsible for adding noise to the globally aggregated " "parameters. It should be noted that trust in the server is required." msgstr "" +"사용자 수준 DP라고도 하는 이 접근 방식에서는 중앙 서버가 전역적으로 집계된 " +"매개변수에 노이즈를 추가하는 역할을 담당합니다. 서버에 대한 신뢰가 " +"필요하다는 점에 유의해야 합니다." #: ../../source/explanation-differential-privacy.rst:76 msgid "" @@ -2914,10 +3363,20 @@ msgid "" " by restricting the `L2` norm of the clients' model updates, ensuring " "that larger updates are scaled down to fit within the norm `S`." msgstr "" +"federated 학습에서 중앙 DP를 구현하는 방법은 여러 가지가 있지만, 여기서는 [2]" +"와 [3]에서 제안한 알고리즘에 집중합니다. 전반적인 접근 방식은 클라이언트가 " +"전송한 모델 업데이트를 잘라내고 집계된 모델에 약간의 노이즈를 추가하는 " +"것입니다. 각 반복에서 특정 확률로 훈련할 무작위 클라이언트 세트가 " +"선택됩니다. 각 클라이언트는 자체 데이터에 대해 로컬 학습을 수행합니다. 그런 " +"다음 각 클라이언트의 업데이트는 특정 값 `S`(민감도 `S`)에 의해 잘립니다. " +"이렇게 하면 개별 클라이언트의 영향을 제한할 수 있어 개인정보 보호에 중요하고 " +"견고성에 도움이 되는 경우가 많습니다. 이를 달성하기 위한 일반적인 접근 " +"방식은 클라이언트 모델 업데이트의 `L2` 규범을 제한하여 더 큰 업데이트가 규범 " +"`S`에 맞도록 축소되도록 하는 것입니다." #: ../../source/explanation-differential-privacy.rst:-1 msgid "clipping" -msgstr "" +msgstr "클리핑" #: ../../source/explanation-differential-privacy.rst:89 msgid "" @@ -2927,16 +3386,22 @@ msgid "" "mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " "noise_scale * S ) / (number of sampled clients)`." msgstr "" +"그 후 가우시안 메커니즘을 사용하여 모든 클라이언트의 업데이트 합계를 " +"왜곡하기 위해 노이즈를 추가합니다. 노이즈의 양은 감도 값에 따라 조정되어 " +"프라이버시 보장을 얻습니다. 가우시안 메커니즘은 `N (0, σ²)`에서 샘플링된 " +"노이즈와 함께 사용됩니다. 여기서 `σ = (noise_scale * S) / (샘플링된 " +"클라이언트 수)`입니다." #: ../../source/explanation-differential-privacy.rst:94 msgid "Clipping" -msgstr "" +msgstr "클리핑" #: ../../source/explanation-differential-privacy.rst:96 msgid "" "There are two forms of clipping commonly used in Central DP: Fixed " "Clipping and Adaptive Clipping." -msgstr "" +msgstr "Central DP에서 일반적으로 사용되는 클리핑에는 고정 클리핑과 조정 클리핑의 두 " +"가지 형태가 있습니다." #: ../../source/explanation-differential-privacy.rst:98 msgid "" @@ -2944,6 +3409,9 @@ msgid "" "of clients' updates. Any update exceeding this threshold is clipped back " "to the threshold value." msgstr "" +"**고정 클리핑** : 클라이언트의 업데이트 크기에 대해 미리 정의된 고정 " +"임계값이 설정됩니다. 이 임계값을 초과하는 모든 업데이트는 임계값으로 다시 " +"클리핑됩니다." #: ../../source/explanation-differential-privacy.rst:100 msgid "" @@ -2952,19 +3420,23 @@ msgid "" " is tuned during the rounds with respect to the quantile of the update " "norm distribution." msgstr "" +"**조 클리핑** : 클리핑 임계값은 관찰된 업데이트 분포에 따라 동적으로 " +"조정됩니다[4]. 즉, 클리핑 값은 업데이트 표준 분포의 사분위수에 따라 라운드가 " +"진행되는 동안 조정됩니다." #: ../../source/explanation-differential-privacy.rst:102 msgid "" "The choice between fixed and adaptive clipping depends on various factors" " such as privacy requirements, data distribution, model complexity, and " "others." -msgstr "" +msgstr "고정 클리핑과 조정 클리핑 중 선택은 개인정보 보호 요구 사항, 데이터 배포, " +"모델 복잡성 등 다양한 요인에 따라 달라집니다." #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:105 #: ../../source/how-to-use-differential-privacy.rst:96 msgid "Local Differential Privacy" -msgstr "" +msgstr "로컬 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:107 msgid "" @@ -2973,10 +3445,13 @@ msgid "" "that local DP leads to a decrease in accuracy but better privacy in " "comparison to central DP." msgstr "" +"이 접근 방식에서는 각 클라이언트가 DP를 수행할 책임이 있습니다. 로컬 DP는 " +"완전히 신뢰할 수 있는 애그리게이터가 필요하지 않지만, 로컬 DP는 중앙 DP에 " +"비해 정확도는 떨어져도 개인 정보 보호는 더 우수하다는 점에 유의해야 합니다." #: ../../source/explanation-differential-privacy.rst:116 msgid "In this explainer, we focus on two forms of achieving Local DP:" -msgstr "" +msgstr "이 설명에서는 로컬 DP를 달성하는 두 가지 형태에 중점을 둡니다:" #: ../../source/explanation-differential-privacy.rst:118 msgid "" @@ -2985,6 +3460,10 @@ msgid "" "the sensitivity of the local model to be ∆, Gaussian noise is applied " "with a noise scale of σ where:" msgstr "" +"각 클라이언트는 로컬 업데이트를 서버로 보내기 전에 로컬 업데이트에 노이즈를 " +"추가합니다. 로컬 모델의 감도를 ∆로 간주하여 가우시안 노이즈가 σ의 노이즈 " +"스케일로 적용되어 (:math:`\\epsilon`, :math:`\\delta`)-DP를 달성하기 위해, " +"여기서 σ는 노이즈 스케일입니다:" #: ../../source/explanation-differential-privacy.rst:120 msgid "" @@ -2993,6 +3472,10 @@ msgid "" "\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" "\n" msgstr "" +"\\small\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right" +")}}{\\epsilon}\n" +"\n" #: ../../source/explanation-differential-privacy.rst:125 msgid "" @@ -3000,41 +3483,45 @@ msgid "" "training (DP-SGD). More specifically, in this approach, gradients are " "clipped and an amount of calibrated noise is injected into the gradients." msgstr "" +"각 클라이언트는 로컬 트레이닝(DP-SGD) 중에 모델의 gradient에 노이즈를 " +"추가합니다. 보다 구체적으로, 이 접근 방식에서는 gradient이 클리핑되고 보정된 " +"노이즈가 gradient에 주입됩니다." #: ../../source/explanation-differential-privacy.rst:128 msgid "" "Please note that these two approaches are providing privacy at different " "levels." -msgstr "" +msgstr "이 두 가지 접근 방식은 서로 다른 수준의 개인정보 보호 기능을 제공한다는 점에 " +"유의하세요." #: ../../source/explanation-differential-privacy.rst:131 msgid "**References:**" -msgstr "" +msgstr "**참고:**" #: ../../source/explanation-differential-privacy.rst:133 msgid "[1] Dwork et al. The Algorithmic Foundations of Differential Privacy." -msgstr "" +msgstr "[1] Dwork 외. 차분 프라이버시의 알고리즘적 기초." #: ../../source/explanation-differential-privacy.rst:135 msgid "" "[2] McMahan et al. Learning Differentially Private Recurrent Language " "Models." -msgstr "" +msgstr "[2] McMahan 외. 차분적 개인 반복 언어 모델 학습." #: ../../source/explanation-differential-privacy.rst:137 msgid "" "[3] Geyer et al. Differentially Private Federated Learning: A Client " "Level Perspective." -msgstr "" +msgstr "[3] Geyer 외. 차분적 개인 Federated 학습: 고객 수준의 관점." #: ../../source/explanation-differential-privacy.rst:139 msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." -msgstr "" +msgstr "[4] Galen 외. 조정형 클리핑을 통한 차분적 개인 학습." #: ../../source/explanation-federated-evaluation.rst:2 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:292 msgid "Federated evaluation" -msgstr "" +msgstr "Federated 평가" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" @@ -3042,14 +3529,17 @@ msgid "" "systems: centralized (or server-side) evaluation and federated (or " "client-side) evaluation." msgstr "" +"federated 학습 시스템에서 모델을 평가하는 데는 centralized(또는 서버 측) " +"평가와 federated(또는 클라이언트 측) 평가라는 두 가지 주요 접근 방식이 " +"있습니다." #: ../../source/explanation-federated-evaluation.rst:8 msgid "Centralized Evaluation" -msgstr "" +msgstr "Centralized 평가" #: ../../source/explanation-federated-evaluation.rst:11 msgid "Built-In Strategies" -msgstr "" +msgstr "기본 제공 전략" #: ../../source/explanation-federated-evaluation.rst:13 msgid "" @@ -3058,10 +3548,13 @@ msgid "" "function that can take the current global model parameters as input and " "return evaluation results:" msgstr "" +"모든 기본 제공 전략은 초기화 중에 평가 함수를 제공하여 centralized 평가를 " +"지원합니다. 평가 함수는 현재 글로벌 모델 파라미터를 입력으로 받아 평가 " +"결과를 반환할 수 있는 모든 함수입니다:" #: ../../source/explanation-federated-evaluation.rst:58 msgid "Custom Strategies" -msgstr "" +msgstr "사용자 정의 전략" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" @@ -3071,30 +3564,35 @@ msgid "" ":code:`evaluate` after parameter aggregation and before federated " "evaluation (see next paragraph)." msgstr "" +"코드:`전략` 추상화는 현재 전역 모델 파라미터를 평가하는 데 직접 사용할 수 " +"있는 :코드:`평가`라는 메서드를 제공합니다. 현재 서버 구현에서는 매개변수 " +"집계 후와 연합 평가 전에 :code:`evaluate`를 호출합니다(다음 단락 참조)." #: ../../source/explanation-federated-evaluation.rst:65 msgid "Federated Evaluation" -msgstr "" +msgstr "Federated 평가" #: ../../source/explanation-federated-evaluation.rst:68 msgid "Implementing Federated Evaluation" -msgstr "" +msgstr "Federated 평가 구현" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" "Client-side evaluation happens in the :code:`Client.evaluate` method and " "can be configured from the server side." -msgstr "" +msgstr "클라이언트 측 평가는 :code:`Client.evaluate` 메서드에서 이루어지며 서버 " +"측에서 구성할 수 있습니다." #: ../../source/explanation-federated-evaluation.rst:101 msgid "Configuring Federated Evaluation" -msgstr "" +msgstr "Federated 평가 구성" #: ../../source/explanation-federated-evaluation.rst:103 msgid "" "Federated evaluation can be configured from the server side. Built-in " "strategies support the following arguments:" -msgstr "" +msgstr "Federated 평가는 서버 측에서 구성할 수 있습니다. 기본 제공 전략은 다음 " +"인수를 지원합니다:" #: ../../source/explanation-federated-evaluation.rst:105 msgid "" @@ -3105,6 +3603,11 @@ msgid "" "for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " "federated evaluation will be disabled." msgstr "" +":code:`fraction_evaluate`: 평가를 위해 선택될 클라이언트의 비율을 정의하는 " +":code:`float`입니다. 코드:`fraction_evaluate`가 :code:`0.1`로 설정되어 있고 " +":code:`100` 클라이언트가 서버에 연결되어 있는 경우 :code:`10`이 평가를 위해 " +"무작위로 선택됩니다. code:`fraction_evaluate`가 :code:`0.0`으로 설정된 경우 " +"federated 평가가 비활성화됩니다." #: ../../source/explanation-federated-evaluation.rst:106 msgid "" @@ -3114,6 +3617,10 @@ msgid "" ":code:`100` clients are connected to the server, then :code:`20` clients " "will be selected for evaluation." msgstr "" +":code:`min_evaluate_clients`: 평가를 위해 선택할 최소 클라이언트 수. " +":code:`int`. 코드:`fraction_evaluate`가 :code:`0.1`로 설정되어 있고 " +":code:`fraction_evaluate`가 20으로 설정되어 있으며 :code:`100` 클라이언트가 " +"서버에 연결되어 있는 경우 :code:`20` 클라이언트가 평가를 위해 선택됩니다." #: ../../source/explanation-federated-evaluation.rst:107 msgid "" @@ -3124,6 +3631,11 @@ msgid "" "will wait until more clients are connected before it continues to sample " "clients for evaluation." msgstr "" +":code:`min_available_clients`: federated 평가 단계를 시작하기 전에 서버에 " +"연결해야 하는 최소 클라이언트 수를 정의하는 :code:`int`입니다. 서버에 연결된 " +"클라이언트가 :code:`min_available_clients`보다 적으면 서버는 더 많은 " +"클라이언트가 연결될 때까지 기다렸다가 평가를 위한 클라이언트 샘플링을 " +"계속합니다." #: ../../source/explanation-federated-evaluation.rst:108 msgid "" @@ -3133,10 +3645,14 @@ msgid "" "client-side evaluation from the server side, for example, to configure " "the number of validation steps performed." msgstr "" +"code:`on_evaluate_config_fn`: 선택한 클라이언트로 전송할 구성 사전을 " +"반환하는 함수입니다. 이 함수는 각 단계 중에 호출되며, 서버 측에서 클라이언트 " +"측 평가를 사용자 지정하는 편리한 방법을 제공합니다(예: 수행되는 유효성 검사 " +"단계 수 구성)." #: ../../source/explanation-federated-evaluation.rst:135 msgid "Evaluating Local Model Updates During Training" -msgstr "" +msgstr "훈련 중 로컬 모델 업데이트 평가" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" @@ -3144,10 +3660,12 @@ msgid "" ":code:`Client.fit` can return arbitrary evaluation results as a " "dictionary:" msgstr "" +"모델 파라미터는 훈련 중에도 평가할 수 있습니다. :code:`Client.fit`은 임의의 " +"평가 결과를 dictionary로 반환할 수 있습니다:" #: ../../source/explanation-federated-evaluation.rst:177 msgid "Full Code Example" -msgstr "" +msgstr "전체 코드 예제" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" @@ -3156,79 +3674,83 @@ msgid "" "be applied to workloads implemented in any other framework): " "https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" msgstr "" +"federated 평가와 centralized 평가를 모두 사용하는 전체 코드 예제는 *고급 " +"텐서플로우 예제*(다른 프레임워크에서 구현된 워크로드에도 동일한 접근 방식을 " +"적용할 수 있음)를 참조하세요: https://github.com/adap/flower/tree/main/" +"examples/advanced-tensorflow" #: ../../source/fed/0000-20200102-fed-template.md:10 msgid "FED Template" -msgstr "" +msgstr "FED 템플릿" #: ../../source/fed/0000-20200102-fed-template.md:12 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:12 msgid "Table of Contents" -msgstr "" +msgstr "목차" #: ../../source/fed/0000-20200102-fed-template.md:14 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:14 msgid "[Table of Contents](#table-of-contents)" -msgstr "" +msgstr "[목차](#목차)" #: ../../source/fed/0000-20200102-fed-template.md:15 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:15 msgid "[Summary](#summary)" -msgstr "" +msgstr "[요약](#요약)" #: ../../source/fed/0000-20200102-fed-template.md:16 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:16 msgid "[Motivation](#motivation)" -msgstr "" +msgstr "[동기](#동기)" #: ../../source/fed/0000-20200102-fed-template.md:17 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:17 msgid "[Goals](#goals)" -msgstr "" +msgstr "[목표](#목표)" #: ../../source/fed/0000-20200102-fed-template.md:18 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:18 msgid "[Non-Goals](#non-goals)" -msgstr "" +msgstr "[비목표](#비목표)" #: ../../source/fed/0000-20200102-fed-template.md:19 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:19 msgid "[Proposal](#proposal)" -msgstr "" +msgstr "[제안](#제안)" #: ../../source/fed/0000-20200102-fed-template.md:20 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:23 msgid "[Drawbacks](#drawbacks)" -msgstr "" +msgstr "[단점](#단점)" #: ../../source/fed/0000-20200102-fed-template.md:21 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:24 msgid "[Alternatives Considered](#alternatives-considered)" -msgstr "" +msgstr "[고려되는 대안](#고려되는 대안)" #: ../../source/fed/0000-20200102-fed-template.md:22 msgid "[Appendix](#appendix)" -msgstr "" +msgstr "[부록](#부록)" #: ../../source/fed/0000-20200102-fed-template.md:24 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:28 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:76 msgid "Summary" -msgstr "" +msgstr "요약" #: ../../source/fed/0000-20200102-fed-template.md:26 msgid "\\[TODO - sentence 1: summary of the problem\\]" -msgstr "" +msgstr "\\[TODO - 문장 1: 문제 요약\\]" #: ../../source/fed/0000-20200102-fed-template.md:28 msgid "\\[TODO - sentence 2: summary of the solution\\]" -msgstr "" +msgstr "\\[TODO - 문장 2: 솔루션 요약\\]" #: ../../source/fed/0000-20200102-fed-template.md:30 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:47 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:77 msgid "Motivation" -msgstr "" +msgstr "동기" #: ../../source/fed/0000-20200102-fed-template.md:32 #: ../../source/fed/0000-20200102-fed-template.md:36 @@ -3238,93 +3760,93 @@ msgstr "" #: ../../source/fed/0000-20200102-fed-template.md:54 #: ../../source/fed/0000-20200102-fed-template.md:58 msgid "\\[TODO\\]" -msgstr "" +msgstr "\\[TODO\\]" #: ../../source/fed/0000-20200102-fed-template.md:34 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:53 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:78 msgid "Goals" -msgstr "" +msgstr "목표" #: ../../source/fed/0000-20200102-fed-template.md:38 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:59 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:79 msgid "Non-Goals" -msgstr "" +msgstr "비목표" #: ../../source/fed/0000-20200102-fed-template.md:42 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:65 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:80 msgid "Proposal" -msgstr "" +msgstr "제안" #: ../../source/fed/0000-20200102-fed-template.md:46 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:85 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:129 msgid "Drawbacks" -msgstr "" +msgstr "단점" #: ../../source/fed/0000-20200102-fed-template.md:50 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:86 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:135 msgid "Alternatives Considered" -msgstr "" +msgstr "고려되는 대안" #: ../../source/fed/0000-20200102-fed-template.md:52 msgid "\\[Alternative 1\\]" -msgstr "" +msgstr "\\[대안 1\\]" #: ../../source/fed/0000-20200102-fed-template.md:56 msgid "\\[Alternative 2\\]" -msgstr "" +msgstr "\\[대안 2\\]" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:10 msgid "Flower Enhancement Doc" -msgstr "" +msgstr "Flower Enhancement Doc" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:20 msgid "[Enhancement Doc Template](#enhancement-doc-template)" -msgstr "" +msgstr "[Enhancement Doc 템플릿](#enhancement-doc-템플릿)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:21 msgid "[Metadata](#metadata)" -msgstr "" +msgstr "[Metadata](#metadata)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:22 msgid "[Workflow](#workflow)" -msgstr "" +msgstr "[워크플로우](#워크플로우)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:25 msgid "[GitHub Issues](#github-issues)" -msgstr "" +msgstr "[GitHub Issues](#github-issues)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:26 msgid "[Google Docs](#google-docs)" -msgstr "" +msgstr "[Google Docs](#google-docs)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:30 msgid "A Flower Enhancement is a standardized development process to" -msgstr "" +msgstr "Flower Enhancement는 다음과 같은 표준화된 개발 프로세스입니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:32 msgid "provide a common structure for proposing larger changes" -msgstr "" +msgstr "더 큰 변경 사항을 제안하기 위한 공통 구조를 제공합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:33 msgid "ensure that the motivation for a change is clear" -msgstr "" +msgstr "변화의 동기가 분명한지 확인합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:34 msgid "persist project information in a version control system" -msgstr "" +msgstr "버전 관리 시스템에서 프로젝트 정보를 유지합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:35 msgid "document the motivation for impactful user-facing changes" -msgstr "" +msgstr "사용자에게 영향력 있는 변화에 대한 동기를 문서화합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:36 msgid "reserve GitHub issues for tracking work in flight" -msgstr "" +msgstr "운행 중 작업 추적을 위한 깃허브 이슈를 예약합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" @@ -3332,28 +3854,31 @@ msgid "" "completion across one or more releases while stakeholders are adequately " "represented throughout the process" msgstr "" +"커뮤니티 참여자가 하나 이상의 릴리즈에서 변경 사항을 성공적으로 완료할 수 " +"있도록 하는 동시에 이해 관계자가 프로세스 전반에 걸쳐 적절히 대표되도록 " +"보장합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 msgid "Hence, an Enhancement Doc combines aspects of" -msgstr "" +msgstr "따라서 Enhancement 문서에는 다음과 같은 측면이 결합되어 있습니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:41 msgid "a feature, and effort-tracking document" -msgstr "" +msgstr "기능 및 effort-tracking 문서" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:42 msgid "a product requirements document" -msgstr "" +msgstr "제품 요구 사항 문서" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:43 msgid "a design document" -msgstr "" +msgstr "디자인 문서" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:45 msgid "" "into one file, which is created incrementally in collaboration with the " "community." -msgstr "" +msgstr "를 하나의 파일로 통합하여 커뮤니티와 협력해 점진적으로 생성합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" @@ -3361,6 +3886,9 @@ msgid "" "beyond a single GitHub issue or pull request is required to understand " "and communicate upcoming changes to the project." msgstr "" +"Flower에 제안된 변경 사항이나 기능을 멀리 가져오는 경우, 프로젝트의 향후 " +"변경 사항을 이해하고 전달하기 위해 단일 GitHub 이슈 또는 pull request를 " +"넘어서는 abstraction이 필요합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" @@ -3369,6 +3897,10 @@ msgid "" "video calls, and hallway conversations into a well-tracked artifact, this" " process aims to enhance communication and discoverability." msgstr "" +"이 프로세스의 목적은 커뮤니티 내 '부족한 지식'의 양을 줄이는 것입니다. 이 " +"프로세스는 Slack 스레드, 영상 통화, 복도 대화에서 나온 의사 결정을 잘 추적된 " +"아티팩트로 옮김으로써 커뮤니케이션과 검색 가능성을 향상시키는 것을 목표로 " +"합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" @@ -3377,6 +3909,9 @@ msgid "" "verbal communication to anyone besides the author or developer, then " "consider creating an Enhancement Doc." msgstr "" +"대략적으로 사용자를 대상으로 하는 대규모 개선 사항은 개선 프로세스를 따라야 " +"합니다. 개선 사항을 작성자나 개발자 이외의 다른 사람에게 서면 또는 구두로 " +"설명해야 하는 경우에는 개선 문서 작성을 고려하세요." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" @@ -3385,6 +3920,9 @@ msgid "" "also be communicated widely. The Enhancement process is suited for this " "even if it will have zero impact on the typical user or operator." msgstr "" +"마찬가지로 개발 커뮤니티의 많은 부분에 영향을 미치는 기술적 노력(리팩토링, " +"주요 아키텍처 변경)도 널리 알려야 합니다. 개선 프로세스는 일반 사용자나 " +"운영자에게 전혀 영향을 미치지 않더라도 이를 위해 적합합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" @@ -3393,13 +3931,18 @@ msgid "" "adding new Federated Learning algorithms, as these only add features " "without changing how Flower works or is used." msgstr "" +"작은 변경 및 추가의 경우, 개선 프로세스를 거치는 것은 시간이 많이 걸리고 " +"불필요합니다. 예를 들어, 새로운 Federated 학습 알고리즘을 추가하는 것은 " +"Flower의 작동 방식이나 사용 방식을 변경하지 않고 기능만 추가하는 것이기 " +"때문입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " "providing a laid-out path for implementation and are championed by " "members of the community." -msgstr "" +msgstr "기능 개선은 이미 구현할 수 있는 경로가 마련되어 있고 커뮤니티 구성원들이 " +"지지하는 것이므로 기능 요청과는 다릅니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" @@ -3407,105 +3950,110 @@ msgid "" "template and a workflow to review and store enhancement docs for " "reference — the Enhancement Doc." msgstr "" +"개선 사항은 정의된 템플릿과 참조용으로 Enhancement Doc.를 검토하고 저장하는 " +"워크플로우를 따르는 Markdown 파일에 캡처됩니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:69 msgid "Enhancement Doc Template" -msgstr "" +msgstr "Enhancement Doc 템플릿" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:71 msgid "" "Each enhancement doc is provided as a Markdown file having the following " "structure" -msgstr "" +msgstr "각 개선 사항 문서는 다음과 같은 구조의 Markdown 파일로 제공됩니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:73 msgid "Metadata (as [described below](#metadata) in form of a YAML preamble)" -msgstr "" +msgstr "Metadata ([아래 설명](#metadata) YAML preamble 형식)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:74 msgid "Title (same as in metadata)" -msgstr "" +msgstr "Title (metadata와 같게)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:75 msgid "Table of Contents (if needed)" -msgstr "" +msgstr "Table of Contents (필요시)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:81 msgid "Notes/Constraints/Caveats (optional)" -msgstr "" +msgstr "Notes/Constraints/Caveats (선택 사항)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:82 msgid "Design Details (optional)" -msgstr "" +msgstr "Design Details (선택 사항)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:83 msgid "Graduation Criteria" -msgstr "" +msgstr "졸업 기준" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:84 msgid "Upgrade/Downgrade Strategy (if applicable)" -msgstr "" +msgstr "업그레이드/다운그레이드 전략(해당되는 경우)" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:88 msgid "As a reference, this document follows the above structure." -msgstr "" +msgstr "참고로 이 문서는 위의 구조를 따릅니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:90 #: ../../source/ref-api/flwr.common.Metadata.rst:2 msgid "Metadata" -msgstr "" +msgstr "Metadata" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" "**fed-number** (Required) The `fed-number` of the last Flower Enhancement" " Doc + 1. With this number, it becomes easy to reference other proposals." msgstr "" +"**피드 번호** (필수) 마지막 Flower Enhancement 문서의 `피드 번호` + 1. 이 " +"번호를 사용하면 다른 제안을 쉽게 참조할 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 msgid "**title** (Required) The title of the proposal in plain language." -msgstr "" +msgstr "**제목** (필수) 제안서의 제목을 평이한 언어로 입력합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" "**status** (Required) The current status of the proposal. See " "[workflow](#workflow) for the possible states." -msgstr "" +msgstr "**상태** (필수) 제안의 현재 상태입니다. 가능한 상태는 [워크플로](#워크플로)" +"를 참조하세요." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" "**authors** (Required) A list of authors of the proposal. This is simply " "the GitHub ID." -msgstr "" +msgstr "**저자** (필수) 제안서의 작성자 목록입니다. 간단히 GitHub ID입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" "**creation-date** (Required) The date that the proposal was first " "submitted in a PR." -msgstr "" +msgstr "**생성 날짜** (필수) PR에서 제안서를 처음 제출한 날짜입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 msgid "" "**last-updated** (Optional) The date that the proposal was last changed " "significantly." -msgstr "" +msgstr "**마지막 업데이트** (선택 사항) 제안서가 마지막으로 크게 변경된 날짜입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" "**see-also** (Optional) A list of other proposals that are relevant to " "this one." -msgstr "" +msgstr "**함께 보기** (선택 사항) 이 제안과 관련된 다른 제안 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 msgid "**replaces** (Optional) A list of proposals that this one replaces." -msgstr "" +msgstr "**대체** (선택 사항) 이 제안이 대체하는 제안 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." -msgstr "" +msgstr "**대체됨** (선택 사항) 이 제안이 대체하는 제안의 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 msgid "Workflow" -msgstr "" +msgstr "워크플로우" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" @@ -3514,6 +4062,9 @@ msgid "" "author, who shepherds the enhancement. This person also has to find " "committers to Flower willing to review the proposal." msgstr "" +"개선 사항을 구성하는 아이디어는 이미 커뮤니티에서 논의되었거나 제안된 적이 " +"있어야 합니다. 따라서 개선 사항을 주도하는 사(보통 작성자)이 필요합니다. 이 " +"사람은 또한 제안을 검토할 의향이 있는 Flower 커미터를 찾아야 합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" @@ -3523,6 +4074,10 @@ msgid "" "state as part of a pull request. Discussions are done as part of the pull" " request review." msgstr "" +"새 개선 사항은 `NNNN-YYYYMMDD-enhancement-title.md` 형식의 파일 이름으로 " +"체크인되며, `NNNN`은 Flower 개선 문서 번호이고 `enhancements`에 해당합니다. " +"모든 개선 사항은 pull request의 일부로 `잠정` 상태에서 시작됩니다. 토론은 " +"pull request 검토의 일부로 이루어집니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" @@ -3532,12 +4087,16 @@ msgid "" "enhancement as part of their description. After the implementation is " "done, the proposal status is changed to `implemented`." msgstr "" +"개선 사항이 검토 및 승인되면 상태가 '구현 가능'으로 변경됩니다. 그런 다음 " +"실제 구현은 별도의 pull requests를 통해 이루어집니다. 이러한 pull requests는 " +"설명의 일부로 해당 개선 사항을 언급해야 합니다. 구현이 완료되면 제안 상태는 " +"'구현됨'으로 변경됩니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" "Under certain conditions, other states are possible. An Enhancement has " "the following states:" -msgstr "" +msgstr "특정 조건에서는 다른 상태도 가능합니다. 개선에는 다음과 같은 상태가 있습니다:" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" @@ -3545,34 +4104,37 @@ msgid "" "defined. This is the starting state while the proposal is being fleshed " "out and actively defined and discussed." msgstr "" +"'잠정적': 개선 사항이 제안되어 활발히 정의되고 있습니다. 제안이 구체화되고 " +"활발하게 정의 및 논의되는 동안의 시작 단계입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 msgid "`implementable`: The enhancement has been reviewed and approved." -msgstr "" +msgstr "`구현 가능`: 개선 사항이 검토 및 승인되었습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:123 msgid "" "`implemented`: The enhancement has been implemented and is no longer " "actively changed." -msgstr "" +msgstr "`구현됨`: 개선 사항이 구현되었으며 더 이상 활발히 변경되지 않습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 msgid "`deferred`: The enhancement is proposed but not actively being worked on." -msgstr "" +msgstr "'지연됨': 개선 사항이 제안되었지만 아직 활발히 작업 중이 아닙니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" "`rejected`: The authors and reviewers have decided that this enhancement " "is not moving forward." -msgstr "" +msgstr "`거부됨`: 작성자와 검토자는 이 개선 사항을 더 이상 진행하지 않기로 " +"결정했습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 msgid "`withdrawn`: The authors have withdrawn the enhancement." -msgstr "" +msgstr "`철회`: 작성자가 개선 사항을 철회했습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:127 msgid "`replaced`: The enhancement has been replaced by a new enhancement." -msgstr "" +msgstr "'대체됨': 개선 사항이 새로운 개선 사항으로 대체되었습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" @@ -3580,6 +4142,8 @@ msgid "" "(Issues and Pull Requests) adds more complexity and can be a barrier for " "potential first-time contributors." msgstr "" +"GitHub에서 이미 제공하는 프로세스(이슈 및 Pull Requests)에 추가 프로세스를 " +"추가하면 더 복잡해지고 잠재적인 처음인 기여자에게는 장벽이 될 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" @@ -3587,10 +4151,12 @@ msgid "" "currently required in the features issue template may be a heavy burden " "for non-native English speakers." msgstr "" +"현재 기능 이슈 템플릿에서 요구되는 한 문장 설명 이상으로 제안서 템플릿을 " +"확장하는 것은 영어가 모국어가 아닌 사용자에게는 큰 부담이 될 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 msgid "GitHub Issues" -msgstr "" +msgstr "GitHub 이슈" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" @@ -3602,10 +4168,16 @@ msgid "" "parts of the doc. Managing these multiple discussions can be confusing " "when using GitHub Issues." msgstr "" +"이러한 종류의 개선을 위해 GitHub 이슈를 사용하면 가능합니다. 예를 들어 " +"태그를 사용하여 다른 이슈와 구별하고 필터링할 수 있습니다. 주요 이슈는 개선 " +"사항에 대해 토론하고 검토하는 것입니다: GitHub 이슈에는 댓글 스레드가 하나만 " +"있습니다. 개선 사항에는 일반적으로 문서의 여러 부분에 대해 동시에 여러 개의 " +"토론 스레드가 있습니다. GitHub 이슈를 사용할 때 이러한 여러 토론을 관리하면 " +"혼란스러울 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 msgid "Google Docs" -msgstr "" +msgstr "Google 문서 도구" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" @@ -3616,24 +4188,29 @@ msgid "" "proposals as part of Flower's repository, the potential for missing links" " is much higher." msgstr "" +"Google 문서는 여러 스레드의 토론을 허용합니다. 하지만 Google 문서는 프로젝트 " +"외부에서 호스팅되므로 커뮤니티에서 검색할 수 있도록 관리해야 합니다. 모든 " +"제안에 대한 링크 목록을 관리하고 커뮤니티에 제공해야 합니다. Flower 저장소의 " +"일부로 제안서를 보낼 때와 비교하면 링크가 누락될 가능성이 훨씬 더 높습니다." #: ../../source/fed/index.md:1 msgid "FED - Flower Enhancement Doc" -msgstr "" +msgstr "FED - Flower 개선 문서" #: ../../source/how-to-aggregate-evaluation-results.rst:2 msgid "Aggregate evaluation results" -msgstr "" +msgstr "종합 평가 결과" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" "The Flower server does not prescribe a way to aggregate evaluation " "results, but it enables the user to fully customize result aggregation." -msgstr "" +msgstr "Flower 서버는 평가 결과를 집계하는 방법을 규정하고 있지 않지만 사용자가 결과 " +"집계를 완전히 사용자 지정할 수 있습니다." #: ../../source/how-to-aggregate-evaluation-results.rst:8 msgid "Aggregate Custom Evaluation Results" -msgstr "" +msgstr "사용자 지정 평가 결과 집계" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" @@ -3641,16 +4218,20 @@ msgid "" " custom evaluation results coming from individual clients. Clients can " "return custom metrics to the server by returning a dictionary:" msgstr "" +"동일한 :code:`Strategy`-사용자 지정 방식을 사용하여 개별 클라이언트로부터 " +"오는 사용자 지정 평가 결과를 집계할 수 있습니다. 클라이언트는 dictionary를 " +"반환하여 사용자 지정 지표를 서버에 반환할 수 있습니다:" #: ../../source/how-to-aggregate-evaluation-results.rst:36 msgid "" "The server can then use a customized strategy to aggregate the metrics " "provided in these dictionaries:" -msgstr "" +msgstr "그런 다음 서버는 사용자 지정 전략을 사용하여 이러한 dictionaries에서 " +"제공하는 메트릭을 집계할 수 있습니다:" #: ../../source/how-to-authenticate-supernodes.rst:2 msgid "Authenticate SuperNodes" -msgstr "" +msgstr "SuperNodes 인증하기" #: ../../source/how-to-authenticate-supernodes.rst:4 msgid "" @@ -3659,26 +4240,30 @@ msgid "" "Flower node authentication works similar to how GitHub SSH authentication" " works:" msgstr "" +"Flower는 SuperLink에 연결하는 각 SuperNodes의 신원을 확인하는 데 사용할 수 " +"있는 인증된 SuperNodes에 대한 기본 지원을 제공합니다. Flower 노드 인증은 " +"GitHub SSH 인증 방식과 유사하게 작동합니다:" #: ../../source/how-to-authenticate-supernodes.rst:7 msgid "SuperLink (server) stores a list of known (client) node public keys" -msgstr "" +msgstr "SuperLink(서버)는 알려진 (클라이언트) 노드 공개키 목록을 저장합니다" #: ../../source/how-to-authenticate-supernodes.rst:8 msgid "" "Using ECDH, both SuperNode and SuperLink independently derive a shared " "secret" -msgstr "" +msgstr "SuperNode와 SuperLink는 ECDH를 사용하여 독립적으로 공유된 비밀을 도출합니다" #: ../../source/how-to-authenticate-supernodes.rst:9 msgid "" "Shared secret is used to compute the HMAC value of the message sent from " "SuperNode to SuperLink as a token" -msgstr "" +msgstr "비밀 공유는 SuperNode에서 SuperLink로 토큰으로 전송된 메시지의 HMAC 값을 " +"계산하는 데 사용됩니다" #: ../../source/how-to-authenticate-supernodes.rst:10 msgid "SuperLink verifies the token" -msgstr "" +msgstr "SuperLink가 토큰을 확인합니다" #: ../../source/how-to-authenticate-supernodes.rst:12 msgid "" @@ -3687,22 +4272,27 @@ msgid "" "authentication>`_ demonstrating federated learning with Flower in an " "authenticated setting." msgstr "" +"인증된 환경에서 Flower로 federated 학습을 시연하는 전체 '코드 예제 " +"`" +"_를 확인하는 것이 좋습니다." #: ../../source/how-to-authenticate-supernodes.rst:15 msgid "" "This guide covers a preview feature that might change in future versions " "of Flower." -msgstr "" +msgstr "이 가이드에서는 향후 버전의 Flower에서 변경될 수 있는 미리보기 기능에 대해 " +"설명합니다." #: ../../source/how-to-authenticate-supernodes.rst:18 msgid "" "For increased security, node authentication can only be used when " "encrypted connections (SSL/TLS) are enabled." -msgstr "" +msgstr "보안을 강화하기 위해 노드 인증은 암호화된 연결(SSL/TLS)을 사용하도록 설정한 " +"경우에만 사용할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:21 msgid "Enable node authentication in :code:`SuperLink`" -msgstr "" +msgstr ":code:`SuperLink`에서 노드 인증 활성화" #: ../../source/how-to-authenticate-supernodes.rst:23 msgid "" @@ -3715,10 +4305,16 @@ msgid "" ":code:`SuperNode` that has both secure connections and node " "authentication enabled:" msgstr "" +"노드 인증을 활성화하려면 먼저 SuperLink<>SuperNode 통신을 보호하기 위해 SSL/" +"TLS 연결을 구성해야 합니다. 전체 가이드는 `여기 `_에서 확인할 수 있습니다. 보안 " +"연결을 구성한 후, 장기 실행하는 Flower :code:`SuperLink`에서 클라이언트 " +"인증을 활성화할 수 있습니다. 다음 터미널 명령을 사용하여 보안 연결과 노드 " +"인증이 모두 활성화된 Flower :code:`SuperNode`를 시작하세요:" #: ../../source/how-to-authenticate-supernodes.rst:38 msgid "Let's break down the authentication flags:" -msgstr "" +msgstr "인증 플래그를 세분화해 보겠습니다:" #: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" @@ -3727,6 +4323,9 @@ msgid "" " public keys that are allowed to participate in a federation in one CSV " "file (:code:`.csv`)." msgstr "" +"첫 번째 플래그 :code:`--auth-list-public-keys`는 알려진 모든 노드 공개키를 " +"저장하는 CSV 파일의 경로를 기대합니다. federation에 참여하도록 허용된 모든 " +"알려진 노드 공개 키를 하나의 CSV 파일(:code:`.csv`)에 저장해야 합니다." #: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" @@ -3735,6 +4334,9 @@ msgid "" "example, refer to our code sample, which contains a CSV file with two " "known node public keys." msgstr "" +"알려진 노드 공개키를 저장하는 유효한 CSV 파일은 쉼표로 구분하고 주석 없이 " +"OpenSSH 형식으로 키를 나열해야 합니다. 예를 들어, 두 개의 알려진 노드 " +"공개키가 포함된 CSV 파일이 포함된 코드 샘플을 참조하세요." #: ../../source/how-to-authenticate-supernodes.rst:44 msgid "" @@ -3743,6 +4345,10 @@ msgid "" "public keys. For development purposes, you can generate a private and " "public key pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" +"두 번째 및 세 번째 플래그 :code:`--auth-superlink-private-key` 및 :code" +":`--auth-superlink-public-key`는 서버의 개인 및 공개 키의 경로를 예상합니다. " +"개발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 및 공개 키 " +"쌍을 생성할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:47 msgid "" @@ -3752,10 +4358,15 @@ msgid "" "start the server again. Support for dynamically changing the set of known" " nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" +"Flower 1.9에서는 알려진 노드 공개키를 SuperLink에 동적으로 제거, 편집 또는 " +"추가하는 기능이 지원되지 않습니다. 알려진 노드 집합을 변경하려면 서버를 " +"종료하고 CSV 파일을 편집한 다음 서버를 다시 시작해야 합니다. 알려진 노드 " +"집합을 동적으로 변경하는 기능은 Flower 1.10(출시 예정일: 6월)에서 로드맵에 " +"포함되어 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:53 msgid "Enable node authentication in :code:`SuperNode`" -msgstr "" +msgstr ":code:`SuperNode`에서 노드 인증을 활성화합니다" #: ../../source/how-to-authenticate-supernodes.rst:55 msgid "" @@ -3764,6 +4375,9 @@ msgid "" "(:code:`SuperNode`). Use the following terminal command to start an " "authenticated :code:`SuperNode`:" msgstr "" +"장기 실행 중인 Flower 서버(:code:`SuperLink`)와 마찬가지로, 장기 실행 중인 " +"Flower 클라이언트(:code:`SuperNode`)에서도 노드 인증을 쉽게 활성화할 수 " +"있습니다. 다음 터미널 명령을 사용하여 인증된 :code:`SuperNode`를 시작하세요:" #: ../../source/how-to-authenticate-supernodes.rst:66 msgid "" @@ -3773,10 +4387,14 @@ msgid "" "you can generate a private and public key pair using :code:`ssh-keygen -t" " ecdsa -b 384`." msgstr "" +":code:`--auth-supernode-private-key` 플래그는 노드의 개인 키 파일 경로를, " +":code:`--auth-supernode-public-key` 플래그는 노드의 공개 키 파일 경로를 " +"예상합니다. 개발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 " +"및 공개 키 쌍을 생성할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:70 msgid "Security notice" -msgstr "" +msgstr "보안 공지" #: ../../source/how-to-authenticate-supernodes.rst:72 msgid "" @@ -3788,13 +4406,18 @@ msgid "" "communication is done in a secure manner, using trusted communication " "methods." msgstr "" +"시스템의 보안은 SuperLink와 각SuperNode의 자격 증명에 의존합니다. 따라서 " +"공개키 기반구조(PKI) 사칭 공격과 같은 보안 위험을 피하기 위해 자격 증명을 " +"보호하고 안전하게 보관하는 것이 필수적입니다. 노드 인증 메커니즘에는 사람의 " +"상호 작용도 포함되므로 모든 통신이 신뢰할 수 있는 통신 방법을 사용하여 " +"안전한 방식으로 이루어지도록 하세요." #: ../../source/how-to-authenticate-supernodes.rst:77 #: ../../source/how-to-enable-ssl-connections.rst:68 #: ../../source/how-to-use-built-in-mods.rst:85 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:287 msgid "Conclusion" -msgstr "" +msgstr "결론" #: ../../source/how-to-authenticate-supernodes.rst:79 msgid "" @@ -3803,10 +4426,14 @@ msgid "" "authentication enabled. You should also know the significance of the " "private key and store it safely to minimize security risks." msgstr "" +"이제 노드 인증이 활성화된 상태에서 장기간 실행되는 Flower " +"서버(:code:`SuperLink`)와 클라이언트(:code:`SuperNode`)를 시작하는 방법을 " +"배웠을 것입니다. 또한 보안 위험을 최소화하기 위해 개인키의 중요성을 알고 " +"안전하게 보관해야 합니다." #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" -msgstr "" +msgstr "클라이언트 구성" #: ../../source/how-to-configure-clients.rst:4 msgid "" @@ -3815,10 +4442,13 @@ msgid "" " for example, a popular way to control client-side hyperparameters from " "the server." msgstr "" +"모델 파라미터와 함께 Flower는 설정 값을 클라이언트에 전송할 수 있습니다. " +"구성 값은 다양한 용도로 사용할 수 있습니다. 예를 들어 서버에서 클라이언트 측 " +"하이퍼파라미터를 제어하는 데 널리 사용되는 방법입니다." #: ../../source/how-to-configure-clients.rst:7 msgid "Configuration values" -msgstr "" +msgstr "구성 값" #: ../../source/how-to-configure-clients.rst:9 msgid "" @@ -3827,6 +4457,9 @@ msgid "" "float), ``int``, or ``str`` (or equivalent types in different languages)." " Here is an example of a configuration dictionary in Python:" msgstr "" +"구성 값은 ``str`` 키와 ``bool``, ``bytes``, ``double``(64비트 정밀도 정수), " +"``int`` 또는 ``str``(또는 다른 언어의 동등한 유형) 유형의 값으로 구성된 " +"사전으로 표현됩니다. 다음은 Python의 구성 사전 예제입니다:" #: ../../source/how-to-configure-clients.rst:20 msgid "" @@ -3834,6 +4467,9 @@ msgid "" "short) to their ProtoBuf representation, transports them to the client " "using gRPC, and then deserializes them back to Python dictionaries." msgstr "" +"Flower는 이러한 구성 dictionaries(또는 줄여서 *config dict*)를 ProtoBuf " +"표현으로 직렬화하고, gRPC를 사용하여 클라이언트로 전송한 다음 다시 Python " +"dictionaries로 역직렬화합니다." #: ../../source/how-to-configure-clients.rst:24 msgid "" @@ -3843,6 +4479,10 @@ msgid "" " by converting them to one of the supported value types (and converting " "them back on the client-side)." msgstr "" +"현재 구성 사전에서 컬렉션 유형(예: ``Set``, ``List``, ``Map``)을 값으로 직접 " +"전송하는 기능은 지원되지 않습니다. 컬렉션을 지원되는 값 유형 중 하나로 " +"변환한 다음 클라이언트 측에서 다시 변환하여 값으로 보내는 몇 가지 해결 " +"방법이 있습니다." #: ../../source/how-to-configure-clients.rst:26 msgid "" @@ -3851,10 +4491,13 @@ msgid "" " then convert the JSON string back to a list of floating-point numbers on" " the client." msgstr "" +"예를 들어 부동 소수점 숫자 목록을 JSON 문자열로 변환한 다음 구성 " +"dictionary을 사용하여 JSON 문자열을 전송한 다음 클라이언트에서 다시 부동 " +"소수점 숫자 목록으로 변환할 수 있습니다." #: ../../source/how-to-configure-clients.rst:30 msgid "Configuration through built-in strategies" -msgstr "" +msgstr "기본 제공 전략을 통한 구성" #: ../../source/how-to-configure-clients.rst:32 msgid "" @@ -3865,6 +4508,11 @@ msgid "" "the current round. It then forwards the configuration dictionary to all " "the clients selected during that round." msgstr "" +"클라이언트에 구성 값을 보내는 가장 쉬운 방법은 :code:`FedAvg`와 같은 기본 " +"제공 전략을 사용하는 것입니다. 기본 제공 전략은 소위 구성 함수를 지원합니다. " +"구성 함수는 내장 전략이 현재 단계의 구성 사전을 가져오기 위해 호출하는 " +"함수입니다. 그런 다음 해당 단계 동안 선택된 모든 클라이언트에 구성 사전을 " +"전달합니다." #: ../../source/how-to-configure-clients.rst:34 msgid "" @@ -3873,6 +4521,9 @@ msgid "" "federated learning, and (c) the number of epochs to train on the client-" "side. Our configuration function could look like this:" msgstr "" +"간단한 예부터 시작하겠습니다. (a) 클라이언트가 사용해야 하는 배치 크기, (b) " +"현재 글로벌 연합 federated 라운드, (c) 클라이언트 측에서 학습할 에포크 수를 " +"전송하고 싶다고 가정해 보겠습니다. 구성 함수는 다음과 같습니다:" #: ../../source/how-to-configure-clients.rst:47 msgid "" @@ -3880,10 +4531,12 @@ msgid "" "``FedAvg`` during initialization using the parameter " ":code:`on_fit_config_fn`:" msgstr "" +"기본 제공 전략이 이 함수를 사용하도록 하려면 초기화 중에 매개 변수 " +":code:`on_fit_config_fn`을 사용하여 ``FedAvg``에 이 함수를 전달하면 됩니다:" #: ../../source/how-to-configure-clients.rst:56 msgid "One the client side, we receive the configuration dictionary in ``fit``:" -msgstr "" +msgstr "클라이언트 측에서는 ``fit``으로 구성 dictionary을 받습니다:" #: ../../source/how-to-configure-clients.rst:67 msgid "" @@ -3892,6 +4545,9 @@ msgid "" " send different configuration values to `evaluate` (for example, to use a" " different batch size)." msgstr "" +"평가를 구성하는 `on_evaluate_config_fn`도 있으며, 같은 방식으로 작동합니다. " +"다른 배치 크기를 사용하기 위해 다른 구성 값을 `evaluate`로 보내려고 할 수 " +"있기 때문에 이 함수는 별도의 함수입니다." #: ../../source/how-to-configure-clients.rst:69 msgid "" @@ -3902,20 +4558,25 @@ msgid "" "hyperparameter schedule, for example, to increase the number of local " "epochs during later rounds, we could do the following:" msgstr "" +"기본 제공 전략은 매 라운드마다 이 함수를 호출합니다(즉, `Strategy." +"configure_fit` 또는 `Strategy.configure_evaluate`가 실행될 때마다). 매 " +"라운드마다 `on_evaluate_config_fn`을 호출하면 연속된 라운드에서 config " +"dict를 변경/변경할 수 있습니다. 예를 들어 이후 라운드에서 로컬 에포크 수를 " +"늘리기 위해 하이퍼파라미터 일정을 구현하려면 다음과 같이 할 수 있습니다:" #: ../../source/how-to-configure-clients.rst:82 msgid "The :code:`FedAvg` strategy will call this function *every round*." -msgstr "" +msgstr ":code:`FedAvg` 전략은 이 함수를 *매 라운드마다* 호출합니다." #: ../../source/how-to-configure-clients.rst:85 msgid "Configuring individual clients" -msgstr "" +msgstr "개별 클라이언트 구성" #: ../../source/how-to-configure-clients.rst:87 msgid "" "In some cases, it is necessary to send different configuration values to " "different clients." -msgstr "" +msgstr "경우에 따라 다른 구성 값을 다른 클라이언트에 보내야 하는 경우도 있습니다." #: ../../source/how-to-configure-clients.rst:89 msgid "" @@ -3927,10 +4588,16 @@ msgid "" "list, the other clients in this round to not receive this \"special\" " "config value):" msgstr "" +"이는 기존 전략을 사용자 지정하거나 :doc:`implementing a custom strategy from " +"scratch `를 통해 수행할 수 있습니다. 다음은 " +"사용자 지정 ``\"hello\"'를 추가하여 :code:`FedAvg`를 사용자 지정하는 " +"무의미한 예입니다: \"world\"`` 구성 키/값 쌍을 *단일 클라이언트*의 config " +"dict에 추가합니다(목록의 첫 번째 클라이언트만, 이 라운드의 다른 클라이언트는 " +"이 \"특별한\" 구성 값을 수신하지 않음):" #: ../../source/how-to-configure-logging.rst:2 msgid "Configure logging" -msgstr "" +msgstr "로깅 구성" #: ../../source/how-to-configure-logging.rst:4 msgid "" @@ -3938,6 +4605,8 @@ msgid "" "federated learning workloads. It presents information by default " "following a standard message format:" msgstr "" +"Flower 로거는 federated 학습 워크로드에서 발생하는 모든 핵심 이벤트를 " +"추적합니다. 기본적으로 표준 메시지 형식에 따라 정보를 표시합니다:" #: ../../source/how-to-configure-logging.rst:13 msgid "" @@ -3946,10 +4615,13 @@ msgid "" "took place from, as well as the log message itself. In this way, the " "logger would typically display information on your terminal as follows:" msgstr "" +"로그 메시지 수준(예: :code:`INFO`, :code:`DEBUG`), 타임스탬프, 로깅이 발생한 " +"줄, 로그 메시지 자체 등 관련 정보를 포함합니다. 이러한 방식으로 로거는 " +"일반적으로 다음과 같은 정보를 터미널에 표시합니다:" #: ../../source/how-to-configure-logging.rst:34 msgid "Saving log to file" -msgstr "" +msgstr "파일에 로그 저장" #: ../../source/how-to-configure-logging.rst:36 msgid "" @@ -3963,6 +4635,14 @@ msgid "" "`_" " function. For example:" msgstr "" +"기본적으로 Flower 로그는 Federated 학습 워크로드를 실행하는 터미널에 " +"출력됩니다. 이는 gRPC 기반 페더레이션(즉,:code:`fl.simulation." +"start_simulation`를 실행하는 경우)과 :code:`VirtualClientEngine`을 사용하는 " +"경우(즉, :코드:`fl.simulation.start_simulation`을 실행하는 경우) 모두에 " +"적용됩니다. 경우에 따라 이 로그를 디스크에 저장하고 싶을 수도 있습니다. 이 " +"경우 `fl.common.logger.configure() `_ 함수를 호출하여 저장할 수 있습니다. 예를 " +"들어:" #: ../../source/how-to-configure-logging.rst:53 msgid "" @@ -3971,10 +4651,14 @@ msgid "" "you are running the code from. If we inspect we see the log above is also" " recorded but prefixing with :code:`identifier` each line:" msgstr "" +"위와 같이 하면 Flower는 터미널에 표시되는 로그를 :code:`log.txt`에 " +"기록합니다. 이 파일은 코드를 실행한 디렉터리와 동일한 디렉터리에 생성됩니다. " +"검사해보면 위의 로그도 기록되지만 각 줄 앞에 :code:`identifier` 접두사가 " +"붙는 것을 확인할 수 있습니다:" #: ../../source/how-to-configure-logging.rst:74 msgid "Log your own messages" -msgstr "" +msgstr "나만의 메시지 기록" #: ../../source/how-to-configure-logging.rst:76 msgid "" @@ -3982,16 +4666,19 @@ msgid "" "by adding more messages relevant to your application. You can achieve " "this easily as follows." msgstr "" +"애플리케이션과 관련된 메시지를 더 추가하여 Flower 로거에 기본적으로 표시되는 " +"정보를 확장할 수 있습니다. 다음과 같이 쉽게 추가할 수 있습니다." #: ../../source/how-to-configure-logging.rst:102 msgid "" "In this way your logger will show, in addition to the default messages, " "the ones introduced by the clients as specified above." -msgstr "" +msgstr "이렇게 하면 로거에 기본 메시지 외에 위에서 지정한 대로 클라이언트가 소개한 " +"메시지가 표시됩니다." #: ../../source/how-to-configure-logging.rst:128 msgid "Log to a remote service" -msgstr "" +msgstr "원격 서비스에 로그인" #: ../../source/how-to-configure-logging.rst:130 msgid "" @@ -4005,10 +4692,17 @@ msgid "" ":code:`HTTPHandler` should you wish to backup or analyze the logs " "somewhere else." msgstr "" +"또한 :code:`fl.common.logger.configure` 함수를 사용하면 네이티브 Python " +":code:`logging.handler.HTTPHandler`를 통해 로그를 푸시할 수 있는 호스트를 " +"지정할 수 있습니다(:code:`POST`를 통해). 이는 모든 엔티티(예: 서버 및 " +"클라이언트)에서 로그를 수집하는 것이 번거로울 수 있는 :code:`gRPC` 기반 " +"Federated 학습 워크로드에서 특히 유용한 기능입니다. Flower 시뮬레이션에서는 " +"서버가 모든 로그를 자동으로 표시합니다. 로그를 다른 곳에 백업하거나 " +"분석하려는 경우 :code:`HTTPHandler`를 지정할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:2 msgid "Enable SSL connections" -msgstr "" +msgstr "SSL 연결 사용" #: ../../source/how-to-enable-ssl-connections.rst:4 msgid "" @@ -4016,6 +4710,9 @@ msgid "" "(:code:`SuperLink`) can be started and how a Flower client " "(:code:`SuperNode`) can establish a secure connections to it." msgstr "" +"이 가이드에서는 SSL을 지원하는 보안 Flower 서버(:코드:`SuperLink`)를 " +"시작하는 방법과 Flower 클라이언트(:코드:`SuperNode`)가 이 서버에 보안 연결을 " +"설정하는 방법을 설명합니다." #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" @@ -4023,6 +4720,8 @@ msgid "" "`here `_." msgstr "" +"보안 연결을 보여주는 전체 코드 예제는 '여기 `_'에서 확인할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" @@ -4031,10 +4730,13 @@ msgid "" "descriptive on how it does so. Stick to this guide for a deeper " "introduction to the topic." msgstr "" +"코드 예제에는 시작 방법을 설명하는 :code:`README.md` 파일이 함께 제공됩니다. " +"이미 SSL을 사용하도록 설정되어 있지만 그 방법에 대한 설명이 부족할 수 " +"있습니다. 이 가이드를 참고하여 이 주제에 대해 자세히 알아보세요." #: ../../source/how-to-enable-ssl-connections.rst:16 msgid "Certificates" -msgstr "" +msgstr "인증서" #: ../../source/how-to-enable-ssl-connections.rst:18 msgid "" @@ -4044,12 +4746,18 @@ msgid "" "to ask you to run the script in :code:`examples/advanced-" "tensorflow/certificates/generate.sh` with the following command sequence:" msgstr "" +"SSL 사용 연결을 사용하려면 서버와 클라이언트에 인증서를 전달해야 합니다. 이 " +"가이드에서는 자체 서명된 인증서를 생성하겠습니다. 이 과정은 상당히 복잡할 수 " +"있으므로 다음 명령 시퀀스를 사용하여 :code:`examples/advanced-tensorflow/" +"certificates/generate.sh`에서 스크립트를 실행하도록 요청하겠습니다:" #: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" "This will generate the certificates in :code:`examples/advanced-" "tensorflow/.cache/certificates`." msgstr "" +"이렇게 하면 :code:`examples/advanced-tensorflow/.cache/certificates`에 " +"인증서가 생성됩니다." #: ../../source/how-to-enable-ssl-connections.rst:31 msgid "" @@ -4061,39 +4769,48 @@ msgid "" "projects, it might be sufficient to use the self-signed certificates " "generated using the scripts mentioned in this guide." msgstr "" +"이 예의 맥락에서 SSL 인증서를 생성하는 접근 방식은 영감과 출발점이 될 수 " +"있지만 프로덕션 환경에 대한 참조로 사용해서는 안 됩니다. 프로덕션 환경용 " +"인증서를 올바르게 생성하는 문제에 대해서는 다른 출처를 참조하세요. 중요하지 " +"않은 프로토타이핑 또는 연구 프로젝트의 경우, 이 가이드에 언급된 스크립트를 " +"사용하여 생성한 자체 서명 인증서를 사용하는 것으로 충분할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:39 msgid "Server (SuperLink)" -msgstr "" +msgstr "서버(SuperLink)" #: ../../source/how-to-enable-ssl-connections.rst:41 msgid "" "Use the following terminal command to start a sever (SuperLink) that uses" " the previously generated certificates:" -msgstr "" +msgstr "다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 서버(SuperLink)" +"를 시작합니다:" #: ../../source/how-to-enable-ssl-connections.rst:50 msgid "" "When providing certificates, the server expects a tuple of three " "certificates paths: CA certificate, server certificate and server private" " key." -msgstr "" +msgstr "인증서를 제공할 때 서버는 세 가지 인증서 경로의 튜플을 기대합니다: CA " +"인증서, 서버 인증서 및 서버 개인 키입니다." #: ../../source/how-to-enable-ssl-connections.rst:54 msgid "Client (SuperNode)" -msgstr "" +msgstr "클라이언트(SuperNode)" #: ../../source/how-to-enable-ssl-connections.rst:56 msgid "" "Use the following terminal command to start a client (SuperNode) that " "uses the previously generated certificates:" -msgstr "" +msgstr "다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 " +"클라이언트(SuperNode)를 시작합니다:" #: ../../source/how-to-enable-ssl-connections.rst:64 msgid "" "When setting :code:`root_certificates`, the client expects a file path to" " PEM-encoded root certificates." -msgstr "" +msgstr "코드:`root_certificates`를 설정하면 클라이언트는 PEM 인코딩된 루트 인증서의 " +"파일 경로를 예상합니다." #: ../../source/how-to-enable-ssl-connections.rst:70 msgid "" @@ -4101,28 +4818,30 @@ msgid "" "using the given script, start an SSL-enabled server and have a client " "establish a secure connection to it." msgstr "" +"이제 주어진 스크립트를 사용하여 자체 서명 인증서를 생성하고, SSL 사용 서버를 " +"시작하고, 클라이언트가 보안 연결을 설정하는 방법을 배웠을 것입니다." #: ../../source/how-to-enable-ssl-connections.rst:75 msgid "Additional resources" -msgstr "" +msgstr "추가 리소스" #: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" "These additional sources might be relevant if you would like to dive " "deeper into the topic of certificates:" -msgstr "" +msgstr "인증서에 대해 더 자세히 알아보고 싶다면 이러한 추가 자료를 참고하세요:" #: ../../source/how-to-enable-ssl-connections.rst:79 msgid "`Let's Encrypt `_" -msgstr "" +msgstr "'암호화하세요 `_'" #: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" -msgstr "" +msgstr "인증봇 `_" #: ../../source/how-to-implement-strategies.rst:2 msgid "Implement strategies" -msgstr "" +msgstr "전략 구현" #: ../../source/how-to-implement-strategies.rst:4 msgid "" @@ -4133,10 +4852,15 @@ msgid "" "evaluate models. Flower provides a few built-in strategies which are " "based on the same API described below." msgstr "" +"전략 추상화를 통해 완전한 맞춤형 전략을 구현할 수 있습니다. 전략은 " +"기본적으로 서버에서 실행되는 federated 학습 알고리즘입니다. 전략은 " +"클라이언트를 샘플링하는 방법, 학습을 위해 클라이언트를 구성하는 방법, " +"업데이트를 집계하는 방법, 모델을 평가하는 방법을 결정합니다. Flower는 아래에 " +"설명된 것과 동일한 API를 기반으로 하는 몇 가지 기본 제공 전략을 제공합니다." #: ../../source/how-to-implement-strategies.rst:11 msgid "The :code:`Strategy` abstraction" -msgstr "" +msgstr ":code:`Strategy` 추상화" #: ../../source/how-to-implement-strategies.rst:13 msgid "" @@ -4146,12 +4870,15 @@ msgid "" "implementations have the exact same capabilities at their disposal as " "built-in ones." msgstr "" +"모든 전략 구현은 기본 제공 구현과 타사 구현 모두 추상 기본 클래스인 " +":code:`flwr.server.strategy.Strategy`에서 파생됩니다. 즉, 사용자 정의 전략 " +"구현은 기본 제공 구현과 완전히 동일한 기능을 사용할 수 있습니다." #: ../../source/how-to-implement-strategies.rst:18 msgid "" "The strategy abstraction defines a few abstract methods that need to be " "implemented:" -msgstr "" +msgstr "전략 추상화에서는 구현해야 하는 몇 가지 추상적인 메서드를 정의합니다:" #: ../../source/how-to-implement-strategies.rst:75 msgid "" @@ -4159,18 +4886,21 @@ msgid "" "from the abstract base class :code:`Strategy`) that implements for the " "previously shown abstract methods:" msgstr "" +"새 전략을 생성한다는 것은 이전에 표시된 추상 메서드에 대해 구현하는 새로운 " +":code:`class`(추상 기본 클래스 :code:`Strategy`에서 파생됨)를 구현하는 것을 " +"의미합니다:" #: ../../source/how-to-implement-strategies.rst:100 msgid "The Flower server calls these methods in the following order:" -msgstr "" +msgstr "Flower 서버는 다음 순서로 이러한 메서드를 호출합니다:" #: ../../source/how-to-implement-strategies.rst:177 msgid "The following sections describe each of those methods in more detail." -msgstr "" +msgstr "다음 섹션에서는 이러한 각 방법에 대해 자세히 설명합니다." #: ../../source/how-to-implement-strategies.rst:180 msgid "The :code:`initialize_parameters` method" -msgstr "" +msgstr ":code:`initialize_parameters` 메서드" #: ../../source/how-to-implement-strategies.rst:182 msgid "" @@ -4178,6 +4908,9 @@ msgid "" "of an execution. It is responsible for providing the initial global model" " parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" +"code:`initialize_parameters`는 실행을 처음 시작할 때 한 번만 호출됩니다. 이 " +"함수는 초기 전역 모델 파라미터를 직렬화된 형식(즉, :code:`Parameters` 객체)" +"으로 제공하는 역할을 합니다." #: ../../source/how-to-implement-strategies.rst:184 msgid "" @@ -4185,6 +4918,8 @@ msgid "" "following example shows how initial parameters can be passed to " ":code:`FedAvg`:" msgstr "" +"기본 제공 전략은 사용자가 제공한 초기 매개 변수를 반환합니다. 다음 예는 초기 " +"매개 변수를 :code:`FedAvg`에 전달하는 방법을 보여줍니다:" #: ../../source/how-to-implement-strategies.rst:209 msgid "" @@ -4197,6 +4932,13 @@ msgid "" "useful for prototyping. In practice, it is recommended to always use " "server-side parameter initialization." msgstr "" +"Flower 서버는 :code:`initialize_parameters`를 호출하여 " +":code:`initial_parameters`에 전달된 파라미터를 반환하거나 :code:`None`을 " +"반환합니다. :code:`initial_parameters`에서 반환되는 매개변수가 없는 경우(즉, " +":code:`None`) 서버는 무작위로 클라이언트 하나를 선택하여 해당 클라이언트에 " +"매개변수를 제공하도록 요청합니다. 이는 편의 기능이며 실제로는 권장하지 " +"않지만 프로토타이핑에는 유용할 수 있습니다. 실제로는 항상 서버 측 매개변수 " +"초기화를 사용하는 것이 좋습니다." #: ../../source/how-to-implement-strategies.rst:213 msgid "" @@ -4206,10 +4948,14 @@ msgid "" "approaches, for example, to fine-tune a pre-trained model using federated" " learning." msgstr "" +"서버 측 파라미터 초기화는 강력한 메커니즘입니다. 예를 들어 이전에 저장한 " +"체크포인트에서 학습을 재개하는 데 사용할 수 있습니다. 또한 federated 학습을 " +"사용하여 사전 학습된 모델을 미세 조정하는 등 하이브리드 접근 방식을 구현하는 " +"데 필요한 기본 기능입니다." #: ../../source/how-to-implement-strategies.rst:216 msgid "The :code:`configure_fit` method" -msgstr "" +msgstr ":code:`configure_fit` 메서드" #: ../../source/how-to-implement-strategies.rst:218 msgid "" @@ -4218,6 +4964,10 @@ msgid "" "round means selecting clients and deciding what instructions to send to " "these clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" +":code:`configure_fit`은 다가오는 학 라운드를 구성하는 역할을 합니다. 이 " +"문맥에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 클라이언트를 " +"선택하고 이 클라이언트에게 어떤 지침을 보낼지 결정하는 것을 의미합니다. " +"code:`configure_fit`의 시그니처를 보면 이를 명확히 알 수 있습니다:" #: ../../source/how-to-implement-strategies.rst:231 msgid "" @@ -4225,6 +4975,9 @@ msgid "" "that will be sent to a particular client. Strategy implementations " "usually perform the following steps in :code:`configure_fit`:" msgstr "" +"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 instruction을 " +"나타냅니다. 전략 구현은 일반적으로 :code:`configure_fit`에서 다음 단계를 " +"수행합니다:" #: ../../source/how-to-implement-strategies.rst:233 #: ../../source/how-to-implement-strategies.rst:280 @@ -4232,12 +4985,16 @@ msgid "" "Use the :code:`client_manager` to randomly sample all (or a subset of) " "available clients (each represented as a :code:`ClientProxy` object)" msgstr "" +":code:`client_manager`를 사용하여 사용 가능한 모든 클라이언트(또는 그 하위 " +"집합)를 무작위로 샘플링합니다(각각 :code:`ClientProxy` 개체로 표시됨)" #: ../../source/how-to-implement-strategies.rst:234 msgid "" "Pair each :code:`ClientProxy` with the same :code:`FitIns` holding the " "current global model :code:`parameters` and :code:`config` dict" msgstr "" +"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 " +":code:`config` dict를 보유한 동일한 :code:`FitIns`와 쌍을 이룹니다" #: ../../source/how-to-implement-strategies.rst:236 msgid "" @@ -4246,6 +5003,9 @@ msgid "" "in a round if the corresponding :code:`ClientProxy` is included in the " "list returned from :code:`configure_fit`." msgstr "" +"보다 정교한 구현은 :code:`configure_fit`을 사용하여 사용자 지정 클라이언트 " +"선택 로직을 구현할 수 있습니다. 클라이언트는 :code:`configure_fit`에서 " +"반환된 목록에 해당 :code:`ClientProxy`가 포함된 경우에만 라운드에 참여합니다." #: ../../source/how-to-implement-strategies.rst:240 msgid "" @@ -4256,10 +5016,15 @@ msgid "" "different hyperparameters on different clients (via the :code:`config` " "dict)." msgstr "" +"이 반환 값의 구조는 사용자에게 많은 유연성을 제공합니다. instructions은 " +"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 instructions을 전송할 수 " +"있습니다. 이를 통해 예를 들어 클라이언트마다 다른 모델을 학습시키거나 " +"클라이언트마다 다른 하이퍼파라미터를 사용하는 사용자 지정 전략을 사용할 수 " +"있습니다(:code:`config` dict를 통해)." #: ../../source/how-to-implement-strategies.rst:243 msgid "The :code:`aggregate_fit` method" -msgstr "" +msgstr ":code:`aggregate_fit` 메서드" #: ../../source/how-to-implement-strategies.rst:245 msgid "" @@ -4267,6 +5032,8 @@ msgid "" " by the clients that were selected and asked to train in " ":code:`configure_fit`." msgstr "" +"code:`aggregate_fit`은 :code:`configure_fit`에서 훈련하도록 선택되고 요청된 " +"클라이언트가 반환한 결과를 집계하는 역할을 담당합니다." #: ../../source/how-to-implement-strategies.rst:258 msgid "" @@ -4275,6 +5042,10 @@ msgid "" ":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " "of :code:`results`, but also a list of :code:`failures`." msgstr "" +"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 " +"결과를 얻을 수 있다는 보장은 없습니다(:code:`configure_fit`을 통해). 따라서 " +":code:`aggregate_fit`은 :code:`results` 목록뿐만 아니라 :code:`failures` " +"목록도 받습니다." #: ../../source/how-to-implement-strategies.rst:260 msgid "" @@ -4283,10 +5054,14 @@ msgid "" " optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" +"code:`aggregate_fit`은 선택적 :code:`Parameters` 개체와 집계된 메트릭의 " +"dictionary를 반환합니다. :code:`Parameters` 반환 값은 :code:`aggregate_fit`" +"이 제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 " +"너무 많음) 선택 사항입니다." #: ../../source/how-to-implement-strategies.rst:263 msgid "The :code:`configure_evaluate` method" -msgstr "" +msgstr ":code:`configure_evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:265 msgid "" @@ -4296,6 +5071,11 @@ msgid "" "instructions to send to these clients. The signature of " ":code:`configure_evaluate` makes this clear:" msgstr "" +":code:`configure_evaluate`는 다가오는 평가 라운드를 구성하는 역할을 합니다. " +"이 문맥에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 " +"클라이언트를 선택하고 이러한 클라이언트에 전송할 지침을 결정하는 것을 " +"의미합니다. :code:`configure_evaluate`의 시그니처를 보면 이를 명확히 알 수 " +"있습니다:" #: ../../source/how-to-implement-strategies.rst:278 msgid "" @@ -4303,12 +5083,17 @@ msgid "" "that will be sent to a particular client. Strategy implementations " "usually perform the following steps in :code:`configure_evaluate`:" msgstr "" +"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 instructions을 " +"나타냅니다. 전략 구현은 일반적으로 :code:`configure_evaluate`에서 다음 " +"단계를 수행합니다:" #: ../../source/how-to-implement-strategies.rst:281 msgid "" "Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " "the current global model :code:`parameters` and :code:`config` dict" msgstr "" +"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 " +":code:`config` dict를 보유한 동일한 :code:`EvaluateIns`와 쌍을 이룹니다" #: ../../source/how-to-implement-strategies.rst:283 msgid "" @@ -4317,6 +5102,10 @@ msgid "" "in a round if the corresponding :code:`ClientProxy` is included in the " "list returned from :code:`configure_evaluate`." msgstr "" +"보다 정교한 구현은 :code:`configure_evaluate`를 사용하여 사용자 지정 " +"클라이언트 선택 로직을 구현할 수 있습니다. 클라이언트는 " +":code:`configure_evaluate`에서 반환된 목록에 해당 :code:`ClientProxy`가 " +"포함된 경우에만 라운드에 참여합니다." #: ../../source/how-to-implement-strategies.rst:287 msgid "" @@ -4327,10 +5116,15 @@ msgid "" "different hyperparameters on different clients (via the :code:`config` " "dict)." msgstr "" +"이 반환 값의 구조는 사용자에게 많은 유연성을 제공합니다. instructions은 " +"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 instructions을 전송할 수 " +"있습니다. 이를 통해 사용자 지정 전략을 통해 예를 들어 클라이언트마다 다른 " +"모델을 평가하거나 클라이언트마다 다른 하이퍼파라미터를 사용할 수 " +"있습니다(:code:`config` dict를 통해)." #: ../../source/how-to-implement-strategies.rst:291 msgid "The :code:`aggregate_evaluate` method" -msgstr "" +msgstr ":code:`aggregate_evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:293 msgid "" @@ -4338,6 +5132,8 @@ msgid "" "returned by the clients that were selected and asked to evaluate in " ":code:`configure_evaluate`." msgstr "" +"code:`aggregate_evaluate`는 :code:`configure_evaluate`에서 선택되어 평가를 " +"요청한 클라이언트가 반환한 결과를 집계하는 역할을 담당합니다." #: ../../source/how-to-implement-strategies.rst:306 msgid "" @@ -4346,6 +5142,10 @@ msgid "" ":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " "receives a list of :code:`results`, but also a list of :code:`failures`." msgstr "" +"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 " +"결과를 얻을 수 있다는 보장은 없습니다(:code:`configure_evaluate`를 통해). " +"따라서 :code:`aggregate_evaluate`는 :code:`results` 목록뿐만 아니라 " +":code:`failures` 목록도 받습니다." #: ../../source/how-to-implement-strategies.rst:308 msgid "" @@ -4354,10 +5154,14 @@ msgid "" "optional because :code:`aggregate_evaluate` might decide that the results" " provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" +"code:`aggregate_evaluate`는 선택적 :code:`float`(손실)와 집계된 메트릭의 " +"dictionary를 반환합니다. code:`float` 반환 값은 :code:`aggregate_evaluate`가 " +"제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 너무 " +"많음) 선택 사항입니다." #: ../../source/how-to-implement-strategies.rst:311 msgid "The :code:`evaluate` method" -msgstr "" +msgstr ":code:`evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:313 msgid "" @@ -4366,6 +5170,10 @@ msgid "" ":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " "to perform both servers-side and client-side (federated) evaluation." msgstr "" +":code:`evaluate`는 서버 측에서 모델 매개변수를 평가하는 역할을 담당합니다. " +"code:`configure_evaluate`/:code:`aggregate_evaluate`와 함께 :code:`evaluate`" +"를 사용하면 서버 측과 클라이언트 측(federated) 평가를 모두 수행할 수 있는 " +"전략을 사용할 수 있습니다." #: ../../source/how-to-implement-strategies.rst:323 msgid "" @@ -4374,63 +5182,69 @@ msgid "" ":code:`evaluate` method might not complete successfully (e.g., it might " "fail to load the server-side evaluation data)." msgstr "" +"반환 값은 전략에서 서버 측 평가를 구현할 필요가 없거나 사용자 정의 " +":code:`evaluate` 메서드가 성공적으로 완료되지 않을 수 있기 때문에(예: 서버 " +"측 평가 데이터를 로드하지 못할 수 있음) 다시 선택 사항으로 설정할 수 " +"있습니다." #: ../../source/how-to-install-flower.rst:2 msgid "Install Flower" -msgstr "" +msgstr "Flower 설치" #: ../../source/how-to-install-flower.rst:6 msgid "Python version" -msgstr "" +msgstr "Python 버전" #: ../../source/how-to-install-flower.rst:12 msgid "Install stable release" -msgstr "" +msgstr "안정적인 릴리즈 설치" #: ../../source/how-to-install-flower.rst:15 #: ../../source/how-to-upgrade-to-flower-next.rst:46 msgid "Using pip" -msgstr "" +msgstr "pip 사용" #: ../../source/how-to-install-flower.rst:17 msgid "" "Stable releases are available on `PyPI " "`_::" -msgstr "" +msgstr "안정적인 릴리즈는 `PyPI `_:: 에서 확인할 수 " +"있습니다::" #: ../../source/how-to-install-flower.rst:21 msgid "" "For simulations that use the Virtual Client Engine, ``flwr`` should be " "installed with the ``simulation`` extra::" -msgstr "" +msgstr "가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우 ``flwr``을 ``simulation``" +"extra와 함께 설치해야 합니다:" #: ../../source/how-to-install-flower.rst:27 msgid "Using conda (or mamba)" -msgstr "" +msgstr "conda(또는 mamba) 사용" #: ../../source/how-to-install-flower.rst:29 msgid "Flower can also be installed from the ``conda-forge`` channel." -msgstr "" +msgstr "Flower은 'conda-forge' 채널에서도 설치할 수 있습니다." #: ../../source/how-to-install-flower.rst:31 msgid "" "If you have not added ``conda-forge`` to your channels, you will first " "need to run the following::" -msgstr "" +msgstr "채널에 'conda-forge'를 추가하지 않은 경우 먼저 다음을 실행해야 합니다:" #: ../../source/how-to-install-flower.rst:36 msgid "" "Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " "installed with ``conda``::" -msgstr "" +msgstr "conda-forge`` 채널이 활성화되면 ``flwr``을 ``conda``로 설치할 수 있습니다::" #: ../../source/how-to-install-flower.rst:40 msgid "or with ``mamba``::" -msgstr "" +msgstr "또는 ``mamba``::" #: ../../source/how-to-install-flower.rst:46 msgid "Verify installation" -msgstr "" +msgstr "설치 확인" #: ../../source/how-to-install-flower.rst:48 msgid "" @@ -4438,22 +5252,25 @@ msgid "" "installed. If everything worked, it should print the version of Flower to" " the command line::" msgstr "" +"다음 명령을 사용하여 Flower가 성공적으로 설치되었는지 확인할 수 있습니다. " +"모든 것이 정상적으로 작동하면 명령줄에 Flower의 버전이 출력됩니다:" #: ../../source/how-to-install-flower.rst:55 msgid "Advanced installation options" -msgstr "" +msgstr "고급 설치 옵션" #: ../../source/how-to-install-flower.rst:58 msgid "Install via Docker" -msgstr "" +msgstr "Docker를 통해 설치" #: ../../source/how-to-install-flower.rst:60 msgid ":doc:`How to run Flower using Docker `" -msgstr "" +msgstr ":doc:`Docker를 사용하여 Flower를 실행하는 방법 `" #: ../../source/how-to-install-flower.rst:63 msgid "Install pre-release" -msgstr "" +msgstr "사전 릴리즈 설치" #: ../../source/how-to-install-flower.rst:65 msgid "" @@ -4461,32 +5278,39 @@ msgid "" "pre-release versions (alpha, beta, release candidate) before the stable " "release happens::" msgstr "" +"새(불안정할 수 있는) 버전의 Flower는 안정 버전이 출시되기 전에 사전 릴리즈 " +"버전(알파, 베타, 릴리즈 후보)으로 제공되는 경우가 있습니다:" #: ../../source/how-to-install-flower.rst:69 msgid "" "For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" " should be installed with the ``simulation`` extra::" msgstr "" +"가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우 ``flwr`` 사전 릴리즈를 " +"``simulation`` extra와 함께 설치해야 합니다:" #: ../../source/how-to-install-flower.rst:74 msgid "Install nightly release" -msgstr "" +msgstr "야간 릴리즈 설치" #: ../../source/how-to-install-flower.rst:76 msgid "" "The latest (potentially unstable) changes in Flower are available as " "nightly releases::" -msgstr "" +msgstr "Flower의 최신 (불안정할 수 있는) 변경 사항은 다음과 같이 야간 릴리즈로 " +"제공됩니다:" #: ../../source/how-to-install-flower.rst:80 msgid "" "For simulations that use the Virtual Client Engine, ``flwr-nightly`` " "should be installed with the ``simulation`` extra::" msgstr "" +"가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우, ``flwr-nightly``를 " +"``simulation`` extr와 함께 설치해야 합니다::" #: ../../source/how-to-monitor-simulation.rst:2 msgid "Monitor simulation" -msgstr "" +msgstr "모니터 시뮬레이션" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" @@ -4496,16 +5320,22 @@ msgid "" "constrain the total usage. Insights from resource consumption can help " "you make smarter decisions and speed up the execution time." msgstr "" +"Flower를 사용하면 시뮬레이션을 실행하는 동안 시스템 리소스를 모니터링할 수 " +"있습니다. 또한 Flower 시뮬레이션 엔진은 강력하며 클라이언트별 리소스 할당 " +"방법을 결정하고 총 사용량을 제한할 수 있습니다. 리소스 소비에 대한 " +"인사이트를 통해 더 현명한 결정을 내리고 실행 시간을 단축할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:6 msgid "" "The specific instructions assume you are using macOS and have the " "`Homebrew `_ package manager installed." msgstr "" +"구체적인 지침은 macOS를 사용 중이고 'Homebrew `_ 패키지 " +"관리자가 설치되어 있다고 가정합니다." #: ../../source/how-to-monitor-simulation.rst:10 msgid "Downloads" -msgstr "" +msgstr "다운로드" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" @@ -4514,26 +5344,31 @@ msgid "" "collected data. They are both well integrated with `Ray " "`_ which Flower uses under the hood." msgstr "" +"`Prometheus `_는 데이터 수집에 사용되며, `Grafana " +"`_는 수집된 데이터를 시각화할 수 있게 해줍니다. 이 두 " +"도구는 모두 Flower가 내부적으로 사용하는 `Ray `_와 잘 " +"통합되어 있습니다." #: ../../source/how-to-monitor-simulation.rst:18 msgid "" "Overwrite the configuration files (depending on your device, it might be " "installed on a different path)." -msgstr "" +msgstr "구성 파일을 덮어씁니다(장치에 따라 다른 경로에 설치되어 있을 수 있음)." #: ../../source/how-to-monitor-simulation.rst:20 msgid "If you are on an M1 Mac, it should be:" -msgstr "" +msgstr "M1 Mac을 사용 중이라면:" #: ../../source/how-to-monitor-simulation.rst:27 msgid "On the previous generation Intel Mac devices, it should be:" -msgstr "" +msgstr "이전 세대 Intel Mac 장치에서는:" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" "Open the respective configuration files and change them. Depending on " "your device, use one of the two following commands:" -msgstr "" +msgstr "각 구성 파일을 열고 변경합니다. 장치에 따라 다음 두 명령 중 하나를 " +"사용합니다:" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" @@ -4541,6 +5376,8 @@ msgid "" "config you see below. You may adjust the time intervals to your " "requirements:" msgstr "" +"를 입력한 다음 파일의 모든 텍스트를 삭제하고 아래에 표시된 새 Prometheus " +"설정을 붙여넣습니다. 요구 사항에 따라 시간 간격을 조정할 수 있습니다:" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" @@ -4548,54 +5385,59 @@ msgid "" "the Grafana configuration files. Open those using one of the following " "commands as before:" msgstr "" +"이제 Prometheus 구성을 편집한 후 Grafana 구성 파일에 대해서도 동일한 작업을 " +"수행합니다. 이전과 마찬가지로 다음 명령 중 하나를 사용하여 파일을 엽니다:" #: ../../source/how-to-monitor-simulation.rst:69 msgid "" "Your terminal editor should open and allow you to apply the following " "configuration as before." -msgstr "" +msgstr "터미널 편집기가 열리면 이전과 마찬가지로 다음 구성을 적용할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:84 msgid "" "Congratulations, you just downloaded all the necessary software needed " "for metrics tracking. Now, let’s start it." -msgstr "" +msgstr "축하합니다. 매트릭 트레킹에 필요한 모든 소프트웨어를 다운로드하셨습니다. " +"이제 시작해 보겠습니다." #: ../../source/how-to-monitor-simulation.rst:88 msgid "Tracking metrics" -msgstr "" +msgstr "매트릭 트래킹" #: ../../source/how-to-monitor-simulation.rst:90 msgid "" "Before running your Flower simulation, you have to start the monitoring " "tools you have just installed and configured." -msgstr "" +msgstr "Flower 시뮬레이션을 실행하기 전에 방금 설치 및 구성한 모니터링 도구를 " +"시작해야 합니다." #: ../../source/how-to-monitor-simulation.rst:97 msgid "" "Please include the following argument in your Python code when starting a" " simulation." -msgstr "" +msgstr "시뮬레이션을 시작할 때 Python 코드에 다음 argument를 포함하세요." #: ../../source/how-to-monitor-simulation.rst:108 msgid "Now, you are ready to start your workload." -msgstr "" +msgstr "이제 워크로드를 시작할 준비가 되었습니다." #: ../../source/how-to-monitor-simulation.rst:110 msgid "" "Shortly after the simulation starts, you should see the following logs in" " your terminal:" -msgstr "" +msgstr "시뮬레이션이 시작되고 얼마 지나지 않아 터미널에 다음 로그가 표시됩니다:" #: ../../source/how-to-monitor-simulation.rst:117 msgid "You can look at everything at ``_ ." -msgstr "" +msgstr "``_ 에서 모든 것을 볼 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:119 msgid "" "It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" " lowest option)." -msgstr "" +msgstr "Ray 대시보드입니다. 메트릭(왼쪽 패널의 가장 아래 옵션)으로 이동할 수 " +"있습니다." #: ../../source/how-to-monitor-simulation.rst:121 msgid "" @@ -4605,6 +5447,11 @@ msgid "" "can only use Grafana to explore the metrics. You can start Grafana by " "going to ``http://localhost:3000/``." msgstr "" +"또는 오른쪽 위 모서리인 \"Grafana에서 보기\"를 클릭하여 Grafana에서 바로 " +"확인할 수도 있습니다. Ray 대시보드는 시뮬레이션 중에만 액세스할 수 있다는 " +"점에 유의하세요. 시뮬레이션이 종료된 후에는 Grafana를 사용하여 메트릭을 " +"탐색할 수만 있습니다. ``http://localhost:3000/``로 이동하여 Grafana를 시작할 " +"수 있습니다." #: ../../source/how-to-monitor-simulation.rst:123 msgid "" @@ -4612,16 +5459,19 @@ msgid "" "important as they will otherwise block, for example port :code:`3000` on " "your machine as long as they are running." msgstr "" +"시각화를 완료한 후에는 Prometheus와 Grafana를 중지합니다. 그렇지 않으면 실행 " +"중인 동안 컴퓨터에서 포트 :code:`3000` 등을 차단하므로 이 작업이 중요합니다." #: ../../source/how-to-monitor-simulation.rst:132 msgid "Resource allocation" -msgstr "" +msgstr "리소스 할당" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" "You must understand how the Ray library works to efficiently allocate " "system resources to simulation clients on your own." -msgstr "" +msgstr "Ray 라이브러리가 어떻게 작동하는지 이해해야 시뮬레이션 클라이언트에 시스템 " +"리소스를 효율적으로 할당할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:136 msgid "" @@ -4632,20 +5482,27 @@ msgid "" "You will learn more about that in the later part of this blog. You can " "check the system resources by running the following:" msgstr "" +"처음에 시뮬레이션(Ray가 내부에서 처리하는)은 기본적으로 시스템에서 사용 " +"가능한 모든 리소스를 사용하여 시작되며, 이 리소스는 클라이언트 간에 " +"공유됩니다. 그렇다고 해서 모든 클라이언트에게 균등하게 분배하거나 모든 " +"클라이언트에서 동시에 모델 학습이 이루어지는 것은 아닙니다. 이에 대한 자세한 " +"내용은 이 블로그의 뒷부분에서 설명합니다. 다음을 실행하여 시스템 리소스를 " +"확인할 수 있습니다:" #: ../../source/how-to-monitor-simulation.rst:143 msgid "In Google Colab, the result you see might be similar to this:" -msgstr "" +msgstr "Google Colab에서는 이와 유사한 결과가 표시될 수 있습니다:" #: ../../source/how-to-monitor-simulation.rst:155 msgid "" "However, you can overwrite the defaults. When starting a simulation, do " "the following (you don't need to overwrite all of them):" -msgstr "" +msgstr "그러나 기본값을 덮어쓸 수 있습니다. 시뮬레이션을 시작할 때 다음을 수행합니다(" +"모두 덮어쓸 필요는 없음):" #: ../../source/how-to-monitor-simulation.rst:175 msgid "Let’s also specify the resource for a single client." -msgstr "" +msgstr "단일 클라이언트에 대한 리소스도 지정해 보겠습니다." #: ../../source/how-to-monitor-simulation.rst:205 msgid "" @@ -4653,6 +5510,8 @@ msgid "" "all the required resources (such that they run in parallel) when the " "resources allow." msgstr "" +"이제 중요한 부분이 나옵니다. Ray는 리소스가 허용하는 경우에만 필요한 모든 " +"리소스가 있을 때(병렬로 실행되는 등) 새 클라이언트를 시작합니다." #: ../../source/how-to-monitor-simulation.rst:207 msgid "" @@ -4663,14 +5522,20 @@ msgid "" ":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " "had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." msgstr "" +"위의 예에서는 하나의 클라이언트만 실행되므로 클라이언트가 동시에 실행되지 " +"않습니다. :code:`client_num_gpus = 0.5` 를 설정하면 두 개의 클라이언트를 " +"실행할 수 있으므로 동시에 실행할 수 있습니다. 사용 가능한 리소스보다 더 많은 " +"리소스를 요구하지 않도록 주의하세요. :code:`client_num_gpus = 2`를 지정하면 " +"시뮬레이션이 시작되지 않습니다(GPU가 2개이지만 :code:`ray_init_args`에서 " +"1개를 설정한 경우에도 마찬가지입니다)." #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 msgid "FAQ" -msgstr "" +msgstr "자주 묻는 질문" #: ../../source/how-to-monitor-simulation.rst:214 msgid "Q: I don't see any metrics logged." -msgstr "" +msgstr "질문: 기록된 메트릭이 보이지 않습니다." #: ../../source/how-to-monitor-simulation.rst:216 msgid "" @@ -4678,6 +5543,9 @@ msgid "" "right corner (\"Last 30 minutes\" by default). Please change the " "timeframe to reflect the period when the simulation was running." msgstr "" +"A: 기간이 제대로 설정되지 않았을 수 있습니다. 설정은 오른쪽 상단에 있습니다(" +"기본값은 '지난 30분'). 시뮬레이션이 실행된 기간을 반영하도록 기간을 변경해 " +"주세요." #: ../../source/how-to-monitor-simulation.rst:218 msgid "" @@ -4685,42 +5553,49 @@ msgid "" "server is running and refresh this page” after going to the Metrics tab " "in Ray Dashboard." msgstr "" +"질문: \"Grafana 서버가 감지되지 않았습니다. Ray 대시보드의 메트릭 탭으로 " +"이동한 후 Grafana 서버가 실행 중인지 확인하고 이 페이지를 새로고침하세요." +"\"라는 메시지가 표시됩니다." #: ../../source/how-to-monitor-simulation.rst:220 msgid "" "A: You probably don't have Grafana running. Please check the running " "services" -msgstr "" +msgstr "A: Grafana가 실행되고 있지 않을 수 있습니다. 실행 중인 서비스를 확인하세요" #: ../../source/how-to-monitor-simulation.rst:226 msgid "" "Q: I see \"This site can't be reached\" when going to " "``_." msgstr "" +"Q: ``_로 이동할 때 \"이 사이트에 연결할 수 없습니다." +"\"라는 메시지가 표시됩니다." #: ../../source/how-to-monitor-simulation.rst:228 msgid "" "A: Either the simulation has already finished, or you still need to start" " Prometheus." -msgstr "" +msgstr "A: 시뮬레이션이 이미 완료되었거나 아직 Prometheus를 시작해야 합니다." #: ../../source/how-to-monitor-simulation.rst:232 msgid "Resources" -msgstr "" +msgstr "리소스" #: ../../source/how-to-monitor-simulation.rst:234 msgid "" "Ray Dashboard: ``_" msgstr "" +"Ray 대시보드: ``_" #: ../../source/how-to-monitor-simulation.rst:236 msgid "Ray Metrics: ``_" -msgstr "" +msgstr "Ray 메트릭: ``_" #: ../../source/how-to-run-flower-using-docker.rst:2 msgid "Run Flower using Docker" -msgstr "" +msgstr "Docker를 사용하여 Flower 실행" #: ../../source/how-to-run-flower-using-docker.rst:4 msgid "" @@ -4729,10 +5604,13 @@ msgid "" "`__. Supported architectures include " "``amd64`` and ``arm64v8``." msgstr "" +"Flower를 시작하는 가장 간단한 방법은 `Docker Hub `__에서 찾을 수 있는 미리 만들어진 Docker 이미지를 사용하는 것입니다. " +"지원되는 아키텍처는 ``amd64`` 및 ``arm64v8``입니다." #: ../../source/how-to-run-flower-using-docker.rst:8 msgid "Before you start, make sure that the Docker daemon is running:" -msgstr "" +msgstr "시작하기 전에 Docker daemon이 실행 중인지 확인하세요:" #: ../../source/how-to-run-flower-using-docker.rst:15 msgid "" @@ -4741,6 +5619,9 @@ msgid "" "You can find installation instruction `here `_." msgstr "" +"전이 표시되지 않고 대신 명령을 찾을 수 없다는 오류가 표시되는 경우 먼저 " +"Docker를 설치해야 합니다. `여기 `_에서 " +"설치 지침을 찾을 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:21 msgid "" @@ -4749,6 +5630,9 @@ msgid "" "`_ on the " "official Docker website." msgstr "" +"Linux에서 Docker 명령을 실행하려면 ``sudo`` 권한이 필요합니다. sudo``를 " +"사용하지 않으려면 공식 Docker 웹사이트의 `Post-installation steps " +"`_를 따르세요." #: ../../source/how-to-run-flower-using-docker.rst:27 msgid "" @@ -4757,18 +5641,22 @@ msgid "" "This guarantees seamless integration and avoids potential conflicts or " "issues that may arise from using different versions." msgstr "" +"최적의 성능과 호환성을 보장하려면 SuperLink, SuperNode 및 ServerApp 이미지를 " +"함께 실행할 때 버전이 동일해야 합니다. 이렇게 하면 원활한 통합을 보장하고 " +"서로 다른 버전을 사용할 때 발생할 수 있는 잠재적인 충돌이나 문제를 방지할 수 " +"있습니다." #: ../../source/how-to-run-flower-using-docker.rst:32 msgid "Flower SuperLink" -msgstr "" +msgstr "Flower SuperLink" #: ../../source/how-to-run-flower-using-docker.rst:35 msgid "Quickstart" -msgstr "" +msgstr "빠른 시작" #: ../../source/how-to-run-flower-using-docker.rst:37 msgid "If you're looking to try out Flower, you can use the following command:" -msgstr "" +msgstr "Flower를 사용해보고 싶다면 다음 명령을 사용하면 됩니다:" #: ../../source/how-to-run-flower-using-docker.rst:43 msgid "" @@ -4776,6 +5664,9 @@ msgid "" "Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " "The ``--rm`` flag tells Docker to remove the container after it exits." msgstr "" +"이 명령은 Docker Hub에서 ``1.8.0`` 태그가 있는 Docker 이미지를 가져옵니다. " +"이 태그는 Flower 버전을 지정합니다. 이 경우, Flower 1.8.0입니다. '`--rm`` " +"플래그는 컨테이너가 종료된 후 컨테이너를 제거하도록 Docker에 지시합니다." #: ../../source/how-to-run-flower-using-docker.rst:49 msgid "" @@ -4784,6 +5675,9 @@ msgid "" "starts. We will show below how to save the state in a file on your host " "system." msgstr "" +"기본적으로 Flower SuperLink는 상태를 in-memory에 유지합니다. Docker 플래그 " +"`--rm``을 사용하는 경우 컨테이너 시작 사이에 상태가 유지되지 않습니다. " +"아래에서 호스트 시스템의 파일에 상태를 저장하는 방법을 보여드리겠습니다." #: ../../source/how-to-run-flower-using-docker.rst:53 msgid "" @@ -4794,6 +5688,11 @@ msgid "" "after the tag is passed to the Flower SuperLink. Here, we are passing the" " flag ``--insecure``." msgstr "" +"``-p :`` 플래그는 호스트의 포트 ``9091``/``9092``를 " +"컨테이너의 ``9091``/``9092``에 매핑하여 ``http://localhost:9091``의 드라이버 " +"API와 ``http://localhost:9092``의 Fleet API에 액세스할 수 있도록 Docker에 " +"지시합니다. 마지막으로, 태그 뒤에 오는 모든 플래그는 Flower SuperLink에 " +"전달됩니다. 여기서는 ``--insecure``플래그를 전달합니다." #: ../../source/how-to-run-flower-using-docker.rst:60 #: ../../source/how-to-run-flower-using-docker.rst:259 @@ -4805,16 +5704,20 @@ msgid "" "flower-using-docker.html#enabling-ssl-for-secure-connections>`__ when " "deploying to a production environment." msgstr "" +"``--insecure`` 플래그는 안전하지 않은 통신(HTTPS가 아닌 HTTP 사용)을 " +"활성화하며 테스트 목적으로만 사용해야 합니다. 프로덕션 환경에 배포할 때는 `" +"SSL `__을 활성화할 것을 강력히 권장합니다." #: ../../source/how-to-run-flower-using-docker.rst:65 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" -msgstr "" +msgstr "'`--help``을 사용하면 SuperLink가 지원하는 모든 플래그를 볼 수 있습니다:" #: ../../source/how-to-run-flower-using-docker.rst:72 msgid "Mounting a volume to store the state on the host system" -msgstr "" +msgstr "호스트 시스템에 상태를 저장할 볼륨 마운트하기" #: ../../source/how-to-run-flower-using-docker.rst:74 msgid "" @@ -4828,6 +5731,14 @@ msgid "" "you can change the user ID back to the current user ID by running ``sudo " "chown -R $USER:$(id -gn) state``." msgstr "" +"호스트 시스템에서 SuperLink의 상태를 유지하려면 호스트 시스템에서 파일을 " +"저장할 디렉터리와 데이터베이스 파일의 이름을 지정하기만 하면 됩니다. " +"기본적으로 SuperLink 컨테이너는 사용자 ID가 ``49999``인 ``app``이라는 루트가 " +"아닌 사용자로 실행됩니다. 마운트된 디렉터리에 적절한 권한이 있는지 " +"확인하려면 새 디렉터리를 생성하고 디렉터리의 사용자 ID를 ``49999``로 " +"변경하는 것이 좋습니다. 나중에 디렉터리를 삭제하려면 ``sudo chown -R $USER:$(" +"id -gn) state``를 실행하여 사용자 ID를 현재 사용자 ID로 다시 변경할 수 " +"있습니다." #: ../../source/how-to-run-flower-using-docker.rst:82 msgid "" @@ -4837,6 +5748,10 @@ msgid "" "Furthermore, we use the flag ``--database`` to specify the name of the " "database file." msgstr "" +"아래 예에서는 새 디렉터리를 생성하고, 사용자 ID를 변경하고, 플래그 " +"``--volume``을 통해 Docker에게 로컬 ``state`` 디렉터리를 컨테이너의 ``/app/" +"state`` 디렉터리에 마운트하도록 지시합니다. 또한 ``--database`` 플래그를 " +"사용하여 데이터베이스 파일의 이름을 지정합니다." #: ../../source/how-to-run-flower-using-docker.rst:95 msgid "" @@ -4845,18 +5760,24 @@ msgid "" "SuperLink tries to restore the state from the file. To start the " "SuperLink with an empty database, simply remove the ``state.db`` file." msgstr "" +"SuperLink가 시작되자마자 호스트 시스템의 ``state`` 디렉터리에 ``state.db`` " +"파일이 생성됩니다. 파일이 이미 존재하는 경우 SuperLink는 파일에서 상태를 " +"복원하려고 시도합니다. 빈 데이터베이스로 SuperLink를 시작하려면 ``state.db`` " +"파일을 제거하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:100 #: ../../source/how-to-run-flower-using-docker.rst:281 #: ../../source/how-to-run-flower-using-docker.rst:397 msgid "Enabling SSL for secure connections" -msgstr "" +msgstr "보안 연결을 위한 SSL 사용 설정" #: ../../source/how-to-run-flower-using-docker.rst:102 msgid "" "To enable SSL, you will need a PEM-encoded root certificate, a PEM-" "encoded private key and a PEM-encoded certificate chain." msgstr "" +"SSL을 사용하려면 PEM으로 인코딩된 루트 인증서, PEM으로 인코딩된 개인 키 및 " +"PEM으로 인코딩된 인증서 체인이 필요합니다." #: ../../source/how-to-run-flower-using-docker.rst:106 msgid "" @@ -4865,6 +5786,9 @@ msgid "" "enable-ssl-connections.html#certificates>`__ page contains a section that" " will guide you through the process." msgstr "" +"테스트 목적으로 자체 서명된 인증서를 생성할 수 있습니다. 'SSL 연결 사용 " +"`__ 페이지에 프로세스를 안내하는 섹션이 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:110 msgid "" @@ -4877,6 +5801,14 @@ msgid "" "the names of the certificates and key file to the SuperLink with the " "``--ssl-ca-certfile``, ``--ssl-certfile`` and ``--ssl-keyfile`` flag." msgstr "" +"필요한 모든 파일이 로컬``certificates`` 디렉터리에 있다고 가정하면, " +"``--volume``플래그를 사용하여 로컬 디렉터리를 컨테이너의 ``/app/certificates/" +"`` 디렉터리에 마운트할 수 있습니다. 이렇게 하면 SuperLink 가 컨테이너 내의 " +"파일에 액세스할 수 있습니다. ``ro``는 ``read-only``을 의미합니다. Docker " +"볼륨은 기본적으로 ``read-write``로 설정되어 있는데, 이 옵션을 사용하면 " +"볼륨을 ``read-only``으로 만들 수 있습니다. 마지막으로 인증서 및 키 파일의 " +"이름을 ``--ssl-ca-certfile``, ``--ssl-certfile`` 및 ``--ssl-keyfile`` " +"플래그와 함께 SuperLink에 전달합니다." #: ../../source/how-to-run-flower-using-docker.rst:128 msgid "" @@ -4886,16 +5818,22 @@ msgid "" " the ``certificates/`` directory, you can run ``sudo chown -R 49999:49999" " certificates/*``." msgstr "" +"기본적으로 Flower 컨테이너는 루트가 아닌 사용자 ``app``로 실행되므로 " +"마운트된 파일과 디렉터리에 사용자 ID ``49999``에 대한 적절한 권한이 있어야 " +"합니다. 예를 들어, ``certificates/`` 디렉터리에 있는 모든 파일의 사용자 ID를 " +"변경하려면 ``sudo chown -R 49999:49999 certificates/*``를 실행하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:134 msgid "Flower SuperNode" -msgstr "" +msgstr "Flower SuperNode" #: ../../source/how-to-run-flower-using-docker.rst:136 msgid "" "The SuperNode Docker image comes with a pre-installed version of Flower " "and serves as a base for building your own SuperNode image." msgstr "" +"SuperNode Docker 이미지는 Flower의 사전 설치된 버전과 함께 제공되며, 자체 " +"SuperNode 이미지를 구축하기 위한 기반 역할을 합니다." #: ../../source/how-to-run-flower-using-docker.rst:141 msgid "" @@ -4906,12 +5844,19 @@ msgid "" "same day. To ensure the versions are in sync, using the concrete tag, " "e.g., ``1.9.0.dev20240501`` instead of ``nightly`` is recommended." msgstr "" +"SuperNode Docker 이미지는 현재 1.9.0 야간 릴리스에서만 작동합니다. 안정 " +"버전은 Flower 1.9.0(안정)이 출시되면 사용할 수 있습니다(예상 출시일: 5월). " +"SuperNode 야간 이미지는 같은 날 릴리스된 해당 SuperLink 및 서버앱 야간 " +"이미지와 페어링되어야 합니다. 버전이 동기화되도록 하려면 ``nightly`` 대신 ``1" +".9.0.dev20240501``과 같은 구체적인 태그를 사용하는 것이 좋습니다." #: ../../source/how-to-run-flower-using-docker.rst:147 msgid "" "We will use the ``quickstart-pytorch`` example, which you can find in the" " Flower repository, to illustrate how you can dockerize your ClientApp." msgstr "" +"Flower 레포지토리에서 찾을 수 있는 ``quickstart-pytorch`` 예제를 사용하여 " +"ClientApp을 도커라이즈하는 방법을 설명하겠습니다." #: ../../source/how-to-run-flower-using-docker.rst:155 msgid "" @@ -4919,19 +5864,22 @@ msgid "" "development environment. You can skip the first part if you want to run " "your ClientApp instead of the ``quickstart-pytorch`` example." msgstr "" +"시작하기 전에 로컬 개발 환경에서 몇 가지 전제 조건을 충족해야 합니다. " +"'quickstart-pytorch' 예제 대신 ClientApp을 실행하려는 경우 첫 번째 부분을 " +"건너뛸 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:159 msgid "Clone the Flower repository." -msgstr "" +msgstr "플라워 레포지토리를 클론합니다." #: ../../source/how-to-run-flower-using-docker.rst:173 msgid "Creating a SuperNode Dockerfile" -msgstr "" +msgstr "SuperNode Dockerfile 만들기" #: ../../source/how-to-run-flower-using-docker.rst:175 #: ../../source/how-to-run-flower-using-docker.rst:311 msgid "Let's assume the following project layout:" -msgstr "" +msgstr "다음과 같은 프로젝트 레이아웃을 가정해 보겠습니다:" #: ../../source/how-to-run-flower-using-docker.rst:184 msgid "" @@ -4939,6 +5887,9 @@ msgid "" "where the ``ClientApp`` code is located. In the file, we list all the " "dependencies that the ClientApp requires." msgstr "" +"먼저 ``ClientApp`` 코드가 있는 디렉토리에 ``requirements.txt`` 파일을 " +"만들어야 합니다. 이 파일에는 클라이언트 앱에 필요한 모든 dependencies을 " +"나열합니다." #: ../../source/how-to-run-flower-using-docker.rst:196 msgid "" @@ -4947,6 +5898,9 @@ msgid "" "package dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" +"`flwr `__ 는 이미 ``flwr/supernode`` 기본 " +"이미지에 설치되어 있으므로, ``torch``, ``tensorflow`` 등과 같은 다른 패키지 " +"dependencies만 ``requirements.txt``에 포함시키면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:200 msgid "" @@ -4954,12 +5908,16 @@ msgid "" "example, create a new file called ``Dockerfile.supernode`` in ``examples" "/quickstart-pytorch``." msgstr "" +"다음으로, Dockerfile을 생성합니다.``quickstart-pytorch`` 예제를 사용하는 " +"경우 ``examples/quickstart-pytorch``에 ``Dockerfile.supernode``라는 새 " +"파일을 생성합니다." #: ../../source/how-to-run-flower-using-docker.rst:203 msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." -msgstr "" +msgstr "``Dockerfile.supernode``에는 SuperNode 이미지를 조립하는 지침이 포함되어 " +"있습니다." #: ../../source/how-to-run-flower-using-docker.rst:217 msgid "" @@ -4973,16 +5931,26 @@ msgid "" "``client:app``. The argument is the object reference of the ClientApp " "(``:``) that will be run inside the ClientApp." msgstr "" +"처음 두 줄에서는 ``nightly`` 태그가 붙은 SuperNode 이미지를 기본 이미지로 " +"사용하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 " +"``/app`` 디렉토리에서 다음 명령이 실행됩니다. 다음으로, ``requirements.txt`` " +"파일을 이미지에 복사하여 ClientApp dependencies 요소를 설치하고 ``pip " +"install``을 실행합니다. 마지막 두 줄에서 ``client.py`` 모듈을 이미지에 " +"복사하고 ``client:app`` 인수를 사용하여 진입점을 ``flower-client-app``로 " +"설정합니다. 인수는 클라이언트앱 내부에서 실행될 클라이언트앱의 객체 참조 " +"(``:``) 입니다." #: ../../source/how-to-run-flower-using-docker.rst:226 msgid "Building the SuperNode Docker image" -msgstr "" +msgstr "SuperNode Docker 이미지 빌드" #: ../../source/how-to-run-flower-using-docker.rst:228 msgid "" "Next, we build the SuperNode Docker image by running the following " "command in the directory where Dockerfile and ClientApp code are located." msgstr "" +"다음으로, Dockerfile 및 ClientApp 코드가 있는 디렉터리에서 다음 명령을 " +"실행하여 SuperNode Docker 이미지를 빌드합니다." #: ../../source/how-to-run-flower-using-docker.rst:235 msgid "" @@ -4990,50 +5958,54 @@ msgid "" "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" +"이미지에 ``flwr_supernode``라는 이름을 붙이고 ``0.0.1`` 태그를 붙였습니다. " +"여기서 선택한 값은 예시일 뿐이라는 점을 기억하세요. 필요에 따라 변경할 수 " +"있습니다." #: ../../source/how-to-run-flower-using-docker.rst:240 msgid "Running the SuperNode Docker image" -msgstr "" +msgstr "SuperNode Docker 이미지 실행" #: ../../source/how-to-run-flower-using-docker.rst:242 msgid "Now that we have built the SuperNode image, we can finally run it." -msgstr "" +msgstr "이제 SuperNode 이미지를 빌드했으니 이제 실행할 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:250 #: ../../source/how-to-run-flower-using-docker.rst:367 msgid "Let's break down each part of this command:" -msgstr "" +msgstr "이 명령의 각 부분을 자세히 살펴보겠습니다:" #: ../../source/how-to-run-flower-using-docker.rst:252 #: ../../source/how-to-run-flower-using-docker.rst:369 msgid "``docker run``: This is the command to run a new Docker container." -msgstr "" +msgstr "``docker run``: 새 Docker 컨테이너를 실행하는 명령입니다." #: ../../source/how-to-run-flower-using-docker.rst:253 #: ../../source/how-to-run-flower-using-docker.rst:370 msgid "" "``--rm``: This option specifies that the container should be " "automatically removed when it stops." -msgstr "" +msgstr "``--rm``: 이 옵션은 컨테이너가 중지될 때 자동으로 제거되도록 지정합니다." #: ../../source/how-to-run-flower-using-docker.rst:254 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." -msgstr "" +msgstr "``flwr_supernode:0.0.1``: 사용할 Docker 이미지의 태그 이름입니다." #: ../../source/how-to-run-flower-using-docker.rst:255 #: ../../source/how-to-run-flower-using-docker.rst:372 msgid "``--insecure``: This option enables insecure communication." -msgstr "" +msgstr "``--insecure``: 이 옵션은 보안되지 않은 통신을 활성화합니다." #: ../../source/how-to-run-flower-using-docker.rst msgid "" "``--superlink 192.168.1.100:9092``: This option specifies the address of " "the SuperLinks Fleet" -msgstr "" +msgstr "``--superlink 192.168.1.100:9092``: 이 옵션은 SuperLinks Fleet의 주소를 " +"지정합니다" #: ../../source/how-to-run-flower-using-docker.rst msgid "API to connect to. Remember to update it with your SuperLink IP." -msgstr "" +msgstr "API에 연결할 수 있습니다. SuperLink IP로 업데이트하는 것을 잊지 마세요." #: ../../source/how-to-run-flower-using-docker.rst:269 msgid "" @@ -5042,18 +6014,25 @@ msgid "" "defined-bridge-networks>`__, use the ``--network`` argument and pass the " "name of the Docker network to run your SuperNodes." msgstr "" +"로컬에서 Flower를 실행하는 것을 테스트하려면 `bridge network `__를 생성하고 ``--network`` argument를 사용하고 SuperNodes를 " +"실행할 Docker 네트워크의 이름을 전달하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:273 msgid "" "Any argument that comes after the tag is passed to the Flower SuperNode " "binary. To see all available flags that the SuperNode supports, run:" msgstr "" +"태그 뒤에 오는 모든 argument는 Flower SuperNode 바이너리에 전달됩니다. " +"SuperNode가 지원하는 사용 가능한 모든 플래그를 보려면 실행하세요:" #: ../../source/how-to-run-flower-using-docker.rst:283 msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your SuperNode container." -msgstr "" +msgstr "SSL을 사용하려면 PEM 인코딩된 루트 인증서를 SuperNode 컨테이너에 마운트해야 " +"합니다." #: ../../source/how-to-run-flower-using-docker.rst:285 msgid "" @@ -5063,16 +6042,21 @@ msgid "" "within the container. Use the ``--root-certificates`` flag when starting " "the container." msgstr "" +"인증서가 이미 로컬에 존재한다고 가정하면, ``--volume`` 플래그를 사용하여 " +"로컬 인증서를 컨테이너의 ``/app/`` 디렉터리에 마운트할 수 있습니다. 이렇게 " +"하면 SuperNode가 컨테이너 내의 인증서에 액세스할 수 있습니다. 컨테이너를 " +"시작할 때 ``--root-certificates`` 플래그를 사용하세요." #: ../../source/how-to-run-flower-using-docker.rst:297 msgid "Flower ServerApp" -msgstr "" +msgstr "Flower 서버앱" #: ../../source/how-to-run-flower-using-docker.rst:299 msgid "" "The procedure for building and running a ServerApp image is almost " "identical to the SuperNode image." -msgstr "" +msgstr "ServerApp 이미지를 빌드하고 실행하는 절차는 SuperNode 이미지와 거의 " +"동일합니다." #: ../../source/how-to-run-flower-using-docker.rst:301 msgid "" @@ -5080,6 +6064,9 @@ msgid "" "pre-installed version of Flower and serves as a base for building your " "own ServerApp image." msgstr "" +"SuperNode 이미지와 마찬가지로 ServerApp Docker 이미지는 Flower의 사전 설치된 " +"버전과 함께 제공되며, 자체 ServerApp 이미지를 구축하기 위한 기본 역할을 " +"합니다." #: ../../source/how-to-run-flower-using-docker.rst:304 msgid "" @@ -5087,10 +6074,13 @@ msgid "" "Flower SuperNode section. If you have not already done so, please follow " "the `SuperNode Prerequisites`_ before proceeding." msgstr "" +"여기서는 Flower SuperNode 섹션에서와 동일한`quickstart-pytorch`` 예제를 " +"사용하겠습니다. 아직 수행하지 않았다면 계속 진행하기 전에 `SuperNode " +"Prerequisites`_ 을 따르세요." #: ../../source/how-to-run-flower-using-docker.rst:309 msgid "Creating a ServerApp Dockerfile" -msgstr "" +msgstr "ServerApp Dockerfile 만들기" #: ../../source/how-to-run-flower-using-docker.rst:320 msgid "" @@ -5099,12 +6089,16 @@ msgid "" "example, create a new file called ``Dockerfile.serverapp`` in ``examples" "/quickstart-pytorch``." msgstr "" +"먼저, ``ServerApp`` 코드가 있는 디렉토리에 Docker파일을 생성해야 합니다. " +"``quickstart-pytorch`` 예제를 사용하는 경우 ``examples/quickstart-pytorch``" +"에 ``Dockerfile.serverapp``이라는 새 파일을 생성합니다." #: ../../source/how-to-run-flower-using-docker.rst:324 msgid "" "The ``Dockerfile.serverapp`` contains the instructions that assemble the " "ServerApp image." -msgstr "" +msgstr "``Dockerfile.serverapp``에는 ServerApp 이미지를 합치는 지침이 포함되어 " +"있습니다." #: ../../source/how-to-run-flower-using-docker.rst:335 msgid "" @@ -5117,16 +6111,24 @@ msgid "" "ServerApp (``:``) that will be run inside the " "ServerApp container." msgstr "" +"처음 두 줄에서는 ``1.8.0`` 태그가 붙은 ServerApp 이미지를 기본 이미지로 " +"사용하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 " +"``/app`` 디렉토리에서 다음 명령이 실행됩니다. 마지막 두 줄에서는 ``server." +"py`` 모듈을 이미지에 복사하고 ``server:app`` argument를 사용하여 진입점을 " +"``flower-server-app``로 설정합니다. 인수는 ServerApp 컨테이너 내에서 실행될 " +"ServerApp의 객체 참조(``:``)입니다." #: ../../source/how-to-run-flower-using-docker.rst:343 msgid "Building the ServerApp Docker image" -msgstr "" +msgstr "ServerApp Docker 이미지 빌드" #: ../../source/how-to-run-flower-using-docker.rst:345 msgid "" "Next, we build the ServerApp Docker image by running the following " "command in the directory where Dockerfile and ServerApp code are located." msgstr "" +"다음으로, Docker파일과 ServerApp 코드가 있는 디렉터리에서 다음 명령을 " +"실행하여 ServerApp Docker 이미지를 빌드합니다." #: ../../source/how-to-run-flower-using-docker.rst:352 msgid "" @@ -21815,4 +22817,3 @@ msgstr "" #~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" #~ msgstr "" - From 87e247991e00539187c8b86348d26592a1e5397a Mon Sep 17 00:00:00 2001 From: "Weblate (bot)" Date: Sun, 23 Jun 2024 17:30:03 +0200 Subject: [PATCH 119/124] docs(framework) Add latest Hosted Weblate translation updates (#3674) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 박태현 Co-authored-by: Sijiaomg Ohoh --- doc/locales/ko/LC_MESSAGES/framework-docs.po | 15259 +++++++++-------- 1 file changed, 7661 insertions(+), 7598 deletions(-) diff --git a/doc/locales/ko/LC_MESSAGES/framework-docs.po b/doc/locales/ko/LC_MESSAGES/framework-docs.po index 74cb5f00589f..3c41a8647c35 100644 --- a/doc/locales/ko/LC_MESSAGES/framework-docs.po +++ b/doc/locales/ko/LC_MESSAGES/framework-docs.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Flower main\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2024-06-17 16:09+0200\n" -"PO-Revision-Date: 2024-06-22 10:52+0000\n" +"PO-Revision-Date: 2024-06-23 14:41+0000\n" "Last-Translator: 박태현 \n" "Language-Team: Korean \n" @@ -30,9 +30,11 @@ msgstr "엣지 클라이언트 엔진" #: ../../source/contributor-explanation-architecture.rst:7 msgid "" -"`Flower `_ core framework architecture with Edge " -"Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔진" +"`Flower `_ core framework architecture with Edge Client " +"Engine" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 엣지 클라이언트 엔" +"진" #: ../../source/contributor-explanation-architecture.rst:13 msgid "Virtual Client Engine" @@ -42,7 +44,9 @@ msgstr "가상 클라이언트 엔진" msgid "" "`Flower `_ core framework architecture with Virtual " "Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔진" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 가상 클라이언트 엔" +"진" #: ../../source/contributor-explanation-architecture.rst:21 msgid "Virtual Client Engine and Edge Client Engine in the same workload" @@ -50,9 +54,11 @@ msgstr "동일 작업에서 가상 클라이언트 엔진과 엣지 클라이언 #: ../../source/contributor-explanation-architecture.rst:23 msgid "" -"`Flower `_ core framework architecture with both " -"Virtual Client Engine and Edge Client Engine" -msgstr "`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라이언트 엔진" +"`Flower `_ core framework architecture with both Virtual " +"Client Engine and Edge Client Engine" +msgstr "" +"`Flower `_의 핵심 프레임워크 아키텍처와 가상 및 엣지 클라" +"이언트 엔진" #: ../../source/contributor-how-to-build-docker-images.rst:2 msgid "How to build Docker Flower images locally" @@ -60,20 +66,19 @@ msgstr "Docker Flower 이미지를 Locally 구축하는 방법" #: ../../source/contributor-how-to-build-docker-images.rst:4 msgid "" -"Flower provides pre-made docker images on `Docker Hub " -"`_ that include all necessary dependencies" -" for running the SuperLink, SuperNode or ServerApp. You can also build " -"your own custom docker images from scratch with a different version of " -"Python or Linux distribution (Ubuntu/Alpine) if that is what you need. In" -" this guide, we will explain what images exist and how to build them " -"locally." +"Flower provides pre-made docker images on `Docker Hub `_ that include all necessary dependencies for running the " +"SuperLink, SuperNode or ServerApp. You can also build your own custom docker " +"images from scratch with a different version of Python or Linux distribution " +"(Ubuntu/Alpine) if that is what you need. In this guide, we will explain " +"what images exist and how to build them locally." msgstr "" "Flower는 'Docker Hub '_에서 미리 만들어진 " "Docker 이미지들을 제공합니다. 해당 이미지들은 SuperLink, ServerNode 또는 " -"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 " -"다른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 " -"정의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 " -"이미지들과 이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." +"ServerApp을 실행하는 데 필요한 모든 dependencies를 포함합니다. 필요한 경우 다" +"른 버전의 Python이나 Linux 배포판(Ubuntu/Alpine)을 사용해 처음부터 사용자 정" +"의 Docker 이미지를 빌드할 수도 있습니다. 이 가이드에서는 존재하는 이미지들과 " +"이들을 로컬에서 빌드하는 방법에 대해 설명하겠습니다." #: ../../source/contributor-how-to-build-docker-images.rst:10 msgid "" @@ -83,7 +88,7 @@ msgstr "시작하기 전에, 로컬 개발 환경에서 몇 가지 전제 조건 #: ../../source/contributor-how-to-build-docker-images.rst:12 msgid "Clone the flower repository." -msgstr "Flower 리포지토리를 복제합니다." +msgstr "Flower 레포지토리를 복제합니다." #: ../../source/contributor-how-to-build-docker-images.rst:18 #: ../../source/how-to-run-flower-using-docker.rst:165 @@ -93,46 +98,45 @@ msgstr "Docker 데몬이 실행 중인지 확인하십시오." #: ../../source/contributor-how-to-build-docker-images.rst:20 #: ../../source/how-to-run-flower-using-docker.rst:167 msgid "" -"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." +"Please follow the first section on :doc:`Run Flower using Docker ` which covers this step in more detail." msgstr "" -":doc:Run Flower using Docker 의 첫 번째 섹션을 " -"따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." +":doc:Run Flower using Docker 의 첫 번째 섹션" +"을 따라 주십시오. 해당 부분을 더 자세히 설명해 줍니다." #: ../../source/contributor-how-to-build-docker-images.rst:25 msgid "" "The build instructions that assemble the images are located in the " -"respective Dockerfiles. You can find them in the subdirectories of " -"``src/docker``." +"respective Dockerfiles. You can find them in the subdirectories of ``src/" +"docker``." msgstr "" -"이미지들을 조합하는 빌드 instruction들은 해당 Dockerfile에 있습니다. \"src/docker\" 의 하위 " -"디렉토리에서 찾을 수 있습니다." +"이미지들을 조합하는 빌드 명령어들은 해당 Dockerfile에 있습니다. \"src/" +"docker\" 의 하위 디렉토리에서 찾을 수 있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:28 msgid "" "Flower Docker images are configured via build arguments. Through build " -"arguments, we can make the creation of images more flexible. For example," -" in the base image, we can specify the version of Python to install using" -" the ``PYTHON_VERSION`` build argument. Some of the build arguments have " -"default values, others must be specified when building the image. All " -"available build arguments for each image are listed in one of the tables " -"below." +"arguments, we can make the creation of images more flexible. For example, in " +"the base image, we can specify the version of Python to install using the " +"``PYTHON_VERSION`` build argument. Some of the build arguments have default " +"values, others must be specified when building the image. All available " +"build arguments for each image are listed in one of the tables below." msgstr "" -"Flower Docker는 빌드 argument를 통해 구성됩니다. 빌드 argument들을 통해, " +"Flower Docker는 빌드 전달인자를 통해 구성됩니다. 빌드 argument들을 통해, " "이미지를 보다 유연하게 생성할 수 있습니다. 예를 들어, base 이미지에서 " -"\"PYTHON_VERSION\" 빌드 argument를 사용하여 Python 버전을 지정할 수 " -"있습니다. 일부 빌드 argument들은 기본값이며, 이미지를 빌드할 때 지정해야 " -"합니다. 각 이미지에 사용할 수 있는 모든 빌드 argument는 아래 표 중에 " +"\"PYTHON_VERSION\" 빌드 전달인자를 사용하여 Python 버전을 지정할 수 " +"있습니다. 일부 빌드 전달인자들은 기본값이며, 이미지를 빌드할 때 지정해야 " +"합니다. 각 이미지에 사용할 수 있는 모든 빌드 전달인자는 아래 표 중에 " "있습니다." #: ../../source/contributor-how-to-build-docker-images.rst:35 msgid "Building the base image" -msgstr "base 이미지 빌드" +msgstr "기본 이미지 빌드" #: ../../source/contributor-how-to-build-docker-images.rst:41 #: ../../source/contributor-how-to-build-docker-images.rst:98 msgid "Build argument" -msgstr "빌드 argument" +msgstr "빌드 전달인자" #: ../../source/contributor-how-to-build-docker-images.rst:42 #: ../../source/contributor-how-to-build-docker-images.rst:99 @@ -155,7 +159,7 @@ msgstr "``DISTRO``" #: ../../source/contributor-how-to-build-docker-images.rst:46 msgid "The Linux distribution to use as the base image." -msgstr "base 이미지 사용을 위한 Linux 배포판." +msgstr "기본 이미지 사용을 위한 Linux 배포판." #: ../../source/contributor-how-to-build-docker-images.rst:47 #: ../../source/contributor-how-to-build-docker-images.rst:51 @@ -250,20 +254,21 @@ msgstr "``flwr`` 또는 ``flwr-nightly``" #: ../../source/contributor-how-to-build-docker-images.rst:75 msgid "" -"The following example creates a base Ubuntu/Alpine image with Python " -"3.11.0, pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" +"The following example creates a base Ubuntu/Alpine image with Python 3.11.0, " +"pip 23.0.1, setuptools 69.0.2 and Flower 1.8.0:" msgstr "" -"다음 예시에서는 Python 3.11.0, pip 23.0.1, setuptools 및 Flower 1.8.0으로 " -"기본 Ubuntu/Alpine 이미지를 만듭니다:" +"다음 예시에서는 Python 3.11.0, pip 23.0.1, setuptools 및 Flower 1.8.0으로 기" +"본 Ubuntu/Alpine 이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:88 msgid "" -"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that " -"the build arguments as well as the name and tag can be adapted to your " -"needs. These values serve as examples only." +"The name of image is ``flwr_base`` and the tag ``0.1.0``. Remember that the " +"build arguments as well as the name and tag can be adapted to your needs. " +"These values serve as examples only." msgstr "" -"이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 argument들 뿐만 아니라 이름과" -" 태그도 정할 수 있습니다. 이 값들은 예시일 뿐입니다." +"이미지의 이름은 ``flwr_base``이고 태그는 ``0.1.0``입니다. 필요에 따라 빌드 " +"전달인자들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 예시일 " +"뿐입니다." #: ../../source/contributor-how-to-build-docker-images.rst:92 msgid "Building the SuperLink/SuperNode or ServerApp image" @@ -275,7 +280,7 @@ msgstr "``BASE_REPOSITORY``" #: ../../source/contributor-how-to-build-docker-images.rst:103 msgid "The repository name of the base image." -msgstr "base 이미지의 리포지토리 이름." +msgstr "기본 이미지의 레포지토리 이름." #: ../../source/contributor-how-to-build-docker-images.rst:105 msgid "``flwr/base``" @@ -295,19 +300,19 @@ msgstr "``1.8.0-py3.10-ubuntu22.04``" #: ../../source/contributor-how-to-build-docker-images.rst:111 msgid "" -"The following example creates a SuperLink/SuperNode or ServerApp image " -"with the official Flower base image:" -msgstr "다음 예시에서는 공식 Flower 기본 이미지로 SuperLink/SuperNode 또는 " -"ServerApp이미지를 만듭니다:" +"The following example creates a SuperLink/SuperNode or ServerApp image with " +"the official Flower base image:" +msgstr "" +"다음 예시에서는 공식 Flower 기본 이미지로 SuperLink/SuperNode 또는 ServerApp" +"이미지를 만듭니다:" #: ../../source/contributor-how-to-build-docker-images.rst:122 msgid "" -"If you want to use your own base image instead of the official Flower " -"base image, all you need to do is set the ``BASE_REPOSITORY`` build " -"argument." +"If you want to use your own base image instead of the official Flower base " +"image, all you need to do is set the ``BASE_REPOSITORY`` build argument." msgstr "" "공식 Flower 기본 이미지 대신 자체 기본 이미지를 사용 하길 원한다면, " -"``BASE_REPOSITORY`` 빌드 argument들을 설정해야 합니다." +"``BASE_REPOSITORY`` 빌드 전달인자들을 설정해야 합니다." #: ../../source/contributor-how-to-build-docker-images.rst:133 msgid "After creating the image, we can test whether the image is working:" @@ -319,29 +324,30 @@ msgstr "번역 기여" #: ../../source/contributor-how-to-contribute-translations.rst:4 msgid "" -"Since `Flower 1.5 `_ we have introduced translations to " -"our doc pages, but, as you might have noticed, the translations are often" -" imperfect. If you speak languages other than English, you might be able " -"to help us in our effort to make Federated Learning accessible to as many" -" people as possible by contributing to those translations! This might " -"also be a great opportunity for those wanting to become open source " -"contributors with little prerequisites." -msgstr "" -"`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 번역이 불안전한 " -"경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 사람들이 Federated Learning에 접근할 수 있도록 번역 " -"작업에 기여함으로써 저희의 노력에 도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 기여자가 되고자 하는 사람들에게" -" 좋은 기회가 될 수도 있습니다." +"Since `Flower 1.5 `_ we have introduced translations to our doc pages, " +"but, as you might have noticed, the translations are often imperfect. If you " +"speak languages other than English, you might be able to help us in our " +"effort to make Federated Learning accessible to as many people as possible " +"by contributing to those translations! This might also be a great " +"opportunity for those wanting to become open source contributors with little " +"prerequisites." +msgstr "" +"`Flower 1.5 `_ 부터 문서 페이지에 번역을 도입했지만, 아시다시피 " +"번역이 불안전한 경우가 많습니다. 만일 영어 이외의 언어를 사용한다면, 많은 " +"사람들이 연합 학습에 접근할 수 있도록 번역 작업에 기여함으로써 저희의 노력에 " +"도움을 주실 수 있습니다! 이는 전제 조건이 거의 없는 오픈 소스 기여자가 " +"되고자 하는 사람들에게 좋은 기회가 될 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:13 msgid "" -"Our translation project is publicly available over on `Weblate " -"`_, this " -"where most of the work will happen." +"Our translation project is publicly available over on `Weblate `_, this where most of " +"the work will happen." msgstr "" -"번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." +"번역 프로젝트는 `Weblate `_에서 공개적으로 진행되며, 대부분의 작업이 이곳에서 이루어집니다." #: ../../source/contributor-how-to-contribute-translations.rst:18 msgid "Contribute to existing languages" @@ -349,43 +355,43 @@ msgstr "기존 언어에 기여하기" #: ../../source/contributor-how-to-contribute-translations.rst:23 msgid "" -"The first thing you will need to do in order to contribute is to create a" -" free Weblate account on this `page " -"`_. More information about" -" profile settings can be found `here " +"The first thing you will need to do in order to contribute is to create a " +"free Weblate account on this `page `_. More information about profile settings can be found `here " "`_." msgstr "" -"기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page " -"`_에서 무료 Weblate 계정을 만드는 " -"것입니다. 프로필 설정에 대한 자세한 정보는 `here " -"`_를 참조하세요." +"기여를 하기 위해 가장 먼저 해야 할 일은 해당 `page `_에서 무료 Weblate 계정을 만드는 것입니다. 프로필 설" +"정에 대한 자세한 정보는 `here `_를 참조하세요." #: ../../source/contributor-how-to-contribute-translations.rst:29 msgid "" -"Once you are signed in to Weblate, you can navigate to the `Flower " -"Framework project `_. Here, you should see the different existing languages" -" that can be found on the website." +"Once you are signed in to Weblate, you can navigate to the `Flower Framework " +"project `_. " +"Here, you should see the different existing languages that can be found on " +"the website." msgstr "" -"Weblate에 로그인한 후, `Flower Framework project " -"`_로 이동할 수 " -"있습니다. 여기에서 웹사이트에 있는 다양한 기존 언어들을 확인할 수 있습니다." +"Weblate에 로그인한 후, `Flower Framework project `_로 이동할 수 있습니다. 여기에서 웹사이트에 " +"있는 다양한 기존 언어들을 확인할 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:34 msgid "" -"Once you have selected the language you want to contribute to, you should" -" see a similar interface to this:" +"Once you have selected the language you want to contribute to, you should " +"see a similar interface to this:" msgstr "기여하고자 하는 언어를 선택하면, 다음과 같은 인터페이스가 나타납니다:" #: ../../source/contributor-how-to-contribute-translations.rst:39 msgid "" "The most straight forward option here is to click on the ``Translate`` " -"button on the top right (in the ``Translation status`` section). This " -"will automatically bring you to the translation interface for " -"untranslated strings." +"button on the top right (in the ``Translation status`` section). This will " +"automatically bring you to the translation interface for untranslated " +"strings." msgstr "" -"여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 ``Translate`` 버튼을 " -"클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 인터페이스로 자동으로 이동합니다." +"여기서 가장 간단한 옵션은 오른쪽 상단(``Translation status`` 부분)에 있는 " +"``Translate`` 버튼을 클릭하는 것 입니다. 번역되지 않은 문장에 대한 번역 인터" +"페이스로 자동으로 이동합니다." #: ../../source/contributor-how-to-contribute-translations.rst:43 msgid "This is what the interface looks like:" @@ -393,44 +399,47 @@ msgstr "인터페이스는 다음과 같습니다:" #: ../../source/contributor-how-to-contribute-translations.rst:47 msgid "" -"You input your translation in the text box at the top and then, once you " -"are happy with it, you either press ``Save and continue`` (to save the " -"translation and go to the next untranslated string), ``Save and stay`` " -"(to save the translation and stay on the same page), ``Suggest`` (to add " -"your translation to suggestions for other users to view), or ``Skip`` (to" -" go to the next untranslated string without saving anything)." +"You input your translation in the text box at the top and then, once you are " +"happy with it, you either press ``Save and continue`` (to save the " +"translation and go to the next untranslated string), ``Save and stay`` (to " +"save the translation and stay on the same page), ``Suggest`` (to add your " +"translation to suggestions for other users to view), or ``Skip`` (to go to " +"the next untranslated string without saving anything)." msgstr "" -"번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and continue``(번역을 저장하고 다음 미번역 " -"문장으로 이동), ``Save and stay``(번역을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 " -"볼 수 있도록 번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 문장으로 이동) 중 하나를 선택하면 " -"됩니다." +"번역문을 상단의 텍스트 상자에 입력한 후, 번역이 만족스러우면 ``Save and " +"continue``(번역을 저장하고 다음 미번역 문장으로 이동), ``Save and stay``(번역" +"을 저장하고 해당 페이지에 머무르기), ``Suggest`` (다른 사용자가 볼 수 있도록 " +"번역을 제안 항목에 추가), ``Skip``(아무것도 저장하지 않고 다음 미번역 문장으" +"로 이동) 중 하나를 선택하면 됩니다." #: ../../source/contributor-how-to-contribute-translations.rst:54 msgid "" "In order to help with the translations, you can see on the bottom the " "``Nearby strings``, the ``Comments`` (from other contributors), the " "``Automatic suggestions`` (from machine translation engines), the " -"translations in ``Other languages``, and the ``History`` of translations " -"for this string." +"translations in ``Other languages``, and the ``History`` of translations for " +"this string." msgstr "" -"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``자동 제안``(기계 번역의), ``다른 " -"언어``의 번역 및 해당 문장의 번역``히스토리``를 볼 수 있습니다." +"번역에 도움을 주기위해 하단에서 `주변 문자열``, ``의견``(다른 기여자의), ``자" +"동 제안``(기계 번역의), ``다른 언어``의 번역 및 해당 문장의 번역``히스토리``" +"를 볼 수 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:59 msgid "" -"On the right, under the ``String information`` section, you can also " -"click the link under ``Source string location`` in order to view the " -"source of the doc file containing the string." -msgstr "오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 포함된 문서의 파일 소스를 볼 수도 있습니다." +"On the right, under the ``String information`` section, you can also click " +"the link under ``Source string location`` in order to view the source of the " +"doc file containing the string." +msgstr "" +"오른쪽의 ``문자열 정보``에서 ``원본 문자열 위치``를 클릭하여 해당 문장이 포함" +"된 문서의 파일 소스를 볼 수도 있습니다." #: ../../source/contributor-how-to-contribute-translations.rst:63 msgid "" -"For more information about translating using Weblate, you can check out " -"this `in-depth guide " -"`_." +"For more information about translating using Weblate, you can check out this " +"`in-depth guide `_." msgstr "" -"Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide " -"`_를 확인하세요." +"Weblate를 통한 번역에 대한 자세한 정보는 `in-depth guide `_를 확인하세요." #: ../../source/contributor-how-to-contribute-translations.rst:67 msgid "Add new languages" @@ -438,12 +447,13 @@ msgstr "새 언어 추가" #: ../../source/contributor-how-to-contribute-translations.rst:69 msgid "" -"If you want to add a new language, you will first have to contact us, " -"either on `Slack `_, or by opening an issue" -" on our `GitHub repo `_." +"If you want to add a new language, you will first have to contact us, either " +"on `Slack `_, or by opening an issue on our " +"`GitHub repo `_." msgstr "" -"새 언어를 추가하려면, `Slack `에 문의하거나 `GitHub repo " -"`_에서 issue에 들어가 문의 해야 합니다." +"새 언어를 추가하려면, `Slack `에 문의하거나 " +"`GitHub repo `_에서 issue에 들어가 문의 해야 " +"합니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:2 msgid "Develop in VSCode Dev Containers" @@ -451,49 +461,52 @@ msgstr "VSCode Dev Container에서 개발" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:4 msgid "" -"When working on the Flower framework we want to ensure that all " -"contributors use the same developer environment to format code or run " -"tests. For this purpose we are using the VSCode Remote Containers " -"extension. What is it? Read the following quote:" +"When working on the Flower framework we want to ensure that all contributors " +"use the same developer environment to format code or run tests. For this " +"purpose we are using the VSCode Remote Containers extension. What is it? " +"Read the following quote:" msgstr "" -"Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 동일한 개발 환경을 사용하길 원합니다. 이를 " -"위해 VSCode Remote Containers 확장을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 " -"읽어보세요:" +"Flower 프레임워크 작업시, 모든 기여자들이 코드 포맷팅이나 테스트 실행을 위해 " +"동일한 개발 환경을 사용하길 원합니다. 이를 위해 VSCode Remote Containers 확장" +"을 사용하고 있습니다. 그것이 무엇인지 알아보기 위해 다음 인용문을 읽어보세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:7 msgid "" -"The Visual Studio Code Remote - Containers extension lets you use a " -"Docker container as a fully-featured development environment. It allows " -"you to open any folder inside (or mounted into) a container and take " -"advantage of Visual Studio Code's full feature set. A " -":code:`devcontainer.json` file in your project tells VS Code how to " -"access (or create) a development container with a well-defined tool and " -"runtime stack. This container can be used to run an application or to " -"separate tools, libraries, or runtimes needed for working with a " -"codebase." -msgstr "" -"Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 기능을 갖춘 개발 환경으로 " -"사용할 수 있습니다. 이 확장 기능을 사용하면 컨테이너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio" -" Code의 모든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer.json` 파일은 잘 정의된 " -"도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(또는 생성)하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 " -"애플리케이션을 실행하거나 코드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 데 사용할 수 있습니다." +"The Visual Studio Code Remote - Containers extension lets you use a Docker " +"container as a fully-featured development environment. It allows you to open " +"any folder inside (or mounted into) a container and take advantage of Visual " +"Studio Code's full feature set. A :code:`devcontainer.json` file in your " +"project tells VS Code how to access (or create) a development container with " +"a well-defined tool and runtime stack. This container can be used to run an " +"application or to separate tools, libraries, or runtimes needed for working " +"with a codebase." +msgstr "" +"Visual Studio Code Remote - 컨테이너 확장을 사용하면 Docker 컨테이너를 모든 " +"기능을 갖춘 개발 환경으로 사용할 수 있습니다. 이 확장 기능을 사용하면 컨테이" +"너 내부(또는 컨테이너에 마운트된)의 모든 폴더를 열고 Visual Studio Code의 모" +"든 기능을 활용할 수 있습니다. 프로젝트에 있는 :code:`devcontainer.json` 파일" +"은 잘 정의된 도구와 런타임 스택을 사용하여 개발 컨테이너에 액세스(또는 생성)" +"하는 방법을 VS Code에 알려줍니다. 이 컨테이너는 애플리케이션을 실행하거나 코" +"드베이스 작업에 필요한 도구, 라이브러리 또는 런타임을 분리하는 데 사용할 수 " +"있습니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:9 msgid "" -"Workspace files are mounted from the local file system or copied or " -"cloned into the container. Extensions are installed and run inside the " -"container, where they have full access to the tools, platform, and file " -"system. This means that you can seamlessly switch your entire development" -" environment just by connecting to a different container." +"Workspace files are mounted from the local file system or copied or cloned " +"into the container. Extensions are installed and run inside the container, " +"where they have full access to the tools, platform, and file system. This " +"means that you can seamlessly switch your entire development environment " +"just by connecting to a different container." msgstr "" -"작업 공간 파일은 로컬 파일 시스템에서 마운트되거나 컨테이너에 복사 또는 클론됩니다. 확장 프로그램은 컨테이너 내부에 설치되고 " -"실행되며, 도구, 플랫폼 및 파일 시스템에 완전한 접근 권한을 갖습니다. 이는 다른 컨테이너에 연결하는 것만으로 전체 개발 환경을 " -"원활하게 전환할 수 있음을 의미합니다." +"작업 공간 파일은 로컬 파일 시스템에서 마운트되거나 컨테이너에 복사 또는 클론" +"됩니다. 확장 프로그램은 컨테이너 내부에 설치되고 실행되며, 도구, 플랫폼 및 파" +"일 시스템에 완전한 접근 권한을 갖습니다. 이는 다른 컨테이너에 연결하는 것만으" +"로 전체 개발 환경을 원활하게 전환할 수 있음을 의미합니다." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:11 msgid "" -"Source: `Official VSCode documentation " -"`_" +"Source: `Official VSCode documentation `_" msgstr "출처 : 공식 VSCode 문서" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:15 @@ -502,52 +515,57 @@ msgstr "시작하기" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:17 msgid "" -"Configuring and setting up the :code:`Dockerfile` as well the " -"configuration for the devcontainer can be a bit more involved. The good " -"thing is you don't have to do it. Usually it should be enough to install " -"`Docker `_ on your system and " -"ensure its available on your command line. Additionally, install the " -"`VSCode Containers Extension `_." -msgstr "" -"`Dockerfile`을 설정하고 구성하는 것과 개발 컨테이너 구성은 약간 복잡할 수 있습니다. 다행히도, 이를 직접 할 필요는 " -"없습니다. 일반적으로 시스템에 `Docker `_를 " -"설치하고 커맨드 라인에서 사용할 수 있는지 확인하는 것으로 충분합니다. 추가로 `VSCode Containers Extension " +"Configuring and setting up the :code:`Dockerfile` as well the configuration " +"for the devcontainer can be a bit more involved. The good thing is you don't " +"have to do it. Usually it should be enough to install `Docker `_ on your system and ensure its available on " +"your command line. Additionally, install the `VSCode Containers Extension " +"`_." +msgstr "" +"`Dockerfile`을 설정하고 구성하는 것과 개발 컨테이너 구성은 약간 복잡할 수 있" +"습니다. 다행히도, 이를 직접 할 필요는 없습니다. 일반적으로 시스템에 `Docker " +"`_를 설치하고 커맨드 라인에서 사용" +"할 수 있는지 확인하는 것으로 충분합니다. 추가로 `VSCode Containers Extension " "`_을 설치하세요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:19 msgid "" -"Now you should be good to go. When starting VSCode, it will ask you to " -"run in the container environment and - if you confirm - automatically " -"build the container and use it. To manually instruct VSCode to use the " -"devcontainer, you can, after installing the extension, click the green " -"area in the bottom left corner of your VSCode window and select the " -"option *(Re)Open Folder in Container*." +"Now you should be good to go. When starting VSCode, it will ask you to run " +"in the container environment and - if you confirm - automatically build the " +"container and use it. To manually instruct VSCode to use the devcontainer, " +"you can, after installing the extension, click the green area in the bottom " +"left corner of your VSCode window and select the option *(Re)Open Folder in " +"Container*." msgstr "" -"이제 준비가 완료되었습니다. VSCode를 시작하면 컨테이너 환경에서 실행할지를 묻고, 확인하면 자동으로 컨테이너를 빌드하고 사용할" -" 것입니다. VSCode에 수동으로 개발 컨테이너를 사용하도록 지시하려면, 확장을 설치한 후, VSCode 창의 왼쪽 하단에 있는 " -"초록색 부을 클릭하고 *(Re)Open Folder in Container* 옵션을 선택하세요." +"이제 준비가 완료되었습니다. VSCode를 시작하면 컨테이너 환경에서 실행할지를 묻" +"고, 확인하면 자동으로 컨테이너를 빌드하고 사용할 것입니다. VSCode에 수동으로 " +"개발 컨테이너를 사용하도록 지시하려면, 확장을 설치한 후, VSCode 창의 왼쪽 하" +"단에 있는 초록색 부을 클릭하고 *(Re)Open Folder in Container* 옵션을 선택하세" +"요." #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:21 msgid "" -"In some cases your setup might be more involved. For those cases consult " -"the following sources:" -msgstr "경우에 따라 설정이 더 복잡할 수도 있습니다. 이러한 경우에는 다음 소스를 참조하세요:" +"In some cases your setup might be more involved. For those cases consult the " +"following sources:" +msgstr "" +"경우에 따라 설정이 더 복잡할 수도 있습니다. 이러한 경우에는 다음 소스를 참조" +"하세요:" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:23 msgid "" -"`Developing inside a Container " -"`_" +"`Developing inside a Container `_" msgstr "" -"`컨테이너 내부 개발`_" +"`컨테이너 내부 개발`_" #: ../../source/contributor-how-to-develop-in-vscode-dev-containers.rst:24 msgid "" -"`Remote development in Containers " -"`_" -msgstr "`컨테이너 원격 개발`_" +"`Remote development in Containers `_" +msgstr "" +"`컨테이너 원격 개발`_" #: ../../source/contributor-how-to-install-development-versions.rst:2 msgid "Install development versions" @@ -563,19 +581,20 @@ msgstr "Poetry 사용하기(권장)" #: ../../source/contributor-how-to-install-development-versions.rst:10 msgid "" -"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency " -"in ``pyproject.toml`` and then reinstall (don't forget to delete " -"``poetry.lock`` (``rm poetry.lock``) before running ``poetry install``)." +"Install a ``flwr`` pre-release from PyPI: update the ``flwr`` dependency in " +"``pyproject.toml`` and then reinstall (don't forget to delete ``poetry." +"lock`` (``rm poetry.lock``) before running ``poetry install``)." msgstr "" -"PyPI에서 ``flwr`` 사전 릴리스 설치하기: ``pyproject.toml``에서 ``flwr``의 dependency를 " -"업데이트한 다음, 재설치하세요(``poetry 설치``이전에 ``poetry.lock`` (``rm poetry.lock``)를 " -"제거하는 것을 잊지 마세요)." +"PyPI에서 ``flwr`` 사전 릴리스 설치하기: ``pyproject.toml``에서 ``flwr``의 " +"의존성을 업데이트한 다음, 재설치하세요(``poetry 설치``이전에 ``poetry.lock`` " +"(``rm poetry.lock``)를 제거하는 것을 잊지 마세요)." #: ../../source/contributor-how-to-install-development-versions.rst:12 msgid "" "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (without " "extras)" -msgstr "``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (extras 제외)" +msgstr "" +"``flwr = { version = \"1.0.0a0\", allow-prereleases = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:13 msgid "" @@ -587,9 +606,11 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:15 msgid "" -"Install ``flwr`` from a local copy of the Flower source code via " -"``pyproject.toml``:" -msgstr "``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 설치하세요:" +"Install ``flwr`` from a local copy of the Flower source code via ``pyproject." +"toml``:" +msgstr "" +"``pyproject.toml``을 통해 Flower 소스 코드의 로컬 복사본에서 ``flwr``을 설치" +"하세요:" #: ../../source/contributor-how-to-install-development-versions.rst:17 msgid "``flwr = { path = \"../../\", develop = true }`` (without extras)" @@ -597,11 +618,11 @@ msgstr "``flwr = { path = \"../../\", develop = true }`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:18 msgid "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " -"}`` (with extras)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " +"(with extras)" msgstr "" -"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] " -"}`` (extras 포함)" +"``flwr = { path = \"../../\", develop = true, extras = [\"simulation\"] }`` " +"(extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:20 msgid "Install ``flwr`` from a local wheel file via ``pyproject.toml``:" @@ -609,11 +630,11 @@ msgstr "``pyproject.toml``을 통해 로컬 wheel file에서 ``flwr``을 설치 #: ../../source/contributor-how-to-install-development-versions.rst:22 msgid "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without" -" extras)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (without " +"extras)" msgstr "" -"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (extras " -"제외)" +"``flwr = { path = \"../../dist/flwr-1.8.0-py3-none-any.whl\" }`` (extras 제" +"외)" #: ../../source/contributor-how-to-install-development-versions.rst:23 msgid "" @@ -629,8 +650,8 @@ msgid "" "Dependency Specification `_" msgstr "" -"자세한 내용은 Poetry 문서를 참고하세요: `Poetry Dependency Specification `_" +"자세한 내용은 Poetry 문서를 참고하세요: `Poetry Dependency Specification " +"`_" #: ../../source/contributor-how-to-install-development-versions.rst:28 msgid "Using pip (recommended on Colab)" @@ -638,7 +659,7 @@ msgstr "pip 사용하기(Colab에서 권장)" #: ../../source/contributor-how-to-install-development-versions.rst:30 msgid "Install a ``flwr`` pre-release from PyPI:" -msgstr "PyPI에서 ``flwr`` 사전 릴리스를 설치하기:" +msgstr "PyPI에서 ``flwr`` 사전 릴리즈를 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:32 msgid "``pip install -U --pre flwr`` (without extras)" @@ -653,8 +674,8 @@ msgid "" "Python packages can be installed from git repositories. Use one of the " "following commands to install the Flower directly from GitHub." msgstr "" -"Python 패키지는 git 저장소에서 설치할 수 있습니다. 다음 명령어 중 하나를 사용하여 GitHub에서 직접 Flower를 " -"설치하세요." +"Python 패키지는 git 저장소에서 설치할 수 있습니다. 다음 명령어 중 하나를 사용" +"하여 GitHub에서 직접 Flower를 설치하세요." #: ../../source/contributor-how-to-install-development-versions.rst:37 msgid "Install ``flwr`` from the default GitHub branch (``main``):" @@ -662,9 +683,9 @@ msgstr "기본 GitHub branch (``main``)에서 ``flwr`` 를 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:39 msgid "" -"``pip install flwr@git+https://github.com/adap/flower.git`` (without " -"extras)" -msgstr "``pip install flwr@git+https://github.com/adap/flower.git`` (extras 제외)" +"``pip install flwr@git+https://github.com/adap/flower.git`` (without extras)" +msgstr "" +"``pip install flwr@git+https://github.com/adap/flower.git`` (extras 제외)" #: ../../source/contributor-how-to-install-development-versions.rst:40 msgid "" @@ -688,11 +709,11 @@ msgstr "" #: ../../source/contributor-how-to-install-development-versions.rst:45 msgid "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" -"@branch-name`` (with extras)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" +"name`` (with extras)" msgstr "" -"``pip install flwr[simulation]@git+https://github.com/adap/flower.git" -"@branch-name`` (extras 포함)" +"``pip install flwr[simulation]@git+https://github.com/adap/flower.git@branch-" +"name`` (extras 포함)" #: ../../source/contributor-how-to-install-development-versions.rst:49 msgid "Open Jupyter Notebooks on Google Colab" @@ -703,32 +724,32 @@ msgid "" "Open the notebook ``doc/source/tutorial-series-get-started-with-flower-" "pytorch.ipynb``:" msgstr "" -"``doc/source/tutorial-series-get-started-with-flower-" -"pytorch.ipynb``notebook을 엽니다:" +"``doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb``notebook" +"을 엽니다:" #: ../../source/contributor-how-to-install-development-versions.rst:53 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/main/doc/source/" +"tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:55 msgid "" -"Open a development version of the same notebook from branch `branch-name`" -" by changing ``main`` to ``branch-name`` (right after ``blob``):" +"Open a development version of the same notebook from branch `branch-name` by " +"changing ``main`` to ``branch-name`` (right after ``blob``):" msgstr "" -"``main``을 ``branch-name``(``blob`` 바로 뒤)으로 변경하여 동일한 notebook의 개발 버전을 브랜치 " -"`branch-name`에서 엽니다 :" +"``main``을 ``branch-name``(``blob`` 바로 뒤)으로 변경하여 동일한 notebook의 " +"개발 버전을 브랜치 `branch-name`에서 엽니다 :" #: ../../source/contributor-how-to-install-development-versions.rst:57 msgid "" -"https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-series-get-started-with-flower-pytorch.ipynb" msgstr "" -"https://colab.research.google.com/github/adap/flower/blob/branch-" -"name/doc/source/tutorial-series-get-started-with-flower-pytorch.ipynb" +"https://colab.research.google.com/github/adap/flower/blob/branch-name/doc/" +"source/tutorial-series-get-started-with-flower-pytorch.ipynb" #: ../../source/contributor-how-to-install-development-versions.rst:59 msgid "Install a `whl` on Google Colab:" @@ -736,9 +757,11 @@ msgstr "Google Colab에서 `whl` 설치하기:" #: ../../source/contributor-how-to-install-development-versions.rst:61 msgid "" -"In the vertical icon grid on the left hand side, select ``Files`` > " -"``Upload to session storage``" -msgstr "왼쪽의 수직 아이콘 그리드에서 ``Files`` > ``Upload to session storage``를 선택하세요" +"In the vertical icon grid on the left hand side, select ``Files`` > ``Upload " +"to session storage``" +msgstr "" +"왼쪽의 수직 아이콘 그리드에서 ``Files`` > ``Upload to session storage``를 선" +"택하세요" #: ../../source/contributor-how-to-install-development-versions.rst:62 msgid "Upload the whl (e.g., ``flwr-1.8.0-py3-none-any.whl``)" @@ -746,13 +769,13 @@ msgstr "whl (예:``flwr-1.8.0-py3-none-any.whl``)을 업로드하세요" #: ../../source/contributor-how-to-install-development-versions.rst:63 msgid "" -"Change ``!pip install -q 'flwr[simulation]' torch torchvision " -"matplotlib`` to ``!pip install -q 'flwr-1.8.0-py3-none-" -"any.whl[simulation]' torch torchvision matplotlib``" +"Change ``!pip install -q 'flwr[simulation]' torch torchvision matplotlib`` " +"to ``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " +"torchvision matplotlib``" msgstr "" -"``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``를 " -"``!pip install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch " -"torchvision matplotlib``로 바꾸세요" +"``!pip install -q 'flwr[simulation]' torch torchvision matplotlib``를 ``!pip " +"install -q 'flwr-1.8.0-py3-none-any.whl[simulation]' torch torchvision " +"matplotlib``로 바꾸세요" #: ../../source/contributor-how-to-release-flower.rst:2 msgid "Release Flower" @@ -762,7 +785,8 @@ msgstr "Flower 릴리즈 하기" msgid "" "This document describes the current release process. It may or may not " "change in the future." -msgstr "이 문서는 현재 릴리즈 과정을 설명합니다. 이는 앞으로 변경될 수도 있습니다." +msgstr "" +"이 문서는 현재 릴리즈 과정을 설명합니다. 이는 앞으로 변경될 수도 있습니다." #: ../../source/contributor-how-to-release-flower.rst:7 msgid "During the release" @@ -770,12 +794,11 @@ msgstr "릴리즈 동안에" #: ../../source/contributor-how-to-release-flower.rst:9 msgid "" -"The version number of a release is stated in ``pyproject.toml``. To " -"release a new version of Flower, the following things need to happen (in " -"that order):" +"The version number of a release is stated in ``pyproject.toml``. To release " +"a new version of Flower, the following things need to happen (in that order):" msgstr "" -"릴리즈의 버전 번호는 ``pyproject.toml``에 명시되어 있습니다. Flower의 새 버전을 릴리즈하려면 다음 작업이 " -"순서대로 수행되어야 합니다:" +"릴리즈의 버전 번호는 ``pyproject.toml``에 명시되어 있습니다. Flower의 새 버전" +"을 릴리즈하려면 다음 작업이 순서대로 수행되어야 합니다:" #: ../../source/contributor-how-to-release-flower.rst:11 msgid "" @@ -783,39 +806,42 @@ msgid "" "order to add every new change to the changelog (feel free to make manual " "changes to the changelog afterwards until it looks good)." msgstr "" -"모든 새로운 변경 사항을 변경 로그에 추가하기 위해``python3 " -"src/py/flwr_tool/update_changelog.py ``을 실행합니다 (변경 로그가 " -"만족스러워질 때까지 수동으로 변경해도 됩니다)." +"모든 새로운 변경 사항을 변경 로그에 추가하기 위해``python3 src/py/flwr_tool/" +"update_changelog.py ``을 실행합니다 (변경 로그가 만족스러워질 " +"때까지 수동으로 변경해도 됩니다)." #: ../../source/contributor-how-to-release-flower.rst:12 msgid "" -"Once the changelog has been updated with all the changes, run ``./dev" -"/prepare-release-changelog.sh v``, where ```` " -"is the version stated in ``pyproject.toml`` (notice the ``v`` added " -"before it). This will replace the ``Unreleased`` header of the changelog " -"by the version and current date, and it will add a thanking message for " -"the contributors. Open a pull request with those changes." +"Once the changelog has been updated with all the changes, run ``./dev/" +"prepare-release-changelog.sh v``, where ```` is " +"the version stated in ``pyproject.toml`` (notice the ``v`` added before it). " +"This will replace the ``Unreleased`` header of the changelog by the version " +"and current date, and it will add a thanking message for the contributors. " +"Open a pull request with those changes." msgstr "" -"모든 변경 사항으로 변경 로그가 업데이트되면,``./dev/prepare-release-changelog.sh " -"v``을 실행합니다. 여기서 ````은 ``pyproject.toml``에 명시된 " -"버전 번호입니다 (앞에 ``v``가 추가된 것을 주의하세요). 이 명령어는 변경 로그의 ``Unreleased``헤더를 해당 버전과" -" 현재 날짜로 교체하고, 기여자들에게 감사 메시지가 추가됩니다. 이러한 변경 사항으로 pull request합니다." +"모든 변경 사항으로 변경 로그가 업데이트되면,``./dev/prepare-release-" +"changelog.sh v``을 실행합니다. 여기서 ````은 " +"``pyproject.toml``에 명시된 버전 번호입니다 (앞에 ``v``가 추가된 것을 주의하" +"세요). 이 명령어는 변경 로그의 ``Unreleased``헤더를 해당 버전과 현재 날짜로 " +"교체하고, 기여자들에게 감사 메시지가 추가됩니다. 이러한 변경 사항으로 pull " +"request합니다." #: ../../source/contributor-how-to-release-flower.rst:13 msgid "" "Once the pull request is merged, tag the release commit with the version " -"number as soon as the PR is merged: ``git tag v`` (notice " -"the ``v`` added before the version number), then ``git push --tags``. " -"This will create a draft release on GitHub containing the correct " -"artifacts and the relevant part of the changelog." +"number as soon as the PR is merged: ``git tag v`` (notice the " +"``v`` added before the version number), then ``git push --tags``. This will " +"create a draft release on GitHub containing the correct artifacts and the " +"relevant part of the changelog." msgstr "" "pull request가 병합되면, PR이 병합되는 즉시 버전 번호로 릴리즈 커밋에 태그를 " -"지정합니다:``git tag v`` (버전 번호 앞에 ``v``가 추가된 것을 " -"확인), 그 다음 ``git push --tags``. 이렇게 하면 올바른 아티팩트와 변경 " -"로그의 관련 부분이 포함된 초안 릴리즈가 GitHub에 생성됩니다." +"지정합니다:``git tag v`` (버전 번호 앞에 ``v``가 추가된 것을 확" +"인), 그 다음 ``git push --tags``. 이렇게 하면 올바른 아티팩트와 변경 로그의 " +"관련 부분이 포함된 초안 릴리즈가 GitHub에 생성됩니다." #: ../../source/contributor-how-to-release-flower.rst:14 -msgid "Check the draft release on GitHub, and if everything is good, publish it." +msgid "" +"Check the draft release on GitHub, and if everything is good, publish it." msgstr "GitHub에서 릴리즈 초안을 확인하고, 모든 것이 양호하면 게시하세요." #: ../../source/contributor-how-to-release-flower.rst:15 @@ -824,10 +850,10 @@ msgstr "Docker 이미지 빌드를 위해 CI를 트리거합니다." #: ../../source/contributor-how-to-release-flower.rst:17 msgid "" -"To trigger the workflow, a collaborator must create a " -"``workflow_dispatch`` event in the GitHub CI. This can be done either " -"through the UI or via the GitHub CLI. The event requires only one input, " -"the Flower version, to be released." +"To trigger the workflow, a collaborator must create a ``workflow_dispatch`` " +"event in the GitHub CI. This can be done either through the UI or via the " +"GitHub CLI. The event requires only one input, the Flower version, to be " +"released." msgstr "" "워크플로우를 트리거하려면 공동 작업자가 GitHub CI에서 ``workflow_dispatch``" "를 생성해야 합니다. 이 작업은 UI 또는 GitHub CLI 를 통해 수행할 수 있습니다. " @@ -839,18 +865,19 @@ msgstr "**UI를 통해서**" #: ../../source/contributor-how-to-release-flower.rst:23 msgid "" -"Go to the ``Build docker images`` workflow `page " -"`_." +"Go to the ``Build docker images`` workflow `page `_." msgstr "" "``Build docker images`` 워크플로우 `페이지 `_로 이동합니다." #: ../../source/contributor-how-to-release-flower.rst:24 msgid "" -"Click on the ``Run workflow`` button and type the new version of Flower " -"in the ``Version of Flower`` input field." -msgstr "``Run workflow`` 버튼을 누르고 ``Version of Flower``에 Flower의 새버전을 " -"입력합니다." +"Click on the ``Run workflow`` button and type the new version of Flower in " +"the ``Version of Flower`` input field." +msgstr "" +"``Run workflow`` 버튼을 누르고 ``Version of Flower``에 Flower의 새버전을 입력" +"합니다." #: ../../source/contributor-how-to-release-flower.rst:25 msgid "Click on the **green** ``Run workflow`` button." @@ -864,16 +891,17 @@ msgstr "**GitHub CI를 통해서**" msgid "" "Make sure you are logged in via ``gh auth login`` and that the current " "working directory is the root of the Flower repository." -msgstr "``gh auth login``을 통해 로그인 했는지, 현재 작업 디렉토리가 Flower " -"리포지토리의 root인지 확인하세요." +msgstr "" +"``gh auth login``을 통해 로그인 했는지, 현재 작업 디렉토리가 Flower 리포지토" +"리의 root인지 확인하세요." #: ../../source/contributor-how-to-release-flower.rst:32 msgid "" "Trigger the workflow via ``gh workflow run docker-images.yml -f flwr-" "version=``." msgstr "" -"``gh workflow run docker-images.yml -f flwr-version=``을 통해 " -"워크플로우 를 트리거합니다." +"``gh workflow run docker-images.yml -f flwr-version=``을 통해 워" +"크플로우 를 트리거합니다." #: ../../source/contributor-how-to-release-flower.rst:35 msgid "After the release" @@ -897,10 +925,11 @@ msgstr "``changelog.md``에 ``Unreleased`` 섹션을 새로 추가합니다." #: ../../source/contributor-how-to-release-flower.rst:43 msgid "" -"Merge the pull request on the same day (i.e., before a new nightly " -"release gets published to PyPI)." -msgstr "pull request를 같은 날(즉, 새로운 nightly 릴리즈가 PyPI에 게시되기 전에) " -"병합하세요." +"Merge the pull request on the same day (i.e., before a new nightly release " +"gets published to PyPI)." +msgstr "" +"pull request를 같은 날(즉, 새로운 nightly 릴리즈가 PyPI에 게시되기 전에) 병합" +"하세요." #: ../../source/contributor-how-to-release-flower.rst:46 msgid "Publishing a pre-release" @@ -912,11 +941,11 @@ msgstr "사전 릴리즈 이름" #: ../../source/contributor-how-to-release-flower.rst:51 msgid "" -"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases" -" MUST use one of the following naming patterns:" +"PyPI supports pre-releases (alpha, beta, release candidate). Pre-releases " +"MUST use one of the following naming patterns:" msgstr "" -"PyPI는 사전 릴리즈(알파, 베타, 릴리스 후보)를 지원합니다. 사전 릴리즈는 " -"반드시 다음 명명 패턴 중 하나를 사용해야 합니다:" +"PyPI는 사전 릴리즈(알파, 베타, 릴리스 후보)를 지원합니다. 사전 릴리즈는 반드" +"시 다음 명명 패턴 중 하나를 사용해야 합니다:" #: ../../source/contributor-how-to-release-flower.rst:53 msgid "Alpha: ``MAJOR.MINOR.PATCHaN``" @@ -954,7 +983,8 @@ msgstr "``1.0.0rc1``" msgid "" "This is in line with PEP-440 and the recommendations from the Python " "Packaging Authority (PyPA):" -msgstr "이는 PEP-440 및 Python Packaging Authority (PyPA)의 권장 사항과 일치합니다:" +msgstr "" +"이는 PEP-440 및 Python Packaging Authority (PyPA)의 권장 사항과 일치합니다:" #: ../../source/contributor-how-to-release-flower.rst:67 msgid "`PEP-440 `_" @@ -962,37 +992,38 @@ msgstr "`PEP-440 `_" #: ../../source/contributor-how-to-release-flower.rst:68 msgid "" -"`PyPA Choosing a versioning scheme " -"`_" +"`PyPA Choosing a versioning scheme `_" msgstr "" "`PyPA 버전 관리 체계 선택하기 `_" #: ../../source/contributor-how-to-release-flower.rst:70 msgid "" -"Note that the approach defined by PyPA is not compatible with SemVer " -"2.0.0 spec, for details consult the `Semantic Versioning Specification " -"`_ (specifically item " -"11 on precedence)." +"Note that the approach defined by PyPA is not compatible with SemVer 2.0.0 " +"spec, for details consult the `Semantic Versioning Specification `_ (specifically item 11 on " +"precedence)." msgstr "" -"PyPA에서 정의한 접근 방식은 SemVer 2.0.0 사양과 호환되지 않으며, 자세한 " -"내용은`Semantic Versioning 관리 사양 `_ (특히 항목 11이 우선순위)을 참조하세요." +"PyPA에서 정의한 접근 방식은 SemVer 2.0.0 사양과 호환되지 않으며, 자세한 내용" +"은`Semantic Versioning 관리 사양 `_ (특히 항목 11이 우선순위)을 참조하세요." #: ../../source/contributor-how-to-release-flower.rst:73 msgid "Pre-release classification" msgstr "사전 릴리즈 분류" #: ../../source/contributor-how-to-release-flower.rst:75 -msgid "Should the next pre-release be called alpha, beta, or release candidate?" -msgstr "다음 사전 릴리를 알파, 베타 또는 릴리스 후보라고 불러야 하나요?" +msgid "" +"Should the next pre-release be called alpha, beta, or release candidate?" +msgstr "다음 사전 릴리즈를 알파, 베타 또는 릴리스 후보라고 불러야 하나요?" #: ../../source/contributor-how-to-release-flower.rst:77 msgid "" -"RC: feature complete, no known issues (apart from issues that are " -"classified as \"won't fix\" for the next stable release) - if no issues " -"surface this will become the next stable release" +"RC: feature complete, no known issues (apart from issues that are classified " +"as \"won't fix\" for the next stable release) - if no issues surface this " +"will become the next stable release" msgstr "" "RC: 기능 완료, 알려진 문제 없음(다음 stable 릴리즈에서 \"수정되지 않음\"으로 " "분류된 문제 제외) - 문제가 나타나지 않으면 다음 stable 릴리즈가 됩니다" @@ -1013,12 +1044,12 @@ msgstr "가상 환경 설정" msgid "" "It is recommended to run your Python setup within a virtual environment. " "This guide shows three different examples how to create a virtual " -"environment with pyenv virtualenv, poetry, or Anaconda. You can follow " -"the instructions or choose your preferred setup." +"environment with pyenv virtualenv, poetry, or Anaconda. You can follow the " +"instructions or choose your preferred setup." msgstr "" "가상 환경 내에서 파이썬 설정을 실행하는 것이 좋습니다. 이 가이드에서는 pyenv " -"virtualenv, poetry 또는 Anaconda를 사용하여 가상 환경을 만드는 세 가지 " -"예제를 보여줍니다. 안내를 따르거나 원하는 설정을 선택할 수 있습니다." +"virtualenv, poetry 또는 Anaconda를 사용하여 가상 환경을 만드는 세 가지 예제" +"를 보여줍니다. 안내를 따르거나 원하는 설정을 선택할 수 있습니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:9 msgid "Python Version" @@ -1027,23 +1058,21 @@ msgstr "Python 버전" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:11 #: ../../source/how-to-install-flower.rst:8 msgid "" -"Flower requires at least `Python 3.8 `_, " -"but `Python 3.10 `_ or above is " -"recommended." +"Flower requires at least `Python 3.8 `_, but " +"`Python 3.10 `_ or above is recommended." msgstr "" -"Flower는 `Python 3.8 `_이상이 필요하지만, `" -"Python 3.10 `_이상을 권장합니다." +"Flower는 `Python 3.8 `_이상이 필요하지만, " +"`Python 3.10 `_이상을 권장합니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:14 msgid "" -"Due to a known incompatibility with `ray " -"`_, we currently recommend utilizing at " -"most `Python 3.11 `_ for running Flower " -"simulations." +"Due to a known incompatibility with `ray `_, " +"we currently recommend utilizing at most `Python 3.11 `_ for running Flower simulations." msgstr "" -"`Ray `__와 호환되지 않는 것으로 알려져 " -"있으므로, 현재 Flower 시뮬레이션을 실행할 때는 최대 `Python 3.11 " -"`_을 사용하는 것이 좋습니다." +"`Ray `__와 호환되지 않는 것으로 알려져 있으므" +"로, 현재 Flower 시뮬레이션을 실행할 때는 최대 `Python 3.11 `_을 사용하는 것이 좋습니다." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:19 msgid "Virtualenv with Pyenv/Virtualenv" @@ -1051,23 +1080,23 @@ msgstr "Pyenv/Virtualenv를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:21 msgid "" -"One of the recommended virtual environment is `pyenv " -"`_/`virtualenv `_. Please see `Flower examples " -"`_ for details." +"One of the recommended virtual environment is `pyenv `_/`virtualenv `_. " +"Please see `Flower examples `_ for details." msgstr "" -"권장 가상 환경 중 하나는 `pyenv `_/`" -"virtualenv `_입니다. 자세한 " -"내용은 `Flower examples `" -"_를 참조하세요." +"권장 가상 환경 중 하나는 `pyenv `_/" +"`virtualenv `_입니다. 자세한 내용" +"은 `Flower examples `_를 " +"참조하세요." #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:23 msgid "" "Once Pyenv is set up, you can use it to install `Python Version 3.10 " "`_ or above:" msgstr "" -"Pyenv가 설정되면 이를 사용하여 'Python 버전 3.10 `_ 이상'을 설치할 수 있습니다:" +"Pyenv가 설정되면 이를 사용하여 'Python 버전 3.10 `_ 이상'을 설치할 수 있습니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:29 msgid "Create the virtualenv with:" @@ -1083,19 +1112,20 @@ msgstr "Poetry를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:46 msgid "" -"The Flower examples are based on `Poetry `_ to manage dependencies. After installing Poetry you " -"simply create a virtual environment with:" +"The Flower examples are based on `Poetry `_ " +"to manage dependencies. After installing Poetry you simply create a virtual " +"environment with:" msgstr "" -"Flower examples은 dependencies을 관리하기 위해 `Poetry `_를 기반으로 합니다. Poetry를 설치한 후 가상 환경을 생성하기만 " -"하면 됩니다:" +"Flower examples은 의존성을 관리하기 위해 `Poetry `_를 기반으로 합니다. Poetry를 설치한 후 가상 환경을 생성하기만 하면 " +"됩니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:52 msgid "" -"If you open a new terminal you can activate the previously created " -"virtual environment with the following command:" -msgstr "새 터미널을 열면 다음 명령을 사용하여 이전에 생성한 가상 환경을 활성화할 수 " +"If you open a new terminal you can activate the previously created virtual " +"environment with the following command:" +msgstr "" +"새 터미널을 열면 다음 명령을 사용하여 이전에 생성한 가상 환경을 활성화할 수 " "있습니다:" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:60 @@ -1104,12 +1134,12 @@ msgstr "Anaconda를 사용한 가상 환경" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:62 msgid "" -"If you prefer to use Anaconda for your virtual environment then install " -"and setup the `conda `_ package. After setting it up you can " -"create a virtual environment with:" +"If you prefer to use Anaconda for your virtual environment then install and " +"setup the `conda `_ package. After setting it up you can create a virtual " +"environment with:" msgstr "" -"가상 환경에서 Anaconda를 사용하려면 `conda `_ 패키지를 설치 및 " "설정하세요. 설정 후 다음을 사용하여 가상 환경을 만들 수 있습니다:" @@ -1123,8 +1153,8 @@ msgstr "그다음은?" #: ../../source/contributor-how-to-set-up-a-virtual-env.rst:78 msgid "" -"As soon as you created your virtual environment you clone one of the " -"`Flower examples `_." +"As soon as you created your virtual environment you clone one of the `Flower " +"examples `_." msgstr "" "가상 환경을 생성하자마자 'Flower examples `_ 중 하나를 클론합니다." @@ -1139,25 +1169,24 @@ msgstr "프로젝트 레이아웃" #: ../../source/contributor-how-to-write-documentation.rst:8 msgid "" -"The Flower documentation lives in the ``doc`` directory. The Sphinx-based" -" documentation system supports both reStructuredText (``.rst`` files) and" -" Markdown (``.md`` files)." +"The Flower documentation lives in the ``doc`` directory. The Sphinx-based " +"documentation system supports both reStructuredText (``.rst`` files) and " +"Markdown (``.md`` files)." msgstr "" "Flower 문서는 ``doc`` 디렉토리에 있습니다. Sphinx 기반 문서 시스템은 " -"reStructuredText 텍스트(``.rst`` 파일)와 Markdown(``.md`` 파일)을 모두 " -"지원합니다." +"reStructuredText 텍스트(``.rst`` 파일)와 Markdown(``.md`` 파일)을 모두 지원합" +"니다." #: ../../source/contributor-how-to-write-documentation.rst:10 #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:169 msgid "" -"Note that, in order to build the documentation locally (with ``poetry run" -" make html``, like described below), `Pandoc " -"`_ needs to be installed on the " -"system." +"Note that, in order to build the documentation locally (with ``poetry run " +"make html``, like described below), `Pandoc `_ needs to be installed on the system." msgstr "" -"로컬에서 문서를 작성하려면(아래 설명과 같이 ``poetry run make html``로) `" -"Pandoc `_이 시스템에 설치되어 있어야 " -"합니다." +"로컬에서 문서를 작성하려면(아래 설명과 같이 ``poetry run make html``로) " +"`Pandoc `_이 시스템에 설치되어 있어야 합" +"니다." #: ../../source/contributor-how-to-write-documentation.rst:14 msgid "Edit an existing page" @@ -1170,7 +1199,8 @@ msgstr "doc/source/``에서 기존 ``.rst``(또는 ``.md``) 파일을 편집합 #: ../../source/contributor-how-to-write-documentation.rst:17 #: ../../source/contributor-how-to-write-documentation.rst:27 msgid "Compile the docs: ``cd doc``, then ``poetry run make html``" -msgstr "문서를 컴파일합니다: ``cd doc``, ``poetry run make html`` 순으로 컴파일합니다" +msgstr "" +"문서를 컴파일합니다: ``cd doc``, ``poetry run make html`` 순으로 컴파일합니다" #: ../../source/contributor-how-to-write-documentation.rst:18 #: ../../source/contributor-how-to-write-documentation.rst:28 @@ -1195,18 +1225,18 @@ msgstr "``index.rst``에서 새 rst로 연결합니다" #: ../../source/contributor-ref-good-first-contributions.rst:2 msgid "Good first contributions" -msgstr "좋은 첫 번째 기여" +msgstr "훌륭한 첫 번째 기여" #: ../../source/contributor-ref-good-first-contributions.rst:4 msgid "" -"We welcome contributions to Flower! However, it is not always easy to " -"know where to start. We therefore put together a few recommendations on " -"where to start to increase your chances of getting your PR accepted into " -"the Flower codebase." +"We welcome contributions to Flower! However, it is not always easy to know " +"where to start. We therefore put together a few recommendations on where to " +"start to increase your chances of getting your PR accepted into the Flower " +"codebase." msgstr "" "Flower에 대한 기여를 환영합니다! 하지만 어디서부터 시작해야 할지 알기란 쉽지 " -"않습니다. 그래서 저희는 여러분의 PR이 Flower 코드베이스에 채택될 가능성을 " -"높이기 위해 어디서부터 시작해야 하는지 몇 가지 권장 사항을 정리해 보았습니다." +"않습니다. 그래서 저희는 여러분의 PR이 Flower 코드베이스에 채택될 가능성을 높" +"이기 위해 어디서부터 시작해야 하는지 몇 가지 권장 사항을 정리해 보았습니다." #: ../../source/contributor-ref-good-first-contributions.rst:11 msgid "Where to start" @@ -1214,13 +1244,13 @@ msgstr "시작 위치" #: ../../source/contributor-ref-good-first-contributions.rst:13 msgid "" -"Until the Flower core library matures it will be easier to get PR's " -"accepted if they only touch non-core areas of the codebase. Good " -"candidates to get started are:" +"Until the Flower core library matures it will be easier to get PR's accepted " +"if they only touch non-core areas of the codebase. Good candidates to get " +"started are:" msgstr "" "Flower 코어 라이브러리가 완성될 때까지는 코드베이스의 비핵심 영역만 건드리는 " -"것이 PR을 승인받기가 더 쉬울 것입니다. 시작하기에 좋은 후보자는 다음과 " -"같습니다:" +"것이 PR을 승인받기가 더 쉬울 것입니다. 시작하기에 좋은 후보자는 다음과 같습니" +"다:" #: ../../source/contributor-ref-good-first-contributions.rst:17 msgid "Documentation: What's missing? What could be expressed more clearly?" @@ -1240,31 +1270,31 @@ msgstr "Flower Baselines 요청" #: ../../source/contributor-ref-good-first-contributions.rst:25 msgid "" -"If you are not familiar with Flower Baselines, you should probably check-" -"out our `contributing guide for baselines " -"`_." +"If you are not familiar with Flower Baselines, you should probably check-out " +"our `contributing guide for baselines `_." msgstr "" "Flower Baseline에 익숙하지 않다면 ' Baseline 기여 가이드 `_를 확인해보세요." #: ../../source/contributor-ref-good-first-contributions.rst:27 msgid "" -"You should then check out the open `issues " -"`_" -" for baseline requests. If you find a baseline that you'd like to work on" -" and that has no assignees, feel free to assign it to yourself and start " -"working on it!" +"You should then check out the open `issues `_ for baseline " +"requests. If you find a baseline that you'd like to work on and that has no " +"assignees, feel free to assign it to yourself and start working on it!" msgstr "" -"그런 다음 오픈 된 `이슈 `_에서 baseline " "요청을 확인해야 합니다. 작업하고 싶은 기준선을 찾았지만 담당자가 없는 경우, " "자유롭게 자신에게 할당하고 작업을 시작하세요!" #: ../../source/contributor-ref-good-first-contributions.rst:31 msgid "" -"Otherwise, if you don't find a baseline you'd like to work on, be sure to" -" open a new issue with the baseline request template!" -msgstr "그렇지 않으면 작업하고 싶은 baseline을 찾지 못하면 baseline 요청 템플릿으로 " +"Otherwise, if you don't find a baseline you'd like to work on, be sure to " +"open a new issue with the baseline request template!" +msgstr "" +"그렇지 않으면 작업하고 싶은 baseline을 찾지 못하면 baseline 요청 템플릿으로 " "새 이슈를 열어야 합니다!" #: ../../source/contributor-ref-good-first-contributions.rst:34 @@ -1274,8 +1304,8 @@ msgstr "예시 요청" #: ../../source/contributor-ref-good-first-contributions.rst:36 msgid "" "We wish we had more time to write usage examples because we believe they " -"help users to get started with building what they want to build. Here are" -" a few ideas where we'd be happy to accept a PR:" +"help users to get started with building what they want to build. Here are a " +"few ideas where we'd be happy to accept a PR:" msgstr "" "사용 예시는 사용자가 원하는 것을 구축하는 데 도움이 된다고 생각하기 때문에 " "더 많은 시간을 할애하여 작성할 수 있었으면 합니다. 다음은 저희가 기꺼이 PR을 " @@ -1299,15 +1329,15 @@ msgstr "Secure Aggregation 프로토콜" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:4 msgid "" -"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg " -"protocol has not been implemented yet, so its diagram and abstraction may" -" not be accurate in practice. The SecAgg protocol can be considered as a " -"special case of the SecAgg+ protocol." +"Include SecAgg, SecAgg+, and LightSecAgg protocol. The LightSecAgg protocol " +"has not been implemented yet, so its diagram and abstraction may not be " +"accurate in practice. The SecAgg protocol can be considered as a special " +"case of the SecAgg+ protocol." msgstr "" -"SecAgg, SecAgg+, LightSecAgg 프로토콜을 포함합니다. LightSecAgg 프로토콜은 " -"아직 구현되지 않았기 때문에 다이어그램과 추상화가 실제로는 정확하지 않을 수 " -"있습니다. SecAgg 프로토콜은 SecAgg+ 프로토콜의 특수한 경우로 간주할 수 " -"있습니다." +"SecAgg, SecAgg+, LightSecAgg 프로토콜을 포함합니다. LightSecAgg 프로토콜은 아" +"직 구현되지 않았기 때문에 다이어그램과 추상화가 실제로는 정확하지 않을 수 있" +"습니다. SecAgg 프로토콜은 SecAgg+ 프로토콜의 특수한 경우로 간주할 수 있습니" +"다." #: ../../source/contributor-ref-secure-aggregation-protocols.rst:8 msgid "The :code:`SecAgg+` abstraction" @@ -1317,18 +1347,18 @@ msgstr "The :code:`SecAgg+` 추상화" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:161 msgid "" "In this implementation, each client will be assigned with a unique index " -"(int) for secure aggregation, and thus many python dictionaries used have" -" keys of int type rather than ClientProxy type." +"(int) for secure aggregation, and thus many python dictionaries used have " +"keys of int type rather than ClientProxy type." msgstr "" -"구현에서는 각 클라이언트에 secure aggregation를 위한 고유 인덱스(int)가 " -"할당되므로 사용되는 많은 파이썬 dictionaries에는 ClientProxy 타입이 아닌 int " -"타입의 키가 있습니다." +"구현에서는 각 클라이언트에 secure aggregation를 위한 고유 인덱스(int)가 할당" +"되므로 사용되는 많은 파이썬 dictionaries에는 ClientProxy 타입이 아닌 int 타입" +"의 키가 있습니다." #: ../../source/contributor-ref-secure-aggregation-protocols.rst:65 #: ../../source/contributor-ref-secure-aggregation-protocols.rst:198 msgid "" -"The Flower server will execute and process received results in the " -"following order:" +"The Flower server will execute and process received results in the following " +"order:" msgstr "Flower 서버는 수신된 결과를 다음 순서로 실행하고 처리합니다:" #: ../../source/contributor-ref-secure-aggregation-protocols.rst:159 @@ -1345,16 +1375,17 @@ msgstr "GitHub에서 기여하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:4 msgid "" -"This guide is for people who want to get involved with Flower, but who " -"are not used to contributing to GitHub projects." -msgstr "이 가이드는 Flower에 참여하고 싶지만 GitHub 프로젝트에 기여하는 데 익숙하지 " +"This guide is for people who want to get involved with Flower, but who are " +"not used to contributing to GitHub projects." +msgstr "" +"이 가이드는 Flower에 참여하고 싶지만 GitHub 프로젝트에 기여하는 데 익숙하지 " "않은 분들을 위한 것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:6 msgid "" -"If you're familiar with how contributing on GitHub works, you can " -"directly checkout our :doc:`getting started guide for contributors " -"`." +"If you're familiar with how contributing on GitHub works, you can directly " +"checkout our :doc:`getting started guide for contributors `." msgstr "" "깃허브에서 기여하는 방식에 익숙하다면 :doc:`기여자를 위한 시작 가이드" "`를 직접 확인하세요." @@ -1372,19 +1403,19 @@ msgid "" "Git is a distributed version control tool. This allows for an entire " "codebase's history to be stored and every developer's machine. It is a " "software that will need to be installed on your local machine, you can " -"follow this `guide `_ to set it up." +"follow this `guide `_ to set it up." msgstr "" "Git은 분산 버전 관리 도구입니다. 이를 통해 전체 코드베이스의 히스토리와 모든 " -"개발자의 컴퓨터를 저장할 수 있습니다. 로컬 컴퓨터에 설치해야 하는 " -"소프트웨어로, 이 `가이드 `_를 따라 설정할 수 있습니다." +"개발자의 컴퓨터를 저장할 수 있습니다. 로컬 컴퓨터에 설치해야 하는 소프트웨어" +"로, 이 `가이드 `_를 따라 설정할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:16 msgid "" "GitHub, itself, is a code hosting platform for version control and " -"collaboration. It allows for everyone to collaborate and work from " -"anywhere on remote repositories." +"collaboration. It allows for everyone to collaborate and work from anywhere " +"on remote repositories." msgstr "" "GitHub는 그 자체로 버전 관리 및 협업을 위한 코드 호스팅 플랫폼입니다. 누구나 " "원격 레포지토리에서 어디서든 협업하고 작업할 수 있습니다." @@ -1393,19 +1424,20 @@ msgstr "" msgid "" "If you haven't already, you will need to create an account on `GitHub " "`_." -msgstr "아직 계정을 만들지 않았다면 `GitHub `_에서 계정을 " +msgstr "" +"아직 계정을 만들지 않았다면 `GitHub `_에서 계정을 " "만들어야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:20 msgid "" -"The idea behind the generic Git and GitHub workflow boils down to this: " -"you download code from a remote repository on GitHub, make changes " -"locally and keep track of them using Git and then you upload your new " -"history back to GitHub." +"The idea behind the generic Git and GitHub workflow boils down to this: you " +"download code from a remote repository on GitHub, make changes locally and " +"keep track of them using Git and then you upload your new history back to " +"GitHub." msgstr "" "일반적인 Git 및 GitHub 워크플로우의 기본 개념은 다음과 같이 요약됩니다. " -"GitHub의 원격 레포지토리에서 코드를 다운로드하고 로컬에서 변경한 후 Git을 " -"사용하여 추적한 다음 새 기록을 다시 GitHub에 업로드하는 것입니다." +"GitHub의 원격 레포지토리에서 코드를 다운로드하고 로컬에서 변경한 후 Git을 사" +"용하여 추적한 다음 새 기록을 다시 GitHub에 업로드하는 것입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:32 msgid "**Forking the Flower repository**" @@ -1413,25 +1445,25 @@ msgstr "**Flower 레포지토리 포크하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:24 msgid "" -"A fork is a personal copy of a GitHub repository. To create one for " -"Flower, you must navigate to ``_ (while " -"connected to your GitHub account) and click the ``Fork`` button situated " -"on the top right of the page." +"A fork is a personal copy of a GitHub repository. To create one for Flower, " +"you must navigate to ``_ (while connected to " +"your GitHub account) and click the ``Fork`` button situated on the top right " +"of the page." msgstr "" "포크는 GitHub 리포지토리의 개인 복사본입니다. Flower용 포크를 만들려면 " -"``_로 이동하여(GitHub 계정에 연결된 상태에서)" -" 페이지 오른쪽 상단에 있는 ``포크`` 버튼을 클릭해야 합니다." +"``_로 이동하여(GitHub 계정에 연결된 상태에" +"서) 페이지 오른쪽 상단에 있는 ``포크`` 버튼을 클릭해야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:29 msgid "" "You can change the name if you want, but this is not necessary as this " -"version of Flower will be yours and will sit inside your own account " -"(i.e., in your own list of repositories). Once created, you should see on" -" the top left corner that you are looking at your own version of Flower." +"version of Flower will be yours and will sit inside your own account (i.e., " +"in your own list of repositories). Once created, you should see on the top " +"left corner that you are looking at your own version of Flower." msgstr "" -"원하는 경우 이름을 변경할 수 있지만, 이 버전의 Flower는 자신의 계정(즉, " -"자신의 리포지토리 목록)에 위치하게 되므로 변경할 필요는 없습니다. 만들기가 " -"완료되면 왼쪽 상단에Flower 버전이 표시되는 것을 볼 수 있습니다." +"원하는 경우 이름을 변경할 수 있지만, 이 버전의 Flower는 자신의 계정(즉, 자신" +"의 리포지토리 목록)에 위치하게 되므로 변경할 필요는 없습니다. 만들기가 완료되" +"면 왼쪽 상단에Flower 버전이 표시되는 것을 볼 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "**Cloning your forked repository**" @@ -1440,27 +1472,29 @@ msgstr "**포크된 레포지토리 클론하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:35 msgid "" "The next step is to download the forked repository on your machine to be " -"able to make changes to it. On your forked repository page, you should " -"first click on the ``Code`` button on the right, this will give you the " -"ability to copy the HTTPS link of the repository." +"able to make changes to it. On your forked repository page, you should first " +"click on the ``Code`` button on the right, this will give you the ability to " +"copy the HTTPS link of the repository." msgstr "" -"다음 단계는 컴퓨터에서 포크된 레포지토리를 변경할 수 있도록 다운로드하는 " -"것입니다. 포크된 포지토리 페이지에서 먼저 오른쪽의 ``Code`` 버튼을 클릭하면 " -"레포지토리의 HTTPS 링크를 복사할 수 있습니다." +"다음 단계는 컴퓨터에서 포크된 레포지토리를 변경할 수 있도록 다운로드하는 것입" +"니다. 포크된 포지토리 페이지에서 먼저 오른쪽의 ``Code`` 버튼을 클릭하면 레포" +"지토리의 HTTPS 링크를 복사할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:41 msgid "" "Once you copied the \\, you can open a terminal on your machine, " "navigate to the place you want to download the repository to and type:" -msgstr "\\를 복사한 후에는 컴퓨터에서 터미널을 열고 레포지토리를 다운로드할 " -"위치로 이동하여 입력하면 됩니다:" +msgstr "" +"\\를 복사한 후에는 컴퓨터에서 터미널을 열고 레포지토리를 다운로드할 위" +"치로 이동하여 입력하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:47 msgid "" -"This will create a ``flower/`` (or the name of your fork if you renamed " -"it) folder in the current working directory." -msgstr "현재 작업 디렉터리에``flower/``(또는 포크 이름을 변경한 경우 포크 이름) " -"폴더가 생성됩니다." +"This will create a ``flower/`` (or the name of your fork if you renamed it) " +"folder in the current working directory." +msgstr "" +"현재 작업 디렉터리에``flower/``(또는 포크 이름을 변경한 경우 포크 이름) 폴더" +"가 생성됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:66 msgid "**Add origin**" @@ -1472,14 +1506,14 @@ msgstr "그런 다음 레포지토리 폴더로 이동할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:56 msgid "" -"And here we will need to add an origin to our repository. The origin is " -"the \\ of the remote fork repository. To obtain it, we can do as " -"previously mentioned by going to our fork repository on our GitHub " -"account and copying the link." +"And here we will need to add an origin to our repository. The origin is the " +"\\ of the remote fork repository. To obtain it, we can do as " +"previously mentioned by going to our fork repository on our GitHub account " +"and copying the link." msgstr "" -"여기에 레포지토리에 origin을 추가해야 합니다. origin은 원격 포크 " -"레포지토리의 \\입니다. origin을 얻으려면 앞서 설명한 대로 GitHub " -"계정의 포크 레포지토리로 이동하여 링크를 복사하면 됩니다." +"여기에 레포지토리에 origin을 추가해야 합니다. origin은 원격 포크 레포지토리" +"의 \\입니다. origin을 얻으려면 앞서 설명한 대로 GitHub 계정의 포크 레" +"포지토리로 이동하여 링크를 복사하면 됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:61 msgid "" @@ -1495,32 +1529,34 @@ msgstr "**Upstream 추가하기**" msgid "" "Now we will add an upstream address to our repository. Still in the same " "directory, we must run the following command:" -msgstr "이제 레포지토리에 upstream 주소를 추가하겠습니다. 여전히 같은 디렉터리에서 " -"다음 명령을 실행해야 합니다:" +msgstr "" +"이제 레포지토리에 upstream 주소를 추가하겠습니다. 여전히 같은 디렉터리에서 다" +"음 명령을 실행해야 합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:76 -msgid "The following diagram visually explains what we did in the previous steps:" +msgid "" +"The following diagram visually explains what we did in the previous steps:" msgstr "다음 다이어그램은 이전 단계에서 수행한 작업을 시각적으로 설명합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:80 msgid "" -"The upstream is the GitHub remote address of the parent repository (in " -"this case Flower), i.e. the one we eventually want to contribute to and " -"therefore need an up-to-date history of. The origin is just the GitHub " -"remote address of the forked repository we created, i.e. the copy (fork) " -"in our own account." +"The upstream is the GitHub remote address of the parent repository (in this " +"case Flower), i.e. the one we eventually want to contribute to and therefore " +"need an up-to-date history of. The origin is just the GitHub remote address " +"of the forked repository we created, i.e. the copy (fork) in our own account." msgstr "" -"upstream은 부모 레포지토리(이 경우 Flower)의 GitHub 원격 주소, 즉 우리가 " -"최종적으로 기여하고 싶고 따라서 최신 기록이 필요한 레포지토리입니다. " -"origin은 우리가 만든 포크된 레포지토리의 GitHub 원격 주소, 즉 우리 계정에 " -"있는 사본(포크)입니다." +"upstream은 부모 레포지토리(이 경우 Flower)의 GitHub 원격 주소, 즉 우리가 최종" +"적으로 기여하고 싶고 따라서 최신 기록이 필요한 레포지토리입니다. origin은 우" +"리가 만든 포크된 레포지토리의 GitHub 원격 주소, 즉 우리 계정에 있는 사본(포" +"크)입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:84 msgid "" "To make sure our local version of the fork is up-to-date with the latest " "changes from the Flower repository, we can execute the following command:" -msgstr "로컬 버전의 포크가 Flower 레포지토리의 최신 변경 사항으로 최신 상태인지 " -"확인하려면 다음 명령을 실행하면 됩니다:" +msgstr "" +"로컬 버전의 포크가 Flower 레포지토리의 최신 변경 사항으로 최신 상태인지 확인" +"하려면 다음 명령을 실행하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:93 msgid "Setting up the coding environment" @@ -1529,12 +1565,12 @@ msgstr "코딩 환경 설정" #: ../../source/contributor-tutorial-contribute-on-github.rst:95 msgid "" "This can be achieved by following this :doc:`getting started guide for " -"contributors ` (note " -"that you won't need to clone the repository). Once you are able to write " -"code and test it, you can finally start making changes!" +"contributors ` (note that " +"you won't need to clone the repository). Once you are able to write code and " +"test it, you can finally start making changes!" msgstr "" ":doc:'기여자를 위한 시작 가이드 '를 참조하세요(리포지토리를 복제할 필요는 없습니다). 코드를 " +"contributor>'를 참조하세요(레포지토리를 복제할 필요는 없습니다). 코드를 " "작성하고 테스트할 수 있게 되면 드디어 변경을 시작할 수 있습니다!" #: ../../source/contributor-tutorial-contribute-on-github.rst:100 @@ -1543,8 +1579,7 @@ msgstr "변경하기" #: ../../source/contributor-tutorial-contribute-on-github.rst:102 msgid "" -"Before making any changes make sure you are up-to-date with your " -"repository:" +"Before making any changes make sure you are up-to-date with your repository:" msgstr "변경하기 전에 레포지토리를 최신 상태로 유지하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:108 @@ -1557,16 +1592,15 @@ msgstr "**새 브랜치 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:115 msgid "" -"To make the history cleaner and easier to work with, it is good practice " -"to create a new branch for each feature/project that needs to be " -"implemented." -msgstr "히스토리를 더 깔끔하고 작업하기 쉽게 만들려면 구현해야 하는 각 기능/" -"프로젝트에 대해 새 브랜치를 만드는 것이 좋습니다." +"To make the history cleaner and easier to work with, it is good practice to " +"create a new branch for each feature/project that needs to be implemented." +msgstr "" +"히스토리를 더 깔끔하고 작업하기 쉽게 만들려면 구현해야 하는 각 기능/프로젝트" +"에 대해 새 브랜치를 만드는 것이 좋습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:118 msgid "" -"To do so, just run the following command inside the repository's " -"directory:" +"To do so, just run the following command inside the repository's directory:" msgstr "이렇게 하려면 레포지토리 디렉토리에서 다음 명령을 실행하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 @@ -1574,8 +1608,9 @@ msgid "**Make changes**" msgstr "**변경하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:125 -msgid "Write great code and create wonderful changes using your favorite editor!" -msgstr "선호하 편집기를 사용하여 멋진 코드를 작성하고 훌륭한 변화를 만들어 보세요!" +msgid "" +"Write great code and create wonderful changes using your favorite editor!" +msgstr "선호하는 편집기를 사용하여 멋진 코드를 작성하고 훌륭한 변화를 만들어 보세요!" #: ../../source/contributor-tutorial-contribute-on-github.rst:138 msgid "**Test and format your code**" @@ -1583,9 +1618,9 @@ msgstr "**코드 테스트 및 서식 지정**" #: ../../source/contributor-tutorial-contribute-on-github.rst:128 msgid "" -"Don't forget to test and format your code! Otherwise your code won't be " -"able to be merged into the Flower repository. This is done so the " -"codebase stays consistent and easy to understand." +"Don't forget to test and format your code! Otherwise your code won't be able " +"to be merged into the Flower repository. This is done so the codebase stays " +"consistent and easy to understand." msgstr "" "코드를 테스트하고 서식을 지정하는 것을 잊지 마세요! 그렇지 않으면 코드를 " "Flower 레포지토리에 병합할 수 없습니다. 이는 코드베이스가 일관성을 유지하고 " @@ -1601,10 +1636,11 @@ msgstr "**Stage 변경**" #: ../../source/contributor-tutorial-contribute-on-github.rst:141 msgid "" -"Before creating a commit that will update your history, you must specify " -"to Git which files it needs to take into account." -msgstr "기록을 업데이트할 커밋을 만들기 전에 어떤 파일을 고려해야 하는지 Git에 " -"지정해야 합니다." +"Before creating a commit that will update your history, you must specify to " +"Git which files it needs to take into account." +msgstr "" +"기록을 업데이트할 커밋을 만들기 전에 어떤 파일을 고려해야 하는지 Git에 지정해" +"야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:143 msgid "This can be done with:" @@ -1612,12 +1648,12 @@ msgstr "이 작업을 수행할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:149 msgid "" -"To check which files have been modified compared to the last version " -"(last commit) and to see which files are staged for commit, you can use " -"the :code:`git status` command." +"To check which files have been modified compared to the last version (last " +"commit) and to see which files are staged for commit, you can use the :code:" +"`git status` command." msgstr "" -"마지막 버전(마지막 커밋)과 비교하여 수정된 파일을 확인하고 커밋을 위해 " -"스테이징된 파일을 확인하려면 :code:`git status` 명령을 사용하면 됩니다." +"마지막 버전(마지막 커밋)과 비교하여 수정된 파일을 확인하고 커밋을 위해 스테이" +"징된 파일을 확인하려면 :code:`git status` 명령을 사용하면 됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:160 msgid "**Commit changes**" @@ -1628,18 +1664,18 @@ msgid "" "Once you have added all the files you wanted to commit using :code:`git " "add`, you can finally create your commit using this command:" msgstr "" -":code:`git add`를 사용하여 커밋하려는 모든 파일을 추가한 후, 마지막으로 이 " -"명령을 사용하여 커밋을 생성할 수 있습니다:" +":code:`git add`를 사용하여 커밋하려는 모든 파일을 추가한 후, 마지막으로 이 명" +"령을 사용하여 커밋을 생성할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:159 msgid "" -"The \\ is there to explain to others what the commit " -"does. It should be written in an imperative style and be concise. An " -"example would be :code:`git commit -m \"Add images to README\"`." +"The \\ is there to explain to others what the commit does. " +"It should be written in an imperative style and be concise. An example would " +"be :code:`git commit -m \"Add images to README\"`." msgstr "" -"커밋의 내용을 다른 사람에게 설명하기 위해 \\가 있습니다. " -"명령형 스타일로 작성해야 하며 간결해야 합니다. 예를 들면 :code:`git commit -" -"m \"Add images to README\"`." +"커밋의 내용을 다른 사람에게 설명하기 위해 \\가 있습니다. 명" +"령형 스타일로 작성해야 하며 간결해야 합니다. 예를 들면 :code:`git commit -m " +"\"Add images to README\"`." #: ../../source/contributor-tutorial-contribute-on-github.rst:171 msgid "**Push the changes to the fork**" @@ -1647,19 +1683,20 @@ msgstr "**변경 사항을 포크에 푸시**" #: ../../source/contributor-tutorial-contribute-on-github.rst:163 msgid "" -"Once we have committed our changes, we have effectively updated our local" -" history, but GitHub has no way of knowing this unless we push our " -"changes to our origin's remote address:" +"Once we have committed our changes, we have effectively updated our local " +"history, but GitHub has no way of knowing this unless we push our changes to " +"our origin's remote address:" msgstr "" -"변경 사항을 커밋하면 로컬 히스토리를 효과적으로 업데이트한 것이지만, 변경 " -"사항을 원본의 원격 주소로 푸시하지 않는 한 GitHub는 이를 알 방법이 없습니다:" +"변경 사항을 커밋하면 로컬 히스토리를 효과적으로 업데이트한 것이지만, 변경 사" +"항을 원본의 원격 주소로 푸시하지 않는 한 GitHub는 이를 알 방법이 없습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:170 msgid "" "Once this is done, you will see on the GitHub that your forked repo was " "updated with the changes you have made." -msgstr "이 작업이 완료되면 변경한 내용으로 포크된 레포지토리가 업데이트된 것을 " -"GitHub에서 확인할 수 있습니다." +msgstr "" +"이 작업이 완료되면 변경한 내용으로 포크된 레포지토리가 업데이트된 것을 GitHub" +"에서 확인할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:174 msgid "Creating and merging a pull request (PR)" @@ -1671,39 +1708,43 @@ msgstr "**PR 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:177 msgid "" -"Once you have pushed changes, on the GitHub webpage of your repository " -"you should see the following message:" -msgstr "변경 사항을 푸시하고 나면 레포지토리의 GitHub 웹페이지에 다음 메시지가 " -"표시됩니다:" +"Once you have pushed changes, on the GitHub webpage of your repository you " +"should see the following message:" +msgstr "" +"변경 사항을 푸시하고 나면 레포지토리의 GitHub 웹페이지에 다음 메시지가 표시됩" +"니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:181 msgid "Otherwise you can always find this option in the ``Branches`` page." -msgstr "그렇지 않으면 언제든지 ``Branches`` 페이지에서 이 옵션을 찾을 수 있습니다." +msgstr "" +"그렇지 않으면 언제든지 ``Branches`` 페이지에서 이 옵션을 찾을 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:183 msgid "" "Once you click the ``Compare & pull request`` button, you should see " "something similar to this:" -msgstr "``Compare & pull request`` 버튼을 클릭하면 이와 비슷한 화면이 표시됩니다:" +msgstr "" +"``Compare & pull request`` 버튼을 클릭하면 이와 비슷한 화면이 표시됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:187 -msgid "At the top you have an explanation of which branch will be merged where:" +msgid "" +"At the top you have an explanation of which branch will be merged where:" msgstr "상단에는 어느 지점이 어디에 병합될 것인지에 대한 설명이 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:191 msgid "" -"In this example you can see that the request is to merge the branch " -"``doc-fixes`` from my forked repository to branch ``main`` from the " -"Flower repository." +"In this example you can see that the request is to merge the branch ``doc-" +"fixes`` from my forked repository to branch ``main`` from the Flower " +"repository." msgstr "" -"이 예제에서는 내 포크된 레포지토리의 ``doc-fixes`` 브랜치를 Flower " -"레포지토리의 ``main`` 브랜치에 병합하라는 요청을 볼 수 있습니다." +"이 예제에서는 내 포크된 레포지토리의 ``doc-fixes`` 브랜치를 Flower 레포지토리" +"의 ``main`` 브랜치에 병합하라는 요청을 볼 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:193 msgid "" "The title should be changed to adhere to the :ref:`pr_title_format` " -"guidelines, otherwise it won't be possible to merge the PR. So in this " -"case, a correct title might be ``docs(framework:skip) Fix typos``." +"guidelines, otherwise it won't be possible to merge the PR. So in this case, " +"a correct title might be ``docs(framework:skip) Fix typos``." msgstr "" "제목은 :ref:`pr_title_format` 가이드라인을 준수하도록 변경해야 하며, 그렇지 " "않으면 PR을 병합할 수 없습니다. 따라서 이 경우 올바른 제목은 " @@ -1711,14 +1752,13 @@ msgstr "" #: ../../source/contributor-tutorial-contribute-on-github.rst:196 msgid "" -"The input box in the middle is there for you to describe what your PR " -"does and to link it to existing issues. We have placed comments (that " -"won't be rendered once the PR is opened) to guide you through the " -"process." +"The input box in the middle is there for you to describe what your PR does " +"and to link it to existing issues. We have placed comments (that won't be " +"rendered once the PR is opened) to guide you through the process." msgstr "" -"가운데에 있는 입력 상자는 PR의 기능을 설명하고 기존 이슈에 연결할 수 있는 " -"곳입니다. 프로세스를 안내하기 위해 코멘트(PR이 열리면 렌더링되지 않음)를 " -"배치했습니다." +"가운데에 있는 입력 상자는 PR의 기능을 설명하고 기존 이슈에 연결할 수 있는 곳" +"입니다. 프로세스를 안내하기 위해 코멘트(PR이 열리면 렌더링되지 않음)를 배치했" +"습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:199 msgid "It is important to follow the instructions described in comments." @@ -1727,16 +1767,16 @@ msgstr "코멘트에 설명된 지침을 따르는 것이 중요합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:201 msgid "" "At the bottom you will find the button to open the PR. This will notify " -"reviewers that a new PR has been opened and that they should look over it" -" to merge or to request changes." +"reviewers that a new PR has been opened and that they should look over it to " +"merge or to request changes." msgstr "" "하단에는 PR을 여는 버튼이 있습니다. 이렇게 하면 검토자에게 새 PR이 열렸으며 " "병합하거나 변경을 요청하기 위해 검토해야 함을 알립니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:204 msgid "" -"If your PR is not yet ready for review, and you don't want to notify " -"anyone, you have the option to create a draft pull request:" +"If your PR is not yet ready for review, and you don't want to notify anyone, " +"you have the option to create a draft pull request:" msgstr "" "PR이 아직 검토할 준비가 되지 않았고 다른 사람에게 알리고 싶지 않은 경우 pull " "request 초안을 만드는 옵션이 있습니다:" @@ -1748,10 +1788,11 @@ msgstr "**new changes 만들기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:209 msgid "" "Once the PR has been opened (as draft or not), you can still push new " -"commits to it the same way we did before, by making changes to the branch" -" associated with the PR." -msgstr "PR이 초안으로 열렸든 아니든, PR과 연결된 브랜치를 변경하여 이전과 같은 " -"방식으로 새 커밋을 푸시할 수 있습니다." +"commits to it the same way we did before, by making changes to the branch " +"associated with the PR." +msgstr "" +"PR이 초안으로 열렸든 아니든, PR과 연결된 브랜치를 변경하여 이전과 같은 방식으" +"로 새 커밋을 푸시할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:231 msgid "**Review the PR**" @@ -1759,17 +1800,19 @@ msgstr "**PR 검토하기**" #: ../../source/contributor-tutorial-contribute-on-github.rst:212 msgid "" -"Once the PR has been opened or once the draft PR has been marked as " -"ready, a review from code owners will be automatically requested:" -msgstr "PR이 열리거나 초안 PR이 준비됨으로 표시되면 코드 소유자의 검토가 자동으로 " -"요청됩니다:" +"Once the PR has been opened or once the draft PR has been marked as ready, a " +"review from code owners will be automatically requested:" +msgstr "" +"PR이 열리거나 초안 PR이 준비됨으로 표시되면 코드 소유자의 검토가 자동으로 요" +"청됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:216 msgid "" -"Code owners will then look into the code, ask questions, request changes " -"or validate the PR." -msgstr "그러면 코드 소유자는 코드를 살펴보고, 질문하고, 변경을 요청하거나 PR의 " -"유효성을 검사합니다." +"Code owners will then look into the code, ask questions, request changes or " +"validate the PR." +msgstr "" +"그러면 코드 소유자는 코드를 살펴보고, 질문하고, 변경을 요청하거나 PR의 유효성" +"을 검사합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:218 msgid "Merging will be blocked if there are ongoing requested changes." @@ -1777,9 +1820,10 @@ msgstr "진행 중인 변경 요청이 있는 경우 병합이 차단됩니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:222 msgid "" -"To resolve them, just push the necessary changes to the branch associated" -" with the PR:" -msgstr "이를 해결하려면 PR과 연결된 브랜치에 필요한 변경 사항을 푸시하면 됩니다:" +"To resolve them, just push the necessary changes to the branch associated " +"with the PR:" +msgstr "" +"이를 해결하려면 PR과 연결된 브랜치에 필요한 변경 사항을 푸시하면 됩니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:226 msgid "And resolve the conversation:" @@ -1787,8 +1831,7 @@ msgstr "그리고 소통을 통해 해결하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:230 msgid "" -"Once all the conversations have been resolved, you can re-request a " -"review." +"Once all the conversations have been resolved, you can re-request a review." msgstr "모든 대화가 해결되면 검토를 다시 요청할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:251 @@ -1797,16 +1840,18 @@ msgstr "**PR이 병합되면**" #: ../../source/contributor-tutorial-contribute-on-github.rst:234 msgid "" -"If all the automatic tests have passed and reviewers have no more changes" -" to request, they can approve the PR and merge it." -msgstr "모든 자동 테스트가 통과되고 검토자가 더 이상 요청할 변경 사항이 없는 경우 " -"PR을 승인하고 병합할 수 있습니다." +"If all the automatic tests have passed and reviewers have no more changes to " +"request, they can approve the PR and merge it." +msgstr "" +"모든 자동 테스트가 통과되고 검토자가 더 이상 요청할 변경 사항이 없는 경우 PR" +"을 승인하고 병합할 수 있습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:238 msgid "" "Once it is merged, you can delete the branch on GitHub (a button should " "appear to do so) and also delete it locally by doing:" -msgstr "병합이 완료되면 GitHub에서 브랜치를 삭제할 수 있으며(삭제 버튼이 표시되어야 " +msgstr "" +"병합이 완료되면 GitHub에서 브랜치를 삭제할 수 있으며(삭제 버튼이 표시되어야 " "함), 로컬에서도 삭제할 수 있습니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:245 @@ -1823,40 +1868,43 @@ msgstr "문제" #: ../../source/contributor-tutorial-contribute-on-github.rst:259 msgid "" -"For our documentation, we've started to use the `Diàtaxis framework " -"`_." -msgstr "저희 문서에는 'Diàtaxis 프레임워크 `_'를 사용하기 " -"시작했습니다." +"For our documentation, we've started to use the `Diàtaxis framework `_." +msgstr "" +"저희 문서에는 'Diàtaxis 프레임워크 `_'를 사용하기 시작" +"했습니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:261 msgid "" -"Our \"How to\" guides should have titles that continue the sentence \"How" -" to …\", for example, \"How to upgrade to Flower 1.0\"." +"Our \"How to\" guides should have titles that continue the sentence \"How to " +"…\", for example, \"How to upgrade to Flower 1.0\"." msgstr "" -"'How to' 가이드의 제목은 \"How to …\"라는 문장을 이어가는 제목이어야 " -"합니다(예: \"How to upgrade to Flower 1.0\")." +"'How to' 가이드의 제목은 \"How to …\"라는 문장을 이어가는 제목이어야 합니다" +"(예: \"How to upgrade to Flower 1.0\")." #: ../../source/contributor-tutorial-contribute-on-github.rst:263 msgid "" "Most of our guides do not follow this new format yet, and changing their " "title is (unfortunately) more involved than one might think." -msgstr "대부분의 가이드는 아직 이 새로운 형식을 따르지 않으며, 안타깝게도 제목을 " -"변경하는 작업은 생각보다 복잡합니다." +msgstr "" +"대부분의 가이드는 아직 이 새로운 형식을 따르지 않으며, 안타깝게도 제목을 변경" +"하는 작업은 생각보다 복잡합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:265 msgid "" -"This issue is about changing the title of a doc from present continuous " -"to present simple." -msgstr "이번 이슈는 문서 제목을 현재 연속형에서 현재 단순형으로 변경하는 것에 관한 " -"것입니다." +"This issue is about changing the title of a doc from present continuous to " +"present simple." +msgstr "" +"이번 이슈는 문서 제목을 현재 연속형에서 현재 단순형으로 변경하는 것에 관한 것" +"입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:267 msgid "" "Let's take the example of \"Saving Progress\" which we changed to \"Save " "Progress\". Does this pass our check?" msgstr "" -"\"How to saving progress\"을 \"How to save progress\"으로 변경한 예를 들어 " -"보겠습니다. 이것이 우리의 점검을 통과했나요?" +"\"How to saving progress\"을 \"How to save progress\"으로 변경한 예를 들어 보" +"겠습니다. 이것이 우리의 점검을 통과했나요?" #: ../../source/contributor-tutorial-contribute-on-github.rst:269 msgid "Before: \"How to saving progress\" ❌" @@ -1876,7 +1924,7 @@ msgid "" "After cloning and setting up the Flower repo, here's what you should do:" msgstr "" "이것은 사소한 변경이지만 end-to-end 설정을 테스트할 수 있습니다. Flower " -"포지토리를 복제하고 설정한 후에는 다음과 같이 하세요:" +"레포지토리를 복제하고 설정한 후에는 다음과 같이 하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:278 msgid "Find the source file in ``doc/source``" @@ -1886,13 +1934,14 @@ msgstr "``doc/source``에서 소스 파일을 찾습니다" msgid "" "Make the change in the ``.rst`` file (beware, the dashes under the title " "should be the same length as the title itself)" -msgstr "``.rst`` 파일에서 변경합니다(제목 아래의 대시는 제목 자체의 길이와 같아야 " -"합니다)" +msgstr "" +"``.rst`` 파일에서 변경합니다(제목 아래의 대시는 제목 자체의 길이와 같아야 합" +"니다)" #: ../../source/contributor-tutorial-contribute-on-github.rst:280 msgid "" -"Build the docs and `check the result `_" +"Build the docs and `check the result `_" msgstr "" "문서를 빌드하고 '결과 확인 `_'합니다" @@ -1903,14 +1952,14 @@ msgstr "파일 이름 바꾸기" #: ../../source/contributor-tutorial-contribute-on-github.rst:285 msgid "" -"You might have noticed that the file name still reflects the old wording." -" If we just change the file, then we break all existing links to it - it " -"is **very important** to avoid that, breaking links can harm our search " -"engine ranking." +"You might have noticed that the file name still reflects the old wording. If " +"we just change the file, then we break all existing links to it - it is " +"**very important** to avoid that, breaking links can harm our search engine " +"ranking." msgstr "" -"파일 이름에 여전히 이전 문구가 반영되어 있는 것을 보셨을 것입니다. 파일만 " -"변경하면 파일에 대한 기존 링크가 모두 끊어지는데, 링크를 끊으면 검색 엔진 " -"순위에 영향을 줄 수 있으므로 이를 방지하는 것이 **매우 중요**합니다." +"파일 이름에 여전히 이전 문구가 반영되어 있는 것을 보셨을 것입니다. 파일만 변" +"경하면 파일에 대한 기존 링크가 모두 끊어지는데, 링크를 끊으면 검색 엔진 순위" +"에 영향을 줄 수 있으므로 이를 방지하는 것이 **매우 중요**합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:288 msgid "Here's how to change the file name:" @@ -1926,11 +1975,11 @@ msgstr "'doc/source/conf.py'에 리디렉션 규칙을 추가합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:293 msgid "" -"This will cause a redirect from ``saving-progress.html`` to ``save-" -"progress.html``, old links will continue to work." +"This will cause a redirect from ``saving-progress.html`` to ``save-progress." +"html``, old links will continue to work." msgstr "" -"이렇게 하면 ``saving-progress.html``에서 ``save-progress.html``로 " -"리디렉션되며, 이전 링크는 계속 작동합니다." +"이렇게 하면 ``saving-progress.html``에서 ``save-progress.html``로 리디렉션되" +"며, 이전 링크는 계속 작동합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:296 msgid "Apply changes in the index file" @@ -1942,8 +1991,8 @@ msgid "" "update the ``index.rst`` file as well. This is where we define the whole " "arborescence of the navbar." msgstr "" -"횡방향 내비게이션 바가 제대로 작동하려면 ``index.rst`` 파일도 업데이트하는 " -"것이 매우 중요합니다. 이 파일은 탐색 모음의 전체 배열을 정의하는 곳입니다." +"횡방향 내비게이션 바가 제대로 작동하려면 ``index.rst`` 파일도 업데이트하는 것" +"이 매우 중요합니다. 이 파일은 탐색 모음의 전체 배열을 정의하는 곳입니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:301 msgid "Find and modify the file name in ``index.rst``" @@ -1955,11 +2004,11 @@ msgstr "PR 열기" #: ../../source/contributor-tutorial-contribute-on-github.rst:306 msgid "" -"Commit the changes (commit messages are always imperative: \"Do " -"something\", in this case \"Change …\")" +"Commit the changes (commit messages are always imperative: \"Do something\", " +"in this case \"Change …\")" msgstr "" -"변경 사항을 커밋합니다(커밋 메시지는 항상 필수 메시지입니다:\"Do something\"(" -"이 경우 는 \"Change …\" )" +"변경 사항을 커밋합니다(커밋 메시지는 항상 필수 메시지입니다:\"Do " +"something\"(이 경우 는 \"Change …\" )" #: ../../source/contributor-tutorial-contribute-on-github.rst:307 msgid "Push the changes to your fork" @@ -1967,9 +2016,10 @@ msgstr "변경 사항을 포크에 푸시합니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:308 msgid "" -"Open a PR (as shown above) with title ``docs(framework) Update how-to " -"guide title``" -msgstr "``docs(framework) Update how-to guide title`` 제목으로 PR(위와 같이)을 엽니다" +"Open a PR (as shown above) with title ``docs(framework) Update how-to guide " +"title``" +msgstr "" +"``docs(framework) Update how-to guide title`` 제목으로 PR(위와 같이)을 엽니다" #: ../../source/contributor-tutorial-contribute-on-github.rst:309 msgid "Wait for it to be approved!" @@ -1990,18 +2040,17 @@ msgstr "다음 단계" #: ../../source/contributor-tutorial-contribute-on-github.rst:316 msgid "" -"Once you have made your first PR, and want to contribute more, be sure to" -" check out the following :" -msgstr "첫 번째 PR을 작성하고 더 많은 기여를 하고 싶다면 다음 을 확인하세요:" +"Once you have made your first PR, and want to contribute more, be sure to " +"check out the following :" +msgstr "첫 번째 PR을 작성하고 더 많은 기여를 하고 싶다면 다음을 확인하세요:" #: ../../source/contributor-tutorial-contribute-on-github.rst:318 msgid "" -":doc:`Good first contributions `, where you should particularly look into the " -":code:`baselines` contributions." +":doc:`Good first contributions `, " +"where you should particularly look into the :code:`baselines` contributions." msgstr "" -":doc:`훌륭한 첫 번째 기여 `, 특히 " -":code:`baselines` 기여를 살펴봐야 합니다." +":doc:`훌륭한 첫 번째 기여 `, 특히 :" +"code:`baselines` 기여를 살펴봐야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:322 #: ../../source/fed/0000-20200102-fed-template.md:60 @@ -2018,23 +2067,23 @@ msgstr "다음과 같은 PR 제목 형식을 적용합니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:335 msgid "" -"(or ``(:skip) `` to ignore the PR in the " -"changelog)" -msgstr "(또는 ``(:skip) ``를 사용하면 변경 로그에서 PR을 " -"무시합니다.)" +"(or ``(:skip) `` to ignore the PR in the changelog)" +msgstr "" +"(또는 ``(:skip) ``를 사용하면 변경 로그에서 PR을 무시" +"합니다.)" #: ../../source/contributor-tutorial-contribute-on-github.rst:337 msgid "" -"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, " -"break}``, ```` should be in ``{framework, baselines, datasets, " -"examples, or '*' when modifying multiple projects which requires the " -"':skip' flag to be used}``, and ```` starts with a capitalised " -"verb in the imperative mood." +"Where ```` needs to be in ``{ci, fix, feat, docs, refactor, break}``, " +"```` should be in ``{framework, baselines, datasets, examples, or " +"'*' when modifying multiple projects which requires the ':skip' flag to be " +"used}``, and ```` starts with a capitalised verb in the imperative " +"mood." msgstr "" "여기서 ````은 ``{ci, fix, feat, docs, refactor, break}``, ````" -"는 ``{framework, baselines, datasets, examples, or '*' ':skip' 플래그를 " -"사용해야 하는 여러 프로젝트를 수정하는 경우}``로 입력해야 하며, ````" -"는 대문자로 시작해야 합니다." +"는 ``{framework, baselines, datasets, examples, or '*' ':skip' 플래그를 사용" +"해야 하는 여러 프로젝트를 수정하는 경우}``로 입력해야 하며, ````는 " +"대문자로 시작해야 합니다." #: ../../source/contributor-tutorial-contribute-on-github.rst:341 msgid "Valid examples:" @@ -2054,7 +2103,7 @@ msgstr "``ci(*:skip) Enforce PR title format``" #: ../../source/contributor-tutorial-contribute-on-github.rst:347 msgid "Invalid examples:" -msgstr "잘못된 예제입니다:" +msgstr "잘못된 예시입니다:" #: ../../source/contributor-tutorial-contribute-on-github.rst:349 msgid "``feat(framework): Add flwr build CLI command`` (extra ``:``)" @@ -2064,7 +2113,8 @@ msgstr "``feat(framework): Add flwr build CLI command`` ( ``:``제외)" msgid "" "``feat(*) Add flwr build CLI command`` (missing ``skip`` flag along with " "``*``)" -msgstr "``feat(*) Add flwr build CLI command`` (``skip`` flag와 함께 ``*``누락)" +msgstr "" +"``feat(*) Add flwr build CLI command`` (``skip`` flag와 함께 ``*``누락)" #: ../../source/contributor-tutorial-contribute-on-github.rst:351 msgid "``feat(skip) Add flwr build CLI command`` (missing ````)" @@ -2072,7 +2122,8 @@ msgstr "``feat(skip) Add flwr build CLI command`` (````누락)" #: ../../source/contributor-tutorial-contribute-on-github.rst:352 msgid "``feat(framework) add flwr build CLI command`` (non capitalised verb)" -msgstr "``feat(framework) add flwr build CLI command`` (대문자로 표기되지 않은 동사)" +msgstr "" +"``feat(framework) add flwr build CLI command`` (대문자로 표기되지 않은 동사)" #: ../../source/contributor-tutorial-contribute-on-github.rst:353 msgid "``feat(framework) Add flwr build CLI command.`` (dot at the end)" @@ -2104,17 +2155,19 @@ msgid "(Optional) `pyenv `_" msgstr "(선택 사항) `pyenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:10 -msgid "(Optional) `pyenv-virtualenv `_" -msgstr "(선택 사항) `pyenv-virtualenv `_" +msgid "" +"(Optional) `pyenv-virtualenv `_" +msgstr "" +"(선택 사항) `pyenv-virtualenv `_" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:12 msgid "" "Flower uses :code:`pyproject.toml` to manage dependencies and configure " -"development tools (the ones which support it). Poetry is a build tool " -"which supports `PEP 517 `_." +"development tools (the ones which support it). Poetry is a build tool which " +"supports `PEP 517 `_." msgstr "" -"Flower는 dependencies을 관리하고 개발 도구(이를 지원하는 도구)를 구성하기 " -"위해 :code:`pyproject.toml`을 사용합니다. Poetry는 `PEP 517 `_을 지원하는 빌드 도구입니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:18 @@ -2127,7 +2180,7 @@ msgstr "사전 준비" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:22 msgid "Some system-wide dependencies are needed." -msgstr "일부 시스템 전체에 대한 dependencies이 필요합니다." +msgstr "일부 시스템 전체에 대한 의존성이 필요합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:25 msgid "For macOS" @@ -2135,17 +2188,18 @@ msgstr "macOS의 경우" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:27 msgid "" -"Install `homebrew `_. Don't forget the post-" -"installation actions to add `brew` to your PATH." +"Install `homebrew `_. Don't forget the post-installation " +"actions to add `brew` to your PATH." msgstr "" -"`homebrew `_를 설치합니다. 설치 후 `brew`를 PATH에 " -"추가하는 작업을 잊지 마세요." +"`homebrew `_를 설치합니다. 설치 후 `brew`를 PATH에 추가하" +"는 작업을 잊지 마세요." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:28 msgid "" -"Install `xz` (to install different Python versions) and `pandoc` to build" -" the docs::" -msgstr "xz`(다른 Python 버전을 설치하려면)와 `pandoc`을 설치하여 문서를 빌드합니다::" +"Install `xz` (to install different Python versions) and `pandoc` to build " +"the docs::" +msgstr "" +"xz`(다른 Python 버전을 설치하려면)와 `pandoc`을 설치하여 문서를 빌드합니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:34 msgid "For Ubuntu" @@ -2153,10 +2207,11 @@ msgstr "Ubuntu의 경우" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:35 msgid "" -"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all " -"necessary packages::" -msgstr "시스템(우분투 22.04 이상)이 최신 상태이고 필요한 패키지가 모두 설치되어 " -"있는지 확인하세요:" +"Ensure you system (Ubuntu 22.04+) is up-to-date, and you have all necessary " +"packages::" +msgstr "" +"시스템(우분투 22.04 이상)이 최신 상태이고 필요한 패키지가 모두 설치되어 있는" +"지 확인하세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:44 msgid "Create Flower Dev Environment" @@ -2167,27 +2222,27 @@ msgid "" "1. Clone the `Flower repository `_ from " "GitHub::" msgstr "" -"1. GitHub: 에서 ``Flower 레포지토리 `_를 " -"복제합니다::" +"1. GitHub: 에서 ``Flower 레포지토리 `_를 복제" +"합니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:52 msgid "" -"Let's create the Python environment for all-things Flower. If you wish to" -" use :code:`pyenv`, we provide two convenience scripts that you can use. " -"If you prefer using something else than :code:`pyenv`, create a new " +"Let's create the Python environment for all-things Flower. If you wish to " +"use :code:`pyenv`, we provide two convenience scripts that you can use. If " +"you prefer using something else than :code:`pyenv`, create a new " "environment, activate and skip to the last point where all packages are " "installed." msgstr "" -"Flower의 모든 것을 위한 파이썬 환경을 만들어 보겠습니다.:code:`pyenv`를 " -"사용하고자 하는 경우 사용할 수 있는 두 가지 편의 스크립트를 " -"제공합니다.:code:`pyenv`가 아닌 다른 것을 사용하려면 새 환경을 생성하고 " -"활성화한 후 모든 패키지가 설치된 마지막 지점으로 건너뛰세요." +"Flower의 모든 것을 위한 파이썬 환경을 만들어 보겠습니다.:code:`pyenv`를 사용" +"하고자 하는 경우 사용할 수 있는 두 가지 편의 스크립트를 제공합니다.:code:" +"`pyenv`가 아닌 다른 것을 사용하려면 새 환경을 생성하고 활성화한 후 모든 패키" +"지가 설치된 마지막 지점으로 건너뛰세요." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:54 msgid "" -"If you don't have :code:`pyenv` installed, the following script that will" -" install it, set it up, and create the virtual environment (with " -":code:`Python 3.8.17` by default)::" +"If you don't have :code:`pyenv` installed, the following script that will " +"install it, set it up, and create the virtual environment (with :code:" +"`Python 3.8.17` by default)::" msgstr "" ":code:`pyenv`가 설치되어 있지 않은 경우 다음 스크립트를 사용하여 설치, 설정 " "및 가상 환경을 생성합니다(기본적으로 :code:`Python 3.8.17` 사용):" @@ -2195,8 +2250,8 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:58 msgid "" "If you already have :code:`pyenv` installed (along with the :code:`pyenv-" -"virtualenv` plugin), you can use the following convenience script (with " -":code:`Python 3.8.17` by default)::" +"virtualenv` plugin), you can use the following convenience script (with :" +"code:`Python 3.8.17` by default)::" msgstr "" ":code:`pyenv`가 이미 설치되어 있는 경우( :code:`pyenv-virtualenv` 플러그인과 " "함께) 다음과 같은 편의 스크립트를 사용할 수 있습니다(기본적으로 코드:`Python " @@ -2204,11 +2259,11 @@ msgstr "" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:62 msgid "" -"3. Install the Flower package in development mode (think :code:`pip " -"install -e`) along with all necessary dependencies::" +"3. Install the Flower package in development mode (think :code:`pip install -" +"e`) along with all necessary dependencies::" msgstr "" -"3. 필요한 모든 dependencies와 함께 개발 모드에서 Flower 패키지를 " -"설치합니다(예:code:`pip install -e`)::" +"3. 필요한 모든 dependencies와 함께 개발 모드에서 Flower 패키지를 설치합니다" +"(예:code:`pip install -e`)::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:69 msgid "Convenience Scripts" @@ -2217,13 +2272,13 @@ msgstr "편의 스크립트" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:71 msgid "" "The Flower repository contains a number of convenience scripts to make " -"recurring development tasks easier and less error-prone. See the " -":code:`/dev` subdirectory for a full list. The following scripts are " -"amongst the most important ones:" +"recurring development tasks easier and less error-prone. See the :code:`/" +"dev` subdirectory for a full list. The following scripts are amongst the " +"most important ones:" msgstr "" -"Flower 레포지토리에는 반복적인 개발 작업을 더 쉽고 오류를 줄이기 위한 여러 " -"가지 편의 스크립트가 포함되어 있습니다. 전체 목록은 :code:`/dev` 하위 " -"디렉터리를 참조하세요. 다음 스크립트는 가장 중요한 스크립트 중 하나입니다:" +"Flower 레포지토리에는 반복적인 개발 작업을 더 쉽고 오류를 줄이기 위한 여러 가" +"지 편의 스크립트가 포함되어 있습니다. 전체 목록은 :code:`/dev` 하위 디렉터리" +"를 참조하세요. 다음 스크립트는 가장 중요한 스크립트 중 하나입니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:77 msgid "Create/Delete Virtual Environment" @@ -2247,50 +2302,53 @@ msgstr "사전 커밋 훅 추가" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:108 msgid "" -"Developers may integrate a pre-commit hook into their workflow utilizing " -"the `pre-commit `_ library. The pre-" -"commit hook is configured to execute two primary operations: " -"``./dev/format.sh`` and ``./dev/test.sh`` scripts." +"Developers may integrate a pre-commit hook into their workflow utilizing the " +"`pre-commit `_ library. The pre-commit hook " +"is configured to execute two primary operations: ``./dev/format.sh`` and ``./" +"dev/test.sh`` scripts." msgstr "" -"개발자는 `pre-commit `_ 라이브러리를 " -"사용하여 사전 커밋 훅을 워크플로에 통합할 수 있습니다. 사전 커밋 훅은 두 " -"가지 기본 작업을 실행하도록 구성됩니다:``./dev/format.sh`` 및 ``./dev/test." -"sh`` 스크립트." +"개발자는 `pre-commit `_ 라이브러리를 사용하" +"여 사전 커밋 훅을 워크플로에 통합할 수 있습니다. 사전 커밋 훅은 두 가지 기본 " +"작업을 실행하도록 구성됩니다:``./dev/format.sh`` 및 ``./dev/test.sh`` 스크립" +"트." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:110 msgid "There are multiple ways developers can use this:" msgstr "개발자가 이것을 사용할 수 있는 여러가지 방법이 있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:112 -msgid "Install the pre-commit hook to your local git directory by simply running:" +msgid "" +"Install the pre-commit hook to your local git directory by simply running:" msgstr "간단하게 실행하여 로컬 git 디렉터리에 사전 커밋 훅을 설치하세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:118 msgid "" -"Each ``git commit`` will trigger the execution of formatting and " -"linting/test scripts." +"Each ``git commit`` will trigger the execution of formatting and linting/" +"test scripts." msgstr "각 ``git 커밋``은 포맷 및 린팅/테스트 스크립트의 실행을 트리거합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:119 msgid "" -"If in a hurry, bypass the hook using ``--no-verify`` with the ``git " -"commit`` command. ::" -msgstr "급한 경우 ``git commit`` 명령과 함께 `--no-verify``를 사용하여 훅을 넘기세요:" +"If in a hurry, bypass the hook using ``--no-verify`` with the ``git commit`` " +"command. ::" +msgstr "" +"급한 경우 ``git commit`` 명령과 함께 `--no-verify``를 사용하여 훅을 넘기세요:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:124 msgid "" "For developers who prefer not to install the hook permanently, it is " -"possible to execute a one-time check prior to committing changes by using" -" the following command:" +"possible to execute a one-time check prior to committing changes by using " +"the following command:" msgstr "" -"훅을 영구적으로 설치하지 않으려는 개발자의 경우 다음 명령을 사용하여 변경 " -"사항을 커밋하기 전에 일회성 검사를 실행할 수 있습니다:" +"훅을 영구적으로 설치하지 않으려는 개발자의 경우 다음 명령을 사용하여 변경 사" +"항을 커밋하기 전에 일회성 검사를 실행할 수 있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:130 msgid "" "This executes the formatting and linting checks/tests on all the files " "without modifying the default behavior of ``git commit``." -msgstr "이렇게 하면 ``git commit``의 기본 동작을 수정하지 않고 모든 파일에 대해 포맷 " +msgstr "" +"이렇게 하면 ``git commit``의 기본 동작을 수정하지 않고 모든 파일에 대해 포맷 " "및 린팅 검사/테스트를 실행합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:133 @@ -2299,21 +2357,22 @@ msgstr "로컬에서 Github Action(CI) 실행하기" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:135 msgid "" -"Developers could run the full set of Github Actions workflows under their" -" local environment by using `Act `_. " -"Please refer to the installation instructions under the linked repository" -" and run the next command under Flower main cloned repository folder::" +"Developers could run the full set of Github Actions workflows under their " +"local environment by using `Act `_. Please " +"refer to the installation instructions under the linked repository and run " +"the next command under Flower main cloned repository folder::" msgstr "" -"개발자는 `Act `_를 사용하여 로컬 환경에서 " -"전체 Github Actions 워크플로우 세트를 실행할 수 있습니다. 링크된 레포지토리 " -"아래의 설치 지침을 참조하여 Flower 메인 클론 레포지토리 폴더 아래에서 다음 " -"명령을 실행하세요::" +"개발자는 `Act `_를 사용하여 로컬 환경에서 전" +"체 Github Actions 워크플로우 세트를 실행할 수 있습니다. 링크된 레포지토리 아" +"래의 설치 지침을 참조하여 Flower 메인 클론 레포지토리 폴더 아래에서 다음 명령" +"을 실행하세요::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:142 msgid "" "The Flower default workflow would run by setting up the required Docker " "machines underneath." -msgstr "Flower 기본 워크플로우는 아래에 필요한 Docker 머신을 설정하여 실행합니다." +msgstr "" +"Flower 기본 워크플로우는 아래에 필요한 Docker 머신을 설정하여 실행합니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:147 msgid "Build Release" @@ -2321,17 +2380,19 @@ msgstr "릴리즈 빌드" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:149 msgid "" -"Flower uses Poetry to build releases. The necessary command is wrapped in" -" a simple script::" -msgstr "Flower는 Poetry를 사용하여 릴리즈를 빌드합니다. 필요한 명령은 간단한 " -"스크립트로 래핑됩니다::" +"Flower uses Poetry to build releases. The necessary command is wrapped in a " +"simple script::" +msgstr "" +"Flower는 Poetry를 사용하여 릴리즈를 빌드합니다. 필요한 명령은 간단한 스크립트" +"로 래핑됩니다::" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:154 msgid "" -"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in" -" the :code:`/dist` subdirectory." -msgstr "결과물인 :code:`.whl` 및 :code:`.tar.gz` 릴리즈는 :code:`/dist` 하위 " -"디렉터리에 저장됩니다." +"The resulting :code:`.whl` and :code:`.tar.gz` releases will be stored in " +"the :code:`/dist` subdirectory." +msgstr "" +"결과물인 :code:`.whl` 및 :code:`.tar.gz` 릴리즈는 :code:`/dist` 하위 디렉터리" +"에 저장됩니다." #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:159 msgid "Build Documentation" @@ -2339,13 +2400,13 @@ msgstr "문서 빌드" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:161 msgid "" -"Flower's documentation uses `Sphinx `_. " -"There's no convenience script to re-build the documentation yet, but it's" -" pretty easy::" +"Flower's documentation uses `Sphinx `_. There's " +"no convenience script to re-build the documentation yet, but it's pretty " +"easy::" msgstr "" -"Flower의 문서는 `Sphinx `_를 사용합니다. 아직 " -"문서를 다시 작성할 수 있는 편리한 스크립트는 없지만 다음과 같이 쉽게 작성할 " -"수 있습니다:" +"Flower의 문서는 `Sphinx `_를 사용합니다. 아직 문" +"서를 다시 작성할 수 있는 편리한 스크립트는 없지만 다음과 같이 쉽게 작성할 수 " +"있습니다:" #: ../../source/contributor-tutorial-get-started-as-a-contributor.rst:167 msgid "This will generate HTML documentation in ``doc/build/html``." @@ -2353,40 +2414,39 @@ msgstr "그러면 ``doc/build/html``에 HTML 문서가 생성됩니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:2 msgid "Example: FedBN in PyTorch - From Centralized To Federated" -msgstr "예시: PyTorch에서 FedBN - Centralize에서 Federated으로" +msgstr "예시: PyTorch에서 FedBN - 중앙 집중식에서 연합식으로" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload with `FedBN " -"`_, a federated training strategy " -"designed for non-iid data. We are using PyTorch to train a Convolutional " -"Neural Network(with Batch Normalization layers) on the CIFAR-10 dataset. " -"When applying FedBN, only few changes needed compared to :doc:`Example: " -"PyTorch - From Centralized To Federated `." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload with `FedBN `_, a federated training strategy designed for non-iid data. We " +"are using PyTorch to train a Convolutional Neural Network(with Batch " +"Normalization layers) on the CIFAR-10 dataset. When applying FedBN, only few " +"changes needed compared to :doc:`Example: PyTorch - From Centralized To " +"Federated `." msgstr "" "이 튜토리얼에서는 non-iid data를 위해 설계된 federated 훈련 전략인 `FedBN " "`_으로 기존 머신러닝 워크로드의 federated " "버전을 구축하기 위해 Flower를 사용하는 방법을 보여드립니다. 우리는 PyTorch를 " "사용하여 CIFAR-10 데이터 세트에서 컨볼루션 신경망(일괄 정규화 레이어 포함)을 " -"훈련하고 있습니다. FedBN을 적용할 때, :doc:`예제: 파이토치 -Centralized에서 " -"Federated으로 ` 와 비교했을 " -"때 몇 가지 사항만 변경 하면 됩니다." +"훈련하고 있습니다. FedBN을 적용할 때, :doc:`예제: 파이토치 -중앙 집중식에서 " +"연합식으로 ` 와 비교했을 때 " +"몇 가지 사항만 변경 하면 됩니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:9 #: ../../source/example-pytorch-from-centralized-to-federated.rst:10 msgid "Centralized Training" -msgstr "Centralized 훈련" +msgstr "중앙 집중식 훈련" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:10 msgid "" -"All files are revised based on :doc:`Example: PyTorch - From Centralized " -"To Federated `. The only " -"thing to do is modifying the file called :code:`cifar.py`, revised part " -"is shown below:" +"All files are revised based on :doc:`Example: PyTorch - From Centralized To " +"Federated `. The only thing " +"to do is modifying the file called :code:`cifar.py`, revised part is shown " +"below:" msgstr "" -"모든 파일은 :doc:`예제: 파이토치 - Centralized에서 Federated으로 `를 기반으로 수정합니다. :code:`cifar." "py`라는 파일을 수정하기만 하면 되며, 수정된 부분은 아래와 같습니다:" @@ -2394,8 +2454,9 @@ msgstr "" msgid "" "The model architecture defined in class Net() is added with Batch " "Normalization layers accordingly." -msgstr "Net() 클래스에 정의된 모델 아키텍처는 그에 따라 배치 정규화 레이어가 " -"추가됩니다." +msgstr "" +"Net() 클래스에 정의된 모델 아키텍처는 그에 따라 배치 정규화 레이어가 추가됩니" +"다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:41 #: ../../source/example-pytorch-from-centralized-to-federated.rst:157 @@ -2404,56 +2465,55 @@ msgstr "이제 머신 러닝 워크로드를 실행할 수 있습니다:" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:47 msgid "" -"So far this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"federated learning system within FedBN, the system consists of one server" -" and two clients." +"So far this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a federated " +"learning system within FedBN, the system consists of one server and two " +"clients." msgstr "" "지금까지는 파이토치를 사용해 본 적이 있다면 상당히 익숙하게 보일 것입니다. " "다음 단계로 넘어가서 우리가 구축한 것을 사용하여 FedBN 내에서 하나의 서버와 " -"두 개의 클라이언트로 구성된 federated 학습 시스템을 만들어 보겠습니다." +"두 개의 클라이언트로 구성된 연합학습 시스템을 만들어 보겠습니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:51 #: ../../source/example-pytorch-from-centralized-to-federated.rst:167 msgid "Federated Training" -msgstr "Federated 훈련" +msgstr "연합 훈련" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:53 msgid "" "If you have read :doc:`Example: PyTorch - From Centralized To Federated " -"`, the following parts are" -" easy to follow, only :code:`get_parameters` and :code:`set_parameters` " -"function in :code:`client.py` needed to revise. If not, please read the " -":doc:`Example: PyTorch - From Centralized To Federated `. first." +"`, the following parts are " +"easy to follow, only :code:`get_parameters` and :code:`set_parameters` " +"function in :code:`client.py` needed to revise. If not, please read the :doc:" +"`Example: PyTorch - From Centralized To Federated `. first." msgstr "" -":doc:`예제: 파이토치 - Centralized에서 Federated으로 `를 읽었다면, 다음 부분은 쉽게 따라할 수 있으며 " ":code:`client.py`의 :code:`get_parameters`와 :code:`set_parameters` 함수만 " -"수정해야 합니다. 그렇지 않은 경우 :doc:`예제: 파이토치 - Centralized에서 " -"Federated으로 `를 먼저 " +"수정해야 합니다. 그렇지 않은 경우 :doc:`예제: 파이토치 - 중앙 집중식에서 " +"연합식으로 `를 먼저 " "읽어보세요." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:56 msgid "" -"Our example consists of one *server* and two *clients*. In FedBN, " -":code:`server.py` keeps unchanged, we can start the server directly." +"Our example consists of one *server* and two *clients*. In FedBN, :code:" +"`server.py` keeps unchanged, we can start the server directly." msgstr "" -"이 예제는 하나의 *서버*와 두 개의 *클라이언트*로 구성됩니다. FedBN에서 " -":code:`server.py`는 변경되지 않고 그대로 유지되므로 서버를 바로 시작할 수 " -"있습니다." +"이 예제는 하나의 *서버*와 두 개의 *클라이언트*로 구성됩니다. FedBN에서 :code:" +"`server.py`는 변경되지 않고 그대로 유지되므로 서버를 바로 시작할 수 있습니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:62 msgid "" -"Finally, we will revise our *client* logic by changing " -":code:`get_parameters` and :code:`set_parameters` in :code:`client.py`, " -"we will exclude batch normalization parameters from model parameter list " -"when sending to or receiving from the server." +"Finally, we will revise our *client* logic by changing :code:" +"`get_parameters` and :code:`set_parameters` in :code:`client.py`, we will " +"exclude batch normalization parameters from model parameter list when " +"sending to or receiving from the server." msgstr "" -"마지막으로, :code:`client.py`에서 :code:`get_parameters` 및 " -":code:`set_parameters`를 변경하여 *client* 로직을 수정할 것입니다. 서버로 " -"보내거나 서버에서 받을 때 모델 파라미터 목록에서 배치 정규화 파라미터를 " -"제외할 수 있습니다." +"마지막으로, :code:`client.py`에서 :code:`get_parameters` 및 :code:" +"`set_parameters`를 변경하여 *client* 로직을 수정할 것입니다. 서버로 보내거나 " +"서버에서 받을 때 모델 파라미터 목록에서 배치 정규화 파라미터를 제외할 수 있습" +"니다." #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:85 msgid "Now, you can now open two additional terminal windows and run" @@ -2461,13 +2521,13 @@ msgstr "이제 두 개의 터미널 창을 추가로 열고 다음을 실행할 #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:91 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your (previously centralized) PyTorch project run federated " -"learning with FedBN strategy across two clients. Congratulations!" +"in each window (make sure that the server is still running before you do so) " +"and see your (previously centralized) PyTorch project run federated learning " +"with FedBN strategy across two clients. Congratulations!" msgstr "" -"를 입력하고(클릭하기 전에 서버가 계속 실행 중인지 확인하세요), (이전에 " -"centralized된) PyTorch 프로젝트가 두 클라이언트에서 FedBN으로 federated " -"학습을 실행하는 것을 확인합니다. 축하합니다!" +"를 입력하고(클릭하기 전에 서버가 계속 실행 중인지 확인하세요), (이전에 중앙 " +"집중된) PyTorch 프로젝트가 두 클라이언트에서 FedBN으로 연합 학습을 실행하는 " +"것을 확인합니다. 축하합니다!" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:94 #: ../../source/example-jax-from-centralized-to-federated.rst:277 @@ -2478,20 +2538,19 @@ msgstr "다음 단계" #: ../../source/example-fedbn-pytorch-from-centralized-to-federated.rst:96 msgid "" -"The full source code for this example can be found `here " -"`_. Our example is of course somewhat over-" -"simplified because both clients load the exact same dataset, which isn't " -"realistic. You're now prepared to explore this topic further. How about " -"using different subsets of CIFAR-10 on each client? How about adding more" -" clients?" +"The full source code for this example can be found `here `_. Our " +"example is of course somewhat over-simplified because both clients load the " +"exact same dataset, which isn't realistic. You're now prepared to explore " +"this topic further. How about using different subsets of CIFAR-10 on each " +"client? How about adding more clients?" msgstr "" "이 예제의 전체 소스 코드는 '여기 `_'에서 확인할 수 있습니다. " -"물론 이 예제는 두 클라이언트가 완전히 동일한 데이터 세트를 로드하기 때문에 " -"다소 지나치게 단순화되어 있으며, 이는 현실적이지 않습니다. 이제 이 주제를 더 " -"자세히 살펴볼 준비가 되셨습니다. 각 클라이언트에서 서로 다른 CIFAR-10의 하위 " -"집합을 사용해 보는 것은 어떨까요? 클라이언트를 더 추가하는 것은 어떨까요?" +"examples/pytorch-from-centralized-to-federated>`_'에서 확인할 수 있습니다. 물" +"론 이 예제는 두 클라이언트가 완전히 동일한 데이터 세트를 로드하기 때문에 다" +"소 지나치게 단순화되어 있으며, 이는 현실적이지 않습니다. 이제 이 주제를 더 자" +"세히 살펴볼 준비가 되셨습니다. 각 클라이언트에서 서로 다른 CIFAR-10의 하위 집" +"합을 사용해 보는 것은 어떨까요? 클라이언트를 더 추가하는 것은 어떨까요?" #: ../../source/example-jax-from-centralized-to-federated.rst:2 msgid "Example: JAX - Run JAX Federated" @@ -2500,32 +2559,31 @@ msgstr "예시: JAX - JAX Federated 실행" #: ../../source/example-jax-from-centralized-to-federated.rst:4 #: ../../source/tutorial-quickstart-jax.rst:10 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing JAX workload. We are using JAX to train a linear " -"regression model on a scikit-learn dataset. We will structure the example" -" similar to our `PyTorch - From Centralized To Federated " -"`_ walkthrough. First, we build a centralized " -"training approach based on the `Linear Regression with JAX " -"`_" -" tutorial`. Then, we build upon the centralized training code to run the " -"training in a federated fashion." -msgstr "" -"이 튜토리얼에서는 Flower를 사용하여 기존 JAX 워크로드의 federated 버전을 " -"구축하는 방법을 보여드립니다. JAX를 사용해 scikit-learn 데이터 세트에서 선형 " -"회귀 모델을 훈련하고 있습니다. 예제는 '파이토치 - Centralized에서 " -"Federated으로 `_ 워크스루와 유사하게 구성하겠습니다. 먼저, `" -"JAX를 사용한 선형 회귀 `_ 튜토리얼`을 기반으로 centralized 학습 접근 " -"방식을 구축합니다. 그런 다음 centralized 트레이닝 코드를 기반으로 federated " -"방식으로 트레이닝을 실행합니다." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing JAX workload. We are using JAX to train a linear regression " +"model on a scikit-learn dataset. We will structure the example similar to " +"our `PyTorch - From Centralized To Federated `_ walkthrough. " +"First, we build a centralized training approach based on the `Linear " +"Regression with JAX `_ tutorial`. Then, we build upon the centralized " +"training code to run the training in a federated fashion." +msgstr "" +"이 튜토리얼에서는 Flower를 사용하여 기존 JAX 워크로드의 연합 버전을 구축하는 " +"방법을 보여드립니다. JAX를 사용해 scikit-learn 데이터 세트에서 선형 회귀 " +"모델을 훈련하고 있습니다. 예제는 '파이토치 - Centralized에서 Federated으로 " +"`_ 워크스루와 유사하게 구성하겠습니다. 먼저, `JAX를 사용한 선형 " +"회귀 `_ 튜토리얼`을 기반으로 centralized 학습 접근 방식을 구축합니다. 그런 " +"다음 centralized 트레이닝 코드를 기반으로 federated 방식으로 트레이닝을 " +"실행합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:10 #: ../../source/tutorial-quickstart-jax.rst:16 msgid "" -"Before we start building our JAX example, we need install the packages " -":code:`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" +"Before we start building our JAX example, we need install the packages :code:" +"`jax`, :code:`jaxlib`, :code:`scikit-learn`, and :code:`flwr`:" msgstr "" "JAX 예제 빌드를 시작하기 전에 :code:`jax`, :code:`jaxlib`, :code:`scikit-" "learn`, :code:`flwr` 패키지를 설치해야 합니다:" @@ -2538,12 +2596,12 @@ msgstr "JAX를 사용한 선형 회귀" #: ../../source/example-jax-from-centralized-to-federated.rst:20 #: ../../source/tutorial-quickstart-jax.rst:26 msgid "" -"We begin with a brief description of the centralized training code based " -"on a :code:`Linear Regression` model. If you want a more in-depth " -"explanation of what's going on then have a look at the official `JAX " -"documentation `_." +"We begin with a brief description of the centralized training code based on " +"a :code:`Linear Regression` model. If you want a more in-depth explanation " +"of what's going on then have a look at the official `JAX documentation " +"`_." msgstr "" -"먼저 :code:`선형 회귀` 모델을 기반으로 하는 centralized 훈련 코드에 대한 " +"먼저 :code:`선형 회귀` 모델을 기반으로 하는 중앙 집중식 훈련 코드에 대한 " "간략한 설명부터 시작하겠습니다. 더 자세한 설명을 원하시면 공식 `JAX 문서 " "`_를 참조하세요." @@ -2552,14 +2610,13 @@ msgstr "" msgid "" "Let's create a new file called :code:`jax_training.py` with all the " "components required for a traditional (centralized) linear regression " -"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to " -"be imported. In addition, we need to import :code:`sklearn` since we use " -":code:`make_regression` for the dataset and :code:`train_test_split` to " -"split the dataset into a training and test set. You can see that we do " -"not yet import the :code:`flwr` package for federated learning. This will" -" be done later." -msgstr "" -"전통적인(centralized) 선형 회귀 훈련에 필요한 모든 구성 요소가 포함된 " +"training. First, the JAX packages :code:`jax` and :code:`jaxlib` need to be " +"imported. In addition, we need to import :code:`sklearn` since we use :code:" +"`make_regression` for the dataset and :code:`train_test_split` to split the " +"dataset into a training and test set. You can see that we do not yet import " +"the :code:`flwr` package for federated learning. This will be done later." +msgstr "" +"전통적인(중앙 집중식) 선형 회귀 훈련에 필요한 모든 구성 요소가 포함된 " ":code:`jax_training.py`라는 새 파일을 생성해 보겠습니다. 먼저, JAX 패키지인 " ":code:`jax`와 :code:`jaxlib`를 가져와야 합니다. 또한 데이터 세트에 " ":code:`make_regression`을 사용하고 데이터 세트를 학습 및 테스트 세트로 " @@ -2570,38 +2627,39 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:37 #: ../../source/tutorial-quickstart-jax.rst:43 msgid "" -"The :code:`load_data()` function loads the mentioned training and test " -"sets." -msgstr "code:`load_data()` 함수는 앞서 언급한 트레이닝 및 테스트 세트를 로드합니다." +"The :code:`load_data()` function loads the mentioned training and test sets." +msgstr "" +"code:`load_data()` 함수는 앞서 언급한 트레이닝 및 테스트 세트를 로드합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:47 #: ../../source/tutorial-quickstart-jax.rst:53 msgid "" -"The model architecture (a very simple :code:`Linear Regression` model) is" -" defined in :code:`load_model()`." -msgstr "모델 아키텍처(매우 간단한 :code:`선형 회귀` 모델)는 :code:`load_model()`에 " -"정의되어 있습니다." +"The model architecture (a very simple :code:`Linear Regression` model) is " +"defined in :code:`load_model()`." +msgstr "" +"모델 아키텍처(매우 간단한 :code:`선형 회귀` 모델)는 :code:`load_model()`에 정" +"의되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:59 #: ../../source/tutorial-quickstart-jax.rst:65 msgid "" -"We now need to define the training (function :code:`train()`), which " -"loops over the training set and measures the loss (function " -":code:`loss_fn()`) for each batch of training examples. The loss function" -" is separate since JAX takes derivatives with a :code:`grad()` function " -"(defined in the :code:`main()` function and called in :code:`train()`)." +"We now need to define the training (function :code:`train()`), which loops " +"over the training set and measures the loss (function :code:`loss_fn()`) for " +"each batch of training examples. The loss function is separate since JAX " +"takes derivatives with a :code:`grad()` function (defined in the :code:" +"`main()` function and called in :code:`train()`)." msgstr "" -"이제 훈련 집합을 반복하고 각 훈련 예제 배치에 대해 손실을 측정하는(함수 " -":code:`loss_fn()`) 훈련(함수 :code:`train()`)을 정의해야 합니다. JAX는 " -":code:`grad()` 함수(:code:`main()` 함수에 정의되고 :code:`train()`에서 " -"호출됨)로 파생물을 취하므로 손실 함수는 분리되어 있습니다." +"이제 훈련 집합을 반복하고 각 훈련 예제 배치에 대해 손실을 측정하는(함수 :" +"code:`loss_fn()`) 훈련(함수 :code:`train()`)을 정의해야 합니다. JAX는 :code:" +"`grad()` 함수(:code:`main()` 함수에 정의되고 :code:`train()`에서 호출됨)로 파" +"생물을 취하므로 손실 함수는 분리되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:77 #: ../../source/tutorial-quickstart-jax.rst:83 msgid "" -"The evaluation of the model is defined in the function " -":code:`evaluation()`. The function takes all test examples and measures " -"the loss of the linear regression model." +"The evaluation of the model is defined in the function :code:`evaluation()`. " +"The function takes all test examples and measures the loss of the linear " +"regression model." msgstr "" "모델의 평가는 :code:`evaluation()` 함수에 정의되어 있습니다. 이 함수는 모든 " "테스트 예제를 가져와 선형 회귀 모델의 손실을 측정합니다." @@ -2610,29 +2668,29 @@ msgstr "" #: ../../source/tutorial-quickstart-jax.rst:94 msgid "" "Having defined the data loading, model architecture, training, and " -"evaluation we can put everything together and train our model using JAX. " -"As already mentioned, the :code:`jax.grad()` function is defined in " -":code:`main()` and passed to :code:`train()`." +"evaluation we can put everything together and train our model using JAX. As " +"already mentioned, the :code:`jax.grad()` function is defined in :code:" +"`main()` and passed to :code:`train()`." msgstr "" -"데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으므로 이제 모든 것을 " -"종합하여 JAX를 사용 모델을 훈련할 수 있습니다. 이미 언급했듯이 :code:`jax." -"grad()` 함수는 :code:`main()`에 정의되어 :code:`train()`에 전달됩니다." +"데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으므로 이제 모든 것을 종합하" +"여 JAX를 사용 모델을 훈련할 수 있습니다. 이미 언급했듯이 :code:`jax.grad()` " +"함수는 :code:`main()`에 정의되어 :code:`train()`에 전달됩니다." #: ../../source/example-jax-from-centralized-to-federated.rst:105 #: ../../source/tutorial-quickstart-jax.rst:111 msgid "You can now run your (centralized) JAX linear regression workload:" -msgstr "이제 (centralized) JAX 선형 회귀 워크로드를 실행할 수 있습니다:" +msgstr "이제 (중앙 집중식) JAX 선형 회귀 워크로드를 실행할 수 있습니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:111 #: ../../source/tutorial-quickstart-jax.rst:117 msgid "" -"So far this should all look fairly familiar if you've used JAX before. " -"Let's take the next step and use what we've built to create a simple " -"federated learning system consisting of one server and two clients." +"So far this should all look fairly familiar if you've used JAX before. Let's " +"take the next step and use what we've built to create a simple federated " +"learning system consisting of one server and two clients." msgstr "" -"지금까지는 JAX를 사용해 본 적이 있다면 이 모든 것이 상당히 익숙해 보일 " -"것입니다. 다음 단계로 넘어가서 우리가 구축한 것을 사용하여 하나의 서버와 두 " -"개의 클라이언트로 구성된 간단한 연합 학습 시스템을 만들어 보겠습니다." +"지금까지는 JAX를 사용해 본 적이 있다면 이 모든 것이 상당히 익숙해 보일 것입니" +"다. 다음 단계로 넘어가서 우리가 구축한 것을 사용하여 하나의 서버와 두 개의 클" +"라이언트로 구성된 간단한 연합 학습 시스템을 만들어 보겠습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:115 #: ../../source/tutorial-quickstart-jax.rst:121 @@ -2642,36 +2700,36 @@ msgstr "JAX와 Flower의 만남" #: ../../source/example-jax-from-centralized-to-federated.rst:117 #: ../../source/tutorial-quickstart-jax.rst:123 msgid "" -"The concept of federating an existing workload is always the same and " -"easy to understand. We have to start a *server* and then use the code in " -":code:`jax_training.py` for the *clients* that are connected to the " -"*server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server*, which averages all received " -"parameter updates. This describes one round of the federated learning " -"process, and we repeat this for multiple rounds." -msgstr "" -"기존 워크로드를 federating하는 개념은 항상 동일하고 이해하기 쉽습니다. 서버*" -"를 시작한 다음 *서버*에 연결된 *클라이언트*에 대해 :code:`jax_training.py`의 " +"The concept of federating an existing workload is always the same and easy " +"to understand. We have to start a *server* and then use the code in :code:" +"`jax_training.py` for the *clients* that are connected to the *server*. The " +"*server* sends model parameters to the clients. The *clients* run the " +"training and update the parameters. The updated parameters are sent back to " +"the *server*, which averages all received parameter updates. This describes " +"one round of the federated learning process, and we repeat this for multiple " +"rounds." +msgstr "" +"기존 워크로드를 연합하는 개념은 항상 동일하고 이해하기 쉽습니다. 서버*를 " +"시작한 다음 *서버*에 연결된 *클라이언트*에 대해 :code:`jax_training.py`의 " "코드를 사용해야 합니다. *서버*는 모델 파라미터를 클라이언트로 전송합니다. " "클라이언트는 학습을 실행하고 파라미터를 업데이트합니다. 업데이트된 " "파라미터는 *서버*로 다시 전송되며, 수신된 모든 파라미터 업데이트의 평균을 " -"구합니다. 이는 federated 학습 프로세스의 한 라운드를 설명하며, 이 과정을 " -"여러 라운드에 걸쳐 반복합니다." +"구합니다. 이는 연합 학습 프로세스의 한 라운드를 설명하며, 이 과정을 여러 " +"라운드에 걸쳐 반복합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:123 #: ../../source/example-pytorch-from-centralized-to-federated.rst:181 #: ../../source/tutorial-quickstart-jax.rst:129 msgid "" -"Our example consists of one *server* and two *clients*. Let's set up " -":code:`server.py` first. The *server* needs to import the Flower package " -":code:`flwr`. Next, we use the :code:`start_server` function to start a " -"server and tell it to perform three rounds of federated learning." +"Our example consists of one *server* and two *clients*. Let's set up :code:" +"`server.py` first. The *server* needs to import the Flower package :code:" +"`flwr`. Next, we use the :code:`start_server` function to start a server and " +"tell it to perform three rounds of federated learning." msgstr "" "이 예제는 하나의 *서버*와 두 개의 *클라이언트*로 구성됩니다. 먼저 " ":code:`server.py`를 설정해 보겠습니다. *server*는 Flower 패키지 :code:`flwr`" "를 가져와야 합니다. 다음으로, :code:`start_server` 함수를 사용하여 서버를 " -"시작하고 세 차례의 federated 학습을 수행하도록 지시합니다." +"시작하고 세 차례의 연합 학습을 수행하도록 지시합니다." #: ../../source/example-jax-from-centralized-to-federated.rst:133 #: ../../source/example-pytorch-from-centralized-to-federated.rst:191 @@ -2682,39 +2740,38 @@ msgstr "이미 *서버*를 시작할 수 있습니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:139 #: ../../source/tutorial-quickstart-jax.rst:145 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined JAX training in :code:`jax_training.py`. Our" -" *client* needs to import :code:`flwr`, but also :code:`jax` and " -":code:`jaxlib` to update the parameters on our JAX model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined JAX training in :code:`jax_training.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`jax` and :code:" +"`jaxlib` to update the parameters on our JAX model:" msgstr "" -"마지막으로, :code:`client.py`에서 *client* 로직을 정의하고 " -":code:`jax_training.py`에서 이전에 정의한 JAX 교육을 기반으로 빌드합니다. " -"*클라이언트*는 :code:`flwr`을 가져와야 하며, JAX 모델의 파라미터를 " -"업데이트하기 위해 :code:`jax` 및 :code:`jaxlib`도 가져와야 합니다:" +"마지막으로, :code:`client.py`에서 *client* 로직을 정의하고 :code:" +"`jax_training.py`에서 이전에 정의한 JAX 교육을 기반으로 빌드합니다. *클라이언" +"트*는 :code:`flwr`을 가져와야 하며, JAX 모델의 파라미터를 업데이트하기 위해 :" +"code:`jax` 및 :code:`jaxlib`도 가져와야 합니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:154 #: ../../source/tutorial-quickstart-jax.rst:160 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`FlowerClient`. :code:`NumPyClient` is slightly " -"easier to implement than :code:`Client` if you use a framework with good " -"NumPy interoperability (like JAX) because it avoids some of the " -"boilerplate that would otherwise be necessary. :code:`FlowerClient` needs" -" to implement four methods, two methods for getting/setting model " -"parameters, one method for training the model, and one method for testing" -" the model:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`FlowerClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like JAX) because it avoids some of the boilerplate that " +"would otherwise be necessary. :code:`FlowerClient` needs to implement four " +"methods, two methods for getting/setting model parameters, one method for " +"training the model, and one method for testing the model:" msgstr "" "Flower *클라이언트*를 구현한다는 것은 기본적으로 :code:`flwr.client.Client` " -"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 " -"의미합니다. 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, 이를 " -":code:`FlowerClient`라고 부를 것입니다. :code:`NumPyClient`는 필요한 일부 " -"보일러플레이를 피할 수 있기 때문에 NumPy 상호 운용성이 좋은 프레임워크(예: " -"JAX)를 사용하는 경우 :code:`Client`보다 구현하기가 약간 더 쉽습니다. " -"code:`FlowerClient`는 모델 매개변수를 가져오거나 설정하는 메서드 2개, 모델 " -"학습을 위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 총 4개의 메서드를 " -"구현해야 합니다:" +"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 의미합니" +"다. 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, 이를 :code:" +"`FlowerClient`라고 부를 것입니다. :code:`NumPyClient`는 필요한 일부 보일러플" +"레이를 피할 수 있기 때문에 NumPy 상호 운용성이 좋은 프레임워크(예: JAX)를 사" +"용하는 경우 :code:`Client`보다 구현하기가 약간 더 쉽습니다. code:" +"`FlowerClient`는 모델 매개변수를 가져오거나 설정하는 메서드 2개, 모델 학습을 " +"위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 총 4개의 메서드를 구현해야 " +"합니다:" #: ../../source/example-jax-from-centralized-to-federated.rst:161 #: ../../source/tutorial-quickstart-jax.rst:167 @@ -2725,8 +2782,7 @@ msgstr ":code:`set_parameters (선택사항)`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 #: ../../source/tutorial-quickstart-jax.rst:166 msgid "" -"set the model parameters on the local model that are received from the " -"server" +"set the model parameters on the local model that are received from the server" msgstr "서버에서 수신한 로컬 모델의 모델 파라미터를 설정합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:161 @@ -2738,10 +2794,11 @@ msgstr "매개 변수를 NumPy :code:`ndarray`로 변환" #: ../../source/example-pytorch-from-centralized-to-federated.rst:220 #: ../../source/tutorial-quickstart-jax.rst:168 msgid "" -"loop over the list of model parameters received as NumPy " -":code:`ndarray`'s (think list of neural network layers)" -msgstr "(신경망 레이어 목록으로 생각하면 됩니다) NumPy :code:`ndarray`로 받은 모델 " -"파라미터 목록에 대해 반복합니다" +"loop over the list of model parameters received as NumPy :code:`ndarray`'s " +"(think list of neural network layers)" +msgstr "" +"(신경망 레이어 목록으로 생각하면 됩니다) NumPy :code:`ndarray`로 받은 모델 파" +"라미터 목록에 대해 반복합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:163 #: ../../source/example-pytorch-from-centralized-to-federated.rst:221 @@ -2755,11 +2812,11 @@ msgstr ":code:`get_parameters`" #: ../../source/example-pytorch-from-centralized-to-federated.rst:222 #: ../../source/tutorial-quickstart-jax.rst:170 msgid "" -"get the model parameters and return them as a list of NumPy " -":code:`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" +"get the model parameters and return them as a list of NumPy :code:" +"`ndarray`'s (which is what :code:`flwr.client.NumPyClient` expects)" msgstr "" -"모델 매개변수를 가져와서 NumPy :code:`ndarray`의 목록으로 반환합니다(이는 " -":code:`flwr.client.NumPyClient`가 기대하는 바와 같습니다)" +"모델 매개변수를 가져와서 NumPy :code:`ndarray`의 목록으로 반환합니다(이는 :" +"code:`flwr.client.NumPyClient`가 기대하는 바와 같습니다)" #: ../../source/example-jax-from-centralized-to-federated.rst:167 #: ../../source/example-pytorch-from-centralized-to-federated.rst:225 @@ -2776,8 +2833,8 @@ msgstr ":code:`fit`" #: ../../source/tutorial-quickstart-jax.rst:172 #: ../../source/tutorial-quickstart-jax.rst:176 msgid "" -"update the parameters of the local model with the parameters received " -"from the server" +"update the parameters of the local model with the parameters received from " +"the server" msgstr "서버에서 받은 파라미터로 로컬 모델의 파라미터를 업데이트합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:167 @@ -2813,9 +2870,9 @@ msgstr "로컬 손실을 서버로 반환합니다" #: ../../source/example-jax-from-centralized-to-federated.rst:174 #: ../../source/tutorial-quickstart-jax.rst:180 msgid "" -"The challenging part is to transform the JAX model parameters from " -":code:`DeviceArray` to :code:`NumPy ndarray` to make them compatible with" -" `NumPyClient`." +"The challenging part is to transform the JAX model parameters from :code:" +"`DeviceArray` to :code:`NumPy ndarray` to make them compatible with " +"`NumPyClient`." msgstr "" "어려운 부분은 JAX 모델 매개변수를 :code:`DeviceArray`에서 :code:`NumPy " "ndarray`로 변환하여 `NumPyClient`와 호환되도록 하는 것입니다." @@ -2823,97 +2880,96 @@ msgstr "" #: ../../source/example-jax-from-centralized-to-federated.rst:176 #: ../../source/tutorial-quickstart-jax.rst:182 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`evaluate()` previously " +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`evaluate()` previously " "defined in :code:`jax_training.py`. So what we really do here is we tell " -"Flower through our :code:`NumPyClient` subclass which of our already " -"defined functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." -msgstr "" -"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전에 " -":code:`jax_training.py`에 정의된 함수 :code:`train()`과 :code:`evaluate()`를 " -"사용합니다. 따라서 여기서 우리가 실제로 하는 일은 이미 정의된 함수 중 훈련과 " -"평가를 위해 호출할 함수를 :code:`NumPyClient` 서브클래스를 통해 Flower에게 " -"알려주는 것입니다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 유형 type " -"annotation을 포함했습니다." +"Flower through our :code:`NumPyClient` subclass which of our already defined " +"functions to call for training and evaluation. We included type annotations " +"to give you a better understanding of the data types that get passed around." +msgstr "" +"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전" +"에 :code:`jax_training.py`에 정의된 함수 :code:`train()`과 :code:`evaluate()`" +"를 사용합니다. 따라서 여기서 우리가 실제로 하는 일은 이미 정의된 함수 중 훈련" +"과 평가를 위해 호출할 함수를 :code:`NumPyClient` 서브클래스를 통해 Flower에" +"게 알려주는 것입니다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 유형 " +"type annotation을 포함했습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:245 #: ../../source/tutorial-quickstart-jax.rst:251 msgid "Having defined the federation process, we can run it." -msgstr "federation 프로세스를 정의했으면 이제 실행할 수 있습니다." +msgstr "연합 프로세스를 정의했으면 이제 실행할 수 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:268 #: ../../source/example-pytorch-from-centralized-to-federated.rst:301 #: ../../source/tutorial-quickstart-jax.rst:274 msgid "And that's it. You can now open two additional terminal windows and run" -msgstr "" +msgstr "여기까지입니다. 이제 두 개의 터미널 창을 추가로 열고 다음을 실행할 수 " +"있습니다" #: ../../source/example-jax-from-centralized-to-federated.rst:274 #: ../../source/tutorial-quickstart-jax.rst:280 msgid "" -"in each window (make sure that the server is still running before you do " -"so) and see your JAX project run federated learning across two clients. " +"in each window (make sure that the server is still running before you do so) " +"and see your JAX project run federated learning across two clients. " "Congratulations!" msgstr "" "를 입력하고(그 전에 서버가 계속 실행 중인지 확인하세요) 두 클라이언트에서 " -"federated 학습을 실행하는 JAX 프로젝트를 확인합니다. 축하합니다!" +"연합 학습을 실행하는 JAX 프로젝트를 확인합니다. 축하합니다!" #: ../../source/example-jax-from-centralized-to-federated.rst:279 #: ../../source/tutorial-quickstart-jax.rst:285 msgid "" "The source code of this example was improved over time and can be found " -"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " +"here: `Quickstart JAX `_. Our example is somewhat over-simplified because both " "clients load the same dataset." msgstr "" -"이 예제의 소스 코드는 시간이 지남에 따라 개선되었으며 여기에서 확인할 수 " -"있습니다: 'Quickstart JAX `_. 두 클라이언트가 동일한 데이터 세트를 로드하기 때문에 이 " -"예제는 다소 단순화되어 있습니다." +"이 예제의 소스 코드는 시간이 지남에 따라 개선되었으며 여기에서 확인할 수 있습" +"니다: 'Quickstart JAX `_. 두 클라이언트가 동일한 데이터 세트를 로드하기 때문에 이 예" +"제는 다소 단순화되어 있습니다." #: ../../source/example-jax-from-centralized-to-federated.rst:282 #: ../../source/tutorial-quickstart-jax.rst:288 msgid "" -"You're now prepared to explore this topic further. How about using a more" -" sophisticated model or using a different dataset? How about adding more " +"You're now prepared to explore this topic further. How about using a more " +"sophisticated model or using a different dataset? How about adding more " "clients?" msgstr "" -"이제 이 주제를 더 자세히 살펴볼 준비가 되었습니다. 더 정교한 모델을 " -"사용하거나 다른 데이터 집합을 사용해 보는 것은 어떨까요? 클라이언트를 더 " -"추가하는 것은 어떨까요?" +"이제 이 주제를 더 자세히 살펴볼 준비가 되었습니다. 더 정교한 모델을 사용하거" +"나 다른 데이터 집합을 사용해 보는 것은 어떨까요? 클라이언트를 더 추가하는 것" +"은 어떨까요?" #: ../../source/example-pytorch-from-centralized-to-federated.rst:2 msgid "Example: PyTorch - From Centralized To Federated" -msgstr "예제: 파이토치 - 중앙 Centralized에서 Federated으로" +msgstr "예제: 파이토치 - 중앙 집중식에서 연합식으로" #: ../../source/example-pytorch-from-centralized-to-federated.rst:4 msgid "" -"This tutorial will show you how to use Flower to build a federated " -"version of an existing machine learning workload. We are using PyTorch to" -" train a Convolutional Neural Network on the CIFAR-10 dataset. First, we " -"introduce this machine learning task with a centralized training approach" -" based on the `Deep Learning with PyTorch " -"`_ " -"tutorial. Then, we build upon the centralized training code to run the " -"training in a federated fashion." +"This tutorial will show you how to use Flower to build a federated version " +"of an existing machine learning workload. We are using PyTorch to train a " +"Convolutional Neural Network on the CIFAR-10 dataset. First, we introduce " +"this machine learning task with a centralized training approach based on the " +"`Deep Learning with PyTorch `_ tutorial. Then, we build upon the centralized " +"training code to run the training in a federated fashion." msgstr "" -"이 튜토리얼에서는 Flower를 사용해 기존 머신 러닝 워크로드의 federated 버전을 " +"이 튜토리얼에서는 Flower를 사용해 기존 머신 러닝 워크로드의 연합 버전을 " "구축하는 방법을 보여드립니다. 여기서는 PyTorch를 사용해 CIFAR-10 데이터 " "세트에서 컨볼루션 신경망을 훈련합니다. 먼저, 'PyTorch로 딥 러닝 " "`_ " "튜토리얼을 기반으로 centralized 학습 접근 방식을 사용하여 이 머신 러닝 " -"작업을 소개합니다. 그런 다음 centralized 훈련 코드를 기반으로 federated 방식 " +"작업을 소개합니다. 그런 다음 centralized 훈련 코드를 기반으로 연합 방식 " "훈련을 실행합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:12 msgid "" -"We begin with a brief description of the centralized CNN training code. " -"If you want a more in-depth explanation of what's going on then have a " -"look at the official `PyTorch tutorial " -"`_." +"We begin with a brief description of the centralized CNN training code. If " +"you want a more in-depth explanation of what's going on then have a look at " +"the official `PyTorch tutorial `_." msgstr "" -"centralized CNN 트레이닝 코드에 대한 간략한 설명부터 시작하겠습니다. 무슨 " +"중앙 집중식 CNN 트레이닝 코드에 대한 간략한 설명부터 시작하겠습니다. 무슨 " "일이 일어나고 있는지 더 자세히 설명하려면 공식 `PyTorch 튜토리얼 " "`_을 " "참조하세요." @@ -2921,18 +2977,17 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:15 msgid "" "Let's create a new file called :code:`cifar.py` with all the components " -"required for a traditional (centralized) training on CIFAR-10. First, all" -" required packages (such as :code:`torch` and :code:`torchvision`) need " -"to be imported. You can see that we do not import any package for " -"federated learning. You can keep all these imports as they are even when " -"we add the federated learning components at a later point." +"required for a traditional (centralized) training on CIFAR-10. First, all " +"required packages (such as :code:`torch` and :code:`torchvision`) need to be " +"imported. You can see that we do not import any package for federated " +"learning. You can keep all these imports as they are even when we add the " +"federated learning components at a later point." msgstr "" -"CIFAR-10에 대한 기존 (centralized) 교육에 필요한 모든 구성 요소가 포함된 " +"CIFAR-10에 대한 기존 (중앙 집중식) 교육에 필요한 모든 구성 요소가 포함된 " ":code:`cifar.py`라는 새 파일을 생성해 보겠습니다. 먼저, 필요한 모든 " -"패키지(예: :code:`torch` 및 :code:`torchvision`)를 가져와야 합니다. " -"federated 학습을 위한 패키지를 가져오지 않는 것을 확인 할 수 있습니. 나중에 " -"federated 학습 구성 요소를 추가할 때에도 이러한 모든 가져오기를 그대로 " -"유지할 수 있습니다." +"패키지(예: :code:`torch` 및 :code:`torchvision`)를 가져와야 합니다. 연합 " +"학습을 위한 패키지를 가져오지 않는 것을 확인 할 수 있습니. 나중에 연합 학습 " +"구성 요소를 추가할 때에도 이러한 모든 가져오기를 그대로 유지할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:32 msgid "" @@ -2946,124 +3001,125 @@ msgstr "" #: ../../source/example-pytorch-from-centralized-to-federated.rst:56 msgid "" -"The :code:`load_data()` function loads the CIFAR-10 training and test " -"sets. The :code:`transform` normalized the data after loading." +"The :code:`load_data()` function loads the CIFAR-10 training and test sets. " +"The :code:`transform` normalized the data after loading." msgstr "" -":code:`load_data()` 함수는 CIFAR-10 훈련 및 테스트 세트를 로드합니다. " -":code:`transform`은 로드 후 데이터를 정규화합니다." +":code:`load_data()` 함수는 CIFAR-10 훈련 및 테스트 세트를 로드합니다. :code:" +"`transform`은 로드 후 데이터를 정규화합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:74 msgid "" -"We now need to define the training (function :code:`train()`) which loops" -" over the training set, measures the loss, backpropagates it, and then " -"takes one optimizer step for each batch of training examples." +"We now need to define the training (function :code:`train()`) which loops " +"over the training set, measures the loss, backpropagates it, and then takes " +"one optimizer step for each batch of training examples." msgstr "" "이제 학습 집합을 반복하고, 손실을 측정하고, 이를 역전파한 다음 각 학습 예제 " -"배치에 대해 하나의 최적화 단계를 수행하는 학습(함수 :code:`train()`)을 " -"정의해야 합니다." +"배치에 대해 하나의 최적화 단계를 수행하는 학습(함수 :code:`train()`)을 정의해" +"야 합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:76 msgid "" -"The evaluation of the model is defined in the function :code:`test()`. " -"The function loops over all test samples and measures the loss of the " -"model based on the test dataset." +"The evaluation of the model is defined in the function :code:`test()`. The " +"function loops over all test samples and measures the loss of the model " +"based on the test dataset." msgstr "" -"모델 평가는 :code:`test()` 함수에 정의되어 있습니다. 이 함수는 모든 테스트 " -"샘플을 반복하고 테스트 데이터 세트에 따라 모델의 손실을 측정합니다." +"모델 평가는 :code:`test()` 함수에 정의되어 있습니다. 이 함수는 모든 테스트 샘" +"플을 반복하고 테스트 데이터 세트에 따라 모델의 손실을 측정합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:136 msgid "" "Having defined the data loading, model architecture, training, and " "evaluation we can put everything together and train our CNN on CIFAR-10." -msgstr "데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으면 모든 것을 종합하여 " +msgstr "" +"데이터 로딩, 모델 아키텍처, 훈련 및 평가를 정의했으면 모든 것을 종합하여 " "CIFAR-10에서 CNN을 훈련할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:163 msgid "" -"So far, this should all look fairly familiar if you've used PyTorch " -"before. Let's take the next step and use what we've built to create a " -"simple federated learning system consisting of one server and two " -"clients." +"So far, this should all look fairly familiar if you've used PyTorch before. " +"Let's take the next step and use what we've built to create a simple " +"federated learning system consisting of one server and two clients." msgstr "" -"지금까지는 파이토치를 사용해 본 적이 있다면 상당히 익숙하게 보일 것입니다. " -"다음 단계로 넘어가서 구축한 것을 사용하여 하나의 서버와 두 개의 클라이언트로 " -"구성된 간단한 연합 학습 시스템을 만들어 보겠습니다." +"지금까지는 파이토치를 사용해 본 적이 있다면 상당히 익숙하게 보일 것입니다. 다" +"음 단계로 넘어가서 구축한 것을 사용하여 하나의 서버와 두 개의 클라이언트로 구" +"성된 간단한 연합 학습 시스템을 만들어 보겠습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:169 msgid "" -"The simple machine learning project discussed in the previous section " -"trains the model on a single dataset (CIFAR-10), we call this centralized" -" learning. This concept of centralized learning, as shown in the previous" -" section, is probably known to most of you, and many of you have used it " -"previously. Normally, if you'd want to run machine learning workloads in " -"a federated fashion, then you'd have to change most of your code and set " -"everything up from scratch. This can be a considerable effort." +"The simple machine learning project discussed in the previous section trains " +"the model on a single dataset (CIFAR-10), we call this centralized learning. " +"This concept of centralized learning, as shown in the previous section, is " +"probably known to most of you, and many of you have used it previously. " +"Normally, if you'd want to run machine learning workloads in a federated " +"fashion, then you'd have to change most of your code and set everything up " +"from scratch. This can be a considerable effort." msgstr "" "이전 섹션에서 설명한 간단한 머신 러닝 프로젝트는 단일 데이터 세트(CIFAR-10)" -"로 모델을 학습시키는데, 이를 centralized 학습이라고 부릅니다. 이전 섹션에서 " -"설명한 centralized 학습의 개념은 대부분 알고 계실 것이며, 많은 분들이 이전에 " -"사용해 보셨을 것입니다. 일반적으로 머신 러닝 워크로드를 federated 방식으로 " +"로 모델을 학습시키는데, 이를 중앙 집중식 학습이라고 부릅니다. 이전 섹션에서 " +"설명한 중앙 집중식 학습의 개념은 대부분 알고 계실 것이며, 많은 분들이 이전에 " +"사용해 보셨을 것입니다. 일반적으로 머신 러닝 워크로드를 연합 방식으로 " "실행하려면 대부분의 코드를 변경하고 모든 것을 처음부터 다시 설정해야 합니다. " "이는 상당한 노력이 필요할 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:173 msgid "" -"However, with Flower you can evolve your pre-existing code into a " -"federated learning setup without the need for a major rewrite." -msgstr "하지만 Flower를 사용하면 대대적인 재작성 없이도 기존 코드를 연합 학습 " -"설정으로 발전시킬 수 있습니다." +"However, with Flower you can evolve your pre-existing code into a federated " +"learning setup without the need for a major rewrite." +msgstr "" +"하지만 Flower를 사용하면 대대적인 재작성 없이도 기존 코드를 연합 학습 설정으" +"로 발전시킬 수 있습니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:175 msgid "" -"The concept is easy to understand. We have to start a *server* and then " -"use the code in :code:`cifar.py` for the *clients* that are connected to " -"the *server*. The *server* sends model parameters to the clients. The " -"*clients* run the training and update the parameters. The updated " -"parameters are sent back to the *server* which averages all received " -"parameter updates. This describes one round of the federated learning " -"process and we repeat this for multiple rounds." +"The concept is easy to understand. We have to start a *server* and then use " +"the code in :code:`cifar.py` for the *clients* that are connected to the " +"*server*. The *server* sends model parameters to the clients. The *clients* " +"run the training and update the parameters. The updated parameters are sent " +"back to the *server* which averages all received parameter updates. This " +"describes one round of the federated learning process and we repeat this for " +"multiple rounds." msgstr "" "개념은 이해하기 쉽습니다. *서버*를 시작한 다음 *서버*에 연결된 *클라이언트*" "에 대해 :code:`cifar.py`의 코드를 사용해야 합니다. *서버*는 모델 파라미터를 " "클라이언트로 전송합니다. *클라이언트*는 학습을 실행하고 파라미터를 " "업데이트합니다. 업데이트된 파라미터는 *서버*로 다시 전송되며, *서버*는 " -"수신된 모든 파라미터 업데이트의 평균을 구합니다. 이것은 federated 학습 " -"프로세스의 한 라운드를 설명하며 여러 라운드에 걸쳐 이 과정을 반복합니다." +"수신된 모든 파라미터 업데이트의 평균을 구합니다. 이것은 연합 학습 프로세스의 " +"한 라운드를 설명하며 여러 라운드에 걸쳐 이 과정을 반복합니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:197 msgid "" -"Finally, we will define our *client* logic in :code:`client.py` and build" -" upon the previously defined centralized training in :code:`cifar.py`. " -"Our *client* needs to import :code:`flwr`, but also :code:`torch` to " -"update the parameters on our PyTorch model:" +"Finally, we will define our *client* logic in :code:`client.py` and build " +"upon the previously defined centralized training in :code:`cifar.py`. Our " +"*client* needs to import :code:`flwr`, but also :code:`torch` to update the " +"parameters on our PyTorch model:" msgstr "" "마지막으로, :code:`client.py`에서 *client* 로직을 정의하고 :code:`cifar.py`" -"에서 이전에 정의한 centralized 학습을 기반으로 구축합니다. *클라이언트*는 " +"에서 이전에 정의한 중앙 집중식 학습을 기반으로 구축합니다. *클라이언트*는 " ":code:`flwr`을 가져와야 하며, PyTorch 모델의 파라미터를 업데이트하기 위해 " ":code:`torch`도 가져와야 합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:213 msgid "" -"Implementing a Flower *client* basically means implementing a subclass of" -" either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. " -"Our implementation will be based on :code:`flwr.client.NumPyClient` and " -"we'll call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier" -" to implement than :code:`Client` if you use a framework with good NumPy " -"interoperability (like PyTorch or TensorFlow/Keras) because it avoids " -"some of the boilerplate that would otherwise be necessary. " -":code:`CifarClient` needs to implement four methods, two methods for " -"getting/setting model parameters, one method for training the model, and " -"one method for testing the model:" +"Implementing a Flower *client* basically means implementing a subclass of " +"either :code:`flwr.client.Client` or :code:`flwr.client.NumPyClient`. Our " +"implementation will be based on :code:`flwr.client.NumPyClient` and we'll " +"call it :code:`CifarClient`. :code:`NumPyClient` is slightly easier to " +"implement than :code:`Client` if you use a framework with good NumPy " +"interoperability (like PyTorch or TensorFlow/Keras) because it avoids some " +"of the boilerplate that would otherwise be necessary. :code:`CifarClient` " +"needs to implement four methods, two methods for getting/setting model " +"parameters, one method for training the model, and one method for testing " +"the model:" msgstr "" "Flower *클라이언트*를 구현한다는 것은 기본적으로 :code:`flwr.client.Client` " -"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 " -"의미합니다. 우리의 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, " -"이를 :code:`CifarClient`라고 부를 것입니다. :code:`NumPyClient`는 파이토치나 " -"텐서플로우/Keras처럼 NumPy 상호운용성이 좋은 프레임워크를 사용하는 경우 " -"필요한 일부 보일러플레이트를 피하기 때문에 :code:`Client`보다 구현하기가 " -"조금 더 쉽습니다. code:`CifarClient`는 모델 파라미터를 가져오거나 설정하는 " -"메서드 2개, 모델 학습을 위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 네 " -"가지 메서드를 구현해야 합니다:" +"또는 :code:`flwr.client.NumPyClient`의 서브클래스를 구현하는 것을 의미합니" +"다. 우리의 구현은 :code:`flwr.client.NumPyClient`를 기반으로 하며, 이를 :" +"code:`CifarClient`라고 부를 것입니다. :code:`NumPyClient`는 파이토치나 텐서플" +"로우/Keras처럼 NumPy 상호운용성이 좋은 프레임워크를 사용하는 경우 필요한 일" +"부 보일러플레이트를 피하기 때문에 :code:`Client`보다 구현하기가 조금 더 쉽습" +"니다. code:`CifarClient`는 모델 파라미터를 가져오거나 설정하는 메서드 2개, 모" +"델 학습을 위한 메서드 1개, 모델 테스트를 위한 메서드 1개 등 네 가지 메서드를 " +"구현해야 합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:219 msgid ":code:`set_parameters`" @@ -3079,62 +3135,61 @@ msgstr "로컬 손실 및 정확도를 서버에 반환합니다" #: ../../source/example-pytorch-from-centralized-to-federated.rst:232 msgid "" -"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make" -" use of the functions :code:`train()` and :code:`test()` previously " -"defined in :code:`cifar.py`. So what we really do here is we tell Flower " -"through our :code:`NumPyClient` subclass which of our already defined " -"functions to call for training and evaluation. We included type " -"annotations to give you a better understanding of the data types that get" -" passed around." -msgstr "" -"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전에 " -":code:`cifar.py`에 정의된 함수인 :code:`train()`과 :code:`test()`를 " -"활용합니다. 따라서 여기서 실제로 하는 일은 :code:`NumPyClient` 서브클래스를 " -"통해 이미 정의된 함수 중 훈련과 평가를 위해 호출할 함수를 Flower에 알려주는 " -"것입니다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 type annotations을 " -"포함했습니다." +"The two :code:`NumPyClient` methods :code:`fit` and :code:`evaluate` make " +"use of the functions :code:`train()` and :code:`test()` previously defined " +"in :code:`cifar.py`. So what we really do here is we tell Flower through " +"our :code:`NumPyClient` subclass which of our already defined functions to " +"call for training and evaluation. We included type annotations to give you a " +"better understanding of the data types that get passed around." +msgstr "" +"두 개의 :code:`NumPyClient` 메서드인 :code:`fit`과 :code:`evaluate`는 이전" +"에 :code:`cifar.py`에 정의된 함수인 :code:`train()`과 :code:`test()`를 활용합" +"니다. 따라서 여기서 실제로 하는 일은 :code:`NumPyClient` 서브클래스를 통해 이" +"미 정의된 함수 중 훈련과 평가를 위해 호출할 함수를 Flower에 알려주는 것입니" +"다. 전달되는 데이터 유형을 더 잘 이해할 수 있도록 type annotations을 포함했습" +"니다." #: ../../source/example-pytorch-from-centralized-to-federated.rst:280 msgid "" "All that's left to do it to define a function that loads both model and " -"data, creates a :code:`CifarClient`, and starts this client. You load " -"your data and model by using :code:`cifar.py`. Start :code:`CifarClient` " -"with the function :code:`fl.client.start_client()` by pointing it at the " -"same IP address we used in :code:`server.py`:" +"data, creates a :code:`CifarClient`, and starts this client. You load your " +"data and model by using :code:`cifar.py`. Start :code:`CifarClient` with the " +"function :code:`fl.client.start_client()` by pointing it at the same IP " +"address we used in :code:`server.py`:" msgstr "" -"이제 모델과 데이터를 모두 로드하는 함수를 정의하고, :code:`CifarClient`를 " -"생성하고, 이 클라이언트를 시작하는 작업만 남았습니다. 코드:`cifar.py`를 " -"사용하여 데이터와 모델을 로드합니다. :code:`server.py`에서 사용한 것과 " -"동일한 IP 주소를 지정하여 :code:`fl.client.start_client()` 함수로 " -":code:`CifarClient`를 시작합니다:" +"이제 모델과 데이터를 모두 로드하는 함수를 정의하고, :code:`CifarClient`를 생" +"성하고, 이 클라이언트를 시작하는 작업만 남았습니다. 코드:`cifar.py`를 사용하" +"여 데이터와 모델을 로드합니다. :code:`server.py`에서 사용한 것과 동일한 IP 주" +"소를 지정하여 :code:`fl.client.start_client()` 함수로 :code:`CifarClient`를 " +"시작합니다:" #: ../../source/example-pytorch-from-centralized-to-federated.rst:307 msgid "" -"in each window (make sure that the server is running before you do so) " -"and see your (previously centralized) PyTorch project run federated " -"learning across two clients. Congratulations!" +"in each window (make sure that the server is running before you do so) and " +"see your (previously centralized) PyTorch project run federated learning " +"across two clients. Congratulations!" msgstr "" -"를 입력하고(그 전에 서버가 실행 중인지 확인하세요) (이전에는centralized) " -"PyTorch 프로젝트가 두 클라이언트에서 federated 학습을 실행하는 것을 " -"확인합니다. 축하합니다!" +"를 입력하고(그 전에 서버가 실행 중인지 확인하세요) (이전에는 중앙 집중식) " +"PyTorch 프로젝트가 두 클라이언트에서 연합 학습을 실행하는 것을 확인합니다. " +"축하합니다!" #: ../../source/example-pytorch-from-centralized-to-federated.rst:312 msgid "" "The full source code for this example: `PyTorch: From Centralized To " -"Federated (Code) `_. Our example is, of course, " -"somewhat over-simplified because both clients load the exact same " -"dataset, which isn't realistic. You're now prepared to explore this topic" -" further. How about using different subsets of CIFAR-10 on each client? " -"How about adding more clients?" -msgstr "" -"이 예제의 전체 소스 코드: `파이토치: 중앙 Centralized에서 Federated으로 " -"(코드) `_. 물론 이 예제는 두 클라이언트가 완전히 동일한 " -"데이터 세트를 로드하기 때문에 다소 지나치게 단순화되어 있으며, 이는 " -"현실적이지 않습니다. 이제 이 주제를 더 자세히 살펴볼 준비가 되셨습니다. 각 " -"클라이언트에서 서로 다른 CIFAR-10의 하위 집합을 사용해 보는 것은 어떨까요? " -"클라이언트를 더 추가하는 것은 어떨까요?" +"Federated (Code) `_. Our example is, of course, somewhat over-" +"simplified because both clients load the exact same dataset, which isn't " +"realistic. You're now prepared to explore this topic further. How about " +"using different subsets of CIFAR-10 on each client? How about adding more " +"clients?" +msgstr "" +"이 예제의 전체 소스 코드: `파이토치: 중앙 Centralized에서 Federated으로 (코" +"드) `_. 물론 이 예제는 두 클라이언트가 완전히 동일한 데" +"이터 세트를 로드하기 때문에 다소 지나치게 단순화되어 있으며, 이는 현실적이지 " +"않습니다. 이제 이 주제를 더 자세히 살펴볼 준비가 되셨습니다. 각 클라이언트에" +"서 서로 다른 CIFAR-10의 하위 집합을 사용해 보는 것은 어떨까요? 클라이언트를 " +"더 추가하는 것은 어떨까요?" #: ../../source/explanation-differential-privacy.rst:2 #: ../../source/explanation-differential-privacy.rst:11 @@ -3144,27 +3199,26 @@ msgstr "차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:3 msgid "" -"The information in datasets like healthcare, financial transactions, user" -" preferences, etc., is valuable and has the potential for scientific " -"breakthroughs and provides important business insights. However, such " -"data is also sensitive and there is a risk of compromising individual " -"privacy." +"The information in datasets like healthcare, financial transactions, user " +"preferences, etc., is valuable and has the potential for scientific " +"breakthroughs and provides important business insights. However, such data " +"is also sensitive and there is a risk of compromising individual privacy." msgstr "" -"의료, 금융 거래, 사용자 선호도 등과 같은 데이터 세트의 정보는 가치 있고 " -"과학적 혁신의 잠재력을 지니고 있으며 중요한 비즈니스 인사이트를 제공합니다. " -"그러나 이러한 데이터는 또한 민감한 정보이며 개인의 프라이버시를 침해할 " -"위험이 있습니다." +"의료, 금융 거래, 사용자 선호도 등과 같은 데이터 세트의 정보는 가치 있고 과학" +"적 혁신의 잠재력을 지니고 있으며 중요한 비즈니스 인사이트를 제공합니다. 그러" +"나 이러한 데이터는 또한 민감한 정보이며 개인의 프라이버시를 침해할 위험이 있" +"습니다." #: ../../source/explanation-differential-privacy.rst:6 msgid "" "Traditional methods like anonymization alone would not work because of " -"attacks like Re-identification and Data Linkage. That's where " -"differential privacy comes in. It provides the possibility of analyzing " -"data while ensuring the privacy of individuals." +"attacks like Re-identification and Data Linkage. That's where differential " +"privacy comes in. It provides the possibility of analyzing data while " +"ensuring the privacy of individuals." msgstr "" -"익명화와 같은 기존 방법만으로는 재식별 및 데이터 연결과 같은 공격으로 인해 " -"효과가 없습니다. 그래서 차분 프라이버시가 등장했습니다. 차등 개인정보 보호는 " -"개인의 프라이버시를 보장하면서 데이터를 분석할 수 있는 가능성을 제공합니다." +"익명화와 같은 기존 방법만으로는 재식별 및 데이터 연결과 같은 공격으로 인해 효" +"과가 없습니다. 그래서 차분 프라이버시가 등장했습니다. 차등 개인정보 보호는 개" +"인의 프라이버시를 보장하면서 데이터를 분석할 수 있는 가능성을 제공합니다." #: ../../source/explanation-differential-privacy.rst:12 msgid "" @@ -3172,8 +3226,8 @@ msgid "" "instance, Alice's data). Differential Privacy (DP) guarantees that any " "analysis (M), like calculating the average income, will produce nearly " "identical results for both datasets (O and O' would be similar). This " -"preserves group patterns while obscuring individual details, ensuring the" -" individual's information remains hidden in the crowd." +"preserves group patterns while obscuring individual details, ensuring the " +"individual's information remains hidden in the crowd." msgstr "" "하나의 레코드(예: 앨리스의 데이터)를 제외하고는 동일한 두 개의 데이터 세트가 " "있다고 상상해 보세요. 차분 프라이버(DP)는 평균 소득 계산과 같은 모든 분석(M)" @@ -3189,12 +3243,11 @@ msgstr "DP 소개" msgid "" "One of the most commonly used mechanisms to achieve DP is adding enough " "noise to the output of the analysis to mask the contribution of each " -"individual in the data while preserving the overall accuracy of the " -"analysis." +"individual in the data while preserving the overall accuracy of the analysis." msgstr "" -"DP를 달성하기 위해 가장 일반적으로 사용되는 메커니즘 중 하나는 분석의 " -"전반적인 정확도를 유지하면서 데이터에서 각 개인의 기여도를 가릴 수 있도록 " -"분석 결과에 충분한 노이즈를 추가하는 것입니다." +"DP를 달성하기 위해 가장 일반적으로 사용되는 메커니즘 중 하나는 분석의 전반적" +"인 정확도를 유지하면서 데이터에서 각 개인의 기여도를 가릴 수 있도록 분석 결과" +"에 충분한 노이즈를 추가하는 것입니다." #: ../../source/explanation-differential-privacy.rst:25 msgid "Formal Definition" @@ -3204,19 +3257,19 @@ msgstr "공식 정의" msgid "" "Differential Privacy (DP) provides statistical guarantees against the " "information an adversary can infer through the output of a randomized " -"algorithm. It provides an unconditional upper bound on the influence of a" -" single individual on the output of the algorithm by adding noise [1]. A " -"randomized mechanism M provides (:math:`\\epsilon`, " -":math:`\\delta`)-differential privacy if for any two neighboring " -"databases, D :sub:`1` and D :sub:`2`, that differ in only a single " -"record, and for all possible outputs S ⊆ Range(A):" +"algorithm. It provides an unconditional upper bound on the influence of a " +"single individual on the output of the algorithm by adding noise [1]. A " +"randomized mechanism M provides (:math:`\\epsilon`, :math:`\\delta`)-" +"differential privacy if for any two neighboring databases, D :sub:`1` and D :" +"sub:`2`, that differ in only a single record, and for all possible outputs S " +"⊆ Range(A):" msgstr "" "차분 프라이버시(DP)는 공격자가 무작위 알고리즘의 출력을 통해 유추할 수 있는 " -"정보에 대해 통계적 보장을 제공합니다. 이는 노이즈를 추가하여 알고리즘의 " -"출력에 대한 한 개인의 영향력에 대한 무조건적인 상한선을 제공합니다[1]. " -"무작위 메커니즘 M은 하나의 레코드만 다른 두 개의 인접 데이터베이스인 " -"D:sub:`1`과 D:sub:`2`의 경우, 가능한 모든 출력 S ⊆ Range(A)에 대해 (:math:`" -"\\epsilon`, :math:`\\delta`)-차분 프라이버시를 제공합니다:" +"정보에 대해 통계적 보장을 제공합니다. 이는 노이즈를 추가하여 알고리즘의 출력" +"에 대한 한 개인의 영향력에 대한 무조건적인 상한선을 제공합니다[1]. 무작위 메" +"커니즘 M은 하나의 레코드만 다른 두 개의 인접 데이터베이스인 D:sub:`1`과 D:" +"sub:`2`의 경우, 가능한 모든 출력 S ⊆ Range(A)에 대해 (:math:`\\epsilon`, :" +"math:`\\delta`)-차분 프라이버시를 제공합니다:" #: ../../source/explanation-differential-privacy.rst:32 msgid "" @@ -3231,19 +3284,19 @@ msgid "" "The :math:`\\epsilon` parameter, also known as the privacy budget, is a " "metric of privacy loss. It also controls the privacy-utility trade-off; " "lower :math:`\\epsilon` values indicate higher levels of privacy but are " -"likely to reduce utility as well. The :math:`\\delta` parameter accounts " -"for a small probability on which the upper bound :math:`\\epsilon` does " -"not hold. The amount of noise needed to achieve differential privacy is " -"proportional to the sensitivity of the output, which measures the maximum" -" change in the output due to the inclusion or removal of a single record." +"likely to reduce utility as well. The :math:`\\delta` parameter accounts for " +"a small probability on which the upper bound :math:`\\epsilon` does not " +"hold. The amount of noise needed to achieve differential privacy is " +"proportional to the sensitivity of the output, which measures the maximum " +"change in the output due to the inclusion or removal of a single record." msgstr "" "프라이버시 예산이라고도 하는 :math:`\\epsilon` 매개변수는 프라이버시 손실을 " -"측정하는 지표입니다. 이 매개변수는 프라이버시와 효용의 균형을 제어하며, " -":math:`\\epsilon` 값이 낮을수록 프라이버시 수준이 높지만 효용도 감소할 " -"가능성이 높습니다. math:`\\delta` 매개변수는 상한값인 :math:`\\epsilon`이 " -"적용되지 않는 작은 확률을 설명합니다. 차분 프라이버시를 달성하는 데 필요한 " -"노이즈의 양은 출력의 감도에 비례하며, 이는 단일 레코드의 포함 또는 제거로 " -"인한 출력의 최대 변화를 측정합니다." +"측정하는 지표입니다. 이 매개변수는 프라이버시와 효용의 균형을 제어하며, :" +"math:`\\epsilon` 값이 낮을수록 프라이버시 수준이 높지만 효용도 감소할 가능성" +"이 높습니다. math:`\\delta` 매개변수는 상한값인 :math:`\\epsilon`이 적용되지 " +"않는 작은 확률을 설명합니다. 차분 프라이버시를 달성하는 데 필요한 노이즈의 양" +"은 출력의 감도에 비례하며, 이는 단일 레코드의 포함 또는 제거로 인한 출력의 최" +"대 변화를 측정합니다." #: ../../source/explanation-differential-privacy.rst:45 msgid "Differential Privacy in Machine Learning" @@ -3253,40 +3306,39 @@ msgstr "머신 러닝의 차분 프라이버시" msgid "" "DP can be utilized in machine learning to preserve the privacy of the " "training data. Differentially private machine learning algorithms are " -"designed in a way to prevent the algorithm to learn any specific " -"information about any individual data points and subsequently prevent the" -" model from revealing sensitive information. Depending on the stage at " -"which noise is introduced, various methods exist for applying DP to " -"machine learning algorithms. One approach involves adding noise to the " -"training data (either to the features or labels), while another method " -"entails injecting noise into the gradients of the loss function during " -"model training. Additionally, such noise can be incorporated into the " -"model's output." -msgstr "" -"머신 러닝에서 DP를 활용하여 학습 데이터의 개인정보를 보호할 수 있습니다. " -"차분 비공개 머신 러닝 알고리즘은 알고리즘이 개별 데이터 포인트에 대한 특정 " -"정보를 학습하지 못하도록 하여 모델이 민감한 정보를 노출하지 않도록 하는 " -"방식으로 설계되었습니다. 노이즈가 도입되는 단계에 따라 머신 러닝 알고리즘에 " -"DP를 적용하는 다양한 방법이 존재합니다. 한 가지 방법은 학습 데이터(특징 또는 " -"레이블)에 노이즈를 추가하는 것이고, 다른 방법은 모델 학습 중에 손실 함수의 " -"기울기에 노이즈를 주입하는 것입니다. 또한 이러한 노이즈를 모델의 출력에 " -"통합할 수도 있습니다." +"designed in a way to prevent the algorithm to learn any specific information " +"about any individual data points and subsequently prevent the model from " +"revealing sensitive information. Depending on the stage at which noise is " +"introduced, various methods exist for applying DP to machine learning " +"algorithms. One approach involves adding noise to the training data (either " +"to the features or labels), while another method entails injecting noise " +"into the gradients of the loss function during model training. Additionally, " +"such noise can be incorporated into the model's output." +msgstr "" +"머신 러닝에서 DP를 활용하여 학습 데이터의 개인정보를 보호할 수 있습니다. 차" +"분 비공개 머신 러닝 알고리즘은 알고리즘이 개별 데이터 포인트에 대한 특정 정보" +"를 학습하지 못하도록 하여 모델이 민감한 정보를 노출하지 않도록 하는 방식으로 " +"설계되었습니다. 노이즈가 도입되는 단계에 따라 머신 러닝 알고리즘에 DP를 적용" +"하는 다양한 방법이 존재합니다. 한 가지 방법은 학습 데이터(특징 또는 레이블)" +"에 노이즈를 추가하는 것이고, 다른 방법은 모델 학습 중에 손실 함수의 기울기에 " +"노이즈를 주입하는 것입니다. 또한 이러한 노이즈를 모델의 출력에 통합할 수도 있" +"습니다." #: ../../source/explanation-differential-privacy.rst:53 msgid "Differential Privacy in Federated Learning" -msgstr "Federated 학습의 차분 프라이버시" +msgstr "연합 학습의 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:54 msgid "" "Federated learning is a data minimization approach that allows multiple " "parties to collaboratively train a model without sharing their raw data. " "However, federated learning also introduces new privacy challenges. The " -"model updates between parties and the central server can leak information" -" about the local data. These leaks can be exploited by attacks such as " +"model updates between parties and the central server can leak information " +"about the local data. These leaks can be exploited by attacks such as " "membership inference and property inference attacks, or model inversion " "attacks." msgstr "" -"Federated 학습은 여러 당사자가 원시 데이터를 공유하지 않고도 공동으로 모델을 " +"연합 학습은 여러 당사자가 원시 데이터를 공유하지 않고도 공동으로 모델을 " "학습할 수 있는 데이터 최소화 접근 방식입니다. 그러나 연합 학습은 새로운 " "개인정보 보호 문제를 야기하기도 합니다. 당사자와 중앙 서버 간의 모델 " "업데이트는 로컬 데이터에 대한 정보를 유출할 수 있습니다. 이러한 유출은 " @@ -3295,43 +3347,43 @@ msgstr "" #: ../../source/explanation-differential-privacy.rst:58 msgid "" -"DP can play a crucial role in federated learning to provide privacy for " -"the clients' data." -msgstr "DP는 federated학습에서 클라이언트의 데이터에 대한 개인 정보 보호를 제공하는 " -"데 중요한 역할을 할 수 있습니다." +"DP can play a crucial role in federated learning to provide privacy for the " +"clients' data." +msgstr "DP는 연합 학습에서 클라이언트의 데이터에 대한 개인 정보 보호를 제공하는 데 " +"중요한 역할을 할 수 있습니다." #: ../../source/explanation-differential-privacy.rst:60 msgid "" -"Depending on the granularity of privacy provision or the location of " -"noise addition, different forms of DP exist in federated learning. In " -"this explainer, we focus on two approaches of DP utilization in federated" -" learning based on where the noise is added: at the server (also known as" -" the center) or at the client (also known as the local)." +"Depending on the granularity of privacy provision or the location of noise " +"addition, different forms of DP exist in federated learning. In this " +"explainer, we focus on two approaches of DP utilization in federated " +"learning based on where the noise is added: at the server (also known as the " +"center) or at the client (also known as the local)." msgstr "" -"개인 정보 제공의 세분성 또는 노이즈 추가 위치에 따라 federated 학습에는 " -"다양한 형태의 DP가 존재합니다. 이 설명에서는 노이즈가 추가되는 위치에 따라 " -"서버(중앙이라고도 함) 또는 클라이언트(로컬이라고도 함)에서의 federated " -"학습에서 DP를 활용하는 두 가지 접근 방식에 중점을 둡니다." +"개인 정보 제공의 세분성 또는 노이즈 추가 위치에 따라 연합 학습에는 다양한 " +"형태의 DP가 존재합니다. 이 설명에서는 노이즈가 추가되는 위치에 따라 서버(" +"중앙이라고도 함) 또는 클라이언트(로컬이라고도 함)에서의 연합 학습에서 DP를 " +"활용하는 두 가지 접근 방식에 중점을 둡니다." #: ../../source/explanation-differential-privacy.rst:63 msgid "" -"**Central Differential Privacy**: DP is applied by the server and the " -"goal is to prevent the aggregated model from leaking information about " -"each client's data." +"**Central Differential Privacy**: DP is applied by the server and the goal " +"is to prevent the aggregated model from leaking information about each " +"client's data." msgstr "" -"**중앙 차분 프라이버시**: DP는 서버에서 적용되며 집계된 모델이 각 " -"클라이언트의 데이터에 대한 정보를 유출하는 것을 방지하는 것이 목표입니다." +"**중앙 차분 프라이버시**: DP는 서버에서 적용되며 집계된 모델이 각 클라이언트" +"의 데이터에 대한 정보를 유출하는 것을 방지하는 것이 목표입니다." #: ../../source/explanation-differential-privacy.rst:65 msgid "" "**Local Differential Privacy**: DP is applied on the client side before " -"sending any information to the server and the goal is to prevent the " -"updates that are sent to the server from leaking any information about " -"the client's data." +"sending any information to the server and the goal is to prevent the updates " +"that are sent to the server from leaking any information about the client's " +"data." msgstr "" -"**로컬 차분 개인정보 보호**: DP는 정보를 서버로 보내기 전에 클라이언트 " -"측에서 적용되며, 서버로 전송되는 업데이트가 클라이언트 데이터에 대한 정보를 " -"유출하는 것을 방지하는 것이 목표입니다." +"**로컬 차분 개인정보 보호**: DP는 정보를 서버로 보내기 전에 클라이언트 측에" +"서 적용되며, 서버로 전송되는 업데이트가 클라이언트 데이터에 대한 정보를 유출" +"하는 것을 방지하는 것이 목표입니다." #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:68 @@ -3341,30 +3393,30 @@ msgstr "중앙 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:69 msgid "" -"In this approach, which is also known as user-level DP, the central " -"server is responsible for adding noise to the globally aggregated " -"parameters. It should be noted that trust in the server is required." +"In this approach, which is also known as user-level DP, the central server " +"is responsible for adding noise to the globally aggregated parameters. It " +"should be noted that trust in the server is required." msgstr "" -"사용자 수준 DP라고도 하는 이 접근 방식에서는 중앙 서버가 전역적으로 집계된 " -"매개변수에 노이즈를 추가하는 역할을 담당합니다. 서버에 대한 신뢰가 " -"필요하다는 점에 유의해야 합니다." +"사용자 수준 DP라고도 하는 이 접근 방식에서는 중앙 서버가 전역적으로 집계된 매" +"개변수에 노이즈를 추가하는 역할을 담당합니다. 서버에 대한 신뢰가 필요하다는 " +"점에 유의해야 합니다." #: ../../source/explanation-differential-privacy.rst:76 msgid "" -"While there are various ways to implement central DP in federated " -"learning, we concentrate on the algorithms proposed by [2] and [3]. The " -"overall approach is to clip the model updates sent by the clients and add" -" some amount of noise to the aggregated model. In each iteration, a " -"random set of clients is chosen with a specific probability for training." -" Each client performs local training on its own data. The update of each " -"client is then clipped by some value `S` (sensitivity `S`). This would " -"limit the impact of any individual client which is crucial for privacy " -"and often beneficial for robustness. A common approach to achieve this is" -" by restricting the `L2` norm of the clients' model updates, ensuring " -"that larger updates are scaled down to fit within the norm `S`." -msgstr "" -"federated 학습에서 중앙 DP를 구현하는 방법은 여러 가지가 있지만, 여기서는 [2]" -"와 [3]에서 제안한 알고리즘에 집중합니다. 전반적인 접근 방식은 클라이언트가 " +"While there are various ways to implement central DP in federated learning, " +"we concentrate on the algorithms proposed by [2] and [3]. The overall " +"approach is to clip the model updates sent by the clients and add some " +"amount of noise to the aggregated model. In each iteration, a random set of " +"clients is chosen with a specific probability for training. Each client " +"performs local training on its own data. The update of each client is then " +"clipped by some value `S` (sensitivity `S`). This would limit the impact of " +"any individual client which is crucial for privacy and often beneficial for " +"robustness. A common approach to achieve this is by restricting the `L2` " +"norm of the clients' model updates, ensuring that larger updates are scaled " +"down to fit within the norm `S`." +msgstr "" +"연합 학습에서 중앙 DP를 구현하는 방법은 여러 가지가 있지만, 여기서는 [2]와 " +"[3]에서 제안한 알고리즘에 집중합니다. 전반적인 접근 방식은 클라이언트가 " "전송한 모델 업데이트를 잘라내고 집계된 모델에 약간의 노이즈를 추가하는 " "것입니다. 각 반복에서 특정 확률로 훈련할 무작위 클라이언트 세트가 " "선택됩니다. 각 클라이언트는 자체 데이터에 대해 로컬 학습을 수행합니다. 그런 " @@ -3380,17 +3432,17 @@ msgstr "클리핑" #: ../../source/explanation-differential-privacy.rst:89 msgid "" -"Afterwards, the Gaussian mechanism is used to add noise in order to " -"distort the sum of all clients' updates. The amount of noise is scaled to" -" the sensitivity value to obtain a privacy guarantee. The Gaussian " -"mechanism is used with a noise sampled from `N (0, σ²)` where `σ = ( " -"noise_scale * S ) / (number of sampled clients)`." +"Afterwards, the Gaussian mechanism is used to add noise in order to distort " +"the sum of all clients' updates. The amount of noise is scaled to the " +"sensitivity value to obtain a privacy guarantee. The Gaussian mechanism is " +"used with a noise sampled from `N (0, σ²)` where `σ = ( noise_scale * S ) / " +"(number of sampled clients)`." msgstr "" -"그 후 가우시안 메커니즘을 사용하여 모든 클라이언트의 업데이트 합계를 " -"왜곡하기 위해 노이즈를 추가합니다. 노이즈의 양은 감도 값에 따라 조정되어 " -"프라이버시 보장을 얻습니다. 가우시안 메커니즘은 `N (0, σ²)`에서 샘플링된 " -"노이즈와 함께 사용됩니다. 여기서 `σ = (noise_scale * S) / (샘플링된 " -"클라이언트 수)`입니다." +"그 후 가우시안 메커니즘을 사용하여 모든 클라이언트의 업데이트 합계를 왜곡하" +"기 위해 노이즈를 추가합니다. 노이즈의 양은 감도 값에 따라 조정되어 프라이버" +"시 보장을 얻습니다. 가우시안 메커니즘은 `N (0, σ²)`에서 샘플링된 노이즈와 함" +"께 사용됩니다. 여기서 `σ = (noise_scale * S) / (샘플링된 클라이언트 수)`입니" +"다." #: ../../source/explanation-differential-privacy.rst:94 msgid "Clipping" @@ -3398,39 +3450,40 @@ msgstr "클리핑" #: ../../source/explanation-differential-privacy.rst:96 msgid "" -"There are two forms of clipping commonly used in Central DP: Fixed " -"Clipping and Adaptive Clipping." -msgstr "Central DP에서 일반적으로 사용되는 클리핑에는 고정 클리핑과 조정 클리핑의 두 " +"There are two forms of clipping commonly used in Central DP: Fixed Clipping " +"and Adaptive Clipping." +msgstr "중앙 DP에서 일반적으로 사용되는 클리핑에는 고정 클리핑과 조정 클리핑의 두 " "가지 형태가 있습니다." #: ../../source/explanation-differential-privacy.rst:98 msgid "" -"**Fixed Clipping** : A predefined fix threshold is set for the magnitude " -"of clients' updates. Any update exceeding this threshold is clipped back " -"to the threshold value." +"**Fixed Clipping** : A predefined fix threshold is set for the magnitude of " +"clients' updates. Any update exceeding this threshold is clipped back to the " +"threshold value." msgstr "" -"**고정 클리핑** : 클라이언트의 업데이트 크기에 대해 미리 정의된 고정 " -"임계값이 설정됩니다. 이 임계값을 초과하는 모든 업데이트는 임계값으로 다시 " -"클리핑됩니다." +"**고정 클리핑** : 클라이언트의 업데이트 크기에 대해 미리 정의된 고정 임계값" +"이 설정됩니다. 이 임계값을 초과하는 모든 업데이트는 임계값으로 다시 클리핑됩" +"니다." #: ../../source/explanation-differential-privacy.rst:100 msgid "" -"**Adaptive Clipping** : The clipping threshold dynamically adjusts based " -"on the observed update distribution [4]. It means that the clipping value" -" is tuned during the rounds with respect to the quantile of the update " -"norm distribution." +"**Adaptive Clipping** : The clipping threshold dynamically adjusts based on " +"the observed update distribution [4]. It means that the clipping value is " +"tuned during the rounds with respect to the quantile of the update norm " +"distribution." msgstr "" -"**조 클리핑** : 클리핑 임계값은 관찰된 업데이트 분포에 따라 동적으로 " +"**조정 클리핑** : 클리핑 임계값은 관찰된 업데이트 분포에 따라 동적으로 " "조정됩니다[4]. 즉, 클리핑 값은 업데이트 표준 분포의 사분위수에 따라 라운드가 " "진행되는 동안 조정됩니다." #: ../../source/explanation-differential-privacy.rst:102 msgid "" -"The choice between fixed and adaptive clipping depends on various factors" -" such as privacy requirements, data distribution, model complexity, and " +"The choice between fixed and adaptive clipping depends on various factors " +"such as privacy requirements, data distribution, model complexity, and " "others." -msgstr "고정 클리핑과 조정 클리핑 중 선택은 개인정보 보호 요구 사항, 데이터 배포, " -"모델 복잡성 등 다양한 요인에 따라 달라집니다." +msgstr "" +"고정 클리핑과 조정 클리핑 중 선택은 개인정보 보호 요구 사항, 데이터 배포, 모" +"델 복잡성 등 다양한 요인에 따라 달라집니다." #: ../../source/explanation-differential-privacy.rst:-1 #: ../../source/explanation-differential-privacy.rst:105 @@ -3441,13 +3494,13 @@ msgstr "로컬 차분 프라이버시" #: ../../source/explanation-differential-privacy.rst:107 msgid "" "In this approach, each client is responsible for performing DP. Local DP " -"avoids the need for a fully trusted aggregator, but it should be noted " -"that local DP leads to a decrease in accuracy but better privacy in " -"comparison to central DP." +"avoids the need for a fully trusted aggregator, but it should be noted that " +"local DP leads to a decrease in accuracy but better privacy in comparison to " +"central DP." msgstr "" -"이 접근 방식에서는 각 클라이언트가 DP를 수행할 책임이 있습니다. 로컬 DP는 " -"완전히 신뢰할 수 있는 애그리게이터가 필요하지 않지만, 로컬 DP는 중앙 DP에 " -"비해 정확도는 떨어져도 개인 정보 보호는 더 우수하다는 점에 유의해야 합니다." +"이 접근 방식에서는 각 클라이언트가 DP를 수행할 책임이 있습니다. 로컬 DP는 완" +"전히 신뢰할 수 있는 애그리게이터가 필요하지 않지만, 로컬 DP는 중앙 DP에 비해 " +"정확도는 떨어져도 개인 정보 보호는 더 우수하다는 점에 유의해야 합니다." #: ../../source/explanation-differential-privacy.rst:116 msgid "In this explainer, we focus on two forms of achieving Local DP:" @@ -3456,25 +3509,25 @@ msgstr "이 설명에서는 로컬 DP를 달성하는 두 가지 형태에 중 #: ../../source/explanation-differential-privacy.rst:118 msgid "" "Each client adds noise to the local updates before sending them to the " -"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering " -"the sensitivity of the local model to be ∆, Gaussian noise is applied " -"with a noise scale of σ where:" +"server. To achieve (:math:`\\epsilon`, :math:`\\delta`)-DP, considering the " +"sensitivity of the local model to be ∆, Gaussian noise is applied with a " +"noise scale of σ where:" msgstr "" "각 클라이언트는 로컬 업데이트를 서버로 보내기 전에 로컬 업데이트에 노이즈를 " -"추가합니다. 로컬 모델의 감도를 ∆로 간주하여 가우시안 노이즈가 σ의 노이즈 " -"스케일로 적용되어 (:math:`\\epsilon`, :math:`\\delta`)-DP를 달성하기 위해, " -"여기서 σ는 노이즈 스케일입니다:" +"추가합니다. 로컬 모델의 감도를 ∆로 간주하여 가우시안 노이즈가 σ의 노이즈 스케" +"일로 적용되어 (:math:`\\epsilon`, :math:`\\delta`)-DP를 달성하기 위해, 여기" +"서 σ는 노이즈 스케일입니다:" #: ../../source/explanation-differential-privacy.rst:120 msgid "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times " -"\\log\\left(\\frac{1.25}{\\delta}\\right)}}{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" +"{\\epsilon}\n" "\n" msgstr "" "\\small\n" -"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right" -")}}{\\epsilon}\n" +"\\frac{∆ \\times \\sqrt{2 \\times \\log\\left(\\frac{1.25}{\\delta}\\right)}}" +"{\\epsilon}\n" "\n" #: ../../source/explanation-differential-privacy.rst:125 @@ -3483,15 +3536,16 @@ msgid "" "training (DP-SGD). More specifically, in this approach, gradients are " "clipped and an amount of calibrated noise is injected into the gradients." msgstr "" -"각 클라이언트는 로컬 트레이닝(DP-SGD) 중에 모델의 gradient에 노이즈를 " -"추가합니다. 보다 구체적으로, 이 접근 방식에서는 gradient이 클리핑되고 보정된 " -"노이즈가 gradient에 주입됩니다." +"각 클라이언트는 로컬 트레이닝(DP-SGD) 중에 모델의 gradient에 노이즈를 추가합" +"니다. 보다 구체적으로, 이 접근 방식에서는 gradient이 클리핑되고 보정된 노이즈" +"가 gradient에 주입됩니다." #: ../../source/explanation-differential-privacy.rst:128 msgid "" "Please note that these two approaches are providing privacy at different " "levels." -msgstr "이 두 가지 접근 방식은 서로 다른 수준의 개인정보 보호 기능을 제공한다는 점에 " +msgstr "" +"이 두 가지 접근 방식은 서로 다른 수준의 개인정보 보호 기능을 제공한다는 점에 " "유의하세요." #: ../../source/explanation-differential-privacy.rst:131 @@ -3504,38 +3558,37 @@ msgstr "[1] Dwork 외. 차분 프라이버시의 알고리즘적 기초." #: ../../source/explanation-differential-privacy.rst:135 msgid "" -"[2] McMahan et al. Learning Differentially Private Recurrent Language " -"Models." +"[2] McMahan et al. Learning Differentially Private Recurrent Language Models." msgstr "[2] McMahan 외. 차분적 개인 반복 언어 모델 학습." #: ../../source/explanation-differential-privacy.rst:137 msgid "" -"[3] Geyer et al. Differentially Private Federated Learning: A Client " -"Level Perspective." -msgstr "[3] Geyer 외. 차분적 개인 Federated 학습: 고객 수준의 관점." +"[3] Geyer et al. Differentially Private Federated Learning: A Client Level " +"Perspective." +msgstr "[3] Geyer 외. 차분적 개인 연합 학습: 고객 수준의 관점." #: ../../source/explanation-differential-privacy.rst:139 -msgid "[4] Galen et al. Differentially Private Learning with Adaptive Clipping." +msgid "" +"[4] Galen et al. Differentially Private Learning with Adaptive Clipping." msgstr "[4] Galen 외. 조정형 클리핑을 통한 차분적 개인 학습." #: ../../source/explanation-federated-evaluation.rst:2 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:292 msgid "Federated evaluation" -msgstr "Federated 평가" +msgstr "연합 평가" #: ../../source/explanation-federated-evaluation.rst:4 msgid "" "There are two main approaches to evaluating models in federated learning " -"systems: centralized (or server-side) evaluation and federated (or " -"client-side) evaluation." +"systems: centralized (or server-side) evaluation and federated (or client-" +"side) evaluation." msgstr "" -"federated 학습 시스템에서 모델을 평가하는 데는 centralized(또는 서버 측) " -"평가와 federated(또는 클라이언트 측) 평가라는 두 가지 주요 접근 방식이 " -"있습니다." +"연합 학습 시스템에서 모델을 평가하는 데는 중앙 집중식(또는 서버 측) 평가와 " +"연합(또는 클라이언트 측) 평가라는 두 가지 주요 접근 방식이 있습니다." #: ../../source/explanation-federated-evaluation.rst:8 msgid "Centralized Evaluation" -msgstr "Centralized 평가" +msgstr "중앙 집중식 평가" #: ../../source/explanation-federated-evaluation.rst:11 msgid "Built-In Strategies" @@ -3548,7 +3601,7 @@ msgid "" "function that can take the current global model parameters as input and " "return evaluation results:" msgstr "" -"모든 기본 제공 전략은 초기화 중에 평가 함수를 제공하여 centralized 평가를 " +"모든 기본 제공 전략은 초기화 중에 평가 함수를 제공하여 중앙 집중식 평가를 " "지원합니다. 평가 함수는 현재 글로벌 모델 파라미터를 입력으로 받아 평가 " "결과를 반환할 수 있는 모든 함수입니다:" @@ -3558,97 +3611,95 @@ msgstr "사용자 정의 전략" #: ../../source/explanation-federated-evaluation.rst:60 msgid "" -"The :code:`Strategy` abstraction provides a method called " -":code:`evaluate` that can directly be used to evaluate the current global" -" model parameters. The current server implementation calls " -":code:`evaluate` after parameter aggregation and before federated " -"evaluation (see next paragraph)." +"The :code:`Strategy` abstraction provides a method called :code:`evaluate` " +"that can directly be used to evaluate the current global model parameters. " +"The current server implementation calls :code:`evaluate` after parameter " +"aggregation and before federated evaluation (see next paragraph)." msgstr "" -"코드:`전략` 추상화는 현재 전역 모델 파라미터를 평가하는 데 직접 사용할 수 " -"있는 :코드:`평가`라는 메서드를 제공합니다. 현재 서버 구현에서는 매개변수 " -"집계 후와 연합 평가 전에 :code:`evaluate`를 호출합니다(다음 단락 참조)." +"코드:`전략` 추상화는 현재 전역 모델 파라미터를 평가하는 데 직접 사용할 수 있" +"는 :코드:`평가`라는 메서드를 제공합니다. 현재 서버 구현에서는 매개변수 집계 " +"후와 연합 평가 전에 :code:`evaluate`를 호출합니다(다음 단락 참조)." #: ../../source/explanation-federated-evaluation.rst:65 msgid "Federated Evaluation" -msgstr "Federated 평가" +msgstr "연합 평가" #: ../../source/explanation-federated-evaluation.rst:68 msgid "Implementing Federated Evaluation" -msgstr "Federated 평가 구현" +msgstr "연합 평가 구현" #: ../../source/explanation-federated-evaluation.rst:70 msgid "" -"Client-side evaluation happens in the :code:`Client.evaluate` method and " -"can be configured from the server side." -msgstr "클라이언트 측 평가는 :code:`Client.evaluate` 메서드에서 이루어지며 서버 " -"측에서 구성할 수 있습니다." +"Client-side evaluation happens in the :code:`Client.evaluate` method and can " +"be configured from the server side." +msgstr "" +"클라이언트 측 평가는 :code:`Client.evaluate` 메서드에서 이루어지며 서버 측에" +"서 구성할 수 있습니다." #: ../../source/explanation-federated-evaluation.rst:101 msgid "Configuring Federated Evaluation" -msgstr "Federated 평가 구성" +msgstr "연합 평가 구성" #: ../../source/explanation-federated-evaluation.rst:103 msgid "" "Federated evaluation can be configured from the server side. Built-in " "strategies support the following arguments:" -msgstr "Federated 평가는 서버 측에서 구성할 수 있습니다. 기본 제공 전략은 다음 " -"인수를 지원합니다:" +msgstr "연합 평가는 서버 측에서 구성할 수 있습니다. 기본 제공 전략은 다음 인수를 " +"지원합니다:" #: ../../source/explanation-federated-evaluation.rst:105 msgid "" -":code:`fraction_evaluate`: a :code:`float` defining the fraction of " -"clients that will be selected for evaluation. If " -":code:`fraction_evaluate` is set to :code:`0.1` and :code:`100` clients " -"are connected to the server, then :code:`10` will be randomly selected " -"for evaluation. If :code:`fraction_evaluate` is set to :code:`0.0`, " -"federated evaluation will be disabled." +":code:`fraction_evaluate`: a :code:`float` defining the fraction of clients " +"that will be selected for evaluation. If :code:`fraction_evaluate` is set " +"to :code:`0.1` and :code:`100` clients are connected to the server, then :" +"code:`10` will be randomly selected for evaluation. If :code:" +"`fraction_evaluate` is set to :code:`0.0`, federated evaluation will be " +"disabled." msgstr "" ":code:`fraction_evaluate`: 평가를 위해 선택될 클라이언트의 비율을 정의하는 " ":code:`float`입니다. 코드:`fraction_evaluate`가 :code:`0.1`로 설정되어 있고 " ":code:`100` 클라이언트가 서버에 연결되어 있는 경우 :code:`10`이 평가를 위해 " "무작위로 선택됩니다. code:`fraction_evaluate`가 :code:`0.0`으로 설정된 경우 " -"federated 평가가 비활성화됩니다." +"연합 평가가 비활성화됩니다." #: ../../source/explanation-federated-evaluation.rst:106 msgid "" -":code:`min_evaluate_clients`: an :code:`int`: the minimum number of " -"clients to be selected for evaluation. If :code:`fraction_evaluate` is " -"set to :code:`0.1`, :code:`min_evaluate_clients` is set to 20, and " -":code:`100` clients are connected to the server, then :code:`20` clients " -"will be selected for evaluation." +":code:`min_evaluate_clients`: an :code:`int`: the minimum number of clients " +"to be selected for evaluation. If :code:`fraction_evaluate` is set to :code:" +"`0.1`, :code:`min_evaluate_clients` is set to 20, and :code:`100` clients " +"are connected to the server, then :code:`20` clients will be selected for " +"evaluation." msgstr "" -":code:`min_evaluate_clients`: 평가를 위해 선택할 최소 클라이언트 수. " -":code:`int`. 코드:`fraction_evaluate`가 :code:`0.1`로 설정되어 있고 " -":code:`fraction_evaluate`가 20으로 설정되어 있으며 :code:`100` 클라이언트가 " -"서버에 연결되어 있는 경우 :code:`20` 클라이언트가 평가를 위해 선택됩니다." +":code:`min_evaluate_clients`: 평가를 위해 선택할 최소 클라이언트 수. :code:" +"`int`. 코드:`fraction_evaluate`가 :code:`0.1`로 설정되어 있고 :code:" +"`fraction_evaluate`가 20으로 설정되어 있으며 :code:`100` 클라이언트가 서버에 " +"연결되어 있는 경우 :code:`20` 클라이언트가 평가를 위해 선택됩니다." #: ../../source/explanation-federated-evaluation.rst:107 msgid "" ":code:`min_available_clients`: an :code:`int` that defines the minimum " -"number of clients which need to be connected to the server before a round" -" of federated evaluation can start. If fewer than " -":code:`min_available_clients` are connected to the server, the server " -"will wait until more clients are connected before it continues to sample " -"clients for evaluation." -msgstr "" -":code:`min_available_clients`: federated 평가 단계를 시작하기 전에 서버에 " -"연결해야 하는 최소 클라이언트 수를 정의하는 :code:`int`입니다. 서버에 연결된 " -"클라이언트가 :code:`min_available_clients`보다 적으면 서버는 더 많은 " -"클라이언트가 연결될 때까지 기다렸다가 평가를 위한 클라이언트 샘플링을 " -"계속합니다." +"number of clients which need to be connected to the server before a round of " +"federated evaluation can start. If fewer than :code:`min_available_clients` " +"are connected to the server, the server will wait until more clients are " +"connected before it continues to sample clients for evaluation." +msgstr "" +":code:`min_available_clients`: federated 평가 단계를 시작하기 전에 서버에 연" +"결해야 하는 최소 클라이언트 수를 정의하는 :code:`int`입니다. 서버에 연결된 클" +"라이언트가 :code:`min_available_clients`보다 적으면 서버는 더 많은 클라이언트" +"가 연결될 때까지 기다렸다가 평가를 위한 클라이언트 샘플링을 계속합니다." #: ../../source/explanation-federated-evaluation.rst:108 msgid "" ":code:`on_evaluate_config_fn`: a function that returns a configuration " -"dictionary which will be sent to the selected clients. The function will " -"be called during each round and provides a convenient way to customize " -"client-side evaluation from the server side, for example, to configure " -"the number of validation steps performed." +"dictionary which will be sent to the selected clients. The function will be " +"called during each round and provides a convenient way to customize client-" +"side evaluation from the server side, for example, to configure the number " +"of validation steps performed." msgstr "" -"code:`on_evaluate_config_fn`: 선택한 클라이언트로 전송할 구성 사전을 " -"반환하는 함수입니다. 이 함수는 각 단계 중에 호출되며, 서버 측에서 클라이언트 " -"측 평가를 사용자 지정하는 편리한 방법을 제공합니다(예: 수행되는 유효성 검사 " -"단계 수 구성)." +"code:`on_evaluate_config_fn`: 선택한 클라이언트로 전송할 구성 사전을 반환하" +"는 함수입니다. 이 함수는 각 단계 중에 호출되며, 서버 측에서 클라이언트 측 평" +"가를 사용자 지정하는 편리한 방법을 제공합니다(예: 수행되는 유효성 검사 단계 " +"수 구성)." #: ../../source/explanation-federated-evaluation.rst:135 msgid "Evaluating Local Model Updates During Training" @@ -3656,9 +3707,8 @@ msgstr "훈련 중 로컬 모델 업데이트 평가" #: ../../source/explanation-federated-evaluation.rst:137 msgid "" -"Model parameters can also be evaluated during training. " -":code:`Client.fit` can return arbitrary evaluation results as a " -"dictionary:" +"Model parameters can also be evaluated during training. :code:`Client.fit` " +"can return arbitrary evaluation results as a dictionary:" msgstr "" "모델 파라미터는 훈련 중에도 평가할 수 있습니다. :code:`Client.fit`은 임의의 " "평가 결과를 dictionary로 반환할 수 있습니다:" @@ -3669,12 +3719,12 @@ msgstr "전체 코드 예제" #: ../../source/explanation-federated-evaluation.rst:179 msgid "" -"For a full code example that uses both centralized and federated " -"evaluation, see the *Advanced TensorFlow Example* (the same approach can " -"be applied to workloads implemented in any other framework): " -"https://github.com/adap/flower/tree/main/examples/advanced-tensorflow" +"For a full code example that uses both centralized and federated evaluation, " +"see the *Advanced TensorFlow Example* (the same approach can be applied to " +"workloads implemented in any other framework): https://github.com/adap/" +"flower/tree/main/examples/advanced-tensorflow" msgstr "" -"federated 평가와 centralized 평가를 모두 사용하는 전체 코드 예제는 *고급 " +"연합 평가와 중앙 집중식 평가를 모두 사용하는 전체 코드 예제는 *고급 " "텐서플로우 예제*(다른 프레임워크에서 구현된 워크로드에도 동일한 접근 방식을 " "적용할 수 있음)를 참조하세요: https://github.com/adap/flower/tree/main/" "examples/advanced-tensorflow" @@ -3850,13 +3900,13 @@ msgstr "운행 중 작업 추적을 위한 깃허브 이슈를 예약합니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:37 msgid "" -"ensure community participants can successfully drive changes to " -"completion across one or more releases while stakeholders are adequately " -"represented throughout the process" +"ensure community participants can successfully drive changes to completion " +"across one or more releases while stakeholders are adequately represented " +"throughout the process" msgstr "" -"커뮤니티 참여자가 하나 이상의 릴리즈에서 변경 사항을 성공적으로 완료할 수 " -"있도록 하는 동시에 이해 관계자가 프로세스 전반에 걸쳐 적절히 대표되도록 " -"보장합니다" +"커뮤니티 참여자가 하나 이상의 릴리즈에서 변경 사항을 성공적으로 완료할 수 있" +"도록 하는 동시에 이해 관계자가 프로세스 전반에 걸쳐 적절히 대표되도록 보장합" +"니다" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:39 msgid "Hence, an Enhancement Doc combines aspects of" @@ -3883,72 +3933,72 @@ msgstr "를 하나의 파일로 통합하여 커뮤니티와 협력해 점진적 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:49 msgid "" "For far-fetching changes or features proposed to Flower, an abstraction " -"beyond a single GitHub issue or pull request is required to understand " -"and communicate upcoming changes to the project." +"beyond a single GitHub issue or pull request is required to understand and " +"communicate upcoming changes to the project." msgstr "" -"Flower에 제안된 변경 사항이나 기능을 멀리 가져오는 경우, 프로젝트의 향후 " -"변경 사항을 이해하고 전달하기 위해 단일 GitHub 이슈 또는 pull request를 " -"넘어서는 abstraction이 필요합니다." +"Flower에 제안된 변경 사항이나 기능을 멀리 가져오는 경우, 프로젝트의 향후 변" +"경 사항을 이해하고 전달하기 위해 단일 GitHub 이슈 또는 pull request를 넘어서" +"는 abstraction이 필요합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:51 msgid "" -"The purpose of this process is to reduce the amount of \"tribal " -"knowledge\" in our community. By moving decisions from Slack threads, " -"video calls, and hallway conversations into a well-tracked artifact, this" -" process aims to enhance communication and discoverability." +"The purpose of this process is to reduce the amount of \"tribal knowledge\" " +"in our community. By moving decisions from Slack threads, video calls, and " +"hallway conversations into a well-tracked artifact, this process aims to " +"enhance communication and discoverability." msgstr "" -"이 프로세스의 목적은 커뮤니티 내 '부족한 지식'의 양을 줄이는 것입니다. 이 " -"프로세스는 Slack 스레드, 영상 통화, 복도 대화에서 나온 의사 결정을 잘 추적된 " -"아티팩트로 옮김으로써 커뮤니케이션과 검색 가능성을 향상시키는 것을 목표로 " -"합니다." +"이 프로세스의 목적은 커뮤니티 내 '부족한 지식'의 양을 줄이는 것입니다. 이 프" +"로세스는 Slack 스레드, 영상 통화, 복도 대화에서 나온 의사 결정을 잘 추적된 아" +"티팩트로 옮김으로써 커뮤니케이션과 검색 가능성을 향상시키는 것을 목표로 합니" +"다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:55 msgid "" -"Roughly any larger, user-facing enhancement should follow the Enhancement" -" process. If an enhancement would be described in either written or " -"verbal communication to anyone besides the author or developer, then " -"consider creating an Enhancement Doc." +"Roughly any larger, user-facing enhancement should follow the Enhancement " +"process. If an enhancement would be described in either written or verbal " +"communication to anyone besides the author or developer, then consider " +"creating an Enhancement Doc." msgstr "" "대략적으로 사용자를 대상으로 하는 대규모 개선 사항은 개선 프로세스를 따라야 " -"합니다. 개선 사항을 작성자나 개발자 이외의 다른 사람에게 서면 또는 구두로 " -"설명해야 하는 경우에는 개선 문서 작성을 고려하세요." +"합니다. 개선 사항을 작성자나 개발자 이외의 다른 사람에게 서면 또는 구두로 설" +"명해야 하는 경우에는 개선 문서 작성을 고려하세요." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:57 msgid "" -"Similarly, any technical effort (refactoring, major architectural change)" -" that will impact a large section of the development community should " -"also be communicated widely. The Enhancement process is suited for this " -"even if it will have zero impact on the typical user or operator." +"Similarly, any technical effort (refactoring, major architectural change) " +"that will impact a large section of the development community should also be " +"communicated widely. The Enhancement process is suited for this even if it " +"will have zero impact on the typical user or operator." msgstr "" -"마찬가지로 개발 커뮤니티의 많은 부분에 영향을 미치는 기술적 노력(리팩토링, " -"주요 아키텍처 변경)도 널리 알려야 합니다. 개선 프로세스는 일반 사용자나 " -"운영자에게 전혀 영향을 미치지 않더라도 이를 위해 적합합니다." +"마찬가지로 개발 커뮤니티의 많은 부분에 영향을 미치는 기술적 노력(리팩토링, 주" +"요 아키텍처 변경)도 널리 알려야 합니다. 개선 프로세스는 일반 사용자나 운영자" +"에게 전혀 영향을 미치지 않더라도 이를 위해 적합합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:61 msgid "" -"For small changes and additions, going through the Enhancement process " -"would be time-consuming and unnecessary. This includes, for example, " -"adding new Federated Learning algorithms, as these only add features " -"without changing how Flower works or is used." +"For small changes and additions, going through the Enhancement process would " +"be time-consuming and unnecessary. This includes, for example, adding new " +"Federated Learning algorithms, as these only add features without changing " +"how Flower works or is used." msgstr "" "작은 변경 및 추가의 경우, 개선 프로세스를 거치는 것은 시간이 많이 걸리고 " -"불필요합니다. 예를 들어, 새로운 Federated 학습 알고리즘을 추가하는 것은 " -"Flower의 작동 방식이나 사용 방식을 변경하지 않고 기능만 추가하는 것이기 " -"때문입니다." +"불필요합니다. 예를 들어, 새로운 연합 학습 알고리즘을 추가하는 것은 Flower의 " +"작동 방식이나 사용 방식을 변경하지 않고 기능만 추가하는 것이기 때문입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:63 msgid "" "Enhancements are different from feature requests, as they are already " -"providing a laid-out path for implementation and are championed by " -"members of the community." -msgstr "기능 개선은 이미 구현할 수 있는 경로가 마련되어 있고 커뮤니티 구성원들이 " -"지지하는 것이므로 기능 요청과는 다릅니다." +"providing a laid-out path for implementation and are championed by members " +"of the community." +msgstr "" +"기능 개선은 이미 구현할 수 있는 경로가 마련되어 있고 커뮤니티 구성원들이 지지" +"하는 것이므로 기능 요청과는 다릅니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:67 msgid "" "An Enhancement is captured in a Markdown file that follows a defined " -"template and a workflow to review and store enhancement docs for " -"reference — the Enhancement Doc." +"template and a workflow to review and store enhancement docs for reference " +"— the Enhancement Doc." msgstr "" "개선 사항은 정의된 템플릿과 참조용으로 Enhancement Doc.를 검토하고 저장하는 " "워크플로우를 따르는 Markdown 파일에 캡처됩니다." @@ -4002,11 +4052,11 @@ msgstr "Metadata" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:92 msgid "" -"**fed-number** (Required) The `fed-number` of the last Flower Enhancement" -" Doc + 1. With this number, it becomes easy to reference other proposals." +"**fed-number** (Required) The `fed-number` of the last Flower Enhancement " +"Doc + 1. With this number, it becomes easy to reference other proposals." msgstr "" -"**피드 번호** (필수) 마지막 Flower Enhancement 문서의 `피드 번호` + 1. 이 " -"번호를 사용하면 다른 제안을 쉽게 참조할 수 있습니다." +"**피드 번호** (필수) 마지막 Flower Enhancement 문서의 `피드 번호` + 1. 이 번" +"호를 사용하면 다른 제안을 쉽게 참조할 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:94 msgid "**title** (Required) The title of the proposal in plain language." @@ -4014,33 +4064,35 @@ msgstr "**제목** (필수) 제안서의 제목을 평이한 언어로 입력합 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:96 msgid "" -"**status** (Required) The current status of the proposal. See " -"[workflow](#workflow) for the possible states." -msgstr "**상태** (필수) 제안의 현재 상태입니다. 가능한 상태는 [워크플로](#워크플로)" +"**status** (Required) The current status of the proposal. See [workflow]" +"(#workflow) for the possible states." +msgstr "" +"**상태** (필수) 제안의 현재 상태입니다. 가능한 상태는 [워크플로](#워크플로)" "를 참조하세요." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:98 msgid "" -"**authors** (Required) A list of authors of the proposal. This is simply " -"the GitHub ID." +"**authors** (Required) A list of authors of the proposal. This is simply the " +"GitHub ID." msgstr "**저자** (필수) 제안서의 작성자 목록입니다. 간단히 GitHub ID입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:100 msgid "" -"**creation-date** (Required) The date that the proposal was first " -"submitted in a PR." +"**creation-date** (Required) The date that the proposal was first submitted " +"in a PR." msgstr "**생성 날짜** (필수) PR에서 제안서를 처음 제출한 날짜입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:102 msgid "" "**last-updated** (Optional) The date that the proposal was last changed " "significantly." -msgstr "**마지막 업데이트** (선택 사항) 제안서가 마지막으로 크게 변경된 날짜입니다." +msgstr "" +"**마지막 업데이트** (선택 사항) 제안서가 마지막으로 크게 변경된 날짜입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:104 msgid "" -"**see-also** (Optional) A list of other proposals that are relevant to " -"this one." +"**see-also** (Optional) A list of other proposals that are relevant to this " +"one." msgstr "**함께 보기** (선택 사항) 이 제안과 관련된 다른 제안 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:106 @@ -4048,7 +4100,8 @@ msgid "**replaces** (Optional) A list of proposals that this one replaces." msgstr "**대체** (선택 사항) 이 제안이 대체하는 제안 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:108 -msgid "**superseded-by** (Optional) A list of proposals that this one supersedes." +msgid "" +"**superseded-by** (Optional) A list of proposals that this one supersedes." msgstr "**대체됨** (선택 사항) 이 제안이 대체하는 제안의 목록입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:111 @@ -4058,54 +4111,55 @@ msgstr "워크플로우" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:113 msgid "" "The idea forming the enhancement should already have been discussed or " -"pitched in the community. As such, it needs a champion, usually the " -"author, who shepherds the enhancement. This person also has to find " -"committers to Flower willing to review the proposal." +"pitched in the community. As such, it needs a champion, usually the author, " +"who shepherds the enhancement. This person also has to find committers to " +"Flower willing to review the proposal." msgstr "" -"개선 사항을 구성하는 아이디어는 이미 커뮤니티에서 논의되었거나 제안된 적이 " -"있어야 합니다. 따라서 개선 사항을 주도하는 사(보통 작성자)이 필요합니다. 이 " -"사람은 또한 제안을 검토할 의향이 있는 Flower 커미터를 찾아야 합니다." +"개선 사항을 구성하는 아이디어는 이미 커뮤니티에서 논의되었거나 제안된 적이 있" +"어야 합니다. 따라서 개선 사항을 주도하는 사(보통 작성자)이 필요합니다. 이 사" +"람은 또한 제안을 검토할 의향이 있는 Flower 커미터를 찾아야 합니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:115 msgid "" "New enhancements are checked in with a file name in the form of `NNNN-" -"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement " -"Doc number, to `enhancements`. All enhancements start in `provisional` " -"state as part of a pull request. Discussions are done as part of the pull" -" request review." +"YYYYMMDD-enhancement-title.md`, with `NNNN` being the Flower Enhancement Doc " +"number, to `enhancements`. All enhancements start in `provisional` state as " +"part of a pull request. Discussions are done as part of the pull request " +"review." msgstr "" -"새 개선 사항은 `NNNN-YYYYMMDD-enhancement-title.md` 형식의 파일 이름으로 " -"체크인되며, `NNNN`은 Flower 개선 문서 번호이고 `enhancements`에 해당합니다. " -"모든 개선 사항은 pull request의 일부로 `잠정` 상태에서 시작됩니다. 토론은 " -"pull request 검토의 일부로 이루어집니다." +"새 개선 사항은 `NNNN-YYYYMMDD-enhancement-title.md` 형식의 파일 이름으로 체크" +"인되며, `NNNN`은 Flower 개선 문서 번호이고 `enhancements`에 해당합니다. 모든 " +"개선 사항은 pull request의 일부로 `잠정` 상태에서 시작됩니다. 토론은 pull " +"request 검토의 일부로 이루어집니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:117 msgid "" -"Once an enhancement has been reviewed and approved, its status is changed" -" to `implementable`. The actual implementation is then done in separate " -"pull requests. These pull requests should mention the respective " -"enhancement as part of their description. After the implementation is " -"done, the proposal status is changed to `implemented`." +"Once an enhancement has been reviewed and approved, its status is changed to " +"`implementable`. The actual implementation is then done in separate pull " +"requests. These pull requests should mention the respective enhancement as " +"part of their description. After the implementation is done, the proposal " +"status is changed to `implemented`." msgstr "" -"개선 사항이 검토 및 승인되면 상태가 '구현 가능'으로 변경됩니다. 그런 다음 " -"실제 구현은 별도의 pull requests를 통해 이루어집니다. 이러한 pull requests는 " -"설명의 일부로 해당 개선 사항을 언급해야 합니다. 구현이 완료되면 제안 상태는 " -"'구현됨'으로 변경됩니다." +"개선 사항이 검토 및 승인되면 상태가 '구현 가능'으로 변경됩니다. 그런 다음 실" +"제 구현은 별도의 pull requests를 통해 이루어집니다. 이러한 pull requests는 설" +"명의 일부로 해당 개선 사항을 언급해야 합니다. 구현이 완료되면 제안 상태는 '구" +"현됨'으로 변경됩니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:119 msgid "" -"Under certain conditions, other states are possible. An Enhancement has " -"the following states:" -msgstr "특정 조건에서는 다른 상태도 가능합니다. 개선에는 다음과 같은 상태가 있습니다:" +"Under certain conditions, other states are possible. An Enhancement has the " +"following states:" +msgstr "" +"특정 조건에서는 다른 상태도 가능합니다. 개선에는 다음과 같은 상태가 있습니다:" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:121 msgid "" "`provisional`: The enhancement has been proposed and is actively being " -"defined. This is the starting state while the proposal is being fleshed " -"out and actively defined and discussed." +"defined. This is the starting state while the proposal is being fleshed out " +"and actively defined and discussed." msgstr "" -"'잠정적': 개선 사항이 제안되어 활발히 정의되고 있습니다. 제안이 구체화되고 " -"활발하게 정의 및 논의되는 동안의 시작 단계입니다." +"'잠정적': 개선 사항이 제안되어 활발히 정의되고 있습니다. 제안이 구체화되고 활" +"발하게 정의 및 논의되는 동안의 시작 단계입니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:122 msgid "`implementable`: The enhancement has been reviewed and approved." @@ -4118,15 +4172,17 @@ msgid "" msgstr "`구현됨`: 개선 사항이 구현되었으며 더 이상 활발히 변경되지 않습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:124 -msgid "`deferred`: The enhancement is proposed but not actively being worked on." +msgid "" +"`deferred`: The enhancement is proposed but not actively being worked on." msgstr "'지연됨': 개선 사항이 제안되었지만 아직 활발히 작업 중이 아닙니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:125 msgid "" -"`rejected`: The authors and reviewers have decided that this enhancement " -"is not moving forward." -msgstr "`거부됨`: 작성자와 검토자는 이 개선 사항을 더 이상 진행하지 않기로 " -"결정했습니다." +"`rejected`: The authors and reviewers have decided that this enhancement is " +"not moving forward." +msgstr "" +"`거부됨`: 작성자와 검토자는 이 개선 사항을 더 이상 진행하지 않기로 결정했습니" +"다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:126 msgid "`withdrawn`: The authors have withdrawn the enhancement." @@ -4138,21 +4194,21 @@ msgstr "'대체됨': 개선 사항이 새로운 개선 사항으로 대체되었 #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:131 msgid "" -"Adding an additional process to the ones already provided by GitHub " -"(Issues and Pull Requests) adds more complexity and can be a barrier for " -"potential first-time contributors." +"Adding an additional process to the ones already provided by GitHub (Issues " +"and Pull Requests) adds more complexity and can be a barrier for potential " +"first-time contributors." msgstr "" -"GitHub에서 이미 제공하는 프로세스(이슈 및 Pull Requests)에 추가 프로세스를 " -"추가하면 더 복잡해지고 잠재적인 처음인 기여자에게는 장벽이 될 수 있습니다." +"GitHub에서 이미 제공하는 프로세스(이슈 및 Pull Requests)에 추가 프로세스를 추" +"가하면 더 복잡해지고 잠재적인 처음인 기여자에게는 장벽이 될 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:133 msgid "" "Expanding the proposal template beyond the single-sentence description " -"currently required in the features issue template may be a heavy burden " -"for non-native English speakers." +"currently required in the features issue template may be a heavy burden for " +"non-native English speakers." msgstr "" -"현재 기능 이슈 템플릿에서 요구되는 한 문장 설명 이상으로 제안서 템플릿을 " -"확장하는 것은 영어가 모국어가 아닌 사용자에게는 큰 부담이 될 수 있습니다." +"현재 기능 이슈 템플릿에서 요구되는 한 문장 설명 이상으로 제안서 템플릿을 확장" +"하는 것은 영어가 모국어가 아닌 사용자에게는 큰 부담이 될 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:137 msgid "GitHub Issues" @@ -4161,19 +4217,19 @@ msgstr "GitHub 이슈" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:139 msgid "" "Using GitHub Issues for these kinds of enhancements is doable. One could " -"use, for example, tags, to differentiate and filter them from other " -"issues. The main issue is in discussing and reviewing an enhancement: " -"GitHub issues only have a single thread for comments. Enhancements " -"usually have multiple threads of discussion at the same time for various " -"parts of the doc. Managing these multiple discussions can be confusing " -"when using GitHub Issues." -msgstr "" -"이러한 종류의 개선을 위해 GitHub 이슈를 사용하면 가능합니다. 예를 들어 " -"태그를 사용하여 다른 이슈와 구별하고 필터링할 수 있습니다. 주요 이슈는 개선 " -"사항에 대해 토론하고 검토하는 것입니다: GitHub 이슈에는 댓글 스레드가 하나만 " -"있습니다. 개선 사항에는 일반적으로 문서의 여러 부분에 대해 동시에 여러 개의 " -"토론 스레드가 있습니다. GitHub 이슈를 사용할 때 이러한 여러 토론을 관리하면 " -"혼란스러울 수 있습니다." +"use, for example, tags, to differentiate and filter them from other issues. " +"The main issue is in discussing and reviewing an enhancement: GitHub issues " +"only have a single thread for comments. Enhancements usually have multiple " +"threads of discussion at the same time for various parts of the doc. " +"Managing these multiple discussions can be confusing when using GitHub " +"Issues." +msgstr "" +"이러한 종류의 개선을 위해 GitHub 이슈를 사용하면 가능합니다. 예를 들어 태그" +"를 사용하여 다른 이슈와 구별하고 필터링할 수 있습니다. 주요 이슈는 개선 사항" +"에 대해 토론하고 검토하는 것입니다: GitHub 이슈에는 댓글 스레드가 하나만 있습" +"니다. 개선 사항에는 일반적으로 문서의 여러 부분에 대해 동시에 여러 개의 토론 " +"스레드가 있습니다. GitHub 이슈를 사용할 때 이러한 여러 토론을 관리하면 혼란스" +"러울 수 있습니다." #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:141 msgid "Google Docs" @@ -4181,17 +4237,16 @@ msgstr "Google 문서 도구" #: ../../source/fed/0001-20220311-flower-enhancement-doc.md:143 msgid "" -"Google Docs allow for multiple threads of discussions. But as Google Docs" -" are hosted outside the project, their discoverability by the community " -"needs to be taken care of. A list of links to all proposals has to be " -"managed and made available for the community. Compared to shipping " -"proposals as part of Flower's repository, the potential for missing links" -" is much higher." +"Google Docs allow for multiple threads of discussions. But as Google Docs " +"are hosted outside the project, their discoverability by the community needs " +"to be taken care of. A list of links to all proposals has to be managed and " +"made available for the community. Compared to shipping proposals as part of " +"Flower's repository, the potential for missing links is much higher." msgstr "" "Google 문서는 여러 스레드의 토론을 허용합니다. 하지만 Google 문서는 프로젝트 " -"외부에서 호스팅되므로 커뮤니티에서 검색할 수 있도록 관리해야 합니다. 모든 " -"제안에 대한 링크 목록을 관리하고 커뮤니티에 제공해야 합니다. Flower 저장소의 " -"일부로 제안서를 보낼 때와 비교하면 링크가 누락될 가능성이 훨씬 더 높습니다." +"외부에서 호스팅되므로 커뮤니티에서 검색할 수 있도록 관리해야 합니다. 모든 제" +"안에 대한 링크 목록을 관리하고 커뮤니티에 제공해야 합니다. Flower 저장소의 일" +"부로 제안서를 보낼 때와 비교하면 링크가 누락될 가능성이 훨씬 더 높습니다." #: ../../source/fed/index.md:1 msgid "FED - Flower Enhancement Doc" @@ -4203,9 +4258,10 @@ msgstr "종합 평가 결과" #: ../../source/how-to-aggregate-evaluation-results.rst:4 msgid "" -"The Flower server does not prescribe a way to aggregate evaluation " -"results, but it enables the user to fully customize result aggregation." -msgstr "Flower 서버는 평가 결과를 집계하는 방법을 규정하고 있지 않지만 사용자가 결과 " +"The Flower server does not prescribe a way to aggregate evaluation results, " +"but it enables the user to fully customize result aggregation." +msgstr "" +"Flower 서버는 평가 결과를 집계하는 방법을 규정하고 있지 않지만 사용자가 결과 " "집계를 완전히 사용자 지정할 수 있습니다." #: ../../source/how-to-aggregate-evaluation-results.rst:8 @@ -4214,20 +4270,21 @@ msgstr "사용자 지정 평가 결과 집계" #: ../../source/how-to-aggregate-evaluation-results.rst:10 msgid "" -"The same :code:`Strategy`-customization approach can be used to aggregate" -" custom evaluation results coming from individual clients. Clients can " -"return custom metrics to the server by returning a dictionary:" +"The same :code:`Strategy`-customization approach can be used to aggregate " +"custom evaluation results coming from individual clients. Clients can return " +"custom metrics to the server by returning a dictionary:" msgstr "" -"동일한 :code:`Strategy`-사용자 지정 방식을 사용하여 개별 클라이언트로부터 " -"오는 사용자 지정 평가 결과를 집계할 수 있습니다. 클라이언트는 dictionary를 " -"반환하여 사용자 지정 지표를 서버에 반환할 수 있습니다:" +"동일한 :code:`Strategy`-사용자 지정 방식을 사용하여 개별 클라이언트로부터 오" +"는 사용자 지정 평가 결과를 집계할 수 있습니다. 클라이언트는 dictionary를 반환" +"하여 사용자 지정 지표를 서버에 반환할 수 있습니다:" #: ../../source/how-to-aggregate-evaluation-results.rst:36 msgid "" "The server can then use a customized strategy to aggregate the metrics " "provided in these dictionaries:" -msgstr "그런 다음 서버는 사용자 지정 전략을 사용하여 이러한 dictionaries에서 " -"제공하는 메트릭을 집계할 수 있습니다:" +msgstr "" +"그런 다음 서버는 사용자 지정 전략을 사용하여 이러한 dictionaries에서 제공하" +"는 메트릭을 집계할 수 있습니다:" #: ../../source/how-to-authenticate-supernodes.rst:2 msgid "Authenticate SuperNodes" @@ -4235,13 +4292,12 @@ msgstr "SuperNodes 인증하기" #: ../../source/how-to-authenticate-supernodes.rst:4 msgid "" -"Flower has built-in support for authenticated SuperNodes that you can use" -" to verify the identities of each SuperNode connecting to a SuperLink. " -"Flower node authentication works similar to how GitHub SSH authentication" -" works:" +"Flower has built-in support for authenticated SuperNodes that you can use to " +"verify the identities of each SuperNode connecting to a SuperLink. Flower " +"node authentication works similar to how GitHub SSH authentication works:" msgstr "" -"Flower는 SuperLink에 연결하는 각 SuperNodes의 신원을 확인하는 데 사용할 수 " -"있는 인증된 SuperNodes에 대한 기본 지원을 제공합니다. Flower 노드 인증은 " +"Flower는 SuperLink에 연결하는 각 SuperNodes의 신원을 확인하는 데 사용할 수 있" +"는 인증된 SuperNodes에 대한 기본 지원을 제공합니다. Flower 노드 인증은 " "GitHub SSH 인증 방식과 유사하게 작동합니다:" #: ../../source/how-to-authenticate-supernodes.rst:7 @@ -4250,16 +4306,17 @@ msgstr "SuperLink(서버)는 알려진 (클라이언트) 노드 공개키 목록 #: ../../source/how-to-authenticate-supernodes.rst:8 msgid "" -"Using ECDH, both SuperNode and SuperLink independently derive a shared " -"secret" -msgstr "SuperNode와 SuperLink는 ECDH를 사용하여 독립적으로 공유된 비밀을 도출합니다" +"Using ECDH, both SuperNode and SuperLink independently derive a shared secret" +msgstr "" +"SuperNode와 SuperLink는 ECDH를 사용하여 독립적으로 공유된 비밀을 도출합니다" #: ../../source/how-to-authenticate-supernodes.rst:9 msgid "" "Shared secret is used to compute the HMAC value of the message sent from " "SuperNode to SuperLink as a token" -msgstr "비밀 공유는 SuperNode에서 SuperLink로 토큰으로 전송된 메시지의 HMAC 값을 " -"계산하는 데 사용됩니다" +msgstr "" +"비밀 공유는 SuperNode에서 SuperLink로 토큰으로 전송된 메시지의 HMAC 값을 계산" +"하는 데 사용됩니다" #: ../../source/how-to-authenticate-supernodes.rst:10 msgid "SuperLink verifies the token" @@ -4267,27 +4324,28 @@ msgstr "SuperLink가 토큰을 확인합니다" #: ../../source/how-to-authenticate-supernodes.rst:12 msgid "" -"We recommend you to check out the complete `code example " -"`_ demonstrating federated learning with Flower in an " -"authenticated setting." +"We recommend you to check out the complete `code example `_ demonstrating " +"federated learning with Flower in an authenticated setting." msgstr "" -"인증된 환경에서 Flower로 federated 학습을 시연하는 전체 '코드 예제 " -"`" -"_를 확인하는 것이 좋습니다." +"인증된 환경에서 Flower로 연합 학습을 시연하는 전체 '코드 예제 `_를 확인하는 것이 " +"좋습니다." #: ../../source/how-to-authenticate-supernodes.rst:15 msgid "" -"This guide covers a preview feature that might change in future versions " -"of Flower." -msgstr "이 가이드에서는 향후 버전의 Flower에서 변경될 수 있는 미리보기 기능에 대해 " -"설명합니다." +"This guide covers a preview feature that might change in future versions of " +"Flower." +msgstr "" +"이 가이드에서는 향후 버전의 Flower에서 변경될 수 있는 미리보기 기능에 대해 설" +"명합니다." #: ../../source/how-to-authenticate-supernodes.rst:18 msgid "" -"For increased security, node authentication can only be used when " -"encrypted connections (SSL/TLS) are enabled." -msgstr "보안을 강화하기 위해 노드 인증은 암호화된 연결(SSL/TLS)을 사용하도록 설정한 " +"For increased security, node authentication can only be used when encrypted " +"connections (SSL/TLS) are enabled." +msgstr "" +"보안을 강화하기 위해 노드 인증은 암호화된 연결(SSL/TLS)을 사용하도록 설정한 " "경우에만 사용할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:21 @@ -4297,20 +4355,19 @@ msgstr ":code:`SuperLink`에서 노드 인증 활성화" #: ../../source/how-to-authenticate-supernodes.rst:23 msgid "" "To enable node authentication, first you need to configure SSL/TLS " -"connections to secure the SuperLink<>SuperNode communication. You can " -"find the complete guide `here `_. After configuring secure connections, you" -" can enable client authentication in a long-running Flower " -":code:`SuperLink`. Use the following terminal command to start a Flower " -":code:`SuperNode` that has both secure connections and node " -"authentication enabled:" +"connections to secure the SuperLink<>SuperNode communication. You can find " +"the complete guide `here `_. After configuring secure connections, you can enable " +"client authentication in a long-running Flower :code:`SuperLink`. Use the " +"following terminal command to start a Flower :code:`SuperNode` that has both " +"secure connections and node authentication enabled:" msgstr "" "노드 인증을 활성화하려면 먼저 SuperLink<>SuperNode 통신을 보호하기 위해 SSL/" "TLS 연결을 구성해야 합니다. 전체 가이드는 `여기 `_에서 확인할 수 있습니다. 보안 " -"연결을 구성한 후, 장기 실행하는 Flower :code:`SuperLink`에서 클라이언트 " -"인증을 활성화할 수 있습니다. 다음 터미널 명령을 사용하여 보안 연결과 노드 " -"인증이 모두 활성화된 Flower :code:`SuperNode`를 시작하세요:" +"연결을 구성한 후, 장기 실행하는 Flower :code:`SuperLink`에서 클라이언트 인증" +"을 활성화할 수 있습니다. 다음 터미널 명령을 사용하여 보안 연결과 노드 인증이 " +"모두 활성화된 Flower :code:`SuperNode`를 시작하세요:" #: ../../source/how-to-authenticate-supernodes.rst:38 msgid "Let's break down the authentication flags:" @@ -4318,51 +4375,51 @@ msgstr "인증 플래그를 세분화해 보겠습니다:" #: ../../source/how-to-authenticate-supernodes.rst:40 msgid "" -"The first flag :code:`--auth-list-public-keys` expects a path to a CSV " -"file storing all known node public keys. You need to store all known node" -" public keys that are allowed to participate in a federation in one CSV " -"file (:code:`.csv`)." +"The first flag :code:`--auth-list-public-keys` expects a path to a CSV file " +"storing all known node public keys. You need to store all known node public " +"keys that are allowed to participate in a federation in one CSV file (:code:" +"`.csv`)." msgstr "" -"첫 번째 플래그 :code:`--auth-list-public-keys`는 알려진 모든 노드 공개키를 " -"저장하는 CSV 파일의 경로를 기대합니다. federation에 참여하도록 허용된 모든 " -"알려진 노드 공개 키를 하나의 CSV 파일(:code:`.csv`)에 저장해야 합니다." +"첫 번째 플래그 :code:`--auth-list-public-keys`는 알려진 모든 노드 공개키를 저" +"장하는 CSV 파일의 경로를 기대합니다. federation에 참여하도록 허용된 모든 알려" +"진 노드 공개 키를 하나의 CSV 파일(:code:`.csv`)에 저장해야 합니다." #: ../../source/how-to-authenticate-supernodes.rst:42 msgid "" "A valid CSV file storing known node public keys should list the keys in " "OpenSSH format, separated by commas and without any comments. For an " -"example, refer to our code sample, which contains a CSV file with two " -"known node public keys." +"example, refer to our code sample, which contains a CSV file with two known " +"node public keys." msgstr "" "알려진 노드 공개키를 저장하는 유효한 CSV 파일은 쉼표로 구분하고 주석 없이 " -"OpenSSH 형식으로 키를 나열해야 합니다. 예를 들어, 두 개의 알려진 노드 " -"공개키가 포함된 CSV 파일이 포함된 코드 샘플을 참조하세요." +"OpenSSH 형식으로 키를 나열해야 합니다. 예를 들어, 두 개의 알려진 노드 공개키" +"가 포함된 CSV 파일이 포함된 코드 샘플을 참조하세요." #: ../../source/how-to-authenticate-supernodes.rst:44 msgid "" -"The second and third flags :code:`--auth-superlink-private-key` and :code" -":`--auth-superlink-public-key` expect paths to the server's private and " -"public keys. For development purposes, you can generate a private and " -"public key pair using :code:`ssh-keygen -t ecdsa -b 384`." +"The second and third flags :code:`--auth-superlink-private-key` and :code:`--" +"auth-superlink-public-key` expect paths to the server's private and public " +"keys. For development purposes, you can generate a private and public key " +"pair using :code:`ssh-keygen -t ecdsa -b 384`." msgstr "" -"두 번째 및 세 번째 플래그 :code:`--auth-superlink-private-key` 및 :code" -":`--auth-superlink-public-key`는 서버의 개인 및 공개 키의 경로를 예상합니다. " -"개발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 및 공개 키 " -"쌍을 생성할 수 있습니다." +"두 번째 및 세 번째 플래그 :code:`--auth-superlink-private-key` 및 :code:`--" +"auth-superlink-public-key`는 서버의 개인 및 공개 키의 경로를 예상합니다. 개" +"발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 및 공개 키 쌍" +"을 생성할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:47 msgid "" "In Flower 1.9, there is no support for dynamically removing, editing, or " -"adding known node public keys to the SuperLink. To change the set of " -"known nodes, you need to shut the server down, edit the CSV file, and " -"start the server again. Support for dynamically changing the set of known" -" nodes is on the roadmap to be released in Flower 1.10 (ETA: June)." +"adding known node public keys to the SuperLink. To change the set of known " +"nodes, you need to shut the server down, edit the CSV file, and start the " +"server again. Support for dynamically changing the set of known nodes is on " +"the roadmap to be released in Flower 1.10 (ETA: June)." msgstr "" -"Flower 1.9에서는 알려진 노드 공개키를 SuperLink에 동적으로 제거, 편집 또는 " -"추가하는 기능이 지원되지 않습니다. 알려진 노드 집합을 변경하려면 서버를 " -"종료하고 CSV 파일을 편집한 다음 서버를 다시 시작해야 합니다. 알려진 노드 " -"집합을 동적으로 변경하는 기능은 Flower 1.10(출시 예정일: 6월)에서 로드맵에 " -"포함되어 있습니다." +"Flower 1.9에서는 알려진 노드 공개키를 SuperLink에 동적으로 제거, 편집 또는 추" +"가하는 기능이 지원되지 않습니다. 알려진 노드 집합을 변경하려면 서버를 종료하" +"고 CSV 파일을 편집한 다음 서버를 다시 시작해야 합니다. 알려진 노드 집합을 동" +"적으로 변경하는 기능은 Flower 1.10(출시 예정일: 6월)에서 로드맵에 포함되어 있" +"습니다." #: ../../source/how-to-authenticate-supernodes.rst:53 msgid "Enable node authentication in :code:`SuperNode`" @@ -4371,26 +4428,26 @@ msgstr ":code:`SuperNode`에서 노드 인증을 활성화합니다" #: ../../source/how-to-authenticate-supernodes.rst:55 msgid "" "Similar to the long-running Flower server (:code:`SuperLink`), you can " -"easily enable node authentication in the long-running Flower client " -"(:code:`SuperNode`). Use the following terminal command to start an " -"authenticated :code:`SuperNode`:" +"easily enable node authentication in the long-running Flower client (:code:" +"`SuperNode`). Use the following terminal command to start an authenticated :" +"code:`SuperNode`:" msgstr "" "장기 실행 중인 Flower 서버(:code:`SuperLink`)와 마찬가지로, 장기 실행 중인 " -"Flower 클라이언트(:code:`SuperNode`)에서도 노드 인증을 쉽게 활성화할 수 " -"있습니다. 다음 터미널 명령을 사용하여 인증된 :code:`SuperNode`를 시작하세요:" +"Flower 클라이언트(:code:`SuperNode`)에서도 노드 인증을 쉽게 활성화할 수 있습" +"니다. 다음 터미널 명령을 사용하여 인증된 :code:`SuperNode`를 시작하세요:" #: ../../source/how-to-authenticate-supernodes.rst:66 msgid "" -"The :code:`--auth-supernode-private-key` flag expects a path to the " -"node's private key file and the :code:`--auth-supernode-public-key` flag " -"expects a path to the node's public key file. For development purposes, " -"you can generate a private and public key pair using :code:`ssh-keygen -t" -" ecdsa -b 384`." +"The :code:`--auth-supernode-private-key` flag expects a path to the node's " +"private key file and the :code:`--auth-supernode-public-key` flag expects a " +"path to the node's public key file. For development purposes, you can " +"generate a private and public key pair using :code:`ssh-keygen -t ecdsa -b " +"384`." msgstr "" -":code:`--auth-supernode-private-key` 플래그는 노드의 개인 키 파일 경로를, " -":code:`--auth-supernode-public-key` 플래그는 노드의 공개 키 파일 경로를 " -"예상합니다. 개발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 " -"및 공개 키 쌍을 생성할 수 있습니다." +":code:`--auth-supernode-private-key` 플래그는 노드의 개인 키 파일 경로를, :" +"code:`--auth-supernode-public-key` 플래그는 노드의 공개 키 파일 경로를 예상합" +"니다. 개발 목적으로 :code:`ssh-keygen -t ecdsa -b 384`를 사용하여 개인 및 공" +"개 키 쌍을 생성할 수 있습니다." #: ../../source/how-to-authenticate-supernodes.rst:70 msgid "Security notice" @@ -4398,19 +4455,18 @@ msgstr "보안 공지" #: ../../source/how-to-authenticate-supernodes.rst:72 msgid "" -"The system's security relies on the credentials of the SuperLink and each" -" SuperNode. Therefore, it is imperative to safeguard and safely store the" -" credentials to avoid security risks such as Public Key Infrastructure " -"(PKI) impersonation attacks. The node authentication mechanism also " -"involves human interaction, so please ensure that all of the " -"communication is done in a secure manner, using trusted communication " -"methods." +"The system's security relies on the credentials of the SuperLink and each " +"SuperNode. Therefore, it is imperative to safeguard and safely store the " +"credentials to avoid security risks such as Public Key Infrastructure (PKI) " +"impersonation attacks. The node authentication mechanism also involves human " +"interaction, so please ensure that all of the communication is done in a " +"secure manner, using trusted communication methods." msgstr "" -"시스템의 보안은 SuperLink와 각SuperNode의 자격 증명에 의존합니다. 따라서 " -"공개키 기반구조(PKI) 사칭 공격과 같은 보안 위험을 피하기 위해 자격 증명을 " -"보호하고 안전하게 보관하는 것이 필수적입니다. 노드 인증 메커니즘에는 사람의 " -"상호 작용도 포함되므로 모든 통신이 신뢰할 수 있는 통신 방법을 사용하여 " -"안전한 방식으로 이루어지도록 하세요." +"시스템의 보안은 SuperLink와 각SuperNode의 자격 증명에 의존합니다. 따라서 공개" +"키 기반구조(PKI) 사칭 공격과 같은 보안 위험을 피하기 위해 자격 증명을 보호하" +"고 안전하게 보관하는 것이 필수적입니다. 노드 인증 메커니즘에는 사람의 상호 작" +"용도 포함되므로 모든 통신이 신뢰할 수 있는 통신 방법을 사용하여 안전한 방식으" +"로 이루어지도록 하세요." #: ../../source/how-to-authenticate-supernodes.rst:77 #: ../../source/how-to-enable-ssl-connections.rst:68 @@ -4421,15 +4477,15 @@ msgstr "결론" #: ../../source/how-to-authenticate-supernodes.rst:79 msgid "" -"You should now have learned how to start a long-running Flower server " -"(:code:`SuperLink`) and client (:code:`SuperNode`) with node " -"authentication enabled. You should also know the significance of the " -"private key and store it safely to minimize security risks." +"You should now have learned how to start a long-running Flower server (:code:" +"`SuperLink`) and client (:code:`SuperNode`) with node authentication " +"enabled. You should also know the significance of the private key and store " +"it safely to minimize security risks." msgstr "" -"이제 노드 인증이 활성화된 상태에서 장기간 실행되는 Flower " -"서버(:code:`SuperLink`)와 클라이언트(:code:`SuperNode`)를 시작하는 방법을 " -"배웠을 것입니다. 또한 보안 위험을 최소화하기 위해 개인키의 중요성을 알고 " -"안전하게 보관해야 합니다." +"이제 노드 인증이 활성화된 상태에서 장기간 실행되는 Flower 서버(:code:" +"`SuperLink`)와 클라이언트(:code:`SuperNode`)를 시작하는 방법을 배웠을 것입니" +"다. 또한 보안 위험을 최소화하기 위해 개인키의 중요성을 알고 안전하게 보관해" +"야 합니다." #: ../../source/how-to-configure-clients.rst:2 msgid "Configure clients" @@ -4438,13 +4494,13 @@ msgstr "클라이언트 구성" #: ../../source/how-to-configure-clients.rst:4 msgid "" "Along with model parameters, Flower can send configuration values to " -"clients. Configuration values can be used for various purposes. They are," -" for example, a popular way to control client-side hyperparameters from " -"the server." +"clients. Configuration values can be used for various purposes. They are, " +"for example, a popular way to control client-side hyperparameters from the " +"server." msgstr "" -"모델 파라미터와 함께 Flower는 설정 값을 클라이언트에 전송할 수 있습니다. " -"구성 값은 다양한 용도로 사용할 수 있습니다. 예를 들어 서버에서 클라이언트 측 " -"하이퍼파라미터를 제어하는 데 널리 사용되는 방법입니다." +"모델 파라미터와 함께 Flower는 설정 값을 클라이언트에 전송할 수 있습니다. 구" +"성 값은 다양한 용도로 사용할 수 있습니다. 예를 들어 서버에서 클라이언트 측 하" +"이퍼파라미터를 제어하는 데 널리 사용되는 방법입니다." #: ../../source/how-to-configure-clients.rst:7 msgid "Configuration values" @@ -4452,48 +4508,48 @@ msgstr "구성 값" #: ../../source/how-to-configure-clients.rst:9 msgid "" -"Configuration values are represented as a dictionary with ``str`` keys " -"and values of type ``bool``, ``bytes``, ``double`` (64-bit precision " -"float), ``int``, or ``str`` (or equivalent types in different languages)." -" Here is an example of a configuration dictionary in Python:" +"Configuration values are represented as a dictionary with ``str`` keys and " +"values of type ``bool``, ``bytes``, ``double`` (64-bit precision float), " +"``int``, or ``str`` (or equivalent types in different languages). Here is an " +"example of a configuration dictionary in Python:" msgstr "" "구성 값은 ``str`` 키와 ``bool``, ``bytes``, ``double``(64비트 정밀도 정수), " -"``int`` 또는 ``str``(또는 다른 언어의 동등한 유형) 유형의 값으로 구성된 " -"사전으로 표현됩니다. 다음은 Python의 구성 사전 예제입니다:" +"``int`` 또는 ``str``(또는 다른 언어의 동등한 유형) 유형의 값으로 구성된 사전" +"으로 표현됩니다. 다음은 Python의 구성 사전 예제입니다:" #: ../../source/how-to-configure-clients.rst:20 msgid "" "Flower serializes these configuration dictionaries (or *config dict* for " -"short) to their ProtoBuf representation, transports them to the client " -"using gRPC, and then deserializes them back to Python dictionaries." +"short) to their ProtoBuf representation, transports them to the client using " +"gRPC, and then deserializes them back to Python dictionaries." msgstr "" -"Flower는 이러한 구성 dictionaries(또는 줄여서 *config dict*)를 ProtoBuf " -"표현으로 직렬화하고, gRPC를 사용하여 클라이언트로 전송한 다음 다시 Python " +"Flower는 이러한 구성 dictionaries(또는 줄여서 *config dict*)를 ProtoBuf 표현" +"으로 직렬화하고, gRPC를 사용하여 클라이언트로 전송한 다음 다시 Python " "dictionaries로 역직렬화합니다." #: ../../source/how-to-configure-clients.rst:24 msgid "" -"Currently, there is no support for directly sending collection types " -"(e.g., ``Set``, ``List``, ``Map``) as values in configuration " -"dictionaries. There are several workarounds to send collections as values" -" by converting them to one of the supported value types (and converting " -"them back on the client-side)." +"Currently, there is no support for directly sending collection types (e.g., " +"``Set``, ``List``, ``Map``) as values in configuration dictionaries. There " +"are several workarounds to send collections as values by converting them to " +"one of the supported value types (and converting them back on the client-" +"side)." msgstr "" "현재 구성 사전에서 컬렉션 유형(예: ``Set``, ``List``, ``Map``)을 값으로 직접 " -"전송하는 기능은 지원되지 않습니다. 컬렉션을 지원되는 값 유형 중 하나로 " -"변환한 다음 클라이언트 측에서 다시 변환하여 값으로 보내는 몇 가지 해결 " -"방법이 있습니다." +"전송하는 기능은 지원되지 않습니다. 컬렉션을 지원되는 값 유형 중 하나로 변환" +"한 다음 클라이언트 측에서 다시 변환하여 값으로 보내는 몇 가지 해결 방법이 있" +"습니다." #: ../../source/how-to-configure-clients.rst:26 msgid "" "One can, for example, convert a list of floating-point numbers to a JSON " -"string, then send the JSON string using the configuration dictionary, and" -" then convert the JSON string back to a list of floating-point numbers on" -" the client." +"string, then send the JSON string using the configuration dictionary, and " +"then convert the JSON string back to a list of floating-point numbers on the " +"client." msgstr "" -"예를 들어 부동 소수점 숫자 목록을 JSON 문자열로 변환한 다음 구성 " -"dictionary을 사용하여 JSON 문자열을 전송한 다음 클라이언트에서 다시 부동 " -"소수점 숫자 목록으로 변환할 수 있습니다." +"예를 들어 부동 소수점 숫자 목록을 JSON 문자열로 변환한 다음 구성 dictionary" +"을 사용하여 JSON 문자열을 전송한 다음 클라이언트에서 다시 부동 소수점 숫자 목" +"록으로 변환할 수 있습니다." #: ../../source/how-to-configure-clients.rst:30 msgid "Configuration through built-in strategies" @@ -4501,68 +4557,68 @@ msgstr "기본 제공 전략을 통한 구성" #: ../../source/how-to-configure-clients.rst:32 msgid "" -"The easiest way to send configuration values to clients is to use a " -"built-in strategy like :code:`FedAvg`. Built-in strategies support so-" -"called configuration functions. A configuration function is a function " -"that the built-in strategy calls to get the configuration dictionary for " -"the current round. It then forwards the configuration dictionary to all " -"the clients selected during that round." +"The easiest way to send configuration values to clients is to use a built-in " +"strategy like :code:`FedAvg`. Built-in strategies support so-called " +"configuration functions. A configuration function is a function that the " +"built-in strategy calls to get the configuration dictionary for the current " +"round. It then forwards the configuration dictionary to all the clients " +"selected during that round." msgstr "" -"클라이언트에 구성 값을 보내는 가장 쉬운 방법은 :code:`FedAvg`와 같은 기본 " -"제공 전략을 사용하는 것입니다. 기본 제공 전략은 소위 구성 함수를 지원합니다. " -"구성 함수는 내장 전략이 현재 단계의 구성 사전을 가져오기 위해 호출하는 " -"함수입니다. 그런 다음 해당 단계 동안 선택된 모든 클라이언트에 구성 사전을 " -"전달합니다." +"클라이언트에 구성 값을 보내는 가장 쉬운 방법은 :code:`FedAvg`와 같은 기본 제" +"공 전략을 사용하는 것입니다. 기본 제공 전략은 소위 구성 함수를 지원합니다. 구" +"성 함수는 내장 전략이 현재 단계의 구성 사전을 가져오기 위해 호출하는 함수입니" +"다. 그런 다음 해당 단계 동안 선택된 모든 클라이언트에 구성 사전을 전달합니다." #: ../../source/how-to-configure-clients.rst:34 msgid "" "Let's start with a simple example. Imagine we want to send (a) the batch " -"size that the client should use, (b) the current global round of " -"federated learning, and (c) the number of epochs to train on the client-" -"side. Our configuration function could look like this:" +"size that the client should use, (b) the current global round of federated " +"learning, and (c) the number of epochs to train on the client-side. Our " +"configuration function could look like this:" msgstr "" "간단한 예부터 시작하겠습니다. (a) 클라이언트가 사용해야 하는 배치 크기, (b) " -"현재 글로벌 연합 federated 라운드, (c) 클라이언트 측에서 학습할 에포크 수를 " -"전송하고 싶다고 가정해 보겠습니다. 구성 함수는 다음과 같습니다:" +"현재 글로벌 연합 라운드, (c) 클라이언트 측에서 학습할 에포크 수를 전송하고 " +"싶다고 가정해 보겠습니다. 구성 함수는 다음과 같습니다:" #: ../../source/how-to-configure-clients.rst:47 msgid "" "To make the built-in strategies use this function, we can pass it to " -"``FedAvg`` during initialization using the parameter " -":code:`on_fit_config_fn`:" +"``FedAvg`` during initialization using the parameter :code:" +"`on_fit_config_fn`:" msgstr "" -"기본 제공 전략이 이 함수를 사용하도록 하려면 초기화 중에 매개 변수 " -":code:`on_fit_config_fn`을 사용하여 ``FedAvg``에 이 함수를 전달하면 됩니다:" +"기본 제공 전략이 이 함수를 사용하도록 하려면 초기화 중에 매개 변수 :code:" +"`on_fit_config_fn`을 사용하여 ``FedAvg``에 이 함수를 전달하면 됩니다:" #: ../../source/how-to-configure-clients.rst:56 -msgid "One the client side, we receive the configuration dictionary in ``fit``:" +msgid "" +"One the client side, we receive the configuration dictionary in ``fit``:" msgstr "클라이언트 측에서는 ``fit``으로 구성 dictionary을 받습니다:" #: ../../source/how-to-configure-clients.rst:67 msgid "" "There is also an `on_evaluate_config_fn` to configure evaluation, which " -"works the same way. They are separate functions because one might want to" -" send different configuration values to `evaluate` (for example, to use a" -" different batch size)." +"works the same way. They are separate functions because one might want to " +"send different configuration values to `evaluate` (for example, to use a " +"different batch size)." msgstr "" "평가를 구성하는 `on_evaluate_config_fn`도 있으며, 같은 방식으로 작동합니다. " -"다른 배치 크기를 사용하기 위해 다른 구성 값을 `evaluate`로 보내려고 할 수 " -"있기 때문에 이 함수는 별도의 함수입니다." +"다른 배치 크기를 사용하기 위해 다른 구성 값을 `evaluate`로 보내려고 할 수 있" +"기 때문에 이 함수는 별도의 함수입니다." #: ../../source/how-to-configure-clients.rst:69 msgid "" -"The built-in strategies call this function every round (that is, every " -"time `Strategy.configure_fit` or `Strategy.configure_evaluate` runs). " -"Calling `on_evaluate_config_fn` every round allows us to vary/change the " -"config dict over consecutive rounds. If we wanted to implement a " -"hyperparameter schedule, for example, to increase the number of local " -"epochs during later rounds, we could do the following:" +"The built-in strategies call this function every round (that is, every time " +"`Strategy.configure_fit` or `Strategy.configure_evaluate` runs). Calling " +"`on_evaluate_config_fn` every round allows us to vary/change the config dict " +"over consecutive rounds. If we wanted to implement a hyperparameter " +"schedule, for example, to increase the number of local epochs during later " +"rounds, we could do the following:" msgstr "" "기본 제공 전략은 매 라운드마다 이 함수를 호출합니다(즉, `Strategy." -"configure_fit` 또는 `Strategy.configure_evaluate`가 실행될 때마다). 매 " -"라운드마다 `on_evaluate_config_fn`을 호출하면 연속된 라운드에서 config " -"dict를 변경/변경할 수 있습니다. 예를 들어 이후 라운드에서 로컬 에포크 수를 " -"늘리기 위해 하이퍼파라미터 일정을 구현하려면 다음과 같이 할 수 있습니다:" +"configure_fit` 또는 `Strategy.configure_evaluate`가 실행될 때마다). 매 라운드" +"마다 `on_evaluate_config_fn`을 호출하면 연속된 라운드에서 config dict를 변경/" +"변경할 수 있습니다. 예를 들어 이후 라운드에서 로컬 에포크 수를 늘리기 위해 하" +"이퍼파라미터 일정을 구현하려면 다음과 같이 할 수 있습니다:" #: ../../source/how-to-configure-clients.rst:82 msgid "The :code:`FedAvg` strategy will call this function *every round*." @@ -4576,24 +4632,24 @@ msgstr "개별 클라이언트 구성" msgid "" "In some cases, it is necessary to send different configuration values to " "different clients." -msgstr "경우에 따라 다른 구성 값을 다른 클라이언트에 보내야 하는 경우도 있습니다." +msgstr "" +"경우에 따라 다른 구성 값을 다른 클라이언트에 보내야 하는 경우도 있습니다." #: ../../source/how-to-configure-clients.rst:89 msgid "" -"This can be achieved by customizing an existing strategy or by " -":doc:`implementing a custom strategy from scratch `. Here's a nonsensical example that customizes :code:`FedAvg`" -" by adding a custom ``\"hello\": \"world\"`` configuration key/value pair" -" to the config dict of a *single client* (only the first client in the " -"list, the other clients in this round to not receive this \"special\" " -"config value):" +"This can be achieved by customizing an existing strategy or by :doc:" +"`implementing a custom strategy from scratch `. " +"Here's a nonsensical example that customizes :code:`FedAvg` by adding a " +"custom ``\"hello\": \"world\"`` configuration key/value pair to the config " +"dict of a *single client* (only the first client in the list, the other " +"clients in this round to not receive this \"special\" config value):" msgstr "" "이는 기존 전략을 사용자 지정하거나 :doc:`implementing a custom strategy from " -"scratch `를 통해 수행할 수 있습니다. 다음은 " -"사용자 지정 ``\"hello\"'를 추가하여 :code:`FedAvg`를 사용자 지정하는 " -"무의미한 예입니다: \"world\"`` 구성 키/값 쌍을 *단일 클라이언트*의 config " -"dict에 추가합니다(목록의 첫 번째 클라이언트만, 이 라운드의 다른 클라이언트는 " -"이 \"특별한\" 구성 값을 수신하지 않음):" +"scratch `를 통해 수행할 수 있습니다. 다음은 사용" +"자 지정 ``\"hello\"'를 추가하여 :code:`FedAvg`를 사용자 지정하는 무의미한 예" +"입니다: \"world\"`` 구성 키/값 쌍을 *단일 클라이언트*의 config dict에 추가합" +"니다(목록의 첫 번째 클라이언트만, 이 라운드의 다른 클라이언트는 이 \"특별한" +"\" 구성 값을 수신하지 않음):" #: ../../source/how-to-configure-logging.rst:2 msgid "Configure logging" @@ -4602,22 +4658,22 @@ msgstr "로깅 구성" #: ../../source/how-to-configure-logging.rst:4 msgid "" "The Flower logger keeps track of all core events that take place in " -"federated learning workloads. It presents information by default " -"following a standard message format:" +"federated learning workloads. It presents information by default following a " +"standard message format:" msgstr "" -"Flower 로거는 federated 학습 워크로드에서 발생하는 모든 핵심 이벤트를 " -"추적합니다. 기본적으로 표준 메시지 형식에 따라 정보를 표시합니다:" +"Flower 로거는 federated 학습 워크로드에서 발생하는 모든 핵심 이벤트를 추적합" +"니다. 기본적으로 표준 메시지 형식에 따라 정보를 표시합니다:" #: ../../source/how-to-configure-logging.rst:13 msgid "" -"containing relevant information including: log message level (e.g. " -":code:`INFO`, :code:`DEBUG`), a timestamp, the line where the logging " -"took place from, as well as the log message itself. In this way, the " -"logger would typically display information on your terminal as follows:" +"containing relevant information including: log message level (e.g. :code:" +"`INFO`, :code:`DEBUG`), a timestamp, the line where the logging took place " +"from, as well as the log message itself. In this way, the logger would " +"typically display information on your terminal as follows:" msgstr "" "로그 메시지 수준(예: :code:`INFO`, :code:`DEBUG`), 타임스탬프, 로깅이 발생한 " -"줄, 로그 메시지 자체 등 관련 정보를 포함합니다. 이러한 방식으로 로거는 " -"일반적으로 다음과 같은 정보를 터미널에 표시합니다:" +"줄, 로그 메시지 자체 등 관련 정보를 포함합니다. 이러한 방식으로 로거는 일반적" +"으로 다음과 같은 정보를 터미널에 표시합니다:" #: ../../source/how-to-configure-logging.rst:34 msgid "Saving log to file" @@ -4627,34 +4683,32 @@ msgstr "파일에 로그 저장" msgid "" "By default, the Flower log is outputted to the terminal where you launch " "your Federated Learning workload from. This applies for both gRPC-based " -"federation (i.e. when you do :code:`fl.server.start_server`) and when " -"using the :code:`VirtualClientEngine` (i.e. when you do " -":code:`fl.simulation.start_simulation`). In some situations you might " -"want to save this log to disk. You can do so by calling the " -"`fl.common.logger.configure() " -"`_" -" function. For example:" -msgstr "" -"기본적으로 Flower 로그는 Federated 학습 워크로드를 실행하는 터미널에 " -"출력됩니다. 이는 gRPC 기반 페더레이션(즉,:code:`fl.simulation." -"start_simulation`를 실행하는 경우)과 :code:`VirtualClientEngine`을 사용하는 " -"경우(즉, :코드:`fl.simulation.start_simulation`을 실행하는 경우) 모두에 " -"적용됩니다. 경우에 따라 이 로그를 디스크에 저장하고 싶을 수도 있습니다. 이 " -"경우 `fl.common.logger.configure() `_ 함수를 호출하여 저장할 수 있습니다. 예를 " -"들어:" +"federation (i.e. when you do :code:`fl.server.start_server`) and when using " +"the :code:`VirtualClientEngine` (i.e. when you do :code:`fl.simulation." +"start_simulation`). In some situations you might want to save this log to " +"disk. You can do so by calling the `fl.common.logger.configure() `_ function. " +"For example:" +msgstr "" +"기본적으로 Flower 로그는 Federated 학습 워크로드를 실행하는 터미널에 출력됩니" +"다. 이는 gRPC 기반 페더레이션(즉,:code:`fl.simulation.start_simulation`를 실" +"행하는 경우)과 :code:`VirtualClientEngine`을 사용하는 경우(즉, :코드:`fl." +"simulation.start_simulation`을 실행하는 경우) 모두에 적용됩니다. 경우에 따라 " +"이 로그를 디스크에 저장하고 싶을 수도 있습니다. 이 경우 `fl.common.logger." +"configure() `_ 함수를 호출하여 저장할 수 있습니다. 예를 들어:" #: ../../source/how-to-configure-logging.rst:53 msgid "" -"With the above, Flower will record the log you see on your terminal to " -":code:`log.txt`. This file will be created in the same directory as were " -"you are running the code from. If we inspect we see the log above is also" -" recorded but prefixing with :code:`identifier` each line:" +"With the above, Flower will record the log you see on your terminal to :code:" +"`log.txt`. This file will be created in the same directory as were you are " +"running the code from. If we inspect we see the log above is also recorded " +"but prefixing with :code:`identifier` each line:" msgstr "" -"위와 같이 하면 Flower는 터미널에 표시되는 로그를 :code:`log.txt`에 " -"기록합니다. 이 파일은 코드를 실행한 디렉터리와 동일한 디렉터리에 생성됩니다. " -"검사해보면 위의 로그도 기록되지만 각 줄 앞에 :code:`identifier` 접두사가 " -"붙는 것을 확인할 수 있습니다:" +"위와 같이 하면 Flower는 터미널에 표시되는 로그를 :code:`log.txt`에 기록합니" +"다. 이 파일은 코드를 실행한 디렉터리와 동일한 디렉터리에 생성됩니다. 검사해보" +"면 위의 로그도 기록되지만 각 줄 앞에 :code:`identifier` 접두사가 붙는 것을 확" +"인할 수 있습니다:" #: ../../source/how-to-configure-logging.rst:74 msgid "Log your own messages" @@ -4662,19 +4716,20 @@ msgstr "나만의 메시지 기록" #: ../../source/how-to-configure-logging.rst:76 msgid "" -"You might expand the information shown by default with the Flower logger " -"by adding more messages relevant to your application. You can achieve " -"this easily as follows." +"You might expand the information shown by default with the Flower logger by " +"adding more messages relevant to your application. You can achieve this " +"easily as follows." msgstr "" "애플리케이션과 관련된 메시지를 더 추가하여 Flower 로거에 기본적으로 표시되는 " "정보를 확장할 수 있습니다. 다음과 같이 쉽게 추가할 수 있습니다." #: ../../source/how-to-configure-logging.rst:102 msgid "" -"In this way your logger will show, in addition to the default messages, " -"the ones introduced by the clients as specified above." -msgstr "이렇게 하면 로거에 기본 메시지 외에 위에서 지정한 대로 클라이언트가 소개한 " -"메시지가 표시됩니다." +"In this way your logger will show, in addition to the default messages, the " +"ones introduced by the clients as specified above." +msgstr "" +"이렇게 하면 로거에 기본 메시지 외에 위에서 지정한 대로 클라이언트가 소개한 메" +"시지가 표시됩니다." #: ../../source/how-to-configure-logging.rst:128 msgid "Log to a remote service" @@ -4682,23 +4737,22 @@ msgstr "원격 서비스에 로그인" #: ../../source/how-to-configure-logging.rst:130 msgid "" -"The :code:`fl.common.logger.configure` function, also allows specifying a" -" host to which logs can be pushed (via :code:`POST`) through a native " -"Python :code:`logging.handler.HTTPHandler`. This is a particularly useful" -" feature in :code:`gRPC`-based Federated Learning workloads where " -"otherwise gathering logs from all entities (i.e. the server and the " -"clients) might be cumbersome. Note that in Flower simulation, the server " -"automatically displays all logs. You can still specify a " -":code:`HTTPHandler` should you wish to backup or analyze the logs " -"somewhere else." -msgstr "" -"또한 :code:`fl.common.logger.configure` 함수를 사용하면 네이티브 Python " -":code:`logging.handler.HTTPHandler`를 통해 로그를 푸시할 수 있는 호스트를 " -"지정할 수 있습니다(:code:`POST`를 통해). 이는 모든 엔티티(예: 서버 및 " -"클라이언트)에서 로그를 수집하는 것이 번거로울 수 있는 :code:`gRPC` 기반 " -"Federated 학습 워크로드에서 특히 유용한 기능입니다. Flower 시뮬레이션에서는 " -"서버가 모든 로그를 자동으로 표시합니다. 로그를 다른 곳에 백업하거나 " -"분석하려는 경우 :code:`HTTPHandler`를 지정할 수 있습니다." +"The :code:`fl.common.logger.configure` function, also allows specifying a " +"host to which logs can be pushed (via :code:`POST`) through a native Python :" +"code:`logging.handler.HTTPHandler`. This is a particularly useful feature " +"in :code:`gRPC`-based Federated Learning workloads where otherwise gathering " +"logs from all entities (i.e. the server and the clients) might be " +"cumbersome. Note that in Flower simulation, the server automatically " +"displays all logs. You can still specify a :code:`HTTPHandler` should you " +"wish to backup or analyze the logs somewhere else." +msgstr "" +"또한 :code:`fl.common.logger.configure` 함수를 사용하면 네이티브 Python :" +"code:`logging.handler.HTTPHandler`를 통해 로그를 푸시할 수 있는 호스트를 지정" +"할 수 있습니다(:code:`POST`를 통해). 이는 모든 엔티티(예: 서버 및 클라이언트)" +"에서 로그를 수집하는 것이 번거로울 수 있는 :code:`gRPC` 기반 Federated 학습 " +"워크로드에서 특히 유용한 기능입니다. Flower 시뮬레이션에서는 서버가 모든 로그" +"를 자동으로 표시합니다. 로그를 다른 곳에 백업하거나 분석하려는 경우 :code:" +"`HTTPHandler`를 지정할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:2 msgid "Enable SSL connections" @@ -4706,33 +4760,32 @@ msgstr "SSL 연결 사용" #: ../../source/how-to-enable-ssl-connections.rst:4 msgid "" -"This guide describes how to a SSL-enabled secure Flower server " -"(:code:`SuperLink`) can be started and how a Flower client " -"(:code:`SuperNode`) can establish a secure connections to it." +"This guide describes how to a SSL-enabled secure Flower server (:code:" +"`SuperLink`) can be started and how a Flower client (:code:`SuperNode`) can " +"establish a secure connections to it." msgstr "" -"이 가이드에서는 SSL을 지원하는 보안 Flower 서버(:코드:`SuperLink`)를 " -"시작하는 방법과 Flower 클라이언트(:코드:`SuperNode`)가 이 서버에 보안 연결을 " -"설정하는 방법을 설명합니다." +"이 가이드에서는 SSL을 지원하는 보안 Flower 서버(:코드:`SuperLink`)를 시작하" +"는 방법과 Flower 클라이언트(:코드:`SuperNode`)가 이 서버에 보안 연결을 설정하" +"는 방법을 설명합니다." #: ../../source/how-to-enable-ssl-connections.rst:7 msgid "" -"A complete code example demonstrating a secure connection can be found " -"`here `_." +"A complete code example demonstrating a secure connection can be found `here " +"`_." msgstr "" "보안 연결을 보여주는 전체 코드 예제는 '여기 `_'에서 확인할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:10 msgid "" -"The code example comes with a :code:`README.md` file which explains how " -"to start it. Although it is already SSL-enabled, it might be less " -"descriptive on how it does so. Stick to this guide for a deeper " -"introduction to the topic." +"The code example comes with a :code:`README.md` file which explains how to " +"start it. Although it is already SSL-enabled, it might be less descriptive " +"on how it does so. Stick to this guide for a deeper introduction to the " +"topic." msgstr "" "코드 예제에는 시작 방법을 설명하는 :code:`README.md` 파일이 함께 제공됩니다. " -"이미 SSL을 사용하도록 설정되어 있지만 그 방법에 대한 설명이 부족할 수 " -"있습니다. 이 가이드를 참고하여 이 주제에 대해 자세히 알아보세요." +"이미 SSL을 사용하도록 설정되어 있지만 그 방법에 대한 설명이 부족할 수 있습니" +"다. 이 가이드를 참고하여 이 주제에 대해 자세히 알아보세요." #: ../../source/how-to-enable-ssl-connections.rst:16 msgid "Certificates" @@ -4741,10 +4794,10 @@ msgstr "인증서" #: ../../source/how-to-enable-ssl-connections.rst:18 msgid "" "Using SSL-enabled connections requires certificates to be passed to the " -"server and client. For the purpose of this guide we are going to generate" -" self-signed certificates. As this can become quite complex we are going " -"to ask you to run the script in :code:`examples/advanced-" -"tensorflow/certificates/generate.sh` with the following command sequence:" +"server and client. For the purpose of this guide we are going to generate " +"self-signed certificates. As this can become quite complex we are going to " +"ask you to run the script in :code:`examples/advanced-tensorflow/" +"certificates/generate.sh` with the following command sequence:" msgstr "" "SSL 사용 연결을 사용하려면 서버와 클라이언트에 인증서를 전달해야 합니다. 이 " "가이드에서는 자체 서명된 인증서를 생성하겠습니다. 이 과정은 상당히 복잡할 수 " @@ -4753,27 +4806,27 @@ msgstr "" #: ../../source/how-to-enable-ssl-connections.rst:29 msgid "" -"This will generate the certificates in :code:`examples/advanced-" -"tensorflow/.cache/certificates`." +"This will generate the certificates in :code:`examples/advanced-tensorflow/." +"cache/certificates`." msgstr "" -"이렇게 하면 :code:`examples/advanced-tensorflow/.cache/certificates`에 " -"인증서가 생성됩니다." +"이렇게 하면 :code:`examples/advanced-tensorflow/.cache/certificates`에 인증서" +"가 생성됩니다." #: ../../source/how-to-enable-ssl-connections.rst:31 msgid "" -"The approach for generating SSL certificates in the context of this " -"example can serve as an inspiration and starting point, but it should not" -" be used as a reference for production environments. Please refer to " -"other sources regarding the issue of correctly generating certificates " -"for production environments. For non-critical prototyping or research " -"projects, it might be sufficient to use the self-signed certificates " -"generated using the scripts mentioned in this guide." +"The approach for generating SSL certificates in the context of this example " +"can serve as an inspiration and starting point, but it should not be used as " +"a reference for production environments. Please refer to other sources " +"regarding the issue of correctly generating certificates for production " +"environments. For non-critical prototyping or research projects, it might be " +"sufficient to use the self-signed certificates generated using the scripts " +"mentioned in this guide." msgstr "" -"이 예의 맥락에서 SSL 인증서를 생성하는 접근 방식은 영감과 출발점이 될 수 " -"있지만 프로덕션 환경에 대한 참조로 사용해서는 안 됩니다. 프로덕션 환경용 " -"인증서를 올바르게 생성하는 문제에 대해서는 다른 출처를 참조하세요. 중요하지 " -"않은 프로토타이핑 또는 연구 프로젝트의 경우, 이 가이드에 언급된 스크립트를 " -"사용하여 생성한 자체 서명 인증서를 사용하는 것으로 충분할 수 있습니다." +"이 예의 맥락에서 SSL 인증서를 생성하는 접근 방식은 영감과 출발점이 될 수 있지" +"만 프로덕션 환경에 대한 참조로 사용해서는 안 됩니다. 프로덕션 환경용 인증서" +"를 올바르게 생성하는 문제에 대해서는 다른 출처를 참조하세요. 중요하지 않은 프" +"로토타이핑 또는 연구 프로젝트의 경우, 이 가이드에 언급된 스크립트를 사용하여 " +"생성한 자체 서명 인증서를 사용하는 것으로 충분할 수 있습니다." #: ../../source/how-to-enable-ssl-connections.rst:39 msgid "Server (SuperLink)" @@ -4781,18 +4834,20 @@ msgstr "서버(SuperLink)" #: ../../source/how-to-enable-ssl-connections.rst:41 msgid "" -"Use the following terminal command to start a sever (SuperLink) that uses" -" the previously generated certificates:" -msgstr "다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 서버(SuperLink)" +"Use the following terminal command to start a sever (SuperLink) that uses " +"the previously generated certificates:" +msgstr "" +"다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 서버(SuperLink)" "를 시작합니다:" #: ../../source/how-to-enable-ssl-connections.rst:50 msgid "" "When providing certificates, the server expects a tuple of three " -"certificates paths: CA certificate, server certificate and server private" -" key." -msgstr "인증서를 제공할 때 서버는 세 가지 인증서 경로의 튜플을 기대합니다: CA " -"인증서, 서버 인증서 및 서버 개인 키입니다." +"certificates paths: CA certificate, server certificate and server private " +"key." +msgstr "" +"인증서를 제공할 때 서버는 세 가지 인증서 경로의 튜플을 기대합니다: CA 인증" +"서, 서버 인증서 및 서버 개인 키입니다." #: ../../source/how-to-enable-ssl-connections.rst:54 msgid "Client (SuperNode)" @@ -4800,23 +4855,25 @@ msgstr "클라이언트(SuperNode)" #: ../../source/how-to-enable-ssl-connections.rst:56 msgid "" -"Use the following terminal command to start a client (SuperNode) that " -"uses the previously generated certificates:" -msgstr "다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 " -"클라이언트(SuperNode)를 시작합니다:" +"Use the following terminal command to start a client (SuperNode) that uses " +"the previously generated certificates:" +msgstr "" +"다음 터미널 명령을 사용하여 이전에 생성한 인증서를 사용하는 클라이언트" +"(SuperNode)를 시작합니다:" #: ../../source/how-to-enable-ssl-connections.rst:64 msgid "" -"When setting :code:`root_certificates`, the client expects a file path to" -" PEM-encoded root certificates." -msgstr "코드:`root_certificates`를 설정하면 클라이언트는 PEM 인코딩된 루트 인증서의 " +"When setting :code:`root_certificates`, the client expects a file path to " +"PEM-encoded root certificates." +msgstr "" +"코드:`root_certificates`를 설정하면 클라이언트는 PEM 인코딩된 루트 인증서의 " "파일 경로를 예상합니다." #: ../../source/how-to-enable-ssl-connections.rst:70 msgid "" -"You should now have learned how to generate self-signed certificates " -"using the given script, start an SSL-enabled server and have a client " -"establish a secure connection to it." +"You should now have learned how to generate self-signed certificates using " +"the given script, start an SSL-enabled server and have a client establish a " +"secure connection to it." msgstr "" "이제 주어진 스크립트를 사용하여 자체 서명 인증서를 생성하고, SSL 사용 서버를 " "시작하고, 클라이언트가 보안 연결을 설정하는 방법을 배웠을 것입니다." @@ -4827,8 +4884,8 @@ msgstr "추가 리소스" #: ../../source/how-to-enable-ssl-connections.rst:77 msgid "" -"These additional sources might be relevant if you would like to dive " -"deeper into the topic of certificates:" +"These additional sources might be relevant if you would like to dive deeper " +"into the topic of certificates:" msgstr "인증서에 대해 더 자세히 알아보고 싶다면 이러한 추가 자료를 참고하세요:" #: ../../source/how-to-enable-ssl-connections.rst:79 @@ -4837,7 +4894,7 @@ msgstr "'암호화하세요 `_'" #: ../../source/how-to-enable-ssl-connections.rst:80 msgid "`certbot `_" -msgstr "인증봇 `_" +msgstr "`인증봇 `_" #: ../../source/how-to-implement-strategies.rst:2 msgid "Implement strategies" @@ -4845,18 +4902,18 @@ msgstr "전략 구현" #: ../../source/how-to-implement-strategies.rst:4 msgid "" -"The strategy abstraction enables implementation of fully custom " -"strategies. A strategy is basically the federated learning algorithm that" -" runs on the server. Strategies decide how to sample clients, how to " -"configure clients for training, how to aggregate updates, and how to " -"evaluate models. Flower provides a few built-in strategies which are " -"based on the same API described below." +"The strategy abstraction enables implementation of fully custom strategies. " +"A strategy is basically the federated learning algorithm that runs on the " +"server. Strategies decide how to sample clients, how to configure clients " +"for training, how to aggregate updates, and how to evaluate models. Flower " +"provides a few built-in strategies which are based on the same API described " +"below." msgstr "" "전략 추상화를 통해 완전한 맞춤형 전략을 구현할 수 있습니다. 전략은 " -"기본적으로 서버에서 실행되는 federated 학습 알고리즘입니다. 전략은 " -"클라이언트를 샘플링하는 방법, 학습을 위해 클라이언트를 구성하는 방법, " -"업데이트를 집계하는 방법, 모델을 평가하는 방법을 결정합니다. Flower는 아래에 " -"설명된 것과 동일한 API를 기반으로 하는 몇 가지 기본 제공 전략을 제공합니다." +"기본적으로 서버에서 실행되는 연합 학습 알고리즘입니다. 전략은 클라이언트를 " +"샘플링하는 방법, 학습을 위해 클라이언트를 구성하는 방법, 업데이트를 집계하는 " +"방법, 모델을 평가하는 방법을 결정합니다. Flower는 아래에 설명된 것과 동일한 " +"API를 기반으로 하는 몇 가지 기본 제공 전략을 제공합니다." #: ../../source/how-to-implement-strategies.rst:11 msgid "The :code:`Strategy` abstraction" @@ -4864,15 +4921,14 @@ msgstr ":code:`Strategy` 추상화" #: ../../source/how-to-implement-strategies.rst:13 msgid "" -"All strategy implementation are derived from the abstract base class " -":code:`flwr.server.strategy.Strategy`, both built-in implementations and " -"third party implementations. This means that custom strategy " -"implementations have the exact same capabilities at their disposal as " -"built-in ones." +"All strategy implementation are derived from the abstract base class :code:" +"`flwr.server.strategy.Strategy`, both built-in implementations and third " +"party implementations. This means that custom strategy implementations have " +"the exact same capabilities at their disposal as built-in ones." msgstr "" -"모든 전략 구현은 기본 제공 구현과 타사 구현 모두 추상 기본 클래스인 " -":code:`flwr.server.strategy.Strategy`에서 파생됩니다. 즉, 사용자 정의 전략 " -"구현은 기본 제공 구현과 완전히 동일한 기능을 사용할 수 있습니다." +"모든 전략 구현은 기본 제공 구현과 타사 구현 모두 추상 기본 클래스인 :code:" +"`flwr.server.strategy.Strategy`에서 파생됩니다. 즉, 사용자 정의 전략 구현은 " +"기본 제공 구현과 완전히 동일한 기능을 사용할 수 있습니다." #: ../../source/how-to-implement-strategies.rst:18 msgid "" @@ -4882,13 +4938,13 @@ msgstr "전략 추상화에서는 구현해야 하는 몇 가지 추상적인 #: ../../source/how-to-implement-strategies.rst:75 msgid "" -"Creating a new strategy means implementing a new :code:`class` (derived " -"from the abstract base class :code:`Strategy`) that implements for the " -"previously shown abstract methods:" +"Creating a new strategy means implementing a new :code:`class` (derived from " +"the abstract base class :code:`Strategy`) that implements for the previously " +"shown abstract methods:" msgstr "" -"새 전략을 생성한다는 것은 이전에 표시된 추상 메서드에 대해 구현하는 새로운 " -":code:`class`(추상 기본 클래스 :code:`Strategy`에서 파생됨)를 구현하는 것을 " -"의미합니다:" +"새 전략을 생성한다는 것은 이전에 표시된 추상 메서드에 대해 구현하는 새로운 :" +"code:`class`(추상 기본 클래스 :code:`Strategy`에서 파생됨)를 구현하는 것을 의" +"미합니다:" #: ../../source/how-to-implement-strategies.rst:100 msgid "The Flower server calls these methods in the following order:" @@ -4904,19 +4960,18 @@ msgstr ":code:`initialize_parameters` 메서드" #: ../../source/how-to-implement-strategies.rst:182 msgid "" -":code:`initialize_parameters` is called only once, at the very beginning " -"of an execution. It is responsible for providing the initial global model" -" parameters in a serialized form (i.e., as a :code:`Parameters` object)." +":code:`initialize_parameters` is called only once, at the very beginning of " +"an execution. It is responsible for providing the initial global model " +"parameters in a serialized form (i.e., as a :code:`Parameters` object)." msgstr "" "code:`initialize_parameters`는 실행을 처음 시작할 때 한 번만 호출됩니다. 이 " -"함수는 초기 전역 모델 파라미터를 직렬화된 형식(즉, :code:`Parameters` 객체)" -"으로 제공하는 역할을 합니다." +"함수는 초기 전역 모델 파라미터를 직렬화된 형식(즉, :code:`Parameters` 객체)으" +"로 제공하는 역할을 합니다." #: ../../source/how-to-implement-strategies.rst:184 msgid "" -"Built-in strategies return user-provided initial parameters. The " -"following example shows how initial parameters can be passed to " -":code:`FedAvg`:" +"Built-in strategies return user-provided initial parameters. The following " +"example shows how initial parameters can be passed to :code:`FedAvg`:" msgstr "" "기본 제공 전략은 사용자가 제공한 초기 매개 변수를 반환합니다. 다음 예는 초기 " "매개 변수를 :code:`FedAvg`에 전달하는 방법을 보여줍니다:" @@ -4924,32 +4979,31 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:209 msgid "" "The Flower server will call :code:`initialize_parameters`, which either " -"returns the parameters that were passed to :code:`initial_parameters`, or" -" :code:`None`. If no parameters are returned from " -":code:`initialize_parameters` (i.e., :code:`None`), the server will " -"randomly select one client and ask it to provide its parameters. This is " -"a convenience feature and not recommended in practice, but it can be " -"useful for prototyping. In practice, it is recommended to always use " -"server-side parameter initialization." -msgstr "" -"Flower 서버는 :code:`initialize_parameters`를 호출하여 " -":code:`initial_parameters`에 전달된 파라미터를 반환하거나 :code:`None`을 " -"반환합니다. :code:`initial_parameters`에서 반환되는 매개변수가 없는 경우(즉, " -":code:`None`) 서버는 무작위로 클라이언트 하나를 선택하여 해당 클라이언트에 " -"매개변수를 제공하도록 요청합니다. 이는 편의 기능이며 실제로는 권장하지 " -"않지만 프로토타이핑에는 유용할 수 있습니다. 실제로는 항상 서버 측 매개변수 " -"초기화를 사용하는 것이 좋습니다." +"returns the parameters that were passed to :code:`initial_parameters`, or :" +"code:`None`. If no parameters are returned from :code:" +"`initialize_parameters` (i.e., :code:`None`), the server will randomly " +"select one client and ask it to provide its parameters. This is a " +"convenience feature and not recommended in practice, but it can be useful " +"for prototyping. In practice, it is recommended to always use server-side " +"parameter initialization." +msgstr "" +"Flower 서버는 :code:`initialize_parameters`를 호출하여 :code:" +"`initial_parameters`에 전달된 파라미터를 반환하거나 :code:`None`을 반환합니" +"다. :code:`initial_parameters`에서 반환되는 매개변수가 없는 경우(즉, :code:" +"`None`) 서버는 무작위로 클라이언트 하나를 선택하여 해당 클라이언트에 매개변수" +"를 제공하도록 요청합니다. 이는 편의 기능이며 실제로는 권장하지 않지만 프로토" +"타이핑에는 유용할 수 있습니다. 실제로는 항상 서버 측 매개변수 초기화를 사용하" +"는 것이 좋습니다." #: ../../source/how-to-implement-strategies.rst:213 msgid "" "Server-side parameter initialization is a powerful mechanism. It can be " -"used, for example, to resume training from a previously saved checkpoint." -" It is also the fundamental capability needed to implement hybrid " -"approaches, for example, to fine-tune a pre-trained model using federated" -" learning." +"used, for example, to resume training from a previously saved checkpoint. It " +"is also the fundamental capability needed to implement hybrid approaches, " +"for example, to fine-tune a pre-trained model using federated learning." msgstr "" "서버 측 파라미터 초기화는 강력한 메커니즘입니다. 예를 들어 이전에 저장한 " -"체크포인트에서 학습을 재개하는 데 사용할 수 있습니다. 또한 federated 학습을 " +"체크포인트에서 학습을 재개하는 데 사용할 수 있습니다. 또한 연합 학습을 " "사용하여 사전 학습된 모델을 미세 조정하는 등 하이브리드 접근 방식을 구현하는 " "데 필요한 기본 기능입니다." @@ -4959,23 +5013,23 @@ msgstr ":code:`configure_fit` 메서드" #: ../../source/how-to-implement-strategies.rst:218 msgid "" -":code:`configure_fit` is responsible for configuring the upcoming round " -"of training. What does *configure* mean in this context? Configuring a " -"round means selecting clients and deciding what instructions to send to " -"these clients. The signature of :code:`configure_fit` makes this clear:" +":code:`configure_fit` is responsible for configuring the upcoming round of " +"training. What does *configure* mean in this context? Configuring a round " +"means selecting clients and deciding what instructions to send to these " +"clients. The signature of :code:`configure_fit` makes this clear:" msgstr "" -":code:`configure_fit`은 다가오는 학 라운드를 구성하는 역할을 합니다. 이 " -"문맥에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 클라이언트를 " -"선택하고 이 클라이언트에게 어떤 지침을 보낼지 결정하는 것을 의미합니다. " -"code:`configure_fit`의 시그니처를 보면 이를 명확히 알 수 있습니다:" +":code:`configure_fit`은 다가오는 학 라운드를 구성하는 역할을 합니다. 이 문맥" +"에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 클라이언트를 선택하" +"고 이 클라이언트에게 어떤 지침을 보낼지 결정하는 것을 의미합니다. code:" +"`configure_fit`의 시그니처를 보면 이를 명확히 알 수 있습니다:" #: ../../source/how-to-implement-strategies.rst:231 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_fit`:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_fit`:" msgstr "" -"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 instruction을 " +"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 명령어를 " "나타냅니다. 전략 구현은 일반적으로 :code:`configure_fit`에서 다음 단계를 " "수행합니다:" @@ -4985,39 +5039,38 @@ msgid "" "Use the :code:`client_manager` to randomly sample all (or a subset of) " "available clients (each represented as a :code:`ClientProxy` object)" msgstr "" -":code:`client_manager`를 사용하여 사용 가능한 모든 클라이언트(또는 그 하위 " -"집합)를 무작위로 샘플링합니다(각각 :code:`ClientProxy` 개체로 표시됨)" +":code:`client_manager`를 사용하여 사용 가능한 모든 클라이언트(또는 그 하위 집" +"합)를 무작위로 샘플링합니다(각각 :code:`ClientProxy` 개체로 표시됨)" #: ../../source/how-to-implement-strategies.rst:234 msgid "" "Pair each :code:`ClientProxy` with the same :code:`FitIns` holding the " "current global model :code:`parameters` and :code:`config` dict" msgstr "" -"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 " -":code:`config` dict를 보유한 동일한 :code:`FitIns`와 쌍을 이룹니다" +"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 :code:" +"`config` dict를 보유한 동일한 :code:`FitIns`와 쌍을 이룹니다" #: ../../source/how-to-implement-strategies.rst:236 msgid "" "More sophisticated implementations can use :code:`configure_fit` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_fit`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_fit`." msgstr "" -"보다 정교한 구현은 :code:`configure_fit`을 사용하여 사용자 지정 클라이언트 " -"선택 로직을 구현할 수 있습니다. 클라이언트는 :code:`configure_fit`에서 " -"반환된 목록에 해당 :code:`ClientProxy`가 포함된 경우에만 라운드에 참여합니다." +"보다 정교한 구현은 :code:`configure_fit`을 사용하여 사용자 지정 클라이언트 선" +"택 로직을 구현할 수 있습니다. 클라이언트는 :code:`configure_fit`에서 반환된 " +"목록에 해당 :code:`ClientProxy`가 포함된 경우에만 라운드에 참여합니다." #: ../../source/how-to-implement-strategies.rst:240 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to train, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"train, for example, different models on different clients, or use different " +"hyperparameters on different clients (via the :code:`config` dict)." msgstr "" "이 반환 값의 구조는 사용자에게 많은 유연성을 제공합니다. instructions은 " -"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 instructions을 전송할 수 " +"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 명령어를 전송할 수 " "있습니다. 이를 통해 예를 들어 클라이언트마다 다른 모델을 학습시키거나 " "클라이언트마다 다른 하이퍼파라미터를 사용하는 사용자 지정 전략을 사용할 수 " "있습니다(:code:`config` dict를 통해)." @@ -5028,9 +5081,8 @@ msgstr ":code:`aggregate_fit` 메서드" #: ../../source/how-to-implement-strategies.rst:245 msgid "" -":code:`aggregate_fit` is responsible for aggregating the results returned" -" by the clients that were selected and asked to train in " -":code:`configure_fit`." +":code:`aggregate_fit` is responsible for aggregating the results returned by " +"the clients that were selected and asked to train in :code:`configure_fit`." msgstr "" "code:`aggregate_fit`은 :code:`configure_fit`에서 훈련하도록 선택되고 요청된 " "클라이언트가 반환한 결과를 집계하는 역할을 담당합니다." @@ -5038,26 +5090,26 @@ msgstr "" #: ../../source/how-to-implement-strategies.rst:258 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_fit`). :code:`aggregate_fit` therefore receives a list " -"of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_fit`). :code:`aggregate_fit` therefore receives a list of :code:" +"`results`, but also a list of :code:`failures`." msgstr "" -"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 " -"결과를 얻을 수 있다는 보장은 없습니다(:code:`configure_fit`을 통해). 따라서 " -":code:`aggregate_fit`은 :code:`results` 목록뿐만 아니라 :code:`failures` " -"목록도 받습니다." +"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 결과" +"를 얻을 수 있다는 보장은 없습니다(:code:`configure_fit`을 통해). 따라서 :" +"code:`aggregate_fit`은 :code:`results` 목록뿐만 아니라 :code:`failures` 목록" +"도 받습니다." #: ../../source/how-to-implement-strategies.rst:260 msgid "" -":code:`aggregate_fit` returns an optional :code:`Parameters` object and a" -" dictionary of aggregated metrics. The :code:`Parameters` return value is" -" optional because :code:`aggregate_fit` might decide that the results " +":code:`aggregate_fit` returns an optional :code:`Parameters` object and a " +"dictionary of aggregated metrics. The :code:`Parameters` return value is " +"optional because :code:`aggregate_fit` might decide that the results " "provided are not sufficient for aggregation (e.g., too many failures)." msgstr "" "code:`aggregate_fit`은 선택적 :code:`Parameters` 개체와 집계된 메트릭의 " "dictionary를 반환합니다. :code:`Parameters` 반환 값은 :code:`aggregate_fit`" -"이 제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 " -"너무 많음) 선택 사항입니다." +"이 제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 너" +"무 많음) 선택 사항입니다." #: ../../source/how-to-implement-strategies.rst:263 msgid "The :code:`configure_evaluate` method" @@ -5065,59 +5117,56 @@ msgstr ":code:`configure_evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:265 msgid "" -":code:`configure_evaluate` is responsible for configuring the upcoming " -"round of evaluation. What does *configure* mean in this context? " -"Configuring a round means selecting clients and deciding what " -"instructions to send to these clients. The signature of " -":code:`configure_evaluate` makes this clear:" +":code:`configure_evaluate` is responsible for configuring the upcoming round " +"of evaluation. What does *configure* mean in this context? Configuring a " +"round means selecting clients and deciding what instructions to send to " +"these clients. The signature of :code:`configure_evaluate` makes this clear:" msgstr "" ":code:`configure_evaluate`는 다가오는 평가 라운드를 구성하는 역할을 합니다. " -"이 문맥에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 " -"클라이언트를 선택하고 이러한 클라이언트에 전송할 지침을 결정하는 것을 " -"의미합니다. :code:`configure_evaluate`의 시그니처를 보면 이를 명확히 알 수 " -"있습니다:" +"이 문맥에서 *구성*은 무엇을 의미하나요? 라운드를 구성한다는 것은 클라이언트" +"를 선택하고 이러한 클라이언트에 전송할 지침을 결정하는 것을 의미합니다. :" +"code:`configure_evaluate`의 시그니처를 보면 이를 명확히 알 수 있습니다:" #: ../../source/how-to-implement-strategies.rst:278 msgid "" "The return value is a list of tuples, each representing the instructions " -"that will be sent to a particular client. Strategy implementations " -"usually perform the following steps in :code:`configure_evaluate`:" +"that will be sent to a particular client. Strategy implementations usually " +"perform the following steps in :code:`configure_evaluate`:" msgstr "" -"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 instructions을 " +"반환 값은 튜플 목록으로, 각 튜플은 특정 클라이언트로 전송될 명령어를 " "나타냅니다. 전략 구현은 일반적으로 :code:`configure_evaluate`에서 다음 " "단계를 수행합니다:" #: ../../source/how-to-implement-strategies.rst:281 msgid "" -"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding " -"the current global model :code:`parameters` and :code:`config` dict" +"Pair each :code:`ClientProxy` with the same :code:`EvaluateIns` holding the " +"current global model :code:`parameters` and :code:`config` dict" msgstr "" -"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 " -":code:`config` dict를 보유한 동일한 :code:`EvaluateIns`와 쌍을 이룹니다" +"각 :code:`ClientProxy`를 현재 글로벌 모델 :code:`parameters` 및 :code:" +"`config` dict를 보유한 동일한 :code:`EvaluateIns`와 쌍을 이룹니다" #: ../../source/how-to-implement-strategies.rst:283 msgid "" "More sophisticated implementations can use :code:`configure_evaluate` to " -"implement custom client selection logic. A client will only participate " -"in a round if the corresponding :code:`ClientProxy` is included in the " -"list returned from :code:`configure_evaluate`." +"implement custom client selection logic. A client will only participate in a " +"round if the corresponding :code:`ClientProxy` is included in the list " +"returned from :code:`configure_evaluate`." msgstr "" -"보다 정교한 구현은 :code:`configure_evaluate`를 사용하여 사용자 지정 " -"클라이언트 선택 로직을 구현할 수 있습니다. 클라이언트는 " -":code:`configure_evaluate`에서 반환된 목록에 해당 :code:`ClientProxy`가 " -"포함된 경우에만 라운드에 참여합니다." +"보다 정교한 구현은 :code:`configure_evaluate`를 사용하여 사용자 지정 클라이언" +"트 선택 로직을 구현할 수 있습니다. 클라이언트는 :code:`configure_evaluate`에" +"서 반환된 목록에 해당 :code:`ClientProxy`가 포함된 경우에만 라운드에 참여합니" +"다." #: ../../source/how-to-implement-strategies.rst:287 msgid "" "The structure of this return value provides a lot of flexibility to the " "user. Since instructions are defined on a per-client basis, different " -"instructions can be sent to each client. This enables custom strategies " -"to evaluate, for example, different models on different clients, or use " -"different hyperparameters on different clients (via the :code:`config` " -"dict)." +"instructions can be sent to each client. This enables custom strategies to " +"evaluate, for example, different models on different clients, or use " +"different hyperparameters on different clients (via the :code:`config` dict)." msgstr "" -"이 반환 값의 구조는 사용자에게 많은 유연성을 제공합니다. instructions은 " -"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 instructions을 전송할 수 " +"이 반환 값의 구조는 사용자에게 많은 유연성을 제공합니다. 명령어는 " +"클라이언트별로 정의되므로 각 클라이언트에 서로 다른 명령어를 전송할 수 " "있습니다. 이를 통해 사용자 지정 전략을 통해 예를 들어 클라이언트마다 다른 " "모델을 평가하거나 클라이언트마다 다른 하이퍼파라미터를 사용할 수 " "있습니다(:code:`config` dict를 통해)." @@ -5129,35 +5178,35 @@ msgstr ":code:`aggregate_evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:293 msgid "" ":code:`aggregate_evaluate` is responsible for aggregating the results " -"returned by the clients that were selected and asked to evaluate in " -":code:`configure_evaluate`." +"returned by the clients that were selected and asked to evaluate in :code:" +"`configure_evaluate`." msgstr "" -"code:`aggregate_evaluate`는 :code:`configure_evaluate`에서 선택되어 평가를 " -"요청한 클라이언트가 반환한 결과를 집계하는 역할을 담당합니다." +"code:`aggregate_evaluate`는 :code:`configure_evaluate`에서 선택되어 평가를 요" +"청한 클라이언트가 반환한 결과를 집계하는 역할을 담당합니다." #: ../../source/how-to-implement-strategies.rst:306 msgid "" "Of course, failures can happen, so there is no guarantee that the server " -"will get results from all the clients it sent instructions to (via " -":code:`configure_evaluate`). :code:`aggregate_evaluate` therefore " -"receives a list of :code:`results`, but also a list of :code:`failures`." +"will get results from all the clients it sent instructions to (via :code:" +"`configure_evaluate`). :code:`aggregate_evaluate` therefore receives a list " +"of :code:`results`, but also a list of :code:`failures`." msgstr "" -"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 " -"결과를 얻을 수 있다는 보장은 없습니다(:code:`configure_evaluate`를 통해). " -"따라서 :code:`aggregate_evaluate`는 :code:`results` 목록뿐만 아니라 " -":code:`failures` 목록도 받습니다." +"물론 실패가 발생할 수 있으므로 서버가 명령을 보낸 모든 클라이언트로부터 결과" +"를 얻을 수 있다는 보장은 없습니다(:code:`configure_evaluate`를 통해). 따라" +"서 :code:`aggregate_evaluate`는 :code:`results` 목록뿐만 아니라 :code:" +"`failures` 목록도 받습니다." #: ../../source/how-to-implement-strategies.rst:308 msgid "" -":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a" -" dictionary of aggregated metrics. The :code:`float` return value is " -"optional because :code:`aggregate_evaluate` might decide that the results" -" provided are not sufficient for aggregation (e.g., too many failures)." +":code:`aggregate_evaluate` returns an optional :code:`float` (loss) and a " +"dictionary of aggregated metrics. The :code:`float` return value is optional " +"because :code:`aggregate_evaluate` might decide that the results provided " +"are not sufficient for aggregation (e.g., too many failures)." msgstr "" "code:`aggregate_evaluate`는 선택적 :code:`float`(손실)와 집계된 메트릭의 " "dictionary를 반환합니다. code:`float` 반환 값은 :code:`aggregate_evaluate`가 " -"제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 너무 " -"많음) 선택 사항입니다." +"제공된 결과가 집계에 충분하지 않다고 판단할 수 있으므로(예: 실패 수가 너무 많" +"음) 선택 사항입니다." #: ../../source/how-to-implement-strategies.rst:311 msgid "The :code:`evaluate` method" @@ -5166,26 +5215,25 @@ msgstr ":code:`evaluate` 메서드" #: ../../source/how-to-implement-strategies.rst:313 msgid "" ":code:`evaluate` is responsible for evaluating model parameters on the " -"server-side. Having :code:`evaluate` in addition to " -":code:`configure_evaluate`/:code:`aggregate_evaluate` enables strategies " -"to perform both servers-side and client-side (federated) evaluation." +"server-side. Having :code:`evaluate` in addition to :code:" +"`configure_evaluate`/:code:`aggregate_evaluate` enables strategies to " +"perform both servers-side and client-side (federated) evaluation." msgstr "" ":code:`evaluate`는 서버 측에서 모델 매개변수를 평가하는 역할을 담당합니다. " "code:`configure_evaluate`/:code:`aggregate_evaluate`와 함께 :code:`evaluate`" -"를 사용하면 서버 측과 클라이언트 측(federated) 평가를 모두 수행할 수 있는 " -"전략을 사용할 수 있습니다." +"를 사용하면 서버 측과 클라이언트 측(federated) 평가를 모두 수행할 수 있는 전" +"략을 사용할 수 있습니다." #: ../../source/how-to-implement-strategies.rst:323 msgid "" -"The return value is again optional because the strategy might not need to" -" implement server-side evaluation or because the user-defined " -":code:`evaluate` method might not complete successfully (e.g., it might " -"fail to load the server-side evaluation data)." +"The return value is again optional because the strategy might not need to " +"implement server-side evaluation or because the user-defined :code:" +"`evaluate` method might not complete successfully (e.g., it might fail to " +"load the server-side evaluation data)." msgstr "" -"반환 값은 전략에서 서버 측 평가를 구현할 필요가 없거나 사용자 정의 " -":code:`evaluate` 메서드가 성공적으로 완료되지 않을 수 있기 때문에(예: 서버 " -"측 평가 데이터를 로드하지 못할 수 있음) 다시 선택 사항으로 설정할 수 " -"있습니다." +"반환 값은 전략에서 서버 측 평가를 구현할 필요가 없거나 사용자 정의 :code:" +"`evaluate` 메서드가 성공적으로 완료되지 않을 수 있기 때문에(예: 서버 측 평가 " +"데이터를 로드하지 못할 수 있음) 다시 선택 사항으로 설정할 수 있습니다." #: ../../source/how-to-install-flower.rst:2 msgid "Install Flower" @@ -5206,17 +5254,18 @@ msgstr "pip 사용" #: ../../source/how-to-install-flower.rst:17 msgid "" -"Stable releases are available on `PyPI " -"`_::" -msgstr "안정적인 릴리즈는 `PyPI `_:: 에서 확인할 수 " +"Stable releases are available on `PyPI `_::" +msgstr "" +"안정적인 릴리즈는 `PyPI `_:: 에서 확인할 수 " "있습니다::" #: ../../source/how-to-install-flower.rst:21 msgid "" "For simulations that use the Virtual Client Engine, ``flwr`` should be " "installed with the ``simulation`` extra::" -msgstr "가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우 ``flwr``을 ``simulation``" -"extra와 함께 설치해야 합니다:" +msgstr "" +"가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우 ``flwr``을 " +"``simulation``extra와 함께 설치해야 합니다:" #: ../../source/how-to-install-flower.rst:27 msgid "Using conda (or mamba)" @@ -5228,15 +5277,16 @@ msgstr "Flower은 'conda-forge' 채널에서도 설치할 수 있습니다." #: ../../source/how-to-install-flower.rst:31 msgid "" -"If you have not added ``conda-forge`` to your channels, you will first " -"need to run the following::" +"If you have not added ``conda-forge`` to your channels, you will first need " +"to run the following::" msgstr "채널에 'conda-forge'를 추가하지 않은 경우 먼저 다음을 실행해야 합니다:" #: ../../source/how-to-install-flower.rst:36 msgid "" -"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be " -"installed with ``conda``::" -msgstr "conda-forge`` 채널이 활성화되면 ``flwr``을 ``conda``로 설치할 수 있습니다::" +"Once the ``conda-forge`` channel has been enabled, ``flwr`` can be installed " +"with ``conda``::" +msgstr "" +"conda-forge`` 채널이 활성화되면 ``flwr``을 ``conda``로 설치할 수 있습니다::" #: ../../source/how-to-install-flower.rst:40 msgid "or with ``mamba``::" @@ -5249,11 +5299,11 @@ msgstr "설치 확인" #: ../../source/how-to-install-flower.rst:48 msgid "" "The following command can be used to verify if Flower was successfully " -"installed. If everything worked, it should print the version of Flower to" -" the command line::" +"installed. If everything worked, it should print the version of Flower to " +"the command line::" msgstr "" -"다음 명령을 사용하여 Flower가 성공적으로 설치되었는지 확인할 수 있습니다. " -"모든 것이 정상적으로 작동하면 명령줄에 Flower의 버전이 출력됩니다:" +"다음 명령을 사용하여 Flower가 성공적으로 설치되었는지 확인할 수 있습니다. 모" +"든 것이 정상적으로 작동하면 명령줄에 Flower의 버전이 출력됩니다:" #: ../../source/how-to-install-flower.rst:55 msgid "Advanced installation options" @@ -5265,7 +5315,8 @@ msgstr "Docker를 통해 설치" #: ../../source/how-to-install-flower.rst:60 msgid ":doc:`How to run Flower using Docker `" -msgstr ":doc:`Docker를 사용하여 Flower를 실행하는 방법 `" #: ../../source/how-to-install-flower.rst:63 @@ -5274,17 +5325,17 @@ msgstr "사전 릴리즈 설치" #: ../../source/how-to-install-flower.rst:65 msgid "" -"New (possibly unstable) versions of Flower are sometimes available as " -"pre-release versions (alpha, beta, release candidate) before the stable " -"release happens::" +"New (possibly unstable) versions of Flower are sometimes available as pre-" +"release versions (alpha, beta, release candidate) before the stable release " +"happens::" msgstr "" -"새(불안정할 수 있는) 버전의 Flower는 안정 버전이 출시되기 전에 사전 릴리즈 " -"버전(알파, 베타, 릴리즈 후보)으로 제공되는 경우가 있습니다:" +"새(불안정할 수 있는) 버전의 Flower는 안정 버전이 출시되기 전에 사전 릴리즈 버" +"전(알파, 베타, 릴리즈 후보)으로 제공되는 경우가 있습니다:" #: ../../source/how-to-install-flower.rst:69 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases" -" should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr`` pre-releases " +"should be installed with the ``simulation`` extra::" msgstr "" "가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우 ``flwr`` 사전 릴리즈를 " "``simulation`` extra와 함께 설치해야 합니다:" @@ -5295,15 +5346,16 @@ msgstr "야간 릴리즈 설치" #: ../../source/how-to-install-flower.rst:76 msgid "" -"The latest (potentially unstable) changes in Flower are available as " -"nightly releases::" -msgstr "Flower의 최신 (불안정할 수 있는) 변경 사항은 다음과 같이 야간 릴리즈로 " -"제공됩니다:" +"The latest (potentially unstable) changes in Flower are available as nightly " +"releases::" +msgstr "" +"Flower의 최신 (불안정할 수 있는) 변경 사항은 다음과 같이 야간 릴리즈로 제공됩" +"니다:" #: ../../source/how-to-install-flower.rst:80 msgid "" -"For simulations that use the Virtual Client Engine, ``flwr-nightly`` " -"should be installed with the ``simulation`` extra::" +"For simulations that use the Virtual Client Engine, ``flwr-nightly`` should " +"be installed with the ``simulation`` extra::" msgstr "" "가상 클라이언트 엔진을 사용하는 시뮬레이션의 경우, ``flwr-nightly``를 " "``simulation`` extr와 함께 설치해야 합니다::" @@ -5314,24 +5366,24 @@ msgstr "모니터 시뮬레이션" #: ../../source/how-to-monitor-simulation.rst:4 msgid "" -"Flower allows you to monitor system resources while running your " -"simulation. Moreover, the Flower simulation engine is powerful and " -"enables you to decide how to allocate resources per client manner and " -"constrain the total usage. Insights from resource consumption can help " -"you make smarter decisions and speed up the execution time." +"Flower allows you to monitor system resources while running your simulation. " +"Moreover, the Flower simulation engine is powerful and enables you to decide " +"how to allocate resources per client manner and constrain the total usage. " +"Insights from resource consumption can help you make smarter decisions and " +"speed up the execution time." msgstr "" -"Flower를 사용하면 시뮬레이션을 실행하는 동안 시스템 리소스를 모니터링할 수 " -"있습니다. 또한 Flower 시뮬레이션 엔진은 강력하며 클라이언트별 리소스 할당 " -"방법을 결정하고 총 사용량을 제한할 수 있습니다. 리소스 소비에 대한 " -"인사이트를 통해 더 현명한 결정을 내리고 실행 시간을 단축할 수 있습니다." +"Flower를 사용하면 시뮬레이션을 실행하는 동안 시스템 리소스를 모니터링할 수 있" +"습니다. 또한 Flower 시뮬레이션 엔진은 강력하며 클라이언트별 리소스 할당 방법" +"을 결정하고 총 사용량을 제한할 수 있습니다. 리소스 소비에 대한 인사이트를 통" +"해 더 현명한 결정을 내리고 실행 시간을 단축할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:6 msgid "" -"The specific instructions assume you are using macOS and have the " -"`Homebrew `_ package manager installed." +"The specific instructions assume you are using macOS and have the `Homebrew " +"`_ package manager installed." msgstr "" -"구체적인 지침은 macOS를 사용 중이고 'Homebrew `_ 패키지 " -"관리자가 설치되어 있다고 가정합니다." +"구체적인 지침은 macOS를 사용 중이고 'Homebrew `_ 패키지 관" +"리자가 설치되어 있다고 가정합니다." #: ../../source/how-to-monitor-simulation.rst:10 msgid "Downloads" @@ -5339,15 +5391,15 @@ msgstr "다운로드" #: ../../source/how-to-monitor-simulation.rst:16 msgid "" -"`Prometheus `_ is used for data collection, while" -" `Grafana `_ will enable you to visualize the " -"collected data. They are both well integrated with `Ray " -"`_ which Flower uses under the hood." +"`Prometheus `_ is used for data collection, while " +"`Grafana `_ will enable you to visualize the collected " +"data. They are both well integrated with `Ray `_ which " +"Flower uses under the hood." msgstr "" "`Prometheus `_는 데이터 수집에 사용되며, `Grafana " "`_는 수집된 데이터를 시각화할 수 있게 해줍니다. 이 두 " -"도구는 모두 Flower가 내부적으로 사용하는 `Ray `_와 잘 " -"통합되어 있습니다." +"도구는 모두 Flower가 내부적으로 사용하는 `Ray `_와 잘 통" +"합되어 있습니다." #: ../../source/how-to-monitor-simulation.rst:18 msgid "" @@ -5365,25 +5417,25 @@ msgstr "이전 세대 Intel Mac 장치에서는:" #: ../../source/how-to-monitor-simulation.rst:34 msgid "" -"Open the respective configuration files and change them. Depending on " -"your device, use one of the two following commands:" -msgstr "각 구성 파일을 열고 변경합니다. 장치에 따라 다음 두 명령 중 하나를 " -"사용합니다:" +"Open the respective configuration files and change them. Depending on your " +"device, use one of the two following commands:" +msgstr "" +"각 구성 파일을 열고 변경합니다. 장치에 따라 다음 두 명령 중 하나를 사용합니" +"다:" #: ../../source/how-to-monitor-simulation.rst:44 msgid "" -"and then delete all the text in the file and paste a new Prometheus " -"config you see below. You may adjust the time intervals to your " -"requirements:" +"and then delete all the text in the file and paste a new Prometheus config " +"you see below. You may adjust the time intervals to your requirements:" msgstr "" -"를 입력한 다음 파일의 모든 텍스트를 삭제하고 아래에 표시된 새 Prometheus " -"설정을 붙여넣습니다. 요구 사항에 따라 시간 간격을 조정할 수 있습니다:" +"를 입력한 다음 파일의 모든 텍스트를 삭제하고 아래에 표시된 새 Prometheus 설정" +"을 붙여넣습니다. 요구 사항에 따라 시간 간격을 조정할 수 있습니다:" #: ../../source/how-to-monitor-simulation.rst:59 msgid "" -"Now after you have edited the Prometheus configuration, do the same with " -"the Grafana configuration files. Open those using one of the following " -"commands as before:" +"Now after you have edited the Prometheus configuration, do the same with the " +"Grafana configuration files. Open those using one of the following commands " +"as before:" msgstr "" "이제 Prometheus 구성을 편집한 후 Grafana 구성 파일에 대해서도 동일한 작업을 " "수행합니다. 이전과 마찬가지로 다음 명령 중 하나를 사용하여 파일을 엽니다:" @@ -5392,14 +5444,16 @@ msgstr "" msgid "" "Your terminal editor should open and allow you to apply the following " "configuration as before." -msgstr "터미널 편집기가 열리면 이전과 마찬가지로 다음 구성을 적용할 수 있습니다." +msgstr "" +"터미널 편집기가 열리면 이전과 마찬가지로 다음 구성을 적용할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:84 msgid "" -"Congratulations, you just downloaded all the necessary software needed " -"for metrics tracking. Now, let’s start it." -msgstr "축하합니다. 매트릭 트레킹에 필요한 모든 소프트웨어를 다운로드하셨습니다. " -"이제 시작해 보겠습니다." +"Congratulations, you just downloaded all the necessary software needed for " +"metrics tracking. Now, let’s start it." +msgstr "" +"축하합니다. 매트릭 트레킹에 필요한 모든 소프트웨어를 다운로드하셨습니다. 이" +"제 시작해 보겠습니다." #: ../../source/how-to-monitor-simulation.rst:88 msgid "Tracking metrics" @@ -5409,14 +5463,15 @@ msgstr "매트릭 트래킹" msgid "" "Before running your Flower simulation, you have to start the monitoring " "tools you have just installed and configured." -msgstr "Flower 시뮬레이션을 실행하기 전에 방금 설치 및 구성한 모니터링 도구를 " -"시작해야 합니다." +msgstr "" +"Flower 시뮬레이션을 실행하기 전에 방금 설치 및 구성한 모니터링 도구를 시작해" +"야 합니다." #: ../../source/how-to-monitor-simulation.rst:97 msgid "" -"Please include the following argument in your Python code when starting a" -" simulation." -msgstr "시뮬레이션을 시작할 때 Python 코드에 다음 argument를 포함하세요." +"Please include the following argument in your Python code when starting a " +"simulation." +msgstr "시뮬레이션을 시작할 때 Python 코드에 다음 전달인자를 포함하세요." #: ../../source/how-to-monitor-simulation.rst:108 msgid "Now, you are ready to start your workload." @@ -5424,9 +5479,10 @@ msgstr "이제 워크로드를 시작할 준비가 되었습니다." #: ../../source/how-to-monitor-simulation.rst:110 msgid "" -"Shortly after the simulation starts, you should see the following logs in" -" your terminal:" -msgstr "시뮬레이션이 시작되고 얼마 지나지 않아 터미널에 다음 로그가 표시됩니다:" +"Shortly after the simulation starts, you should see the following logs in " +"your terminal:" +msgstr "" +"시뮬레이션이 시작되고 얼마 지나지 않아 터미널에 다음 로그가 표시됩니다:" #: ../../source/how-to-monitor-simulation.rst:117 msgid "You can look at everything at ``_ ." @@ -5434,24 +5490,24 @@ msgstr "``_ 에서 모든 것을 볼 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:119 msgid "" -"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the" -" lowest option)." -msgstr "Ray 대시보드입니다. 메트릭(왼쪽 패널의 가장 아래 옵션)으로 이동할 수 " -"있습니다." +"It's a Ray Dashboard. You can navigate to Metrics (on the left panel, the " +"lowest option)." +msgstr "" +"Ray 대시보드입니다. 메트릭(왼쪽 패널의 가장 아래 옵션)으로 이동할 수 있습니" +"다." #: ../../source/how-to-monitor-simulation.rst:121 msgid "" -"Or alternatively, you can just see them in Grafana by clicking on the " -"right-up corner, “View in Grafana”. Please note that the Ray dashboard is" -" only accessible during the simulation. After the simulation ends, you " -"can only use Grafana to explore the metrics. You can start Grafana by " -"going to ``http://localhost:3000/``." +"Or alternatively, you can just see them in Grafana by clicking on the right-" +"up corner, “View in Grafana”. Please note that the Ray dashboard is only " +"accessible during the simulation. After the simulation ends, you can only " +"use Grafana to explore the metrics. You can start Grafana by going to " +"``http://localhost:3000/``." msgstr "" -"또는 오른쪽 위 모서리인 \"Grafana에서 보기\"를 클릭하여 Grafana에서 바로 " -"확인할 수도 있습니다. Ray 대시보드는 시뮬레이션 중에만 액세스할 수 있다는 " -"점에 유의하세요. 시뮬레이션이 종료된 후에는 Grafana를 사용하여 메트릭을 " -"탐색할 수만 있습니다. ``http://localhost:3000/``로 이동하여 Grafana를 시작할 " -"수 있습니다." +"또는 오른쪽 위 모서리인 \"Grafana에서 보기\"를 클릭하여 Grafana에서 바로 확인" +"할 수도 있습니다. Ray 대시보드는 시뮬레이션 중에만 액세스할 수 있다는 점에 유" +"의하세요. 시뮬레이션이 종료된 후에는 Grafana를 사용하여 메트릭을 탐색할 수만 " +"있습니다. ``http://localhost:3000/``로 이동하여 Grafana를 시작할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:123 msgid "" @@ -5468,26 +5524,26 @@ msgstr "리소스 할당" #: ../../source/how-to-monitor-simulation.rst:134 msgid "" -"You must understand how the Ray library works to efficiently allocate " -"system resources to simulation clients on your own." -msgstr "Ray 라이브러리가 어떻게 작동하는지 이해해야 시뮬레이션 클라이언트에 시스템 " -"리소스를 효율적으로 할당할 수 있습니다." +"You must understand how the Ray library works to efficiently allocate system " +"resources to simulation clients on your own." +msgstr "" +"Ray 라이브러리가 어떻게 작동하는지 이해해야 시뮬레이션 클라이언트에 시스템 리" +"소스를 효율적으로 할당할 수 있습니다." #: ../../source/how-to-monitor-simulation.rst:136 msgid "" "Initially, the simulation (which Ray handles under the hood) starts by " "default with all the available resources on the system, which it shares " -"among the clients. It doesn't mean it divides it equally among all of " -"them, nor that the model training happens at all of them simultaneously. " -"You will learn more about that in the later part of this blog. You can " -"check the system resources by running the following:" -msgstr "" -"처음에 시뮬레이션(Ray가 내부에서 처리하는)은 기본적으로 시스템에서 사용 " -"가능한 모든 리소스를 사용하여 시작되며, 이 리소스는 클라이언트 간에 " -"공유됩니다. 그렇다고 해서 모든 클라이언트에게 균등하게 분배하거나 모든 " -"클라이언트에서 동시에 모델 학습이 이루어지는 것은 아닙니다. 이에 대한 자세한 " -"내용은 이 블로그의 뒷부분에서 설명합니다. 다음을 실행하여 시스템 리소스를 " -"확인할 수 있습니다:" +"among the clients. It doesn't mean it divides it equally among all of them, " +"nor that the model training happens at all of them simultaneously. You will " +"learn more about that in the later part of this blog. You can check the " +"system resources by running the following:" +msgstr "" +"처음에 시뮬레이션(Ray가 내부에서 처리하는)은 기본적으로 시스템에서 사용 가능" +"한 모든 리소스를 사용하여 시작되며, 이 리소스는 클라이언트 간에 공유됩니다. " +"그렇다고 해서 모든 클라이언트에게 균등하게 분배하거나 모든 클라이언트에서 동" +"시에 모델 학습이 이루어지는 것은 아닙니다. 이에 대한 자세한 내용은 이 블로그" +"의 뒷부분에서 설명합니다. 다음을 실행하여 시스템 리소스를 확인할 수 있습니다:" #: ../../source/how-to-monitor-simulation.rst:143 msgid "In Google Colab, the result you see might be similar to this:" @@ -5495,10 +5551,11 @@ msgstr "Google Colab에서는 이와 유사한 결과가 표시될 수 있습니 #: ../../source/how-to-monitor-simulation.rst:155 msgid "" -"However, you can overwrite the defaults. When starting a simulation, do " -"the following (you don't need to overwrite all of them):" -msgstr "그러나 기본값을 덮어쓸 수 있습니다. 시뮬레이션을 시작할 때 다음을 수행합니다(" -"모두 덮어쓸 필요는 없음):" +"However, you can overwrite the defaults. When starting a simulation, do the " +"following (you don't need to overwrite all of them):" +msgstr "" +"그러나 기본값을 덮어쓸 수 있습니다. 시뮬레이션을 시작할 때 다음을 수행합니다" +"(모두 덮어쓸 필요는 없음):" #: ../../source/how-to-monitor-simulation.rst:175 msgid "Let’s also specify the resource for a single client." @@ -5506,28 +5563,28 @@ msgstr "단일 클라이언트에 대한 리소스도 지정해 보겠습니다. #: ../../source/how-to-monitor-simulation.rst:205 msgid "" -"Now comes the crucial part. Ray will start a new client only when it has " -"all the required resources (such that they run in parallel) when the " -"resources allow." +"Now comes the crucial part. Ray will start a new client only when it has all " +"the required resources (such that they run in parallel) when the resources " +"allow." msgstr "" -"이제 중요한 부분이 나옵니다. Ray는 리소스가 허용하는 경우에만 필요한 모든 " -"리소스가 있을 때(병렬로 실행되는 등) 새 클라이언트를 시작합니다." +"이제 중요한 부분이 나옵니다. Ray는 리소스가 허용하는 경우에만 필요한 모든 리" +"소스가 있을 때(병렬로 실행되는 등) 새 클라이언트를 시작합니다." #: ../../source/how-to-monitor-simulation.rst:207 msgid "" -"In the example above, only one client will be run, so your clients won't " -"run concurrently. Setting :code:`client_num_gpus = 0.5` would allow " -"running two clients and therefore enable them to run concurrently. Be " -"careful not to require more resources than available. If you specified " -":code:`client_num_gpus = 2`, the simulation wouldn't start (even if you " -"had 2 GPUs but decided to set 1 in :code:`ray_init_args`)." +"In the example above, only one client will be run, so your clients won't run " +"concurrently. Setting :code:`client_num_gpus = 0.5` would allow running two " +"clients and therefore enable them to run concurrently. Be careful not to " +"require more resources than available. If you specified :code:" +"`client_num_gpus = 2`, the simulation wouldn't start (even if you had 2 GPUs " +"but decided to set 1 in :code:`ray_init_args`)." msgstr "" -"위의 예에서는 하나의 클라이언트만 실행되므로 클라이언트가 동시에 실행되지 " -"않습니다. :code:`client_num_gpus = 0.5` 를 설정하면 두 개의 클라이언트를 " -"실행할 수 있으므로 동시에 실행할 수 있습니다. 사용 가능한 리소스보다 더 많은 " -"리소스를 요구하지 않도록 주의하세요. :code:`client_num_gpus = 2`를 지정하면 " -"시뮬레이션이 시작되지 않습니다(GPU가 2개이지만 :code:`ray_init_args`에서 " -"1개를 설정한 경우에도 마찬가지입니다)." +"위의 예에서는 하나의 클라이언트만 실행되므로 클라이언트가 동시에 실행되지 않" +"습니다. :code:`client_num_gpus = 0.5` 를 설정하면 두 개의 클라이언트를 실행" +"할 수 있으므로 동시에 실행할 수 있습니다. 사용 가능한 리소스보다 더 많은 리소" +"스를 요구하지 않도록 주의하세요. :code:`client_num_gpus = 2`를 지정하면 시뮬" +"레이션이 시작되지 않습니다(GPU가 2개이지만 :code:`ray_init_args`에서 1개를 설" +"정한 경우에도 마찬가지입니다)." #: ../../source/how-to-monitor-simulation.rst:212 ../../source/ref-faq.rst:2 msgid "FAQ" @@ -5539,29 +5596,29 @@ msgstr "질문: 기록된 메트릭이 보이지 않습니다." #: ../../source/how-to-monitor-simulation.rst:216 msgid "" -"A: The timeframe might not be properly set. The setting is in the top " -"right corner (\"Last 30 minutes\" by default). Please change the " -"timeframe to reflect the period when the simulation was running." +"A: The timeframe might not be properly set. The setting is in the top right " +"corner (\"Last 30 minutes\" by default). Please change the timeframe to " +"reflect the period when the simulation was running." msgstr "" -"A: 기간이 제대로 설정되지 않았을 수 있습니다. 설정은 오른쪽 상단에 있습니다(" -"기본값은 '지난 30분'). 시뮬레이션이 실행된 기간을 반영하도록 기간을 변경해 " +"A: 기간이 제대로 설정되지 않았을 수 있습니다. 설정은 오른쪽 상단에 있습니다" +"(기본값은 '지난 30분'). 시뮬레이션이 실행된 기간을 반영하도록 기간을 변경해 " "주세요." #: ../../source/how-to-monitor-simulation.rst:218 msgid "" -"Q: I see “Grafana server not detected. Please make sure the Grafana " -"server is running and refresh this page” after going to the Metrics tab " -"in Ray Dashboard." +"Q: I see “Grafana server not detected. Please make sure the Grafana server " +"is running and refresh this page” after going to the Metrics tab in Ray " +"Dashboard." msgstr "" -"질문: \"Grafana 서버가 감지되지 않았습니다. Ray 대시보드의 메트릭 탭으로 " -"이동한 후 Grafana 서버가 실행 중인지 확인하고 이 페이지를 새로고침하세요." -"\"라는 메시지가 표시됩니다." +"질문: \"Grafana 서버가 감지되지 않았습니다. Ray 대시보드의 메트릭 탭으로 이동" +"한 후 Grafana 서버가 실행 중인지 확인하고 이 페이지를 새로고침하세요.\"라는 " +"메시지가 표시됩니다." #: ../../source/how-to-monitor-simulation.rst:220 msgid "" -"A: You probably don't have Grafana running. Please check the running " -"services" -msgstr "A: Grafana가 실행되고 있지 않을 수 있습니다. 실행 중인 서비스를 확인하세요" +"A: You probably don't have Grafana running. Please check the running services" +msgstr "" +"A: Grafana가 실행되고 있지 않을 수 있습니다. 실행 중인 서비스를 확인하세요" #: ../../source/how-to-monitor-simulation.rst:226 msgid "" @@ -5573,8 +5630,8 @@ msgstr "" #: ../../source/how-to-monitor-simulation.rst:228 msgid "" -"A: Either the simulation has already finished, or you still need to start" -" Prometheus." +"A: Either the simulation has already finished, or you still need to start " +"Prometheus." msgstr "A: 시뮬레이션이 이미 완료되었거나 아직 Prometheus를 시작해야 합니다." #: ../../source/how-to-monitor-simulation.rst:232 @@ -5599,14 +5656,13 @@ msgstr "Docker를 사용하여 Flower 실행" #: ../../source/how-to-run-flower-using-docker.rst:4 msgid "" -"The simplest way to get started with Flower is by using the pre-made " -"Docker images, which you can find on `Docker Hub " -"`__. Supported architectures include " -"``amd64`` and ``arm64v8``." +"The simplest way to get started with Flower is by using the pre-made Docker " +"images, which you can find on `Docker Hub `__. Supported architectures include ``amd64`` and ``arm64v8``." msgstr "" "Flower를 시작하는 가장 간단한 방법은 `Docker Hub `__에서 찾을 수 있는 미리 만들어진 Docker 이미지를 사용하는 것입니다. " -"지원되는 아키텍처는 ``amd64`` 및 ``arm64v8``입니다." +"flwr>`__에서 찾을 수 있는 미리 만들어진 Docker 이미지를 사용하는 것입니다. 지" +"원되는 아키텍처는 ``amd64`` 및 ``arm64v8``입니다." #: ../../source/how-to-run-flower-using-docker.rst:8 msgid "Before you start, make sure that the Docker daemon is running:" @@ -5614,10 +5670,9 @@ msgstr "시작하기 전에 Docker daemon이 실행 중인지 확인하세요:" #: ../../source/how-to-run-flower-using-docker.rst:15 msgid "" -"If you do not see the version of Docker but instead get an error saying " -"that the command was not found, you will need to install Docker first. " -"You can find installation instruction `here `_." +"If you do not see the version of Docker but instead get an error saying that " +"the command was not found, you will need to install Docker first. You can " +"find installation instruction `here `_." msgstr "" "전이 표시되지 않고 대신 명령을 찾을 수 없다는 오류가 표시되는 경우 먼저 " "Docker를 설치해야 합니다. `여기 `_에서 " @@ -5625,26 +5680,26 @@ msgstr "" #: ../../source/how-to-run-flower-using-docker.rst:21 msgid "" -"On Linux, Docker commands require ``sudo`` privilege. If you want to " -"avoid using ``sudo``, you can follow the `Post-installation steps " -"`_ on the " -"official Docker website." +"On Linux, Docker commands require ``sudo`` privilege. If you want to avoid " +"using ``sudo``, you can follow the `Post-installation steps `_ on the official Docker " +"website." msgstr "" -"Linux에서 Docker 명령을 실행하려면 ``sudo`` 권한이 필요합니다. sudo``를 " +"Linux에서 Docker 명령을 실행하려면 ``sudo`` 권한이 필요합니다. ``sudo`` 를 " "사용하지 않으려면 공식 Docker 웹사이트의 `Post-installation steps " "`_를 따르세요." #: ../../source/how-to-run-flower-using-docker.rst:27 msgid "" -"To ensure optimal performance and compatibility, the SuperLink, SuperNode" -" and ServerApp image must have the same version when running together. " -"This guarantees seamless integration and avoids potential conflicts or " -"issues that may arise from using different versions." +"To ensure optimal performance and compatibility, the SuperLink, SuperNode " +"and ServerApp image must have the same version when running together. This " +"guarantees seamless integration and avoids potential conflicts or issues " +"that may arise from using different versions." msgstr "" "최적의 성능과 호환성을 보장하려면 SuperLink, SuperNode 및 ServerApp 이미지를 " -"함께 실행할 때 버전이 동일해야 합니다. 이렇게 하면 원활한 통합을 보장하고 " -"서로 다른 버전을 사용할 때 발생할 수 있는 잠재적인 충돌이나 문제를 방지할 수 " -"있습니다." +"함께 실행할 때 버전이 동일해야 합니다. 이렇게 하면 원활한 통합을 보장하고 서" +"로 다른 버전을 사용할 때 발생할 수 있는 잠재적인 충돌이나 문제를 방지할 수 있" +"습니다." #: ../../source/how-to-run-flower-using-docker.rst:32 msgid "Flower SuperLink" @@ -5660,60 +5715,60 @@ msgstr "Flower를 사용해보고 싶다면 다음 명령을 사용하면 됩니 #: ../../source/how-to-run-flower-using-docker.rst:43 msgid "" -"The command pulls the Docker image with the tag ``1.8.0`` from Docker " -"Hub. The tag specifies the Flower version. In this case, Flower 1.8.0. " -"The ``--rm`` flag tells Docker to remove the container after it exits." +"The command pulls the Docker image with the tag ``1.8.0`` from Docker Hub. " +"The tag specifies the Flower version. In this case, Flower 1.8.0. The ``--" +"rm`` flag tells Docker to remove the container after it exits." msgstr "" "이 명령은 Docker Hub에서 ``1.8.0`` 태그가 있는 Docker 이미지를 가져옵니다. " -"이 태그는 Flower 버전을 지정합니다. 이 경우, Flower 1.8.0입니다. '`--rm`` " -"플래그는 컨테이너가 종료된 후 컨테이너를 제거하도록 Docker에 지시합니다." +"이 태그는 Flower 버전을 지정합니다. 이 경우, Flower 1.8.0입니다. '`--rm`` 플" +"래그는 컨테이너가 종료된 후 컨테이너를 제거하도록 Docker에 지시합니다." #: ../../source/how-to-run-flower-using-docker.rst:49 msgid "" "By default, the Flower SuperLink keeps state in-memory. When using the " -"Docker flag ``--rm``, the state is not persisted between container " -"starts. We will show below how to save the state in a file on your host " -"system." +"Docker flag ``--rm``, the state is not persisted between container starts. " +"We will show below how to save the state in a file on your host system." msgstr "" "기본적으로 Flower SuperLink는 상태를 in-memory에 유지합니다. Docker 플래그 " -"`--rm``을 사용하는 경우 컨테이너 시작 사이에 상태가 유지되지 않습니다. " -"아래에서 호스트 시스템의 파일에 상태를 저장하는 방법을 보여드리겠습니다." +"`--rm``을 사용하는 경우 컨테이너 시작 사이에 상태가 유지되지 않습니다. 아래에" +"서 호스트 시스템의 파일에 상태를 저장하는 방법을 보여드리겠습니다." #: ../../source/how-to-run-flower-using-docker.rst:53 msgid "" -"The ``-p :`` flag tells Docker to map the ports " -"``9091``/``9092`` of the host to ``9091``/``9092`` of the container, " -"allowing you to access the Driver API on ``http://localhost:9091`` and " -"the Fleet API on ``http://localhost:9092``. Lastly, any flag that comes " -"after the tag is passed to the Flower SuperLink. Here, we are passing the" -" flag ``--insecure``." +"The ``-p :`` flag tells Docker to map the ports ``9091``/" +"``9092`` of the host to ``9091``/``9092`` of the container, allowing you to " +"access the Driver API on ``http://localhost:9091`` and the Fleet API on " +"``http://localhost:9092``. Lastly, any flag that comes after the tag is " +"passed to the Flower SuperLink. Here, we are passing the flag ``--insecure``." msgstr "" -"``-p :`` 플래그는 호스트의 포트 ``9091``/``9092``를 " -"컨테이너의 ``9091``/``9092``에 매핑하여 ``http://localhost:9091``의 드라이버 " -"API와 ``http://localhost:9092``의 Fleet API에 액세스할 수 있도록 Docker에 " -"지시합니다. 마지막으로, 태그 뒤에 오는 모든 플래그는 Flower SuperLink에 " -"전달됩니다. 여기서는 ``--insecure``플래그를 전달합니다." +"``-p :`` 플래그는 호스트의 포트 ``9091``/``9092``를 컨테이너" +"의 ``9091``/``9092``에 매핑하여 ``http://localhost:9091``의 드라이버 API와 " +"``http://localhost:9092``의 Fleet API에 액세스할 수 있도록 Docker에 지시합니" +"다. 마지막으로, 태그 뒤에 오는 모든 플래그는 Flower SuperLink에 전달됩니다. " +"여기서는 ``--insecure``플래그를 전달합니다." #: ../../source/how-to-run-flower-using-docker.rst:60 #: ../../source/how-to-run-flower-using-docker.rst:259 #: ../../source/how-to-run-flower-using-docker.rst:376 msgid "" "The ``--insecure`` flag enables insecure communication (using HTTP, not " -"HTTPS) and should only be used for testing purposes. We strongly " -"recommend enabling `SSL `__ when " -"deploying to a production environment." +"HTTPS) and should only be used for testing purposes. We strongly recommend " +"enabling `SSL `__ when deploying to a " +"production environment." msgstr "" -"``--insecure`` 플래그는 안전하지 않은 통신(HTTPS가 아닌 HTTP 사용)을 " -"활성화하며 테스트 목적으로만 사용해야 합니다. 프로덕션 환경에 배포할 때는 `" -"SSL `__을 활성화할 것을 강력히 권장합니다." +"``--insecure`` 플래그는 안전하지 않은 통신(HTTPS가 아닌 HTTP 사용)을 활성화하" +"며 테스트 목적으로만 사용해야 합니다. 프로덕션 환경에 배포할 때는 `SSL " +"`__을 활성화할 것을 강력히 권장합니" +"다." #: ../../source/how-to-run-flower-using-docker.rst:65 msgid "" "You can use ``--help`` to view all available flags that the SuperLink " "supports:" -msgstr "'`--help``을 사용하면 SuperLink가 지원하는 모든 플래그를 볼 수 있습니다:" +msgstr "" +"'`--help``을 사용하면 SuperLink가 지원하는 모든 플래그를 볼 수 있습니다:" #: ../../source/how-to-run-flower-using-docker.rst:72 msgid "Mounting a volume to store the state on the host system" @@ -5721,49 +5776,47 @@ msgstr "호스트 시스템에 상태를 저장할 볼륨 마운트하기" #: ../../source/how-to-run-flower-using-docker.rst:74 msgid "" -"If you want to persist the state of the SuperLink on your host system, " -"all you need to do is specify a directory where you want to save the file" -" on your host system and a name for the database file. By default, the " -"SuperLink container runs with a non-root user called ``app`` with the " -"user ID ``49999``. It is recommended to create new directory and change " -"the user ID of the directory to ``49999`` to ensure the mounted directory" -" has the proper permissions. If you later want to delete the directory, " -"you can change the user ID back to the current user ID by running ``sudo " -"chown -R $USER:$(id -gn) state``." -msgstr "" -"호스트 시스템에서 SuperLink의 상태를 유지하려면 호스트 시스템에서 파일을 " -"저장할 디렉터리와 데이터베이스 파일의 이름을 지정하기만 하면 됩니다. " -"기본적으로 SuperLink 컨테이너는 사용자 ID가 ``49999``인 ``app``이라는 루트가 " -"아닌 사용자로 실행됩니다. 마운트된 디렉터리에 적절한 권한이 있는지 " -"확인하려면 새 디렉터리를 생성하고 디렉터리의 사용자 ID를 ``49999``로 " -"변경하는 것이 좋습니다. 나중에 디렉터리를 삭제하려면 ``sudo chown -R $USER:$(" -"id -gn) state``를 실행하여 사용자 ID를 현재 사용자 ID로 다시 변경할 수 " -"있습니다." +"If you want to persist the state of the SuperLink on your host system, all " +"you need to do is specify a directory where you want to save the file on " +"your host system and a name for the database file. By default, the SuperLink " +"container runs with a non-root user called ``app`` with the user ID " +"``49999``. It is recommended to create new directory and change the user ID " +"of the directory to ``49999`` to ensure the mounted directory has the proper " +"permissions. If you later want to delete the directory, you can change the " +"user ID back to the current user ID by running ``sudo chown -R $USER:$(id -" +"gn) state``." +msgstr "" +"호스트 시스템에서 SuperLink의 상태를 유지하려면 호스트 시스템에서 파일을 저장" +"할 디렉터리와 데이터베이스 파일의 이름을 지정하기만 하면 됩니다. 기본적으로 " +"SuperLink 컨테이너는 사용자 ID가 ``49999``인 ``app``이라는 루트가 아닌 사용자" +"로 실행됩니다. 마운트된 디렉터리에 적절한 권한이 있는지 확인하려면 새 디렉터" +"리를 생성하고 디렉터리의 사용자 ID를 ``49999``로 변경하는 것이 좋습니다. 나중" +"에 디렉터리를 삭제하려면 ``sudo chown -R $USER:$(id -gn) state``를 실행하여 " +"사용자 ID를 현재 사용자 ID로 다시 변경할 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:82 msgid "" -"In the example below, we create a new directory, change the user ID and " -"tell Docker via the flag ``--volume`` to mount the local ``state`` " -"directory into the ``/app/state`` directory of the container. " -"Furthermore, we use the flag ``--database`` to specify the name of the " -"database file." +"In the example below, we create a new directory, change the user ID and tell " +"Docker via the flag ``--volume`` to mount the local ``state`` directory into " +"the ``/app/state`` directory of the container. Furthermore, we use the flag " +"``--database`` to specify the name of the database file." msgstr "" -"아래 예에서는 새 디렉터리를 생성하고, 사용자 ID를 변경하고, 플래그 " -"``--volume``을 통해 Docker에게 로컬 ``state`` 디렉터리를 컨테이너의 ``/app/" -"state`` 디렉터리에 마운트하도록 지시합니다. 또한 ``--database`` 플래그를 " -"사용하여 데이터베이스 파일의 이름을 지정합니다." +"아래 예에서는 새 디렉터리를 생성하고, 사용자 ID를 변경하고, 플래그 ``--" +"volume``을 통해 Docker에게 로컬 ``state`` 디렉터리를 컨테이너의 ``/app/" +"state`` 디렉터리에 마운트하도록 지시합니다. 또한 ``--database`` 플래그를 사용" +"하여 데이터베이스 파일의 이름을 지정합니다." #: ../../source/how-to-run-flower-using-docker.rst:95 msgid "" "As soon as the SuperLink starts, the file ``state.db`` is created in the " "``state`` directory on your host system. If the file already exists, the " -"SuperLink tries to restore the state from the file. To start the " -"SuperLink with an empty database, simply remove the ``state.db`` file." +"SuperLink tries to restore the state from the file. To start the SuperLink " +"with an empty database, simply remove the ``state.db`` file." msgstr "" -"SuperLink가 시작되자마자 호스트 시스템의 ``state`` 디렉터리에 ``state.db`` " -"파일이 생성됩니다. 파일이 이미 존재하는 경우 SuperLink는 파일에서 상태를 " -"복원하려고 시도합니다. 빈 데이터베이스로 SuperLink를 시작하려면 ``state.db`` " -"파일을 제거하면 됩니다." +"SuperLink가 시작되자마자 호스트 시스템의 ``state`` 디렉터리에 ``state.db`` 파" +"일이 생성됩니다. 파일이 이미 존재하는 경우 SuperLink는 파일에서 상태를 복원하" +"려고 시도합니다. 빈 데이터베이스로 SuperLink를 시작하려면 ``state.db`` 파일" +"을 제거하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:100 #: ../../source/how-to-run-flower-using-docker.rst:281 @@ -5773,18 +5826,18 @@ msgstr "보안 연결을 위한 SSL 사용 설정" #: ../../source/how-to-run-flower-using-docker.rst:102 msgid "" -"To enable SSL, you will need a PEM-encoded root certificate, a PEM-" -"encoded private key and a PEM-encoded certificate chain." +"To enable SSL, you will need a PEM-encoded root certificate, a PEM-encoded " +"private key and a PEM-encoded certificate chain." msgstr "" "SSL을 사용하려면 PEM으로 인코딩된 루트 인증서, PEM으로 인코딩된 개인 키 및 " "PEM으로 인코딩된 인증서 체인이 필요합니다." #: ../../source/how-to-run-flower-using-docker.rst:106 msgid "" -"For testing purposes, you can generate your own self-signed certificates." -" The `Enable SSL connections `__ page contains a section that" -" will guide you through the process." +"For testing purposes, you can generate your own self-signed certificates. " +"The `Enable SSL connections `__ page contains a section that will " +"guide you through the process." msgstr "" "테스트 목적으로 자체 서명된 인증서를 생성할 수 있습니다. 'SSL 연결 사용 " "`__ is already installed " -"in the ``flwr/supernode`` base image, so you only need to include other " -"package dependencies in your ``requirements.txt``, such as ``torch``, " +"Note that `flwr `__ is already installed in " +"the ``flwr/supernode`` base image, so you only need to include other package " +"dependencies in your ``requirements.txt``, such as ``torch``, " "``tensorflow``, etc." msgstr "" -"`flwr `__ 는 이미 ``flwr/supernode`` 기본 " -"이미지에 설치되어 있으므로, ``torch``, ``tensorflow`` 등과 같은 다른 패키지 " +"`flwr `__ 는 이미 ``flwr/supernode`` 기본 이" +"미지에 설치되어 있으므로, ``torch``, ``tensorflow`` 등과 같은 다른 패키지 " "dependencies만 ``requirements.txt``에 포함시키면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:200 msgid "" -"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` " -"example, create a new file called ``Dockerfile.supernode`` in ``examples" -"/quickstart-pytorch``." +"Next, we create a Dockerfile. If you use the ``quickstart-pytorch`` example, " +"create a new file called ``Dockerfile.supernode`` in ``examples/quickstart-" +"pytorch``." msgstr "" -"다음으로, Dockerfile을 생성합니다.``quickstart-pytorch`` 예제를 사용하는 " -"경우 ``examples/quickstart-pytorch``에 ``Dockerfile.supernode``라는 새 " -"파일을 생성합니다." +"다음으로, Dockerfile을 생성합니다.``quickstart-pytorch`` 예제를 사용하는 경" +"우 ``examples/quickstart-pytorch``에 ``Dockerfile.supernode``라는 새 파일을 " +"생성합니다." #: ../../source/how-to-run-flower-using-docker.rst:203 msgid "" "The ``Dockerfile.supernode`` contains the instructions that assemble the " "SuperNode image." -msgstr "``Dockerfile.supernode``에는 SuperNode 이미지를 조립하는 지침이 포함되어 " -"있습니다." +msgstr "" +"``Dockerfile.supernode``에는 SuperNode 이미지를 조립하는 지침이 포함되어 있습" +"니다." #: ../../source/how-to-run-flower-using-docker.rst:217 msgid "" -"In the first two lines, we instruct Docker to use the SuperNode image " -"tagged ``nightly`` as a base image and set our working directory to " -"``/app``. The following instructions will now be executed in the ``/app``" -" directory. Next, we install the ClientApp dependencies by copying the " -"``requirements.txt`` file into the image and run ``pip install``. In the " -"last two lines, we copy the ``client.py`` module into the image and set " -"the entry point to ``flower-client-app`` with the argument " -"``client:app``. The argument is the object reference of the ClientApp " -"(``:``) that will be run inside the ClientApp." -msgstr "" -"처음 두 줄에서는 ``nightly`` 태그가 붙은 SuperNode 이미지를 기본 이미지로 " -"사용하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 " -"``/app`` 디렉토리에서 다음 명령이 실행됩니다. 다음으로, ``requirements.txt`` " -"파일을 이미지에 복사하여 ClientApp dependencies 요소를 설치하고 ``pip " -"install``을 실행합니다. 마지막 두 줄에서 ``client.py`` 모듈을 이미지에 " -"복사하고 ``client:app`` 인수를 사용하여 진입점을 ``flower-client-app``로 " -"설정합니다. 인수는 클라이언트앱 내부에서 실행될 클라이언트앱의 객체 참조 " -"(``:``) 입니다." +"In the first two lines, we instruct Docker to use the SuperNode image tagged " +"``nightly`` as a base image and set our working directory to ``/app``. The " +"following instructions will now be executed in the ``/app`` directory. Next, " +"we install the ClientApp dependencies by copying the ``requirements.txt`` " +"file into the image and run ``pip install``. In the last two lines, we copy " +"the ``client.py`` module into the image and set the entry point to ``flower-" +"client-app`` with the argument ``client:app``. The argument is the object " +"reference of the ClientApp (``:``) that will be run " +"inside the ClientApp." +msgstr "" +"처음 두 줄에서는 ``nightly`` 태그가 붙은 SuperNode 이미지를 기본 이미지로 사" +"용하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 ``/" +"app`` 디렉토리에서 다음 명령이 실행됩니다. 다음으로, ``requirements.txt`` 파" +"일을 이미지에 복사하여 ClientApp dependencies 요소를 설치하고 ``pip install``" +"을 실행합니다. 마지막 두 줄에서 ``client.py`` 모듈을 이미지에 복사하고 " +"``client:app`` 인수를 사용하여 진입점을 ``flower-client-app``로 설정합니다. " +"인수는 클라이언트앱 내부에서 실행될 클라이언트앱의 객체 참조 (``:" +"``) 입니다." #: ../../source/how-to-run-flower-using-docker.rst:226 msgid "Building the SuperNode Docker image" @@ -5946,11 +5999,11 @@ msgstr "SuperNode Docker 이미지 빌드" #: ../../source/how-to-run-flower-using-docker.rst:228 msgid "" -"Next, we build the SuperNode Docker image by running the following " -"command in the directory where Dockerfile and ClientApp code are located." +"Next, we build the SuperNode Docker image by running the following command " +"in the directory where Dockerfile and ClientApp code are located." msgstr "" -"다음으로, Dockerfile 및 ClientApp 코드가 있는 디렉터리에서 다음 명령을 " -"실행하여 SuperNode Docker 이미지를 빌드합니다." +"다음으로, Dockerfile 및 ClientApp 코드가 있는 디렉터리에서 다음 명령을 실행하" +"여 SuperNode Docker 이미지를 빌드합니다." #: ../../source/how-to-run-flower-using-docker.rst:235 msgid "" @@ -5958,9 +6011,9 @@ msgid "" "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" -"이미지에 ``flwr_supernode``라는 이름을 붙이고 ``0.0.1`` 태그를 붙였습니다. " -"여기서 선택한 값은 예시일 뿐이라는 점을 기억하세요. 필요에 따라 변경할 수 " -"있습니다." +"이미지에 ``flwr_supernode``라는 이름을 붙이고 ``0.0.1`` 태그를 붙였습니다. 여" +"기서 선택한 값은 예시일 뿐이라는 점을 기억하세요. 필요에 따라 변경할 수 있습" +"니다." #: ../../source/how-to-run-flower-using-docker.rst:240 msgid "Running the SuperNode Docker image" @@ -5983,9 +6036,10 @@ msgstr "``docker run``: 새 Docker 컨테이너를 실행하는 명령입니다. #: ../../source/how-to-run-flower-using-docker.rst:253 #: ../../source/how-to-run-flower-using-docker.rst:370 msgid "" -"``--rm``: This option specifies that the container should be " -"automatically removed when it stops." -msgstr "``--rm``: 이 옵션은 컨테이너가 중지될 때 자동으로 제거되도록 지정합니다." +"``--rm``: This option specifies that the container should be automatically " +"removed when it stops." +msgstr "" +"``--rm``: 이 옵션은 컨테이너가 중지될 때 자동으로 제거되도록 지정합니다." #: ../../source/how-to-run-flower-using-docker.rst:254 msgid "``flwr_supernode:0.0.1``: The name the tag of the Docker image to use." @@ -5998,26 +6052,28 @@ msgstr "``--insecure``: 이 옵션은 보안되지 않은 통신을 활성화합 #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--superlink 192.168.1.100:9092``: This option specifies the address of " -"the SuperLinks Fleet" -msgstr "``--superlink 192.168.1.100:9092``: 이 옵션은 SuperLinks Fleet의 주소를 " -"지정합니다" +"``--superlink 192.168.1.100:9092``: This option specifies the address of the " +"SuperLinks Fleet" +msgstr "" +"``--superlink 192.168.1.100:9092``: 이 옵션은 SuperLinks Fleet의 주소를 지정" +"합니다" #: ../../source/how-to-run-flower-using-docker.rst msgid "API to connect to. Remember to update it with your SuperLink IP." -msgstr "API에 연결할 수 있습니다. SuperLink IP로 업데이트하는 것을 잊지 마세요." +msgstr "" +"API에 연결할 수 있습니다. SuperLink IP로 업데이트하는 것을 잊지 마세요." #: ../../source/how-to-run-flower-using-docker.rst:269 msgid "" -"To test running Flower locally, you can create a `bridge network " -"`__, use the ``--network`` argument and pass the " -"name of the Docker network to run your SuperNodes." +"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " +"network to run your SuperNodes." msgstr "" "로컬에서 Flower를 실행하는 것을 테스트하려면 `bridge network `__를 생성하고 ``--network`` argument를 사용하고 SuperNodes를 " -"실행할 Docker 네트워크의 이름을 전달하면 됩니다." +"networks>`__를 생성하고 ``--network`` argument를 사용하고 SuperNodes를 실행" +"할 Docker 네트워크의 이름을 전달하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:273 msgid "" @@ -6031,21 +6087,21 @@ msgstr "" msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your SuperNode container." -msgstr "SSL을 사용하려면 PEM 인코딩된 루트 인증서를 SuperNode 컨테이너에 마운트해야 " +msgstr "" +"SSL을 사용하려면 PEM 인코딩된 루트 인증서를 SuperNode 컨테이너에 마운트해야 " "합니다." #: ../../source/how-to-run-flower-using-docker.rst:285 msgid "" -"Assuming the certificate already exists locally, we can use the flag " -"``--volume`` to mount the local certificate into the container's " -"``/app/`` directory. This allows the SuperNode to access the certificate " -"within the container. Use the ``--root-certificates`` flag when starting " -"the container." +"Assuming the certificate already exists locally, we can use the flag ``--" +"volume`` to mount the local certificate into the container's ``/app/`` " +"directory. This allows the SuperNode to access the certificate within the " +"container. Use the ``--root-certificates`` flag when starting the container." msgstr "" -"인증서가 이미 로컬에 존재한다고 가정하면, ``--volume`` 플래그를 사용하여 " -"로컬 인증서를 컨테이너의 ``/app/`` 디렉터리에 마운트할 수 있습니다. 이렇게 " -"하면 SuperNode가 컨테이너 내의 인증서에 액세스할 수 있습니다. 컨테이너를 " -"시작할 때 ``--root-certificates`` 플래그를 사용하세요." +"인증서가 이미 로컬에 존재한다고 가정하면, ``--volume`` 플래그를 사용하여 로" +"컬 인증서를 컨테이너의 ``/app/`` 디렉터리에 마운트할 수 있습니다. 이렇게 하" +"면 SuperNode가 컨테이너 내의 인증서에 액세스할 수 있습니다. 컨테이너를 시작" +"할 때 ``--root-certificates`` 플래그를 사용하세요." #: ../../source/how-to-run-flower-using-docker.rst:297 msgid "Flower ServerApp" @@ -6053,29 +6109,30 @@ msgstr "Flower 서버앱" #: ../../source/how-to-run-flower-using-docker.rst:299 msgid "" -"The procedure for building and running a ServerApp image is almost " -"identical to the SuperNode image." -msgstr "ServerApp 이미지를 빌드하고 실행하는 절차는 SuperNode 이미지와 거의 " -"동일합니다." +"The procedure for building and running a ServerApp image is almost identical " +"to the SuperNode image." +msgstr "" +"ServerApp 이미지를 빌드하고 실행하는 절차는 SuperNode 이미지와 거의 동일합니" +"다." #: ../../source/how-to-run-flower-using-docker.rst:301 msgid "" -"Similar to the SuperNode image, the ServerApp Docker image comes with a " -"pre-installed version of Flower and serves as a base for building your " -"own ServerApp image." +"Similar to the SuperNode image, the ServerApp Docker image comes with a pre-" +"installed version of Flower and serves as a base for building your own " +"ServerApp image." msgstr "" "SuperNode 이미지와 마찬가지로 ServerApp Docker 이미지는 Flower의 사전 설치된 " -"버전과 함께 제공되며, 자체 ServerApp 이미지를 구축하기 위한 기본 역할을 " -"합니다." +"버전과 함께 제공되며, 자체 ServerApp 이미지를 구축하기 위한 기본 역할을 합니" +"다." #: ../../source/how-to-run-flower-using-docker.rst:304 msgid "" -"We will use the same ``quickstart-pytorch`` example as we do in the " -"Flower SuperNode section. If you have not already done so, please follow " -"the `SuperNode Prerequisites`_ before proceeding." +"We will use the same ``quickstart-pytorch`` example as we do in the Flower " +"SuperNode section. If you have not already done so, please follow the " +"`SuperNode Prerequisites`_ before proceeding." msgstr "" -"여기서는 Flower SuperNode 섹션에서와 동일한`quickstart-pytorch`` 예제를 " -"사용하겠습니다. 아직 수행하지 않았다면 계속 진행하기 전에 `SuperNode " +"여기서는 Flower SuperNode 섹션에서와 동일한`quickstart-pytorch`` 예제를 사용" +"하겠습니다. 아직 수행하지 않았다면 계속 진행하기 전에 `SuperNode " "Prerequisites`_ 을 따르세요." #: ../../source/how-to-run-flower-using-docker.rst:309 @@ -6086,8 +6143,8 @@ msgstr "ServerApp Dockerfile 만들기" msgid "" "First, we need to create a Dockerfile in the directory where the " "``ServerApp`` code is located. If you use the ``quickstart-pytorch`` " -"example, create a new file called ``Dockerfile.serverapp`` in ``examples" -"/quickstart-pytorch``." +"example, create a new file called ``Dockerfile.serverapp`` in ``examples/" +"quickstart-pytorch``." msgstr "" "먼저, ``ServerApp`` 코드가 있는 디렉토리에 Docker파일을 생성해야 합니다. " "``quickstart-pytorch`` 예제를 사용하는 경우 ``examples/quickstart-pytorch``" @@ -6097,24 +6154,24 @@ msgstr "" msgid "" "The ``Dockerfile.serverapp`` contains the instructions that assemble the " "ServerApp image." -msgstr "``Dockerfile.serverapp``에는 ServerApp 이미지를 합치는 지침이 포함되어 " -"있습니다." +msgstr "" +"``Dockerfile.serverapp``에는 ServerApp 이미지를 합치는 지침이 포함되어 있습니" +"다." #: ../../source/how-to-run-flower-using-docker.rst:335 msgid "" -"In the first two lines, we instruct Docker to use the ServerApp image " -"tagged ``1.8.0`` as a base image and set our working directory to " -"``/app``. The following instructions will now be executed in the ``/app``" -" directory. In the last two lines, we copy the ``server.py`` module into " -"the image and set the entry point to ``flower-server-app`` with the " -"argument ``server:app``. The argument is the object reference of the " -"ServerApp (``:``) that will be run inside the " -"ServerApp container." -msgstr "" -"처음 두 줄에서는 ``1.8.0`` 태그가 붙은 ServerApp 이미지를 기본 이미지로 " -"사용하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 " -"``/app`` 디렉토리에서 다음 명령이 실행됩니다. 마지막 두 줄에서는 ``server." -"py`` 모듈을 이미지에 복사하고 ``server:app`` argument를 사용하여 진입점을 " +"In the first two lines, we instruct Docker to use the ServerApp image tagged " +"``1.8.0`` as a base image and set our working directory to ``/app``. The " +"following instructions will now be executed in the ``/app`` directory. In " +"the last two lines, we copy the ``server.py`` module into the image and set " +"the entry point to ``flower-server-app`` with the argument ``server:app``. " +"The argument is the object reference of the ServerApp (``:" +"``) that will be run inside the ServerApp container." +msgstr "" +"처음 두 줄에서는 ``1.8.0`` 태그가 붙은 ServerApp 이미지를 기본 이미지로 사용" +"하고 작업 디렉터리를 ``/app``로 설정하도록 Docker에 지시합니다. 이제 ``/" +"app`` 디렉토리에서 다음 명령이 실행됩니다. 마지막 두 줄에서는 ``server.py`` " +"모듈을 이미지에 복사하고 ``server:app`` argument를 사용하여 진입점을 " "``flower-server-app``로 설정합니다. 인수는 ServerApp 컨테이너 내에서 실행될 " "ServerApp의 객체 참조(``:``)입니다." @@ -6124,11 +6181,11 @@ msgstr "ServerApp Docker 이미지 빌드" #: ../../source/how-to-run-flower-using-docker.rst:345 msgid "" -"Next, we build the ServerApp Docker image by running the following " -"command in the directory where Dockerfile and ServerApp code are located." +"Next, we build the ServerApp Docker image by running the following command " +"in the directory where Dockerfile and ServerApp code are located." msgstr "" -"다음으로, Docker파일과 ServerApp 코드가 있는 디렉터리에서 다음 명령을 " -"실행하여 ServerApp Docker 이미지를 빌드합니다." +"다음으로, Docker파일과 ServerApp 코드가 있는 디렉터리에서 다음 명령을 실행하" +"여 ServerApp Docker 이미지를 빌드합니다." #: ../../source/how-to-run-flower-using-docker.rst:352 msgid "" @@ -6136,453 +6193,600 @@ msgid "" "Remember that the here chosen values only serve as an example. You can " "change them to your needs." msgstr "" +"이미지에``flwr_serverapp``이라는 이름을 붙이고 ``0.0.1``이라는 태그를 붙였습" +"니다. 여기서 선택한 값은 예시일 뿐이라는 점을 기억하세요. 필요에 따라 변경할 " +"수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:357 msgid "Running the ServerApp Docker image" -msgstr "" +msgstr "ServerApp Docker 이미지 실행" #: ../../source/how-to-run-flower-using-docker.rst:359 msgid "Now that we have built the ServerApp image, we can finally run it." -msgstr "" +msgstr "이제 ServerApp 이미지를 빌드했으니 이제 실행할 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:371 msgid "``flwr_serverapp:0.0.1``: The name the tag of the Docker image to use." -msgstr "" +msgstr "``flwr_serverapp:0.0.1``: 사용할 Docker 이미지의 태그 이름입니다." #: ../../source/how-to-run-flower-using-docker.rst msgid "" -"``--superlink 192.168.1.100:9091``: This option specifies the address of " -"the SuperLinks Driver" +"``--superlink 192.168.1.100:9091``: This option specifies the address of the " +"SuperLinks Driver" msgstr "" +"``--superlink 192.168.1.100:9091``: 이 옵션은 SuperLinks 드라이버의 주소를 지" +"정합니다" #: ../../source/how-to-run-flower-using-docker.rst:385 msgid "" -"To test running Flower locally, you can create a `bridge network " -"`__, use the ``--network`` argument and pass the " -"name of the Docker network to run your ServerApps." +"To test running Flower locally, you can create a `bridge network `__, use the ``--network`` argument and pass the name of the Docker " +"network to run your ServerApps." msgstr "" +"로컬에서 Flower를 실행하는 것을 테스트하려면 `bridge network `__,를 생성하고 ``--network`` argument를 사용하여 ServerApp을 실행" +"할 Docker 네트워크의 이름을 전달하면 됩니다." #: ../../source/how-to-run-flower-using-docker.rst:389 msgid "" "Any argument that comes after the tag is passed to the Flower ServerApp " "binary. To see all available flags that the ServerApp supports, run:" msgstr "" +"태그 뒤에 오는 모든 argument는 Flower ServerApp 바이너리에 전달됩니다. " +"ServerApp에서 지원하는 사용 가능한 모든 플래그를 보려면 실행하세요:" #: ../../source/how-to-run-flower-using-docker.rst:399 msgid "" "To enable SSL, we will need to mount a PEM-encoded root certificate into " "your ServerApp container." msgstr "" +"SSL을 사용하려면 PEM 인코딩된 루트 인증서를 ServerApp 컨테이너에 마운트해야 " +"합니다." #: ../../source/how-to-run-flower-using-docker.rst:401 msgid "" -"Assuming the certificate already exists locally, we can use the flag " -"``--volume`` to mount the local certificate into the container's " -"``/app/`` directory. This allows the ServerApp to access the certificate " -"within the container. Use the ``--root-certificates`` flags when starting" -" the container." +"Assuming the certificate already exists locally, we can use the flag ``--" +"volume`` to mount the local certificate into the container's ``/app/`` " +"directory. This allows the ServerApp to access the certificate within the " +"container. Use the ``--root-certificates`` flags when starting the container." msgstr "" +"인증서가 이미 로컬에 존재한다고 가정하면, ``--volume`` 플래그를 사용하여 로" +"컬 인증서를 컨테이너의 ``/app/`` 디렉터리에 마운트할 수 있습니다. 이렇게 하" +"면 ServerApp이 컨테이너 내의 인증서에 액세스할 수 있습니다. 컨테이너를 시작" +"할 때 ``--root-certificates`` 플래그를 사용하세요." #: ../../source/how-to-run-flower-using-docker.rst:412 msgid "Advanced Docker options" -msgstr "" +msgstr "고급 Docker 옵션" #: ../../source/how-to-run-flower-using-docker.rst:415 msgid "Run with root user privileges" -msgstr "" +msgstr "루트 사용자 권한으로 실행" #: ../../source/how-to-run-flower-using-docker.rst:417 msgid "" -"Flower Docker images, by default, run with a non-root user " -"(username/groupname: ``app``, UID/GID: ``49999``). Using root user is not" -" recommended unless it is necessary for specific tasks during the build " -"process. Always make sure to run the container as a non-root user in " -"production to maintain security best practices." +"Flower Docker images, by default, run with a non-root user (username/" +"groupname: ``app``, UID/GID: ``49999``). Using root user is not recommended " +"unless it is necessary for specific tasks during the build process. Always " +"make sure to run the container as a non-root user in production to maintain " +"security best practices." msgstr "" +"기본적으로 Flower Docker 이미지는 루트 사용자가 아닌 사용자(사용자명/그룹명:" +"``app``, UID/GID: ``49999``)로 실행됩니다. 빌드 프로세스 중 특정 작업에 필요" +"한 경우가 아니라면 루트 사용자를 사용하지 않는 것이 좋습니다. 보안 모범 사례" +"를 유지하려면 항상 프로덕션 환경에서 루트 사용자가 아닌 사용자로 컨테이너를 " +"실행해야 합니다." #: ../../source/how-to-run-flower-using-docker.rst:422 msgid "**Run a container with root user privileges**" -msgstr "" +msgstr "**루트 사용자 권한으로 컨테이너 실행하기**" #: ../../source/how-to-run-flower-using-docker.rst:424 msgid "" "Run the Docker image with the ``-u`` flag and specify ``root`` as the " "username:" msgstr "" +"``-u`` 플래그를 사용하여 Docker 이미지를 실행하고 사용자 이름으로 ``root``를 " +"지정합니다:" #: ../../source/how-to-run-flower-using-docker.rst:430 msgid "This command will run the Docker container with root user privileges." -msgstr "" +msgstr "이 명령은 루트 사용자 권한으로 Docker 컨테이너를 실행합니다." #: ../../source/how-to-run-flower-using-docker.rst:432 msgid "**Run the build process with root user privileges**" -msgstr "" +msgstr "**루트 사용자 권한으로 빌드 프로세스를 실행합니다**" #: ../../source/how-to-run-flower-using-docker.rst:434 msgid "" "If you want to switch to the root user during the build process of the " -"Docker image to install missing system dependencies, you can use the " -"``USER root`` directive within your Dockerfile." +"Docker image to install missing system dependencies, you can use the ``USER " +"root`` directive within your Dockerfile." msgstr "" +"Docker 이미지 빌드 과정에서 루트 사용자로 전환하여 누락된 시스템 의존성을 " +"설치하려면 Dockerfile 내에서 ``USER root`` 지시어를 사용할 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:454 msgid "Using a different Flower version" -msgstr "" +msgstr "다른 Flower 버전 사용" #: ../../source/how-to-run-flower-using-docker.rst:456 msgid "" "If you want to use a different version of Flower, for example Flower " -"nightly, you can do so by changing the tag. All available versions are on" -" `Docker Hub `__." +"nightly, you can do so by changing the tag. All available versions are on " +"`Docker Hub `__." msgstr "" +"다른 버전의 Flower를 사용하려면 태그를 변경하여 사용할 수 있습니다(예: " +"Flower nightly). 사용 가능한 모든 버전은 `Docker Hub `__에 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:460 msgid "Pinning a Docker image to a specific version" -msgstr "" +msgstr "특정 버전에 Docker 이미지 고정하기" #: ../../source/how-to-run-flower-using-docker.rst:462 msgid "" "It may happen that we update the images behind the tags. Such updates " "usually include security updates of system dependencies that should not " -"change the functionality of Flower. However, if you want to ensure that " -"you always use the same image, you can specify the hash of the image " -"instead of the tag." +"change the functionality of Flower. However, if you want to ensure that you " +"always use the same image, you can specify the hash of the image instead of " +"the tag." msgstr "" +"태그 뒤에 있는 이미지가 업데이트될 수 있습니다. 이러한 업데이트에는 " +"일반적으로 Flower의 기능을 변경해서는 안 되는 시스템 의존성에 대한 보안 " +"업데이트가 포함됩니다. 그러나 항상 동일한 이미지를 사용하려면 태그 대신 " +"이미지의 해시를 지정할 수 있습니다." #: ../../source/how-to-run-flower-using-docker.rst:467 msgid "" "The following command returns the current image hash referenced by the " "``superlink:1.8.0`` tag:" msgstr "" +"다음 명령은 ``superlink:1.8.0`` 태그가 참조하는 현재 이미지 해시를 반환합니" +"다:" #: ../../source/how-to-run-flower-using-docker.rst:474 msgid "Next, we can pin the hash when running a new SuperLink container:" -msgstr "" +msgstr "다음으로, 새 SuperLink 컨테이너를 실행할 때 해시를 고정할 수 있습니다:" #: ../../source/how-to-run-flower-using-docker.rst:483 msgid "Setting environment variables" -msgstr "" +msgstr "환경 변수 설정" #: ../../source/how-to-run-flower-using-docker.rst:485 msgid "" "To set a variable inside a Docker container, you can use the ``-e " "=`` flag." msgstr "" +"Docker 컨테이너 내에서 변수를 설정하려면 ``-e =`` 플래그를 사용" +"하면 됩니다." #: ../../source/how-to-run-simulations.rst:2 msgid "Run simulations" -msgstr "" +msgstr "시뮬레이션 실행" #: ../../source/how-to-run-simulations.rst:8 msgid "" "Simulating Federated Learning workloads is useful for a multitude of use-" -"cases: you might want to run your workload on a large cohort of clients " -"but without having to source, configure and mange a large number of " -"physical devices; you might want to run your FL workloads as fast as " -"possible on the compute systems you have access to without having to go " -"through a complex setup process; you might want to validate your " -"algorithm on different scenarios at varying levels of data and system " -"heterogeneity, client availability, privacy budgets, etc. These are among" -" some of the use-cases where simulating FL workloads makes sense. Flower " -"can accommodate these scenarios by means of its `VirtualClientEngine " -"`_ or " -"VCE." -msgstr "" +"cases: you might want to run your workload on a large cohort of clients but " +"without having to source, configure and mange a large number of physical " +"devices; you might want to run your FL workloads as fast as possible on the " +"compute systems you have access to without having to go through a complex " +"setup process; you might want to validate your algorithm on different " +"scenarios at varying levels of data and system heterogeneity, client " +"availability, privacy budgets, etc. These are among some of the use-cases " +"where simulating FL workloads makes sense. Flower can accommodate these " +"scenarios by means of its `VirtualClientEngine `_ or VCE." +msgstr "" +"Federated 학습 워크로드 시뮬레이션은 다양한 사용 사례에 유용합니다. 대규모 클" +"라이언트 집단에서 워크로드를 실행하되 많은 수의 물리적 장치를 소싱, 구성 및 " +"관리할 필요가 없는 경우, 복잡한 설정 과정을 거치지 않고도 액세스 가능한 컴퓨" +"팅 시스템에서 최대한 빠르게 FL 워크로드를 실행하려는 경우, 다양한 수준의 데이" +"터 및 시스템 이질성, 클라이언트 가용성, 개인정보 예산 등의 다양한 시나리오에" +"서 알고리즘을 검증하려는 경우 등 여러 가지 사용 사례에 유용합니다. 이러한 사" +"례는 FL 워크로드 시뮬레이션이 적합한 사용 사례 중 일부입니다. Flower는 " +"`VirtualClientEngine `_ 또는 VCE를 통해 이러한 시나리오를 수용할 수 있습니다." #: ../../source/how-to-run-simulations.rst:10 msgid "" -"The :code:`VirtualClientEngine` schedules, launches and manages `virtual`" -" clients. These clients are identical to `non-virtual` clients (i.e. the " -"ones you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by " -"creating a class inheriting, for example, from `flwr.client.NumPyClient " -"`_ and therefore behave in an " -"identical way. In addition to that, clients managed by the " -":code:`VirtualClientEngine` are:" -msgstr "" +"The :code:`VirtualClientEngine` schedules, launches and manages `virtual` " +"clients. These clients are identical to `non-virtual` clients (i.e. the ones " +"you launch via the command `flwr.client.start_client `_) in the sense that they can be configure by creating a " +"class inheriting, for example, from `flwr.client.NumPyClient `_ and therefore behave in an identical way. In " +"addition to that, clients managed by the :code:`VirtualClientEngine` are:" +msgstr "" +":code:`VirtualClientEngine`은 `virtual` 클라이언트를 예약, 실행 및 관리합니" +"다. 이러한 클라이언트는 `non-virtual` 클라이언트(예: `flwr.client." +"start_client `_ 명령을 통해 실행하는 클라이언" +"트)와 동일하며, `flwr.client.NumPyClient `_에서 상속하는 클래스 생성으로 구성될 수 있으므로 동일한 방식으" +"로 동작합니다. 그 외에도 :code:`VirtualClientEngine`에 의해 관리되는 클라이언" +"트는 다음과 같습니다:" #: ../../source/how-to-run-simulations.rst:12 msgid "" -"resource-aware: this means that each client gets assigned a portion of " -"the compute and memory on your system. You as a user can control this at " -"the beginning of the simulation and allows you to control the degree of " +"resource-aware: this means that each client gets assigned a portion of the " +"compute and memory on your system. You as a user can control this at the " +"beginning of the simulation and allows you to control the degree of " "parallelism of your Flower FL simulation. The fewer the resources per " "client, the more clients can run concurrently on the same hardware." msgstr "" +"resource-aware: 이는 각 클라이언트가 시스템에서 컴퓨팅 및 메모리의 일부를 할" +"당받는다는 것을 의미합니다. 사용자는 시뮬레이션을 시작할 때 이를 제어할 수 있" +"으며, 이를 통해 Flower FL 시뮬레이션의 병렬 처리 정도를 제어할 수 있습니다. " +"클라이언트당 리소스가 적을수록 동일한 하드웨어에서 더 많은 클라이언트를 동시" +"에 실행할 수 있습니다." #: ../../source/how-to-run-simulations.rst:13 msgid "" -"self-managed: this means that you as a user do not need to launch clients" -" manually, instead this gets delegated to :code:`VirtualClientEngine`'s " +"self-managed: this means that you as a user do not need to launch clients " +"manually, instead this gets delegated to :code:`VirtualClientEngine`'s " "internals." msgstr "" +"self-managed: 이는 사용자가 클라이언트를 수동으로 실행할 필요가 없으며, 대" +"신 :code:`VirtualClientEngine`의 내부에 위임된다는 의미입니다." #: ../../source/how-to-run-simulations.rst:14 msgid "" -"ephemeral: this means that a client is only materialized when it is " -"required in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards," -" releasing the resources it was assigned and allowing in this way other " -"clients to participate." +"ephemeral: this means that a client is only materialized when it is required " +"in the FL process (e.g. to do `fit() `_). The object is destroyed afterwards, releasing the resources it was " +"assigned and allowing in this way other clients to participate." msgstr "" +"ephemeral: 이는 클라이언트가 FL 프로세스에서 필요할 때만 구체화됨을 의미합니" +"다(예: `fit() `_을 수행하기 위해). " +"객체는 나중에 소멸되어 할당된 리소스를 해제하고 다른 클라이언트가 참여할 수 " +"있도록 허용합니다." #: ../../source/how-to-run-simulations.rst:16 msgid "" "The :code:`VirtualClientEngine` implements `virtual` clients using `Ray " "`_, an open-source framework for scalable Python " -"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use " -"of `Actors `_ to " -"spawn `virtual` clients and run their workload." +"workloads. In particular, Flower's :code:`VirtualClientEngine` makes use of " +"`Actors `_ to spawn " +"`virtual` clients and run their workload." msgstr "" +":code:`VirtualClientEngine`은 확장 가능한 파이썬 워크로드를 위한 오픈 소스 프" +"레임워크인 `Ray `_를 사용하여 `virtual` 클라이언트를 구" +"현합니다. 특히 Flower의 :code:`VirtualClientEngine`은 `Actors `_를 사용하여 `virtual` 클라이언트를 생" +"성하고 해당 워크로드를 실행합니다." #: ../../source/how-to-run-simulations.rst:20 msgid "Launch your Flower simulation" -msgstr "" +msgstr "Flower 시뮬레이션 시작" #: ../../source/how-to-run-simulations.rst:22 msgid "" -"Running Flower simulations still require you to define your client class," -" a strategy, and utility functions to download and load (and potentially " -"partition) your dataset. With that out of the way, launching your " -"simulation is done with `start_simulation `_ and a minimal example looks" -" as follows:" +"Running Flower simulations still require you to define your client class, a " +"strategy, and utility functions to download and load (and potentially " +"partition) your dataset. With that out of the way, launching your simulation " +"is done with `start_simulation `_ and a minimal example looks as follows:" msgstr "" +"Flower 시뮬레이션을 실행하려면 여전히 클라이언트 클래스, 전략 및 유틸리티 함" +"수를 정의하여 데이터 세트를 다운로드하고 로드(및 파티션)해야 합니다. 이 작업" +"을 마친 후 시뮬레이션을 시작하려면 `start_simulation `_을 사용하면 되며, 최소한의 예시는 다음과 같습니" +"다:" #: ../../source/how-to-run-simulations.rst:44 msgid "VirtualClientEngine resources" -msgstr "" +msgstr "VirtualClientEngine 리소스" #: ../../source/how-to-run-simulations.rst:45 msgid "" -"By default the VCE has access to all system resources (i.e. all CPUs, all" -" GPUs, etc) since that is also the default behavior when starting Ray. " -"However, in some settings you might want to limit how many of your system" -" resources are used for simulation. You can do this via the " -":code:`ray_init_args` input argument to :code:`start_simulation` which " -"the VCE internally passes to Ray's :code:`ray.init` command. For a " -"complete list of settings you can configure check the `ray.init " -"`_" -" documentation. Do not set :code:`ray_init_args` if you want the VCE to " -"use all your system's CPUs and GPUs." -msgstr "" +"By default the VCE has access to all system resources (i.e. all CPUs, all " +"GPUs, etc) since that is also the default behavior when starting Ray. " +"However, in some settings you might want to limit how many of your system " +"resources are used for simulation. You can do this via the :code:" +"`ray_init_args` input argument to :code:`start_simulation` which the VCE " +"internally passes to Ray's :code:`ray.init` command. For a complete list of " +"settings you can configure check the `ray.init `_ documentation. Do not set :" +"code:`ray_init_args` if you want the VCE to use all your system's CPUs and " +"GPUs." +msgstr "" +"기본적으로 VCE는 모든 시스템 리소스(예: 모든 CPU, 모든 GPU 등)에 액세스할 수 " +"있으며, 이는 Ray를 시작할 때의 기본 동작이기도 합니다. 그러나 일부 설정에서" +"는 시뮬레이션에 사용되는 시스템 리소스의 수를 제한하고 싶을 수 있습니다. 이 " +"설정은 VCE가 내부적으로 Ray의 :code:`ray.init` 명령에 전달하는 :code:" +"`start_simulation`에 대한 :code:`ray_init_args` 입력 인수를 통해 수행할 수 있" +"습니다. 구성할 수 있는 전체 설정 목록은 `ray.init `_ 설명서를 확인하세요. VCE가 " +"시스템의 모든 CPU와 GPU를 사용하도록 하려면 :code:`ray_init_args`를 설정하지 " +"마세요." #: ../../source/how-to-run-simulations.rst:62 msgid "Assigning client resources" -msgstr "" +msgstr "클라이언트 리소스 할당" #: ../../source/how-to-run-simulations.rst:63 msgid "" -"By default the :code:`VirtualClientEngine` assigns a single CPU core (and" -" nothing else) to each virtual client. This means that if your system has" -" 10 cores, that many virtual clients can be concurrently running." +"By default the :code:`VirtualClientEngine` assigns a single CPU core (and " +"nothing else) to each virtual client. This means that if your system has 10 " +"cores, that many virtual clients can be concurrently running." msgstr "" +"기본적으로 :code:`VirtualClientEngine`은 각 가상 클라이언트에 단일 CPU 코어" +"를 할당합니다(그 외에는 아무것도 할당하지 않음). 즉, 시스템에 코어가 10개인 " +"경우 그만큼 많은 가상 클라이언트를 동시에 실행할 수 있습니다." #: ../../source/how-to-run-simulations.rst:65 msgid "" -"More often than not, you would probably like to adjust the resources your" -" clients get assigned based on the complexity (i.e. compute and memory " -"footprint) of your FL workload. You can do so when starting your " -"simulation by setting the argument `client_resources` to " -"`start_simulation `_." -" Two keys are internally used by Ray to schedule and spawn workloads (in " -"our case Flower clients):" +"More often than not, you would probably like to adjust the resources your " +"clients get assigned based on the complexity (i.e. compute and memory " +"footprint) of your FL workload. You can do so when starting your simulation " +"by setting the argument `client_resources` to `start_simulation `_. Two keys are internally used " +"by Ray to schedule and spawn workloads (in our case Flower clients):" msgstr "" +"대부분의 경우 FL 워크로드의 복잡성(즉, 컴퓨팅 및 메모리 사용량)에 따라 클라이" +"언트에 할당되는 리소스를 조정하고 싶을 것입니다. 시뮬레이션을 시작할 때 " +"`client_resources` argument를 `start_simulation `_로 설정하여 이를 수행할 수 있습니다. Ray는 내부" +"적으로 두 개의 키를 사용하여 워크로드(이 경우 Flower 클라이언트)를 스케줄링하" +"고 스폰합니다:" #: ../../source/how-to-run-simulations.rst:67 msgid ":code:`num_cpus` indicates the number of CPU cores a client would get." msgstr "" +":code:`num_cpus`는 클라이언트에서 사용할 수 있는 CPU 코어 수를 나타냅니다." #: ../../source/how-to-run-simulations.rst:68 msgid "" ":code:`num_gpus` indicates the **ratio** of GPU memory a client gets " "assigned." msgstr "" +":code:`num_gpus`는 클라이언트에 할당되는 GPU 메모리의 **비율**을 나타냅니다." #: ../../source/how-to-run-simulations.rst:70 msgid "Let's see a few examples:" -msgstr "" +msgstr "몇 가지 예를 살펴보겠습니다:" #: ../../source/how-to-run-simulations.rst:89 msgid "" "While the :code:`client_resources` can be used to control the degree of " "concurrency in your FL simulation, this does not stop you from running " -"dozens, hundreds or even thousands of clients in the same round and " -"having orders of magnitude more `dormant` (i.e. not participating in a " -"round) clients. Let's say you want to have 100 clients per round but your" -" system can only accommodate 8 clients concurrently. The " -":code:`VirtualClientEngine` will schedule 100 jobs to run (each " -"simulating a client sampled by the strategy) and then will execute them " -"in a resource-aware manner in batches of 8." -msgstr "" +"dozens, hundreds or even thousands of clients in the same round and having " +"orders of magnitude more `dormant` (i.e. not participating in a round) " +"clients. Let's say you want to have 100 clients per round but your system " +"can only accommodate 8 clients concurrently. The :code:`VirtualClientEngine` " +"will schedule 100 jobs to run (each simulating a client sampled by the " +"strategy) and then will execute them in a resource-aware manner in batches " +"of 8." +msgstr "" +"code:`client_resources`를 사용하여 FL 시뮬레이션의 동시성 정도를 제어할 수 있" +"지만, 동일한 라운드에서 수십, 수백 또는 수천 개의 클라이언트를 실행하고 훨씬 " +"더 많은 '휴면'(즉, 라운드에 참여하지 않는) 클라이언트를 보유하는 것을 막을 수" +"는 없습니다. 라운드당 100명의 클라이언트를 받고 싶지만 시스템이 동시에 8명의 " +"클라이언트만 수용할 수 있다고 가정해 봅시다. code:`VirtualClientEngine`은 실" +"행할 100개의 작업(각각 전략에서 샘플링한 클라이언트를 시뮬레이션)을 예약한 다" +"음 리소스 인식 방식으로 8개씩 일괄적으로 실행합니다." #: ../../source/how-to-run-simulations.rst:91 msgid "" "To understand all the intricate details on how resources are used to " -"schedule FL clients and how to define custom resources, please take a " -"look at the `Ray documentation `_." +"schedule FL clients and how to define custom resources, please take a look " +"at the `Ray documentation `_." msgstr "" +"리소스가 FL 클라이언트를 예약하는 데 사용되는 방법과 사용자 지정 리소스를 정" +"의하는 방법에 대한 모든 복잡한 세부 사항을 이해하려면 'Ray 문서 '를 참조하세요." #: ../../source/how-to-run-simulations.rst:94 msgid "Simulation examples" -msgstr "" +msgstr "시뮬레이션 예제" #: ../../source/how-to-run-simulations.rst:96 msgid "" -"A few ready-to-run complete examples for Flower simulation in " -"Tensorflow/Keras and PyTorch are provided in the `Flower repository " -"`_. You can run them on Google Colab too:" +"A few ready-to-run complete examples for Flower simulation in Tensorflow/" +"Keras and PyTorch are provided in the `Flower repository `_. You can run them on Google Colab too:" msgstr "" +"Tensorflow/Keras와 파이토치에서 바로 실행할 수 있는 몇 가지 Flower 시뮬레이" +"션 예제는 `Flower 레포지토리 `_에서 제공됩니" +"다. Google Colab에서도 실행할 수 있습니다:" #: ../../source/how-to-run-simulations.rst:98 msgid "" -"`Tensorflow/Keras Simulation " -"`_: 100 clients collaboratively train a MLP model on MNIST." +"`Tensorflow/Keras Simulation `_: 100 clients collaboratively train a MLP " +"model on MNIST." msgstr "" +"`Tensorflow/Keras 시뮬레이션 `_: 100개의 클라이언트가 공동으로 MNIST에서 " +"MLP 모델을 훈련합니다." #: ../../source/how-to-run-simulations.rst:99 msgid "" -"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " +"`PyTorch Simulation `_: 100 clients collaboratively train a CNN model on " "MNIST." msgstr "" +"파이토치 시뮬레이션 `_: 100개의 클라이언트가 공동으로 MNIST에서 CNN 모델을 훈" +"련합니다." #: ../../source/how-to-run-simulations.rst:104 msgid "Multi-node Flower simulations" -msgstr "" +msgstr "멀티 노드 Flower 시뮬레이션" #: ../../source/how-to-run-simulations.rst:106 msgid "" -"Flower's :code:`VirtualClientEngine` allows you to run FL simulations " -"across multiple compute nodes. Before starting your multi-node simulation" -" ensure that you:" +"Flower's :code:`VirtualClientEngine` allows you to run FL simulations across " +"multiple compute nodes. Before starting your multi-node simulation ensure " +"that you:" msgstr "" +"Flower의 :code:`VirtualClientEngine`을 사용하면 여러 컴퓨팅 노드에서 FL 시뮬" +"레이션을 실행할 수 있습니다. 멀티 노드 시뮬레이션을 시작하기 전에 다음 사항" +"을 확인하세요:" #: ../../source/how-to-run-simulations.rst:108 msgid "Have the same Python environment in all nodes." -msgstr "" +msgstr "모든 노드에서 동일한 Python 환경을 유지합니다." #: ../../source/how-to-run-simulations.rst:109 msgid "Have a copy of your code (e.g. your entire repo) in all nodes." -msgstr "" +msgstr "모든 노드에 코드 사본(예: 전체 레포지토리)을 보관하세요." #: ../../source/how-to-run-simulations.rst:110 msgid "" -"Have a copy of your dataset in all nodes (more about this in " -":ref:`simulation considerations `)" +"Have a copy of your dataset in all nodes (more about this in :ref:" +"`simulation considerations `)" msgstr "" +"모든 노드에 데이터 세트의 사본을 보유하세요(자세한 내용은 :ref:`simulation " +"considerations `에서 확인하세요)" #: ../../source/how-to-run-simulations.rst:111 msgid "" -"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation " -"`_ so the " -":code:`VirtualClientEngine` attaches to a running Ray instance." +"Pass :code:`ray_init_args={\"address\"=\"auto\"}` to `start_simulation `_ so the :code:" +"`VirtualClientEngine` attaches to a running Ray instance." msgstr "" +":code:`ray_init_args={\"address\"=\"auto\"}`를 `start_simulation `_에 전달하여 :code:" +"`VirtualClientEngine`이 실행 중인 Ray 인스턴스에 연결되도록 합니다." #: ../../source/how-to-run-simulations.rst:112 msgid "" -"Start Ray on you head node: on the terminal type :code:`ray start " -"--head`. This command will print a few lines, one of which indicates how " -"to attach other nodes to the head node." +"Start Ray on you head node: on the terminal type :code:`ray start --head`. " +"This command will print a few lines, one of which indicates how to attach " +"other nodes to the head node." msgstr "" +"헤드 노드에서 Ray 시작: 터미널에서 :code:`ray start --head`를 입력합니다. 이 " +"명령은 몇 줄을 출력하며, 그 중 하나는 다른 노드를 헤드 노드에 연결하는 방법" +"을 나타냅니다." #: ../../source/how-to-run-simulations.rst:113 msgid "" -"Attach other nodes to the head node: copy the command shown after " -"starting the head and execute it on terminal of a new node: for example " -":code:`ray start --address='192.168.1.132:6379'`" +"Attach other nodes to the head node: copy the command shown after starting " +"the head and execute it on terminal of a new node: for example :code:`ray " +"start --address='192.168.1.132:6379'`" msgstr "" +"헤드 노드에 다른 노드 연결: 헤드를 시작한 후 표시된 명령어을 복사하여 새 노드" +"의 터미널에서 실행합니다: 예: :code:`ray start --" +"address='192.168.1.132:6379'`" #: ../../source/how-to-run-simulations.rst:115 msgid "" "With all the above done, you can run your code from the head node as you " "would if the simulation was running on a single node." msgstr "" +"위의 모든 작업이 완료되면 단일 노드에서 시뮬레이션을 실행할 때와 마찬가지로 " +"헤드 노드에서 코드를 실행할 수 있습니다." #: ../../source/how-to-run-simulations.rst:117 msgid "" -"Once your simulation is finished, if you'd like to dismantle your cluster" -" you simply need to run the command :code:`ray stop` in each node's " -"terminal (including the head node)." +"Once your simulation is finished, if you'd like to dismantle your cluster " +"you simply need to run the command :code:`ray stop` in each node's terminal " +"(including the head node)." msgstr "" +"시뮬레이션이 완료되면 클러스터를 해체하려면 각 노드(헤드 노드 포함)의 터미널" +"에서 :code:`ray stop` 명령을 실행하기만 하면 됩니다." #: ../../source/how-to-run-simulations.rst:120 msgid "Multi-node simulation good-to-know" -msgstr "" +msgstr "멀티 노드 시뮬레이션에 대해 알아두면 좋은 사항" #: ../../source/how-to-run-simulations.rst:122 msgid "" "Here we list a few interesting functionality when running multi-node FL " "simulations:" msgstr "" +"여기에서는 멀티 노드 FL 시뮬레이션을 실행할 때 흥미로운 몇 가지 기능을 나열합" +"니다:" #: ../../source/how-to-run-simulations.rst:124 msgid "" -"User :code:`ray status` to check all nodes connected to your head node as" -" well as the total resources available to the " -":code:`VirtualClientEngine`." +"User :code:`ray status` to check all nodes connected to your head node as " +"well as the total resources available to the :code:`VirtualClientEngine`." msgstr "" +"사용자는 :code:`ray status`를 통해 헤드 노드에 연결된 모든 노드와 :code:" +"`VirtualClientEngine`에 사용 가능한 총 리소스를 확인할 수 있습니다." #: ../../source/how-to-run-simulations.rst:126 msgid "" -"When attaching a new node to the head, all its resources (i.e. all CPUs, " -"all GPUs) will be visible by the head node. This means that the " -":code:`VirtualClientEngine` can schedule as many `virtual` clients as " -"that node can possible run. In some settings you might want to exclude " -"certain resources from the simulation. You can do this by appending " -"`--num-cpus=` and/or `--num-" -"gpus=` in any :code:`ray start` command (including " -"when starting the head)" -msgstr "" +"When attaching a new node to the head, all its resources (i.e. all CPUs, all " +"GPUs) will be visible by the head node. This means that the :code:" +"`VirtualClientEngine` can schedule as many `virtual` clients as that node " +"can possible run. In some settings you might want to exclude certain " +"resources from the simulation. You can do this by appending `--num-" +"cpus=` and/or `--num-gpus=` in any :" +"code:`ray start` command (including when starting the head)" +msgstr "" +"새 노드를 헤드에 연결하면 해당 노드의 모든 리소스(즉, 모든 CPU, 모든 GPU)가 " +"헤드 노드에 표시됩니다. 즉, :code:`VirtualClientEngine`은 해당 노드가 실행할 " +"수 있는 만큼의 `가상` 클라이언트를 예약할 수 있습니다. 일부 설정에서는 시뮬레" +"이션에서 특정 리소스를 제외하고 싶을 수 있습니다. 모든 :code:`ray start` 명령" +"(헤드 시작 시 포함)에 `--num-cpus=` 및/또는 `--num-" +"gpus=`를 추가하여 이 작업을 수행하면 됩니다" #: ../../source/how-to-run-simulations.rst:132 msgid "Considerations for simulations" -msgstr "" +msgstr "시뮬레이션 시 고려 사항" #: ../../source/how-to-run-simulations.rst:135 msgid "" -"We are actively working on these fronts so to make it trivial to run any " -"FL workload with Flower simulation." +"We are actively working on these fronts so to make it trivial to run any FL " +"workload with Flower simulation." msgstr "" +"Flower 시뮬레이션으로 모든 FL 워크로드를 간편하게 실행할 수 있도록 이러한 측" +"면에서 적극적으로 노력하고 있습니다." #: ../../source/how-to-run-simulations.rst:138 msgid "" -"The current VCE allows you to run Federated Learning workloads in " -"simulation mode whether you are prototyping simple scenarios on your " -"personal laptop or you want to train a complex FL pipeline across " -"multiple high-performance GPU nodes. While we add more capabilities to " -"the VCE, the points below highlight some of the considerations to keep in" -" mind when designing your FL pipeline with Flower. We also highlight a " -"couple of current limitations in our implementation." +"The current VCE allows you to run Federated Learning workloads in simulation " +"mode whether you are prototyping simple scenarios on your personal laptop or " +"you want to train a complex FL pipeline across multiple high-performance GPU " +"nodes. While we add more capabilities to the VCE, the points below highlight " +"some of the considerations to keep in mind when designing your FL pipeline " +"with Flower. We also highlight a couple of current limitations in our " +"implementation." msgstr "" +"현재 VCE를 사용하면 개인 노트북에서 간단한 시나리오를 프로토타이핑하든, 여러 " +"고성능 GPU 노드에서 복잡한 FL 파이프라인을 훈련하든 상관없이 시뮬레이션 모드" +"에서 Federated 학습 워크로드를 실행할 수 있습니다. VCE에 더 많은 기능을 추가" +"하는 동안, 아래에서는 Flower로 FL 파이프라인을 설계할 때 염두에 두어야 할 몇 " +"가지 사항을 강조합니다. 또한 현재 구현에서 몇 가지 제한 사항을 강조합니다." #: ../../source/how-to-run-simulations.rst:141 msgid "GPU resources" -msgstr "" +msgstr "GPU 리소스" #: ../../source/how-to-run-simulations.rst:143 msgid "" -"The VCE assigns a share of GPU memory to a client that specifies the key " -":code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " +"The VCE assigns a share of GPU memory to a client that specifies the key :" +"code:`num_gpus` in :code:`client_resources`. This being said, Ray (used " "internally by the VCE) is by default:" msgstr "" +"VCE는 :code:`client_resources`에서 :code:`num_gpus` 키를 지정하는 클라이언트" +"에 GPU 메모리 공유를 할당합니다. 즉, (VCE에서 내부적으로 사용하는) Ray가 기본" +"적으로 사용됩니다:" #: ../../source/how-to-run-simulations.rst:146 msgid "" -"not aware of the total VRAM available on the GPUs. This means that if you" -" set :code:`num_gpus=0.5` and you have two GPUs in your system with " -"different (e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients" -" concurrently." +"not aware of the total VRAM available on the GPUs. This means that if you " +"set :code:`num_gpus=0.5` and you have two GPUs in your system with different " +"(e.g. 32GB and 8GB) VRAM amounts, they both would run 2 clients concurrently." msgstr "" +"GPU에서 사용 가능한 총 VRAM을 인식하지 못합니다. 즉, 시스템에 서로 다른(예: " +"32GB와 8GB) VRAM 용량을 가진 두 개의 GPU가 있고 :code:`num_gpus=0.5`를 설정하" +"면 둘 다 동시에 2개의 클라이언트를 실행하게 됩니다." #: ../../source/how-to-run-simulations.rst:147 msgid "" "not aware of other unrelated (i.e. not created by the VCE) workloads are " "running on the GPU. Two takeaways from this are:" msgstr "" +"관련 없는(즉, VCE에 의해 생성되지 않은) 다른 워크로드가 GPU에서 실행되고 있는" +"지 알지 못합니다. 여기서 두 가지 시사점을 얻을 수 있습니다:" #: ../../source/how-to-run-simulations.rst:149 msgid "" @@ -6590,178 +6794,237 @@ msgid "" "aggregation (by instance when making use of the `evaluate method `_)" msgstr "" +"집계 후 '글로벌 모델'을 평가하려면 Flower 서버에 GPU가 필요할 수 있습니다" +"(예: `evaluate method `_를 사용할 때)" #: ../../source/how-to-run-simulations.rst:150 msgid "" "If you want to run several independent Flower simulations on the same " -"machine you need to mask-out your GPUs with " -":code:`CUDA_VISIBLE_DEVICES=\"\"` when launching your " -"experiment." +"machine you need to mask-out your GPUs with :code:" +"`CUDA_VISIBLE_DEVICES=\"\"` when launching your experiment." msgstr "" +"동일한 머신에서 여러 개의 독립적인 Flower 시뮬레이션을 실행하려면, 실험을 시" +"작할 때 :code:`CUDA_VISIBLE_DEVICES=\"\"`로 GPU를 마스킹해야 합니다." #: ../../source/how-to-run-simulations.rst:153 msgid "" -"In addition, the GPU resource limits passed to :code:`client_resources` " -"are not `enforced` (i.e. they can be exceeded) which can result in the " -"situation of client using more VRAM than the ratio specified when " -"starting the simulation." +"In addition, the GPU resource limits passed to :code:`client_resources` are " +"not `enforced` (i.e. they can be exceeded) which can result in the situation " +"of client using more VRAM than the ratio specified when starting the " +"simulation." msgstr "" +"또한 :code:`client_resources`에 전달된 GPU 리소스 제한이 '강제'되지 않아(즉, " +"초과할 수 있음) 클라이언트가 시뮬레이션을 시작할 때 지정된 비율보다 더 많은 " +"VRAM을 사용하는 상황이 발생할 수 있습니다." #: ../../source/how-to-run-simulations.rst:156 msgid "TensorFlow with GPUs" -msgstr "" +msgstr "GPU를 사용한 TensorFlow" #: ../../source/how-to-run-simulations.rst:158 msgid "" -"When `using a GPU with TensorFlow " -"`_ nearly your entire GPU memory of" -" all your GPUs visible to the process will be mapped. This is done by " -"TensorFlow for optimization purposes. However, in settings such as FL " -"simulations where we want to split the GPU into multiple `virtual` " -"clients, this is not a desirable mechanism. Luckily we can disable this " -"default behavior by `enabling memory growth " -"`_." -msgstr "" +"When `using a GPU with TensorFlow `_ " +"nearly your entire GPU memory of all your GPUs visible to the process will " +"be mapped. This is done by TensorFlow for optimization purposes. However, in " +"settings such as FL simulations where we want to split the GPU into multiple " +"`virtual` clients, this is not a desirable mechanism. Luckily we can disable " +"this default behavior by `enabling memory growth `_." +msgstr "" +"`TensorFlow와 함께 GPU를 사용 `_하면 프" +"로세스에 보이는 모든 GPU의 거의 전체 GPU 메모리가 매핑됩니다. 이는 최적화 목" +"적으로 TensorFlow에서 수행됩니다. 그러나 GPU를 여러 개의 '가상' 클라이언트로 " +"분할하려는 FL 시뮬레이션과 같은 설정에서는 이는 바람직한 메커니즘이 아닙니" +"다. 다행히도 '메모리 증가 활성화 `_'를 통해 이 기본 동작을 비활성화할 수 있습니" +"다." #: ../../source/how-to-run-simulations.rst:160 msgid "" -"This would need to be done in the main process (which is where the server" -" would run) and in each Actor created by the VCE. By means of " -":code:`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` " -"in order to specify a function to be executed upon actor initialization. " -"In this case, to enable GPU growth for TF workloads. It would look as " -"follows:" +"This would need to be done in the main process (which is where the server " +"would run) and in each Actor created by the VCE. By means of :code:" +"`actor_kwargs` we can pass the reserved key `\"on_actor_init_fn\"` in order " +"to specify a function to be executed upon actor initialization. In this " +"case, to enable GPU growth for TF workloads. It would look as follows:" msgstr "" +"이 작업은 메인 프로세스(서버가 실행되는 곳)와 VCE에서 생성한 각 액터에서 수행" +"해야 합니다. :code:`actor_kwargs`를 통해 예약 키 `\"on_actor_init_fn\"`을 전" +"달하여 액터 초기화 시 실행할 함수를 지정할 수 있습니다. 이 경우 TF 워크로드" +"에 대한 GPU 증가를 활성화합니다. 다음과 같이 보입니다:" #: ../../source/how-to-run-simulations.rst:179 msgid "" "This is precisely the mechanism used in `Tensorflow/Keras Simulation " -"`_ example." +"`_ " +"example." msgstr "" +"이것이 바로`Tensorflow/Keras Simulation `_ 예제에서 사용된 메커니즘입니다." #: ../../source/how-to-run-simulations.rst:183 msgid "Multi-node setups" -msgstr "" +msgstr "멀티 노드 설정" #: ../../source/how-to-run-simulations.rst:185 msgid "" -"The VCE does not currently offer a way to control on which node a " -"particular `virtual` client is executed. In other words, if more than a " -"single node have the resources needed by a client to run, then any of " -"those nodes could get the client workload scheduled onto. Later in the FL" -" process (i.e. in a different round) the same client could be executed by" -" a different node. Depending on how your clients access their datasets, " -"this might require either having a copy of all dataset partitions on all " -"nodes or a dataset serving mechanism (e.g. using nfs, a database) to " -"circumvent data duplication." -msgstr "" +"The VCE does not currently offer a way to control on which node a particular " +"`virtual` client is executed. In other words, if more than a single node " +"have the resources needed by a client to run, then any of those nodes could " +"get the client workload scheduled onto. Later in the FL process (i.e. in a " +"different round) the same client could be executed by a different node. " +"Depending on how your clients access their datasets, this might require " +"either having a copy of all dataset partitions on all nodes or a dataset " +"serving mechanism (e.g. using nfs, a database) to circumvent data " +"duplication." +msgstr "" +"VCE는 현재 특정 '가상' 클라이언트를 어느 노드에서 실행할지 제어하는 방법을 제" +"공하지 않습니다. 즉, 클라이언트가 실행하는 데 필요한 리소스가 하나 이상의 노" +"드에 있는 경우 해당 노드 중 어느 노드에나 클라이언트 워크로드가 예약될 수 있" +"습니다. FL 프로세스 후반부(즉, 다른 라운드에서)에는 동일한 클라이언트가 다른 " +"노드에서 실행될 수 있습니다. 클라이언트가 데이터 세트에 액세스하는 방식에 따" +"라 모든 노드에 모든 데이터 세트 파티션의 복사본을 보유하거나 데이터 중복을 피" +"하기 위해 데이터 세트 제공 메커니즘(예: nfs, 데이터베이스 사용)을 사용해야 " +"할 수 있습니다." #: ../../source/how-to-run-simulations.rst:187 msgid "" -"By definition virtual clients are `stateless` due to their ephemeral " -"nature. A client state can be implemented as part of the Flower client " -"class but users need to ensure this saved to persistent storage (e.g. a " -"database, disk) and that can be retrieve later by the same client " -"regardless on which node it is running from. This is related to the point" -" above also since, in some way, the client's dataset could be seen as a " -"type of `state`." +"By definition virtual clients are `stateless` due to their ephemeral nature. " +"A client state can be implemented as part of the Flower client class but " +"users need to ensure this saved to persistent storage (e.g. a database, " +"disk) and that can be retrieve later by the same client regardless on which " +"node it is running from. This is related to the point above also since, in " +"some way, the client's dataset could be seen as a type of `state`." msgstr "" +"정의상 가상 클라이언트는 임시적 특성으로 인해 '상태 없음'입니다. 클라이언트 " +"상태는 Flower 클라이언트 클래스의 일부로 구현할 수 있지만, 사용자는 이를 영" +"구 저장소(예: 데이터베이스, 디스크)에 저장하여 나중에 실행 중인 노드와 관계없" +"이 동일한 클라이언트가 검색할 수 있도록 해야 합니다. 이는 어떤 식으로든 클라" +"이언트의 데이터 세트가 일종의 '상태'로 볼 수 있기 때문에 위의 요점과도 관련" +"이 있습니다." #: ../../source/how-to-save-and-load-model-checkpoints.rst:2 msgid "Save and load model checkpoints" -msgstr "" +msgstr "모델 체크포인트 저장 및 로드" #: ../../source/how-to-save-and-load-model-checkpoints.rst:4 msgid "" -"Flower does not automatically save model updates on the server-side. This" -" how-to guide describes the steps to save (and load) model checkpoints in" -" Flower." +"Flower does not automatically save model updates on the server-side. This " +"how-to guide describes the steps to save (and load) model checkpoints in " +"Flower." msgstr "" +"Flower는 서버 측에서 모델 업데이트를 자동으로 저장하지 않습니다. 이 사용법 가" +"이드에서는 Flower에서 모델 체크포인트를 저장(및 로드)하는 단계에 대해 설명합" +"니다." #: ../../source/how-to-save-and-load-model-checkpoints.rst:8 msgid "Model checkpointing" -msgstr "" +msgstr "모델 체크포인트" #: ../../source/how-to-save-and-load-model-checkpoints.rst:10 msgid "" -"Model updates can be persisted on the server-side by customizing " -":code:`Strategy` methods. Implementing custom strategies is always an " -"option, but for many cases it may be more convenient to simply customize " -"an existing strategy. The following code example defines a new " -":code:`SaveModelStrategy` which customized the existing built-in " -":code:`FedAvg` strategy. In particular, it customizes " -":code:`aggregate_fit` by calling :code:`aggregate_fit` in the base class " -"(:code:`FedAvg`). It then continues to save returned (aggregated) weights" -" before it returns those aggregated weights to the caller (i.e., the " -"server):" -msgstr "" +"Model updates can be persisted on the server-side by customizing :code:" +"`Strategy` methods. Implementing custom strategies is always an option, but " +"for many cases it may be more convenient to simply customize an existing " +"strategy. The following code example defines a new :code:`SaveModelStrategy` " +"which customized the existing built-in :code:`FedAvg` strategy. In " +"particular, it customizes :code:`aggregate_fit` by calling :code:" +"`aggregate_fit` in the base class (:code:`FedAvg`). It then continues to " +"save returned (aggregated) weights before it returns those aggregated " +"weights to the caller (i.e., the server):" +msgstr "" +":code:`Strategy` 메소드를 사용자 지정하여 서버 측에서 모델 업데이트를 지속할 " +"수 있습니다. 사용자 지정 전략을 구현하는 것은 항상 옵션이지만 대부분의 경우 " +"기존 전략을 간단히 사용자 지정하는 것이 더 편리할 수 있습니다. 다음 코드 예시" +"는 기존의 기본 제공 :code:`FedAvg` 전략을 사용자 지정한 새로운 :code:" +"`SaveModelStrategy`를 정의합니다. 특히, 기본 클래스(:code:`FedAvg`)에서 :" +"code:`aggregate_fit`을 호출하여 :code:`aggregate_fit`을 사용자 지정합니다. 그" +"런 다음 호출자(즉, 서버)에게 집계된 가중치를 반환하기 전에 반환된(집계된) 가" +"중치를 계속 저장합니다:" #: ../../source/how-to-save-and-load-model-checkpoints.rst:47 msgid "Save and load PyTorch checkpoints" -msgstr "" +msgstr "파이토치 체크포인트 저장 및 로드" #: ../../source/how-to-save-and-load-model-checkpoints.rst:49 msgid "" -"Similar to the previous example but with a few extra steps, we'll show " -"how to store a PyTorch checkpoint we'll use the ``torch.save`` function. " -"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be" -" transformed into a list of NumPy ``ndarray``'s, then those are " -"transformed into the PyTorch ``state_dict`` following the ``OrderedDict``" -" class structure." +"Similar to the previous example but with a few extra steps, we'll show how " +"to store a PyTorch checkpoint we'll use the ``torch.save`` function. " +"Firstly, ``aggregate_fit`` returns a ``Parameters`` object that has to be " +"transformed into a list of NumPy ``ndarray``'s, then those are transformed " +"into the PyTorch ``state_dict`` following the ``OrderedDict`` class " +"structure." msgstr "" +"이전 예제와 비슷하지만 몇 가지 단계가 추가되어 ``torch.save`` 함수를 사용하" +"여 파이토치 체크포인트를 저장하는 방법을 보여드리겠습니다. 먼저, " +"``aggregate_fit``은 ``Parameters`` 객체를 반환하는데, 이 객체는 NumPy " +"``ndarray``의 목록으로 변환되어야 하며, ``OrderedDict`` 클래스 구조에 따라 파" +"이토치 ``state_dict``로 변환됩니다." #: ../../source/how-to-save-and-load-model-checkpoints.rst:85 msgid "" -"To load your progress, you simply append the following lines to your " -"code. Note that this will iterate over all saved checkpoints and load the" -" latest one:" +"To load your progress, you simply append the following lines to your code. " +"Note that this will iterate over all saved checkpoints and load the latest " +"one:" msgstr "" +"진행 상황을 로드하려면 코드에 다음 줄을 추가하기만 하면 됩니다. 이렇게 하면 " +"저장된 모든 체크포인트를 반복하고 최신 체크포인트를 로드합니다:" #: ../../source/how-to-save-and-load-model-checkpoints.rst:97 msgid "" -"Return/use this object of type ``Parameters`` wherever necessary, such as" -" in the ``initial_parameters`` when defining a ``Strategy``." +"Return/use this object of type ``Parameters`` wherever necessary, such as in " +"the ``initial_parameters`` when defining a ``Strategy``." msgstr "" +"``전략``을 정의할 때 ``초기_파라미터``와 같이 필요한 경우 ``파라미터`` 유형" +"의 이 객체를 반환/사용합니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:2 msgid "Upgrade to Flower 1.0" -msgstr "" +msgstr "Flower 1.0으로 업그레이드" #: ../../source/how-to-upgrade-to-flower-1.0.rst:4 msgid "" -"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable" -" foundation for future growth. Compared to Flower 0.19 (and other 0.x " -"series releases), there are a few breaking changes that make it necessary" -" to change the code of existing 0.x-series projects." +"Flower 1.0 is here. Along with new features, Flower 1.0 provides a stable " +"foundation for future growth. Compared to Flower 0.19 (and other 0.x series " +"releases), there are a few breaking changes that make it necessary to change " +"the code of existing 0.x-series projects." msgstr "" +"Flower 1.0이 출시되었습니다. 새로운 기능과 함께 Flower 1.0은 향후 성장을 위" +"한 안정적인 기반을 제공합니다. Flower 0.19(및 다른 0.x 시리즈 릴리스)와 비교" +"했을 때 기존 0.x 시리즈 프로젝트의 코드를 변경해야 하는 몇 가지 획기적인 변" +"경 사항이 있습니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:8 #: ../../source/how-to-upgrade-to-flower-next.rst:43 msgid "Install update" -msgstr "" +msgstr "업데이트 설치" #: ../../source/how-to-upgrade-to-flower-1.0.rst:10 msgid "" -"Here's how to update an existing installation to Flower 1.0 using either " -"pip or Poetry:" +"Here's how to update an existing installation to Flower 1.0 using either pip " +"or Poetry:" msgstr "" +"다음은 pip 또는 Poetry를 사용하여 기존 설치를 Flower 1.0으로 업데이트하는 방" +"법입니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:12 msgid "pip: add ``-U`` when installing." -msgstr "" +msgstr "pip: 설치할 때 ``-U``를 추가합니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:14 msgid "" "``python -m pip install -U flwr`` (when using ``start_server`` and " "``start_client``)" msgstr "" +"``python -m pip install -U flwr``(``start_server`` 및 ``start_client``를 사용" +"하는 경우)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:15 msgid "" "``python -m pip install -U flwr[simulation]`` (when using " "``start_simulation``)" msgstr "" +"``python -m pip install -U flwr[simulation]``(``start_simulation`` 사용 시)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:17 msgid "" @@ -6769,140 +7032,170 @@ msgid "" "reinstall (don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` " "before running ``poetry install``)." msgstr "" +"Poetry: ``pyproject.toml``에서 ``flwr`` dependency을 업데이트한 다음 다시 설" +"치하세요(``poetry 설치``를 실행하기 전에 ``rm poetry.lock``을 통해 ``poetry." +"lock``을 삭제하는 것을 잊지 마세요)." #: ../../source/how-to-upgrade-to-flower-1.0.rst:19 -msgid "``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" -msgstr "" +msgid "" +"``flwr = \"^1.0.0\"`` (when using ``start_server`` and ``start_client``)" +msgstr "``flwr = \"^1.0.0\"``(``start_server`` 및 ``start_client`` 사용 시)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:20 msgid "" -"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when " -"using ``start_simulation``)" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` (when using " +"``start_simulation``)" msgstr "" +"``flwr = { version = \"^1.0.0\", extras = [\"simulation\"] }`` " +"(``start_simulation`` 사용 시)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:24 #: ../../source/how-to-upgrade-to-flower-next.rst:100 msgid "Required changes" -msgstr "" +msgstr "필수 변경 사항" #: ../../source/how-to-upgrade-to-flower-1.0.rst:26 msgid "The following breaking changes require manual updates." -msgstr "" +msgstr "다음과 같은 주요 변경 사항에는 수동 업데이트가 필요합니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:29 msgid "General" -msgstr "" +msgstr "일반" #: ../../source/how-to-upgrade-to-flower-1.0.rst:31 msgid "" "Pass all arguments as keyword arguments (not as positional arguments). " "Here's an example:" -msgstr "" +msgstr "모든 전달인자를 위치 전달인자가 아닌 키워드 전달인자로 전달합니다. 다음은 " +"예시입니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:33 msgid "" "Flower 0.19 (positional arguments): ``start_client(\"127.0.0.1:8080\", " "FlowerClient())``" msgstr "" +"Flower 0.19 (위치 전달인자): ``start_client(\"127.0.0.1:8080\", " +"FlowerClient())``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:34 msgid "" "Flower 1.0 (keyword arguments): " -"``start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())``" +"``start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())``" msgstr "" +"Flower 1.0 (키워드 전달인자): ``start_client(server_address=\"127.0.0.1:" +"8080\", client=FlowerClient())``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:37 #: ../../source/ref-api/flwr.client.Client.rst:2 msgid "Client" -msgstr "" +msgstr "클라이언트" #: ../../source/how-to-upgrade-to-flower-1.0.rst:39 msgid "" "Subclasses of ``NumPyClient``: change ``def get_parameters(self):``` to " "``def get_parameters(self, config):``" msgstr "" +"``NumPyClient``의 서브클래스: ``def get_parameters(self):``를 ``def " +"get_parameters(self, config):``로 변경합니다" #: ../../source/how-to-upgrade-to-flower-1.0.rst:40 msgid "" "Subclasses of ``Client``: change ``def get_parameters(self):``` to ``def " "get_parameters(self, ins: GetParametersIns):``" msgstr "" +"``클라이언트``의 서브클래스: ``def get_parameters(self):``를 ``def " +"get_parameters(self, ins: GetParametersIns):``로 변경합니다" #: ../../source/how-to-upgrade-to-flower-1.0.rst:43 msgid "Strategies / ``start_server`` / ``start_simulation``" -msgstr "" +msgstr "전략 / ``start_server`` / ``start_simulation``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:45 msgid "" "Pass ``ServerConfig`` (instead of a dictionary) to ``start_server`` and " "``start_simulation``. Here's an example:" msgstr "" +"Dictionary 대신 ``ServerConfig``를 ``start_server`` 및 ``start_simulation``" +"에 전달합니다. 다음은 예제입니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:47 msgid "" "Flower 0.19: ``start_server(..., config={\"num_rounds\": 3, " "\"round_timeout\": 600.0}, ...)``" msgstr "" +"Flower 0.19: ``start_server(..., config={\"num_rounds\": 3, " +"\"round_timeout\": 600.0}, ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:48 msgid "" -"Flower 1.0: ``start_server(..., " -"config=flwr.server.ServerConfig(num_rounds=3, round_timeout=600.0), " -"...)``" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" msgstr "" +"Flower 1.0: ``start_server(..., config=flwr.server." +"ServerConfig(num_rounds=3, round_timeout=600.0), ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:50 msgid "" "Replace ``num_rounds=1`` in ``start_simulation`` with the new " "``config=ServerConfig(...)`` (see previous item)" msgstr "" +"``start_simulation``의 ``num_rounds=1``을 새로운 ``config=ServerConfig(...)``" +"로 바꿉니다(이전 항목 참조)" #: ../../source/how-to-upgrade-to-flower-1.0.rst:51 msgid "" "Remove ``force_final_distributed_eval`` parameter from calls to " -"``start_server``. Distributed evaluation on all clients can be enabled by" -" configuring the strategy to sample all clients for evaluation after the " -"last round of training." +"``start_server``. Distributed evaluation on all clients can be enabled by " +"configuring the strategy to sample all clients for evaluation after the last " +"round of training." msgstr "" +"'start_server`` 호출에서 ``force_final_distributed_eval`` 매개변수를 제거합니" +"다. 모든 클라이언트에 대한 분산 평가는 마지막 훈련 라운드 후 평가를 위해 모" +"든 클라이언트를 샘플링하도록 전략을 구성하여 활성화할 수 있습니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:52 msgid "Rename parameter/ndarray conversion functions:" -msgstr "" +msgstr "매개변수/ndarray 변환 함수의 이름을 바꿉니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:54 msgid "``parameters_to_weights`` --> ``parameters_to_ndarrays``" -msgstr "" +msgstr "``parameters_to_weights`` --> ``parameters_to_ndarrays``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:55 msgid "``weights_to_parameters`` --> ``ndarrays_to_parameters``" -msgstr "" +msgstr "``weights_to_parameters`` --> ``ndarrays_to_parameters``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:57 msgid "" -"Strategy initialization: if the strategy relies on the default values for" -" ``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " +"Strategy initialization: if the strategy relies on the default values for " +"``fraction_fit`` and ``fraction_evaluate``, set ``fraction_fit`` and " "``fraction_evaluate`` manually to ``0.1``. Projects that do not manually " "create a strategy (by calling ``start_server`` or ``start_simulation`` " -"without passing a strategy instance) should now manually initialize " -"FedAvg with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." +"without passing a strategy instance) should now manually initialize FedAvg " +"with ``fraction_fit`` and ``fraction_evaluate`` set to ``0.1``." msgstr "" +"전략 초기화: 전략이 ``fraction_fit`` 및 ``fraction_evaluate``의 기본값에 의존" +"하는 경우 ``fraction_fit`` 및 ``fraction_evaluate``를 ``0.1``로 수동 설정합니" +"다. 전략을 수동으로 생성하지 않는 프로젝트(전략 인스턴스를 전달하지 않고 " +"``start_server`` 또는 ``start_simulation``을 호출하여)는 이제 " +"``fraction_fit`` 및 ``fraction_evaluate``를 ``0.1``로 설정하여 FedAvg를 수동" +"으로 초기화해야 합니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:58 msgid "Rename built-in strategy parameters (e.g., ``FedAvg``):" -msgstr "" +msgstr "기본 제공 전략 매개변수의 이름을 바꿉니다(예: ``FedAvg``):" #: ../../source/how-to-upgrade-to-flower-1.0.rst:60 msgid "``fraction_eval`` --> ``fraction_evaluate``" -msgstr "" +msgstr "``fraction_eval`` --> ``fraction_evaluate``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:61 msgid "``min_eval_clients`` --> ``min_evaluate_clients``" -msgstr "" +msgstr "``min_eval_clients`` --> ``min_evaluate_clients``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:62 msgid "``eval_fn`` --> ``evaluate_fn``" -msgstr "" +msgstr "``eval_fn`` --> ``evaluate_fn``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:64 msgid "" @@ -6910,72 +7203,90 @@ msgid "" "functions, for example, ``configure_fit``, ``aggregate_fit``, " "``configure_evaluate``, ``aggregate_evaluate``, and ``evaluate_fn``." msgstr "" +"``rnd``의 이름을 ``server_round``로 바꿉니다. 이는 여러 메서드 및 함수(예: " +"``configure_fit``, ``aggregate_fit``, ``configure_evaluate``, " +"``aggregate_evaluate`` 및 ``evaluate_fn``)에 영향을 미칩니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:65 msgid "Add ``server_round`` and ``config`` to ``evaluate_fn``:" -msgstr "" +msgstr "``server_round`` 및 ``config``를 ``evaluate_fn``에 추가합니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:67 msgid "" -"Flower 0.19: ``def evaluate(parameters: NDArrays) -> " -"Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " +"Dict[str, Scalar]]]:``" msgstr "" +"Flower 0.19: ``def evaluate(parameters: NDArrays) -> Optional[Tuple[float, " +"Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:68 msgid "" -"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, " -"config: Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, " -"Scalar]]]:``" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " +"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" +"Flower 1.0: ``def evaluate(server_round: int, parameters: NDArrays, config: " +"Dict[str, Scalar]) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:71 msgid "Custom strategies" -msgstr "" +msgstr "사용자 정의 전략" #: ../../source/how-to-upgrade-to-flower-1.0.rst:73 msgid "" -"The type of parameter ``failures`` has changed from " -"``List[BaseException]`` to ``List[Union[Tuple[ClientProxy, FitRes], " -"BaseException]]`` (in ``aggregate_fit``) and " -"``List[Union[Tuple[ClientProxy, EvaluateRes], BaseException]]`` (in " -"``aggregate_evaluate``)" +"The type of parameter ``failures`` has changed from ``List[BaseException]`` " +"to ``List[Union[Tuple[ClientProxy, FitRes], BaseException]]`` (in " +"``aggregate_fit``) and ``List[Union[Tuple[ClientProxy, EvaluateRes], " +"BaseException]]`` (in ``aggregate_evaluate``)" msgstr "" +"매개변수 ``failures``의 유형이 ``List[BaseException]``에서 " +"``List[Union[Tuple[ClientProxy], FitRes], BaseException]]``(``aggregate_fit``" +"에서) 및 ``List[Union[Tuple[ClientProxy], EvaluateRes], " +"BaseException]]``(``aggregate_evaluate``)로 변경되었습니다" #: ../../source/how-to-upgrade-to-flower-1.0.rst:74 msgid "" "The ``Strategy`` method ``evaluate`` now receives the current round of " "federated learning/evaluation as the first parameter:" msgstr "" +"이제 ``Strategy`` 메서드 ``evaluate``는 현재 federated 학습/평가 라운드를 첫 " +"번째 파라미터로 받습니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:76 msgid "" "Flower 0.19: ``def evaluate(self, parameters: Parameters) -> " "Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" +"Flower 0.19: ``def evaluate(self, parameters: Parameters) -> " +"Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:77 msgid "" -"Flower 1.0: ``def evaluate(self, server_round: int, parameters: " -"Parameters) -> Optional[Tuple[float, Dict[str, Scalar]]]:``" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" +"> Optional[Tuple[float, Dict[str, Scalar]]]:``" msgstr "" +"Flower 1.0: ``def evaluate(self, server_round: int, parameters: Parameters) -" +"> Optional[Tuple[float, Dict[str, Scalar]]]:``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:80 msgid "Optional improvements" -msgstr "" +msgstr "선택적 개선 사항" #: ../../source/how-to-upgrade-to-flower-1.0.rst:82 msgid "" "Along with the necessary changes above, there are a number of potential " "improvements that just became possible:" msgstr "" +"위의 필수 변경 사항과 함께 방금 가능한 여러 가지 잠재적 개선 사항이 있습니다:" #: ../../source/how-to-upgrade-to-flower-1.0.rst:84 msgid "" "Remove \"placeholder\" methods from subclasses of ``Client`` or " -"``NumPyClient``. If you, for example, use server-side evaluation, then " -"empty placeholder implementations of ``evaluate`` are no longer " -"necessary." +"``NumPyClient``. If you, for example, use server-side evaluation, then empty " +"placeholder implementations of ``evaluate`` are no longer necessary." msgstr "" +"``Client`` 또는 ``NumPyClient``의 서브 클래스에서 \"placeholder\" 메서드를 제" +"거합니다. 예를 들어 서버 측 평가를 사용하는 경우 ``evaluate``의 빈 자리 표시" +"자 구현은 더 이상 필요하지 않습니다." #: ../../source/how-to-upgrade-to-flower-1.0.rst:85 msgid "" @@ -6983,69 +7294,84 @@ msgid "" "``start_simulation(..., config=flwr.server.ServerConfig(num_rounds=3, " "round_timeout=600.0), ...)``" msgstr "" +"``start_simulation``을 통해 라운드 타임아웃을 구성합니다: " +"``start_simulation(..., config=flwr.server.ServerConfig(num_rounds=3, " +"round_timeout=600.0), ...)``" #: ../../source/how-to-upgrade-to-flower-1.0.rst:89 #: ../../source/how-to-upgrade-to-flower-next.rst:317 msgid "Further help" -msgstr "" +msgstr "추가 도움말" #: ../../source/how-to-upgrade-to-flower-1.0.rst:91 msgid "" -"Most official `Flower code examples " -"`_ are already updated" -" to Flower 1.0, they can serve as a reference for using the Flower 1.0 " -"API. If there are further questions, `join the Flower Slack " -"`_ and use the channel ``#questions``." +"Most official `Flower code examples `_ are already updated to Flower 1.0, they can serve as a " +"reference for using the Flower 1.0 API. If there are further questions, " +"`join the Flower Slack `_ and use the channel " +"``#questions``." msgstr "" +"대부분의 공식 ``Flower code 예제 `_는 이미 Flower 1.0으로 업데이트되어 있으며, Flower 1.0 API를 사용" +"하기 위한 참고 자료로 사용할 수 있습니다. 더 궁금한 점이 있다면 ``플라워 슬" +"랙 `_에 가입하여 ``#questions`` 채널을 이용하" +"세요." #: ../../source/how-to-upgrade-to-flower-next.rst:2 msgid "Upgrade to Flower Next" -msgstr "" +msgstr "Flower Next 업그레이드" #: ../../source/how-to-upgrade-to-flower-next.rst:4 msgid "" -"Welcome to the migration guide for updating Flower to Flower Next! " -"Whether you're a seasoned user or just getting started, this guide will " -"help you smoothly transition your existing setup to take advantage of the" -" latest features and improvements in Flower Next, starting from version " -"1.8." +"Welcome to the migration guide for updating Flower to Flower Next! Whether " +"you're a seasoned user or just getting started, this guide will help you " +"smoothly transition your existing setup to take advantage of the latest " +"features and improvements in Flower Next, starting from version 1.8." msgstr "" +"Flower에서 Flower Next로의 업데이트를 위한 이동 가이드에 오신 것을 환영합니" +"다! 이 가이드는 숙련된 사용자든 이제 막 시작한 사용자든 상관없이 기존 설정을 " +"원활하게 전환하여 버전 1.8부터 Flower Next의 최신 기능 및 개선 사항을 활용할 " +"수 있도록 도와드립니다." #: ../../source/how-to-upgrade-to-flower-next.rst:9 msgid "" "This guide shows how to reuse pre-``1.8`` Flower code with minimum code " -"changes by using the *compatibility layer* in Flower Next. In another " -"guide, we will show how to run Flower Next end-to-end with pure Flower " -"Next APIs." +"changes by using the *compatibility layer* in Flower Next. In another guide, " +"we will show how to run Flower Next end-to-end with pure Flower Next APIs." msgstr "" +"이 가이드에서는 Flower Next의 *호환성 레이어*를 사용하여 최소한의 코드 변경으" +"로 ``1.8`` 이전의 Flower 코드를 재사용하는 방법을 보여줍니다. 다른 가이드에서" +"는 순수한 Flower Next API로 Flower Next를 end-to-end로 실행하는 방법을 보여드" +"리겠습니다." #: ../../source/how-to-upgrade-to-flower-next.rst:13 msgid "Let's dive in!" -msgstr "" +msgstr "자세히 알아봅시다!" #: ../../source/how-to-upgrade-to-flower-next.rst:48 msgid "" -"Here's how to update an existing installation of Flower to Flower Next " -"with ``pip``:" +"Here's how to update an existing installation of Flower to Flower Next with " +"``pip``:" msgstr "" +"기존에 설치된 Flower to Flower Next를 ``pip``으로 업데이트하는 방법은 다음과 " +"같습니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:54 msgid "or if you need Flower Next with simulation:" -msgstr "" +msgstr "또는 시뮬레이션이 포함된 Flower Next가 필요한 경우:" #: ../../source/how-to-upgrade-to-flower-next.rst:61 msgid "" -"Ensure you set the following version constraint in your " -"``requirements.txt``" -msgstr "" +"Ensure you set the following version constraint in your ``requirements.txt``" +msgstr "``requirements.txt``에서 다음 버전 제약 조건을 설정했는지 확인하세요" #: ../../source/how-to-upgrade-to-flower-next.rst:71 msgid "or ``pyproject.toml``:" -msgstr "" +msgstr "또는 ``pyproject.toml``:" #: ../../source/how-to-upgrade-to-flower-next.rst:82 msgid "Using Poetry" -msgstr "" +msgstr "Poetry 사용" #: ../../source/how-to-upgrade-to-flower-next.rst:84 msgid "" @@ -7053,122 +7379,155 @@ msgid "" "(don't forget to delete ``poetry.lock`` via ``rm poetry.lock`` before " "running ``poetry install``)." msgstr "" +"``pyproject.toml``에서 ``flwr`` 의존성를 업데이트한 다음 다시 설치하세요(``" +"poetry install``을 실행하기 전에 ``rm poetry.lock``을 통해 ``poetry.lock``을 " +"삭제하는 것을 잊지 마세요)." #: ../../source/how-to-upgrade-to-flower-next.rst:86 msgid "" -"Ensure you set the following version constraint in your " -"``pyproject.toml``:" -msgstr "" +"Ensure you set the following version constraint in your ``pyproject.toml``:" +msgstr "``pyproject.toml``에 다음 버전 제약 조건을 설정했는지 확인하세요:" #: ../../source/how-to-upgrade-to-flower-next.rst:102 msgid "" "In Flower Next, the *infrastructure* and *application layers* have been " -"decoupled. Instead of starting a client in code via ``start_client()``, " -"you create a |clientapp_link|_ and start it via the command line. Instead" -" of starting a server in code via ``start_server()``, you create a " -"|serverapp_link|_ and start it via the command line. The long-running " +"decoupled. Instead of starting a client in code via ``start_client()``, you " +"create a |clientapp_link|_ and start it via the command line. Instead of " +"starting a server in code via ``start_server()``, you create a |" +"serverapp_link|_ and start it via the command line. The long-running " "components of server and client are called SuperLink and SuperNode. The " -"following non-breaking changes that require manual updates and allow you " -"to run your project both in the traditional way and in the Flower Next " -"way:" +"following non-breaking changes that require manual updates and allow you to " +"run your project both in the traditional way and in the Flower Next way:" msgstr "" +"Flower Next에서는 *infrastructure*와 *application layers*가 분리되었습니다. " +"코드에서 ``start_client()``를 통해 클라이언트를 시작하는 대신, 명령줄을 통해 " +"|clientapp_link|_를 생성하여 시작합니다. 코드에서 ``start_server()``를 통해 " +"서버를 시작하는 대신 |serverapp_link|_를 생성하고 명령줄을 통해 서버를 시작합" +"니다. 서버와 클라이언트의 장기 실행 컴포넌트를 SuperLink와 SuperNode라고 합니" +"다. 수동 업데이트가 필요하지 않고 기존 방식과 Flower Next 방식 모두에서 프로" +"젝트를 실행할 수 있는 non-breaking 변경 사항은 다음과 같습니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:109 msgid "|clientapp_link|_" -msgstr "" +msgstr "|clientapp_link|_" #: ../../source/how-to-upgrade-to-flower-next.rst:110 msgid "" -"Wrap your existing client with |clientapp_link|_ instead of launching it " -"via |startclient_link|_. Here's an example:" +"Wrap your existing client with |clientapp_link|_ instead of launching it via " +"|startclient_link|_. Here's an example:" msgstr "" +"|clientapp_link|_를 통해 실행하는 대신 기존 클라이언트를 |clientapp_link|_로 " +"래핑하세요. 다음은 예시입니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:132 msgid "|serverapp_link|_" -msgstr "" +msgstr "|serverapp_link|_" #: ../../source/how-to-upgrade-to-flower-next.rst:133 msgid "" -"Wrap your existing strategy with |serverapp_link|_ instead of starting " -"the server via |startserver_link|_. Here's an example:" +"Wrap your existing strategy with |serverapp_link|_ instead of starting the " +"server via |startserver_link|_. Here's an example:" msgstr "" +"서버를 시작하려면 |startserver_link|_를 통해 서버를 시작하는 대신 기존 전략" +"을 |serverapp_link|_로 래핑하세요. 다음은 예시입니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:154 msgid "Deployment" -msgstr "" +msgstr "배포" #: ../../source/how-to-upgrade-to-flower-next.rst:155 msgid "" -"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, " -"in sequence, |flowernext_clientapp_link|_ (2x) and " -"|flowernext_serverapp_link|_. There is no need to execute `client.py` and" -" `server.py` as Python scripts." +"Run the ``SuperLink`` using |flowernext_superlink_link|_ before running, in " +"sequence, |flowernext_clientapp_link|_ (2x) and |flowernext_serverapp_link|" +"_. There is no need to execute `client.py` and `server.py` as Python scripts." msgstr "" +"실행하기 전에 |flowernext_superlink_link|_를 사용하여 ``SuperLink``를 실행한 " +"후 |flowernext_clientapp_link|_(2회) 및 |flowernext_serverapp_link|_를 " +"순서대로 실행합니다. 'client.py'와 'server.py'를 Python 스크립트로 실행할 " +"필요는 없습니다." #: ../../source/how-to-upgrade-to-flower-next.rst:158 msgid "" -"Here's an example to start the server without HTTPS (only for " -"prototyping):" +"Here's an example to start the server without HTTPS (only for prototyping):" msgstr "" +"다음은 HTTPS 없이 서버를 시작하는 예제입니다(프로토타이핑용으로만 사용):" #: ../../source/how-to-upgrade-to-flower-next.rst:174 msgid "" -"Here's another example to start with HTTPS. Use the ``--ssl-ca-" -"certfile``, ``--ssl-certfile``, and ``--ssl-keyfile`` command line " -"options to pass paths to (CA certificate, server certificate, and server " -"private key)." +"Here's another example to start with HTTPS. Use the ``--ssl-ca-certfile``, " +"``--ssl-certfile``, and ``--ssl-keyfile`` command line options to pass paths " +"to (CA certificate, server certificate, and server private key)." msgstr "" +"다음은 HTTPS로 시작하는 또 다른 예제입니다. '`--ssl-ca-certfile``, '`--ssl-" +"certfile``, '`--ssl-keyfile`` 명령줄 옵션을 사용하여 (CA 인증서, 서버 인증서 " +"및 서버 개인 키)의 경로를 전달합니다." #: ../../source/how-to-upgrade-to-flower-next.rst:201 msgid "Simulation in CLI" -msgstr "" +msgstr "CLI 시뮬레이션" #: ../../source/how-to-upgrade-to-flower-next.rst:202 msgid "" -"Wrap your existing client and strategy with |clientapp_link|_ and " -"|serverapp_link|_, respectively. There is no need to use |startsim_link|_" -" anymore. Here's an example:" +"Wrap your existing client and strategy with |clientapp_link|_ and |" +"serverapp_link|_, respectively. There is no need to use |startsim_link|_ " +"anymore. Here's an example:" msgstr "" +"기존 클라이언트와 전략을 각각 |clientapp_link|_와 |serverapp_link|_로 래핑하" +"세요. 더 이상 |startsim_link|_를 사용할 필요가 없습니다. 다음은 예시입니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:232 msgid "" "Run |flower_simulation_link|_ in CLI and point to the ``server_app`` / " -"``client_app`` object in the code instead of executing the Python script." -" Here's an example (assuming the ``server_app`` and ``client_app`` " -"objects are in a ``sim.py`` module):" +"``client_app`` object in the code instead of executing the Python script. " +"Here's an example (assuming the ``server_app`` and ``client_app`` objects " +"are in a ``sim.py`` module):" msgstr "" +"CLI에서 |flower_simulation_link|_를 실행하고 Python 스크립트를 실행하는 대신 " +"코드에서 ``server_app`` / ``client_app`` 개체를 가리키세요. 다음은 예제입니다" +"(``server_app`` 및 ``client_app`` 객체가 ``sim.py`` 모듈에 있다고 가정):" #: ../../source/how-to-upgrade-to-flower-next.rst:249 msgid "" "Set default resources for each |clientapp_link|_ using the ``--backend-" -"config`` command line argument instead of setting the " -"``client_resources`` argument in |startsim_link|_. Here's an example:" +"config`` command line argument instead of setting the ``client_resources`` " +"argument in |startsim_link|_. Here's an example:" msgstr "" +"|startsim_link|_에서 ``client_resources`` 인수를 설정하는 대신 ``--backend-" +"config`` 명령줄 인수를 사용하여 각 |clientapp_link|_에 대한 기본 리소스를 설" +"정하세요. 다음은 예시입니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:275 msgid "Simulation in a Notebook" -msgstr "" +msgstr "Notebook에서 시뮬레이션" #: ../../source/how-to-upgrade-to-flower-next.rst:276 msgid "" -"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's " -"an example:" +"Run |runsim_link|_ in your notebook instead of |startsim_link|_. Here's an " +"example:" msgstr "" +"notebook에서 |startsim_link|_ 대신 |runsim_link|_를 실행하세요. 다음은 예시입" +"니다:" #: ../../source/how-to-upgrade-to-flower-next.rst:319 msgid "" -"Some official `Flower code examples `_ " -"are already updated to Flower Next so they can serve as a reference for " -"using the Flower Next API. If there are further questions, `join the " -"Flower Slack `_ and use the channel " -"``#questions``. You can also `participate in Flower Discuss " -"`_ where you can find us answering questions," -" or share and learn from others about migrating to Flower Next." -msgstr "" +"Some official `Flower code examples `_ are " +"already updated to Flower Next so they can serve as a reference for using " +"the Flower Next API. If there are further questions, `join the Flower Slack " +"`_ and use the channel ``#questions``. You " +"can also `participate in Flower Discuss `_ where " +"you can find us answering questions, or share and learn from others about " +"migrating to Flower Next." +msgstr "" +"일부 공식 ``Flower 코드 예제 `_는 이미 플라" +"워 넥스트에 업데이트되어 있으므로 플라워 넥스트 API를 사용하는 데 참고할 수 " +"있습니다. 더 궁금한 점이 있다면 ``플라워 슬랙 `_에 가입하고 ``#questions`` 채널을 이용하세요. 또한, ``Flower Discuss " +"`_에 참여하여 질문에 대한 답변을 확인하거나 다른 " +"사람들과 Flower Next로의 이동에 대해 공유하고 배울 수 있습니다." #: ../../source/how-to-upgrade-to-flower-next.rst:325 msgid "Important" -msgstr "" +msgstr "중요" #: ../../source/how-to-upgrade-to-flower-next.rst:328 msgid "" @@ -7176,322 +7535,399 @@ msgid "" "periodically updating this guide. Please feel free to share any feedback " "with us!" msgstr "" +"Flower Next는 빠른 속도로 지속적으로 개선되고 있으므로 이 가이드는 주기적으" +"로 업데이트될 예정입니다. 피드백이 있으면 언제든지 공유해 주세요!" #: ../../source/how-to-upgrade-to-flower-next.rst:334 msgid "Happy migrating! 🚀" -msgstr "" +msgstr "행복한 마이그레이션! 🚀" #: ../../source/how-to-use-built-in-mods.rst:2 msgid "Use Built-in Mods" -msgstr "" +msgstr "기본 제공 모드 사용" #: ../../source/how-to-use-built-in-mods.rst:4 msgid "" -"**Note: This tutorial covers experimental features. The functionality and" -" interfaces may change in future versions.**" +"**Note: This tutorial covers experimental features. The functionality and " +"interfaces may change in future versions.**" msgstr "" +"**참고: 이 튜토리얼은 실험적인 기능을 다룹니다. 기능 및 인터페이스는 향후 버" +"전에서 변경될 수 있습니다.**" #: ../../source/how-to-use-built-in-mods.rst:6 msgid "" -"In this tutorial, we will learn how to utilize built-in mods to augment " -"the behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) " -"allow us to perform operations before and after a task is processed in " -"the ``ClientApp``." +"In this tutorial, we will learn how to utilize built-in mods to augment the " +"behavior of a ``ClientApp``. Mods (sometimes also called Modifiers) allow us " +"to perform operations before and after a task is processed in the " +"``ClientApp``." msgstr "" +"이 튜토리얼에서는 내장 모드를 활용하여 ``ClientApp``의 동작을 보강하는 방법" +"을 배우겠습니다. Mods(Modifiers라고도 함)를 사용하면 ``ClientApp``에서 작업" +"이 처리되기 전과 후에 작업을 수행할 수 있습니다." #: ../../source/how-to-use-built-in-mods.rst:9 msgid "What are Mods?" -msgstr "" +msgstr "Mods란 무엇인가요?" #: ../../source/how-to-use-built-in-mods.rst:11 msgid "" -"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate " -"or inspect the incoming ``Message`` and the resulting outgoing " -"``Message``. The signature for a ``Mod`` is as follows:" +"A Mod is a callable that wraps around a ``ClientApp``. It can manipulate or " +"inspect the incoming ``Message`` and the resulting outgoing ``Message``. The " +"signature for a ``Mod`` is as follows:" msgstr "" +"Mod는 ``ClientApp``을 감싸는 콜러블입니다. 들어오는 ``Message``와 그 결과로 " +"나가는 ``Message``를 조작하거나 검사할 수 있습니다. ``Mod``의 시그니처는 다음" +"과 같습니다:" #: ../../source/how-to-use-built-in-mods.rst:18 msgid "A typical mod function might look something like this:" -msgstr "" +msgstr "일반적인 mod 함수는 다음과 같은 모습일 수 있습니다:" #: ../../source/how-to-use-built-in-mods.rst:31 msgid "Using Mods" -msgstr "" +msgstr "Mods 사용" #: ../../source/how-to-use-built-in-mods.rst:33 msgid "To use mods in your ``ClientApp``, you can follow these steps:" -msgstr "" +msgstr "``ClientApp``에서 mods를 사용하려면 다음 단계를 따르세요:" #: ../../source/how-to-use-built-in-mods.rst:36 msgid "1. Import the required mods" -msgstr "" +msgstr "1. 필요한 mods를 가져옵니다" #: ../../source/how-to-use-built-in-mods.rst:38 msgid "First, import the built-in mod you intend to use:" -msgstr "" +msgstr "먼저 사용하려는 기본 제공 mod를 가져옵니다:" #: ../../source/how-to-use-built-in-mods.rst:46 msgid "2. Define your client function" -msgstr "" +msgstr "2. 클라이언트 기능 정의" #: ../../source/how-to-use-built-in-mods.rst:48 msgid "" "Define your client function (``client_fn``) that will be wrapped by the " "mod(s):" -msgstr "" +msgstr "mod(s)로 래핑할 클라이언트 함수('``client_fn``)를 정의합니다:" #: ../../source/how-to-use-built-in-mods.rst:57 msgid "3. Create the ``ClientApp`` with mods" -msgstr "" +msgstr "3. mods로 ``ClientApp``을 생성합니다" #: ../../source/how-to-use-built-in-mods.rst:59 msgid "" "Create your ``ClientApp`` and pass the mods as a list to the ``mods`` " "argument. The order in which you provide the mods matters:" msgstr "" +"``ClientApp``을 생성하고 mods를 ``mods`` argument에 목록으로 전달합니다. mods" +"를 제공하는 순서가 중요합니다:" #: ../../source/how-to-use-built-in-mods.rst:72 msgid "Order of execution" -msgstr "" +msgstr "실행 순서" #: ../../source/how-to-use-built-in-mods.rst:74 msgid "" "When the ``ClientApp`` runs, the mods are executed in the order they are " "provided in the list:" -msgstr "" +msgstr "``ClientApp``이 실행되면 목록에 제공된 순서대로 모드가 실행됩니다:" #: ../../source/how-to-use-built-in-mods.rst:76 msgid "``example_mod_1`` (outermost mod)" -msgstr "" +msgstr "``example_mod_1``(가장 바깥쪽 mod)" #: ../../source/how-to-use-built-in-mods.rst:77 msgid "``example_mod_2`` (next mod)" -msgstr "" +msgstr "``example_mod_2`` (다음 mod)" #: ../../source/how-to-use-built-in-mods.rst:78 msgid "" "Message handler (core function that handles the incoming ``Message`` and " "returns the outgoing ``Message``)" msgstr "" +"Message handler(들어오는 ``Message``를 처리하고 나가는 ``Message``를 반환하" +"는 핵심 함수)" #: ../../source/how-to-use-built-in-mods.rst:79 msgid "``example_mod_2`` (on the way back)" -msgstr "" +msgstr "``example_mod_2``(돌아가는 방법)" #: ../../source/how-to-use-built-in-mods.rst:80 msgid "``example_mod_1`` (outermost mod on the way back)" -msgstr "" +msgstr "``example_mod_1``(돌아가는 방법에 가장 바깥쪽 모드)" #: ../../source/how-to-use-built-in-mods.rst:82 msgid "" -"Each mod has a chance to inspect and modify the incoming ``Message`` " -"before passing it to the next mod, and likewise with the outgoing " -"``Message`` before returning it up the stack." +"Each mod has a chance to inspect and modify the incoming ``Message`` before " +"passing it to the next mod, and likewise with the outgoing ``Message`` " +"before returning it up the stack." msgstr "" +"각 mod는 다음 mod로 전달하기 전에 들어오는 ``Message``를 검사하고 수정할 기회" +"가 있으며, 스택 위로 반환하기 전에 나가는 ``Message``도 마찬가지로 검사하고 " +"수정할 수 있습니다." #: ../../source/how-to-use-built-in-mods.rst:87 msgid "" "By following this guide, you have learned how to effectively use mods to " -"enhance your ``ClientApp``'s functionality. Remember that the order of " -"mods is crucial and affects how the input and output are processed." +"enhance your ``ClientApp``'s functionality. Remember that the order of mods " +"is crucial and affects how the input and output are processed." msgstr "" +"이 가이드를 따라 mods를 효과적으로 사용하여 ``ClientApp``의 기능을 향상시키" +"는 방법을 배웠습니다. mods 순서는 매우 중요하며 입력과 출력이 처리되는 방식" +"에 영향을 미친다는 점을 기억하세요." #: ../../source/how-to-use-built-in-mods.rst:89 msgid "Enjoy building a more robust and flexible ``ClientApp`` with mods!" -msgstr "" +msgstr "Mods를 통해 더욱 강력하고 유연한 ``ClientApp``을 구축해 보세요!" #: ../../source/how-to-use-differential-privacy.rst:2 msgid "Use Differential Privacy" -msgstr "" +msgstr "차분 개인정보 보호 사용" #: ../../source/how-to-use-differential-privacy.rst:3 msgid "" -"This guide explains how you can utilize differential privacy in the " -"Flower framework. If you are not yet familiar with differential privacy, " -"you can refer to :doc:`explanation-differential-privacy`." +"This guide explains how you can utilize differential privacy in the Flower " +"framework. If you are not yet familiar with differential privacy, you can " +"refer to :doc:`explanation-differential-privacy`." msgstr "" +"이 가이드에서는 Flower 프레임워크에서 차분 개인정보 보호 기능을 활용하는 방법" +"을 설명합니다. 차분 개인정보 보호에 대해 아직 익숙하지 않은 경우 :doc:" +"`explanation-differential-privacy`를 참조하세요." #: ../../source/how-to-use-differential-privacy.rst:7 msgid "" "Differential Privacy in Flower is in a preview phase. If you plan to use " -"these features in a production environment with sensitive data, feel free" -" contact us to discuss your requirements and to receive guidance on how " -"to best use these features." +"these features in a production environment with sensitive data, feel free " +"contact us to discuss your requirements and to receive guidance on how to " +"best use these features." msgstr "" +"Flower의 차분 개인정보 보호는 현재 프리뷰 단계에 있습니다. 민감한 데이터가 있" +"는 프로덕션 환경에서 이러한 기능을 사용할 계획이라면 언제든지 문의하여 요구 " +"사항을 논의하고 이러한 기능을 가장 잘 사용하는 방법에 대한 안내를 받으세요." #: ../../source/how-to-use-differential-privacy.rst:12 msgid "" -"This approach consists of two seprate phases: clipping of the updates and" -" adding noise to the aggregated model. For the clipping phase, Flower " -"framework has made it possible to decide whether to perform clipping on " -"the server side or the client side." +"This approach consists of two seprate phases: clipping of the updates and " +"adding noise to the aggregated model. For the clipping phase, Flower " +"framework has made it possible to decide whether to perform clipping on the " +"server side or the client side." msgstr "" +"이 접근 방식은 업데이트 클리핑과 집계된 모델에 노이즈 추가라는 두 가지 단계" +"로 구성됩니다. 클리핑 단계의 경우, Flower 프레임워크는 클리핑을 서버 측에서 " +"수행할지 클라이언트 측에서 수행할지 결정할 수 있도록 했습니다." #: ../../source/how-to-use-differential-privacy.rst:15 msgid "" "**Server-side Clipping**: This approach has the advantage of the server " "enforcing uniform clipping across all clients' updates and reducing the " "communication overhead for clipping values. However, it also has the " -"disadvantage of increasing the computational load on the server due to " -"the need to perform the clipping operation for all clients." +"disadvantage of increasing the computational load on the server due to the " +"need to perform the clipping operation for all clients." msgstr "" +"**Server-side Clipping**: 이 방식은 서버가 모든 클라이언트의 업데이트에 대해 " +"균일한 클리핑을 적용하고 클리핑 값에 대한 통신 오버헤드를 줄일 수 있다는 장점" +"이 있습니다. 하지만 모든 클라이언트에 대해 클리핑 작업을 수행해야 하기 때문" +"에 서버의 계산 부하가 증가한다는 단점도 있습니다." #: ../../source/how-to-use-differential-privacy.rst:16 msgid "" -"**Client-side Clipping**: This approach has the advantage of reducing the" -" computational overhead on the server. However, it also has the " -"disadvantage of lacking centralized control, as the server has less " -"control over the clipping process." +"**Client-side Clipping**: This approach has the advantage of reducing the " +"computational overhead on the server. However, it also has the disadvantage " +"of lacking centralized control, as the server has less control over the " +"clipping process." msgstr "" +"**Client-side Clipping**: 이 방식은 서버의 계산 오버헤드를 줄일 수 있다는 장" +"점이 있습니다. 하지만 서버가 클리핑 프로세스에 대한 통제력이 떨어지기 때문에 " +"centralized 제어가 부족하다는 단점도 있습니다." #: ../../source/how-to-use-differential-privacy.rst:21 msgid "Server-side Clipping" -msgstr "" +msgstr "서버 측 클리핑" #: ../../source/how-to-use-differential-privacy.rst:22 msgid "" "For central DP with server-side clipping, there are two :code:`Strategy` " "classes that act as wrappers around the actual :code:`Strategy` instance " -"(for example, :code:`FedAvg`). The two wrapper classes are " -":code:`DifferentialPrivacyServerSideFixedClipping` and " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and " -"adaptive clipping." +"(for example, :code:`FedAvg`). The two wrapper classes are :code:" +"`DifferentialPrivacyServerSideFixedClipping` and :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` for fixed and adaptive " +"clipping." msgstr "" +"서버 측 클리핑이 있는 중앙 DP의 경우, 실제 :code:`Strategy` 인스턴스를 감싸" +"는 래퍼 역할을 하는 두 개의 :code:`Strategy` 클래스가 있습니다(예: :code:" +"`FedAvg`). 두 개의 래퍼 클래스는 고정 및 적응형 클리핑을 위한 :code:" +"`DifferentialPrivacyServerSideFixedClipping`과 :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping`입니다." #: ../../source/how-to-use-differential-privacy.rst:-1 msgid "server side clipping" -msgstr "" +msgstr "서버 측 클리핑" #: ../../source/how-to-use-differential-privacy.rst:31 msgid "" -"The code sample below enables the :code:`FedAvg` strategy to use server-" -"side fixed clipping using the " -":code:`DifferentialPrivacyServerSideFixedClipping` wrapper class. The " -"same approach can be used with " -":code:`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " +"The code sample below enables the :code:`FedAvg` strategy to use server-side " +"fixed clipping using the :code:`DifferentialPrivacyServerSideFixedClipping` " +"wrapper class. The same approach can be used with :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping` by adjusting the " "corresponding input parameters." msgstr "" +"아래 코드 샘플은 :code:`FedAvg` 전략이 :code:" +"`DifferentialPrivacyServerSideFixedClipping` 래퍼 클래스를 사용하여 서버 측 " +"고정 클리핑을 사용할 수 있도록 합니다. 해당 입력 매개변수를 조정하여 :code:" +"`DifferentialPrivacyServerSideAdaptiveClipping`과 동일한 접근 방식을 사용할 " +"수 있습니다." #: ../../source/how-to-use-differential-privacy.rst:52 msgid "Client-side Clipping" -msgstr "" +msgstr "클라이언트 측 클리핑" #: ../../source/how-to-use-differential-privacy.rst:53 msgid "" "For central DP with client-side clipping, the server sends the clipping " -"value to selected clients on each round. Clients can use existing Flower " -":code:`Mods` to perform the clipping. Two mods are available for fixed " -"and adaptive client-side clipping: :code:`fixedclipping_mod` and " -":code:`adaptiveclipping_mod` with corresponding server-side wrappers " -":code:`DifferentialPrivacyClientSideFixedClipping` and " -":code:`DifferentialPrivacyClientSideAdaptiveClipping`." -msgstr "" +"value to selected clients on each round. Clients can use existing Flower :" +"code:`Mods` to perform the clipping. Two mods are available for fixed and " +"adaptive client-side clipping: :code:`fixedclipping_mod` and :code:" +"`adaptiveclipping_mod` with corresponding server-side wrappers :code:" +"`DifferentialPrivacyClientSideFixedClipping` and :code:" +"`DifferentialPrivacyClientSideAdaptiveClipping`." +msgstr "" +"클라이언트 측 클리핑이 있는 중앙 DP의 경우 서버는 각 라운드마다 선택한 클라이" +"언트에 클리핑 값을 보냅니다. 클라이언트는 기존 Flower :code:`Mods`를 사용하" +"여 클리핑을 수행할 수 있습니다. 고정 및 적응형 클라이언트 측 클리핑에는 두 가" +"지 모드를 사용할 수 있습니다: :code:`fixedclipping_mod` 및 :code:" +"`adaptiveclipping_mod`와 해당 서버 측 래퍼 :code:" +"`DifferentialPrivacyClientSideFixedClipping` 및 :code:" +"`DifferentialPrivacyClientSideAdaptiveClipping`이 있습니다." #: ../../source/how-to-use-differential-privacy.rst:-1 msgid "client side clipping" -msgstr "" +msgstr "클라이언트 측 클리핑" #: ../../source/how-to-use-differential-privacy.rst:63 msgid "" "The code sample below enables the :code:`FedAvg` strategy to use " -"differential privacy with client-side fixed clipping using both the " -":code:`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on " -"the client, :code:`fixedclipping_mod`:" +"differential privacy with client-side fixed clipping using both the :code:" +"`DifferentialPrivacyClientSideFixedClipping` wrapper class and, on the " +"client, :code:`fixedclipping_mod`:" msgstr "" +"아래 코드 샘플은 :code:`FedAvg` 전략이 클라이언트 측 고정 클리핑과 함께 차분 " +"프라이버시를 사용할 수 있도록 :code:" +"`DifferentialPrivacyClientSideFixedClipping` 래퍼 클래스와 클라이언트에서 :" +"code:`fixedclipping_mod`를 모두 사용하도록 합니다:" #: ../../source/how-to-use-differential-privacy.rst:80 msgid "" -"In addition to the server-side strategy wrapper, the :code:`ClientApp` " -"needs to configure the matching :code:`fixedclipping_mod` to perform the " -"client-side clipping:" +"In addition to the server-side strategy wrapper, the :code:`ClientApp` needs " +"to configure the matching :code:`fixedclipping_mod` to perform the client-" +"side clipping:" msgstr "" +"서버 측 전략 래퍼 외에도 클라이언트 측 클리핑을 수행하려면 :code:`ClientApp`" +"이 일치하는 :code:`fixedclipping_mod`를 구성해야 합니다:" #: ../../source/how-to-use-differential-privacy.rst:97 msgid "" -"To utilize local differential privacy (DP) and add noise to the client " -"model parameters before transmitting them to the server in Flower, you " -"can use the `LocalDpMod`. The following hyperparameters need to be set: " -"clipping norm value, sensitivity, epsilon, and delta." +"To utilize local differential privacy (DP) and add noise to the client model " +"parameters before transmitting them to the server in Flower, you can use the " +"`LocalDpMod`. The following hyperparameters need to be set: clipping norm " +"value, sensitivity, epsilon, and delta." msgstr "" +"로컬 차분 프라이버시(DP)를 활용하고 클라이언트 모델 파라미터를 서버로 전송하" +"기 전에 노이즈를 추가하려면 `LocalDpMod`를 사용하면 됩니다. 클리핑 노멀 값, " +"감도, 엡실론, 델타 등의 하이퍼파라미터를 설정해야 합니다." #: ../../source/how-to-use-differential-privacy.rst:-1 msgid "local DP mod" -msgstr "" +msgstr "로컬 DP mod" #: ../../source/how-to-use-differential-privacy.rst:104 msgid "Below is a code example that shows how to use :code:`LocalDpMod`:" -msgstr "" +msgstr "다음은 :code:`LocalDpMod`를 사용하는 방법을 보여주는 코드 예시입니다:" #: ../../source/how-to-use-differential-privacy.rst:122 msgid "" -"Please note that the order of mods, especially those that modify " -"parameters, is important when using multiple modifiers. Typically, " -"differential privacy (DP) modifiers should be the last to operate on " -"parameters." +"Please note that the order of mods, especially those that modify parameters, " +"is important when using multiple modifiers. Typically, differential privacy " +"(DP) modifiers should be the last to operate on parameters." msgstr "" +"여러 개의 수정자를 사용할 때는 수정자, 특히 매개변수를 수정하는 수정자의 순서" +"가 중요하다는 점에 유의하세요. 일반적으로 차분 프라이버시(DP) 수정자는 매개변" +"수에서 가장 마지막에 작동해야 합니다." #: ../../source/how-to-use-differential-privacy.rst:125 msgid "Local Training using Privacy Engines" -msgstr "" +msgstr "Privacy Engines을 사용한 로컬 훈련" #: ../../source/how-to-use-differential-privacy.rst:126 msgid "" -"For ensuring data instance-level privacy during local model training on " -"the client side, consider leveraging privacy engines such as Opacus and " -"TensorFlow Privacy. For examples of using Flower with these engines, " -"please refer to the Flower examples directory (`Opacus " -"`_, `Tensorflow" -" Privacy `_)." +"For ensuring data instance-level privacy during local model training on the " +"client side, consider leveraging privacy engines such as Opacus and " +"TensorFlow Privacy. For examples of using Flower with these engines, please " +"refer to the Flower examples directory (`Opacus `_, `Tensorflow Privacy `_)." msgstr "" +"클라이언트 측에서 로컬 모델을 훈련하는 동안 데이터 인스턴스 수준의 개인 정보 " +"보호를 보장하려면 Opacus 및 TensorFlow Privacy와 같은 개인 정보 보호 엔진을 " +"활용하는 것을 고려하세요. 이러한 엔진과 함께 Flower를 사용하는 예제는 Flower " +"examples directory (`Opacus `_, `Tensorflow Privacy `_)를 참조하세요." #: ../../source/how-to-use-strategies.rst:2 msgid "Use strategies" -msgstr "" +msgstr "전략 사용하기" #: ../../source/how-to-use-strategies.rst:4 msgid "" -"Flower allows full customization of the learning process through the " -":code:`Strategy` abstraction. A number of built-in strategies are " -"provided in the core framework." +"Flower allows full customization of the learning process through the :code:" +"`Strategy` abstraction. A number of built-in strategies are provided in the " +"core framework." msgstr "" +"Flower는 :code:`Strategy` abstraction를 통해 학습 과정을 완전히 사용자 정의" +"할 수 있습니다. 핵심 프레임워크에는 여러 가지 기본 제공 전략이 제공됩니다." #: ../../source/how-to-use-strategies.rst:6 msgid "" -"There are three ways to customize the way Flower orchestrates the " -"learning process on the server side:" +"There are three ways to customize the way Flower orchestrates the learning " +"process on the server side:" msgstr "" +"서버 측에서 Flower가 학습 과정을 조율하는 방식을 사용자 지정하는 방법에는 세 " +"가지가 있습니다:" #: ../../source/how-to-use-strategies.rst:8 msgid "Use an existing strategy, for example, :code:`FedAvg`" -msgstr "" +msgstr "기존 전략(예: :code:`FedAvg`)을 사용합니다" #: ../../source/how-to-use-strategies.rst:9 #: ../../source/how-to-use-strategies.rst:40 msgid "Customize an existing strategy with callback functions" -msgstr "" +msgstr "콜백 함수로 기존 전략 사용자 지정" #: ../../source/how-to-use-strategies.rst:10 #: ../../source/how-to-use-strategies.rst:87 msgid "Implement a novel strategy" -msgstr "" +msgstr "새로운 전략 구현" #: ../../source/how-to-use-strategies.rst:14 msgid "Use an existing strategy" -msgstr "" +msgstr "기존 전략 사용" #: ../../source/how-to-use-strategies.rst:16 msgid "" -"Flower comes with a number of popular federated learning strategies " -"built-in. A built-in strategy can be instantiated as follows:" +"Flower comes with a number of popular federated learning strategies built-" +"in. A built-in strategy can be instantiated as follows:" msgstr "" +"Flower에는 여러 가지 인기 있는 연합 학습 전략이 기본으로 제공됩니다. 기본 " +"제공 전략은 다음과 같이 인스턴스화할 수 있습니다:" #: ../../source/how-to-use-strategies.rst:25 msgid "" -"This creates a strategy with all parameters left at their default values " -"and passes it to the :code:`start_server` function. It is usually " -"recommended to adjust a few parameters during instantiation:" +"This creates a strategy with all parameters left at their default values and " +"passes it to the :code:`start_server` function. It is usually recommended to " +"adjust a few parameters during instantiation:" msgstr "" +"이렇게 하면 모든 매개변수가 기본값으로 유지된 전략이 생성되어 :code:" +"`start_server` 함수에 전달됩니다. 일반적으로 인스턴스화 중에 몇 가지 매개변수" +"를 조정하는 것이 좋습니다:" #: ../../source/how-to-use-strategies.rst:42 msgid "" @@ -7499,118 +7935,138 @@ msgid "" "Callback functions allow strategies to call user-provided code during " "execution." msgstr "" +"기존 전략은 동작을 사용자 지정하는 여러 가지 방법을 제공합니다. 콜백 함수를 " +"사용하면 전략이 실행 중에 사용자가 제공한 코드를 호출할 수 있습니다." #: ../../source/how-to-use-strategies.rst:45 msgid "Configuring client fit and client evaluate" -msgstr "" +msgstr "클라이언트 적합성 및 클라이언트 평가 구성" #: ../../source/how-to-use-strategies.rst:47 msgid "" "The server can pass new configuration values to the client each round by " -"providing a function to :code:`on_fit_config_fn`. The provided function " -"will be called by the strategy and must return a dictionary of " -"configuration key values pairs that will be sent to the client. It must " -"return a dictionary of arbitrary configuration values :code:`client.fit`" -" and :code:`client.evaluate` functions during each round of federated " -"learning." -msgstr "" +"providing a function to :code:`on_fit_config_fn`. The provided function will " +"be called by the strategy and must return a dictionary of configuration key " +"values pairs that will be sent to the client. It must return a dictionary of " +"arbitrary configuration values :code:`client.fit` and :code:`client." +"evaluate` functions during each round of federated learning." +msgstr "" +"서버는 매 라운드마다 새로운 설정 값을 클라이언트에 전달하기 위해 " +":code:`on_fit_config_fn`에 함수를 제공할 수 있습니다. 제공된 함수는 전략에 " +"의해 호출되며 클라이언트에 전송될 구성 키 값 쌍의 dictionary를 반환해야 " +"합니다. 연합 학습의 각 라운드 동안 임의의 구성 값 dictionary인 :code:`client." +"fit` 및 :code:`client.evaluate` 함수를 반환해야 합니다." #: ../../source/how-to-use-strategies.rst:75 msgid "" "The :code:`on_fit_config_fn` can be used to pass arbitrary configuration " "values from server to client, and poetentially change these values each " -"round, for example, to adjust the learning rate. The client will receive " -"the dictionary returned by the :code:`on_fit_config_fn` in its own " -":code:`client.fit()` function." +"round, for example, to adjust the learning rate. The client will receive the " +"dictionary returned by the :code:`on_fit_config_fn` in its own :code:`client." +"fit()` function." msgstr "" +":code:`on_fit_config_fn`은 서버에서 클라이언트로 임의의 구성 값을 전달하고, " +"예를 들어 학습 속도를 조정하기 위해 매 라운드마다 이 값을 잠재적으로 변경하" +"는 데 사용할 수 있습니다. 클라이언트는 자체 :code:`client.fit()` 함수에서 :" +"code:`on_fit_config_fn`이 반환한 dictionary를 받습니다." #: ../../source/how-to-use-strategies.rst:78 msgid "" -"Similar to :code:`on_fit_config_fn`, there is also " -":code:`on_evaluate_config_fn` to customize the configuration sent to " -":code:`client.evaluate()`" +"Similar to :code:`on_fit_config_fn`, there is also :code:" +"`on_evaluate_config_fn` to customize the configuration sent to :code:`client." +"evaluate()`" msgstr "" +":code:`on_fit_config_fn`과 유사하게, :code:`client.evaluate()`로 전송되는 구" +"성을 사용자 지정하는 :code:`on_evaluate_config_fn`도 있습니다" #: ../../source/how-to-use-strategies.rst:81 msgid "Configuring server-side evaluation" -msgstr "" +msgstr "서버 측 평가 구성" #: ../../source/how-to-use-strategies.rst:83 msgid "" -"Server-side evaluation can be enabled by passing an evaluation function " -"to :code:`evaluate_fn`." +"Server-side evaluation can be enabled by passing an evaluation function to :" +"code:`evaluate_fn`." msgstr "" +"서버 측 평가는 :code:`evaluate_fn`에 평가 함수를 전달하여 활성화할 수 있습니" +"다." #: ../../source/how-to-use-strategies.rst:89 msgid "" -"Writing a fully custom strategy is a bit more involved, but it provides " -"the most flexibility. Read the `Implementing Strategies `_ guide to learn more." +"Writing a fully custom strategy is a bit more involved, but it provides the " +"most flexibility. Read the `Implementing Strategies `_ guide to learn more." msgstr "" +"완전한 사용자 지정 전략을 작성하는 것은 조금 더 복잡하지만 유연성이 가장 뛰어" +"납니다. 자세한 내용은 `Implementing Strategies `_ 가이드를 참조하세요." #: ../../source/index.rst:34 msgid "Tutorial" -msgstr "" +msgstr "튜토리얼" #: ../../source/index.rst:44 msgid "Quickstart tutorials" -msgstr "" +msgstr "빠른 시작 튜토리얼" #: ../../source/index.rst:74 ../../source/index.rst:78 msgid "How-to guides" -msgstr "" +msgstr "사용 방법 가이드" #: ../../source/index.rst:99 msgid "Legacy example guides" -msgstr "" +msgstr "레거시 예제 가이드" #: ../../source/index.rst:108 ../../source/index.rst:112 msgid "Explanations" -msgstr "" +msgstr "설명" #: None:-1 msgid "API reference" -msgstr "" +msgstr "API 참조" #: ../../source/index.rst:137 msgid "Reference docs" -msgstr "" +msgstr "참조 문서" #: ../../source/index.rst:153 msgid "Contributor tutorials" -msgstr "" +msgstr "기여자 튜토리얼" #: ../../source/index.rst:160 msgid "Contributor how-to guides" -msgstr "" +msgstr "기여자 사용법 가이드" #: ../../source/index.rst:172 msgid "Contributor explanations" -msgstr "" +msgstr "기여자 설명" #: ../../source/index.rst:178 msgid "Contributor references" -msgstr "" +msgstr "기여자 참조" #: ../../source/index.rst:-1 msgid "" "Check out the documentation of the main Flower Framework enabling easy " "Python development for Federated Learning." -msgstr "" +msgstr "연합 학습을 위한 Python 개발을 쉽게 할 수 있는 주요 Flower 프레임워크의 " +"설명서를 확인하세요." #: ../../source/index.rst:2 msgid "Flower Framework Documentation" -msgstr "" +msgstr "플라워 프레임워크 문서" #: ../../source/index.rst:7 msgid "" "Welcome to Flower's documentation. `Flower `_ is a " "friendly federated learning framework." msgstr "" +"Flower 문서에 오신 것을 환영합니다. Flower `_는 편한 연합 " +"학습 프레임워크입니다." #: ../../source/index.rst:11 msgid "Join the Flower Community" -msgstr "" +msgstr "Flower 커뮤니티 가입하기" #: ../../source/index.rst:13 msgid "" @@ -7618,158 +8074,175 @@ msgid "" "researchers, engineers, students, professionals, academics, and other " "enthusiasts." msgstr "" +"Flower 커뮤니티는 연구원, 엔지니어, 학생, 전문가, 학자 및 기타 애호가들로 구" +"성된 편한 그룹으로 빠르게 성장하고 있습니다." #: ../../source/index.rst:15 msgid "Join us on Slack" -msgstr "" +msgstr "Slack에 가입하세요" #: ../../source/index.rst:23 msgid "Flower Framework" -msgstr "" +msgstr "Flower 프레임워크" #: ../../source/index.rst:25 msgid "" "The user guide is targeted at researchers and developers who want to use " "Flower to bring existing machine learning workloads into a federated " -"setting. One of Flower's design goals was to make this simple. Read on to" -" learn more." +"setting. One of Flower's design goals was to make this simple. Read on to " +"learn more." msgstr "" +"이 사용자 가이드는 Flower를 사용해 기존 머신 러닝 워크로드를 연합된 환경으로 " +"가져오고자 하는 연구자와 개발자를 대상으로 합니다. Flower의 설계 목표 중 하나" +"는 이를 간단하게 만드는 것이었습니다. 자세히 알아보려면 계속 읽어보세요." #: ../../source/index.rst:30 msgid "Tutorials" -msgstr "" +msgstr "튜토리얼" #: ../../source/index.rst:32 msgid "" -"A learning-oriented series of federated learning tutorials, the best " -"place to start." -msgstr "" +"A learning-oriented series of federated learning tutorials, the best place " +"to start." +msgstr "학습 중심의 연합 학습 튜토리얼 시리즈로, 시작하기에 가장 좋은 곳입니다." #: ../../source/index.rst:61 msgid "" -"QUICKSTART TUTORIALS: :doc:`PyTorch ` | " -":doc:`TensorFlow ` | :doc:`🤗 Transformers" -" ` | :doc:`JAX ` | :doc:`Pandas ` | :doc:`fastai " -"` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:`XGBoost ` | " -":doc:`Android ` | :doc:`iOS `" -msgstr "" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" +"`TensorFlow ` | :doc:`🤗 Transformers " +"` | :doc:`JAX ` | :" +"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:" +"`XGBoost ` | :doc:`Android ` | :doc:`iOS `" +msgstr "" +"QUICKSTART TUTORIALS: :doc:`PyTorch ` | :doc:" +"`TensorFlow ` | :doc:`🤗 Transformers " +"` | :doc:`JAX ` | :" +"doc:`Pandas ` | :doc:`fastai ` | :doc:`PyTorch Lightning ` | :doc:`scikit-learn ` | :doc:" +"`XGBoost ` | :doc:`Android ` | :doc:`iOS `" #: ../../source/index.rst:63 msgid "We also made video tutorials for PyTorch:" -msgstr "" +msgstr "파이토치용 동영상 튜토리얼도 만들었습니다:" #: ../../source/index.rst:68 msgid "And TensorFlow:" -msgstr "" +msgstr "그리고 TensorFlow도:" #: ../../source/index.rst:76 msgid "" -"Problem-oriented how-to guides show step-by-step how to achieve a " -"specific goal." +"Problem-oriented how-to guides show step-by-step how to achieve a specific " +"goal." msgstr "" +"문제 중심의 방법 가이드는 특정 목표를 달성하는 방법을 단계별로 보여줍니다." #: ../../source/index.rst:110 msgid "" "Understanding-oriented concept guides explain and discuss key topics and " "underlying ideas behind Flower and collaborative AI." msgstr "" +"이해 중심의 개념 가이드에서는 Flower와 협업 AI의 주요 주제와 기본 아이디어를 " +"설명하고 토론합니다." #: ../../source/index.rst:120 msgid "References" -msgstr "" +msgstr "참조" #: ../../source/index.rst:122 msgid "Information-oriented API reference and other reference material." -msgstr "" +msgstr "정보 지향 API 참조 및 기타 참고 자료." #: ../../source/index.rst:131::1 msgid ":py:obj:`flwr `\\" -msgstr "" +msgstr ":py:obj:`flwr `\\" #: ../../source/index.rst:131::1 flwr:1 of msgid "Flower main package." -msgstr "" +msgstr "Flower 메인 패키지." #: ../../source/index.rst:148 msgid "Contributor docs" -msgstr "" +msgstr "기여자 문서" #: ../../source/index.rst:150 msgid "" -"The Flower community welcomes contributions. The following docs are " -"intended to help along the way." +"The Flower community welcomes contributions. The following docs are intended " +"to help along the way." msgstr "" +"Flower 커뮤니티는 여러분의 기여를 환영합니다. 다음 문서는 그 과정에서 도움을 " +"드리기 위한 문서입니다." #: ../../source/ref-api-cli.rst:2 msgid "Flower CLI reference" -msgstr "" +msgstr "Flower CLI 참조" #: ../../source/ref-api-cli.rst:7 msgid "flower-simulation" -msgstr "" +msgstr "flower 시뮬레이션" #: ../../source/ref-api-cli.rst:17 msgid "flower-superlink" -msgstr "" +msgstr "flower 초연결" #: ../../source/ref-api-cli.rst:27 msgid "flower-client-app" -msgstr "" +msgstr "flower 클라이언트 앱" #: ../../source/ref-api-cli.rst:37 msgid "flower-server-app" -msgstr "" +msgstr "flower 서버 프로그램" #: ../../source/ref-api/flwr.rst:2 msgid "flwr" -msgstr "" +msgstr "flwr" #: ../../source/ref-api/flwr.client.rst:45 ../../source/ref-api/flwr.rst:25 #: ../../source/ref-api/flwr.server.rst:49 msgid "Modules" -msgstr "" +msgstr "Modules" #: ../../source/ref-api/flwr.rst:35::1 msgid ":py:obj:`flwr.client `\\" -msgstr "" +msgstr ":py:obj:`flwr.client `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.client:1 of msgid "Flower client." -msgstr "" +msgstr "Flower 클라이언트." #: ../../source/ref-api/flwr.rst:35::1 msgid ":py:obj:`flwr.common `\\" -msgstr "" +msgstr ":py:obj:`flwr.common `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.common:1 of msgid "Common components shared between server and client." -msgstr "" +msgstr "서버와 클라이언트 간에 공유되는 공통 구성 요소입니다." #: ../../source/ref-api/flwr.rst:35::1 msgid ":py:obj:`flwr.server `\\" -msgstr "" +msgstr ":py:obj:`flwr.server `\\" #: ../../source/ref-api/flwr.rst:35::1 #: ../../source/ref-api/flwr.server.rst:38::1 flwr.server:1 #: flwr.server.server.Server:1 of msgid "Flower server." -msgstr "" +msgstr "Flower 서버." #: ../../source/ref-api/flwr.rst:35::1 msgid ":py:obj:`flwr.simulation `\\" -msgstr "" +msgstr ":py:obj:`flwr.simulation `\\" #: ../../source/ref-api/flwr.rst:35::1 flwr.simulation:1 of msgid "Flower simulation." -msgstr "" +msgstr "Flower 시뮬레이션." #: ../../source/ref-api/flwr.client.rst:2 msgid "client" -msgstr "" +msgstr "클라이언트" #: ../../source/ref-api/flwr.client.mod.rst:13 #: ../../source/ref-api/flwr.client.rst:13 @@ -7777,47 +8250,51 @@ msgstr "" #: ../../source/ref-api/flwr.server.rst:13 #: ../../source/ref-api/flwr.simulation.rst:13 msgid "Functions" -msgstr "" +msgstr "함수" #: ../../source/ref-api/flwr.client.rst:25::1 msgid ":py:obj:`run_client_app `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_client_app `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.supernode.app.run_client_app:1 of msgid "Run Flower client app." -msgstr "" +msgstr "Flower 클라이언트 앱을 실행합니다." #: ../../source/ref-api/flwr.client.rst:25::1 msgid ":py:obj:`run_supernode `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`run_supernode `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.supernode.app.run_supernode:1 of msgid "Run Flower SuperNode." -msgstr "" +msgstr "Flower SuperNode를 실행합니다." #: ../../source/ref-api/flwr.client.rst:25::1 msgid "" ":py:obj:`start_client `\\ \\(\\*\\, " "server\\_address\\[\\, client\\_fn\\, ...\\]\\)" msgstr "" +":py:obj:`start_client `\\ \\(\\*\\, " +"server\\_address\\[\\, client\\_fn\\, ...\\]\\)" #: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_client:1 of msgid "Start a Flower client node which connects to a Flower server." -msgstr "" +msgstr "Flower 서버에 연결되는 Flower 클라이언트 노드를 시작합니다." #: ../../source/ref-api/flwr.client.rst:25::1 msgid "" -":py:obj:`start_numpy_client `\\ \\(\\*\\," -" server\\_address\\, client\\)" +":py:obj:`start_numpy_client `\\ \\(\\*\\, " +"server\\_address\\, client\\)" msgstr "" +":py:obj:`start_numpy_client `\\ \\(\\*\\, " +"server\\_address\\, client\\)" #: ../../source/ref-api/flwr.client.rst:25::1 #: flwr.client.app.start_numpy_client:1 of msgid "Start a Flower NumPyClient which connects to a gRPC server." -msgstr "" +msgstr "gRPC 서버에 연결되는 Flower NumPyClient를 시작합니다." #: ../../source/ref-api/flwr.client.mod.rst:30 #: ../../source/ref-api/flwr.client.rst:27 @@ -7826,51 +8303,51 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:17 #: ../../source/ref-api/flwr.server.workflow.rst:17 msgid "Classes" -msgstr "" +msgstr "클래스" #: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`Client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`Client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client.Client:1 of msgid "Abstract base class for Flower clients." -msgstr "" +msgstr "Flower 클라이언트를 위한 추상 베이스 클래스입니다." #: ../../source/ref-api/flwr.client.rst:34::1 msgid "" -":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, " -"mods\\]\\)" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" msgstr "" +":py:obj:`ClientApp `\\ \\(\\[client\\_fn\\, mods\\]\\)" #: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.client_app.ClientApp:1 of msgid "Flower ClientApp." -msgstr "" +msgstr "Flower ClientApp." #: ../../source/ref-api/flwr.client.rst:34::1 msgid ":py:obj:`NumPyClient `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`NumPyClient `\\ \\(\\)" #: ../../source/ref-api/flwr.client.rst:34::1 #: flwr.client.numpy_client.NumPyClient:1 of msgid "Abstract base class for Flower clients using NumPy." -msgstr "" +msgstr "NumPy를 사용하는 Flower 클라이언트를 위한 추상 베이스 클래스입니다." #: ../../source/ref-api/flwr.client.rst:52::1 msgid ":py:obj:`flwr.client.mod `\\" -msgstr "" +msgstr ":py:obj:`flwr.client.mod `\\" #: ../../source/ref-api/flwr.client.rst:52::1 flwr.client.mod:1 of msgid "Flower Built-in Mods." -msgstr "" +msgstr "Flower 내장 모드." #: flwr.client.client.Client:1 flwr.client.numpy_client.NumPyClient:1 #: flwr.server.client_manager.ClientManager:1 #: flwr.server.driver.driver.Driver:1 flwr.server.strategy.strategy.Strategy:1 #: of msgid "Bases: :py:class:`~abc.ABC`" -msgstr "" +msgstr "Bases: :py:class:`~abc.ABC`" #: ../../source/ref-api/flwr.client.Client.rst:15 #: ../../source/ref-api/flwr.client.ClientApp.rst:15 @@ -7938,78 +8415,82 @@ msgstr "" #: ../../source/ref-api/flwr.server.workflow.SecAggPlusWorkflow.rst:15 #: ../../source/ref-api/flwr.server.workflow.SecAggWorkflow.rst:15 msgid "Methods" -msgstr "" +msgstr "메소드" #: ../../source/ref-api/flwr.client.Client.rst:44::1 msgid ":py:obj:`evaluate `\\ \\(ins\\)" -msgstr "" +msgstr ":py:obj:`evaluate `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.client.Client.evaluate:1 #: flwr.client.numpy_client.NumPyClient.evaluate:1 of msgid "Evaluate the provided parameters using the locally held dataset." -msgstr "" +msgstr "로컬로 보유한 데이터 세트를 사용하여 제공된 매개변수를 평가합니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 msgid ":py:obj:`fit `\\ \\(ins\\)" -msgstr "" +msgstr ":py:obj:`fit `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.fit:1 of msgid "Refine the provided parameters using the locally held dataset." -msgstr "" +msgstr "로컬로 보유한 데이터 세트를 사용하여 제공된 매개변수를 구체화합니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 msgid ":py:obj:`get_context `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`get_context `\\ \\(\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.client.Client.get_context:1 #: flwr.client.numpy_client.NumPyClient.get_context:1 of msgid "Get the run context from this client." -msgstr "" +msgstr "이 클라이언트에서 실행 컨텍스트를 가져옵니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid ":py:obj:`get_parameters `\\ \\(ins\\)" +msgid "" +":py:obj:`get_parameters `\\ \\(ins\\)" msgstr "" +":py:obj:`get_parameters `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.client.Client.get_parameters:1 #: flwr.client.numpy_client.NumPyClient.get_parameters:1 of msgid "Return the current local model parameters." -msgstr "" +msgstr "현재 로컬 모델 파라미터를 반환합니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 -msgid ":py:obj:`get_properties `\\ \\(ins\\)" +msgid "" +":py:obj:`get_properties `\\ \\(ins\\)" msgstr "" +":py:obj:`get_properties `\\ \\(ins\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.get_properties:1 of msgid "Return set of client's properties." -msgstr "" +msgstr "클라이언트의 속성 집합을 반환합니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 msgid ":py:obj:`set_context `\\ \\(context\\)" -msgstr "" +msgstr ":py:obj:`set_context `\\ \\(context\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.client.Client.set_context:1 #: flwr.client.numpy_client.NumPyClient.set_context:1 of msgid "Apply a run context to this client." -msgstr "" +msgstr "이 클라이언트에 실행 컨텍스트를 적용합니다." #: ../../source/ref-api/flwr.client.Client.rst:44::1 msgid ":py:obj:`to_client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`to_client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.Client.rst:44::1 #: flwr.client.client.Client.to_client:1 of msgid "Return client (itself)." -msgstr "" +msgstr "클라이언트(자체)를 반환합니다." #: ../../source/ref-api/flwr.client.Client.rst:46 #: ../../source/ref-api/flwr.client.NumPyClient.rst:46 @@ -8040,11 +8521,11 @@ msgstr "" #: ../../source/ref-api/flwr.server.LegacyContext.rst:25 #: ../../source/ref-api/flwr.server.ServerConfig.rst:25 msgid "Attributes" -msgstr "" +msgstr "속성" #: flwr.client.client.Client.evaluate:1::1 of msgid ":py:obj:`context `\\" -msgstr "" +msgstr ":py:obj:`context `\\" #: ../../source/ref-api/flwr.common.Parameters.rst:2 #: flwr.client.app.start_client flwr.client.app.start_numpy_client @@ -8094,14 +8575,16 @@ msgstr "" #: flwr.simulation.app.start_simulation #: flwr.simulation.run_simulation.run_simulation of msgid "Parameters" -msgstr "" +msgstr "매개변수" #: flwr.client.client.Client.evaluate:3 of msgid "" -"The evaluation instructions containing (global) model parameters received" -" from the server and a dictionary of configuration values used to " -"customize the local evaluation process." +"The evaluation instructions containing (global) model parameters received " +"from the server and a dictionary of configuration values used to customize " +"the local evaluation process." msgstr "" +"서버에서 받은 (전역) 모델 파라미터와 로컬 평가 프로세스를 사용자 지정하는 데 " +"사용되는 구성 값 사전이 포함된 평가 지침입니다." #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -8130,13 +8613,15 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.initialize_parameters #: flwr.simulation.app.start_simulation of msgid "Returns" -msgstr "" +msgstr "반환" #: flwr.client.client.Client.evaluate:8 of msgid "" "The evaluation result containing the loss on the local dataset and other " "details such as the number of local data examples used for evaluation." msgstr "" +"로컬 데이터 세트의 손실 및 평가에 사용된 로컬 데이터 예제 수와 같은 기타 세" +"부 정보가 포함된 평가 결과입니다." #: flwr.client.client.Client.evaluate flwr.client.client.Client.fit #: flwr.client.client.Client.get_parameters @@ -8163,44 +8648,49 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.initialize_parameters #: flwr.simulation.app.start_simulation of msgid "Return type" -msgstr "" +msgstr "반환 타입" #: flwr.client.client.Client.fit:3 of msgid "" -"The training instructions containing (global) model parameters received " -"from the server and a dictionary of configuration values used to " -"customize the local training process." +"The training instructions containing (global) model parameters received from " +"the server and a dictionary of configuration values used to customize the " +"local training process." msgstr "" +"서버에서 받은 (전역) 모델 파라미터와 로컬 학습 프로세스를 사용자 지정하는 데 " +"사용되는 구성 값 사전이 포함된 학습 지침입니다." #: flwr.client.client.Client.fit:8 of msgid "" -"The training result containing updated parameters and other details such " -"as the number of local training examples used for training." +"The training result containing updated parameters and other details such as " +"the number of local training examples used for training." msgstr "" +"업데이트된 매개변수와 훈련에 사용된 로컬 훈련 예제 수와 같은 기타 세부 정보" +"가 포함된 훈련 결과입니다." #: flwr.client.client.Client.get_parameters:3 of msgid "" "The get parameters instructions received from the server containing a " "dictionary of configuration values." msgstr "" +"구성 값 dictionary이 포함된 서버에서 받은 매개변수 가져오기 명령어입니다." #: flwr.client.client.Client.get_parameters:7 of msgid "The current local model parameters." -msgstr "" +msgstr "현재 로컬 모델 파라미터입니다." #: flwr.client.client.Client.get_properties:3 of msgid "" "The get properties instructions received from the server containing a " "dictionary of configuration values." -msgstr "" +msgstr "구성 값 dictionary이 포함된 서버로부터 받은 속성 가져오기 명령입니다." #: flwr.client.client.Client.get_properties:7 of msgid "The current client properties." -msgstr "" +msgstr "현재 클라이언트 속성입니다." #: ../../source/ref-api/flwr.client.ClientApp.rst:2 msgid "ClientApp" -msgstr "" +msgstr "클라이언트앱" #: flwr.client.client_app.ClientApp:1 flwr.client.mod.localdp_mod.LocalDpMod:1 #: flwr.common.constant.MessageType:1 flwr.common.constant.MessageTypeLegacy:1 @@ -8221,7 +8711,7 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:1 #: of msgid "Bases: :py:class:`object`" -msgstr "" +msgstr "Bases: :py:class:`object`" #: flwr.client.app.start_client:41 flwr.client.app.start_numpy_client:36 #: flwr.client.client_app.ClientApp:4 @@ -8236,112 +8726,127 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:14 #: of msgid "Examples" -msgstr "" +msgstr "예시" #: flwr.client.client_app.ClientApp:5 of msgid "" "Assuming a typical `Client` implementation named `FlowerClient`, you can " "wrap it in a `ClientApp` as follows:" msgstr "" +"일반적인 `Client` 구현의 이름이 `FlowerClient`라고 가정하면, 다음과 같이 " +"`ClientApp`으로 래핑할 수 있습니다:" #: flwr.client.client_app.ClientApp:16 of msgid "" -"If the above code is in a Python module called `client`, it can be " -"started as follows:" +"If the above code is in a Python module called `client`, it can be started " +"as follows:" msgstr "" +"위의 코드가 'client'라는 Python 모듈에 있는 경우 다음과 같이 시작할 수 있습니" +"다:" #: flwr.client.client_app.ClientApp:21 of msgid "" -"In this `client:app` example, `client` refers to the Python module " -"`client.py` in which the previous code lives in and `app` refers to the " -"global attribute `app` that points to an object of type `ClientApp`." +"In this `client:app` example, `client` refers to the Python module `client." +"py` in which the previous code lives in and `app` refers to the global " +"attribute `app` that points to an object of type `ClientApp`." msgstr "" +"이 `client:app` 예제에서 `client`는 이전 코드가 있는 Python 모듈 `client.py`" +"를 가리키고 `app`는 `ClientApp` 유형의 객체를 가리키는 전역 속성 `app`을 가리" +"킵니다." #: flwr.client.client_app.ClientApp.evaluate:1::1 of msgid ":py:obj:`evaluate `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`evaluate `\\ \\(\\)" #: flwr.client.client_app.ClientApp.evaluate:1 #: flwr.client.client_app.ClientApp.evaluate:1::1 of msgid "Return a decorator that registers the evaluate fn with the client app." -msgstr "" +msgstr "클라이언트 앱에 평가함수를 등록하는 데코레이터를 반환합니다." #: flwr.client.client_app.ClientApp.evaluate:1::1 of msgid ":py:obj:`query `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`query `\\ \\(\\)" #: flwr.client.client_app.ClientApp.evaluate:1::1 #: flwr.client.client_app.ClientApp.query:1 of msgid "Return a decorator that registers the query fn with the client app." -msgstr "" +msgstr "클라이언트 앱에 query fn을 등록하는 데코레이터를 반환합니다." #: flwr.client.client_app.ClientApp.evaluate:1::1 of msgid ":py:obj:`train `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`train `\\ \\(\\)" #: flwr.client.client_app.ClientApp.evaluate:1::1 #: flwr.client.client_app.ClientApp.train:1 of msgid "Return a decorator that registers the train fn with the client app." -msgstr "" +msgstr "클라이언트 앱에 train fn을 등록하는 데코레이터를 반환합니다." #: ../../source/ref-api/flwr.client.NumPyClient.rst:2 msgid "NumPyClient" -msgstr "" +msgstr "NumPyClient" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" ":py:obj:`evaluate `\\ \\(parameters\\, " "config\\)" msgstr "" +":py:obj:`evaluate `\\ \\(parameters\\, " +"config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 -msgid ":py:obj:`fit `\\ \\(parameters\\, config\\)" +msgid "" +":py:obj:`fit `\\ \\(parameters\\, config\\)" msgstr "" +":py:obj:`fit `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.fit:1 of msgid "Train the provided parameters using the locally held dataset." -msgstr "" +msgstr "로컬로 보유한 데이터 세트를 사용하여 제공된 파라미터를 학습합니다." #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid ":py:obj:`get_context `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`get_context `\\ \\(\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" ":py:obj:`get_parameters `\\ " "\\(config\\)" msgstr "" +":py:obj:`get_parameters `\\ " +"\\(config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" ":py:obj:`get_properties `\\ " "\\(config\\)" msgstr "" +":py:obj:`get_properties `\\ " +"\\(config\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.get_properties:1 of msgid "Return a client's set of properties." -msgstr "" +msgstr "클라이언트의 속성 집합을 반환합니다." #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid "" -":py:obj:`set_context `\\ " -"\\(context\\)" +":py:obj:`set_context `\\ \\(context\\)" msgstr "" +":py:obj:`set_context `\\ \\(context\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 msgid ":py:obj:`to_client `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`to_client `\\ \\(\\)" #: ../../source/ref-api/flwr.client.NumPyClient.rst:44::1 #: flwr.client.numpy_client.NumPyClient.to_client:1 of msgid "Convert to object to Client type and return it." -msgstr "" +msgstr "객체를 클라이언트 유형으로 변환하고 반환합니다." #: flwr.client.numpy_client.NumPyClient.evaluate:1::1 of msgid ":py:obj:`context `\\" -msgstr "" +msgstr ":py:obj:`context `\\" #: flwr.client.numpy_client.NumPyClient.evaluate:3 #: flwr.client.numpy_client.NumPyClient.fit:3 @@ -8351,262 +8856,311 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.configure_fit:5 #: flwr.server.strategy.strategy.Strategy.evaluate:8 of msgid "The current (global) model parameters." -msgstr "" +msgstr "현재(전역) 모델 매개변수입니다." #: flwr.client.numpy_client.NumPyClient.evaluate:5 of msgid "" -"Configuration parameters which allow the server to influence evaluation " -"on the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to influence the number of examples " -"used for evaluation." +"Configuration parameters which allow the server to influence evaluation on " +"the client. It can be used to communicate arbitrary values from the server " +"to the client, for example, to influence the number of examples used for " +"evaluation." msgstr "" +"서버가 클라이언트의 평가에 영향을 줄 수 있는 구성 매개변수입니다. 예를 들어 " +"평가에 사용되는 예제 수에 영향을 주기 위해 서버에서 클라이언트로 임의의 값을 " +"전달하는 데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" "* **loss** (*float*) -- The evaluation loss of the model on the local " "dataset. * **num_examples** (*int*) -- The number of examples used for " "evaluation. * **metrics** (*Dict[str, Scalar]*) -- A dictionary mapping " -"arbitrary string keys to values of type bool, bytes, float, int, or " -"str. It can be used to communicate arbitrary values back to the server." +"arbitrary string keys to values of type bool, bytes, float, int, or str. " +"It can be used to communicate arbitrary values back to the server." msgstr "" +"* **loss** (*float*) - 로컬 데이터 세트에서 모델의 평가 손실입니다. * " +"**num_examples** (*int*) -- 평가에 사용된 예제 수입니다. * **metrics** " +"(*Dict[str, Scalar]*) -- 임의의 문자열 키를 부울, 바이트, float, int 또는 " +"str 유형의 값에 매핑하는 dictionary입니다. 임의의 값을 서버에 다시 전달하는 " +"데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.evaluate:11 of msgid "" -"**loss** (*float*) -- The evaluation loss of the model on the local " -"dataset." -msgstr "" +"**loss** (*float*) -- The evaluation loss of the model on the local dataset." +msgstr "**loss** (*float*) -- 로컬 데이터 세트에서 모델의 평가 손실입니다." #: flwr.client.numpy_client.NumPyClient.evaluate:12 of msgid "**num_examples** (*int*) -- The number of examples used for evaluation." -msgstr "" +msgstr "**num_examples** (*int*) - 평가에 사용된 예제 수입니다." #: flwr.client.numpy_client.NumPyClient.evaluate:13 #: flwr.client.numpy_client.NumPyClient.fit:13 of msgid "" -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can be " -"used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" +"**metrics** (*Dict[str, Scalar]*) - 임의의 문자열 키를 bool, bytes, float, " +"int 또는 str 타입의 값에 매핑하는 dictionary입니다. 임의의 값을 서버에 다시 " +"전달하는 데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.evaluate:19 of msgid "" -"The previous return type format (int, float, float) and the extended " -"format (int, float, float, Dict[str, Scalar]) have been deprecated and " -"removed since Flower 0.19." +"The previous return type format (int, float, float) and the extended format " +"(int, float, float, Dict[str, Scalar]) have been deprecated and removed " +"since Flower 0.19." msgstr "" +"이전 반환 유형 형식(int, float, float)과 확장 형식(int, float, float, " +"Dict[str, Scalar])은 Flower 0.19부터 더 이상 사용되지 않으며 제거되었습니다." #: flwr.client.numpy_client.NumPyClient.fit:5 of msgid "" -"Configuration parameters which allow the server to influence training on " -"the client. It can be used to communicate arbitrary values from the " -"server to the client, for example, to set the number of (local) training " -"epochs." +"Configuration parameters which allow the server to influence training on the " +"client. It can be used to communicate arbitrary values from the server to " +"the client, for example, to set the number of (local) training epochs." msgstr "" +"서버가 클라이언트의 훈련에 영향을 줄 수 있는 구성 매개변수입니다. 예를 들어 " +"(로컬) 트레이닝 에포크 수를 설정하는 등 서버에서 클라이언트로 임의의 값을 전" +"달하는 데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "" "* **parameters** (*NDArrays*) -- The locally updated model parameters. * " "**num_examples** (*int*) -- The number of examples used for training. * " -"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary " -"string keys to values of type bool, bytes, float, int, or str. It can " -"be used to communicate arbitrary values back to the server." +"**metrics** (*Dict[str, Scalar]*) -- A dictionary mapping arbitrary string " +"keys to values of type bool, bytes, float, int, or str. It can be used to " +"communicate arbitrary values back to the server." msgstr "" +"* **parameters** (*NDArrays*) - 로컬로 업데이트된 모델 파라미터입니다. * " +"**num_examples** (*int*) -- 학습에 사용된 예제 수입니다. * **metrics** " +"(*Dict[str, Scalar]*) - 임의의 문자열 키를 bool, bytes, float, int,또는 str " +"타입의 값에 매핑하는 dictionary입니다. 임의의 값을 서버에 다시 전달하는 데 사" +"용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.fit:11 of msgid "**parameters** (*NDArrays*) -- The locally updated model parameters." -msgstr "" +msgstr "**parameters** (*NDArrays*) - 로컬로 업데이트된 모델 파라미터입니다." #: flwr.client.numpy_client.NumPyClient.fit:12 of msgid "**num_examples** (*int*) -- The number of examples used for training." -msgstr "" +msgstr "**num_examples** (*int*) - 트레이닝에 사용된 예제 수입니다." #: flwr.client.numpy_client.NumPyClient.get_parameters:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which parameters are needed along with some Scalar " -"attributes." +"Configuration parameters requested by the server. This can be used to tell " +"the client which parameters are needed along with some Scalar attributes." msgstr "" +"서버에서 요청한 구성 매개변수입니다. 이는 일부 스칼라 속성과 함께 어떤 매개변" +"수가 필요한지 클라이언트에게 알려주는 데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.get_parameters:8 of -msgid "**parameters** -- The local model parameters as a list of NumPy ndarrays." -msgstr "" +msgid "" +"**parameters** -- The local model parameters as a list of NumPy ndarrays." +msgstr "**parameters** -- 로컬 모델 파라미터를 NumPy 배열 목록으로 표시합니다." #: flwr.client.numpy_client.NumPyClient.get_properties:3 of msgid "" -"Configuration parameters requested by the server. This can be used to " -"tell the client which properties are needed along with some Scalar " -"attributes." +"Configuration parameters requested by the server. This can be used to tell " +"the client which properties are needed along with some Scalar attributes." msgstr "" +"서버에서 요청하는 구성 매개변수입니다. 이는 일부 스칼라 속성과 함께 어떤 속성" +"이 필요한지 클라이언트에게 알려주는 데 사용할 수 있습니다." #: flwr.client.numpy_client.NumPyClient.get_properties:8 of msgid "" -"**properties** -- A dictionary mapping arbitrary string keys to values of" -" type bool, bytes, float, int, or str. It can be used to communicate " +"**properties** -- A dictionary mapping arbitrary string keys to values of " +"type bool, bytes, float, int, or str. It can be used to communicate " "arbitrary property values back to the server." msgstr "" +"**properties** -- 임의의 문자열 키를 bool, bytes, float, int 또는 str 타입의 " +"값에 매핑하는 dictionary입니다. 임의의 속성 값을 서버에 다시 전달하는 데 사용" +"할 수 있습니다." #: ../../source/ref-api/flwr.client.mod.rst:2 msgid "mod" -msgstr "" +msgstr "mod" #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" ":py:obj:`adaptiveclipping_mod `\\ " "\\(msg\\, ctxt\\, call\\_next\\)" msgstr "" +":py:obj:`adaptiveclipping_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:1 of msgid "Client-side adaptive clipping modifier." -msgstr "" +msgstr "클라이언트 측 적응형 클리핑 수정자." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" -":py:obj:`fixedclipping_mod `\\ " -"\\(msg\\, ctxt\\, call\\_next\\)" +":py:obj:`fixedclipping_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" msgstr "" +":py:obj:`fixedclipping_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:1 of msgid "Client-side fixed clipping modifier." -msgstr "" +msgstr "클라이언트 측 고정 클리핑 수정자." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" -msgstr "" +msgstr ":py:obj:`make_ffn `\\ \\(ffn\\, mods\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.utils.make_ffn:1 of msgid "." -msgstr "" +msgstr "." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" ":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " "call\\_next\\)" msgstr "" +":py:obj:`secagg_mod `\\ \\(msg\\, ctxt\\, " +"call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.secure_aggregation.secagg_mod.secagg_mod:1 of -msgid "Handle incoming message and return results, following the SecAgg protocol." -msgstr "" +msgid "" +"Handle incoming message and return results, following the SecAgg protocol." +msgstr "SecAgg 프로토콜에 따라 수신 메시지를 처리하고 결과를 반환합니다." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" ":py:obj:`secaggplus_mod `\\ \\(msg\\, " "ctxt\\, call\\_next\\)" msgstr "" +":py:obj:`secaggplus_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.secure_aggregation.secaggplus_mod.secaggplus_mod:1 of msgid "" -"Handle incoming message and return results, following the SecAgg+ " -"protocol." -msgstr "" +"Handle incoming message and return results, following the SecAgg+ protocol." +msgstr "SecAgg+ 프로토콜에 따라 수신 메시지를 처리하고 결과를 반환합니다." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" -":py:obj:`message_size_mod `\\ \\(msg\\," -" ctxt\\, call\\_next\\)" +":py:obj:`message_size_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" msgstr "" +":py:obj:`message_size_mod `\\ \\(msg\\, " +"ctxt\\, call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.comms_mods.message_size_mod:1 of msgid "Message size mod." -msgstr "" +msgstr "메시지 크기 수정." #: ../../source/ref-api/flwr.client.mod.rst:28::1 msgid "" ":py:obj:`parameters_size_mod `\\ " "\\(msg\\, ctxt\\, call\\_next\\)" msgstr "" +":py:obj:`parameters_size_mod `\\ " +"\\(msg\\, ctxt\\, call\\_next\\)" #: ../../source/ref-api/flwr.client.mod.rst:28::1 #: flwr.client.mod.comms_mods.parameters_size_mod:1 of msgid "Parameters size mod." -msgstr "" +msgstr "매개변수 크기 mod." #: ../../source/ref-api/flwr.client.mod.rst:35::1 msgid "" -":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\," -" sensitivity\\, ...\\)" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\, " +"sensitivity\\, ...\\)" msgstr "" +":py:obj:`LocalDpMod `\\ \\(clipping\\_norm\\, " +"sensitivity\\, ...\\)" #: ../../source/ref-api/flwr.client.mod.rst:35::1 #: flwr.client.mod.localdp_mod.LocalDpMod:1 of msgid "Modifier for local differential privacy." -msgstr "" +msgstr "로컬 차분 프라이버시를 위한 수정자." #: ../../source/ref-api/flwr.client.mod.LocalDpMod.rst:2 msgid "LocalDpMod" -msgstr "" +msgstr "LocalDpMod" #: flwr.client.mod.localdp_mod.LocalDpMod:3 of msgid "" -"This mod clips the client model updates and adds noise to the params " -"before sending them to the server." +"This mod clips the client model updates and adds noise to the params before " +"sending them to the server." msgstr "" +"이 모드는 클라이언트 모델 업데이트를 클립하고 서버로 보내기 전에 파라미터에 " +"노이즈를 추가합니다." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:12 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:10 #: flwr.client.mod.localdp_mod.LocalDpMod:6 of msgid "It operates on messages of type `MessageType.TRAIN`." -msgstr "" +msgstr "이 함수는 `MessageType.TRAIN` 유형의 메시지에 대해 작동합니다." #: flwr.client.mod.localdp_mod.LocalDpMod:8 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:15 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:8 #: of msgid "The value of the clipping norm." -msgstr "" +msgstr "클리핑 기준값입니다." #: flwr.client.mod.localdp_mod.LocalDpMod:10 of msgid "The sensitivity of the client model." -msgstr "" +msgstr "클라이언트 모델의 민감도입니다." #: flwr.client.mod.localdp_mod.LocalDpMod:12 of msgid "" "The privacy budget. Smaller value of epsilon indicates a higher level of " "privacy protection." msgstr "" +"개인정보 보호 예산. 엡실론 값이 작을수록 개인정보 보호 수준이 높음을 나타냅니" +"다." #: flwr.client.mod.localdp_mod.LocalDpMod:15 of msgid "" -"The failure probability. The probability that the privacy mechanism fails" -" to provide the desired level of privacy. A smaller value of delta " -"indicates a stricter privacy guarantee." +"The failure probability. The probability that the privacy mechanism fails to " +"provide the desired level of privacy. A smaller value of delta indicates a " +"stricter privacy guarantee." msgstr "" +"실패 확률입니다. 프라이버시 메커니즘이 원하는 수준의 프라이버시를 제공하지 못" +"할 확률입니다. 델타 값이 작을수록 프라이버시가 더 엄격하게 보장된다는 의미입" +"니다." #: flwr.client.mod.localdp_mod.LocalDpMod:23 of -msgid "Create an instance of the local DP mod and add it to the client-side mods:" -msgstr "" +msgid "" +"Create an instance of the local DP mod and add it to the client-side mods:" +msgstr "로컬 DP 모드의 인스턴스를 생성하고 클라이언트 측 모드에 추가합니다:" #: ../../source/ref-api/flwr.client.mod.adaptiveclipping_mod.rst:2 msgid "adaptiveclipping\\_mod" -msgstr "" +msgstr "adaptiveclipping\\_mod" #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:3 of msgid "" "This mod needs to be used with the " -"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy " -"wrapper." +"DifferentialPrivacyClientSideAdaptiveClipping server-side strategy wrapper." msgstr "" +"이 모드는 서버 측 전략 래퍼인 차분 프라이버시 클라이언트 측 적응형 클리핑과 " +"함께 사용해야 합니다." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:6 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:6 of msgid "The wrapper sends the clipping_norm value to the client." -msgstr "" +msgstr "래퍼는 클라이언트에 clipping_norm 값을 전송합니다." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:8 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:8 of -msgid "This mod clips the client model updates before sending them to the server." -msgstr "" +msgid "" +"This mod clips the client model updates before sending them to the server." +msgstr "이 모드는 클라이언트 모델 업데이트를 서버로 보내기 전에 클립합니다." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:10 of msgid "" "It also sends KEY_NORM_BIT to the server for computing the new clipping " "value." -msgstr "" +msgstr "또한 새 클리핑 값을 계산하기 위해 서버로 KEY_NORM_BIT을 전송합니다." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:15 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:13 @@ -8615,240 +9169,280 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:60 #: of msgid "Notes" -msgstr "" +msgstr "참고" #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:16 #: flwr.client.mod.centraldp_mods.fixedclipping_mod:14 of msgid "Consider the order of mods when using multiple." -msgstr "" +msgstr "여러 개를 사용할 때는 모드의 순서를 고려하세요." #: flwr.client.mod.centraldp_mods.adaptiveclipping_mod:18 of -msgid "Typically, adaptiveclipping_mod should be the last to operate on params." +msgid "" +"Typically, adaptiveclipping_mod should be the last to operate on params." msgstr "" +"일반적으로 adaptiveclipping_mod는 매개변수에서 가장 마지막으로 작동해야 합니" +"다." #: ../../source/ref-api/flwr.client.mod.fixedclipping_mod.rst:2 msgid "fixedclipping\\_mod" -msgstr "" +msgstr "fixedclipping\\_mod" #: flwr.client.mod.centraldp_mods.fixedclipping_mod:3 of msgid "" "This mod needs to be used with the " "DifferentialPrivacyClientSideFixedClipping server-side strategy wrapper." msgstr "" +"이 모드는 서버 측 전략 래퍼인 DifferentialPrivacyClientSideFixedClipping과 함" +"께 사용해야 합니다." #: flwr.client.mod.centraldp_mods.fixedclipping_mod:16 of msgid "Typically, fixedclipping_mod should be the last to operate on params." msgstr "" +"일반적으로 fixedclipping_mod는 매개변수에서 가장 마지막으로 작동해야 합니다." #: ../../source/ref-api/flwr.client.mod.make_ffn.rst:2 msgid "make\\_ffn" -msgstr "" +msgstr "make\\_ffn" #: ../../source/ref-api/flwr.client.mod.message_size_mod.rst:2 msgid "message\\_size\\_mod" -msgstr "" +msgstr "message\\_size\\_mod" #: flwr.client.mod.comms_mods.message_size_mod:3 of msgid "This mod logs the size in bytes of the message being transmited." -msgstr "" +msgstr "이 모드는 전송되는 메시지의 크기를 바이트 단위로 기록합니다." #: ../../source/ref-api/flwr.client.mod.parameters_size_mod.rst:2 msgid "parameters\\_size\\_mod" -msgstr "" +msgstr "parameters\\_size\\_mod" #: flwr.client.mod.comms_mods.parameters_size_mod:3 of msgid "" -"This mod logs the number of parameters transmitted in the message as well" -" as their size in bytes." +"This mod logs the number of parameters transmitted in the message as well as " +"their size in bytes." msgstr "" +"이 모드는 메시지에서 전송된 매개변수의 수와 그 크기를 바이트 단위로 기록합니" +"다." #: ../../source/ref-api/flwr.client.mod.secagg_mod.rst:2 msgid "secagg\\_mod" -msgstr "" +msgstr "secagg\\_mod" #: ../../source/ref-api/flwr.client.mod.secaggplus_mod.rst:2 msgid "secaggplus\\_mod" -msgstr "" +msgstr "secaggplus\\_mod" #: ../../source/ref-api/flwr.client.run_client_app.rst:2 msgid "run\\_client\\_app" -msgstr "" +msgstr "run\\_client\\_app" #: ../../source/ref-api/flwr.client.run_supernode.rst:2 msgid "run\\_supernode" -msgstr "" +msgstr "run\\_supernode" #: ../../source/ref-api/flwr.client.start_client.rst:2 msgid "start\\_client" -msgstr "" +msgstr "start\\_client" #: flwr.client.app.start_client:3 flwr.client.app.start_numpy_client:9 of msgid "" "The IPv4 or IPv6 address of the server. If the Flower server runs on the " -"same machine on port 8080, then `server_address` would be " -"`\"[::]:8080\"`." +"same machine on port 8080, then `server_address` would be `\"[::]:8080\"`." msgstr "" +"서버의 IPv4 또는 IPv6 주소입니다. Flower 서버가 포트 8080의 동일한 컴퓨터에" +"서 실행되는 경우 `서버_주소`는 `\"[::]:8080\"`이 됩니다." #: flwr.client.app.start_client:7 of msgid "A callable that instantiates a Client. (default: None)" -msgstr "" +msgstr "클라이언트를 인스턴스화하는 호출 가능 항목입니다. (기본값: None)" #: flwr.client.app.start_client:9 of msgid "" -"An implementation of the abstract base class `flwr.client.Client` " -"(default: None)" -msgstr "" +"An implementation of the abstract base class `flwr.client.Client` (default: " +"None)" +msgstr "추상 베이스 클래스 `flwr.client.Client`의 구현(기본값: None)" #: flwr.client.app.start_client:12 flwr.client.app.start_numpy_client:15 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" server. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower server needs to be started with the same value (see " -"`flwr.server.start_server`), otherwise it will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"server. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"server needs to be started with the same value (see `flwr.server." +"start_server`), otherwise it will not know about the increased limit and " +"block larger messages." msgstr "" +"Flower 서버와 교환할 수 있는 gRPC 메시지의 최대 길이입니다. 기본값은 대부분" +"의 모델에 충분합니다. 매우 큰 모델을 훈련하는 사용자는 이 값을 늘려야 할 수" +"도 있습니다. Flower 서버는 동일한 값으로 시작해야 하며(`flwr.server." +"start_server` 참조), 그렇지 않으면 증가된 제한을 알지 못해 더 큰 메시지를 차" +"단합니다." #: flwr.client.app.start_client:19 flwr.client.app.start_numpy_client:22 of msgid "" "The PEM-encoded root certificates as a byte string or a path string. If " -"provided, a secure connection using the certificates will be established " -"to an SSL-enabled Flower server." +"provided, a secure connection using the certificates will be established to " +"an SSL-enabled Flower server." msgstr "" +"바이트 문자열 또는 경로 문자열로 PEM 인코딩된 루트 인증서. 제공하면 인증서를 " +"사용하여 SSL이 활성화된 Flower 서버에 보안 연결이 설정됩니다." #: flwr.client.app.start_client:23 flwr.client.app.start_numpy_client:26 of msgid "" -"Starts an insecure gRPC connection when True. Enables HTTPS connection " -"when False, using system certificates if `root_certificates` is None." +"Starts an insecure gRPC connection when True. Enables HTTPS connection when " +"False, using system certificates if `root_certificates` is None." msgstr "" +"True일 경우 안전하지 않은 gRPC 연결을 시작합니다. root_certificates`가 None" +"인 경우 시스템 인증서를 사용하여 False일 때 HTTPS 연결을 활성화합니다." #: flwr.client.app.start_client:26 flwr.client.app.start_numpy_client:29 of msgid "" "Configure the transport layer. Allowed values: - 'grpc-bidi': gRPC, " -"bidirectional streaming - 'grpc-rere': gRPC, request-response " -"(experimental) - 'rest': HTTP (experimental)" +"bidirectional streaming - 'grpc-rere': gRPC, request-response (experimental) " +"- 'rest': HTTP (experimental)" msgstr "" +"전송 계층을 구성합니다. 허용되는 값입니다: - 'grpc-bidi': gRPC, 양방향 스트리" +"밍 - 'grpc-rere': gRPC, 요청-응답(실험적) - 'rest': HTTP(실험적)" #: flwr.client.app.start_client:31 of msgid "" "The maximum number of times the client will try to connect to the server " -"before giving up in case of a connection error. If set to None, there is " -"no limit to the number of tries." +"before giving up in case of a connection error. If set to None, there is no " +"limit to the number of tries." msgstr "" +"연결 오류 발생 시 클라이언트가 서버 연결을 포기하기 전에 시도하는 최대 횟수입" +"니다. None으로 설정하면 시도 횟수에 제한이 없습니다." #: flwr.client.app.start_client:35 of msgid "" -"The maximum duration before the client stops trying to connect to the " -"server in case of connection error. If set to None, there is no limit to " -"the total time." +"The maximum duration before the client stops trying to connect to the server " +"in case of connection error. If set to None, there is no limit to the total " +"time." msgstr "" +"연결 오류 발생 시 클라이언트가 서버에 대한 연결을 시도하지 않는 최대 기간입니" +"다. None으로 설정하면 총 시간에는 제한이 없습니다." #: flwr.client.app.start_client:42 flwr.client.app.start_numpy_client:37 of msgid "Starting a gRPC client with an insecure server connection:" -msgstr "" +msgstr "안전하지 않은 서버 연결로 gRPC 클라이언트 시작하기:" #: flwr.client.app.start_client:49 flwr.client.app.start_numpy_client:44 of msgid "Starting an SSL-enabled gRPC client using system certificates:" -msgstr "" +msgstr "시스템 인증서를 사용하여 SSL 사용 gRPC 클라이언트를 시작합니다:" #: flwr.client.app.start_client:60 flwr.client.app.start_numpy_client:52 of msgid "Starting an SSL-enabled gRPC client using provided certificates:" -msgstr "" +msgstr "제공된 인증서를 사용하여 SSL 지원 gRPC 클라이언트를 시작합니다:" #: ../../source/ref-api/flwr.client.start_numpy_client.rst:2 msgid "start\\_numpy\\_client" -msgstr "" +msgstr "start\\_numpy\\_client" #: flwr.client.app.start_numpy_client:5 of msgid "" -"This function is deprecated since 1.7.0. Use " -":code:`flwr.client.start_client` instead and first convert your " -":code:`NumPyClient` to type :code:`flwr.client.Client` by executing its " -":code:`to_client()` method." +"This function is deprecated since 1.7.0. Use :code:`flwr.client." +"start_client` instead and first convert your :code:`NumPyClient` to type :" +"code:`flwr.client.Client` by executing its :code:`to_client()` method." msgstr "" +"이 함수는 1.7.0부터 더 이상 사용되지 않습니다. 대신 :code:`flwr.client." +"start_client`를 사용하고 먼저 :code:`to_client()` 메서드를 실행하여 :code:" +"`NumPyClient`를 :code:`flwr.client.Client` 유형으로 변환합니다." #: flwr.client.app.start_numpy_client:13 of msgid "An implementation of the abstract base class `flwr.client.NumPyClient`." -msgstr "" +msgstr "추상 베이스 클래스 `flwr.client.NumPyClient`의 구현입니다." #: ../../source/ref-api/flwr.common.rst:2 msgid "common" -msgstr "" +msgstr "공통" #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`array_from_numpy `\\ \\(ndarray\\)" +msgid "" +":py:obj:`array_from_numpy `\\ \\(ndarray\\)" msgstr "" +":py:obj:`array_from_numpy `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.record.conversion_utils.array_from_numpy:1 of msgid "Create Array from NumPy ndarray." -msgstr "" +msgstr "NumPy에서 배열을 만듭니다." #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" +msgid "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.bytes_to_ndarray:1 of msgid "Deserialize NumPy ndarray from bytes." -msgstr "" +msgstr "바이트에서 NumPy를 역직렬화합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid "" ":py:obj:`configure `\\ \\(identifier\\[\\, " "filename\\, host\\]\\)" msgstr "" +":py:obj:`configure `\\ \\(identifier\\[\\, " +"filename\\, host\\]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.logger.configure:1 of msgid "Configure logging to file and/or remote log server." -msgstr "" +msgstr "파일 및/또는 원격 로그 서버에 로깅을 구성합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid "" ":py:obj:`event `\\ \\(event\\_type\\[\\, " "event\\_details\\]\\)" msgstr "" +":py:obj:`event `\\ \\(event\\_type\\[\\, " +"event\\_details\\]\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.telemetry.event:1 of msgid "Submit create_event to ThreadPoolExecutor to avoid blocking." -msgstr "" +msgstr "차단을 피하기 위해 create_event를 ThreadPoolExecutor에 제출합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid "" ":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " "\\*\\*kwargs\\)" msgstr "" +":py:obj:`log `\\ \\(level\\, msg\\, \\*args\\, " +"\\*\\*kwargs\\)" #: ../../source/ref-api/flwr.common.rst:30::1 logging.Logger.log:1 #: of msgid "Log 'msg % args' with the integer severity 'level'." -msgstr "" +msgstr "정수 심각도 'level'과 함께 'msg % args'를 기록합니다." #: ../../source/ref-api/flwr.common.rst:30::1 -msgid ":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" +msgid "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarray_to_bytes:1 of msgid "Serialize NumPy ndarray to bytes." -msgstr "" +msgstr "NumPy와 배열을 바이트열로 직렬화합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid ":py:obj:`now `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`now `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.date.now:1 of msgid "Construct a datetime from time.time() with time zone set to UTC." -msgstr "" +msgstr "표준 시간대를 UTC로 설정하여 time.time()에서 날짜 시간을 생성합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid "" ":py:obj:`ndarrays_to_parameters `\\ " "\\(ndarrays\\)" msgstr "" +":py:obj:`ndarrays_to_parameters `\\ " +"\\(ndarrays\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.ndarrays_to_parameters:1 @@ -8856,1333 +9450,1485 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.ndarrays_to_parameters:1 #: of msgid "Convert NumPy ndarrays to parameters object." -msgstr "" +msgstr "NumPy 배열을 매개변수 객체로 변환합니다." #: ../../source/ref-api/flwr.common.rst:30::1 msgid "" ":py:obj:`parameters_to_ndarrays `\\ " "\\(parameters\\)" msgstr "" +":py:obj:`parameters_to_ndarrays `\\ " +"\\(parameters\\)" #: ../../source/ref-api/flwr.common.rst:30::1 #: flwr.common.parameter.parameters_to_ndarrays:1 of msgid "Convert parameters object to NumPy ndarrays." -msgstr "" +msgstr "매개변수 객체를 NumPy 배열로 변환합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, " -"data\\)" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" msgstr "" +":py:obj:`Array `\\ \\(dtype\\, shape\\, stype\\, data\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.Array:1 of msgid "Array type." -msgstr "" +msgstr "배열 유형." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`ClientMessage `\\ " "\\(\\[get\\_properties\\_res\\, ...\\]\\)" msgstr "" +":py:obj:`ClientMessage `\\ " +"\\(\\[get\\_properties\\_res\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ClientMessage:1 of msgid "ClientMessage is a container used to hold one result message." msgstr "" +"ClientMessage는 하나의 결과 메시지를 저장하는 데 사용되는 컨테이너입니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`Code `\\ \\(value\\)" -msgstr "" +msgstr ":py:obj:`Code `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Code:1 of msgid "Client status codes." -msgstr "" +msgstr "클라이언트 상태 코드." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`ConfigsRecord `\\ " "\\(\\[configs\\_dict\\, keep\\_input\\]\\)" msgstr "" +":py:obj:`ConfigsRecord `\\ " +"\\(\\[configs\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "Configs record." -msgstr "" +msgstr "레코드를 설정합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`Context `\\ \\(state\\)" -msgstr "" +msgstr ":py:obj:`Context `\\ \\(state\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.context.Context:1 of msgid "State of your run." -msgstr "" +msgstr "실행 상태." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`DisconnectRes `\\ \\(reason\\)" -msgstr "" +msgstr ":py:obj:`DisconnectRes `\\ \\(reason\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.DisconnectRes:1 of msgid "DisconnectRes message from client to server." -msgstr "" +msgstr "클라이언트에서 서버로 연결 해제 메시지를 보냅니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`EvaluateIns `\\ \\(parameters\\, " -"config\\)" +":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" msgstr "" +":py:obj:`EvaluateIns `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.EvaluateIns:1 of msgid "Evaluate instructions for a client." -msgstr "" +msgstr "클라이언트에 대한 지침을 평가합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`EvaluateRes `\\ \\(status\\, loss\\, " "num\\_examples\\, metrics\\)" msgstr "" +":py:obj:`EvaluateRes `\\ \\(status\\, loss\\, " +"num\\_examples\\, metrics\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.EvaluateRes:1 of msgid "Evaluate response from a client." -msgstr "" +msgstr "클라이언트의 응답을 평가합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`EventType `\\ \\(value\\)" -msgstr "" +msgstr ":py:obj:`EventType `\\ \\(value\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.telemetry.EventType:1 of msgid "Types of telemetry events." -msgstr "" +msgstr "원격 분석 이벤트의 유형." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`FitIns `\\ \\(parameters\\, config\\)" -msgstr "" +msgstr ":py:obj:`FitIns `\\ \\(parameters\\, config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.FitIns:1 of msgid "Fit instructions for a client." -msgstr "" +msgstr "고객을 위한 맞춤 지침." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`FitRes `\\ \\(status\\, parameters\\, " "num\\_examples\\, metrics\\)" msgstr "" +":py:obj:`FitRes `\\ \\(status\\, parameters\\, " +"num\\_examples\\, metrics\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.FitRes:1 of msgid "Fit response from a client." -msgstr "" +msgstr "클라이언트의 적합성 응답." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`Error `\\ \\(code\\[\\, reason\\]\\)" -msgstr "" +msgstr ":py:obj:`Error `\\ \\(code\\[\\, reason\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Error:1 of msgid "A dataclass that stores information about an error that occurred." -msgstr "" +msgstr "발생한 오류에 대한 정보를 저장하는 데이터 클래스입니다." #: ../../source/ref-api/flwr.common.rst:64::1 -msgid ":py:obj:`GetParametersIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetParametersIns `\\ \\(config\\)" msgstr "" +":py:obj:`GetParametersIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetParametersIns:1 of msgid "Parameters request for a client." -msgstr "" +msgstr "클라이언트에 대한 매개변수 요청입니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`GetParametersRes `\\ \\(status\\, " "parameters\\)" msgstr "" +":py:obj:`GetParametersRes `\\ \\(status\\, " +"parameters\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetParametersRes:1 of msgid "Response when asked to return parameters." -msgstr "" +msgstr "매개변수 반환 요청 시 응답합니다." #: ../../source/ref-api/flwr.common.rst:64::1 -msgid ":py:obj:`GetPropertiesIns `\\ \\(config\\)" +msgid "" +":py:obj:`GetPropertiesIns `\\ \\(config\\)" msgstr "" +":py:obj:`GetPropertiesIns `\\ \\(config\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetPropertiesIns:1 of msgid "Properties request for a client." -msgstr "" +msgstr "클라이언트에 대한 속성 요청." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`GetPropertiesRes `\\ \\(status\\, " "properties\\)" msgstr "" +":py:obj:`GetPropertiesRes `\\ \\(status\\, " +"properties\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.GetPropertiesRes:1 of msgid "Properties response from a client." -msgstr "" +msgstr "클라이언트의 속성 응답을 확인합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`Message `\\ \\(metadata\\[\\, content\\, " "error\\]\\)" msgstr "" +":py:obj:`Message `\\ \\(metadata\\[\\, content\\, " +"error\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Message:1 of msgid "State of your application from the viewpoint of the entity using it." -msgstr "" +msgstr "애플리케이션을 사용하는 엔티티의 관점에서 애플리케이션의 상태입니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`MessageType `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`MessageType `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.constant.MessageType:1 of msgid "Message type." -msgstr "" +msgstr "메시지 타입." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`MessageTypeLegacy `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`MessageTypeLegacy `\\ \\(\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.constant.MessageTypeLegacy:1 of msgid "Legacy message type." -msgstr "" +msgstr "레거시 메시지 타입." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -":py:obj:`Metadata `\\ \\(run\\_id\\, " -"message\\_id\\, src\\_node\\_id\\, ...\\)" +":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " +"src\\_node\\_id\\, ...\\)" msgstr "" +":py:obj:`Metadata `\\ \\(run\\_id\\, message\\_id\\, " +"src\\_node\\_id\\, ...\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.message.Metadata:1 of msgid "A dataclass holding metadata associated with the current message." -msgstr "" +msgstr "현재 메시지와 관련된 메타데이터를 보유한 데이터 클래스입니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`MetricsRecord `\\ " "\\(\\[metrics\\_dict\\, keep\\_input\\]\\)" msgstr "" +":py:obj:`MetricsRecord `\\ " +"\\(\\[metrics\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.metricsrecord.MetricsRecord:1 of msgid "Metrics record." -msgstr "" +msgstr "메트릭 기록." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`NDArray `\\" -msgstr "" +msgstr ":py:obj:`NDArray `\\" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" -"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, " -":py:class:`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" +"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" msgstr "" +"alias of :py:class:`~numpy.ndarray`\\ [:py:obj:`~typing.Any`, :py:class:" +"`~numpy.dtype`\\ [:py:obj:`~typing.Any`]]" #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`Parameters `\\ \\(tensors\\, " "tensor\\_type\\)" msgstr "" +":py:obj:`Parameters `\\ \\(tensors\\, " +"tensor\\_type\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Parameters:1 of msgid "Model parameters." -msgstr "" +msgstr "모델 매개변수." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`ParametersRecord `\\ " "\\(\\[array\\_dict\\, keep\\_input\\]\\)" msgstr "" +":py:obj:`ParametersRecord `\\ " +"\\(\\[array\\_dict\\, keep\\_input\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "Parameters record." -msgstr "" +msgstr "매개변수 기록." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`ReconnectIns `\\ \\(seconds\\)" -msgstr "" +msgstr ":py:obj:`ReconnectIns `\\ \\(seconds\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ReconnectIns:1 of msgid "ReconnectIns message from server to client." -msgstr "" +msgstr "서버에서 클라이언트로 메시지를 다시 연결합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`RecordSet `\\ " "\\(\\[parameters\\_records\\, ...\\]\\)" msgstr "" +":py:obj:`RecordSet `\\ " +"\\(\\[parameters\\_records\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.record.recordset.RecordSet:1 of msgid "RecordSet stores groups of parameters, metrics and configs." -msgstr "" +msgstr "RecordSet은 매개변수, 메트릭 및 설정 그룹을 저장합니다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid "" ":py:obj:`ServerMessage `\\ " "\\(\\[get\\_properties\\_ins\\, ...\\]\\)" msgstr "" +":py:obj:`ServerMessage `\\ " +"\\(\\[get\\_properties\\_ins\\, ...\\]\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.ServerMessage:1 of msgid "ServerMessage is a container used to hold one instruction message." msgstr "" +"ServerMessage는 하나의 instruction 메시지를 저장하는 데 사용되는 컨테이너입니" +"다." #: ../../source/ref-api/flwr.common.rst:64::1 msgid ":py:obj:`Status `\\ \\(code\\, message\\)" -msgstr "" +msgstr ":py:obj:`Status `\\ \\(code\\, message\\)" #: ../../source/ref-api/flwr.common.rst:64::1 #: flwr.common.typing.Status:1 of msgid "Client status." -msgstr "" +msgstr "클라이언트 상태." #: ../../source/ref-api/flwr.common.Array.rst:2 msgid "Array" -msgstr "" +msgstr "배열" #: flwr.common.record.parametersrecord.Array:3 of msgid "" "A dataclass containing serialized data from an array-like or tensor-like " "object along with some metadata about it." msgstr "" +"배열형 또는 텐서형 객체의 직렬화된 데이터와 그에 대한 일부 메타데이터를 포함" +"하는 데이터 클래스입니다." #: flwr.common.record.parametersrecord.Array:6 of msgid "" -"A string representing the data type of the serialised object (e.g. " -"`np.float32`)" -msgstr "" +"A string representing the data type of the serialised object (e.g. `np." +"float32`)" +msgstr "직렬화된 객체의 데이터 유형을 나타내는 문자열(예: `np.float32`)" #: flwr.common.record.parametersrecord.Array:8 of msgid "" -"A list representing the shape of the unserialized array-like object. This" -" is used to deserialize the data (depending on the serialization method) " -"or simply as a metadata field." +"A list representing the shape of the unserialized array-like object. This is " +"used to deserialize the data (depending on the serialization method) or " +"simply as a metadata field." msgstr "" +"직렬화되지 않은 배열과 같은 객체의 모양을 나타내는 목록입니다. 직렬화 방법에 " +"따라 데이터를 역직렬화하는 데 사용되거나 단순히 메타데이터 필드로 사용됩니다." #: flwr.common.record.parametersrecord.Array:12 of msgid "" -"A string indicating the type of serialisation mechanism used to generate " -"the bytes in `data` from an array-like or tensor-like object." +"A string indicating the type of serialisation mechanism used to generate the " +"bytes in `data` from an array-like or tensor-like object." msgstr "" +"배열형 또는 텐서형 객체에서 `데이터`의 바이트를 생성하는 데 사용되는 직렬화 " +"메커니즘의 유형을 나타내는 문자열입니다." #: flwr.common.record.parametersrecord.Array:15 of msgid "A buffer of bytes containing the data." -msgstr "" +msgstr "데이터를 포함하는 바이트 버퍼입니다." #: ../../source/ref-api/flwr.common.Array.rst:26::1 msgid ":py:obj:`numpy `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`numpy `\\ \\(\\)" #: ../../source/ref-api/flwr.common.Array.rst:26::1 #: flwr.common.record.parametersrecord.Array.numpy:1 of msgid "Return the array as a NumPy array." -msgstr "" +msgstr "배열을 NumPy 배열로 반환합니다." #: flwr.common.record.parametersrecord.Array.numpy:1::1 of msgid ":py:obj:`dtype `\\" -msgstr "" +msgstr ":py:obj:`dtype `\\" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of msgid ":py:obj:`shape `\\" -msgstr "" +msgstr ":py:obj:`shape `\\" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of msgid ":py:obj:`stype `\\" -msgstr "" +msgstr ":py:obj:`stype `\\" #: flwr.common.record.parametersrecord.Array.numpy:1::1 of msgid ":py:obj:`data `\\" -msgstr "" +msgstr ":py:obj:`data `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:2 msgid "ClientMessage" -msgstr "" +msgstr "클라이언트 메시지" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid ":py:obj:`evaluate_res `\\" -msgstr "" +msgstr ":py:obj:`evaluate_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid ":py:obj:`fit_res `\\" -msgstr "" +msgstr ":py:obj:`fit_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_res " -"`\\" +":py:obj:`get_parameters_res `\\" msgstr "" +":py:obj:`get_parameters_res `\\" #: ../../source/ref-api/flwr.common.ClientMessage.rst:31::1 msgid "" -":py:obj:`get_properties_res " -"`\\" +":py:obj:`get_properties_res `\\" msgstr "" +":py:obj:`get_properties_res `\\" #: ../../source/ref-api/flwr.common.Code.rst:2 msgid "Code" -msgstr "" +msgstr "코드" #: flwr.common.typing.Code:1 of msgid "Bases: :py:class:`~enum.Enum`" -msgstr "" +msgstr "Bases: :py:class:`~enum.Enum`" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid ":py:obj:`OK `\\" -msgstr "" +msgstr ":py:obj:`OK `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" msgstr "" +":py:obj:`GET_PROPERTIES_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED " -"`\\" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" msgstr "" +":py:obj:`GET_PARAMETERS_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid ":py:obj:`FIT_NOT_IMPLEMENTED `\\" -msgstr "" +msgstr ":py:obj:`FIT_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.Code.rst:26::1 msgid "" -":py:obj:`EVALUATE_NOT_IMPLEMENTED " -"`\\" +":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" msgstr "" +":py:obj:`EVALUATE_NOT_IMPLEMENTED `\\" #: ../../source/ref-api/flwr.common.ConfigsRecord.rst:2 msgid "ConfigsRecord" -msgstr "" +msgstr "컨피그 레코드" #: flwr.common.record.configsrecord.ConfigsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` |" -" :py:class:`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ " -"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`] | " -":py:class:`~typing.List`\\ [:py:class:`str`] | :py:class:`~typing.List`\\" -" [:py:class:`bytes`] | :py:class:`~typing.List`\\ [:py:class:`bool`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`int` | :py:class:`float` | :py:class:`str` | :py:class:" +"`bytes` | :py:class:`bool` | :py:class:`~typing.List`\\ [:py:class:`int`] | :" +"py:class:`~typing.List`\\ [:py:class:`float`] | :py:class:`~typing.List`\\ [:" +"py:class:`str`] | :py:class:`~typing.List`\\ [:py:class:`bytes`] | :py:class:" +"`~typing.List`\\ [:py:class:`bool`]]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:class:`int` | :py:class:`float` | :py:class:`str` | :py:class:`bytes` |" +" :py:class:`bool` | :py:class:`~typing.List`\\ [:py:class:`int`] | " +":py:class:`~typing.List`\\ [:py:class:`float`] | :py:class:`~typing.List`\\ " +"[:py:class:`str`] | :py:class:`~typing.List`\\ [:py:class:`bytes`] | " +":py:class:`~typing.List`\\ [:py:class:`bool`]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1 #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "Remove all items from R." -msgstr "" +msgstr "R에서 모든 항목을 제거합니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`count_bytes `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.configsrecord.ConfigsRecord.count_bytes:1 #: flwr.common.record.metricsrecord.MetricsRecord.count_bytes:1 #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:1 #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "Return number of Bytes stored in this object." -msgstr "" +msgstr "이 객체에 저장된 바이트 수를 반환합니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.get:1 of msgid "d defaults to None." -msgstr "" +msgstr "d는 기본값이 None입니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.pop:1 of -msgid "If key is not found, d is returned if given, otherwise KeyError is raised." -msgstr "" +msgid "" +"If key is not found, d is returned if given, otherwise KeyError is raised." +msgstr "키를 찾을 수 없으면 주어진 경우 d가 반환되고, 그렇지 않으면 KeyError가 " +"발생합니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" +")" #: flwr.common.record.typeddict.TypedDict.clear:1::1 #: flwr.common.record.typeddict.TypedDict.update:1 of msgid "Update R from dict/iterable E and F." -msgstr "" +msgstr "dict/iterable E 및 F에서 R을 업데이트합니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`values `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`values `\\ \\(\\)" #: flwr.common.record.configsrecord.ConfigsRecord.count_bytes:3 of msgid "This function counts booleans as occupying 1 Byte." -msgstr "" +msgstr "이 함수는 booleans을 1바이트를 차지하는 것으로 계산합니다." #: ../../source/ref-api/flwr.common.Context.rst:2 msgid "Context" -msgstr "" +msgstr "컨텍스트" #: flwr.common.context.Context:3 of msgid "" -"Holds records added by the entity in a given run and that will stay " -"local. This means that the data it holds will never leave the system it's" -" running from. This can be used as an intermediate storage or scratchpad " -"when executing mods. It can also be used as a memory to access at " -"different points during the lifecycle of this entity (e.g. across " -"multiple rounds)" +"Holds records added by the entity in a given run and that will stay local. " +"This means that the data it holds will never leave the system it's running " +"from. This can be used as an intermediate storage or scratchpad when " +"executing mods. It can also be used as a memory to access at different " +"points during the lifecycle of this entity (e.g. across multiple rounds)" msgstr "" +"특정 실행에서 엔티티가 추가한 레코드를 보유하며 로컬에 유지됩니다. 즉, " +"저장된 데이터는 실행 중인 시스템을 벗어나지 않습니다. 모드를 실행할 때 중간 " +"저장소나 스크래치 패드로 사용할 수 있습니다. 또한 이 엔티티의 수명 주기 동안 " +"다른 시점에서 액세스하기 위한 메모리로도 사용할 수 있습니다(예: 여러 " +"라운드에 걸쳐)" #: ../../source/ref-api/flwr.common.Context.rst:28::1 msgid ":py:obj:`state `\\" -msgstr "" +msgstr ":py:obj:`state `\\" #: ../../source/ref-api/flwr.common.DisconnectRes.rst:2 msgid "DisconnectRes" -msgstr "" +msgstr "연결 해제" #: ../../source/ref-api/flwr.common.DisconnectRes.rst:28::1 msgid ":py:obj:`reason `\\" -msgstr "" +msgstr ":py:obj:`reason `\\" #: ../../source/ref-api/flwr.common.Error.rst:2 msgid "Error" -msgstr "" +msgstr "오류" #: flwr.common.message.Error:3 of msgid "An identifier for the error." -msgstr "" +msgstr "오류 식별자입니다." #: flwr.common.message.Error:5 of msgid "A reason for why the error arose (e.g. an exception stack-trace)" -msgstr "" +msgstr "오류가 발생한 이유(예: 예외 스택 추적)" #: flwr.common.Error.code:1::1 of msgid ":py:obj:`code `\\" -msgstr "" +msgstr ":py:obj:`code `\\" #: flwr.common.Error.code:1 flwr.common.Error.code:1::1 of msgid "Error code." -msgstr "" +msgstr "오류 코드." #: flwr.common.Error.code:1::1 of msgid ":py:obj:`reason `\\" -msgstr "" +msgstr ":py:obj:`reason `\\" #: flwr.common.Error.code:1::1 flwr.common.Error.reason:1 of msgid "Reason reported about the error." -msgstr "" +msgstr "오류에 대해 보고된 사유입니다." #: ../../source/ref-api/flwr.common.EvaluateIns.rst:2 msgid "EvaluateIns" -msgstr "" +msgstr "평가" #: ../../source/ref-api/flwr.common.EvaluateIns.rst:29::1 msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.EvaluateIns.rst:29::1 msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:2 msgid "EvaluateRes" -msgstr "" +msgstr "EvaluateRes" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 msgid ":py:obj:`loss `\\" -msgstr "" +msgstr ":py:obj:`loss `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 msgid ":py:obj:`num_examples `\\" -msgstr "" +msgstr ":py:obj:`num_examples `\\" #: ../../source/ref-api/flwr.common.EvaluateRes.rst:31::1 msgid ":py:obj:`metrics `\\" -msgstr "" +msgstr ":py:obj:`metrics `\\" #: ../../source/ref-api/flwr.common.EventType.rst:2 msgid "EventType" -msgstr "" +msgstr "이벤트 타입" #: flwr.common.telemetry.EventType:1 of msgid "Bases: :py:class:`str`, :py:class:`~enum.Enum`" -msgstr "" +msgstr "Bases: :py:class:`str`, :py:class:`~enum.Enum`" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`encode `\\ \\(\\[encoding\\, " "errors\\]\\)" msgstr "" +":py:obj:`encode `\\ \\(\\[encoding\\, errors\\]" +"\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.encode:1 of msgid "Encode the string using the codec registered for encoding." -msgstr "" +msgstr "인코딩용으로 등록된 코덱을 사용하여 문자열을 인코딩합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`replace `\\ \\(old\\, new\\[\\, " "count\\]\\)" msgstr "" +":py:obj:`replace `\\ \\(old\\, new\\[\\, " +"count\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.replace:1 of msgid "Return a copy with all occurrences of substring old replaced by new." -msgstr "" +msgstr "이전 하위 문자열이 모두 새 하위 문자열로 바뀐 사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`split `\\ \\(\\[sep\\, " -"maxsplit\\]\\)" +":py:obj:`split `\\ \\(\\[sep\\, maxsplit\\]\\)" msgstr "" +":py:obj:`split `\\ \\(\\[sep\\, maxsplit\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rsplit:1 flwr.common.EventType.split:1 of msgid "" -"Return a list of the substrings in the string, using sep as the separator" -" string." -msgstr "" +"Return a list of the substrings in the string, using sep as the separator " +"string." +msgstr "sep를 구분 문자열로 사용하여 문자열의 하위 문자열 목록을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rsplit `\\ \\(\\[sep\\, " -"maxsplit\\]\\)" +":py:obj:`rsplit `\\ \\(\\[sep\\, maxsplit\\]\\)" msgstr "" +":py:obj:`rsplit `\\ \\(\\[sep\\, maxsplit\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`join `\\ \\(iterable\\, \\/\\)" -msgstr "" +msgstr ":py:obj:`join `\\ \\(iterable\\, \\/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.join:1 of msgid "Concatenate any number of strings." -msgstr "" +msgstr "원하는 수의 문자열을 연결합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`capitalize `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`capitalize `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.capitalize:1 of msgid "Return a capitalized version of the string." -msgstr "" +msgstr "대문자로 된 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`casefold `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`casefold `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.casefold:1 of msgid "Return a version of the string suitable for caseless comparisons." -msgstr "" +msgstr "대소문자 구분 없는 비교에 적합한 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`title `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`title `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.title:1 of msgid "Return a version of the string where each word is titlecased." -msgstr "" +msgstr "각 단어의 제목이 대소문자로 구분된 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`center `\\ \\(width\\[\\, " "fillchar\\]\\)" msgstr "" +":py:obj:`center `\\ \\(width\\[\\, fillchar\\]" +"\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.center:1 of msgid "Return a centered string of length width." -msgstr "" +msgstr "길이 너비의 가운데 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`count `\\ \\(sub\\[\\, start\\[\\, " "end\\]\\]\\)" msgstr "" +":py:obj:`count `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the number of non-overlapping occurrences of substring sub in " -"string S[start:end]." -msgstr "" +"Return the number of non-overlapping occurrences of substring sub in string " +"S[start:end]." +msgstr "문자열 S[start:end]에서 하위 문자열 sub이 겹치지 않는 횟수를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`expandtabs `\\ " -"\\(\\[tabsize\\]\\)" +":py:obj:`expandtabs `\\ \\(\\[tabsize\\]\\)" msgstr "" +":py:obj:`expandtabs `\\ \\(\\[tabsize\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.expandtabs:1 of msgid "Return a copy where all tab characters are expanded using spaces." -msgstr "" +msgstr "모든 탭 문자가 공백을 사용하여 확장된 사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`find `\\ \\(sub\\[\\, start\\[\\, " "end\\]\\]\\)" msgstr "" +":py:obj:`find `\\ \\(sub\\[\\, start\\[\\, end\\]" +"\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the lowest index in S where substring sub is found, such that sub " -"is contained within S[start:end]." -msgstr "" +"Return the lowest index in S where substring sub is found, such that sub is " +"contained within S[start:end]." +msgstr "하위 문자열 sub이 발견되는 S에서 하위가 S[start:end] 내에 포함되는 가장 낮은 " +"인덱스를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`partition `\\ \\(sep\\, \\/\\)" +msgid "" +":py:obj:`partition `\\ \\(sep\\, \\/\\)" msgstr "" +":py:obj:`partition `\\ \\(sep\\, \\/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.partition:1 flwr.common.EventType.rpartition:1 of msgid "Partition the string into three parts using the given separator." -msgstr "" +msgstr "지정된 구분 기호를 사용하여 문자열을 세 부분으로 분할합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`index `\\ \\(sub\\[\\, start\\[\\, " "end\\]\\]\\)" msgstr "" +":py:obj:`index `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`ljust `\\ \\(width\\[\\, " -"fillchar\\]\\)" +":py:obj:`ljust `\\ \\(width\\[\\, fillchar\\]\\)" msgstr "" +":py:obj:`ljust `\\ \\(width\\[\\, fillchar\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.ljust:1 of msgid "Return a left-justified string of length width." -msgstr "" +msgstr "왼쪽으로 정렬된 길이의 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`lower `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`lower `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.lower:1 of msgid "Return a copy of the string converted to lowercase." -msgstr "" +msgstr "소문자로 변환된 문자열 사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`lstrip `\\ \\(\\[chars\\]\\)" -msgstr "" +msgstr ":py:obj:`lstrip `\\ \\(\\[chars\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.lstrip:1 of msgid "Return a copy of the string with leading whitespace removed." -msgstr "" +msgstr "선행 공백이 제거된 문자열의 복사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`rfind `\\ \\(sub\\[\\, start\\[\\, " "end\\]\\]\\)" msgstr "" +":py:obj:`rfind `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -"Return the highest index in S where substring sub is found, such that sub" -" is contained within S[start:end]." -msgstr "" +"Return the highest index in S where substring sub is found, such that sub is " +"contained within S[start:end]." +msgstr "부분 문자열 sub이 발견되는 곳에서 sub이 S[start:end] 내에 포함되도록 S에서 " +"가장 높은 인덱스를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rindex `\\ \\(sub\\[\\, " -"start\\[\\, end\\]\\]\\)" +":py:obj:`rindex `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" msgstr "" +":py:obj:`rindex `\\ \\(sub\\[\\, start\\[\\, " +"end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`rjust `\\ \\(width\\[\\, " -"fillchar\\]\\)" +":py:obj:`rjust `\\ \\(width\\[\\, fillchar\\]\\)" msgstr "" +":py:obj:`rjust `\\ \\(width\\[\\, fillchar\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rjust:1 of msgid "Return a right-justified string of length width." -msgstr "" +msgstr "길이 너비의 오른쪽 정렬된 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`rstrip `\\ \\(\\[chars\\]\\)" -msgstr "" +msgstr ":py:obj:`rstrip `\\ \\(\\[chars\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.rstrip:1 of msgid "Return a copy of the string with trailing whitespace removed." -msgstr "" +msgstr "후행 공백이 제거된 문자열의 복사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" +msgid "" +":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" msgstr "" +":py:obj:`rpartition `\\ \\(sep\\, \\/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`splitlines `\\ " "\\(\\[keepends\\]\\)" msgstr "" +":py:obj:`splitlines `\\ \\(\\[keepends\\]\\" +")" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.splitlines:1 of msgid "Return a list of the lines in the string, breaking at line boundaries." -msgstr "" +msgstr "문자열의 줄 목록을 줄 경계에서 구분하여 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`strip `\\ \\(\\[chars\\]\\)" -msgstr "" +msgstr ":py:obj:`strip `\\ \\(\\[chars\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.strip:1 of -msgid "Return a copy of the string with leading and trailing whitespace removed." -msgstr "" +msgid "" +"Return a copy of the string with leading and trailing whitespace removed." +msgstr "선행 및 후행 공백이 제거된 문자열 사본을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`swapcase `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`swapcase `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.swapcase:1 of msgid "" "Convert uppercase characters to lowercase and lowercase characters to " "uppercase." -msgstr "" +msgstr "대문자를 소문자로, 소문자를 대문자로 변환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid ":py:obj:`translate `\\ \\(table\\, \\/\\)" +msgid "" +":py:obj:`translate `\\ \\(table\\, \\/\\)" msgstr "" +":py:obj:`translate `\\ \\(table\\, \\/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.translate:1 of msgid "Replace each character in the string using the given translation table." -msgstr "" +msgstr "주어진 번역 테이블을 사용하여 문자열의 각 문자를 바꿉니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`upper `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`upper `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.upper:1 of msgid "Return a copy of the string converted to uppercase." -msgstr "" +msgstr "Return a copy of the string converted to uppercase." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`startswith `\\ \\(prefix\\[\\," -" start\\[\\, end\\]\\]\\)" +":py:obj:`startswith `\\ \\(prefix\\[\\, " +"start\\[\\, end\\]\\]\\)" msgstr "" +":py:obj:`startswith `\\ \\(prefix\\[\\, " +"start\\[\\, end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "Return True if S starts with the specified prefix, False otherwise." -msgstr "" +msgstr "S가 지정된 접두사로 시작하면 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`endswith `\\ \\(suffix\\[\\, " "start\\[\\, end\\]\\]\\)" msgstr "" +":py:obj:`endswith `\\ \\(suffix\\[\\, start\\" +"[\\, end\\]\\]\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "Return True if S ends with the specified suffix, False otherwise." -msgstr "" +msgstr "S가 지정된 접미사로 끝나면 True를 반환하고 그렇지 않으면 False을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removeprefix `\\ " -"\\(prefix\\, \\/\\)" +":py:obj:`removeprefix `\\ \\(prefix\\, " +"\\/\\)" msgstr "" +":py:obj:`removeprefix `\\ \\(prefix\\, \\" +"/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.removeprefix:1 of msgid "Return a str with the given prefix string removed if present." -msgstr "" +msgstr "주어진 접두사 문자열이 있는 경우 제거된 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" -":py:obj:`removesuffix `\\ " -"\\(suffix\\, \\/\\)" +":py:obj:`removesuffix `\\ \\(suffix\\, " +"\\/\\)" msgstr "" +":py:obj:`removesuffix `\\ \\(suffix\\, \\" +"/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.removesuffix:1 of msgid "Return a str with the given suffix string removed if present." -msgstr "" +msgstr "주어진 접미사 문자열이 있는 경우 제거된 문자열을 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isascii `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isascii `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isascii:1 of msgid "Return True if all characters in the string are ASCII, False otherwise." -msgstr "" +msgstr "문자열의 모든 문자가 ASCII인 경우 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`islower `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`islower `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.islower:1 of msgid "Return True if the string is a lowercase string, False otherwise." -msgstr "" +msgstr "문자열이 소문자 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isupper `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isupper `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isupper:1 of msgid "Return True if the string is an uppercase string, False otherwise." -msgstr "" +msgstr "문자열이 대문자 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`istitle `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`istitle `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.istitle:1 of msgid "Return True if the string is a title-cased string, False otherwise." -msgstr "" +msgstr "문자열이 제목 대/소문자가 구분된 문자열이면 True를 반환하고, 그렇지 않으면 " +"False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isspace `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isspace `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isspace:1 of msgid "Return True if the string is a whitespace string, False otherwise." -msgstr "" +msgstr "문자열이 공백 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isdecimal `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isdecimal `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isdecimal:1 of msgid "Return True if the string is a decimal string, False otherwise." -msgstr "" +msgstr "문자열이 10진수 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isdigit `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isdigit `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isdigit:1 of msgid "Return True if the string is a digit string, False otherwise." -msgstr "" +msgstr "문자열이 숫자 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isnumeric `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isnumeric `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isnumeric:1 of msgid "Return True if the string is a numeric string, False otherwise." -msgstr "" +msgstr "문자열이 숫자 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isalpha `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isalpha `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isalpha:1 of msgid "Return True if the string is an alphabetic string, False otherwise." -msgstr "" +msgstr "문자열이 알파벳 문자열이면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isalnum `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isalnum `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isalnum:1 of msgid "Return True if the string is an alpha-numeric string, False otherwise." -msgstr "" +msgstr "문자열이 영-숫자 문자열이면 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isidentifier `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isidentifier `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isidentifier:1 of -msgid "Return True if the string is a valid Python identifier, False otherwise." -msgstr "" +msgid "" +"Return True if the string is a valid Python identifier, False otherwise." +msgstr "문자열이 유효한 파이썬 식별자인 경우 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`isprintable `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`isprintable `\\ \\(\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.isprintable:1 of msgid "Return True if the string is printable, False otherwise." -msgstr "" +msgstr "문자열을 인쇄할 수 있으면 True를 반환하고, 그렇지 않으면 False를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`zfill `\\ \\(width\\, \\/\\)" -msgstr "" +msgstr ":py:obj:`zfill `\\ \\(width\\, \\/\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.zfill:1 of msgid "" -"Pad a numeric string with zeros on the left, to fill a field of the given" -" width." -msgstr "" +"Pad a numeric string with zeros on the left, to fill a field of the given " +"width." +msgstr "숫자 문자열을 왼쪽에 0으로 채워서 지정된 너비의 필드를 채웁니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "" ":py:obj:`format `\\ \\(\\*args\\, " "\\*\\*kwargs\\)" msgstr "" +":py:obj:`format `\\ \\(\\*args\\, \\*\\*" +"kwargs\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 -msgid "Return a formatted version of S, using substitutions from args and kwargs." -msgstr "" +msgid "" +"Return a formatted version of S, using substitutions from args and kwargs." +msgstr "args와 kwarg의 치환을 사용하여 형식이 지정된 S를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`format_map `\\ \\(mapping\\)" -msgstr "" +msgstr ":py:obj:`format_map `\\ \\(mapping\\)" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid "Return a formatted version of S, using substitutions from mapping." -msgstr "" +msgstr "매핑의 치환을 사용하여 형식이 지정된 S를 반환합니다." #: ../../source/ref-api/flwr.common.EventType.rst:163::1 msgid ":py:obj:`maketrans `\\" -msgstr "" +msgstr ":py:obj:`maketrans `\\" #: ../../source/ref-api/flwr.common.EventType.rst:163::1 #: flwr.common.EventType.maketrans:1 of msgid "Return a translation table usable for str.translate()." -msgstr "" +msgstr "str.translate()에 사용할 수 있는 번역 테이블을 반환합니다." #: flwr.common.EventType.capitalize:1::1 of msgid ":py:obj:`PING `\\" -msgstr "" +msgstr ":py:obj:`PING `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_CLIENT_ENTER `\\" +msgid "" +":py:obj:`START_CLIENT_ENTER `\\" msgstr "" +":py:obj:`START_CLIENT_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_CLIENT_LEAVE `\\" +msgid "" +":py:obj:`START_CLIENT_LEAVE `\\" msgstr "" +":py:obj:`START_CLIENT_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_SERVER_ENTER `\\" +msgid "" +":py:obj:`START_SERVER_ENTER `\\" msgstr "" +":py:obj:`START_SERVER_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_SERVER_LEAVE `\\" +msgid "" +":py:obj:`START_SERVER_LEAVE `\\" msgstr "" +":py:obj:`START_SERVER_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_ENTER " -"`\\" +":py:obj:`RUN_DRIVER_API_ENTER `\\" msgstr "" +":py:obj:`RUN_DRIVER_API_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_DRIVER_API_LEAVE " -"`\\" +":py:obj:`RUN_DRIVER_API_LEAVE `\\" msgstr "" +":py:obj:`RUN_DRIVER_API_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_ENTER " -"`\\" +":py:obj:`RUN_FLEET_API_ENTER `\\" msgstr "" +":py:obj:`RUN_FLEET_API_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_FLEET_API_LEAVE " -"`\\" +":py:obj:`RUN_FLEET_API_LEAVE `\\" msgstr "" +":py:obj:`RUN_FLEET_API_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_ENTER " -"`\\" +":py:obj:`RUN_SUPERLINK_ENTER `\\" msgstr "" +":py:obj:`RUN_SUPERLINK_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERLINK_LEAVE " -"`\\" +":py:obj:`RUN_SUPERLINK_LEAVE `\\" msgstr "" +":py:obj:`RUN_SUPERLINK_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_ENTER " -"`\\" +":py:obj:`START_SIMULATION_ENTER `\\" msgstr "" +":py:obj:`START_SIMULATION_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`START_SIMULATION_LEAVE " -"`\\" +":py:obj:`START_SIMULATION_LEAVE `\\" msgstr "" +":py:obj:`START_SIMULATION_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid ":py:obj:`DRIVER_CONNECT `\\" -msgstr "" +msgstr ":py:obj:`DRIVER_CONNECT `\\" #: flwr.common.EventType.capitalize:1::1 of msgid ":py:obj:`DRIVER_DISCONNECT `\\" -msgstr "" +msgstr ":py:obj:`DRIVER_DISCONNECT `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_DRIVER_ENTER `\\" +msgid "" +":py:obj:`START_DRIVER_ENTER `\\" msgstr "" +":py:obj:`START_DRIVER_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of -msgid ":py:obj:`START_DRIVER_LEAVE `\\" +msgid "" +":py:obj:`START_DRIVER_LEAVE `\\" msgstr "" +":py:obj:`START_DRIVER_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_ENTER " -"`\\" +":py:obj:`RUN_CLIENT_APP_ENTER `\\" msgstr "" +":py:obj:`RUN_CLIENT_APP_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_CLIENT_APP_LEAVE " -"`\\" +":py:obj:`RUN_CLIENT_APP_LEAVE `\\" msgstr "" +":py:obj:`RUN_CLIENT_APP_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_ENTER " -"`\\" +":py:obj:`RUN_SERVER_APP_ENTER `\\" msgstr "" +":py:obj:`RUN_SERVER_APP_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SERVER_APP_LEAVE " -"`\\" +":py:obj:`RUN_SERVER_APP_LEAVE `\\" msgstr "" +":py:obj:`RUN_SERVER_APP_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_ENTER " -"`\\" +":py:obj:`RUN_SUPERNODE_ENTER `\\" msgstr "" +":py:obj:`RUN_SUPERNODE_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPERNODE_LEAVE " -"`\\" +":py:obj:`RUN_SUPERNODE_LEAVE `\\" msgstr "" +":py:obj:`RUN_SUPERNODE_LEAVE `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPEREXEC_ENTER " -"`\\" +":py:obj:`RUN_SUPEREXEC_ENTER `\\" msgstr "" +":py:obj:`RUN_SUPEREXEC_ENTER `\\" #: flwr.common.EventType.capitalize:1::1 of msgid "" -":py:obj:`RUN_SUPEREXEC_LEAVE " -"`\\" +":py:obj:`RUN_SUPEREXEC_LEAVE `\\" msgstr "" +":py:obj:`RUN_SUPEREXEC_LEAVE `\\" #: flwr.common.EventType.capitalize:3 of msgid "" "More specifically, make the first character have upper case and the rest " "lower case." -msgstr "" +msgstr "보다 구체적으로, 첫 번째 문자는 대문자로, 나머지는 소문자로 만듭니다." #: flwr.common.EventType.center:3 flwr.common.EventType.ljust:3 #: flwr.common.EventType.rjust:3 of -msgid "Padding is done using the specified fill character (default is a space)." -msgstr "" +msgid "" +"Padding is done using the specified fill character (default is a space)." +msgstr "패딩은 지정된 채우기 문자를 사용하여 수행됩니다(기본값은 공백)." #: flwr.common.EventType.count:1 of msgid "" -"Return the number of non-overlapping occurrences of substring sub in " -"string S[start:end]. Optional arguments start and end are interpreted as" -" in slice notation." +"Return the number of non-overlapping occurrences of substring sub in string " +"S[start:end]. Optional arguments start and end are interpreted as in slice " +"notation." msgstr "" +"문자열 S[start:end]에서 부분 문자열 sub의 겹치지 않는 횟수를 반환합니다. " +"선택적 인자 start와 end는 슬라이스 표기법과 같이 해석됩니다." #: flwr.common.EventType.encode:3 of msgid "encoding" -msgstr "" +msgstr "인코딩" #: flwr.common.EventType.encode:4 of msgid "The encoding in which to encode the string." -msgstr "" +msgstr "문자열을 인코딩합니다." #: flwr.common.EventType.encode:9 of msgid "errors" -msgstr "" +msgstr "오류" #: flwr.common.EventType.encode:6 of msgid "" "The error handling scheme to use for encoding errors. The default is " "'strict' meaning that encoding errors raise a UnicodeEncodeError. Other " -"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well " -"as any other name registered with codecs.register_error that can handle " +"possible values are 'ignore', 'replace' and 'xmlcharrefreplace' as well as " +"any other name registered with codecs.register_error that can handle " "UnicodeEncodeErrors." msgstr "" +"인코딩 오류에 사용할 오류 처리 방식입니다. 기본값은 'strict'로, 인코딩 " +"오류가 발생하면 UnicodeEncodeError를 발생시킵니다. 다른 가능한 값으로는 " +"'ignore', 'replace', 'xmlcharrefreplace', 그리고 UnicodeEncodeError를 처리할 " +"수 있는 codecs.register_error에 등록된 다른 이름도 사용할 수 있습니다." #: flwr.common.EventType.endswith:1 of msgid "" "Return True if S ends with the specified suffix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, " -"stop comparing S at that position. suffix can also be a tuple of strings " -"to try." +"optional start, test S beginning at that position. With optional end, stop " +"comparing S at that position. suffix can also be a tuple of strings to try." msgstr "" +"S가 지정된 접미사로 끝나면 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다. 시작 옵션을 사용하면 해당 위치부터 S를 테스트합니다. end 옵션을 " +"사용하면 해당 위치에서 S 비교를 중지합니다. 접미사는 시도할 문자열의 튜플일 " +"수도 있습니다." #: flwr.common.EventType.expandtabs:3 of msgid "If tabsize is not given, a tab size of 8 characters is assumed." -msgstr "" +msgstr "탭 크기를 지정하지 않으면 크기가 8로 지정됩니다." #: flwr.common.EventType.find:1 flwr.common.EventType.index:1 of msgid "" -"Return the lowest index in S where substring sub is found, such that sub " -"is contained within S[start:end]. Optional arguments start and end are " +"Return the lowest index in S where substring sub is found, such that sub is " +"contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" +"부분 문자열 sub가 발견되는 곳의 가장 낮은 인덱스를 반환하며, sub는 " +"S[start:end] 내에 포함되어야 합니다. 선택적 인자 start와 end는 슬라이스 " +"표기법과 같이 해석됩니다." #: flwr.common.EventType.find:5 flwr.common.EventType.rfind:5 of msgid "Return -1 on failure." -msgstr "" +msgstr "실패 시 -1을 반환합니다." #: flwr.common.EventType.format:1 of msgid "" -"Return a formatted version of S, using substitutions from args and " -"kwargs. The substitutions are identified by braces ('{' and '}')." -msgstr "" +"Return a formatted version of S, using substitutions from args and kwargs. " +"The substitutions are identified by braces ('{' and '}')." +msgstr "args와 kwargs의 치환을 사용하여 형식이 지정된 S를 반환합니다. 치환은 " +"중괄호('{' 및 '}')로 식별됩니다." #: flwr.common.EventType.format_map:1 of msgid "" "Return a formatted version of S, using substitutions from mapping. The " "substitutions are identified by braces ('{' and '}')." -msgstr "" +msgstr "매핑의 치환을 사용하여 형식이 지정된 S를 반환합니다. 치환은 중괄호('{' 및 " +"'}')로 식별됩니다." #: flwr.common.EventType.index:5 flwr.common.EventType.rindex:5 of msgid "Raises ValueError when the substring is not found." -msgstr "" +msgstr "부분 문자열을 찾을 수 없을 때 ValueError를 발생시킵니다." #: flwr.common.EventType.isalnum:3 of msgid "" -"A string is alpha-numeric if all characters in the string are alpha-" -"numeric and there is at least one character in the string." -msgstr "" +"A string is alpha-numeric if all characters in the string are alpha-numeric " +"and there is at least one character in the string." +msgstr "문자열의 모든 문자가 영숫자이고 문자열에 하나 이상의 문자가 있는 경우 " +"문자열은 영-숫자입니다." #: flwr.common.EventType.isalpha:3 of msgid "" -"A string is alphabetic if all characters in the string are alphabetic and" -" there is at least one character in the string." -msgstr "" +"A string is alphabetic if all characters in the string are alphabetic and " +"there is at least one character in the string." +msgstr "문자열의 모든 문자가 알파벳이고 문자열에 하나 이상의 문자가 있는 경우 " +"문자열은 알파벳입니다." #: flwr.common.EventType.isascii:3 of msgid "" -"ASCII characters have code points in the range U+0000-U+007F. Empty " -"string is ASCII too." -msgstr "" +"ASCII characters have code points in the range U+0000-U+007F. Empty string " +"is ASCII too." +msgstr "ASCII 문자는 U+0000-U+007F 범위의 코드 포인트가 있습니다. 빈 문자열도 " +"ASCII입니다." #: flwr.common.EventType.isdecimal:3 of msgid "" -"A string is a decimal string if all characters in the string are decimal " -"and there is at least one character in the string." -msgstr "" +"A string is a decimal string if all characters in the string are decimal and " +"there is at least one character in the string." +msgstr "문자열의 모든 문자가 10진수이고 문자열에 하나 이상의 문자가 있는 경우 " +"문자열은 10진수 문자열입니다." #: flwr.common.EventType.isdigit:3 of msgid "" -"A string is a digit string if all characters in the string are digits and" -" there is at least one character in the string." -msgstr "" +"A string is a digit string if all characters in the string are digits and " +"there is at least one character in the string." +msgstr "문자열의 모든 문자가 숫자이고 문자열에 하나 이상의 문자가 있는 경우 문자열은 " +"숫자 문자열입니다." #: flwr.common.EventType.isidentifier:3 of msgid "" -"Call keyword.iskeyword(s) to test whether string s is a reserved " -"identifier, such as \"def\" or \"class\"." +"Call keyword.iskeyword(s) to test whether string s is a reserved identifier, " +"such as \"def\" or \"class\"." msgstr "" +"keyword.iskeyword(s)를 호출하여 문자열 s가 \"def\" 또는 \"class\"와 같은 " +"예약 식별자인지 테스트합니다." #: flwr.common.EventType.islower:3 of msgid "" -"A string is lowercase if all cased characters in the string are lowercase" -" and there is at least one cased character in the string." -msgstr "" +"A string is lowercase if all cased characters in the string are lowercase " +"and there is at least one cased character in the string." +msgstr "문자열이 모두 소문자이고 문자열에 문자가 하나 이상 있는 경우 문자열은 " +"소문자입니다." #: flwr.common.EventType.isnumeric:3 of msgid "" -"A string is numeric if all characters in the string are numeric and there" -" is at least one character in the string." -msgstr "" +"A string is numeric if all characters in the string are numeric and there is " +"at least one character in the string." +msgstr "문자열의 모든 문자가 숫자이고 문자열에 하나 이상의 문자가 있는 경우 문자열은 " +"숫자입니다." #: flwr.common.EventType.isprintable:3 of msgid "" -"A string is printable if all of its characters are considered printable " -"in repr() or if it is empty." -msgstr "" +"A string is printable if all of its characters are considered printable in " +"repr() or if it is empty." +msgstr "문자열은 repr()에서 모든 문자가 인쇄 가능한 것으로 간주되거나 비어 있는 경우 " +"인쇄할 수 있습니다." #: flwr.common.EventType.isspace:3 of msgid "" -"A string is whitespace if all characters in the string are whitespace and" -" there is at least one character in the string." -msgstr "" +"A string is whitespace if all characters in the string are whitespace and " +"there is at least one character in the string." +msgstr "문자열의 모든 문자가 공백이고 문자열에 하나 이상의 문자가 있는 경우 문자열은 " +"공백입니다." #: flwr.common.EventType.istitle:3 of msgid "" -"In a title-cased string, upper- and title-case characters may only follow" -" uncased characters and lowercase characters only cased ones." -msgstr "" +"In a title-cased string, upper- and title-case characters may only follow " +"uncased characters and lowercase characters only cased ones." +msgstr "제목 대/소문자 문자열에서 대문자와 제목 대문자는 대소문자만, 소문자는 " +"대문자만 뒤에 올 수 있습니다." #: flwr.common.EventType.isupper:3 of msgid "" -"A string is uppercase if all cased characters in the string are uppercase" -" and there is at least one cased character in the string." -msgstr "" +"A string is uppercase if all cased characters in the string are uppercase " +"and there is at least one cased character in the string." +msgstr "문자열의 모든 문자가 대문자이고 문자열에 문자가 하나 이상 있는 경우 문자열은 " +"대문자입니다." #: flwr.common.EventType.join:3 of msgid "" -"The string whose method is called is inserted in between each given " -"string. The result is returned as a new string." -msgstr "" +"The string whose method is called is inserted in between each given string. " +"The result is returned as a new string." +msgstr "메서드가 호출되는 문자열은 주어진 각 문자열 사이에 삽입됩니다. 결과는 새 " +"문자열로 반환됩니다." #: flwr.common.EventType.join:6 of msgid "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" -msgstr "" +msgstr "Example: '.'.join(['ab', 'pq', 'rs']) -> 'ab.pq.rs'" #: flwr.common.EventType.lstrip:3 flwr.common.EventType.rstrip:3 #: flwr.common.EventType.strip:3 of msgid "If chars is given and not None, remove characters in chars instead." -msgstr "" +msgstr "None이 아닌 문자가 지정되면 대신 문자열에서 문자를 제거합니다." #: flwr.common.EventType.maketrans:3 of msgid "" @@ -10190,10 +10936,15 @@ msgid "" "ordinals (integers) or characters to Unicode ordinals, strings or None. " "Character keys will be then converted to ordinals. If there are two " "arguments, they must be strings of equal length, and in the resulting " -"dictionary, each character in x will be mapped to the character at the " -"same position in y. If there is a third argument, it must be a string, " -"whose characters will be mapped to None in the result." +"dictionary, each character in x will be mapped to the character at the same " +"position in y. If there is a third argument, it must be a string, whose " +"characters will be mapped to None in the result." msgstr "" +"argument이 하나만 있는 경우, 유니코드 서수(정수) 또는 문자를 유니코드 서수, " +"문자열 또는 None에 매핑하는 dictionary이어야 합니다. 그러면 문자 키가 서수로 " +"변환됩니다. 인수가 두 개이면 길이가 같은 문자열이어야 하며, 결과 " +"dictionary에서 x의 각 문자는 y의 같은 위치에 있는 문자에 매핑됩니다. 세 번째 " +"인수가 있으면 문자열이어야 하며, 그 문자는 결과에서 None에 매핑됩니다." #: flwr.common.EventType.partition:3 of msgid "" @@ -10201,18 +10952,23 @@ msgid "" "found, returns a 3-tuple containing the part before the separator, the " "separator itself, and the part after it." msgstr "" +"문자열에서 구분 기호를 검색합니다. 구분 기호가 발견되면 구분 기호 앞 부분, " +"구분 기호 자체, 구분 기호 뒤 부분을 포함하는 3-tuple을 반환합니다." #: flwr.common.EventType.partition:7 of msgid "" "If the separator is not found, returns a 3-tuple containing the original " "string and two empty strings." -msgstr "" +msgstr "구분 기호를 찾을 수 없으면 원래 문자열과 빈 문자열 2개를 포함하는 3-튜플을 " +"반환합니다." #: flwr.common.EventType.removeprefix:3 of msgid "" -"If the string starts with the prefix string, return string[len(prefix):]." -" Otherwise, return a copy of the original string." +"If the string starts with the prefix string, return string[len(prefix):]. " +"Otherwise, return a copy of the original string." msgstr "" +"문자열이 접두사 문자열로 시작하면 문자열[len(prefix):]을 반환합니다. 그렇지 " +"않으면 원본 문자열의 복사본을 반환합니다." #: flwr.common.EventType.removesuffix:3 of msgid "" @@ -10220,667 +10976,727 @@ msgid "" "return string[:-len(suffix)]. Otherwise, return a copy of the original " "string." msgstr "" +"문자열이 접미사 문자열로 끝나고 해당 접미사가 비어 있지 않으면 " +"문자열[:-len(suffix)]을 반환합니다. 그렇지 않으면 원본 문자열의 복사본을 " +"반환합니다." #: flwr.common.EventType.replace:5 of msgid "count" -msgstr "" +msgstr "카운트" #: flwr.common.EventType.replace:4 of msgid "" "Maximum number of occurrences to replace. -1 (the default value) means " "replace all occurrences." -msgstr "" +msgstr "대체할 최대 발생 횟수입니다. -1(기본값)은 모든 항목을 교체한다는 의미입니다." #: flwr.common.EventType.replace:7 of msgid "" -"If the optional argument count is given, only the first count occurrences" -" are replaced." -msgstr "" +"If the optional argument count is given, only the first count occurrences " +"are replaced." +msgstr "선택적 argument 개수를 지정하면 첫 번째 개수만 바뀝니다." #: flwr.common.EventType.rfind:1 flwr.common.EventType.rindex:1 of msgid "" -"Return the highest index in S where substring sub is found, such that sub" -" is contained within S[start:end]. Optional arguments start and end are " +"Return the highest index in S where substring sub is found, such that sub is " +"contained within S[start:end]. Optional arguments start and end are " "interpreted as in slice notation." msgstr "" +"부분 문자열 sub가 발견되는 곳의 가장 높은 인덱스를 반환하며, sub는 " +"S[start:end] 내에 포함되어야 합니다. 선택적 인자 start와 end는 슬라이스 " +"표기법과 같이 해석됩니다." #: flwr.common.EventType.rpartition:3 of msgid "" -"This will search for the separator in the string, starting at the end. If" -" the separator is found, returns a 3-tuple containing the part before the" -" separator, the separator itself, and the part after it." +"This will search for the separator in the string, starting at the end. If " +"the separator is found, returns a 3-tuple containing the part before the " +"separator, the separator itself, and the part after it." msgstr "" +"그러면 문자열에서 끝 부분부터 시작하여 구분 기호를 검색합니다. 구분 기호가 " +"발견되면 구분 기호 앞 부분, 구분 기호 자체, 구분 기호 뒤 부분을 포함하는 3-" +"tuple을 반환합니다." #: flwr.common.EventType.rpartition:7 of msgid "" "If the separator is not found, returns a 3-tuple containing two empty " "strings and the original string." -msgstr "" +msgstr "구분 기호를 찾을 수 없는 경우 빈 문자열 2개와 원래 문자열을 포함하는 3-" +"tuple을 반환합니다." #: flwr.common.EventType.rsplit:7 flwr.common.EventType.split:7 of msgid "sep" -msgstr "" +msgstr "sep" #: flwr.common.EventType.rsplit:4 flwr.common.EventType.split:4 of msgid "The separator used to split the string." -msgstr "" +msgstr "문자열을 분할하는 데 사용되는 구분 기호입니다." #: flwr.common.EventType.rsplit:6 flwr.common.EventType.split:6 of msgid "" -"When set to None (the default value), will split on any whitespace " -"character (including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard" -" empty strings from the result." +"When set to None (the default value), will split on any whitespace character " +"(including \\\\n \\\\r \\\\t \\\\f and spaces) and will discard empty " +"strings from the result." msgstr "" +"None(기본값)으로 설정하면 모든 공백 문자(\\\\n" +" \\\\r \\\\t \\\\f 및 공백 포함)를 분할하고 결과에서 빈 문자열을 삭제합니다." #: flwr.common.EventType.rsplit:11 flwr.common.EventType.split:11 of msgid "maxsplit" -msgstr "" +msgstr "maxsplit" #: flwr.common.EventType.rsplit:10 flwr.common.EventType.split:10 of msgid "" -"Maximum number of splits (starting from the left). -1 (the default value)" -" means no limit." -msgstr "" +"Maximum number of splits (starting from the left). -1 (the default value) " +"means no limit." +msgstr "최대 분할 횟수(왼쪽부터 시작). -1(기본값)은 제한이 없음을 의미합니다." #: flwr.common.EventType.rsplit:13 of msgid "Splitting starts at the end of the string and works to the front." -msgstr "" +msgstr "분할은 문자열 끝에서 시작하여 앞쪽으로 진행됩니다." #: flwr.common.EventType.split:13 of msgid "" "Note, str.split() is mainly useful for data that has been intentionally " -"delimited. With natural text that includes punctuation, consider using " -"the regular expression module." +"delimited. With natural text that includes punctuation, consider using the " +"regular expression module." msgstr "" +"참고로 str.split()은 주로 의도적으로 구분된 데이터에 유용합니다. 구두점이 " +"포함된 자연 텍스트의 경우 정규식 모듈을 사용하는 것이 좋습니다." #: flwr.common.EventType.splitlines:3 of msgid "" -"Line breaks are not included in the resulting list unless keepends is " -"given and true." -msgstr "" +"Line breaks are not included in the resulting list unless keepends is given " +"and true." +msgstr "줄 바꿈은 keepends가 주어지고 참이 아니면 결과 목록에 포함되지 않습니다." #: flwr.common.EventType.startswith:1 of msgid "" "Return True if S starts with the specified prefix, False otherwise. With " -"optional start, test S beginning at that position. With optional end, " -"stop comparing S at that position. prefix can also be a tuple of strings " -"to try." +"optional start, test S beginning at that position. With optional end, stop " +"comparing S at that position. prefix can also be a tuple of strings to try." msgstr "" +"S가 지정된 접두사로 시작하면 True를 반환하고, 그렇지 않으면 False를 " +"반환합니다. 시작 옵션을 사용하면 해당 위치에서 시작되는 S를 테스트합니다. " +"선택적 end를 사용하면 해당 위치에서 S 비교를 중지합니다. 접두사는 시도할 " +"문자열의 튜플일 수도 있습니다." #: flwr.common.EventType.title:3 of msgid "" -"More specifically, words start with uppercased characters and all " -"remaining cased characters have lower case." -msgstr "" +"More specifically, words start with uppercased characters and all remaining " +"cased characters have lower case." +msgstr "보다 구체적으로, 단어는 대문자로 시작하고 나머지 모든 대소문자는 소문자로 " +"표기합니다." #: flwr.common.EventType.translate:5 of msgid "table" -msgstr "" +msgstr "table" #: flwr.common.EventType.translate:4 of msgid "" -"Translation table, which must be a mapping of Unicode ordinals to Unicode" -" ordinals, strings, or None." -msgstr "" +"Translation table, which must be a mapping of Unicode ordinals to Unicode " +"ordinals, strings, or None." +msgstr "유니코드 서수를 유니코드 서수, 문자열 또는 없음으로 매핑하는 번역 " +"테이블이어야 합니다." #: flwr.common.EventType.translate:7 of msgid "" "The table must implement lookup/indexing via __getitem__, for instance a " -"dictionary or list. If this operation raises LookupError, the character " -"is left untouched. Characters mapped to None are deleted." +"dictionary or list. If this operation raises LookupError, the character is " +"left untouched. Characters mapped to None are deleted." msgstr "" +"테이블은 사전이나 목록과 같이 __getitem__을 통해 조회/색인을 구현해야 " +"합니다. 이 작업에서 LookupError가 발생하면 문자는 그대로 유지됩니다. " +"없음으로 매핑된 문자는 삭제됩니다." #: flwr.common.EventType.zfill:3 of msgid "The string is never truncated." -msgstr "" +msgstr "문자열은 잘리지 않습니다." #: ../../source/ref-api/flwr.common.FitIns.rst:2 msgid "FitIns" -msgstr "" +msgstr "FitIns" #: ../../source/ref-api/flwr.common.FitIns.rst:29::1 msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.FitIns.rst:29::1 msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:2 msgid "FitRes" -msgstr "" +msgstr "FitRes" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 msgid ":py:obj:`num_examples `\\" -msgstr "" +msgstr ":py:obj:`num_examples `\\" #: ../../source/ref-api/flwr.common.FitRes.rst:31::1 msgid ":py:obj:`metrics `\\" -msgstr "" +msgstr ":py:obj:`metrics `\\" #: ../../source/ref-api/flwr.common.GetParametersIns.rst:2 msgid "GetParametersIns" -msgstr "" +msgstr "GetParametersIns" #: ../../source/ref-api/flwr.common.GetParametersIns.rst:28::1 msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:2 msgid "GetParametersRes" -msgstr "" +msgstr "GetParametersRes" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.GetParametersRes.rst:29::1 msgid ":py:obj:`parameters `\\" -msgstr "" +msgstr ":py:obj:`parameters `\\" #: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:2 msgid "GetPropertiesIns" -msgstr "" +msgstr "GetPropertiesIns" #: ../../source/ref-api/flwr.common.GetPropertiesIns.rst:28::1 msgid ":py:obj:`config `\\" -msgstr "" +msgstr ":py:obj:`config `\\" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:2 msgid "GetPropertiesRes" -msgstr "" +msgstr "GetPropertiesRes" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 msgid ":py:obj:`status `\\" -msgstr "" +msgstr ":py:obj:`status `\\" #: ../../source/ref-api/flwr.common.GetPropertiesRes.rst:29::1 msgid ":py:obj:`properties `\\" -msgstr "" +msgstr ":py:obj:`properties `\\" #: ../../source/ref-api/flwr.common.Message.rst:2 msgid "Message" -msgstr "" +msgstr "Message" #: flwr.common.Message.content:1::1 flwr.common.Message.metadata:1 #: flwr.common.message.Message:3 of msgid "A dataclass including information about the message to be executed." -msgstr "" +msgstr "실행할 메시지에 대한 정보를 포함한 데이터 클래스입니다." #: flwr.common.message.Message:5 of msgid "" -"Holds records either sent by another entity (e.g. sent by the server-side" -" logic to a client, or vice-versa) or that will be sent to it." -msgstr "" +"Holds records either sent by another entity (e.g. sent by the server-side " +"logic to a client, or vice-versa) or that will be sent to it." +msgstr "다른 엔터티(예: 서버 측 로직이 클라이언트로 전송하거나 그 반대로 전송하는 등)" +"가 전송했거나 전송할 레코드를 보유합니다." #: flwr.common.message.Message:8 of msgid "" -"A dataclass that captures information about an error that took place when" -" processing another message." -msgstr "" +"A dataclass that captures information about an error that took place when " +"processing another message." +msgstr "다른 메시지를 처리할 때 발생한 오류에 대한 정보를 캡처하는 데이터 " +"클래스입니다." #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" ":py:obj:`create_error_reply `\\ " "\\(error\\[\\, ttl\\]\\)" msgstr "" +":py:obj:`create_error_reply `\\ \\(" +"error\\[\\, ttl\\]\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.create_error_reply:1 of msgid "Construct a reply message indicating an error happened." -msgstr "" +msgstr "오류가 발생했음을 나타내는 답장 메시지를 작성합니다." #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid "" -":py:obj:`create_reply `\\ " -"\\(content\\[\\, ttl\\]\\)" +":py:obj:`create_reply `\\ \\(content\\[\\, " +"ttl\\]\\)" msgstr "" +":py:obj:`create_reply `\\ \\(content\\[\\, " +"ttl\\]\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.create_reply:1 of msgid "Create a reply to this message with specified content and TTL." -msgstr "" +msgstr "지정된 콘텐츠와 TTL을 사용하여 이 메시지에 대한 답글을 작성합니다." #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid ":py:obj:`has_content `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`has_content `\\ \\(\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.has_content:1 of msgid "Return True if message has content, else False." -msgstr "" +msgstr "메시지에 콘텐츠가 있으면 True을 반환하고, 그렇지 않으면 False을 반환합니다." #: ../../source/ref-api/flwr.common.Message.rst:35::1 msgid ":py:obj:`has_error `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`has_error `\\ \\(\\)" #: ../../source/ref-api/flwr.common.Message.rst:35::1 #: flwr.common.message.Message.has_error:1 of msgid "Return True if message has an error, else False." -msgstr "" +msgstr "메시지에 오류가 있으면 True을 반환하고, 그렇지 않으면 False을 반환합니다." #: flwr.common.Message.content:1::1 of msgid ":py:obj:`content `\\" -msgstr "" +msgstr ":py:obj:`content `\\" #: flwr.common.Message.content:1 flwr.common.Message.content:1::1 #: of msgid "The content of this message." -msgstr "" +msgstr "이 메시지의 내용입니다." #: flwr.common.Message.content:1::1 of msgid ":py:obj:`error `\\" -msgstr "" +msgstr ":py:obj:`error `\\" #: flwr.common.Message.content:1::1 flwr.common.Message.error:1 of msgid "Error captured by this message." -msgstr "" +msgstr "이 메시지가 캡처한 오류입니다." #: flwr.common.Message.content:1::1 of msgid ":py:obj:`metadata `\\" -msgstr "" +msgstr ":py:obj:`metadata `\\" #: flwr.common.message.Message.create_error_reply:3 of msgid "The error that was encountered." -msgstr "" +msgstr "오류가 발생했습니다." #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based " -"on the remaining time for the received message before it expires. This " -"follows the equation: ttl = msg.meta.ttl - (reply.meta.created_at - " -"msg.meta.created_at)" +"Time-to-live for this message in seconds. If unset, it will be set based on " +"the remaining time for the received message before it expires. This follows " +"the equation: ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta." +"created_at)" msgstr "" +"이 메시지의 남은 시간(초)입니다. 설정하지 않으면 수신된 메시지가 만료되기 " +"전까지 남은 시간을 기준으로 설정됩니다. 이는 다음과 같은 공식을 따릅니다: " +"ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" #: flwr.common.message.Message.create_error_reply:5 #: flwr.common.message.Message.create_reply:9 of msgid "" -"Time-to-live for this message in seconds. If unset, it will be set based " -"on the remaining time for the received message before it expires. This " -"follows the equation:" +"Time-to-live for this message in seconds. If unset, it will be set based on " +"the remaining time for the received message before it expires. This follows " +"the equation:" msgstr "" +"이 메시지의 남은 시간(초)입니다. 설정하지 않으면 수신된 메시지가 만료되기 " +"전까지 남은 시간을 기준으로 설정됩니다. 이는 다음 공식을 따릅니다:" #: flwr.common.message.Message.create_error_reply:9 #: flwr.common.message.Message.create_reply:13 of msgid "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" -msgstr "" +msgstr "ttl = msg.meta.ttl - (reply.meta.created_at - msg.meta.created_at)" #: flwr.common.message.Message.create_reply:3 of msgid "" -"The method generates a new `Message` as a reply to this message. It " -"inherits 'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from " -"this message and sets 'reply_to_message' to the ID of this message." +"The method generates a new `Message` as a reply to this message. It inherits " +"'run_id', 'src_node_id', 'dst_node_id', and 'message_type' from this message " +"and sets 'reply_to_message' to the ID of this message." msgstr "" +"이 메서드는 이 메시지에 대한 응답으로 새로운 '메시지'를 생성합니다. 이 " +"메시지에서 'run_id', 'src_node_id', 'dst_node_id', 'message_type'을 상속하고 " +"'reply_to_message'를 이 메시지의 ID로 설정합니다." #: flwr.common.message.Message.create_reply:7 of msgid "The content for the reply message." -msgstr "" +msgstr "답장 메시지의 콘텐츠입니다." #: flwr.common.message.Message.create_reply:16 of msgid "A new `Message` instance representing the reply." -msgstr "" +msgstr "답장을 나타내는 새로운 `메시지` 인스턴스입니다." #: ../../source/ref-api/flwr.common.MessageType.rst:2 msgid "MessageType" -msgstr "" +msgstr "MessageType" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 msgid ":py:obj:`EVALUATE `\\" -msgstr "" +msgstr ":py:obj:`EVALUATE `\\" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 msgid ":py:obj:`QUERY `\\" -msgstr "" +msgstr ":py:obj:`QUERY `\\" #: ../../source/ref-api/flwr.common.MessageType.rst:30::1 msgid ":py:obj:`TRAIN `\\" -msgstr "" +msgstr ":py:obj:`TRAIN `\\" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:2 msgid "MessageTypeLegacy" -msgstr "" +msgstr "MessageTypeLegacy" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PARAMETERS `\\" +msgid "" +":py:obj:`GET_PARAMETERS `\\" msgstr "" +":py:obj:`GET_PARAMETERS `\\" #: ../../source/ref-api/flwr.common.MessageTypeLegacy.rst:29::1 -msgid ":py:obj:`GET_PROPERTIES `\\" +msgid "" +":py:obj:`GET_PROPERTIES `\\" msgstr "" +":py:obj:`GET_PROPERTIES `\\" #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.run_id:1 flwr.common.message.Metadata:3 of msgid "An identifier for the current run." -msgstr "" +msgstr "현재 실행에 대한 식별자입니다." #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.message_id:1 flwr.common.message.Metadata:5 of msgid "An identifier for the current message." -msgstr "" +msgstr "현재 메시지의 식별자입니다." #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.src_node_id:1 flwr.common.message.Metadata:7 of msgid "An identifier for the node sending this message." -msgstr "" +msgstr "이 메시지를 보내는 노드의 식별자입니다." #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.dst_node_id:1 flwr.common.message.Metadata:9 of msgid "An identifier for the node receiving this message." -msgstr "" +msgstr "이 메시지를 수신하는 노드의 식별자입니다." #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.reply_to_message:1 flwr.common.message.Metadata:11 of msgid "An identifier for the message this message replies to." -msgstr "" +msgstr "이 메시지가 회신하는 메시지의 식별자입니다." #: flwr.common.message.Metadata:13 of msgid "" -"An identifier for grouping messages. In some settings, this is used as " -"the FL round." -msgstr "" +"An identifier for grouping messages. In some settings, this is used as the " +"FL round." +msgstr "메시지를 그룹화하기 위한 식별자입니다. 일부 설정에서는 FL 라운드로 " +"사용됩니다." #: flwr.common.message.Metadata:16 of msgid "Time-to-live for this message in seconds." -msgstr "" +msgstr "이 메시지의 유효 시간(초)입니다." #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.message_type:1 flwr.common.message.Metadata:18 of msgid "A string that encodes the action to be executed on the receiving end." -msgstr "" +msgstr "수신 측에서 실행할 작업을 인코딩하는 문자열입니다." #: flwr.common.message.Metadata:21 of msgid "" -"An identifier that can be used when loading a particular data partition " -"for a ClientApp. Making use of this identifier is more relevant when " -"conducting simulations." +"An identifier that can be used when loading a particular data partition for " +"a ClientApp. Making use of this identifier is more relevant when conducting " +"simulations." msgstr "" +"클라이언트 앱의 특정 데이터 파티션을 로드할 때 사용할 수 있는 식별자입니다. " +"시뮬레이션을 수행할 때 이 식별자를 사용하는 것이 더 적절합니다." #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`created_at `\\" -msgstr "" +msgstr ":py:obj:`created_at `\\" #: flwr.common.Metadata.created_at:1 #: flwr.common.Metadata.created_at:1::1 of msgid "Unix timestamp when the message was created." -msgstr "" +msgstr "메시지가 생성된 때의 Unix timestamp입니다." #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`dst_node_id `\\" -msgstr "" +msgstr ":py:obj:`dst_node_id `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`group_id `\\" -msgstr "" +msgstr ":py:obj:`group_id `\\" #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.group_id:1 of msgid "An identifier for grouping messages." -msgstr "" +msgstr "메시지를 그룹화하기 위한 식별자입니다." #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`message_id `\\" -msgstr "" +msgstr ":py:obj:`message_id `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`message_type `\\" -msgstr "" +msgstr ":py:obj:`message_type `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`partition_id `\\" -msgstr "" +msgstr ":py:obj:`partition_id `\\" #: flwr.common.Metadata.created_at:1::1 #: flwr.common.Metadata.partition_id:1 of msgid "An identifier telling which data partition a ClientApp should use." -msgstr "" +msgstr "클라이언트앱이 사용해야 하는 데이터 파티션을 알려주는 식별자입니다." #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`reply_to_message `\\" -msgstr "" +msgstr ":py:obj:`reply_to_message `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`run_id `\\" -msgstr "" +msgstr ":py:obj:`run_id `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`src_node_id `\\" -msgstr "" +msgstr ":py:obj:`src_node_id `\\" #: flwr.common.Metadata.created_at:1::1 of msgid ":py:obj:`ttl `\\" -msgstr "" +msgstr ":py:obj:`ttl `\\" #: flwr.common.Metadata.created_at:1::1 flwr.common.Metadata.ttl:1 #: of msgid "Time-to-live for this message." -msgstr "" +msgstr "이 메시지를 기다리는 시간입니다." #: ../../source/ref-api/flwr.common.MetricsRecord.rst:2 msgid "MetricsRecord" -msgstr "" +msgstr "MetricsRecord" #: flwr.common.record.metricsrecord.MetricsRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`int` | :py:class:`float` | " -":py:class:`~typing.List`\\ [:py:class:`int`] | :py:class:`~typing.List`\\" -" [:py:class:`float`]]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`int` | :py:class:`float` | :py:class:`~typing.List`\\ [:py:" +"class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`]]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:class:`int` | :py:class:`float` | :py:class:`~typing.List`\\ " +"[:py:class:`int`] | :py:class:`~typing.List`\\ [:py:class:`float`]]" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`count_bytes `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" +")" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`values `\\ \\(\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*F\\" +")" #: ../../source/ref-api/flwr.common.NDArray.rst:2 msgid "NDArray" -msgstr "" +msgstr "NDArray" #: ../../source/ref-api/flwr.common.Parameters.rst:29::1 msgid ":py:obj:`tensors `\\" -msgstr "" +msgstr ":py:obj:`tensors `\\" #: ../../source/ref-api/flwr.common.Parameters.rst:29::1 msgid ":py:obj:`tensor_type `\\" -msgstr "" +msgstr ":py:obj:`tensor_type `\\" #: ../../source/ref-api/flwr.common.ParametersRecord.rst:2 msgid "ParametersRecord" -msgstr "" +msgstr "ParametersRecord" #: flwr.common.record.parametersrecord.ParametersRecord:1 of msgid "" -"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ " -"[:py:class:`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:" +"`str`, :py:class:`~flwr.common.record.parametersrecord.Array`]" msgstr "" +"Bases: :py:class:`~flwr.common.record.typeddict.TypedDict`\\ [:py:class:`str`" +", :py:class:`~flwr.common.record.parametersrecord.Array`]" #: flwr.common.record.parametersrecord.ParametersRecord:3 of msgid "" -"A dataclass storing named Arrays in order. This means that it holds " -"entries as an OrderedDict[str, Array]. ParametersRecord objects can be " -"viewed as an equivalent to PyTorch's state_dict, but holding serialised " -"tensors instead." +"A dataclass storing named Arrays in order. This means that it holds entries " +"as an OrderedDict[str, Array]. ParametersRecord objects can be viewed as an " +"equivalent to PyTorch's state_dict, but holding serialised tensors instead." msgstr "" +"Arrays라는 이름의 데이터 클래스를 순서대로 저장합니다. 즉, OrderedDict[str, " +"Array]로 항목을 보유합니다. ParametersRecord 객체는 파이토치의 state_dict와 " +"동등한 것으로 볼 수 있지만, 대신 직렬화된 텐서를 보유합니다." #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`clear `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`clear `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of -msgid ":py:obj:`count_bytes `\\ \\(\\)" +msgid "" +":py:obj:`count_bytes `\\ \\(\\)" msgstr "" +":py:obj:`count_bytes `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`get `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`items `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`items `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`keys `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`keys `\\ \\(\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" -msgstr "" +msgstr ":py:obj:`pop `\\ \\(k\\[\\,d\\]\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid "" ":py:obj:`update `\\ \\(\\[E\\, " "\\]\\*\\*F\\)" msgstr "" +":py:obj:`update `\\ \\(\\[E\\, \\]\\*\\*" +"F\\)" #: flwr.common.record.typeddict.TypedDict.clear:1::1 of msgid ":py:obj:`values `\\ \\(\\)" -msgstr "" +msgstr ":py:obj:`values `\\ \\(\\)" #: flwr.common.record.parametersrecord.ParametersRecord.count_bytes:3 of msgid "" -"Note that a small amount of Bytes might also be included in this counting" -" that correspond to metadata of the serialized object (e.g. of NumPy " -"array) needed for deseralization." -msgstr "" +"Note that a small amount of Bytes might also be included in this counting " +"that correspond to metadata of the serialized object (e.g. of NumPy array) " +"needed for deseralization." +msgstr "역직렬화에 필요한 직렬화된 객체의 메타데이터(예: NumPy 배열)에 해당하는 " +"소량의 바이트도 이 카운팅에 포함될 수 있습니다." #: ../../source/ref-api/flwr.common.ReconnectIns.rst:2 msgid "ReconnectIns" -msgstr "" +msgstr "ReconnectIns" #: ../../source/ref-api/flwr.common.ReconnectIns.rst:28::1 msgid ":py:obj:`seconds `\\" -msgstr "" +msgstr ":py:obj:`seconds `\\" #: ../../source/ref-api/flwr.common.RecordSet.rst:2 msgid "RecordSet" -msgstr "" +msgstr "RecordSet" #: flwr.common.RecordSet.configs_records:1::1 of msgid ":py:obj:`configs_records `\\" -msgstr "" +msgstr ":py:obj:`configs_records `\\" #: flwr.common.RecordSet.configs_records:1 #: flwr.common.RecordSet.configs_records:1::1 of msgid "Dictionary holding ConfigsRecord instances." -msgstr "" +msgstr "Dictionary holding ConfigsRecord instances." #: flwr.common.RecordSet.configs_records:1::1 of msgid ":py:obj:`metrics_records `\\" -msgstr "" +msgstr ":py:obj:`metrics_records `\\" #: flwr.common.RecordSet.configs_records:1::1 #: flwr.common.RecordSet.metrics_records:1 of msgid "Dictionary holding MetricsRecord instances." -msgstr "" +msgstr "Dictionary holding MetricsRecord instances." #: flwr.common.RecordSet.configs_records:1::1 of -msgid ":py:obj:`parameters_records `\\" +msgid "" +":py:obj:`parameters_records `\\" msgstr "" +":py:obj:`parameters_records `\\" #: flwr.common.RecordSet.configs_records:1::1 #: flwr.common.RecordSet.parameters_records:1 of msgid "Dictionary holding ParametersRecord instances." -msgstr "" +msgstr "Dictionary holding ParametersRecord instances." #: ../../source/ref-api/flwr.common.ServerMessage.rst:2 msgid "ServerMessage" -msgstr "" +msgstr "ServerMessage" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid ":py:obj:`evaluate_ins `\\" -msgstr "" +msgstr ":py:obj:`evaluate_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid ":py:obj:`fit_ins `\\" -msgstr "" +msgstr ":py:obj:`fit_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_parameters_ins " -"`\\" +":py:obj:`get_parameters_ins `\\" msgstr "" +":py:obj:`get_parameters_ins `\\" #: ../../source/ref-api/flwr.common.ServerMessage.rst:31::1 msgid "" -":py:obj:`get_properties_ins " -"`\\" +":py:obj:`get_properties_ins `\\" msgstr "" +":py:obj:`get_properties_ins `\\" #: ../../source/ref-api/flwr.common.Status.rst:2 msgid "Status" -msgstr "" +msgstr "Status" #: ../../source/ref-api/flwr.common.Status.rst:29::1 msgid ":py:obj:`code `\\" -msgstr "" +msgstr ":py:obj:`code `\\" #: ../../source/ref-api/flwr.common.Status.rst:29::1 msgid ":py:obj:`message `\\" -msgstr "" +msgstr ":py:obj:`message `\\" #: ../../source/ref-api/flwr.common.array_from_numpy.rst:2 msgid "array\\_from\\_numpy" -msgstr "" +msgstr "array\\_from\\_numpy" #: ../../source/ref-api/flwr.common.bytes_to_ndarray.rst:2 msgid "bytes\\_to\\_ndarray" -msgstr "" +msgstr "bytes\\_to\\_ndarray" #: ../../source/ref-api/flwr.common.configure.rst:2 msgid "configure" -msgstr "" +msgstr "구성" #: ../../source/ref-api/flwr.common.event.rst:2 msgid "event" -msgstr "" +msgstr "이벤트" #: ../../source/ref-api/flwr.common.log.rst:2 msgid "log" -msgstr "" +msgstr "로그" #: logging.Logger.log:3 of msgid "" -"To pass exception information, use the keyword argument exc_info with a " -"true value, e.g." -msgstr "" +"To pass exception information, use the keyword argument exc_info with a true " +"value, e.g." +msgstr "예외 정보를 전달하려면 키워드 argument exc_info를 참 값과 함께 사용합니다." #: logging.Logger.log:6 of #, python-format @@ -10993,8 +11809,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.rst:38::1 msgid "" -":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\," -" round\\_timeout\\]\\)" +":py:obj:`ServerConfig `\\ \\(\\[num\\_rounds\\, " +"round\\_timeout\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.rst:38::1 @@ -11003,7 +11819,8 @@ msgid "Flower server config." msgstr "" #: ../../source/ref-api/flwr.server.rst:38::1 -msgid ":py:obj:`SimpleClientManager `\\ \\(\\)" +msgid "" +":py:obj:`SimpleClientManager `\\ \\(\\)" msgstr "" #: ../../source/ref-api/flwr.server.rst:38::1 @@ -11045,7 +11862,8 @@ msgid "Return all available clients." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`num_available `\\ \\(\\)" +msgid "" +":py:obj:`num_available `\\ \\(\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -11068,8 +11886,8 @@ msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of msgid "" -":py:obj:`sample `\\ " -"\\(num\\_clients\\[\\, min\\_num\\_clients\\, criterion\\]\\)" +":py:obj:`sample `\\ \\(num\\_clients\\[\\, " +"min\\_num\\_clients\\, criterion\\]\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -11080,7 +11898,8 @@ msgid "Sample a number of Flower ClientProxy instances." msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 of -msgid ":py:obj:`unregister `\\ \\(client\\)" +msgid "" +":py:obj:`unregister `\\ \\(client\\)" msgstr "" #: flwr.server.client_manager.ClientManager.all:1::1 @@ -11112,8 +11931,7 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.register:6 of msgid "" "**success** -- Indicating if registration was successful. False if " -"ClientProxy is already registered or can not be registered for any " -"reason." +"ClientProxy is already registered or can not be registered for any reason." msgstr "" #: flwr.server.client_manager.ClientManager.unregister:3 @@ -11127,8 +11945,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`create_message `\\ " -"\\(content\\, message\\_type\\, ...\\[\\, ttl\\]\\)" +":py:obj:`create_message `\\ \\(content\\, " +"message\\_type\\, ...\\[\\, ttl\\]\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1 @@ -11158,8 +11976,7 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 of msgid "" -":py:obj:`push_messages `\\ " -"\\(messages\\)" +":py:obj:`push_messages `\\ \\(messages\\)" msgstr "" #: flwr.server.driver.driver.Driver.create_message:1::1 @@ -11180,20 +11997,20 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:3 of msgid "" -"This method constructs a new `Message` with given content and metadata. " -"The `run_id` and `src_node_id` will be set automatically." +"This method constructs a new `Message` with given content and metadata. The " +"`run_id` and `src_node_id` will be set automatically." msgstr "" #: flwr.server.driver.driver.Driver.create_message:6 of msgid "" -"The content for the new message. This holds records that are to be sent " -"to the destination node." +"The content for the new message. This holds records that are to be sent to " +"the destination node." msgstr "" #: flwr.server.driver.driver.Driver.create_message:9 of msgid "" -"The type of the message, defining the action to be executed on the " -"receiving end." +"The type of the message, defining the action to be executed on the receiving " +"end." msgstr "" #: flwr.server.driver.driver.Driver.create_message:12 of @@ -11202,17 +12019,16 @@ msgstr "" #: flwr.server.driver.driver.Driver.create_message:14 of msgid "" -"The ID of the group to which this message is associated. In some " -"settings, this is used as the FL round." +"The ID of the group to which this message is associated. In some settings, " +"this is used as the FL round." msgstr "" #: flwr.server.driver.driver.Driver.create_message:17 of msgid "" -"Time-to-live for the round trip of this message, i.e., the time from " -"sending this message to receiving a reply. It specifies in seconds the " -"duration for which the message and its potential reply are considered " -"valid. If unset, the default TTL (i.e., `common.DEFAULT_TTL`) will be " -"used." +"Time-to-live for the round trip of this message, i.e., the time from sending " +"this message to receiving a reply. It specifies in seconds the duration for " +"which the message and its potential reply are considered valid. If unset, " +"the default TTL (i.e., `common.DEFAULT_TTL`) will be used." msgstr "" #: flwr.server.driver.driver.Driver.create_message:23 of @@ -11223,12 +12039,13 @@ msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:3 of msgid "" -"This method is used to collect messages from the SuperLink that " -"correspond to a set of given message IDs." +"This method is used to collect messages from the SuperLink that correspond " +"to a set of given message IDs." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:6 of -msgid "An iterable of message IDs for which reply messages are to be retrieved." +msgid "" +"An iterable of message IDs for which reply messages are to be retrieved." msgstr "" #: flwr.server.driver.driver.Driver.pull_messages:9 of @@ -11237,8 +12054,8 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:3 of msgid "" -"This method takes an iterable of messages and sends each message to the " -"node specified in `dst_node_id`." +"This method takes an iterable of messages and sends each message to the node " +"specified in `dst_node_id`." msgstr "" #: flwr.server.driver.driver.Driver.push_messages:6 @@ -11248,34 +12065,35 @@ msgstr "" #: flwr.server.driver.driver.Driver.push_messages:9 of msgid "" -"**message_ids** -- An iterable of IDs for the messages that were sent, " -"which can be used to pull replies." +"**message_ids** -- An iterable of IDs for the messages that were sent, which " +"can be used to pull replies." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:3 of msgid "" -"This method sends a list of messages to their destination node IDs and " -"then waits for the replies. It continues to pull replies until either all" -" replies are received or the specified timeout duration is exceeded." +"This method sends a list of messages to their destination node IDs and then " +"waits for the replies. It continues to pull replies until either all replies " +"are received or the specified timeout duration is exceeded." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:9 of msgid "" "The timeout duration in seconds. If specified, the method will wait for " -"replies for this duration. If `None`, there is no time limit and the " -"method will wait until replies for all messages are received." +"replies for this duration. If `None`, there is no time limit and the method " +"will wait until replies for all messages are received." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:14 of -msgid "**replies** -- An iterable of reply messages received from the SuperLink." +msgid "" +"**replies** -- An iterable of reply messages received from the SuperLink." msgstr "" #: flwr.server.driver.driver.Driver.send_and_receive:19 of msgid "" -"This method uses `push_messages` to send the messages and `pull_messages`" -" to collect the replies. If `timeout` is set, the method may not return " -"replies for all sent messages. A message remains valid until its TTL, " -"which is not affected by `timeout`." +"This method uses `push_messages` to send the messages and `pull_messages` to " +"collect the replies. If `timeout` is set, the method may not return replies " +"for all sent messages. A message remains valid until its TTL, which is not " +"affected by `timeout`." msgstr "" #: ../../source/ref-api/flwr.server.History.rst:2 @@ -11284,9 +12102,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_centralized " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_centralized `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1 @@ -11296,9 +12113,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_loss_distributed " -"`\\ \\(server\\_round\\, " -"loss\\)" +":py:obj:`add_loss_distributed `\\ " +"\\(server\\_round\\, loss\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -11308,9 +12124,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_centralized " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_centralized `\\ \\(server\\_round\\, metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -11320,9 +12135,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed " -"`\\ \\(server\\_round\\, " -"metrics\\)" +":py:obj:`add_metrics_distributed `\\ \\(server\\_round\\, metrics\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -11332,9 +12146,8 @@ msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 of msgid "" -":py:obj:`add_metrics_distributed_fit " -"`\\ \\(server\\_round\\," -" ...\\)" +":py:obj:`add_metrics_distributed_fit `\\ \\(server\\_round\\, ...\\)" msgstr "" #: flwr.server.history.History.add_loss_centralized:1::1 @@ -11385,8 +12198,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`disconnect_all_clients " -"`\\ \\(timeout\\)" +":py:obj:`disconnect_all_clients `\\ \\(timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -11416,8 +12229,8 @@ msgstr "" #: flwr.server.server.Server.client_manager:1::1 of msgid "" -":py:obj:`fit_round `\\ \\(server\\_round\\," -" timeout\\)" +":py:obj:`fit_round `\\ \\(server\\_round\\, " +"timeout\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -11437,7 +12250,8 @@ msgid "Set the max_workers used by ThreadPoolExecutor." msgstr "" #: flwr.server.server.Server.client_manager:1::1 of -msgid ":py:obj:`set_strategy `\\ \\(strategy\\)" +msgid "" +":py:obj:`set_strategy `\\ \\(strategy\\)" msgstr "" #: flwr.server.server.Server.client_manager:1::1 @@ -11472,8 +12286,8 @@ msgstr "" #: flwr.server.server_config.ServerConfig:3 of msgid "" -"All attributes have default values which allows users to configure just " -"the ones they care about." +"All attributes have default values which allows users to configure just the " +"ones they care about." msgstr "" #: ../../source/ref-api/flwr.server.ServerConfig.rst:29::1 @@ -11498,14 +12312,13 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`num_available `\\" -" \\(\\)" +":py:obj:`num_available `\\ " +"\\(\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of msgid "" -":py:obj:`register `\\ " -"\\(client\\)" +":py:obj:`register `\\ \\(client\\)" msgstr "" #: flwr.server.client_manager.SimpleClientManager.all:1::1 of @@ -11528,8 +12341,8 @@ msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:3 of msgid "" -"Blocks until the requested number of clients is available or until a " -"timeout is reached. Current timeout default: 1 day." +"Blocks until the requested number of clients is available or until a timeout " +"is reached. Current timeout default: 1 day." msgstr "" #: flwr.server.client_manager.SimpleClientManager.wait_for:6 of @@ -11570,8 +12383,8 @@ msgstr "" #: flwr.server.app.start_server:5 of msgid "" -"A server implementation, either `flwr.server.Server` or a subclass " -"thereof. If no instance is provided, then `start_server` will create one." +"A server implementation, either `flwr.server.Server` or a subclass thereof. " +"If no instance is provided, then `start_server` will create one." msgstr "" #: flwr.server.app.start_server:9 flwr.simulation.app.start_simulation:28 of @@ -11582,41 +12395,41 @@ msgstr "" #: flwr.server.app.start_server:12 of msgid "" -"An implementation of the abstract base class " -"`flwr.server.strategy.Strategy`. If no strategy is provided, then " -"`start_server` will use `flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.strategy." +"Strategy`. If no strategy is provided, then `start_server` will use `flwr." +"server.strategy.FedAvg`." msgstr "" #: flwr.server.app.start_server:16 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_server` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_server` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" #: flwr.server.app.start_server:21 of msgid "" -"The maximum length of gRPC messages that can be exchanged with the Flower" -" clients. The default should be sufficient for most models. Users who " -"train very large models might need to increase this value. Note that the " -"Flower clients need to be started with the same value (see " -"`flwr.client.start_client`), otherwise clients will not know about the " -"increased limit and block larger messages." +"The maximum length of gRPC messages that can be exchanged with the Flower " +"clients. The default should be sufficient for most models. Users who train " +"very large models might need to increase this value. Note that the Flower " +"clients need to be started with the same value (see `flwr.client." +"start_client`), otherwise clients will not know about the increased limit " +"and block larger messages." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order: * CA certificate. * " -"server certificate. * server private key." +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order: * CA certificate. * server " +"certificate. * server private key." msgstr "" #: flwr.server.app.start_server:28 of msgid "" -"Tuple containing root certificate, server certificate, and private key to" -" start a secure SSL-enabled server. The tuple is expected to have three " -"bytes elements in the following order:" +"Tuple containing root certificate, server certificate, and private key to " +"start a secure SSL-enabled server. The tuple is expected to have three bytes " +"elements in the following order:" msgstr "" #: flwr.server.app.start_server:32 of @@ -11649,8 +12462,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Bulyan `\\ \\(\\*\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\)" +":py:obj:`Bulyan `\\ \\(\\*\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11682,9 +12495,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideAdaptiveClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11695,9 +12507,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideAdaptiveClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11708,9 +12519,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyClientSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyClientSideFixedClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11721,9 +12531,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`DifferentialPrivacyServerSideFixedClipping " -"`\\ " -"\\(...\\)" +":py:obj:`DifferentialPrivacyServerSideFixedClipping `\\ \\(...\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11768,8 +12577,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedAvgAndroid `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedAvgAndroid `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11818,8 +12627,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FedTrimmedAvg `\\ " -"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" +":py:obj:`FedTrimmedAvg `\\ \\(\\*\\[\\, " +"fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11873,9 +12682,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`FaultTolerantFedAvg " -"`\\ \\(\\*\\[\\, " -"fraction\\_fit\\, ...\\]\\)" +":py:obj:`FaultTolerantFedAvg `\\ " +"\\(\\*\\[\\, fraction\\_fit\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11885,8 +12693,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`Krum `\\ \\(\\*\\[\\, " -"fraction\\_fit\\, fraction\\_evaluate\\, ...\\]\\)" +":py:obj:`Krum `\\ \\(\\*\\[\\, fraction\\_fit\\, " +"fraction\\_evaluate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -11896,8 +12704,8 @@ msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 msgid "" -":py:obj:`QFedAvg `\\ \\(\\*\\[\\, " -"q\\_param\\, qffl\\_learning\\_rate\\, ...\\]\\)" +":py:obj:`QFedAvg `\\ \\(\\*\\[\\, q\\_param\\, " +"qffl\\_learning\\_rate\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.rst:45::1 @@ -12065,8 +12873,8 @@ msgstr "" #: flwr.server.strategy.bulyan.Bulyan:27 of msgid "" -"Byzantine resilient aggregation rule that is used as the first step of " -"the Bulyan (e.g., Krum)" +"Byzantine resilient aggregation rule that is used as the first step of the " +"Bulyan (e.g., Krum)" msgstr "" #: flwr.server.strategy.bulyan.Bulyan:29 of @@ -12075,9 +12883,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1 @@ -12104,9 +12911,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -12185,9 +12991,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -12204,9 +13009,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -12223,8 +13027,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -12255,9 +13059,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1 @@ -12277,9 +13080,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dpfedavg_adaptive.DPFedAvgAdaptive.aggregate_fit:1 @@ -12291,9 +13093,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12304,9 +13105,8 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12326,15 +13126,15 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.evaluate:1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.evaluate:1 of -msgid "Evaluate model parameters using an evaluation function from the strategy." +msgid "" +"Evaluate model parameters using an evaluation function from the strategy." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -12373,9 +13173,9 @@ msgstr "" msgid "" "**evaluate_configuration** -- A list of tuples. Each tuple in the list " "identifies a `ClientProxy` and the `EvaluateIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated evaluation." +"`ClientProxy`. If a particular `ClientProxy` is not included in this list, " +"it means that this `ClientProxy` will not participate in the next round of " +"federated evaluation." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DPFedAvgFixed.rst:2 @@ -12395,16 +13195,14 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -12416,24 +13214,21 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:1 of msgid "" -"Configure the next round of training incorporating Differential Privacy " -"(DP)." +"Configure the next round of training incorporating Differential Privacy (DP)." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 @@ -12446,25 +13241,23 @@ msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:3 of msgid "" -"Configuration of the next training round includes information related to " -"DP, such as clip norm and noise stddev." +"Configuration of the next training round includes information related to DP, " +"such as clip norm and noise stddev." msgstr "" #: flwr.server.strategy.dpfedavg_fixed.DPFedAvgFixed.configure_fit:13 #: flwr.server.strategy.strategy.Strategy.configure_fit:10 of msgid "" -"**fit_configuration** -- A list of tuples. Each tuple in the list " -"identifies a `ClientProxy` and the `FitIns` for this particular " -"`ClientProxy`. If a particular `ClientProxy` is not included in this " -"list, it means that this `ClientProxy` will not participate in the next " -"round of federated learning." +"**fit_configuration** -- A list of tuples. Each tuple in the list identifies " +"a `ClientProxy` and the `FitIns` for this particular `ClientProxy`. If a " +"particular `ClientProxy` is not included in this list, it means that this " +"`ClientProxy` will not participate in the next round of federated learning." msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideAdaptiveClipping.rst:2 @@ -12481,9 +13274,8 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideAdaptiveClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to " -"happen on the client-side, usually by using the built-in " -"`adaptiveclipping_mod`." +"`DifferentialPrivacyClientSideAdaptiveClipping` expects clipping to happen " +"on the client-side, usually by using the built-in `adaptiveclipping_mod`." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:10 @@ -12519,22 +13311,23 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:19 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:12 #: of -msgid "The desired quantile of updates which should be clipped. Defaults to 0.5." +msgid "" +"The desired quantile of updates which should be clipped. Defaults to 0.5." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:21 #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:14 #: of msgid "" -"The learning rate for the clipping norm adaptation. Defaults to 0.2. " -"Andrew et al. recommends to set to 0.2." +"The learning rate for the clipping norm adaptation. Defaults to 0.2. Andrew " +"et al. recommends to set to 0.2." msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:24 #: of msgid "" -"The stddev of the noise added to the count of updates currently below the" -" estimate. Andrew et al. recommends to set to `expected_num_records/20`" +"The stddev of the noise added to the count of updates currently below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:30 @@ -12548,8 +13341,8 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:34 #: of msgid "" -"Wrap the strategy with the " -"`DifferentialPrivacyClientSideAdaptiveClipping` wrapper:" +"Wrap the strategy with the `DifferentialPrivacyClientSideAdaptiveClipping` " +"wrapper:" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping:40 @@ -12560,17 +13353,17 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 @@ -12584,33 +13377,33 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyClientSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyClientSideFixedClipping.rst:2 @@ -12627,16 +13420,16 @@ msgstr "" msgid "" "In comparison to `DifferentialPrivacyServerSideFixedClipping`, which " "performs clipping on the server-side, " -"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen " -"on the client-side, usually by using the built-in `fixedclipping_mod`." +"`DifferentialPrivacyClientSideFixedClipping` expects clipping to happen on " +"the client-side, usually by using the built-in `fixedclipping_mod`." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:12 #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:5 #: of msgid "" -"The noise multiplier for the Gaussian mechanism for model updates. A " -"value of 1.0 or higher is recommended for strong privacy." +"The noise multiplier for the Gaussian mechanism for model updates. A value " +"of 1.0 or higher is recommended for strong privacy." msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping:26 @@ -12654,17 +13447,17 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 @@ -12676,33 +13469,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyClientSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideAdaptiveClipping.rst:2 @@ -12712,9 +13505,8 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:17 #: of msgid "" -"The standard deviation of the noise added to the count of updates below " -"the estimate. Andrew et al. recommends to set to " -"`expected_num_records/20`" +"The standard deviation of the noise added to the count of updates below the " +"estimate. Andrew et al. recommends to set to `expected_num_records/20`" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping:27 @@ -12727,49 +13519,49 @@ msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ " +"\\(server\\_round\\, parameters\\)" msgstr "" #: flwr.server.strategy.dp_adaptive_clipping.DifferentialPrivacyServerSideAdaptiveClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.DifferentialPrivacyServerSideFixedClipping.rst:2 @@ -12779,24 +13571,23 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping:19 #: of msgid "" -"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping " -"wrapper" +"Wrap the strategy with the DifferentialPrivacyServerSideFixedClipping wrapper" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\" -" \\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ " +"\\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 @@ -12808,33 +13599,33 @@ msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`evaluate " -"`\\" -" \\(server\\_round\\, parameters\\)" +":py:obj:`evaluate `\\ \\(server\\_round\\, " +"parameters\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\" -" \\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ " +"\\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.dp_fixed_clipping.DifferentialPrivacyServerSideFixedClipping.aggregate_fit:3 @@ -12849,17 +13640,15 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " -"\\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ \\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -12881,17 +13670,15 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 @@ -12904,25 +13691,22 @@ msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fault_tolerant_fedavg.FaultTolerantFedAvg.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdagrad.rst:2 @@ -12975,28 +13759,26 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit `\\" -" \\(server\\_round\\, results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit `\\" -" \\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13007,23 +13789,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAdam.rst:2 @@ -13042,9 +13821,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13055,9 +13833,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13074,22 +13851,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -13106,17 +13880,16 @@ msgstr "" #: of msgid "" "Fraction of clients used during training. In case `min_fit_clients` is " -"larger than `fraction_fit * available_clients`, `min_fit_clients` will " -"still be sampled. Defaults to 1.0." +"larger than `fraction_fit * available_clients`, `min_fit_clients` will still " +"be sampled. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:9 flwr.server.strategy.fedprox.FedProx:41 #: of msgid "" -"Fraction of clients used during validation. In case " -"`min_evaluate_clients` is larger than `fraction_evaluate * " -"available_clients`, `min_evaluate_clients` will still be sampled. " -"Defaults to 1.0." +"Fraction of clients used during validation. In case `min_evaluate_clients` " +"is larger than `fraction_evaluate * available_clients`, " +"`min_evaluate_clients` will still be sampled. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavg.FedAvg:33 of @@ -13125,9 +13898,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13138,9 +13910,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13157,22 +13928,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedAvgAndroid.rst:2 @@ -13182,24 +13951,22 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`bytes_to_ndarray " -"`\\ \\(tensor\\)" +":py:obj:`bytes_to_ndarray `\\ \\(tensor\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -13210,16 +13977,14 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -13233,16 +13998,15 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarray_to_bytes " -"`\\ \\(ndarray\\)" +":py:obj:`ndarray_to_bytes `\\ \\(ndarray\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -13253,33 +14017,29 @@ msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`ndarrays_to_parameters " -"`\\ " -"\\(ndarrays\\)" +":py:obj:`ndarrays_to_parameters `\\ \\(ndarrays\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`parameters_to_ndarrays " -"`\\ " -"\\(parameters\\)" +":py:obj:`parameters_to_ndarrays `\\ \\(parameters\\)" msgstr "" #: flwr.server.strategy.fedavg_android.FedAvgAndroid.aggregate_evaluate:1::1 @@ -13298,8 +14058,7 @@ msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:25 of msgid "" -"Server-side learning rate used in server-side optimization. Defaults to " -"1.0." +"Server-side learning rate used in server-side optimization. Defaults to 1.0." msgstr "" #: flwr.server.strategy.fedavgm.FedAvgM:28 of @@ -13308,9 +14067,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13321,9 +14079,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13340,22 +14097,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -13365,9 +14119,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13383,9 +14136,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13402,22 +14154,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -13435,9 +14184,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13448,9 +14196,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13467,22 +14214,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients `\\" -" \\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ " +"\\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedProx.rst:2 @@ -13495,9 +14240,9 @@ msgstr "" #: flwr.server.strategy.fedprox.FedProx:5 of msgid "" -"The strategy in itself will not be different than FedAvg, the client " -"needs to be adjusted. A proximal term needs to be added to the loss " -"function during the training:" +"The strategy in itself will not be different than FedAvg, the client needs " +"to be adjusted. A proximal term needs to be added to the loss function " +"during the training:" msgstr "" #: flwr.server.strategy.fedprox.FedProx:9 of @@ -13530,15 +14275,14 @@ msgstr "" msgid "" "The weight of the proximal term used in the optimization. 0.0 makes this " "strategy equivalent to FedAvg, and the higher the coefficient, the more " -"regularization will be used (that is, the client parameters will need to " -"be closer to the server parameters during training)." +"regularization will be used (that is, the client parameters will need to be " +"closer to the server parameters during training)." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13549,9 +14293,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13568,22 +14311,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -13605,15 +14345,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -13624,15 +14362,13 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -13644,23 +14380,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbBagging.rst:2 @@ -13670,9 +14403,8 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1 @@ -13686,8 +14418,7 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ " +":py:obj:`aggregate_fit `\\ " "\\(server\\_round\\, results\\, failures\\)" msgstr "" @@ -13701,16 +14432,14 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ " +":py:obj:`configure_fit `\\ " "\\(server\\_round\\, parameters\\, ...\\)" msgstr "" @@ -13724,25 +14453,22 @@ msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_bagging.FedXgbBagging.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbCyclic.rst:2 @@ -13752,33 +14478,29 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\," -" results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 @@ -13791,25 +14513,22 @@ msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedxgb_cyclic.FedXgbCyclic.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedXgbNnAvg.rst:2 @@ -13819,36 +14538,31 @@ msgstr "" #: flwr.server.strategy.fedxgb_nn_avg.FedXgbNnAvg:5 of msgid "" "This strategy is deprecated, but a copy of it is available in Flower " -"Baselines: " -"https://github.com/adap/flower/tree/main/baselines/hfedxgboost." +"Baselines: https://github.com/adap/flower/tree/main/baselines/hfedxgboost." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_fit " -"`\\ \\(server\\_round\\, " -"results\\, failures\\)" +":py:obj:`aggregate_fit `\\ " +"\\(server\\_round\\, results\\, failures\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_fit " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_fit `\\ " +"\\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13859,23 +14573,20 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_fit_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: ../../source/ref-api/flwr.server.strategy.FedYogi.rst:2 @@ -13896,9 +14607,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13909,9 +14619,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13928,22 +14637,19 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -13957,15 +14663,14 @@ msgstr "" #: flwr.server.strategy.krum.Krum:17 of msgid "" -"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in" -" that case classical Krum is applied." +"Number of clients to keep before averaging (MultiKrum). Defaults to 0, in " +"that case classical Krum is applied." msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\, " -"results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -13981,9 +14686,8 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\, " -"parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -14000,16 +14704,14 @@ msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.fedavg.FedAvg.aggregate_evaluate:1::1 of @@ -14024,9 +14726,8 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ \\(server\\_round\\," -" results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -14037,9 +14738,8 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`configure_evaluate " -"`\\ \\(server\\_round\\," -" parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of @@ -14056,22 +14756,19 @@ msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_evaluation_clients " -"`\\ " -"\\(num\\_available\\_clients\\)" +":py:obj:`num_evaluation_clients `\\ \\(num\\_available\\_clients\\)" msgstr "" #: flwr.server.strategy.qfedavg.QFedAvg.aggregate_evaluate:1::1 of msgid "" -":py:obj:`num_fit_clients " -"`\\ " +":py:obj:`num_fit_clients `\\ " "\\(num\\_available\\_clients\\)" msgstr "" @@ -14082,9 +14779,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`aggregate_evaluate " -"`\\ " -"\\(server\\_round\\, results\\, ...\\)" +":py:obj:`aggregate_evaluate `\\ \\(server\\_round\\, results\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1 @@ -14108,9 +14804,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`configure_evaluate " -"`\\ " -"\\(server\\_round\\, parameters\\, ...\\)" +":py:obj:`configure_evaluate `\\ \\(server\\_round\\, parameters\\, ...\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -14135,9 +14830,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 #: of msgid "" -":py:obj:`initialize_parameters " -"`\\ " -"\\(client\\_manager\\)" +":py:obj:`initialize_parameters `\\ \\(client\\_manager\\)" msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:1::1 @@ -14147,17 +14841,18 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes` constitutes a successful update from " -"one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:13 #: flwr.server.strategy.strategy.Strategy.aggregate_fit:13 of -msgid "Exceptions that occurred while the server was waiting for client updates." +msgid "" +"Exceptions that occurred while the server was waiting for client updates." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_evaluate:16 of @@ -14168,23 +14863,22 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:5 of msgid "" -"Successful updates from the previously selected and configured clients. " -"Each pair of `(ClientProxy, FitRes)` constitutes a successful update from" -" one of the previously selected clients. Not that not all previously " -"selected clients are necessarily included in this list: a client might " -"drop out and not submit a result. For each client that did not submit an " -"update, there should be an `Exception` in `failures`." +"Successful updates from the previously selected and configured clients. Each " +"pair of `(ClientProxy, FitRes)` constitutes a successful update from one of " +"the previously selected clients. Not that not all previously selected " +"clients are necessarily included in this list: a client might drop out and " +"not submit a result. For each client that did not submit an update, there " +"should be an `Exception` in `failures`." msgstr "" #: flwr.server.strategy.strategy.Strategy.aggregate_fit:17 of msgid "" "**parameters** -- If parameters are returned, then the server will treat " -"these as the new global model parameters (i.e., it will replace the " -"previous parameters with the ones returned from this method). If `None` " -"is returned (e.g., because there were only failures and no viable " -"results) then the server will no update the previous model parameters, " -"the updates received in this round are discarded, and the global model " -"parameters remain the same." +"these as the new global model parameters (i.e., it will replace the previous " +"parameters with the ones returned from this method). If `None` is returned " +"(e.g., because there were only failures and no viable results) then the " +"server will no update the previous model parameters, the updates received in " +"this round are discarded, and the global model parameters remain the same." msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:3 of @@ -14195,9 +14889,8 @@ msgstr "" #: flwr.server.strategy.strategy.Strategy.evaluate:11 of msgid "" -"**evaluation_result** -- The evaluation result, usually a Tuple " -"containing loss and a dictionary containing task-specific metrics (e.g., " -"accuracy)." +"**evaluation_result** -- The evaluation result, usually a Tuple containing " +"loss and a dictionary containing task-specific metrics (e.g., accuracy)." msgstr "" #: flwr.server.strategy.strategy.Strategy.initialize_parameters:6 of @@ -14255,17 +14948,17 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:3 #: of msgid "" -"The SecAgg+ protocol ensures the secure summation of integer vectors " -"owned by multiple parties, without accessing any individual integer " -"vector. This workflow allows the server to compute the weighted average " -"of model parameters across all clients, ensuring individual contributions" -" remain private. This is achieved by clients sending both, a weighting " -"factor and a weighted version of the locally updated parameters, both of " -"which are masked for privacy. Specifically, each client uploads \"[w, w *" -" params]\" with masks, where weighting factor 'w' is the number of " -"examples ('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"The SecAgg+ protocol ensures the secure summation of integer vectors owned " +"by multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " +"parameters across all clients, ensuring individual contributions remain " +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:14 @@ -14302,39 +14995,39 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:22 #: of msgid "" -"Only the aggregated model parameters are exposed and passed to " -"`Strategy.aggregate_fit`, ensuring individual data privacy." +"Only the aggregated model parameters are exposed and passed to `Strategy." +"aggregate_fit`, ensuring individual data privacy." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:25 #: of msgid "" -"The number of shares into which each client's private key is split under " -"the SecAgg+ protocol. If specified as a float, it represents the " -"proportion of all selected clients, and the number of shares will be set " -"dynamically in the run time. A private key can be reconstructed from " -"these shares, allowing for the secure aggregation of model updates. Each " -"client sends one share to each of its neighbors while retaining one." +"The number of shares into which each client's private key is split under the " +"SecAgg+ protocol. If specified as a float, it represents the proportion of " +"all selected clients, and the number of shares will be set dynamically in " +"the run time. A private key can be reconstructed from these shares, allowing " +"for the secure aggregation of model updates. Each client sends one share to " +"each of its neighbors while retaining one." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:25 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:32 #: of msgid "" -"The minimum number of shares required to reconstruct a client's private " -"key, or, if specified as a float, it represents the proportion of the " -"total number of shares needed for reconstruction. This threshold ensures " -"privacy by allowing for the recovery of contributions from dropped " -"clients during aggregation, without compromising individual client data." +"The minimum number of shares required to reconstruct a client's private key, " +"or, if specified as a float, it represents the proportion of the total " +"number of shares needed for reconstruction. This threshold ensures privacy " +"by allowing for the recovery of contributions from dropped clients during " +"aggregation, without compromising individual client data." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:31 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:38 #: of msgid "" -"The maximum value of the weight that can be assigned to any single " -"client's update during the weighted average calculation on the server " -"side, e.g., in the FedAvg algorithm." +"The maximum value of the weight that can be assigned to any single client's " +"update during the weighted average calculation on the server side, e.g., in " +"the FedAvg algorithm." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:35 @@ -14342,8 +15035,8 @@ msgstr "" #: of msgid "" "The range within which model parameters are clipped before quantization. " -"This parameter ensures each model parameter is bounded within " -"[-clipping_range, clipping_range], facilitating quantization." +"This parameter ensures each model parameter is bounded within [-" +"clipping_range, clipping_range], facilitating quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:39 @@ -14361,31 +15054,32 @@ msgstr "" #: of msgid "" "The range of values from which random mask entries are uniformly sampled " -"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. " -"Please use 2**n values for `modulus_range` to prevent overflow issues." +"([0, modulus_range-1]). `modulus_range` must be less than 4294967296. Please " +"use 2**n values for `modulus_range` to prevent overflow issues." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:47 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:54 #: of msgid "" -"The timeout duration in seconds. If specified, the workflow will wait for" -" replies for this duration each time. If `None`, there is no time limit " -"and the workflow will wait until replies for all messages are received." +"The timeout duration in seconds. If specified, the workflow will wait for " +"replies for this duration each time. If `None`, there is no time limit and " +"the workflow will wait until replies for all messages are received." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:61 #: of msgid "" "Generally, higher `num_shares` means more robust to dropouts while " -"increasing the computational costs; higher `reconstruction_threshold` " -"means better privacy guarantees but less tolerance to dropouts." +"increasing the computational costs; higher `reconstruction_threshold` means " +"better privacy guarantees but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:58 #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:64 #: of -msgid "Too large `max_weight` may compromise the precision of the quantization." +msgid "" +"Too large `max_weight` may compromise the precision of the quantization." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:59 @@ -14398,35 +15092,34 @@ msgstr "" #: of msgid "" "When `num_shares` is a float, it is interpreted as the proportion of all " -"selected clients, and hence the number of shares will be determined in " -"the runtime. This allows for dynamic adjustment based on the total number" -" of participating clients." +"selected clients, and hence the number of shares will be determined in the " +"runtime. This allows for dynamic adjustment based on the total number of " +"participating clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:69 #: of msgid "" -"Similarly, when `reconstruction_threshold` is a float, it is interpreted " -"as the proportion of the number of shares needed for the reconstruction " -"of a private key. This feature enables flexibility in setting the " -"security threshold relative to the number of distributed shares." +"Similarly, when `reconstruction_threshold` is a float, it is interpreted as " +"the proportion of the number of shares needed for the reconstruction of a " +"private key. This feature enables flexibility in setting the security " +"threshold relative to the number of distributed shares." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow:73 #: of msgid "" -"`num_shares`, `reconstruction_threshold`, and the quantization parameters" -" (`clipping_range`, `quantization_range`, `modulus_range`) play critical " -"roles in balancing privacy, robustness, and efficiency within the SecAgg+" -" protocol." +"`num_shares`, `reconstruction_threshold`, and the quantization parameters " +"(`clipping_range`, `quantization_range`, `modulus_range`) play critical " +"roles in balancing privacy, robustness, and efficiency within the SecAgg+ " +"protocol." msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\" -" \\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1 @@ -14438,9 +15131,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`setup_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -14452,9 +15144,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage " -"`\\ " -"\\(driver\\, context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -14466,9 +15157,8 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 @@ -14483,51 +15173,50 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:1 of msgid "" -"Bases: " -":py:class:`~flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow`" +"Bases: :py:class:`~flwr.server.workflow.secure_aggregation." +"secaggplus_workflow.SecAggPlusWorkflow`" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:3 of msgid "" -"The SecAgg protocol ensures the secure summation of integer vectors owned" -" by multiple parties, without accessing any individual integer vector. " -"This workflow allows the server to compute the weighted average of model " +"The SecAgg protocol ensures the secure summation of integer vectors owned by " +"multiple parties, without accessing any individual integer vector. This " +"workflow allows the server to compute the weighted average of model " "parameters across all clients, ensuring individual contributions remain " -"private. This is achieved by clients sending both, a weighting factor and" -" a weighted version of the locally updated parameters, both of which are " -"masked for privacy. Specifically, each client uploads \"[w, w * params]\"" -" with masks, where weighting factor 'w' is the number of examples " -"('num_examples') and 'params' represents the model parameters " -"('parameters') from the client's `FitRes`. The server then aggregates " -"these contributions to compute the weighted average of model parameters." +"private. This is achieved by clients sending both, a weighting factor and a " +"weighted version of the locally updated parameters, both of which are masked " +"for privacy. Specifically, each client uploads \"[w, w * params]\" with " +"masks, where weighting factor 'w' is the number of examples ('num_examples') " +"and 'params' represents the model parameters ('parameters') from the " +"client's `FitRes`. The server then aggregates these contributions to compute " +"the weighted average of model parameters." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:14 of msgid "" -"The protocol involves four main stages: - 'setup': Send SecAgg " -"configuration to clients and collect their public keys. - 'share keys': " -"Broadcast public keys among clients and collect encrypted secret" +"The protocol involves four main stages: - 'setup': Send SecAgg configuration " +"to clients and collect their public keys. - 'share keys': Broadcast public " +"keys among clients and collect encrypted secret" msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:54 of msgid "" -"Each client's private key is split into N shares under the SecAgg " -"protocol, where N is the number of selected clients." +"Each client's private key is split into N shares under the SecAgg protocol, " +"where N is the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:56 of msgid "" -"Generally, higher `reconstruction_threshold` means better privacy " -"guarantees but less tolerance to dropouts." +"Generally, higher `reconstruction_threshold` means better privacy guarantees " +"but less tolerance to dropouts." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:60 of msgid "" "When `reconstruction_threshold` is a float, it is interpreted as the " "proportion of the number of all selected clients needed for the " -"reconstruction of a private key. This feature enables flexibility in " -"setting the security threshold relative to the number of selected " -"clients." +"reconstruction of a private key. This feature enables flexibility in setting " +"the security threshold relative to the number of selected clients." msgstr "" #: flwr.server.workflow.secure_aggregation.secagg_workflow.SecAggWorkflow:64 of @@ -14541,32 +15230,29 @@ msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`collect_masked_vectors_stage " -"`\\ " -"\\(driver\\, ...\\)" +":py:obj:`collect_masked_vectors_stage `\\ \\(driver\\, ...\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`setup_stage `\\" -" \\(driver\\, context\\, state\\)" +":py:obj:`setup_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`share_keys_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`share_keys_stage `\\ \\(driver\\, context\\, state\\)" msgstr "" #: flwr.server.workflow.secure_aggregation.secaggplus_workflow.SecAggPlusWorkflow.collect_masked_vectors_stage:1::1 #: of msgid "" -":py:obj:`unmask_stage " -"`\\ \\(driver\\, " -"context\\, state\\)" +":py:obj:`unmask_stage `\\ " +"\\(driver\\, context\\, state\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:2 @@ -14575,8 +15261,8 @@ msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 msgid "" -":py:obj:`start_simulation `\\ \\(\\*\\," -" client\\_fn\\[\\, ...\\]\\)" +":py:obj:`start_simulation `\\ \\(\\*\\, " +"client\\_fn\\[\\, ...\\]\\)" msgstr "" #: ../../source/ref-api/flwr.simulation.rst:18::1 @@ -14607,15 +15293,14 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:6 of msgid "" -"The `ClientApp` to be executed by each of the SuperNodes. It will receive" -" messages sent by the `ServerApp`." +"The `ClientApp` to be executed by each of the SuperNodes. It will receive " +"messages sent by the `ServerApp`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:9 of msgid "" -"Number of nodes that run a ClientApp. They can be sampled by a Driver in " -"the ServerApp and receive a Message describing what the ClientApp should " -"perform." +"Number of nodes that run a ClientApp. They can be sampled by a Driver in the " +"ServerApp and receive a Message describing what the ClientApp should perform." msgstr "" #: flwr.simulation.run_simulation.run_simulation:13 of @@ -14624,26 +15309,26 @@ msgstr "" #: flwr.simulation.run_simulation.run_simulation:15 of msgid "" -"'A dictionary, e.g {\"\": , \"\": } to " -"configure a backend. Values supported in are those included by " -"`flwr.common.typing.ConfigsRecordValues`." +"'A dictionary, e.g {\"\": , \"\": } to configure a " +"backend. Values supported in are those included by `flwr.common." +"typing.ConfigsRecordValues`." msgstr "" #: flwr.simulation.run_simulation.run_simulation:19 of msgid "" -"A boolean to indicate whether to enable GPU growth on the main thread. " -"This is desirable if you make use of a TensorFlow model on your " -"`ServerApp` while having your `ClientApp` running on the same GPU. " -"Without enabling this, you might encounter an out-of-memory error because" -" TensorFlow, by default, allocates all GPU memory. Read more about how " -"`tf.config.experimental.set_memory_growth()` works in the TensorFlow " -"documentation: https://www.tensorflow.org/api/stable." +"A boolean to indicate whether to enable GPU growth on the main thread. This " +"is desirable if you make use of a TensorFlow model on your `ServerApp` while " +"having your `ClientApp` running on the same GPU. Without enabling this, you " +"might encounter an out-of-memory error because TensorFlow, by default, " +"allocates all GPU memory. Read more about how `tf.config.experimental." +"set_memory_growth()` works in the TensorFlow documentation: https://www." +"tensorflow.org/api/stable." msgstr "" #: flwr.simulation.run_simulation.run_simulation:26 of msgid "" -"When diabled, only INFO, WARNING and ERROR log messages will be shown. If" -" enabled, DEBUG-level logs will be displayed." +"When diabled, only INFO, WARNING and ERROR log messages will be shown. If " +"enabled, DEBUG-level logs will be displayed." msgstr "" #: ../../source/ref-api/flwr.simulation.start_simulation.rst:2 @@ -14652,15 +15337,15 @@ msgstr "" #: flwr.simulation.app.start_simulation:3 of msgid "" -"A function creating client instances. The function must take a single " -"`str` argument called `cid`. It should return a single client instance of" -" type Client. Note that the created client instances are ephemeral and " -"will often be destroyed after a single method invocation. Since client " -"instances are not long-lived, they should not attempt to carry state over" -" method invocations. Any state required by the instance (model, dataset, " +"A function creating client instances. The function must take a single `str` " +"argument called `cid`. It should return a single client instance of type " +"Client. Note that the created client instances are ephemeral and will often " +"be destroyed after a single method invocation. Since client instances are " +"not long-lived, they should not attempt to carry state over method " +"invocations. Any state required by the instance (model, dataset, " "hyperparameters, ...) should be (re-)created in either the call to " -"`client_fn` or the call to any of the client methods (e.g., load " -"evaluation data in the `evaluate` method itself)." +"`client_fn` or the call to any of the client methods (e.g., load evaluation " +"data in the `evaluate` method itself)." msgstr "" #: flwr.simulation.app.start_simulation:13 of @@ -14671,16 +15356,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:16 of msgid "" -"List `client_id`s for each client. This is only required if `num_clients`" -" is not set. Setting both `num_clients` and `clients_ids` with " +"List `client_id`s for each client. This is only required if `num_clients` is " +"not set. Setting both `num_clients` and `clients_ids` with " "`len(clients_ids)` not equal to `num_clients` generates an error." msgstr "" #: flwr.simulation.app.start_simulation:20 of msgid "" -"CPU and GPU resources for a single client. Supported keys are `num_cpus` " -"and `num_gpus`. To understand the GPU utilization caused by `num_gpus`, " -"as well as using custom resources, please consult the Ray documentation." +"CPU and GPU resources for a single client. Supported keys are `num_cpus` and " +"`num_gpus`. To understand the GPU utilization caused by `num_gpus`, as well " +"as using custom resources, please consult the Ray documentation." msgstr "" #: flwr.simulation.app.start_simulation:25 of @@ -14691,16 +15376,16 @@ msgstr "" #: flwr.simulation.app.start_simulation:31 of msgid "" -"An implementation of the abstract base class `flwr.server.Strategy`. If " -"no strategy is provided, then `start_server` will use " -"`flwr.server.strategy.FedAvg`." +"An implementation of the abstract base class `flwr.server.Strategy`. If no " +"strategy is provided, then `start_server` will use `flwr.server.strategy." +"FedAvg`." msgstr "" #: flwr.simulation.app.start_simulation:35 of msgid "" -"An implementation of the abstract base class `flwr.server.ClientManager`." -" If no implementation is provided, then `start_simulation` will use " -"`flwr.server.client_manager.SimpleClientManager`." +"An implementation of the abstract base class `flwr.server.ClientManager`. If " +"no implementation is provided, then `start_simulation` will use `flwr.server." +"client_manager.SimpleClientManager`." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -14709,8 +15394,7 @@ msgid "" "ray_init_args is None (the default), Ray will be initialized with the " "following default args: { \"ignore_reinit_error\": True, " "\"include_dashboard\": False } An empty dictionary can be used " -"(ray_init_args={}) to prevent any arguments from being passed to " -"ray.init." +"(ray_init_args={}) to prevent any arguments from being passed to ray.init." msgstr "" #: flwr.simulation.app.start_simulation:39 of @@ -14726,14 +15410,13 @@ msgstr "" #: flwr.simulation.app.start_simulation:45 of msgid "" -"An empty dictionary can be used (ray_init_args={}) to prevent any " -"arguments from being passed to ray.init." +"An empty dictionary can be used (ray_init_args={}) to prevent any arguments " +"from being passed to ray.init." msgstr "" #: flwr.simulation.app.start_simulation:48 of msgid "" -"Set to True to prevent `ray.shutdown()` in case " -"`ray.is_initialized()=True`." +"Set to True to prevent `ray.shutdown()` in case `ray.is_initialized()=True`." msgstr "" #: flwr.simulation.app.start_simulation:50 of @@ -14745,19 +15428,19 @@ msgstr "" #: flwr.simulation.app.start_simulation:54 of msgid "" -"If you want to create your own Actor classes, you might need to pass some" -" input argument. You can use this dictionary for such purpose." +"If you want to create your own Actor classes, you might need to pass some " +"input argument. You can use this dictionary for such purpose." msgstr "" #: flwr.simulation.app.start_simulation:57 of msgid "" -"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for " -"the VCE to choose in which node the actor is placed. If you are an " -"advanced user needed more control you can use lower-level scheduling " -"strategies to pin actors to specific compute nodes (e.g. via " -"NodeAffinitySchedulingStrategy). Please note this is an advanced feature." -" For all details, please refer to the Ray documentation: " -"https://docs.ray.io/en/latest/ray-core/scheduling/index.html" +"(default: \"DEFAULT\") Optional string (\"DEFAULT\" or \"SPREAD\") for the " +"VCE to choose in which node the actor is placed. If you are an advanced user " +"needed more control you can use lower-level scheduling strategies to pin " +"actors to specific compute nodes (e.g. via NodeAffinitySchedulingStrategy). " +"Please note this is an advanced feature. For all details, please refer to " +"the Ray documentation: https://docs.ray.io/en/latest/ray-core/scheduling/" +"index.html" msgstr "" #: flwr.simulation.app.start_simulation:66 of @@ -14785,16 +15468,16 @@ msgstr "" #: ../../source/ref-changelog.md:364 ../../source/ref-changelog.md:448 #: ../../source/ref-changelog.md:512 ../../source/ref-changelog.md:570 msgid "" -"We would like to give our special thanks to all the contributors who made" -" the new version of Flower possible (in `git shortlog` order):" +"We would like to give our special thanks to all the contributors who made " +"the new version of Flower possible (in `git shortlog` order):" msgstr "" #: ../../source/ref-changelog.md:9 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. " -"Beutel`, `Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`," -" `Robert Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " +"`Adam Narozniak`, `Charles Beauville`, `Chong Shen Ng`, `Daniel J. Beutel`, " +"`Daniel Nata Nugraha`, `Heng Pan`, `Javier`, `Mahdi Beitollahi`, `Robert " +"Steiner`, `Taner Topal`, `Yan Gao`, `bapic`, `mohammadnaseri` " msgstr "" #: ../../source/ref-changelog.md:11 ../../source/ref-changelog.md:111 @@ -14811,33 +15494,28 @@ msgstr "" #: ../../source/ref-changelog.md:13 msgid "" -"**Introduce built-in authentication (preview)** " -"([#2946](https://github.com/adap/flower/pull/2946), " -"[#3388](https://github.com/adap/flower/pull/3388), " -"[#2948](https://github.com/adap/flower/pull/2948), " -"[#2917](https://github.com/adap/flower/pull/2917), " -"[#3386](https://github.com/adap/flower/pull/3386), " -"[#3308](https://github.com/adap/flower/pull/3308), " -"[#3001](https://github.com/adap/flower/pull/3001), " -"[#3409](https://github.com/adap/flower/pull/3409), " -"[#2999](https://github.com/adap/flower/pull/2999), " -"[#2979](https://github.com/adap/flower/pull/2979), " -"[#3389](https://github.com/adap/flower/pull/3389), " -"[#3503](https://github.com/adap/flower/pull/3503), " -"[#3366](https://github.com/adap/flower/pull/3366), " -"[#3357](https://github.com/adap/flower/pull/3357))" +"**Introduce built-in authentication (preview)** ([#2946](https://github.com/" +"adap/flower/pull/2946), [#3388](https://github.com/adap/flower/pull/3388), " +"[#2948](https://github.com/adap/flower/pull/2948), [#2917](https://github." +"com/adap/flower/pull/2917), [#3386](https://github.com/adap/flower/" +"pull/3386), [#3308](https://github.com/adap/flower/pull/3308), [#3001]" +"(https://github.com/adap/flower/pull/3001), [#3409](https://github.com/adap/" +"flower/pull/3409), [#2999](https://github.com/adap/flower/pull/2999), [#2979]" +"(https://github.com/adap/flower/pull/2979), [#3389](https://github.com/adap/" +"flower/pull/3389), [#3503](https://github.com/adap/flower/pull/3503), [#3366]" +"(https://github.com/adap/flower/pull/3366), [#3357](https://github.com/adap/" +"flower/pull/3357))" msgstr "" #: ../../source/ref-changelog.md:15 msgid "" "Flower 1.9 introduces the first build-in version of client node " -"authentication. In previous releases, users often wrote glue code to " -"connect Flower to external authentication systems. With this release, the" -" SuperLink can authenticate SuperNodes using a built-in authentication " -"system. A new [how-to guide](https://flower.ai/docs/framework/how-to-" -"authenticate-supernodes.html) and a new [code " -"example](https://github.com/adap/flower/tree/main/examples/flower-" -"authentication) help you to get started." +"authentication. In previous releases, users often wrote glue code to connect " +"Flower to external authentication systems. With this release, the SuperLink " +"can authenticate SuperNodes using a built-in authentication system. A new " +"[how-to guide](https://flower.ai/docs/framework/how-to-authenticate-" +"supernodes.html) and a new [code example](https://github.com/adap/flower/" +"tree/main/examples/flower-authentication) help you to get started." msgstr "" #: ../../source/ref-changelog.md:17 @@ -14849,118 +15527,104 @@ msgstr "" #: ../../source/ref-changelog.md:19 msgid "" -"**Introduce end-to-end Docker support** " -"([#3483](https://github.com/adap/flower/pull/3483), " -"[#3266](https://github.com/adap/flower/pull/3266), " -"[#3390](https://github.com/adap/flower/pull/3390), " -"[#3283](https://github.com/adap/flower/pull/3283), " -"[#3285](https://github.com/adap/flower/pull/3285), " -"[#3391](https://github.com/adap/flower/pull/3391), " -"[#3403](https://github.com/adap/flower/pull/3403), " -"[#3458](https://github.com/adap/flower/pull/3458), " -"[#3533](https://github.com/adap/flower/pull/3533), " -"[#3453](https://github.com/adap/flower/pull/3453), " -"[#3486](https://github.com/adap/flower/pull/3486), " -"[#3290](https://github.com/adap/flower/pull/3290))" +"**Introduce end-to-end Docker support** ([#3483](https://github.com/adap/" +"flower/pull/3483), [#3266](https://github.com/adap/flower/pull/3266), [#3390]" +"(https://github.com/adap/flower/pull/3390), [#3283](https://github.com/adap/" +"flower/pull/3283), [#3285](https://github.com/adap/flower/pull/3285), [#3391]" +"(https://github.com/adap/flower/pull/3391), [#3403](https://github.com/adap/" +"flower/pull/3403), [#3458](https://github.com/adap/flower/pull/3458), [#3533]" +"(https://github.com/adap/flower/pull/3533), [#3453](https://github.com/adap/" +"flower/pull/3453), [#3486](https://github.com/adap/flower/pull/3486), [#3290]" +"(https://github.com/adap/flower/pull/3290))" msgstr "" #: ../../source/ref-changelog.md:21 msgid "" "Full Flower Next Docker support is here! With the release of Flower 1.9, " -"Flower provides stable Docker images for the Flower SuperLink, the Flower" -" SuperNode, and the Flower `ServerApp`. This set of images enables you to" -" run all Flower components in Docker. Check out the new [how-to " -"guide](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html) to get stated." +"Flower provides stable Docker images for the Flower SuperLink, the Flower " +"SuperNode, and the Flower `ServerApp`. This set of images enables you to run " +"all Flower components in Docker. Check out the new [how-to guide](https://" +"flower.ai/docs/framework/how-to-run-flower-using-docker.html) to get stated." msgstr "" #: ../../source/ref-changelog.md:23 msgid "" -"**Re-architect Flower Next simulation engine** " -"([#3307](https://github.com/adap/flower/pull/3307), " -"[#3355](https://github.com/adap/flower/pull/3355), " -"[#3272](https://github.com/adap/flower/pull/3272), " -"[#3273](https://github.com/adap/flower/pull/3273), " -"[#3417](https://github.com/adap/flower/pull/3417), " -"[#3281](https://github.com/adap/flower/pull/3281), " -"[#3343](https://github.com/adap/flower/pull/3343), " -"[#3326](https://github.com/adap/flower/pull/3326))" +"**Re-architect Flower Next simulation engine** ([#3307](https://github.com/" +"adap/flower/pull/3307), [#3355](https://github.com/adap/flower/pull/3355), " +"[#3272](https://github.com/adap/flower/pull/3272), [#3273](https://github." +"com/adap/flower/pull/3273), [#3417](https://github.com/adap/flower/" +"pull/3417), [#3281](https://github.com/adap/flower/pull/3281), [#3343]" +"(https://github.com/adap/flower/pull/3343), [#3326](https://github.com/adap/" +"flower/pull/3326))" msgstr "" #: ../../source/ref-changelog.md:25 msgid "" -"Flower Next simulations now use a new in-memory `Driver` that improves " -"the reliability of simulations, especially in notebook environments. This" -" is a significant step towards a complete overhaul of the Flower Next " -"simulation architecture." +"Flower Next simulations now use a new in-memory `Driver` that improves the " +"reliability of simulations, especially in notebook environments. This is a " +"significant step towards a complete overhaul of the Flower Next simulation " +"architecture." msgstr "" #: ../../source/ref-changelog.md:27 msgid "" -"**Upgrade simulation engine** " -"([#3354](https://github.com/adap/flower/pull/3354), " -"[#3378](https://github.com/adap/flower/pull/3378), " -"[#3262](https://github.com/adap/flower/pull/3262), " -"[#3435](https://github.com/adap/flower/pull/3435), " -"[#3501](https://github.com/adap/flower/pull/3501), " -"[#3482](https://github.com/adap/flower/pull/3482), " -"[#3494](https://github.com/adap/flower/pull/3494))" +"**Upgrade simulation engine** ([#3354](https://github.com/adap/flower/" +"pull/3354), [#3378](https://github.com/adap/flower/pull/3378), [#3262]" +"(https://github.com/adap/flower/pull/3262), [#3435](https://github.com/adap/" +"flower/pull/3435), [#3501](https://github.com/adap/flower/pull/3501), [#3482]" +"(https://github.com/adap/flower/pull/3482), [#3494](https://github.com/adap/" +"flower/pull/3494))" msgstr "" #: ../../source/ref-changelog.md:29 msgid "" "The Flower Next simulation engine comes with improved and configurable " -"logging. The Ray-based simulation backend in Flower 1.9 was updated to " -"use Ray 2.10." +"logging. The Ray-based simulation backend in Flower 1.9 was updated to use " +"Ray 2.10." msgstr "" #: ../../source/ref-changelog.md:31 msgid "" -"**Introduce FedPFT baseline** " -"([#3268](https://github.com/adap/flower/pull/3268))" +"**Introduce FedPFT baseline** ([#3268](https://github.com/adap/flower/" +"pull/3268))" msgstr "" #: ../../source/ref-changelog.md:33 msgid "" "FedPFT allows you to perform one-shot Federated Learning by leveraging " -"widely available foundational models, dramatically reducing communication" -" costs while delivering high performing models. This is work led by Mahdi" -" Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " -"details in their paper: \"Parametric Feature Transfer: One-shot Federated" -" Learning with Foundation Models\" " -"([arxiv](https://arxiv.org/abs/2402.01862))" +"widely available foundational models, dramatically reducing communication " +"costs while delivering high performing models. This is work led by Mahdi " +"Beitollahi from Huawei Noah's Ark Lab (Montreal, Canada). Read all the " +"details in their paper: \"Parametric Feature Transfer: One-shot Federated " +"Learning with Foundation Models\" ([arxiv](https://arxiv.org/abs/2402.01862))" msgstr "" #: ../../source/ref-changelog.md:35 msgid "" "**Launch additional** `flwr new` **templates for Apple MLX, Hugging Face " -"Transformers, scikit-learn and TensorFlow** " -"([#3291](https://github.com/adap/flower/pull/3291), " -"[#3139](https://github.com/adap/flower/pull/3139), " -"[#3284](https://github.com/adap/flower/pull/3284), " -"[#3251](https://github.com/adap/flower/pull/3251), " -"[#3376](https://github.com/adap/flower/pull/3376), " -"[#3287](https://github.com/adap/flower/pull/3287))" +"Transformers, scikit-learn and TensorFlow** ([#3291](https://github.com/adap/" +"flower/pull/3291), [#3139](https://github.com/adap/flower/pull/3139), [#3284]" +"(https://github.com/adap/flower/pull/3284), [#3251](https://github.com/adap/" +"flower/pull/3251), [#3376](https://github.com/adap/flower/pull/3376), [#3287]" +"(https://github.com/adap/flower/pull/3287))" msgstr "" #: ../../source/ref-changelog.md:37 msgid "" -"The `flwr` CLI's `flwr new` command is starting to become everone's " -"favorite way of creating new Flower projects. This release introduces " -"additional `flwr new` templates for Apple MLX, Hugging Face Transformers," -" scikit-learn and TensorFlow. In addition to that, existing templates " -"also received updates." +"The `flwr` CLI's `flwr new` command is starting to become everone's favorite " +"way of creating new Flower projects. This release introduces additional " +"`flwr new` templates for Apple MLX, Hugging Face Transformers, scikit-learn " +"and TensorFlow. In addition to that, existing templates also received " +"updates." msgstr "" #: ../../source/ref-changelog.md:39 msgid "" -"**Refine** `RecordSet` **API** " -"([#3209](https://github.com/adap/flower/pull/3209), " -"[#3331](https://github.com/adap/flower/pull/3331), " -"[#3334](https://github.com/adap/flower/pull/3334), " -"[#3335](https://github.com/adap/flower/pull/3335), " -"[#3375](https://github.com/adap/flower/pull/3375), " -"[#3368](https://github.com/adap/flower/pull/3368))" +"**Refine** `RecordSet` **API** ([#3209](https://github.com/adap/flower/" +"pull/3209), [#3331](https://github.com/adap/flower/pull/3331), [#3334]" +"(https://github.com/adap/flower/pull/3334), [#3335](https://github.com/adap/" +"flower/pull/3335), [#3375](https://github.com/adap/flower/pull/3375), [#3368]" +"(https://github.com/adap/flower/pull/3368))" msgstr "" #: ../../source/ref-changelog.md:41 @@ -14973,29 +15637,25 @@ msgstr "" #: ../../source/ref-changelog.md:43 msgid "" "**Beautify logging** ([#3379](https://github.com/adap/flower/pull/3379), " -"[#3430](https://github.com/adap/flower/pull/3430), " -"[#3461](https://github.com/adap/flower/pull/3461), " -"[#3360](https://github.com/adap/flower/pull/3360), " -"[#3433](https://github.com/adap/flower/pull/3433))" +"[#3430](https://github.com/adap/flower/pull/3430), [#3461](https://github." +"com/adap/flower/pull/3461), [#3360](https://github.com/adap/flower/" +"pull/3360), [#3433](https://github.com/adap/flower/pull/3433))" msgstr "" #: ../../source/ref-changelog.md:45 msgid "" -"Logs received a substantial update. Not only are logs now much nicer to " -"look at, but they are also more configurable." +"Logs received a substantial update. Not only are logs now much nicer to look " +"at, but they are also more configurable." msgstr "" #: ../../source/ref-changelog.md:47 msgid "" -"**Improve reliability** " -"([#3564](https://github.com/adap/flower/pull/3564), " -"[#3561](https://github.com/adap/flower/pull/3561), " -"[#3566](https://github.com/adap/flower/pull/3566), " -"[#3462](https://github.com/adap/flower/pull/3462), " -"[#3225](https://github.com/adap/flower/pull/3225), " -"[#3514](https://github.com/adap/flower/pull/3514), " -"[#3535](https://github.com/adap/flower/pull/3535), " -"[#3372](https://github.com/adap/flower/pull/3372))" +"**Improve reliability** ([#3564](https://github.com/adap/flower/pull/3564), " +"[#3561](https://github.com/adap/flower/pull/3561), [#3566](https://github." +"com/adap/flower/pull/3566), [#3462](https://github.com/adap/flower/" +"pull/3462), [#3225](https://github.com/adap/flower/pull/3225), [#3514]" +"(https://github.com/adap/flower/pull/3514), [#3535](https://github.com/adap/" +"flower/pull/3535), [#3372](https://github.com/adap/flower/pull/3372))" msgstr "" #: ../../source/ref-changelog.md:49 @@ -15006,50 +15666,40 @@ msgstr "" #: ../../source/ref-changelog.md:51 msgid "" -"**Update Swift and C++ SDKs** " -"([#3321](https://github.com/adap/flower/pull/3321), " -"[#2763](https://github.com/adap/flower/pull/2763))" +"**Update Swift and C++ SDKs** ([#3321](https://github.com/adap/flower/" +"pull/3321), [#2763](https://github.com/adap/flower/pull/2763))" msgstr "" #: ../../source/ref-changelog.md:53 msgid "" -"In the C++ SDK, communication-related code is now separate from main " -"client logic. A new abstract class `Communicator` has been introduced " -"alongside a gRPC implementation of it." +"In the C++ SDK, communication-related code is now separate from main client " +"logic. A new abstract class `Communicator` has been introduced alongside a " +"gRPC implementation of it." msgstr "" #: ../../source/ref-changelog.md:55 msgid "" -"**Improve testing, tooling and CI/CD infrastructure** " -"([#3294](https://github.com/adap/flower/pull/3294), " -"[#3282](https://github.com/adap/flower/pull/3282), " -"[#3311](https://github.com/adap/flower/pull/3311), " -"[#2878](https://github.com/adap/flower/pull/2878), " -"[#3333](https://github.com/adap/flower/pull/3333), " -"[#3255](https://github.com/adap/flower/pull/3255), " -"[#3349](https://github.com/adap/flower/pull/3349), " -"[#3400](https://github.com/adap/flower/pull/3400), " -"[#3401](https://github.com/adap/flower/pull/3401), " -"[#3399](https://github.com/adap/flower/pull/3399), " -"[#3346](https://github.com/adap/flower/pull/3346), " -"[#3398](https://github.com/adap/flower/pull/3398), " -"[#3397](https://github.com/adap/flower/pull/3397), " -"[#3347](https://github.com/adap/flower/pull/3347), " -"[#3502](https://github.com/adap/flower/pull/3502), " -"[#3387](https://github.com/adap/flower/pull/3387), " -"[#3542](https://github.com/adap/flower/pull/3542), " -"[#3396](https://github.com/adap/flower/pull/3396), " -"[#3496](https://github.com/adap/flower/pull/3496), " -"[#3465](https://github.com/adap/flower/pull/3465), " -"[#3473](https://github.com/adap/flower/pull/3473), " -"[#3484](https://github.com/adap/flower/pull/3484), " -"[#3521](https://github.com/adap/flower/pull/3521), " -"[#3363](https://github.com/adap/flower/pull/3363), " -"[#3497](https://github.com/adap/flower/pull/3497), " -"[#3464](https://github.com/adap/flower/pull/3464), " -"[#3495](https://github.com/adap/flower/pull/3495), " -"[#3478](https://github.com/adap/flower/pull/3478), " -"[#3271](https://github.com/adap/flower/pull/3271))" +"**Improve testing, tooling and CI/CD infrastructure** ([#3294](https://" +"github.com/adap/flower/pull/3294), [#3282](https://github.com/adap/flower/" +"pull/3282), [#3311](https://github.com/adap/flower/pull/3311), [#2878]" +"(https://github.com/adap/flower/pull/2878), [#3333](https://github.com/adap/" +"flower/pull/3333), [#3255](https://github.com/adap/flower/pull/3255), [#3349]" +"(https://github.com/adap/flower/pull/3349), [#3400](https://github.com/adap/" +"flower/pull/3400), [#3401](https://github.com/adap/flower/pull/3401), [#3399]" +"(https://github.com/adap/flower/pull/3399), [#3346](https://github.com/adap/" +"flower/pull/3346), [#3398](https://github.com/adap/flower/pull/3398), [#3397]" +"(https://github.com/adap/flower/pull/3397), [#3347](https://github.com/adap/" +"flower/pull/3347), [#3502](https://github.com/adap/flower/pull/3502), [#3387]" +"(https://github.com/adap/flower/pull/3387), [#3542](https://github.com/adap/" +"flower/pull/3542), [#3396](https://github.com/adap/flower/pull/3396), [#3496]" +"(https://github.com/adap/flower/pull/3496), [#3465](https://github.com/adap/" +"flower/pull/3465), [#3473](https://github.com/adap/flower/pull/3473), [#3484]" +"(https://github.com/adap/flower/pull/3484), [#3521](https://github.com/adap/" +"flower/pull/3521), [#3363](https://github.com/adap/flower/pull/3363), [#3497]" +"(https://github.com/adap/flower/pull/3497), [#3464](https://github.com/adap/" +"flower/pull/3464), [#3495](https://github.com/adap/flower/pull/3495), [#3478]" +"(https://github.com/adap/flower/pull/3478), [#3271](https://github.com/adap/" +"flower/pull/3271))" msgstr "" #: ../../source/ref-changelog.md:57 @@ -15060,75 +15710,61 @@ msgstr "" #: ../../source/ref-changelog.md:59 msgid "" -"**Improve documentation** " -"([#3530](https://github.com/adap/flower/pull/3530), " -"[#3539](https://github.com/adap/flower/pull/3539), " -"[#3425](https://github.com/adap/flower/pull/3425), " -"[#3520](https://github.com/adap/flower/pull/3520), " -"[#3286](https://github.com/adap/flower/pull/3286), " -"[#3516](https://github.com/adap/flower/pull/3516), " -"[#3523](https://github.com/adap/flower/pull/3523), " -"[#3545](https://github.com/adap/flower/pull/3545), " -"[#3498](https://github.com/adap/flower/pull/3498), " -"[#3439](https://github.com/adap/flower/pull/3439), " -"[#3440](https://github.com/adap/flower/pull/3440), " -"[#3382](https://github.com/adap/flower/pull/3382), " -"[#3559](https://github.com/adap/flower/pull/3559), " -"[#3432](https://github.com/adap/flower/pull/3432), " -"[#3278](https://github.com/adap/flower/pull/3278), " -"[#3371](https://github.com/adap/flower/pull/3371), " -"[#3519](https://github.com/adap/flower/pull/3519), " -"[#3267](https://github.com/adap/flower/pull/3267), " -"[#3204](https://github.com/adap/flower/pull/3204), " -"[#3274](https://github.com/adap/flower/pull/3274))" +"**Improve documentation** ([#3530](https://github.com/adap/flower/" +"pull/3530), [#3539](https://github.com/adap/flower/pull/3539), [#3425]" +"(https://github.com/adap/flower/pull/3425), [#3520](https://github.com/adap/" +"flower/pull/3520), [#3286](https://github.com/adap/flower/pull/3286), [#3516]" +"(https://github.com/adap/flower/pull/3516), [#3523](https://github.com/adap/" +"flower/pull/3523), [#3545](https://github.com/adap/flower/pull/3545), [#3498]" +"(https://github.com/adap/flower/pull/3498), [#3439](https://github.com/adap/" +"flower/pull/3439), [#3440](https://github.com/adap/flower/pull/3440), [#3382]" +"(https://github.com/adap/flower/pull/3382), [#3559](https://github.com/adap/" +"flower/pull/3559), [#3432](https://github.com/adap/flower/pull/3432), [#3278]" +"(https://github.com/adap/flower/pull/3278), [#3371](https://github.com/adap/" +"flower/pull/3371), [#3519](https://github.com/adap/flower/pull/3519), [#3267]" +"(https://github.com/adap/flower/pull/3267), [#3204](https://github.com/adap/" +"flower/pull/3204), [#3274](https://github.com/adap/flower/pull/3274))" msgstr "" #: ../../source/ref-changelog.md:61 msgid "" -"As always, the Flower documentation has received many updates. Notable " -"new pages include:" +"As always, the Flower documentation has received many updates. Notable new " +"pages include:" msgstr "" #: ../../source/ref-changelog.md:63 msgid "" -"[How-to upgrate to Flower Next (Flower Next migration " -"guide)](https://flower.ai/docs/framework/how-to-upgrade-to-flower-" -"next.html)" +"[How-to upgrate to Flower Next (Flower Next migration guide)](https://flower." +"ai/docs/framework/how-to-upgrade-to-flower-next.html)" msgstr "" #: ../../source/ref-changelog.md:65 msgid "" -"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-" -"run-flower-using-docker.html)" +"[How-to run Flower using Docker](https://flower.ai/docs/framework/how-to-run-" +"flower-using-docker.html)" msgstr "" #: ../../source/ref-changelog.md:67 msgid "" -"[Flower Mods reference](https://flower.ai/docs/framework/ref-" -"api/flwr.client.mod.html#module-flwr.client.mod)" +"[Flower Mods reference](https://flower.ai/docs/framework/ref-api/flwr.client." +"mod.html#module-flwr.client.mod)" msgstr "" #: ../../source/ref-changelog.md:69 msgid "" -"**General updates to Flower Examples** " -"([#3205](https://github.com/adap/flower/pull/3205), " -"[#3226](https://github.com/adap/flower/pull/3226), " -"[#3211](https://github.com/adap/flower/pull/3211), " -"[#3252](https://github.com/adap/flower/pull/3252), " -"[#3427](https://github.com/adap/flower/pull/3427), " -"[#3410](https://github.com/adap/flower/pull/3410), " -"[#3426](https://github.com/adap/flower/pull/3426), " -"[#3228](https://github.com/adap/flower/pull/3228), " -"[#3342](https://github.com/adap/flower/pull/3342), " -"[#3200](https://github.com/adap/flower/pull/3200), " -"[#3202](https://github.com/adap/flower/pull/3202), " -"[#3394](https://github.com/adap/flower/pull/3394), " -"[#3488](https://github.com/adap/flower/pull/3488), " -"[#3329](https://github.com/adap/flower/pull/3329), " -"[#3526](https://github.com/adap/flower/pull/3526), " -"[#3392](https://github.com/adap/flower/pull/3392), " -"[#3474](https://github.com/adap/flower/pull/3474), " -"[#3269](https://github.com/adap/flower/pull/3269))" +"**General updates to Flower Examples** ([#3205](https://github.com/adap/" +"flower/pull/3205), [#3226](https://github.com/adap/flower/pull/3226), [#3211]" +"(https://github.com/adap/flower/pull/3211), [#3252](https://github.com/adap/" +"flower/pull/3252), [#3427](https://github.com/adap/flower/pull/3427), [#3410]" +"(https://github.com/adap/flower/pull/3410), [#3426](https://github.com/adap/" +"flower/pull/3426), [#3228](https://github.com/adap/flower/pull/3228), [#3342]" +"(https://github.com/adap/flower/pull/3342), [#3200](https://github.com/adap/" +"flower/pull/3200), [#3202](https://github.com/adap/flower/pull/3202), [#3394]" +"(https://github.com/adap/flower/pull/3394), [#3488](https://github.com/adap/" +"flower/pull/3488), [#3329](https://github.com/adap/flower/pull/3329), [#3526]" +"(https://github.com/adap/flower/pull/3526), [#3392](https://github.com/adap/" +"flower/pull/3392), [#3474](https://github.com/adap/flower/pull/3474), [#3269]" +"(https://github.com/adap/flower/pull/3269))" msgstr "" #: ../../source/ref-changelog.md:71 @@ -15137,41 +15773,30 @@ msgstr "" #: ../../source/ref-changelog.md:73 msgid "" -"**General improvements** " -"([#3532](https://github.com/adap/flower/pull/3532), " -"[#3318](https://github.com/adap/flower/pull/3318), " -"[#3565](https://github.com/adap/flower/pull/3565), " -"[#3296](https://github.com/adap/flower/pull/3296), " -"[#3305](https://github.com/adap/flower/pull/3305), " -"[#3246](https://github.com/adap/flower/pull/3246), " -"[#3224](https://github.com/adap/flower/pull/3224), " -"[#3475](https://github.com/adap/flower/pull/3475), " -"[#3297](https://github.com/adap/flower/pull/3297), " -"[#3317](https://github.com/adap/flower/pull/3317), " -"[#3429](https://github.com/adap/flower/pull/3429), " -"[#3196](https://github.com/adap/flower/pull/3196), " -"[#3534](https://github.com/adap/flower/pull/3534), " -"[#3240](https://github.com/adap/flower/pull/3240), " -"[#3365](https://github.com/adap/flower/pull/3365), " -"[#3407](https://github.com/adap/flower/pull/3407), " -"[#3563](https://github.com/adap/flower/pull/3563), " -"[#3344](https://github.com/adap/flower/pull/3344), " -"[#3330](https://github.com/adap/flower/pull/3330), " -"[#3436](https://github.com/adap/flower/pull/3436), " -"[#3300](https://github.com/adap/flower/pull/3300), " -"[#3327](https://github.com/adap/flower/pull/3327), " -"[#3254](https://github.com/adap/flower/pull/3254), " -"[#3253](https://github.com/adap/flower/pull/3253), " -"[#3419](https://github.com/adap/flower/pull/3419), " -"[#3289](https://github.com/adap/flower/pull/3289), " -"[#3208](https://github.com/adap/flower/pull/3208), " -"[#3245](https://github.com/adap/flower/pull/3245), " -"[#3319](https://github.com/adap/flower/pull/3319), " -"[#3203](https://github.com/adap/flower/pull/3203), " -"[#3423](https://github.com/adap/flower/pull/3423), " -"[#3352](https://github.com/adap/flower/pull/3352), " -"[#3292](https://github.com/adap/flower/pull/3292), " -"[#3261](https://github.com/adap/flower/pull/3261))" +"**General improvements** ([#3532](https://github.com/adap/flower/pull/3532), " +"[#3318](https://github.com/adap/flower/pull/3318), [#3565](https://github." +"com/adap/flower/pull/3565), [#3296](https://github.com/adap/flower/" +"pull/3296), [#3305](https://github.com/adap/flower/pull/3305), [#3246]" +"(https://github.com/adap/flower/pull/3246), [#3224](https://github.com/adap/" +"flower/pull/3224), [#3475](https://github.com/adap/flower/pull/3475), [#3297]" +"(https://github.com/adap/flower/pull/3297), [#3317](https://github.com/adap/" +"flower/pull/3317), [#3429](https://github.com/adap/flower/pull/3429), [#3196]" +"(https://github.com/adap/flower/pull/3196), [#3534](https://github.com/adap/" +"flower/pull/3534), [#3240](https://github.com/adap/flower/pull/3240), [#3365]" +"(https://github.com/adap/flower/pull/3365), [#3407](https://github.com/adap/" +"flower/pull/3407), [#3563](https://github.com/adap/flower/pull/3563), [#3344]" +"(https://github.com/adap/flower/pull/3344), [#3330](https://github.com/adap/" +"flower/pull/3330), [#3436](https://github.com/adap/flower/pull/3436), [#3300]" +"(https://github.com/adap/flower/pull/3300), [#3327](https://github.com/adap/" +"flower/pull/3327), [#3254](https://github.com/adap/flower/pull/3254), [#3253]" +"(https://github.com/adap/flower/pull/3253), [#3419](https://github.com/adap/" +"flower/pull/3419), [#3289](https://github.com/adap/flower/pull/3289), [#3208]" +"(https://github.com/adap/flower/pull/3208), [#3245](https://github.com/adap/" +"flower/pull/3245), [#3319](https://github.com/adap/flower/pull/3319), [#3203]" +"(https://github.com/adap/flower/pull/3203), [#3423](https://github.com/adap/" +"flower/pull/3423), [#3352](https://github.com/adap/flower/pull/3352), [#3292]" +"(https://github.com/adap/flower/pull/3292), [#3261](https://github.com/adap/" +"flower/pull/3261))" msgstr "" #: ../../source/ref-changelog.md:75 ../../source/ref-changelog.md:1058 @@ -15184,36 +15809,36 @@ msgstr "" #: ../../source/ref-changelog.md:79 msgid "" -"Python 3.8 will stop receiving security fixes in [October " -"2024](https://devguide.python.org/versions/). Support for Python 3.8 is " -"now deprecated and will be removed in an upcoming release." +"Python 3.8 will stop receiving security fixes in [October 2024](https://" +"devguide.python.org/versions/). Support for Python 3.8 is now deprecated and " +"will be removed in an upcoming release." msgstr "" #: ../../source/ref-changelog.md:81 msgid "" -"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-" -"api` ([#3416](https://github.com/adap/flower/pull/3416), " -"[#3420](https://github.com/adap/flower/pull/3420))" +"**Deprecate (experimental)** `flower-driver-api` **and** `flower-fleet-api` " +"([#3416](https://github.com/adap/flower/pull/3416), [#3420](https://github." +"com/adap/flower/pull/3420))" msgstr "" #: ../../source/ref-changelog.md:83 msgid "" -"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api`" -" and `flower-fleet-api`. Both commands will be removed in an upcoming " +"Flower 1.9 deprecates the two (experimental) commands `flower-driver-api` " +"and `flower-fleet-api`. Both commands will be removed in an upcoming " "release. Use `flower-superlink` instead." msgstr "" #: ../../source/ref-changelog.md:85 msgid "" -"**Deprecate** `--server` **in favor of** `--superlink` " -"([#3518](https://github.com/adap/flower/pull/3518))" +"**Deprecate** `--server` **in favor of** `--superlink` ([#3518](https://" +"github.com/adap/flower/pull/3518))" msgstr "" #: ../../source/ref-changelog.md:87 msgid "" -"The commands `flower-server-app` and `flower-client-app` should use " -"`--superlink` instead of the now deprecated `--server`. Support for " -"`--server` will be removed in a future release." +"The commands `flower-server-app` and `flower-client-app` should use `--" +"superlink` instead of the now deprecated `--server`. Support for `--server` " +"will be removed in a future release." msgstr "" #: ../../source/ref-changelog.md:89 ../../source/ref-changelog.md:163 @@ -15228,48 +15853,46 @@ msgstr "" #: ../../source/ref-changelog.md:91 msgid "" -"**Replace** `flower-superlink` **CLI option** `--certificates` **with** " -"`--ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` " -"([#3512](https://github.com/adap/flower/pull/3512), " -"[#3408](https://github.com/adap/flower/pull/3408))" +"**Replace** `flower-superlink` **CLI option** `--certificates` **with** `--" +"ssl-ca-certfile` **,** `--ssl-certfile` **and** `--ssl-keyfile` ([#3512]" +"(https://github.com/adap/flower/pull/3512), [#3408](https://github.com/adap/" +"flower/pull/3408))" msgstr "" #: ../../source/ref-changelog.md:93 msgid "" "SSL-related `flower-superlink` CLI arguments were restructured in an " "incompatible way. Instead of passing a single `--certificates` flag with " -"three values, you now need to pass three flags (`--ssl-ca-certfile`, " -"`--ssl-certfile` and `--ssl-keyfile`) with one value each. Check out the " -"[SSL connections](https://flower.ai/docs/framework/how-to-enable-ssl-" -"connections.html) documentation page for details." +"three values, you now need to pass three flags (`--ssl-ca-certfile`, `--ssl-" +"certfile` and `--ssl-keyfile`) with one value each. Check out the [SSL " +"connections](https://flower.ai/docs/framework/how-to-enable-ssl-connections." +"html) documentation page for details." msgstr "" #: ../../source/ref-changelog.md:95 msgid "" -"**Remove SuperLink** `--vce` **option** " -"([#3513](https://github.com/adap/flower/pull/3513))" +"**Remove SuperLink** `--vce` **option** ([#3513](https://github.com/adap/" +"flower/pull/3513))" msgstr "" #: ../../source/ref-changelog.md:97 msgid "" -"Instead of separately starting a SuperLink and a `ServerApp` for " -"simulation, simulations must now be started using the single `flower-" -"simulation` command." +"Instead of separately starting a SuperLink and a `ServerApp` for simulation, " +"simulations must now be started using the single `flower-simulation` command." msgstr "" #: ../../source/ref-changelog.md:99 msgid "" -"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** " -"([#3527](https://github.com/adap/flower/pull/3527))" +"**Merge** `--grpc-rere` **and** `--rest` **SuperLink options** ([#3527]" +"(https://github.com/adap/flower/pull/3527))" msgstr "" #: ../../source/ref-changelog.md:101 msgid "" -"To simplify the usage of `flower-superlink`, previously separate sets of " -"CLI options for gRPC and REST were merged into one unified set of " -"options. Consult the [Flower CLI reference " -"documentation](https://flower.ai/docs/framework/ref-api-cli.html) for " -"details." +"To simplify the usage of `flower-superlink`, previously separate sets of CLI " +"options for gRPC and REST were merged into one unified set of options. " +"Consult the [Flower CLI reference documentation](https://flower.ai/docs/" +"framework/ref-api-cli.html) for details." msgstr "" #: ../../source/ref-changelog.md:103 @@ -15279,237 +15902,212 @@ msgstr "" #: ../../source/ref-changelog.md:109 msgid "" "`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata " -"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear " -"Ashimine`, `Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, " -"`Sebastian van der Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, " -"`tabdar-khan` " +"Nugraha`, `Danny`, `Gustavo Bertoli`, `Heng Pan`, `Ikko Eltociear Ashimine`, " +"`Jack Cook`, `Javier`, `Raj Parekh`, `Robert Steiner`, `Sebastian van der " +"Voort`, `Taner Topal`, `Yan Gao`, `mohammadnaseri`, `tabdar-khan` " msgstr "" #: ../../source/ref-changelog.md:113 msgid "" -"**Introduce Flower Next high-level API (stable)** " -"([#3002](https://github.com/adap/flower/pull/3002), " -"[#2934](https://github.com/adap/flower/pull/2934), " -"[#2958](https://github.com/adap/flower/pull/2958), " -"[#3173](https://github.com/adap/flower/pull/3173), " -"[#3174](https://github.com/adap/flower/pull/3174), " -"[#2923](https://github.com/adap/flower/pull/2923), " -"[#2691](https://github.com/adap/flower/pull/2691), " -"[#3079](https://github.com/adap/flower/pull/3079), " -"[#2961](https://github.com/adap/flower/pull/2961), " -"[#2924](https://github.com/adap/flower/pull/2924), " -"[#3166](https://github.com/adap/flower/pull/3166), " -"[#3031](https://github.com/adap/flower/pull/3031), " -"[#3057](https://github.com/adap/flower/pull/3057), " -"[#3000](https://github.com/adap/flower/pull/3000), " -"[#3113](https://github.com/adap/flower/pull/3113), " -"[#2957](https://github.com/adap/flower/pull/2957), " -"[#3183](https://github.com/adap/flower/pull/3183), " -"[#3180](https://github.com/adap/flower/pull/3180), " -"[#3035](https://github.com/adap/flower/pull/3035), " -"[#3189](https://github.com/adap/flower/pull/3189), " -"[#3185](https://github.com/adap/flower/pull/3185), " -"[#3190](https://github.com/adap/flower/pull/3190), " -"[#3191](https://github.com/adap/flower/pull/3191), " -"[#3195](https://github.com/adap/flower/pull/3195), " -"[#3197](https://github.com/adap/flower/pull/3197))" +"**Introduce Flower Next high-level API (stable)** ([#3002](https://github." +"com/adap/flower/pull/3002), [#2934](https://github.com/adap/flower/" +"pull/2934), [#2958](https://github.com/adap/flower/pull/2958), [#3173]" +"(https://github.com/adap/flower/pull/3173), [#3174](https://github.com/adap/" +"flower/pull/3174), [#2923](https://github.com/adap/flower/pull/2923), [#2691]" +"(https://github.com/adap/flower/pull/2691), [#3079](https://github.com/adap/" +"flower/pull/3079), [#2961](https://github.com/adap/flower/pull/2961), [#2924]" +"(https://github.com/adap/flower/pull/2924), [#3166](https://github.com/adap/" +"flower/pull/3166), [#3031](https://github.com/adap/flower/pull/3031), [#3057]" +"(https://github.com/adap/flower/pull/3057), [#3000](https://github.com/adap/" +"flower/pull/3000), [#3113](https://github.com/adap/flower/pull/3113), [#2957]" +"(https://github.com/adap/flower/pull/2957), [#3183](https://github.com/adap/" +"flower/pull/3183), [#3180](https://github.com/adap/flower/pull/3180), [#3035]" +"(https://github.com/adap/flower/pull/3035), [#3189](https://github.com/adap/" +"flower/pull/3189), [#3185](https://github.com/adap/flower/pull/3185), [#3190]" +"(https://github.com/adap/flower/pull/3190), [#3191](https://github.com/adap/" +"flower/pull/3191), [#3195](https://github.com/adap/flower/pull/3195), [#3197]" +"(https://github.com/adap/flower/pull/3197))" msgstr "" #: ../../source/ref-changelog.md:115 msgid "" "The Flower Next high-level API is stable! Flower Next is the future of " -"Flower - all new features (like Flower Mods) will be built on top of it. " -"You can start to migrate your existing projects to Flower Next by using " -"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or " -"`quickstart-tensorflow`, a detailed migration guide will follow shortly)." -" Flower Next allows you to run multiple projects concurrently (we call " -"this multi-run) and execute the same project in either simulation " -"environments or deployment environments without having to change a single" -" line of code. The best part? It's fully compatible with existing Flower " -"projects that use `Strategy`, `NumPyClient` & co." +"Flower - all new features (like Flower Mods) will be built on top of it. You " +"can start to migrate your existing projects to Flower Next by using " +"`ServerApp` and `ClientApp` (check out `quickstart-pytorch` or `quickstart-" +"tensorflow`, a detailed migration guide will follow shortly). Flower Next " +"allows you to run multiple projects concurrently (we call this multi-run) " +"and execute the same project in either simulation environments or deployment " +"environments without having to change a single line of code. The best part? " +"It's fully compatible with existing Flower projects that use `Strategy`, " +"`NumPyClient` & co." msgstr "" #: ../../source/ref-changelog.md:117 msgid "" -"**Introduce Flower Next low-level API (preview)** " -"([#3062](https://github.com/adap/flower/pull/3062), " -"[#3034](https://github.com/adap/flower/pull/3034), " -"[#3069](https://github.com/adap/flower/pull/3069))" +"**Introduce Flower Next low-level API (preview)** ([#3062](https://github." +"com/adap/flower/pull/3062), [#3034](https://github.com/adap/flower/" +"pull/3034), [#3069](https://github.com/adap/flower/pull/3069))" msgstr "" #: ../../source/ref-changelog.md:119 msgid "" "In addition to the Flower Next *high-level* API that uses `Strategy`, " -"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the " -"new Flower Next *low-level* API. The low-level API allows for granular " -"control of every aspect of the learning process by sending/receiving " -"individual messages to/from client nodes. The new `ServerApp` supports " -"registering a custom `main` function that allows writing custom training " -"loops for methods like async FL, cyclic training, or federated analytics." -" The new `ClientApp` supports registering `train`, `evaluate` and `query`" -" functions that can access the raw message received from the `ServerApp`." -" New abstractions like `RecordSet`, `Message` and `Context` further " -"enable sending multiple models, multiple sets of config values and " -"metrics, stateful computations on the client node and implementations of " -"custom SMPC protocols, to name just a few." +"`NumPyClient` & co, Flower 1.8 also comes with a preview version of the new " +"Flower Next *low-level* API. The low-level API allows for granular control " +"of every aspect of the learning process by sending/receiving individual " +"messages to/from client nodes. The new `ServerApp` supports registering a " +"custom `main` function that allows writing custom training loops for methods " +"like async FL, cyclic training, or federated analytics. The new `ClientApp` " +"supports registering `train`, `evaluate` and `query` functions that can " +"access the raw message received from the `ServerApp`. New abstractions like " +"`RecordSet`, `Message` and `Context` further enable sending multiple models, " +"multiple sets of config values and metrics, stateful computations on the " +"client node and implementations of custom SMPC protocols, to name just a few." msgstr "" #: ../../source/ref-changelog.md:121 msgid "" -"**Introduce Flower Mods (preview)** " -"([#3054](https://github.com/adap/flower/pull/3054), " -"[#2911](https://github.com/adap/flower/pull/2911), " -"[#3083](https://github.com/adap/flower/pull/3083))" +"**Introduce Flower Mods (preview)** ([#3054](https://github.com/adap/flower/" +"pull/3054), [#2911](https://github.com/adap/flower/pull/2911), [#3083]" +"(https://github.com/adap/flower/pull/3083))" msgstr "" #: ../../source/ref-changelog.md:123 msgid "" "Flower Modifiers (we call them Mods) can intercept messages and analyze, " -"edit or handle them directly. Mods can be used to develop pluggable " -"modules that work across different projects. Flower 1.8 already includes " -"mods to log the size of a message, the number of parameters sent over the" -" network, differential privacy with fixed clipping and adaptive clipping," -" local differential privacy and secure aggregation protocols SecAgg and " -"SecAgg+. The Flower Mods API is released as a preview, but researchers " -"can already use it to experiment with arbirtrary SMPC protocols." +"edit or handle them directly. Mods can be used to develop pluggable modules " +"that work across different projects. Flower 1.8 already includes mods to log " +"the size of a message, the number of parameters sent over the network, " +"differential privacy with fixed clipping and adaptive clipping, local " +"differential privacy and secure aggregation protocols SecAgg and SecAgg+. " +"The Flower Mods API is released as a preview, but researchers can already " +"use it to experiment with arbirtrary SMPC protocols." msgstr "" #: ../../source/ref-changelog.md:125 msgid "" -"**Fine-tune LLMs with LLM FlowerTune** " -"([#3029](https://github.com/adap/flower/pull/3029), " -"[#3089](https://github.com/adap/flower/pull/3089), " -"[#3092](https://github.com/adap/flower/pull/3092), " -"[#3100](https://github.com/adap/flower/pull/3100), " -"[#3114](https://github.com/adap/flower/pull/3114), " -"[#3162](https://github.com/adap/flower/pull/3162), " -"[#3172](https://github.com/adap/flower/pull/3172))" +"**Fine-tune LLMs with LLM FlowerTune** ([#3029](https://github.com/adap/" +"flower/pull/3029), [#3089](https://github.com/adap/flower/pull/3089), [#3092]" +"(https://github.com/adap/flower/pull/3092), [#3100](https://github.com/adap/" +"flower/pull/3100), [#3114](https://github.com/adap/flower/pull/3114), [#3162]" +"(https://github.com/adap/flower/pull/3162), [#3172](https://github.com/adap/" +"flower/pull/3172))" msgstr "" #: ../../source/ref-changelog.md:127 msgid "" -"We are introducing LLM FlowerTune, an introductory example that " -"demonstrates federated LLM fine-tuning of pre-trained Llama2 models on " -"the Alpaca-GPT4 dataset. The example is built to be easily adapted to use" -" different models and/or datasets. Read our blog post [LLM FlowerTune: " -"Federated LLM Fine-tuning with Flower](https://flower.ai/blog/2024-03-14" -"-llm-flowertune-federated-llm-finetuning-with-flower/) for more details." +"We are introducing LLM FlowerTune, an introductory example that demonstrates " +"federated LLM fine-tuning of pre-trained Llama2 models on the Alpaca-GPT4 " +"dataset. The example is built to be easily adapted to use different models " +"and/or datasets. Read our blog post [LLM FlowerTune: Federated LLM Fine-" +"tuning with Flower](https://flower.ai/blog/2024-03-14-llm-flowertune-" +"federated-llm-finetuning-with-flower/) for more details." msgstr "" #: ../../source/ref-changelog.md:129 msgid "" -"**Introduce built-in Differential Privacy (preview)** " -"([#2798](https://github.com/adap/flower/pull/2798), " -"[#2959](https://github.com/adap/flower/pull/2959), " -"[#3038](https://github.com/adap/flower/pull/3038), " -"[#3147](https://github.com/adap/flower/pull/3147), " -"[#2909](https://github.com/adap/flower/pull/2909), " -"[#2893](https://github.com/adap/flower/pull/2893), " -"[#2892](https://github.com/adap/flower/pull/2892), " -"[#3039](https://github.com/adap/flower/pull/3039), " -"[#3074](https://github.com/adap/flower/pull/3074))" +"**Introduce built-in Differential Privacy (preview)** ([#2798](https://" +"github.com/adap/flower/pull/2798), [#2959](https://github.com/adap/flower/" +"pull/2959), [#3038](https://github.com/adap/flower/pull/3038), [#3147]" +"(https://github.com/adap/flower/pull/3147), [#2909](https://github.com/adap/" +"flower/pull/2909), [#2893](https://github.com/adap/flower/pull/2893), [#2892]" +"(https://github.com/adap/flower/pull/2892), [#3039](https://github.com/adap/" +"flower/pull/3039), [#3074](https://github.com/adap/flower/pull/3074))" msgstr "" #: ../../source/ref-changelog.md:131 msgid "" "Built-in Differential Privacy is here! Flower supports both central and " -"local differential privacy (DP). Central DP can be configured with either" -" fixed or adaptive clipping. The clipping can happen either on the " -"server-side or the client-side. Local DP does both clipping and noising " -"on the client-side. A new documentation page [explains Differential " -"Privacy approaches](https://flower.ai/docs/framework/explanation-" -"differential-privacy.html) and a new how-to guide describes [how to use " -"the new Differential Privacy components](https://flower.ai/docs/framework" -"/how-to-use-differential-privacy.html) in Flower." +"local differential privacy (DP). Central DP can be configured with either " +"fixed or adaptive clipping. The clipping can happen either on the server-" +"side or the client-side. Local DP does both clipping and noising on the " +"client-side. A new documentation page [explains Differential Privacy " +"approaches](https://flower.ai/docs/framework/explanation-differential-" +"privacy.html) and a new how-to guide describes [how to use the new " +"Differential Privacy components](https://flower.ai/docs/framework/how-to-use-" +"differential-privacy.html) in Flower." msgstr "" #: ../../source/ref-changelog.md:133 msgid "" -"**Introduce built-in Secure Aggregation (preview)** " -"([#3120](https://github.com/adap/flower/pull/3120), " -"[#3110](https://github.com/adap/flower/pull/3110), " -"[#3108](https://github.com/adap/flower/pull/3108))" +"**Introduce built-in Secure Aggregation (preview)** ([#3120](https://github." +"com/adap/flower/pull/3120), [#3110](https://github.com/adap/flower/" +"pull/3110), [#3108](https://github.com/adap/flower/pull/3108))" msgstr "" #: ../../source/ref-changelog.md:135 msgid "" -"Built-in Secure Aggregation is here! Flower now supports different secure" -" aggregation protocols out-of-the-box. The best part? You can add secure " -"aggregation to your Flower projects with only a few lines of code. In " -"this initial release, we inlcude support for SecAgg and SecAgg+, but more" -" protocols will be implemented shortly. We'll also add detailed docs that" -" explain secure aggregation and how to use it in Flower. You can already " +"Built-in Secure Aggregation is here! Flower now supports different secure " +"aggregation protocols out-of-the-box. The best part? You can add secure " +"aggregation to your Flower projects with only a few lines of code. In this " +"initial release, we inlcude support for SecAgg and SecAgg+, but more " +"protocols will be implemented shortly. We'll also add detailed docs that " +"explain secure aggregation and how to use it in Flower. You can already " "check out the new code example that shows how to use Flower to easily " -"combine Federated Learning, Differential Privacy and Secure Aggregation " -"in the same project." +"combine Federated Learning, Differential Privacy and Secure Aggregation in " +"the same project." msgstr "" #: ../../source/ref-changelog.md:137 msgid "" -"**Introduce** `flwr` **CLI (preview)** " -"([#2942](https://github.com/adap/flower/pull/2942), " -"[#3055](https://github.com/adap/flower/pull/3055), " -"[#3111](https://github.com/adap/flower/pull/3111), " -"[#3130](https://github.com/adap/flower/pull/3130), " -"[#3136](https://github.com/adap/flower/pull/3136), " -"[#3094](https://github.com/adap/flower/pull/3094), " -"[#3059](https://github.com/adap/flower/pull/3059), " -"[#3049](https://github.com/adap/flower/pull/3049), " -"[#3142](https://github.com/adap/flower/pull/3142))" +"**Introduce** `flwr` **CLI (preview)** ([#2942](https://github.com/adap/" +"flower/pull/2942), [#3055](https://github.com/adap/flower/pull/3055), [#3111]" +"(https://github.com/adap/flower/pull/3111), [#3130](https://github.com/adap/" +"flower/pull/3130), [#3136](https://github.com/adap/flower/pull/3136), [#3094]" +"(https://github.com/adap/flower/pull/3094), [#3059](https://github.com/adap/" +"flower/pull/3059), [#3049](https://github.com/adap/flower/pull/3049), [#3142]" +"(https://github.com/adap/flower/pull/3142))" msgstr "" #: ../../source/ref-changelog.md:139 msgid "" -"A new `flwr` CLI command allows creating new Flower projects (`flwr new`)" -" and then running them using the Simulation Engine (`flwr run`)." +"A new `flwr` CLI command allows creating new Flower projects (`flwr new`) " +"and then running them using the Simulation Engine (`flwr run`)." msgstr "" #: ../../source/ref-changelog.md:141 msgid "" -"**Introduce Flower Next Simulation Engine** " -"([#3024](https://github.com/adap/flower/pull/3024), " -"[#3061](https://github.com/adap/flower/pull/3061), " -"[#2997](https://github.com/adap/flower/pull/2997), " -"[#2783](https://github.com/adap/flower/pull/2783), " -"[#3184](https://github.com/adap/flower/pull/3184), " -"[#3075](https://github.com/adap/flower/pull/3075), " -"[#3047](https://github.com/adap/flower/pull/3047), " -"[#2998](https://github.com/adap/flower/pull/2998), " -"[#3009](https://github.com/adap/flower/pull/3009), " -"[#3008](https://github.com/adap/flower/pull/3008))" +"**Introduce Flower Next Simulation Engine** ([#3024](https://github.com/adap/" +"flower/pull/3024), [#3061](https://github.com/adap/flower/pull/3061), [#2997]" +"(https://github.com/adap/flower/pull/2997), [#2783](https://github.com/adap/" +"flower/pull/2783), [#3184](https://github.com/adap/flower/pull/3184), [#3075]" +"(https://github.com/adap/flower/pull/3075), [#3047](https://github.com/adap/" +"flower/pull/3047), [#2998](https://github.com/adap/flower/pull/2998), [#3009]" +"(https://github.com/adap/flower/pull/3009), [#3008](https://github.com/adap/" +"flower/pull/3008))" msgstr "" #: ../../source/ref-changelog.md:143 msgid "" -"The Flower Simulation Engine can now run Flower Next projects. For " -"notebook environments, there's also a new `run_simulation` function that " -"can run `ServerApp` and `ClientApp`." +"The Flower Simulation Engine can now run Flower Next projects. For notebook " +"environments, there's also a new `run_simulation` function that can run " +"`ServerApp` and `ClientApp`." msgstr "" #: ../../source/ref-changelog.md:145 msgid "" -"**Handle SuperNode connection errors** " -"([#2969](https://github.com/adap/flower/pull/2969))" +"**Handle SuperNode connection errors** ([#2969](https://github.com/adap/" +"flower/pull/2969))" msgstr "" #: ../../source/ref-changelog.md:147 msgid "" -"A SuperNode will now try to reconnect indefinitely to the SuperLink in " -"case of connection errors. The arguments `--max-retries` and `--max-wait-" -"time` can now be passed to the `flower-client-app` command. `--max-" -"retries` will define the number of tentatives the client should make " -"before it gives up trying to reconnect to the SuperLink, and, `--max-" -"wait-time` defines the time before the SuperNode gives up trying to " -"reconnect to the SuperLink." +"A SuperNode will now try to reconnect indefinitely to the SuperLink in case " +"of connection errors. The arguments `--max-retries` and `--max-wait-time` " +"can now be passed to the `flower-client-app` command. `--max-retries` will " +"define the number of tentatives the client should make before it gives up " +"trying to reconnect to the SuperLink, and, `--max-wait-time` defines the " +"time before the SuperNode gives up trying to reconnect to the SuperLink." msgstr "" #: ../../source/ref-changelog.md:149 msgid "" -"**General updates to Flower Baselines** " -"([#2904](https://github.com/adap/flower/pull/2904), " -"[#2482](https://github.com/adap/flower/pull/2482), " -"[#2985](https://github.com/adap/flower/pull/2985), " -"[#2968](https://github.com/adap/flower/pull/2968))" +"**General updates to Flower Baselines** ([#2904](https://github.com/adap/" +"flower/pull/2904), [#2482](https://github.com/adap/flower/pull/2482), [#2985]" +"(https://github.com/adap/flower/pull/2985), [#2968](https://github.com/adap/" +"flower/pull/2968))" msgstr "" #: ../../source/ref-changelog.md:151 @@ -15520,133 +16118,100 @@ msgstr "" #: ../../source/ref-changelog.md:153 msgid "" -"**Improve documentation and translations** " -"([#3050](https://github.com/adap/flower/pull/3050), " -"[#3044](https://github.com/adap/flower/pull/3044), " -"[#3043](https://github.com/adap/flower/pull/3043), " -"[#2986](https://github.com/adap/flower/pull/2986), " -"[#3041](https://github.com/adap/flower/pull/3041), " -"[#3046](https://github.com/adap/flower/pull/3046), " -"[#3042](https://github.com/adap/flower/pull/3042), " -"[#2978](https://github.com/adap/flower/pull/2978), " -"[#2952](https://github.com/adap/flower/pull/2952), " -"[#3167](https://github.com/adap/flower/pull/3167), " -"[#2953](https://github.com/adap/flower/pull/2953), " -"[#3045](https://github.com/adap/flower/pull/3045), " -"[#2654](https://github.com/adap/flower/pull/2654), " -"[#3082](https://github.com/adap/flower/pull/3082), " -"[#2990](https://github.com/adap/flower/pull/2990), " -"[#2989](https://github.com/adap/flower/pull/2989))" +"**Improve documentation and translations** ([#3050](https://github.com/adap/" +"flower/pull/3050), [#3044](https://github.com/adap/flower/pull/3044), [#3043]" +"(https://github.com/adap/flower/pull/3043), [#2986](https://github.com/adap/" +"flower/pull/2986), [#3041](https://github.com/adap/flower/pull/3041), [#3046]" +"(https://github.com/adap/flower/pull/3046), [#3042](https://github.com/adap/" +"flower/pull/3042), [#2978](https://github.com/adap/flower/pull/2978), [#2952]" +"(https://github.com/adap/flower/pull/2952), [#3167](https://github.com/adap/" +"flower/pull/3167), [#2953](https://github.com/adap/flower/pull/2953), [#3045]" +"(https://github.com/adap/flower/pull/3045), [#2654](https://github.com/adap/" +"flower/pull/2654), [#3082](https://github.com/adap/flower/pull/3082), [#2990]" +"(https://github.com/adap/flower/pull/2990), [#2989](https://github.com/adap/" +"flower/pull/2989))" msgstr "" #: ../../source/ref-changelog.md:155 msgid "" "As usual, we merged many smaller and larger improvements to the " -"documentation. A special thank you goes to [Sebastian van der " -"Voort](https://github.com/svdvoort) for landing a big documentation PR!" +"documentation. A special thank you goes to [Sebastian van der Voort](https://" +"github.com/svdvoort) for landing a big documentation PR!" msgstr "" #: ../../source/ref-changelog.md:157 msgid "" -"**General updates to Flower Examples** " -"([3134](https://github.com/adap/flower/pull/3134), " -"[2996](https://github.com/adap/flower/pull/2996), " -"[2930](https://github.com/adap/flower/pull/2930), " -"[2967](https://github.com/adap/flower/pull/2967), " -"[2467](https://github.com/adap/flower/pull/2467), " -"[2910](https://github.com/adap/flower/pull/2910), " -"[#2918](https://github.com/adap/flower/pull/2918), " -"[#2773](https://github.com/adap/flower/pull/2773), " -"[#3063](https://github.com/adap/flower/pull/3063), " -"[#3116](https://github.com/adap/flower/pull/3116), " -"[#3117](https://github.com/adap/flower/pull/3117))" +"**General updates to Flower Examples** ([3134](https://github.com/adap/" +"flower/pull/3134), [2996](https://github.com/adap/flower/pull/2996), [2930]" +"(https://github.com/adap/flower/pull/2930), [2967](https://github.com/adap/" +"flower/pull/2967), [2467](https://github.com/adap/flower/pull/2467), [2910]" +"(https://github.com/adap/flower/pull/2910), [#2918](https://github.com/adap/" +"flower/pull/2918), [#2773](https://github.com/adap/flower/pull/2773), [#3063]" +"(https://github.com/adap/flower/pull/3063), [#3116](https://github.com/adap/" +"flower/pull/3116), [#3117](https://github.com/adap/flower/pull/3117))" msgstr "" #: ../../source/ref-changelog.md:159 msgid "" -"Two new examples show federated training of a Vision Transformer (ViT) " -"and federated learning in a medical context using the popular MONAI " -"library. `quickstart-pytorch` and `quickstart-tensorflow` demonstrate the" -" new Flower Next `ServerApp` and `ClientApp`. Many other examples " -"received considerable updates as well." +"Two new examples show federated training of a Vision Transformer (ViT) and " +"federated learning in a medical context using the popular MONAI library. " +"`quickstart-pytorch` and `quickstart-tensorflow` demonstrate the new Flower " +"Next `ServerApp` and `ClientApp`. Many other examples received considerable " +"updates as well." msgstr "" #: ../../source/ref-changelog.md:161 msgid "" -"**General improvements** " -"([#3171](https://github.com/adap/flower/pull/3171), " -"[3099](https://github.com/adap/flower/pull/3099), " -"[3003](https://github.com/adap/flower/pull/3003), " -"[3145](https://github.com/adap/flower/pull/3145), " -"[3017](https://github.com/adap/flower/pull/3017), " -"[3085](https://github.com/adap/flower/pull/3085), " -"[3012](https://github.com/adap/flower/pull/3012), " -"[3119](https://github.com/adap/flower/pull/3119), " -"[2991](https://github.com/adap/flower/pull/2991), " -"[2970](https://github.com/adap/flower/pull/2970), " -"[2980](https://github.com/adap/flower/pull/2980), " -"[3086](https://github.com/adap/flower/pull/3086), " -"[2932](https://github.com/adap/flower/pull/2932), " -"[2928](https://github.com/adap/flower/pull/2928), " -"[2941](https://github.com/adap/flower/pull/2941), " -"[2933](https://github.com/adap/flower/pull/2933), " -"[3181](https://github.com/adap/flower/pull/3181), " -"[2973](https://github.com/adap/flower/pull/2973), " -"[2992](https://github.com/adap/flower/pull/2992), " -"[2915](https://github.com/adap/flower/pull/2915), " -"[3040](https://github.com/adap/flower/pull/3040), " -"[3022](https://github.com/adap/flower/pull/3022), " -"[3032](https://github.com/adap/flower/pull/3032), " -"[2902](https://github.com/adap/flower/pull/2902), " -"[2931](https://github.com/adap/flower/pull/2931), " -"[3005](https://github.com/adap/flower/pull/3005), " -"[3132](https://github.com/adap/flower/pull/3132), " -"[3115](https://github.com/adap/flower/pull/3115), " -"[2944](https://github.com/adap/flower/pull/2944), " -"[3064](https://github.com/adap/flower/pull/3064), " -"[3106](https://github.com/adap/flower/pull/3106), " -"[2974](https://github.com/adap/flower/pull/2974), " -"[3178](https://github.com/adap/flower/pull/3178), " -"[2993](https://github.com/adap/flower/pull/2993), " -"[3186](https://github.com/adap/flower/pull/3186), " -"[3091](https://github.com/adap/flower/pull/3091), " -"[3125](https://github.com/adap/flower/pull/3125), " -"[3093](https://github.com/adap/flower/pull/3093), " -"[3013](https://github.com/adap/flower/pull/3013), " -"[3033](https://github.com/adap/flower/pull/3033), " -"[3133](https://github.com/adap/flower/pull/3133), " -"[3068](https://github.com/adap/flower/pull/3068), " -"[2916](https://github.com/adap/flower/pull/2916), " -"[2975](https://github.com/adap/flower/pull/2975), " -"[2984](https://github.com/adap/flower/pull/2984), " -"[2846](https://github.com/adap/flower/pull/2846), " -"[3077](https://github.com/adap/flower/pull/3077), " -"[3143](https://github.com/adap/flower/pull/3143), " -"[2921](https://github.com/adap/flower/pull/2921), " -"[3101](https://github.com/adap/flower/pull/3101), " -"[2927](https://github.com/adap/flower/pull/2927), " -"[2995](https://github.com/adap/flower/pull/2995), " -"[2972](https://github.com/adap/flower/pull/2972), " -"[2912](https://github.com/adap/flower/pull/2912), " -"[3065](https://github.com/adap/flower/pull/3065), " -"[3028](https://github.com/adap/flower/pull/3028), " -"[2922](https://github.com/adap/flower/pull/2922), " -"[2982](https://github.com/adap/flower/pull/2982), " -"[2914](https://github.com/adap/flower/pull/2914), " -"[3179](https://github.com/adap/flower/pull/3179), " -"[3080](https://github.com/adap/flower/pull/3080), " -"[2994](https://github.com/adap/flower/pull/2994), " -"[3187](https://github.com/adap/flower/pull/3187), " -"[2926](https://github.com/adap/flower/pull/2926), " -"[3018](https://github.com/adap/flower/pull/3018), " -"[3144](https://github.com/adap/flower/pull/3144), " -"[3011](https://github.com/adap/flower/pull/3011), " -"[#3152](https://github.com/adap/flower/pull/3152), " -"[#2836](https://github.com/adap/flower/pull/2836), " -"[#2929](https://github.com/adap/flower/pull/2929), " -"[#2943](https://github.com/adap/flower/pull/2943), " -"[#2955](https://github.com/adap/flower/pull/2955), " -"[#2954](https://github.com/adap/flower/pull/2954))" +"**General improvements** ([#3171](https://github.com/adap/flower/pull/3171), " +"[3099](https://github.com/adap/flower/pull/3099), [3003](https://github.com/" +"adap/flower/pull/3003), [3145](https://github.com/adap/flower/pull/3145), " +"[3017](https://github.com/adap/flower/pull/3017), [3085](https://github.com/" +"adap/flower/pull/3085), [3012](https://github.com/adap/flower/pull/3012), " +"[3119](https://github.com/adap/flower/pull/3119), [2991](https://github.com/" +"adap/flower/pull/2991), [2970](https://github.com/adap/flower/pull/2970), " +"[2980](https://github.com/adap/flower/pull/2980), [3086](https://github.com/" +"adap/flower/pull/3086), [2932](https://github.com/adap/flower/pull/2932), " +"[2928](https://github.com/adap/flower/pull/2928), [2941](https://github.com/" +"adap/flower/pull/2941), [2933](https://github.com/adap/flower/pull/2933), " +"[3181](https://github.com/adap/flower/pull/3181), [2973](https://github.com/" +"adap/flower/pull/2973), [2992](https://github.com/adap/flower/pull/2992), " +"[2915](https://github.com/adap/flower/pull/2915), [3040](https://github.com/" +"adap/flower/pull/3040), [3022](https://github.com/adap/flower/pull/3022), " +"[3032](https://github.com/adap/flower/pull/3032), [2902](https://github.com/" +"adap/flower/pull/2902), [2931](https://github.com/adap/flower/pull/2931), " +"[3005](https://github.com/adap/flower/pull/3005), [3132](https://github.com/" +"adap/flower/pull/3132), [3115](https://github.com/adap/flower/pull/3115), " +"[2944](https://github.com/adap/flower/pull/2944), [3064](https://github.com/" +"adap/flower/pull/3064), [3106](https://github.com/adap/flower/pull/3106), " +"[2974](https://github.com/adap/flower/pull/2974), [3178](https://github.com/" +"adap/flower/pull/3178), [2993](https://github.com/adap/flower/pull/2993), " +"[3186](https://github.com/adap/flower/pull/3186), [3091](https://github.com/" +"adap/flower/pull/3091), [3125](https://github.com/adap/flower/pull/3125), " +"[3093](https://github.com/adap/flower/pull/3093), [3013](https://github.com/" +"adap/flower/pull/3013), [3033](https://github.com/adap/flower/pull/3033), " +"[3133](https://github.com/adap/flower/pull/3133), [3068](https://github.com/" +"adap/flower/pull/3068), [2916](https://github.com/adap/flower/pull/2916), " +"[2975](https://github.com/adap/flower/pull/2975), [2984](https://github.com/" +"adap/flower/pull/2984), [2846](https://github.com/adap/flower/pull/2846), " +"[3077](https://github.com/adap/flower/pull/3077), [3143](https://github.com/" +"adap/flower/pull/3143), [2921](https://github.com/adap/flower/pull/2921), " +"[3101](https://github.com/adap/flower/pull/3101), [2927](https://github.com/" +"adap/flower/pull/2927), [2995](https://github.com/adap/flower/pull/2995), " +"[2972](https://github.com/adap/flower/pull/2972), [2912](https://github.com/" +"adap/flower/pull/2912), [3065](https://github.com/adap/flower/pull/3065), " +"[3028](https://github.com/adap/flower/pull/3028), [2922](https://github.com/" +"adap/flower/pull/2922), [2982](https://github.com/adap/flower/pull/2982), " +"[2914](https://github.com/adap/flower/pull/2914), [3179](https://github.com/" +"adap/flower/pull/3179), [3080](https://github.com/adap/flower/pull/3080), " +"[2994](https://github.com/adap/flower/pull/2994), [3187](https://github.com/" +"adap/flower/pull/3187), [2926](https://github.com/adap/flower/pull/2926), " +"[3018](https://github.com/adap/flower/pull/3018), [3144](https://github.com/" +"adap/flower/pull/3144), [3011](https://github.com/adap/flower/pull/3011), " +"[#3152](https://github.com/adap/flower/pull/3152), [#2836](https://github." +"com/adap/flower/pull/2836), [#2929](https://github.com/adap/flower/" +"pull/2929), [#2943](https://github.com/adap/flower/pull/2943), [#2955]" +"(https://github.com/adap/flower/pull/2955), [#2954](https://github.com/adap/" +"flower/pull/2954))" msgstr "" #: ../../source/ref-changelog.md:165 ../../source/ref-changelog.md:442 @@ -15661,97 +16226,91 @@ msgstr "" #: ../../source/ref-changelog.md:173 msgid "" -"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles " -"Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo " -"Gabrielli`, `Gustavo Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S " -"Chaitanya Kumar`, `Mohammad Naseri`, `Nikos Vlachakis`, `Pritam Neog`, " -"`Robert Kuska`, `Robert Steiner`, `Taner Topal`, `Yahia Salaheldin " -"Shaaban`, `Yan Gao`, `Yasar Abbas` " +"`Aasheesh Singh`, `Adam Narozniak`, `Aml Hassan Esmil`, `Charles Beauville`, " +"`Daniel J. Beutel`, `Daniel Nata Nugraha`, `Edoardo Gabrielli`, `Gustavo " +"Bertoli`, `HelinLin`, `Heng Pan`, `Javier`, `M S Chaitanya Kumar`, `Mohammad " +"Naseri`, `Nikos Vlachakis`, `Pritam Neog`, `Robert Kuska`, `Robert Steiner`, " +"`Taner Topal`, `Yahia Salaheldin Shaaban`, `Yan Gao`, `Yasar Abbas` " msgstr "" #: ../../source/ref-changelog.md:177 msgid "" -"**Introduce stateful clients (experimental)** " -"([#2770](https://github.com/adap/flower/pull/2770), " -"[#2686](https://github.com/adap/flower/pull/2686), " -"[#2696](https://github.com/adap/flower/pull/2696), " -"[#2643](https://github.com/adap/flower/pull/2643), " -"[#2769](https://github.com/adap/flower/pull/2769))" +"**Introduce stateful clients (experimental)** ([#2770](https://github.com/" +"adap/flower/pull/2770), [#2686](https://github.com/adap/flower/pull/2686), " +"[#2696](https://github.com/adap/flower/pull/2696), [#2643](https://github." +"com/adap/flower/pull/2643), [#2769](https://github.com/adap/flower/" +"pull/2769))" msgstr "" #: ../../source/ref-changelog.md:179 msgid "" "Subclasses of `Client` and `NumPyClient` can now store local state that " "remains on the client. Let's start with the highlight first: this new " -"feature is compatible with both simulated clients (via " -"`start_simulation`) and networked clients (via `start_client`). It's also" -" the first preview of new abstractions like `Context` and `RecordSet`. " -"Clients can access state of type `RecordSet` via `state: RecordSet = " -"self.context.state`. Changes to this `RecordSet` are preserved across " -"different rounds of execution to enable stateful computations in a " -"unified way across simulation and deployment." +"feature is compatible with both simulated clients (via `start_simulation`) " +"and networked clients (via `start_client`). It's also the first preview of " +"new abstractions like `Context` and `RecordSet`. Clients can access state of " +"type `RecordSet` via `state: RecordSet = self.context.state`. Changes to " +"this `RecordSet` are preserved across different rounds of execution to " +"enable stateful computations in a unified way across simulation and " +"deployment." msgstr "" #: ../../source/ref-changelog.md:181 msgid "" -"**Improve performance** " -"([#2293](https://github.com/adap/flower/pull/2293))" +"**Improve performance** ([#2293](https://github.com/adap/flower/pull/2293))" msgstr "" #: ../../source/ref-changelog.md:183 msgid "" -"Flower is faster than ever. All `FedAvg`-derived strategies now use in-" -"place aggregation to reduce memory consumption. The Flower client " -"serialization/deserialization has been rewritten from the ground up, " -"which results in significant speedups, especially when the client-side " -"training time is short." +"Flower is faster than ever. All `FedAvg`-derived strategies now use in-place " +"aggregation to reduce memory consumption. The Flower client serialization/" +"deserialization has been rewritten from the ground up, which results in " +"significant speedups, especially when the client-side training time is short." msgstr "" #: ../../source/ref-changelog.md:185 msgid "" -"**Support Federated Learning with Apple MLX and Flower** " -"([#2693](https://github.com/adap/flower/pull/2693))" +"**Support Federated Learning with Apple MLX and Flower** ([#2693](https://" +"github.com/adap/flower/pull/2693))" msgstr "" #: ../../source/ref-changelog.md:187 msgid "" -"Flower has official support for federated learning using [Apple " -"MLX](https://ml-explore.github.io/mlx) via the new `quickstart-mlx` code " -"example." +"Flower has official support for federated learning using [Apple MLX](https://" +"ml-explore.github.io/mlx) via the new `quickstart-mlx` code example." msgstr "" #: ../../source/ref-changelog.md:189 msgid "" -"**Introduce new XGBoost cyclic strategy** " -"([#2666](https://github.com/adap/flower/pull/2666), " -"[#2668](https://github.com/adap/flower/pull/2668))" +"**Introduce new XGBoost cyclic strategy** ([#2666](https://github.com/adap/" +"flower/pull/2666), [#2668](https://github.com/adap/flower/pull/2668))" msgstr "" #: ../../source/ref-changelog.md:191 msgid "" -"A new strategy called `FedXgbCyclic` supports a client-by-client style of" -" training (often called cyclic). The `xgboost-comprehensive` code example" -" shows how to use it in a full project. In addition to that, `xgboost-" -"comprehensive` now also supports simulation mode. With this, Flower " -"offers best-in-class XGBoost support." +"A new strategy called `FedXgbCyclic` supports a client-by-client style of " +"training (often called cyclic). The `xgboost-comprehensive` code example " +"shows how to use it in a full project. In addition to that, `xgboost-" +"comprehensive` now also supports simulation mode. With this, Flower offers " +"best-in-class XGBoost support." msgstr "" #: ../../source/ref-changelog.md:193 msgid "" -"**Support Python 3.11** " -"([#2394](https://github.com/adap/flower/pull/2394))" +"**Support Python 3.11** ([#2394](https://github.com/adap/flower/pull/2394))" msgstr "" #: ../../source/ref-changelog.md:195 msgid "" -"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will " -"ensure better support for users using more recent Python versions." +"Framework tests now run on Python 3.8, 3.9, 3.10, and 3.11. This will ensure " +"better support for users using more recent Python versions." msgstr "" #: ../../source/ref-changelog.md:197 msgid "" -"**Update gRPC and ProtoBuf dependencies** " -"([#2814](https://github.com/adap/flower/pull/2814))" +"**Update gRPC and ProtoBuf dependencies** ([#2814](https://github.com/adap/" +"flower/pull/2814))" msgstr "" #: ../../source/ref-changelog.md:199 @@ -15762,72 +16321,65 @@ msgstr "" #: ../../source/ref-changelog.md:201 msgid "" -"**Introduce Docker image for Flower server** " -"([#2700](https://github.com/adap/flower/pull/2700), " -"[#2688](https://github.com/adap/flower/pull/2688), " -"[#2705](https://github.com/adap/flower/pull/2705), " -"[#2695](https://github.com/adap/flower/pull/2695), " -"[#2747](https://github.com/adap/flower/pull/2747), " -"[#2746](https://github.com/adap/flower/pull/2746), " -"[#2680](https://github.com/adap/flower/pull/2680), " -"[#2682](https://github.com/adap/flower/pull/2682), " -"[#2701](https://github.com/adap/flower/pull/2701))" +"**Introduce Docker image for Flower server** ([#2700](https://github.com/" +"adap/flower/pull/2700), [#2688](https://github.com/adap/flower/pull/2688), " +"[#2705](https://github.com/adap/flower/pull/2705), [#2695](https://github." +"com/adap/flower/pull/2695), [#2747](https://github.com/adap/flower/" +"pull/2747), [#2746](https://github.com/adap/flower/pull/2746), [#2680]" +"(https://github.com/adap/flower/pull/2680), [#2682](https://github.com/adap/" +"flower/pull/2682), [#2701](https://github.com/adap/flower/pull/2701))" msgstr "" #: ../../source/ref-changelog.md:203 msgid "" -"The Flower server can now be run using an official Docker image. A new " -"how-to guide explains [how to run Flower using " -"Docker](https://flower.ai/docs/framework/how-to-run-flower-using-" -"docker.html). An official Flower client Docker image will follow." +"The Flower server can now be run using an official Docker image. A new how-" +"to guide explains [how to run Flower using Docker](https://flower.ai/docs/" +"framework/how-to-run-flower-using-docker.html). An official Flower client " +"Docker image will follow." msgstr "" #: ../../source/ref-changelog.md:205 msgid "" -"**Introduce** `flower-via-docker-compose` **example** " -"([#2626](https://github.com/adap/flower/pull/2626))" +"**Introduce** `flower-via-docker-compose` **example** ([#2626](https://" +"github.com/adap/flower/pull/2626))" msgstr "" #: ../../source/ref-changelog.md:207 msgid "" -"**Introduce** `quickstart-sklearn-tabular` **example** " -"([#2719](https://github.com/adap/flower/pull/2719))" +"**Introduce** `quickstart-sklearn-tabular` **example** ([#2719](https://" +"github.com/adap/flower/pull/2719))" msgstr "" #: ../../source/ref-changelog.md:209 msgid "" -"**Introduce** `custom-metrics` **example** " -"([#1958](https://github.com/adap/flower/pull/1958))" +"**Introduce** `custom-metrics` **example** ([#1958](https://github.com/adap/" +"flower/pull/1958))" msgstr "" #: ../../source/ref-changelog.md:211 msgid "" -"**Update code examples to use Flower Datasets** " -"([#2450](https://github.com/adap/flower/pull/2450), " -"[#2456](https://github.com/adap/flower/pull/2456), " -"[#2318](https://github.com/adap/flower/pull/2318), " -"[#2712](https://github.com/adap/flower/pull/2712))" +"**Update code examples to use Flower Datasets** ([#2450](https://github.com/" +"adap/flower/pull/2450), [#2456](https://github.com/adap/flower/pull/2456), " +"[#2318](https://github.com/adap/flower/pull/2318), [#2712](https://github." +"com/adap/flower/pull/2712))" msgstr "" #: ../../source/ref-changelog.md:213 msgid "" -"Several code examples were updated to use [Flower " -"Datasets](https://flower.ai/docs/datasets/)." +"Several code examples were updated to use [Flower Datasets](https://flower." +"ai/docs/datasets/)." msgstr "" #: ../../source/ref-changelog.md:215 msgid "" -"**General updates to Flower Examples** " -"([#2381](https://github.com/adap/flower/pull/2381), " -"[#2805](https://github.com/adap/flower/pull/2805), " -"[#2782](https://github.com/adap/flower/pull/2782), " -"[#2806](https://github.com/adap/flower/pull/2806), " -"[#2829](https://github.com/adap/flower/pull/2829), " -"[#2825](https://github.com/adap/flower/pull/2825), " -"[#2816](https://github.com/adap/flower/pull/2816), " -"[#2726](https://github.com/adap/flower/pull/2726), " -"[#2659](https://github.com/adap/flower/pull/2659), " -"[#2655](https://github.com/adap/flower/pull/2655))" +"**General updates to Flower Examples** ([#2381](https://github.com/adap/" +"flower/pull/2381), [#2805](https://github.com/adap/flower/pull/2805), [#2782]" +"(https://github.com/adap/flower/pull/2782), [#2806](https://github.com/adap/" +"flower/pull/2806), [#2829](https://github.com/adap/flower/pull/2829), [#2825]" +"(https://github.com/adap/flower/pull/2825), [#2816](https://github.com/adap/" +"flower/pull/2816), [#2726](https://github.com/adap/flower/pull/2726), [#2659]" +"(https://github.com/adap/flower/pull/2659), [#2655](https://github.com/adap/" +"flower/pull/2655))" msgstr "" #: ../../source/ref-changelog.md:217 @@ -15840,8 +16392,8 @@ msgstr "" #: ../../source/ref-changelog.md:221 msgid "" -"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), " -"[#2771](https://github.com/adap/flower/pull/2771))" +"HFedXGBoost ([#2226](https://github.com/adap/flower/pull/2226), [#2771]" +"(https://github.com/adap/flower/pull/2771))" msgstr "" #: ../../source/ref-changelog.md:222 @@ -15866,149 +16418,119 @@ msgstr "" #: ../../source/ref-changelog.md:228 msgid "" -"**Improve documentation** " -"([#2674](https://github.com/adap/flower/pull/2674), " -"[#2480](https://github.com/adap/flower/pull/2480), " -"[#2826](https://github.com/adap/flower/pull/2826), " -"[#2727](https://github.com/adap/flower/pull/2727), " -"[#2761](https://github.com/adap/flower/pull/2761), " -"[#2900](https://github.com/adap/flower/pull/2900))" +"**Improve documentation** ([#2674](https://github.com/adap/flower/" +"pull/2674), [#2480](https://github.com/adap/flower/pull/2480), [#2826]" +"(https://github.com/adap/flower/pull/2826), [#2727](https://github.com/adap/" +"flower/pull/2727), [#2761](https://github.com/adap/flower/pull/2761), [#2900]" +"(https://github.com/adap/flower/pull/2900))" msgstr "" #: ../../source/ref-changelog.md:230 msgid "" -"**Improved testing and development infrastructure** " -"([#2797](https://github.com/adap/flower/pull/2797), " -"[#2676](https://github.com/adap/flower/pull/2676), " -"[#2644](https://github.com/adap/flower/pull/2644), " -"[#2656](https://github.com/adap/flower/pull/2656), " -"[#2848](https://github.com/adap/flower/pull/2848), " -"[#2675](https://github.com/adap/flower/pull/2675), " -"[#2735](https://github.com/adap/flower/pull/2735), " -"[#2767](https://github.com/adap/flower/pull/2767), " -"[#2732](https://github.com/adap/flower/pull/2732), " -"[#2744](https://github.com/adap/flower/pull/2744), " -"[#2681](https://github.com/adap/flower/pull/2681), " -"[#2699](https://github.com/adap/flower/pull/2699), " -"[#2745](https://github.com/adap/flower/pull/2745), " -"[#2734](https://github.com/adap/flower/pull/2734), " -"[#2731](https://github.com/adap/flower/pull/2731), " -"[#2652](https://github.com/adap/flower/pull/2652), " -"[#2720](https://github.com/adap/flower/pull/2720), " -"[#2721](https://github.com/adap/flower/pull/2721), " -"[#2717](https://github.com/adap/flower/pull/2717), " -"[#2864](https://github.com/adap/flower/pull/2864), " -"[#2694](https://github.com/adap/flower/pull/2694), " -"[#2709](https://github.com/adap/flower/pull/2709), " -"[#2658](https://github.com/adap/flower/pull/2658), " -"[#2796](https://github.com/adap/flower/pull/2796), " -"[#2692](https://github.com/adap/flower/pull/2692), " -"[#2657](https://github.com/adap/flower/pull/2657), " -"[#2813](https://github.com/adap/flower/pull/2813), " -"[#2661](https://github.com/adap/flower/pull/2661), " -"[#2398](https://github.com/adap/flower/pull/2398))" +"**Improved testing and development infrastructure** ([#2797](https://github." +"com/adap/flower/pull/2797), [#2676](https://github.com/adap/flower/" +"pull/2676), [#2644](https://github.com/adap/flower/pull/2644), [#2656]" +"(https://github.com/adap/flower/pull/2656), [#2848](https://github.com/adap/" +"flower/pull/2848), [#2675](https://github.com/adap/flower/pull/2675), [#2735]" +"(https://github.com/adap/flower/pull/2735), [#2767](https://github.com/adap/" +"flower/pull/2767), [#2732](https://github.com/adap/flower/pull/2732), [#2744]" +"(https://github.com/adap/flower/pull/2744), [#2681](https://github.com/adap/" +"flower/pull/2681), [#2699](https://github.com/adap/flower/pull/2699), [#2745]" +"(https://github.com/adap/flower/pull/2745), [#2734](https://github.com/adap/" +"flower/pull/2734), [#2731](https://github.com/adap/flower/pull/2731), [#2652]" +"(https://github.com/adap/flower/pull/2652), [#2720](https://github.com/adap/" +"flower/pull/2720), [#2721](https://github.com/adap/flower/pull/2721), [#2717]" +"(https://github.com/adap/flower/pull/2717), [#2864](https://github.com/adap/" +"flower/pull/2864), [#2694](https://github.com/adap/flower/pull/2694), [#2709]" +"(https://github.com/adap/flower/pull/2709), [#2658](https://github.com/adap/" +"flower/pull/2658), [#2796](https://github.com/adap/flower/pull/2796), [#2692]" +"(https://github.com/adap/flower/pull/2692), [#2657](https://github.com/adap/" +"flower/pull/2657), [#2813](https://github.com/adap/flower/pull/2813), [#2661]" +"(https://github.com/adap/flower/pull/2661), [#2398](https://github.com/adap/" +"flower/pull/2398))" msgstr "" #: ../../source/ref-changelog.md:232 msgid "" -"The Flower testing and development infrastructure has received " -"substantial updates. This makes Flower 1.7 the most tested release ever." +"The Flower testing and development infrastructure has received substantial " +"updates. This makes Flower 1.7 the most tested release ever." msgstr "" #: ../../source/ref-changelog.md:234 msgid "" -"**Update dependencies** " -"([#2753](https://github.com/adap/flower/pull/2753), " -"[#2651](https://github.com/adap/flower/pull/2651), " -"[#2739](https://github.com/adap/flower/pull/2739), " -"[#2837](https://github.com/adap/flower/pull/2837), " -"[#2788](https://github.com/adap/flower/pull/2788), " -"[#2811](https://github.com/adap/flower/pull/2811), " -"[#2774](https://github.com/adap/flower/pull/2774), " -"[#2790](https://github.com/adap/flower/pull/2790), " -"[#2751](https://github.com/adap/flower/pull/2751), " -"[#2850](https://github.com/adap/flower/pull/2850), " -"[#2812](https://github.com/adap/flower/pull/2812), " -"[#2872](https://github.com/adap/flower/pull/2872), " -"[#2736](https://github.com/adap/flower/pull/2736), " -"[#2756](https://github.com/adap/flower/pull/2756), " -"[#2857](https://github.com/adap/flower/pull/2857), " -"[#2757](https://github.com/adap/flower/pull/2757), " -"[#2810](https://github.com/adap/flower/pull/2810), " -"[#2740](https://github.com/adap/flower/pull/2740), " -"[#2789](https://github.com/adap/flower/pull/2789))" +"**Update dependencies** ([#2753](https://github.com/adap/flower/pull/2753), " +"[#2651](https://github.com/adap/flower/pull/2651), [#2739](https://github." +"com/adap/flower/pull/2739), [#2837](https://github.com/adap/flower/" +"pull/2837), [#2788](https://github.com/adap/flower/pull/2788), [#2811]" +"(https://github.com/adap/flower/pull/2811), [#2774](https://github.com/adap/" +"flower/pull/2774), [#2790](https://github.com/adap/flower/pull/2790), [#2751]" +"(https://github.com/adap/flower/pull/2751), [#2850](https://github.com/adap/" +"flower/pull/2850), [#2812](https://github.com/adap/flower/pull/2812), [#2872]" +"(https://github.com/adap/flower/pull/2872), [#2736](https://github.com/adap/" +"flower/pull/2736), [#2756](https://github.com/adap/flower/pull/2756), [#2857]" +"(https://github.com/adap/flower/pull/2857), [#2757](https://github.com/adap/" +"flower/pull/2757), [#2810](https://github.com/adap/flower/pull/2810), [#2740]" +"(https://github.com/adap/flower/pull/2740), [#2789](https://github.com/adap/" +"flower/pull/2789))" msgstr "" #: ../../source/ref-changelog.md:236 msgid "" -"**General improvements** " -"([#2803](https://github.com/adap/flower/pull/2803), " -"[#2847](https://github.com/adap/flower/pull/2847), " -"[#2877](https://github.com/adap/flower/pull/2877), " -"[#2690](https://github.com/adap/flower/pull/2690), " -"[#2889](https://github.com/adap/flower/pull/2889), " -"[#2874](https://github.com/adap/flower/pull/2874), " -"[#2819](https://github.com/adap/flower/pull/2819), " -"[#2689](https://github.com/adap/flower/pull/2689), " -"[#2457](https://github.com/adap/flower/pull/2457), " -"[#2870](https://github.com/adap/flower/pull/2870), " -"[#2669](https://github.com/adap/flower/pull/2669), " -"[#2876](https://github.com/adap/flower/pull/2876), " -"[#2885](https://github.com/adap/flower/pull/2885), " -"[#2858](https://github.com/adap/flower/pull/2858), " -"[#2867](https://github.com/adap/flower/pull/2867), " -"[#2351](https://github.com/adap/flower/pull/2351), " -"[#2886](https://github.com/adap/flower/pull/2886), " -"[#2860](https://github.com/adap/flower/pull/2860), " -"[#2828](https://github.com/adap/flower/pull/2828), " -"[#2869](https://github.com/adap/flower/pull/2869), " -"[#2875](https://github.com/adap/flower/pull/2875), " -"[#2733](https://github.com/adap/flower/pull/2733), " -"[#2488](https://github.com/adap/flower/pull/2488), " -"[#2646](https://github.com/adap/flower/pull/2646), " -"[#2879](https://github.com/adap/flower/pull/2879), " -"[#2821](https://github.com/adap/flower/pull/2821), " -"[#2855](https://github.com/adap/flower/pull/2855), " -"[#2800](https://github.com/adap/flower/pull/2800), " -"[#2807](https://github.com/adap/flower/pull/2807), " -"[#2801](https://github.com/adap/flower/pull/2801), " -"[#2804](https://github.com/adap/flower/pull/2804), " -"[#2851](https://github.com/adap/flower/pull/2851), " -"[#2787](https://github.com/adap/flower/pull/2787), " -"[#2852](https://github.com/adap/flower/pull/2852), " -"[#2672](https://github.com/adap/flower/pull/2672), " -"[#2759](https://github.com/adap/flower/pull/2759))" +"**General improvements** ([#2803](https://github.com/adap/flower/pull/2803), " +"[#2847](https://github.com/adap/flower/pull/2847), [#2877](https://github." +"com/adap/flower/pull/2877), [#2690](https://github.com/adap/flower/" +"pull/2690), [#2889](https://github.com/adap/flower/pull/2889), [#2874]" +"(https://github.com/adap/flower/pull/2874), [#2819](https://github.com/adap/" +"flower/pull/2819), [#2689](https://github.com/adap/flower/pull/2689), [#2457]" +"(https://github.com/adap/flower/pull/2457), [#2870](https://github.com/adap/" +"flower/pull/2870), [#2669](https://github.com/adap/flower/pull/2669), [#2876]" +"(https://github.com/adap/flower/pull/2876), [#2885](https://github.com/adap/" +"flower/pull/2885), [#2858](https://github.com/adap/flower/pull/2858), [#2867]" +"(https://github.com/adap/flower/pull/2867), [#2351](https://github.com/adap/" +"flower/pull/2351), [#2886](https://github.com/adap/flower/pull/2886), [#2860]" +"(https://github.com/adap/flower/pull/2860), [#2828](https://github.com/adap/" +"flower/pull/2828), [#2869](https://github.com/adap/flower/pull/2869), [#2875]" +"(https://github.com/adap/flower/pull/2875), [#2733](https://github.com/adap/" +"flower/pull/2733), [#2488](https://github.com/adap/flower/pull/2488), [#2646]" +"(https://github.com/adap/flower/pull/2646), [#2879](https://github.com/adap/" +"flower/pull/2879), [#2821](https://github.com/adap/flower/pull/2821), [#2855]" +"(https://github.com/adap/flower/pull/2855), [#2800](https://github.com/adap/" +"flower/pull/2800), [#2807](https://github.com/adap/flower/pull/2807), [#2801]" +"(https://github.com/adap/flower/pull/2801), [#2804](https://github.com/adap/" +"flower/pull/2804), [#2851](https://github.com/adap/flower/pull/2851), [#2787]" +"(https://github.com/adap/flower/pull/2787), [#2852](https://github.com/adap/" +"flower/pull/2852), [#2672](https://github.com/adap/flower/pull/2672), [#2759]" +"(https://github.com/adap/flower/pull/2759))" msgstr "" #: ../../source/ref-changelog.md:240 msgid "" -"**Deprecate** `start_numpy_client` " -"([#2563](https://github.com/adap/flower/pull/2563), " -"[#2718](https://github.com/adap/flower/pull/2718))" +"**Deprecate** `start_numpy_client` ([#2563](https://github.com/adap/flower/" +"pull/2563), [#2718](https://github.com/adap/flower/pull/2718))" msgstr "" #: ../../source/ref-changelog.md:242 msgid "" "Until now, clients of type `NumPyClient` needed to be started via " -"`start_numpy_client`. In our efforts to consolidate framework APIs, we " -"have introduced changes, and now all client types should start via " -"`start_client`. To continue using `NumPyClient` clients, you simply need " -"to first call the `.to_client()` method and then pass returned `Client` " -"object to `start_client`. The examples and the documentation have been " -"updated accordingly." +"`start_numpy_client`. In our efforts to consolidate framework APIs, we have " +"introduced changes, and now all client types should start via " +"`start_client`. To continue using `NumPyClient` clients, you simply need to " +"first call the `.to_client()` method and then pass returned `Client` object " +"to `start_client`. The examples and the documentation have been updated " +"accordingly." msgstr "" #: ../../source/ref-changelog.md:244 msgid "" -"**Deprecate legacy DP wrappers** " -"([#2749](https://github.com/adap/flower/pull/2749))" +"**Deprecate legacy DP wrappers** ([#2749](https://github.com/adap/flower/" +"pull/2749))" msgstr "" #: ../../source/ref-changelog.md:246 msgid "" -"Legacy DP wrapper classes are deprecated, but still functional. This is " -"in preparation for an all-new pluggable version of differential privacy " -"support in Flower." +"Legacy DP wrapper classes are deprecated, but still functional. This is in " +"preparation for an all-new pluggable version of differential privacy support " +"in Flower." msgstr "" #: ../../source/ref-changelog.md:248 @@ -16019,28 +16541,26 @@ msgstr "" #: ../../source/ref-changelog.md:250 msgid "" -"**Rename** `certificates` **to** `root_certificates` **in** `Driver` " -"([#2890](https://github.com/adap/flower/pull/2890))" +"**Rename** `certificates` **to** `root_certificates` **in** `Driver` ([#2890]" +"(https://github.com/adap/flower/pull/2890))" msgstr "" #: ../../source/ref-changelog.md:252 msgid "" -"**Drop experimental** `Task` **fields** " -"([#2866](https://github.com/adap/flower/pull/2866), " -"[#2865](https://github.com/adap/flower/pull/2865))" +"**Drop experimental** `Task` **fields** ([#2866](https://github.com/adap/" +"flower/pull/2866), [#2865](https://github.com/adap/flower/pull/2865))" msgstr "" #: ../../source/ref-changelog.md:254 msgid "" "Experimental fields `sa`, `legacy_server_message` and " -"`legacy_client_message` were removed from `Task` message. The removed " -"fields are superseded by the new `RecordSet` abstraction." +"`legacy_client_message` were removed from `Task` message. The removed fields " +"are superseded by the new `RecordSet` abstraction." msgstr "" #: ../../source/ref-changelog.md:256 msgid "" -"**Retire MXNet examples** " -"([#2724](https://github.com/adap/flower/pull/2724))" +"**Retire MXNet examples** ([#2724](https://github.com/adap/flower/pull/2724))" msgstr "" #: ../../source/ref-changelog.md:258 @@ -16058,65 +16578,62 @@ msgstr "" msgid "" "`Aashish Kolluri`, `Adam Narozniak`, `Alessio Mora`, `Barathwaja S`, " "`Charles Beauville`, `Daniel J. Beutel`, `Daniel Nata Nugraha`, `Gabriel " -"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`," -" `Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, " -"`Steve Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, " -"`cnxdeveloper`, `k3nfalt` " +"Mota`, `Heng Pan`, `Ivan Agarský`, `JS.KIM`, `Javier`, `Marius Schlegel`, " +"`Navin Chandra`, `Nic Lane`, `Peterpan828`, `Qinbin Li`, `Shaz-hash`, `Steve " +"Laskaridis`, `Taner Topal`, `William Lindskog`, `Yan Gao`, `cnxdeveloper`, " +"`k3nfalt` " msgstr "" #: ../../source/ref-changelog.md:270 msgid "" -"**Add experimental support for Python 3.12** " -"([#2565](https://github.com/adap/flower/pull/2565))" +"**Add experimental support for Python 3.12** ([#2565](https://github.com/" +"adap/flower/pull/2565))" msgstr "" #: ../../source/ref-changelog.md:272 msgid "" -"**Add new XGBoost examples** " -"([#2612](https://github.com/adap/flower/pull/2612), " -"[#2554](https://github.com/adap/flower/pull/2554), " -"[#2617](https://github.com/adap/flower/pull/2617), " -"[#2618](https://github.com/adap/flower/pull/2618), " -"[#2619](https://github.com/adap/flower/pull/2619), " -"[#2567](https://github.com/adap/flower/pull/2567))" +"**Add new XGBoost examples** ([#2612](https://github.com/adap/flower/" +"pull/2612), [#2554](https://github.com/adap/flower/pull/2554), [#2617]" +"(https://github.com/adap/flower/pull/2617), [#2618](https://github.com/adap/" +"flower/pull/2618), [#2619](https://github.com/adap/flower/pull/2619), [#2567]" +"(https://github.com/adap/flower/pull/2567))" msgstr "" #: ../../source/ref-changelog.md:274 msgid "" -"We have added a new `xgboost-quickstart` example alongside a new " -"`xgboost-comprehensive` example that goes more in-depth." +"We have added a new `xgboost-quickstart` example alongside a new `xgboost-" +"comprehensive` example that goes more in-depth." msgstr "" #: ../../source/ref-changelog.md:276 msgid "" -"**Add Vertical FL example** " -"([#2598](https://github.com/adap/flower/pull/2598))" +"**Add Vertical FL example** ([#2598](https://github.com/adap/flower/" +"pull/2598))" msgstr "" #: ../../source/ref-changelog.md:278 msgid "" -"We had many questions about Vertical Federated Learning using Flower, so " -"we decided to add an simple example for it on the [Titanic " -"dataset](https://www.kaggle.com/competitions/titanic/data) alongside a " -"tutorial (in the README)." +"We had many questions about Vertical Federated Learning using Flower, so we " +"decided to add an simple example for it on the [Titanic dataset](https://www." +"kaggle.com/competitions/titanic/data) alongside a tutorial (in the README)." msgstr "" #: ../../source/ref-changelog.md:280 msgid "" -"**Support custom** `ClientManager` **in** `start_driver()` " -"([#2292](https://github.com/adap/flower/pull/2292))" +"**Support custom** `ClientManager` **in** `start_driver()` ([#2292](https://" +"github.com/adap/flower/pull/2292))" msgstr "" #: ../../source/ref-changelog.md:282 msgid "" -"**Update REST API to support create and delete nodes** " -"([#2283](https://github.com/adap/flower/pull/2283))" +"**Update REST API to support create and delete nodes** ([#2283](https://" +"github.com/adap/flower/pull/2283))" msgstr "" #: ../../source/ref-changelog.md:284 msgid "" -"**Update the Android SDK** " -"([#2187](https://github.com/adap/flower/pull/2187))" +"**Update the Android SDK** ([#2187](https://github.com/adap/flower/" +"pull/2187))" msgstr "" #: ../../source/ref-changelog.md:286 @@ -16125,11 +16642,10 @@ msgstr "" #: ../../source/ref-changelog.md:288 msgid "" -"**Update the C++ SDK** " -"([#2537](https://github.com/adap/flower/pull/2537), " -"[#2528](https://github.com/adap/flower/pull/2528), " -"[#2523](https://github.com/adap/flower/pull/2523), " -"[#2522](https://github.com/adap/flower/pull/2522))" +"**Update the C++ SDK** ([#2537](https://github.com/adap/flower/pull/2537), " +"[#2528](https://github.com/adap/flower/pull/2528), [#2523](https://github." +"com/adap/flower/pull/2523), [#2522](https://github.com/adap/flower/" +"pull/2522))" msgstr "" #: ../../source/ref-changelog.md:290 @@ -16138,93 +16654,90 @@ msgstr "" #: ../../source/ref-changelog.md:292 msgid "" -"**Make HTTPS the new default** " -"([#2591](https://github.com/adap/flower/pull/2591), " -"[#2636](https://github.com/adap/flower/pull/2636))" +"**Make HTTPS the new default** ([#2591](https://github.com/adap/flower/" +"pull/2591), [#2636](https://github.com/adap/flower/pull/2636))" msgstr "" #: ../../source/ref-changelog.md:294 msgid "" "Flower is moving to HTTPS by default. The new `flower-server` requires " -"passing `--certificates`, but users can enable `--insecure` to use HTTP " -"for prototyping. The same applies to `flower-client`, which can either " -"use user-provided credentials or gRPC-bundled certificates to connect to " -"an HTTPS-enabled server or requires opt-out via passing `--insecure` to " -"enable insecure HTTP connections." +"passing `--certificates`, but users can enable `--insecure` to use HTTP for " +"prototyping. The same applies to `flower-client`, which can either use user-" +"provided credentials or gRPC-bundled certificates to connect to an HTTPS-" +"enabled server or requires opt-out via passing `--insecure` to enable " +"insecure HTTP connections." msgstr "" #: ../../source/ref-changelog.md:296 msgid "" -"For backward compatibility, `start_client()` and `start_numpy_client()` " -"will still start in insecure mode by default. In a future release, " -"insecure connections will require user opt-in by passing `insecure=True`." +"For backward compatibility, `start_client()` and `start_numpy_client()` will " +"still start in insecure mode by default. In a future release, insecure " +"connections will require user opt-in by passing `insecure=True`." msgstr "" #: ../../source/ref-changelog.md:298 msgid "" "**Unify client API** ([#2303](https://github.com/adap/flower/pull/2303), " -"[#2390](https://github.com/adap/flower/pull/2390), " -"[#2493](https://github.com/adap/flower/pull/2493))" +"[#2390](https://github.com/adap/flower/pull/2390), [#2493](https://github." +"com/adap/flower/pull/2493))" msgstr "" #: ../../source/ref-changelog.md:300 msgid "" -"Using the `client_fn`, Flower clients can interchangeably run as " -"standalone processes (i.e. via `start_client`) or in simulation (i.e. via" -" `start_simulation`) without requiring changes to how the client class is" -" defined and instantiated. The `to_client()` function is introduced to " +"Using the `client_fn`, Flower clients can interchangeably run as standalone " +"processes (i.e. via `start_client`) or in simulation (i.e. via " +"`start_simulation`) without requiring changes to how the client class is " +"defined and instantiated. The `to_client()` function is introduced to " "convert a `NumPyClient` to a `Client`." msgstr "" #: ../../source/ref-changelog.md:302 msgid "" -"**Add new** `Bulyan` **strategy** " -"([#1817](https://github.com/adap/flower/pull/1817), " -"[#1891](https://github.com/adap/flower/pull/1891))" +"**Add new** `Bulyan` **strategy** ([#1817](https://github.com/adap/flower/" +"pull/1817), [#1891](https://github.com/adap/flower/pull/1891))" msgstr "" #: ../../source/ref-changelog.md:304 msgid "" -"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., " -"2018](https://arxiv.org/abs/1802.07927)" +"The new `Bulyan` strategy implements Bulyan by [El Mhamdi et al., 2018]" +"(https://arxiv.org/abs/1802.07927)" msgstr "" #: ../../source/ref-changelog.md:306 msgid "" -"**Add new** `XGB Bagging` **strategy** " -"([#2611](https://github.com/adap/flower/pull/2611))" +"**Add new** `XGB Bagging` **strategy** ([#2611](https://github.com/adap/" +"flower/pull/2611))" msgstr "" #: ../../source/ref-changelog.md:308 ../../source/ref-changelog.md:310 msgid "" -"**Introduce `WorkloadState`** " -"([#2564](https://github.com/adap/flower/pull/2564), " -"[#2632](https://github.com/adap/flower/pull/2632))" +"**Introduce `WorkloadState`** ([#2564](https://github.com/adap/flower/" +"pull/2564), [#2632](https://github.com/adap/flower/pull/2632))" msgstr "" #: ../../source/ref-changelog.md:314 msgid "" -"FedProx ([#2210](https://github.com/adap/flower/pull/2210), " -"[#2286](https://github.com/adap/flower/pull/2286), " -"[#2509](https://github.com/adap/flower/pull/2509))" +"FedProx ([#2210](https://github.com/adap/flower/pull/2210), [#2286](https://" +"github.com/adap/flower/pull/2286), [#2509](https://github.com/adap/flower/" +"pull/2509))" msgstr "" #: ../../source/ref-changelog.md:316 msgid "" -"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), " -"[#2400](https://github.com/adap/flower/pull/2400))" +"Baselines Docs ([#2290](https://github.com/adap/flower/pull/2290), [#2400]" +"(https://github.com/adap/flower/pull/2400))" msgstr "" #: ../../source/ref-changelog.md:318 msgid "" -"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), " -"[#2507](https://github.com/adap/flower/pull/2507))" +"FedMLB ([#2340](https://github.com/adap/flower/pull/2340), [#2507](https://" +"github.com/adap/flower/pull/2507))" msgstr "" #: ../../source/ref-changelog.md:320 msgid "" -"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), " -"[#2508](https://github.com/adap/flower/pull/2508))" +"TAMUNA ([#2254](https://github.com/adap/flower/pull/2254), [#2508](https://" +"github.com/adap/flower/pull/2508))" msgstr "" #: ../../source/ref-changelog.md:322 @@ -16257,125 +16770,106 @@ msgstr "" #: ../../source/ref-changelog.md:336 msgid "" -"FedBN ([#2608](https://github.com/adap/flower/pull/2608), " -"[#2615](https://github.com/adap/flower/pull/2615))" +"FedBN ([#2608](https://github.com/adap/flower/pull/2608), [#2615](https://" +"github.com/adap/flower/pull/2615))" msgstr "" #: ../../source/ref-changelog.md:338 msgid "" -"**General updates to Flower Examples** " -"([#2384](https://github.com/adap/flower/pull/2384), " -"[#2425](https://github.com/adap/flower/pull/2425), " -"[#2526](https://github.com/adap/flower/pull/2526), " -"[#2302](https://github.com/adap/flower/pull/2302), " -"[#2545](https://github.com/adap/flower/pull/2545))" +"**General updates to Flower Examples** ([#2384](https://github.com/adap/" +"flower/pull/2384), [#2425](https://github.com/adap/flower/pull/2425), [#2526]" +"(https://github.com/adap/flower/pull/2526), [#2302](https://github.com/adap/" +"flower/pull/2302), [#2545](https://github.com/adap/flower/pull/2545))" msgstr "" #: ../../source/ref-changelog.md:340 msgid "" -"**General updates to Flower Baselines** " -"([#2301](https://github.com/adap/flower/pull/2301), " -"[#2305](https://github.com/adap/flower/pull/2305), " -"[#2307](https://github.com/adap/flower/pull/2307), " -"[#2327](https://github.com/adap/flower/pull/2327), " -"[#2435](https://github.com/adap/flower/pull/2435), " -"[#2462](https://github.com/adap/flower/pull/2462), " -"[#2463](https://github.com/adap/flower/pull/2463), " -"[#2461](https://github.com/adap/flower/pull/2461), " -"[#2469](https://github.com/adap/flower/pull/2469), " -"[#2466](https://github.com/adap/flower/pull/2466), " -"[#2471](https://github.com/adap/flower/pull/2471), " -"[#2472](https://github.com/adap/flower/pull/2472), " -"[#2470](https://github.com/adap/flower/pull/2470))" +"**General updates to Flower Baselines** ([#2301](https://github.com/adap/" +"flower/pull/2301), [#2305](https://github.com/adap/flower/pull/2305), [#2307]" +"(https://github.com/adap/flower/pull/2307), [#2327](https://github.com/adap/" +"flower/pull/2327), [#2435](https://github.com/adap/flower/pull/2435), [#2462]" +"(https://github.com/adap/flower/pull/2462), [#2463](https://github.com/adap/" +"flower/pull/2463), [#2461](https://github.com/adap/flower/pull/2461), [#2469]" +"(https://github.com/adap/flower/pull/2469), [#2466](https://github.com/adap/" +"flower/pull/2466), [#2471](https://github.com/adap/flower/pull/2471), [#2472]" +"(https://github.com/adap/flower/pull/2472), [#2470](https://github.com/adap/" +"flower/pull/2470))" msgstr "" #: ../../source/ref-changelog.md:342 msgid "" -"**General updates to the simulation engine** " -"([#2331](https://github.com/adap/flower/pull/2331), " -"[#2447](https://github.com/adap/flower/pull/2447), " -"[#2448](https://github.com/adap/flower/pull/2448), " -"[#2294](https://github.com/adap/flower/pull/2294))" +"**General updates to the simulation engine** ([#2331](https://github.com/" +"adap/flower/pull/2331), [#2447](https://github.com/adap/flower/pull/2447), " +"[#2448](https://github.com/adap/flower/pull/2448), [#2294](https://github." +"com/adap/flower/pull/2294))" msgstr "" #: ../../source/ref-changelog.md:344 msgid "" -"**General updates to Flower SDKs** " -"([#2288](https://github.com/adap/flower/pull/2288), " -"[#2429](https://github.com/adap/flower/pull/2429), " -"[#2555](https://github.com/adap/flower/pull/2555), " -"[#2543](https://github.com/adap/flower/pull/2543), " -"[#2544](https://github.com/adap/flower/pull/2544), " -"[#2597](https://github.com/adap/flower/pull/2597), " -"[#2623](https://github.com/adap/flower/pull/2623))" +"**General updates to Flower SDKs** ([#2288](https://github.com/adap/flower/" +"pull/2288), [#2429](https://github.com/adap/flower/pull/2429), [#2555]" +"(https://github.com/adap/flower/pull/2555), [#2543](https://github.com/adap/" +"flower/pull/2543), [#2544](https://github.com/adap/flower/pull/2544), [#2597]" +"(https://github.com/adap/flower/pull/2597), [#2623](https://github.com/adap/" +"flower/pull/2623))" msgstr "" #: ../../source/ref-changelog.md:346 msgid "" -"**General improvements** " -"([#2309](https://github.com/adap/flower/pull/2309), " -"[#2310](https://github.com/adap/flower/pull/2310), " -"[#2313](https://github.com/adap/flower/pull/2313), " -"[#2316](https://github.com/adap/flower/pull/2316), " -"[#2317](https://github.com/adap/flower/pull/2317), " -"[#2349](https://github.com/adap/flower/pull/2349), " -"[#2360](https://github.com/adap/flower/pull/2360), " -"[#2402](https://github.com/adap/flower/pull/2402), " -"[#2446](https://github.com/adap/flower/pull/2446), " -"[#2561](https://github.com/adap/flower/pull/2561), " -"[#2273](https://github.com/adap/flower/pull/2273), " -"[#2267](https://github.com/adap/flower/pull/2267), " -"[#2274](https://github.com/adap/flower/pull/2274), " -"[#2275](https://github.com/adap/flower/pull/2275), " -"[#2432](https://github.com/adap/flower/pull/2432), " -"[#2251](https://github.com/adap/flower/pull/2251), " -"[#2321](https://github.com/adap/flower/pull/2321), " -"[#1936](https://github.com/adap/flower/pull/1936), " -"[#2408](https://github.com/adap/flower/pull/2408), " -"[#2413](https://github.com/adap/flower/pull/2413), " -"[#2401](https://github.com/adap/flower/pull/2401), " -"[#2531](https://github.com/adap/flower/pull/2531), " -"[#2534](https://github.com/adap/flower/pull/2534), " -"[#2535](https://github.com/adap/flower/pull/2535), " -"[#2521](https://github.com/adap/flower/pull/2521), " -"[#2553](https://github.com/adap/flower/pull/2553), " -"[#2596](https://github.com/adap/flower/pull/2596))" +"**General improvements** ([#2309](https://github.com/adap/flower/pull/2309), " +"[#2310](https://github.com/adap/flower/pull/2310), [#2313](https://github." +"com/adap/flower/pull/2313), [#2316](https://github.com/adap/flower/" +"pull/2316), [#2317](https://github.com/adap/flower/pull/2317), [#2349]" +"(https://github.com/adap/flower/pull/2349), [#2360](https://github.com/adap/" +"flower/pull/2360), [#2402](https://github.com/adap/flower/pull/2402), [#2446]" +"(https://github.com/adap/flower/pull/2446), [#2561](https://github.com/adap/" +"flower/pull/2561), [#2273](https://github.com/adap/flower/pull/2273), [#2267]" +"(https://github.com/adap/flower/pull/2267), [#2274](https://github.com/adap/" +"flower/pull/2274), [#2275](https://github.com/adap/flower/pull/2275), [#2432]" +"(https://github.com/adap/flower/pull/2432), [#2251](https://github.com/adap/" +"flower/pull/2251), [#2321](https://github.com/adap/flower/pull/2321), [#1936]" +"(https://github.com/adap/flower/pull/1936), [#2408](https://github.com/adap/" +"flower/pull/2408), [#2413](https://github.com/adap/flower/pull/2413), [#2401]" +"(https://github.com/adap/flower/pull/2401), [#2531](https://github.com/adap/" +"flower/pull/2531), [#2534](https://github.com/adap/flower/pull/2534), [#2535]" +"(https://github.com/adap/flower/pull/2535), [#2521](https://github.com/adap/" +"flower/pull/2521), [#2553](https://github.com/adap/flower/pull/2553), [#2596]" +"(https://github.com/adap/flower/pull/2596))" msgstr "" #: ../../source/ref-changelog.md:348 ../../source/ref-changelog.md:438 #: ../../source/ref-changelog.md:502 ../../source/ref-changelog.md:556 #: ../../source/ref-changelog.md:623 -msgid "Flower received many improvements under the hood, too many to list here." +msgid "" +"Flower received many improvements under the hood, too many to list here." msgstr "" #: ../../source/ref-changelog.md:352 msgid "" -"**Remove support for Python 3.7** " -"([#2280](https://github.com/adap/flower/pull/2280), " -"[#2299](https://github.com/adap/flower/pull/2299), " -"[#2304](https://github.com/adap/flower/pull/2304), " -"[#2306](https://github.com/adap/flower/pull/2306), " -"[#2355](https://github.com/adap/flower/pull/2355), " -"[#2356](https://github.com/adap/flower/pull/2356))" +"**Remove support for Python 3.7** ([#2280](https://github.com/adap/flower/" +"pull/2280), [#2299](https://github.com/adap/flower/pull/2299), [#2304]" +"(https://github.com/adap/flower/pull/2304), [#2306](https://github.com/adap/" +"flower/pull/2306), [#2355](https://github.com/adap/flower/pull/2355), [#2356]" +"(https://github.com/adap/flower/pull/2356))" msgstr "" #: ../../source/ref-changelog.md:354 msgid "" -"Python 3.7 support was deprecated in Flower 1.5, and this release removes" -" support. Flower now requires Python 3.8." +"Python 3.7 support was deprecated in Flower 1.5, and this release removes " +"support. Flower now requires Python 3.8." msgstr "" #: ../../source/ref-changelog.md:356 msgid "" -"**Remove experimental argument** `rest` **from** `start_client` " -"([#2324](https://github.com/adap/flower/pull/2324))" +"**Remove experimental argument** `rest` **from** `start_client` ([#2324]" +"(https://github.com/adap/flower/pull/2324))" msgstr "" #: ../../source/ref-changelog.md:358 msgid "" -"The (still experimental) argument `rest` was removed from `start_client` " -"and `start_numpy_client`. Use `transport=\"rest\"` to opt into the " -"experimental REST API instead." +"The (still experimental) argument `rest` was removed from `start_client` and " +"`start_numpy_client`. Use `transport=\"rest\"` to opt into the experimental " +"REST API instead." msgstr "" #: ../../source/ref-changelog.md:360 @@ -16393,125 +16887,108 @@ msgstr "" #: ../../source/ref-changelog.md:370 msgid "" -"**Introduce new simulation engine** " -"([#1969](https://github.com/adap/flower/pull/1969), " -"[#2221](https://github.com/adap/flower/pull/2221), " -"[#2248](https://github.com/adap/flower/pull/2248))" +"**Introduce new simulation engine** ([#1969](https://github.com/adap/flower/" +"pull/1969), [#2221](https://github.com/adap/flower/pull/2221), [#2248]" +"(https://github.com/adap/flower/pull/2248))" msgstr "" #: ../../source/ref-changelog.md:372 msgid "" "The new simulation engine has been rewritten from the ground up, yet it " -"remains fully backwards compatible. It offers much improved stability and" -" memory handling, especially when working with GPUs. Simulations " -"transparently adapt to different settings to scale simulation in CPU-" -"only, CPU+GPU, multi-GPU, or multi-node multi-GPU environments." +"remains fully backwards compatible. It offers much improved stability and " +"memory handling, especially when working with GPUs. Simulations " +"transparently adapt to different settings to scale simulation in CPU-only, " +"CPU+GPU, multi-GPU, or multi-node multi-GPU environments." msgstr "" #: ../../source/ref-changelog.md:374 msgid "" -"Comprehensive documentation includes a new [how-to run " -"simulations](https://flower.ai/docs/framework/how-to-run-" -"simulations.html) guide, new [simulation-" +"Comprehensive documentation includes a new [how-to run simulations](https://" +"flower.ai/docs/framework/how-to-run-simulations.html) guide, new [simulation-" "pytorch](https://flower.ai/docs/examples/simulation-pytorch.html) and " "[simulation-tensorflow](https://flower.ai/docs/examples/simulation-" -"tensorflow.html) notebooks, and a new [YouTube tutorial " -"series](https://www.youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." +"tensorflow.html) notebooks, and a new [YouTube tutorial series](https://www." +"youtube.com/watch?v=cRebUIGB5RU&list=PLNG4feLHqCWlnj8a_E1A_n5zr2-8pafTB)." msgstr "" #: ../../source/ref-changelog.md:376 msgid "" -"**Restructure Flower Docs** " -"([#1824](https://github.com/adap/flower/pull/1824), " -"[#1865](https://github.com/adap/flower/pull/1865), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1887](https://github.com/adap/flower/pull/1887), " -"[#1919](https://github.com/adap/flower/pull/1919), " -"[#1922](https://github.com/adap/flower/pull/1922), " -"[#1920](https://github.com/adap/flower/pull/1920), " -"[#1923](https://github.com/adap/flower/pull/1923), " -"[#1924](https://github.com/adap/flower/pull/1924), " -"[#1962](https://github.com/adap/flower/pull/1962), " -"[#2006](https://github.com/adap/flower/pull/2006), " -"[#2133](https://github.com/adap/flower/pull/2133), " -"[#2203](https://github.com/adap/flower/pull/2203), " -"[#2215](https://github.com/adap/flower/pull/2215), " -"[#2122](https://github.com/adap/flower/pull/2122), " -"[#2223](https://github.com/adap/flower/pull/2223), " -"[#2219](https://github.com/adap/flower/pull/2219), " -"[#2232](https://github.com/adap/flower/pull/2232), " -"[#2233](https://github.com/adap/flower/pull/2233), " -"[#2234](https://github.com/adap/flower/pull/2234), " -"[#2235](https://github.com/adap/flower/pull/2235), " -"[#2237](https://github.com/adap/flower/pull/2237), " -"[#2238](https://github.com/adap/flower/pull/2238), " -"[#2242](https://github.com/adap/flower/pull/2242), " -"[#2231](https://github.com/adap/flower/pull/2231), " -"[#2243](https://github.com/adap/flower/pull/2243), " -"[#2227](https://github.com/adap/flower/pull/2227))" +"**Restructure Flower Docs** ([#1824](https://github.com/adap/flower/" +"pull/1824), [#1865](https://github.com/adap/flower/pull/1865), [#1884]" +"(https://github.com/adap/flower/pull/1884), [#1887](https://github.com/adap/" +"flower/pull/1887), [#1919](https://github.com/adap/flower/pull/1919), [#1922]" +"(https://github.com/adap/flower/pull/1922), [#1920](https://github.com/adap/" +"flower/pull/1920), [#1923](https://github.com/adap/flower/pull/1923), [#1924]" +"(https://github.com/adap/flower/pull/1924), [#1962](https://github.com/adap/" +"flower/pull/1962), [#2006](https://github.com/adap/flower/pull/2006), [#2133]" +"(https://github.com/adap/flower/pull/2133), [#2203](https://github.com/adap/" +"flower/pull/2203), [#2215](https://github.com/adap/flower/pull/2215), [#2122]" +"(https://github.com/adap/flower/pull/2122), [#2223](https://github.com/adap/" +"flower/pull/2223), [#2219](https://github.com/adap/flower/pull/2219), [#2232]" +"(https://github.com/adap/flower/pull/2232), [#2233](https://github.com/adap/" +"flower/pull/2233), [#2234](https://github.com/adap/flower/pull/2234), [#2235]" +"(https://github.com/adap/flower/pull/2235), [#2237](https://github.com/adap/" +"flower/pull/2237), [#2238](https://github.com/adap/flower/pull/2238), [#2242]" +"(https://github.com/adap/flower/pull/2242), [#2231](https://github.com/adap/" +"flower/pull/2231), [#2243](https://github.com/adap/flower/pull/2243), [#2227]" +"(https://github.com/adap/flower/pull/2227))" msgstr "" #: ../../source/ref-changelog.md:378 msgid "" -"Much effort went into a completely restructured Flower docs experience. " -"The documentation on [flower.ai/docs](https://flower.ai/docs) is now " -"divided into Flower Framework, Flower Baselines, Flower Android SDK, " -"Flower iOS SDK, and code example projects." +"Much effort went into a completely restructured Flower docs experience. The " +"documentation on [flower.ai/docs](https://flower.ai/docs) is now divided " +"into Flower Framework, Flower Baselines, Flower Android SDK, Flower iOS SDK, " +"and code example projects." msgstr "" #: ../../source/ref-changelog.md:380 msgid "" -"**Introduce Flower Swift SDK** " -"([#1858](https://github.com/adap/flower/pull/1858), " -"[#1897](https://github.com/adap/flower/pull/1897))" +"**Introduce Flower Swift SDK** ([#1858](https://github.com/adap/flower/" +"pull/1858), [#1897](https://github.com/adap/flower/pull/1897))" msgstr "" #: ../../source/ref-changelog.md:382 msgid "" -"This is the first preview release of the Flower Swift SDK. Flower support" -" on iOS is improving, and alongside the Swift SDK and code example, there" -" is now also an iOS quickstart tutorial." +"This is the first preview release of the Flower Swift SDK. Flower support on " +"iOS is improving, and alongside the Swift SDK and code example, there is now " +"also an iOS quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:384 msgid "" -"**Introduce Flower Android SDK** " -"([#2131](https://github.com/adap/flower/pull/2131))" +"**Introduce Flower Android SDK** ([#2131](https://github.com/adap/flower/" +"pull/2131))" msgstr "" #: ../../source/ref-changelog.md:386 msgid "" -"This is the first preview release of the Flower Kotlin SDK. Flower " -"support on Android is improving, and alongside the Kotlin SDK and code " -"example, there is now also an Android quickstart tutorial." +"This is the first preview release of the Flower Kotlin SDK. Flower support " +"on Android is improving, and alongside the Kotlin SDK and code example, " +"there is now also an Android quickstart tutorial." msgstr "" #: ../../source/ref-changelog.md:388 msgid "" -"**Introduce new end-to-end testing infrastructure** " -"([#1842](https://github.com/adap/flower/pull/1842), " -"[#2071](https://github.com/adap/flower/pull/2071), " -"[#2072](https://github.com/adap/flower/pull/2072), " -"[#2068](https://github.com/adap/flower/pull/2068), " -"[#2067](https://github.com/adap/flower/pull/2067), " -"[#2069](https://github.com/adap/flower/pull/2069), " -"[#2073](https://github.com/adap/flower/pull/2073), " -"[#2070](https://github.com/adap/flower/pull/2070), " -"[#2074](https://github.com/adap/flower/pull/2074), " -"[#2082](https://github.com/adap/flower/pull/2082), " -"[#2084](https://github.com/adap/flower/pull/2084), " -"[#2093](https://github.com/adap/flower/pull/2093), " -"[#2109](https://github.com/adap/flower/pull/2109), " -"[#2095](https://github.com/adap/flower/pull/2095), " -"[#2140](https://github.com/adap/flower/pull/2140), " -"[#2137](https://github.com/adap/flower/pull/2137), " -"[#2165](https://github.com/adap/flower/pull/2165))" +"**Introduce new end-to-end testing infrastructure** ([#1842](https://github." +"com/adap/flower/pull/1842), [#2071](https://github.com/adap/flower/" +"pull/2071), [#2072](https://github.com/adap/flower/pull/2072), [#2068]" +"(https://github.com/adap/flower/pull/2068), [#2067](https://github.com/adap/" +"flower/pull/2067), [#2069](https://github.com/adap/flower/pull/2069), [#2073]" +"(https://github.com/adap/flower/pull/2073), [#2070](https://github.com/adap/" +"flower/pull/2070), [#2074](https://github.com/adap/flower/pull/2074), [#2082]" +"(https://github.com/adap/flower/pull/2082), [#2084](https://github.com/adap/" +"flower/pull/2084), [#2093](https://github.com/adap/flower/pull/2093), [#2109]" +"(https://github.com/adap/flower/pull/2109), [#2095](https://github.com/adap/" +"flower/pull/2095), [#2140](https://github.com/adap/flower/pull/2140), [#2137]" +"(https://github.com/adap/flower/pull/2137), [#2165](https://github.com/adap/" +"flower/pull/2165))" msgstr "" #: ../../source/ref-changelog.md:390 msgid "" -"A new testing infrastructure ensures that new changes stay compatible " -"with existing framework integrations or strategies." +"A new testing infrastructure ensures that new changes stay compatible with " +"existing framework integrations or strategies." msgstr "" #: ../../source/ref-changelog.md:392 @@ -16520,124 +16997,121 @@ msgstr "" #: ../../source/ref-changelog.md:394 msgid "" -"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for" -" Python 3.7 is now deprecated and will be removed in an upcoming release." +"Since Python 3.7 reached its end of life (EOL) on 2023-06-27, support for " +"Python 3.7 is now deprecated and will be removed in an upcoming release." msgstr "" #: ../../source/ref-changelog.md:396 msgid "" -"**Add new** `FedTrimmedAvg` **strategy** " -"([#1769](https://github.com/adap/flower/pull/1769), " -"[#1853](https://github.com/adap/flower/pull/1853))" +"**Add new** `FedTrimmedAvg` **strategy** ([#1769](https://github.com/adap/" +"flower/pull/1769), [#1853](https://github.com/adap/flower/pull/1853))" msgstr "" #: ../../source/ref-changelog.md:398 msgid "" -"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, " -"2018](https://arxiv.org/abs/1803.01498)." +"The new `FedTrimmedAvg` strategy implements Trimmed Mean by [Dong Yin, 2018]" +"(https://arxiv.org/abs/1803.01498)." msgstr "" #: ../../source/ref-changelog.md:400 msgid "" -"**Introduce start_driver** " -"([#1697](https://github.com/adap/flower/pull/1697))" +"**Introduce start_driver** ([#1697](https://github.com/adap/flower/" +"pull/1697))" msgstr "" #: ../../source/ref-changelog.md:402 msgid "" -"In addition to `start_server` and using the raw Driver API, there is a " -"new `start_driver` function that allows for running `start_server` " -"scripts as a Flower driver with only a single-line code change. Check out" -" the `mt-pytorch` code example to see a working example using " -"`start_driver`." +"In addition to `start_server` and using the raw Driver API, there is a new " +"`start_driver` function that allows for running `start_server` scripts as a " +"Flower driver with only a single-line code change. Check out the `mt-" +"pytorch` code example to see a working example using `start_driver`." msgstr "" #: ../../source/ref-changelog.md:404 msgid "" -"**Add parameter aggregation to** `mt-pytorch` **code example** " -"([#1785](https://github.com/adap/flower/pull/1785))" +"**Add parameter aggregation to** `mt-pytorch` **code example** ([#1785]" +"(https://github.com/adap/flower/pull/1785))" msgstr "" #: ../../source/ref-changelog.md:406 msgid "" -"The `mt-pytorch` example shows how to aggregate parameters when writing a" -" driver script. The included `driver.py` and `server.py` have been " -"aligned to demonstrate both the low-level way and the high-level way of " -"building server-side logic." +"The `mt-pytorch` example shows how to aggregate parameters when writing a " +"driver script. The included `driver.py` and `server.py` have been aligned to " +"demonstrate both the low-level way and the high-level way of building server-" +"side logic." msgstr "" #: ../../source/ref-changelog.md:408 msgid "" -"**Migrate experimental REST API to Starlette** " -"([2171](https://github.com/adap/flower/pull/2171))" +"**Migrate experimental REST API to Starlette** ([2171](https://github.com/" +"adap/flower/pull/2171))" msgstr "" #: ../../source/ref-changelog.md:410 msgid "" -"The (experimental) REST API used to be implemented in " -"[FastAPI](https://fastapi.tiangolo.com/), but it has now been migrated to" -" use [Starlette](https://www.starlette.io/) directly." +"The (experimental) REST API used to be implemented in [FastAPI](https://" +"fastapi.tiangolo.com/), but it has now been migrated to use [Starlette]" +"(https://www.starlette.io/) directly." msgstr "" #: ../../source/ref-changelog.md:412 msgid "" -"Please note: The REST request-response API is still experimental and will" -" likely change significantly over time." +"Please note: The REST request-response API is still experimental and will " +"likely change significantly over time." msgstr "" #: ../../source/ref-changelog.md:414 msgid "" -"**Introduce experimental gRPC request-response API** " -"([#1867](https://github.com/adap/flower/pull/1867), " -"[#1901](https://github.com/adap/flower/pull/1901))" +"**Introduce experimental gRPC request-response API** ([#1867](https://github." +"com/adap/flower/pull/1867), [#1901](https://github.com/adap/flower/" +"pull/1901))" msgstr "" #: ../../source/ref-changelog.md:416 msgid "" -"In addition to the existing gRPC API (based on bidirectional streaming) " -"and the experimental REST API, there is now a new gRPC API that uses a " -"request-response model to communicate with client nodes." +"In addition to the existing gRPC API (based on bidirectional streaming) and " +"the experimental REST API, there is now a new gRPC API that uses a request-" +"response model to communicate with client nodes." msgstr "" #: ../../source/ref-changelog.md:418 msgid "" -"Please note: The gRPC request-response API is still experimental and will" -" likely change significantly over time." +"Please note: The gRPC request-response API is still experimental and will " +"likely change significantly over time." msgstr "" #: ../../source/ref-changelog.md:420 msgid "" "**Replace the experimental** `start_client(rest=True)` **with the new** " -"`start_client(transport=\"rest\")` " -"([#1880](https://github.com/adap/flower/pull/1880))" +"`start_client(transport=\"rest\")` ([#1880](https://github.com/adap/flower/" +"pull/1880))" msgstr "" #: ../../source/ref-changelog.md:422 msgid "" -"The (experimental) `start_client` argument `rest` was deprecated in " -"favour of a new argument `transport`. `start_client(transport=\"rest\")` " -"will yield the same behaviour as `start_client(rest=True)` did before. " -"All code should migrate to the new argument `transport`. The deprecated " -"argument `rest` will be removed in a future release." +"The (experimental) `start_client` argument `rest` was deprecated in favour " +"of a new argument `transport`. `start_client(transport=\"rest\")` will yield " +"the same behaviour as `start_client(rest=True)` did before. All code should " +"migrate to the new argument `transport`. The deprecated argument `rest` will " +"be removed in a future release." msgstr "" #: ../../source/ref-changelog.md:424 msgid "" -"**Add a new gRPC option** " -"([#2197](https://github.com/adap/flower/pull/2197))" +"**Add a new gRPC option** ([#2197](https://github.com/adap/flower/pull/2197))" msgstr "" #: ../../source/ref-changelog.md:426 msgid "" -"We now start a gRPC server with the `grpc.keepalive_permit_without_calls`" -" option set to 0 by default. This prevents the clients from sending " -"keepalive pings when there is no outstanding stream." +"We now start a gRPC server with the `grpc.keepalive_permit_without_calls` " +"option set to 0 by default. This prevents the clients from sending keepalive " +"pings when there is no outstanding stream." msgstr "" #: ../../source/ref-changelog.md:428 msgid "" -"**Improve example notebooks** " -"([#2005](https://github.com/adap/flower/pull/2005))" +"**Improve example notebooks** ([#2005](https://github.com/adap/flower/" +"pull/2005))" msgstr "" #: ../../source/ref-changelog.md:430 @@ -16647,36 +17121,31 @@ msgstr "" #: ../../source/ref-changelog.md:432 msgid "" "**Example updates** ([#1772](https://github.com/adap/flower/pull/1772), " -"[#1873](https://github.com/adap/flower/pull/1873), " -"[#1981](https://github.com/adap/flower/pull/1981), " -"[#1988](https://github.com/adap/flower/pull/1988), " -"[#1984](https://github.com/adap/flower/pull/1984), " -"[#1982](https://github.com/adap/flower/pull/1982), " -"[#2112](https://github.com/adap/flower/pull/2112), " -"[#2144](https://github.com/adap/flower/pull/2144), " -"[#2174](https://github.com/adap/flower/pull/2174), " -"[#2225](https://github.com/adap/flower/pull/2225), " -"[#2183](https://github.com/adap/flower/pull/2183))" +"[#1873](https://github.com/adap/flower/pull/1873), [#1981](https://github." +"com/adap/flower/pull/1981), [#1988](https://github.com/adap/flower/" +"pull/1988), [#1984](https://github.com/adap/flower/pull/1984), [#1982]" +"(https://github.com/adap/flower/pull/1982), [#2112](https://github.com/adap/" +"flower/pull/2112), [#2144](https://github.com/adap/flower/pull/2144), [#2174]" +"(https://github.com/adap/flower/pull/2174), [#2225](https://github.com/adap/" +"flower/pull/2225), [#2183](https://github.com/adap/flower/pull/2183))" msgstr "" #: ../../source/ref-changelog.md:434 msgid "" "Many examples have received significant updates, including simplified " "advanced-tensorflow and advanced-pytorch examples, improved macOS " -"compatibility of TensorFlow examples, and code examples for simulation. A" -" major upgrade is that all code examples now have a `requirements.txt` " -"(in addition to `pyproject.toml`)." +"compatibility of TensorFlow examples, and code examples for simulation. A " +"major upgrade is that all code examples now have a `requirements.txt` (in " +"addition to `pyproject.toml`)." msgstr "" #: ../../source/ref-changelog.md:436 msgid "" -"**General improvements** " -"([#1872](https://github.com/adap/flower/pull/1872), " -"[#1866](https://github.com/adap/flower/pull/1866), " -"[#1884](https://github.com/adap/flower/pull/1884), " -"[#1837](https://github.com/adap/flower/pull/1837), " -"[#1477](https://github.com/adap/flower/pull/1477), " -"[#2171](https://github.com/adap/flower/pull/2171))" +"**General improvements** ([#1872](https://github.com/adap/flower/pull/1872), " +"[#1866](https://github.com/adap/flower/pull/1866), [#1884](https://github." +"com/adap/flower/pull/1884), [#1837](https://github.com/adap/flower/" +"pull/1837), [#1477](https://github.com/adap/flower/pull/1477), [#2171]" +"(https://github.com/adap/flower/pull/2171))" msgstr "" #: ../../source/ref-changelog.md:444 @@ -16686,110 +17155,103 @@ msgstr "" #: ../../source/ref-changelog.md:450 msgid "" "`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, " -"`Iacob-Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal " -"Sarkhel`, `L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic " -"Lane`, `Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, " -"`Steve Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" +"`Chenyang Ma (Danny)`, `Daniel J. Beutel`, `Edoardo`, `Gautam Jajoo`, `Iacob-" +"Alexandru-Andrei`, `JDRanpariya`, `Jean Charle Yaacoub`, `Kunal Sarkhel`, " +"`L. Jiang`, `Lennart Behme`, `Max Kapsecker`, `Michał`, `Nic Lane`, " +"`Nikolaos Episkopos`, `Ragy`, `Saurav Maheshkar`, `Semo Yang`, `Steve " +"Laskaridis`, `Steven Hé (Sīchàng)`, `Taner Topal`" msgstr "" #: ../../source/ref-changelog.md:454 msgid "" -"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and " -"example)** ([#1694](https://github.com/adap/flower/pull/1694), " -"[#1709](https://github.com/adap/flower/pull/1709), " -"[#1715](https://github.com/adap/flower/pull/1715), " -"[#1717](https://github.com/adap/flower/pull/1717), " -"[#1763](https://github.com/adap/flower/pull/1763), " -"[#1795](https://github.com/adap/flower/pull/1795))" +"**Introduce support for XGBoost (**`FedXgbNnAvg` **strategy and example)** " +"([#1694](https://github.com/adap/flower/pull/1694), [#1709](https://github." +"com/adap/flower/pull/1709), [#1715](https://github.com/adap/flower/" +"pull/1715), [#1717](https://github.com/adap/flower/pull/1717), [#1763]" +"(https://github.com/adap/flower/pull/1763), [#1795](https://github.com/adap/" +"flower/pull/1795))" msgstr "" #: ../../source/ref-changelog.md:456 msgid "" "XGBoost is a tree-based ensemble machine learning algorithm that uses " -"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg`" -" " -"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/strategy/fedxgb_nn_avg.py)," -" and a [code example](https://github.com/adap/flower/tree/main/examples" -"/xgboost-quickstart) that demonstrates the usage of this new strategy in " -"an XGBoost project." +"gradient boosting to improve model accuracy. We added a new `FedXgbNnAvg` " +"[strategy](https://github.com/adap/flower/tree/main/src/py/flwr/server/" +"strategy/fedxgb_nn_avg.py), and a [code example](https://github.com/adap/" +"flower/tree/main/examples/xgboost-quickstart) that demonstrates the usage of " +"this new strategy in an XGBoost project." msgstr "" #: ../../source/ref-changelog.md:458 msgid "" -"**Introduce iOS SDK (preview)** " -"([#1621](https://github.com/adap/flower/pull/1621), " -"[#1764](https://github.com/adap/flower/pull/1764))" +"**Introduce iOS SDK (preview)** ([#1621](https://github.com/adap/flower/" +"pull/1621), [#1764](https://github.com/adap/flower/pull/1764))" msgstr "" #: ../../source/ref-changelog.md:460 msgid "" -"This is a major update for anyone wanting to implement Federated Learning" -" on iOS mobile devices. We now have a swift iOS SDK present under " -"[src/swift/flwr](https://github.com/adap/flower/tree/main/src/swift/flwr)" -" that will facilitate greatly the app creating process. To showcase its " -"use, the [iOS " +"This is a major update for anyone wanting to implement Federated Learning on " +"iOS mobile devices. We now have a swift iOS SDK present under [src/swift/" +"flwr](https://github.com/adap/flower/tree/main/src/swift/flwr) that will " +"facilitate greatly the app creating process. To showcase its use, the [iOS " "example](https://github.com/adap/flower/tree/main/examples/ios) has also " "been updated!" msgstr "" #: ../../source/ref-changelog.md:462 msgid "" -"**Introduce new \"What is Federated Learning?\" tutorial** " -"([#1657](https://github.com/adap/flower/pull/1657), " -"[#1721](https://github.com/adap/flower/pull/1721))" +"**Introduce new \"What is Federated Learning?\" tutorial** ([#1657](https://" +"github.com/adap/flower/pull/1657), [#1721](https://github.com/adap/flower/" +"pull/1721))" msgstr "" #: ../../source/ref-changelog.md:464 msgid "" -"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-" -"what-is-federated-learning.html) in our documentation explains the basics" -" of Fedetated Learning. It enables anyone who's unfamiliar with Federated" -" Learning to start their journey with Flower. Forward it to anyone who's " +"A new [entry-level tutorial](https://flower.ai/docs/framework/tutorial-what-" +"is-federated-learning.html) in our documentation explains the basics of " +"Fedetated Learning. It enables anyone who's unfamiliar with Federated " +"Learning to start their journey with Flower. Forward it to anyone who's " "interested in Federated Learning!" msgstr "" #: ../../source/ref-changelog.md:466 msgid "" -"**Introduce new Flower Baseline: FedProx MNIST** " -"([#1513](https://github.com/adap/flower/pull/1513), " -"[#1680](https://github.com/adap/flower/pull/1680), " -"[#1681](https://github.com/adap/flower/pull/1681), " -"[#1679](https://github.com/adap/flower/pull/1679))" +"**Introduce new Flower Baseline: FedProx MNIST** ([#1513](https://github.com/" +"adap/flower/pull/1513), [#1680](https://github.com/adap/flower/pull/1680), " +"[#1681](https://github.com/adap/flower/pull/1681), [#1679](https://github." +"com/adap/flower/pull/1679))" msgstr "" #: ../../source/ref-changelog.md:468 msgid "" -"This new baseline replicates the MNIST+CNN task from the paper [Federated" -" Optimization in Heterogeneous Networks (Li et al., " -"2018)](https://arxiv.org/abs/1812.06127). It uses the `FedProx` strategy," -" which aims at making convergence more robust in heterogeneous settings." +"This new baseline replicates the MNIST+CNN task from the paper [Federated " +"Optimization in Heterogeneous Networks (Li et al., 2018)](https://arxiv.org/" +"abs/1812.06127). It uses the `FedProx` strategy, which aims at making " +"convergence more robust in heterogeneous settings." msgstr "" #: ../../source/ref-changelog.md:470 msgid "" -"**Introduce new Flower Baseline: FedAvg FEMNIST** " -"([#1655](https://github.com/adap/flower/pull/1655))" +"**Introduce new Flower Baseline: FedAvg FEMNIST** ([#1655](https://github." +"com/adap/flower/pull/1655))" msgstr "" #: ../../source/ref-changelog.md:472 msgid "" -"This new baseline replicates an experiment evaluating the performance of " -"the FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A " -"Benchmark for Federated Settings (Caldas et al., " -"2018)](https://arxiv.org/abs/1812.01097)." +"This new baseline replicates an experiment evaluating the performance of the " +"FedAvg algorithm on the FEMNIST dataset from the paper [LEAF: A Benchmark " +"for Federated Settings (Caldas et al., 2018)](https://arxiv.org/" +"abs/1812.01097)." msgstr "" #: ../../source/ref-changelog.md:474 msgid "" -"**Introduce (experimental) REST API** " -"([#1594](https://github.com/adap/flower/pull/1594), " -"[#1690](https://github.com/adap/flower/pull/1690), " -"[#1695](https://github.com/adap/flower/pull/1695), " -"[#1712](https://github.com/adap/flower/pull/1712), " -"[#1802](https://github.com/adap/flower/pull/1802), " -"[#1770](https://github.com/adap/flower/pull/1770), " -"[#1733](https://github.com/adap/flower/pull/1733))" +"**Introduce (experimental) REST API** ([#1594](https://github.com/adap/" +"flower/pull/1594), [#1690](https://github.com/adap/flower/pull/1690), [#1695]" +"(https://github.com/adap/flower/pull/1695), [#1712](https://github.com/adap/" +"flower/pull/1712), [#1802](https://github.com/adap/flower/pull/1802), [#1770]" +"(https://github.com/adap/flower/pull/1770), [#1733](https://github.com/adap/" +"flower/pull/1733))" msgstr "" #: ../../source/ref-changelog.md:476 @@ -16807,132 +17269,112 @@ msgstr "" #: ../../source/ref-changelog.md:480 msgid "" -"**Improve the (experimental) Driver API** " -"([#1663](https://github.com/adap/flower/pull/1663), " -"[#1666](https://github.com/adap/flower/pull/1666), " -"[#1667](https://github.com/adap/flower/pull/1667), " -"[#1664](https://github.com/adap/flower/pull/1664), " -"[#1675](https://github.com/adap/flower/pull/1675), " -"[#1676](https://github.com/adap/flower/pull/1676), " -"[#1693](https://github.com/adap/flower/pull/1693), " -"[#1662](https://github.com/adap/flower/pull/1662), " -"[#1794](https://github.com/adap/flower/pull/1794))" +"**Improve the (experimental) Driver API** ([#1663](https://github.com/adap/" +"flower/pull/1663), [#1666](https://github.com/adap/flower/pull/1666), [#1667]" +"(https://github.com/adap/flower/pull/1667), [#1664](https://github.com/adap/" +"flower/pull/1664), [#1675](https://github.com/adap/flower/pull/1675), [#1676]" +"(https://github.com/adap/flower/pull/1676), [#1693](https://github.com/adap/" +"flower/pull/1693), [#1662](https://github.com/adap/flower/pull/1662), [#1794]" +"(https://github.com/adap/flower/pull/1794))" msgstr "" #: ../../source/ref-changelog.md:482 msgid "" -"The Driver API is still an experimental feature, but this release " -"introduces some major upgrades. One of the main improvements is the " -"introduction of an SQLite database to store server state on disk (instead" -" of in-memory). Another improvement is that tasks (instructions or " -"results) that have been delivered will now be deleted. This greatly " -"improves the memory efficiency of a long-running Flower server." +"The Driver API is still an experimental feature, but this release introduces " +"some major upgrades. One of the main improvements is the introduction of an " +"SQLite database to store server state on disk (instead of in-memory). " +"Another improvement is that tasks (instructions or results) that have been " +"delivered will now be deleted. This greatly improves the memory efficiency " +"of a long-running Flower server." msgstr "" #: ../../source/ref-changelog.md:484 msgid "" -"**Fix spilling issues related to Ray during simulations** " -"([#1698](https://github.com/adap/flower/pull/1698))" +"**Fix spilling issues related to Ray during simulations** ([#1698](https://" +"github.com/adap/flower/pull/1698))" msgstr "" #: ../../source/ref-changelog.md:486 msgid "" -"While running long simulations, `ray` was sometimes spilling huge amounts" -" of data that would make the training unable to continue. This is now " -"fixed! 🎉" +"While running long simulations, `ray` was sometimes spilling huge amounts of " +"data that would make the training unable to continue. This is now fixed! 🎉" msgstr "" #: ../../source/ref-changelog.md:488 msgid "" -"**Add new example using** `TabNet` **and Flower** " -"([#1725](https://github.com/adap/flower/pull/1725))" +"**Add new example using** `TabNet` **and Flower** ([#1725](https://github." +"com/adap/flower/pull/1725))" msgstr "" #: ../../source/ref-changelog.md:490 msgid "" -"TabNet is a powerful and flexible framework for training machine learning" -" models on tabular data. We now have a federated example using Flower: " -"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples" -"/quickstart-tabnet)." +"TabNet is a powerful and flexible framework for training machine learning " +"models on tabular data. We now have a federated example using Flower: " +"[quickstart-tabnet](https://github.com/adap/flower/tree/main/examples/" +"quickstart-tabnet)." msgstr "" #: ../../source/ref-changelog.md:492 msgid "" -"**Add new how-to guide for monitoring simulations** " -"([#1649](https://github.com/adap/flower/pull/1649))" +"**Add new how-to guide for monitoring simulations** ([#1649](https://github." +"com/adap/flower/pull/1649))" msgstr "" #: ../../source/ref-changelog.md:494 msgid "" -"We now have a documentation guide to help users monitor their performance" -" during simulations." +"We now have a documentation guide to help users monitor their performance " +"during simulations." msgstr "" #: ../../source/ref-changelog.md:496 msgid "" -"**Add training metrics to** `History` **object during simulations** " -"([#1696](https://github.com/adap/flower/pull/1696))" +"**Add training metrics to** `History` **object during simulations** ([#1696]" +"(https://github.com/adap/flower/pull/1696))" msgstr "" #: ../../source/ref-changelog.md:498 msgid "" -"The `fit_metrics_aggregation_fn` can be used to aggregate training " -"metrics, but previous releases did not save the results in the `History` " -"object. This is now the case!" +"The `fit_metrics_aggregation_fn` can be used to aggregate training metrics, " +"but previous releases did not save the results in the `History` object. This " +"is now the case!" msgstr "" #: ../../source/ref-changelog.md:500 msgid "" -"**General improvements** " -"([#1659](https://github.com/adap/flower/pull/1659), " -"[#1646](https://github.com/adap/flower/pull/1646), " -"[#1647](https://github.com/adap/flower/pull/1647), " -"[#1471](https://github.com/adap/flower/pull/1471), " -"[#1648](https://github.com/adap/flower/pull/1648), " -"[#1651](https://github.com/adap/flower/pull/1651), " -"[#1652](https://github.com/adap/flower/pull/1652), " -"[#1653](https://github.com/adap/flower/pull/1653), " -"[#1659](https://github.com/adap/flower/pull/1659), " -"[#1665](https://github.com/adap/flower/pull/1665), " -"[#1670](https://github.com/adap/flower/pull/1670), " -"[#1672](https://github.com/adap/flower/pull/1672), " -"[#1677](https://github.com/adap/flower/pull/1677), " -"[#1684](https://github.com/adap/flower/pull/1684), " -"[#1683](https://github.com/adap/flower/pull/1683), " -"[#1686](https://github.com/adap/flower/pull/1686), " -"[#1682](https://github.com/adap/flower/pull/1682), " -"[#1685](https://github.com/adap/flower/pull/1685), " -"[#1692](https://github.com/adap/flower/pull/1692), " -"[#1705](https://github.com/adap/flower/pull/1705), " -"[#1708](https://github.com/adap/flower/pull/1708), " -"[#1711](https://github.com/adap/flower/pull/1711), " -"[#1713](https://github.com/adap/flower/pull/1713), " -"[#1714](https://github.com/adap/flower/pull/1714), " -"[#1718](https://github.com/adap/flower/pull/1718), " -"[#1716](https://github.com/adap/flower/pull/1716), " -"[#1723](https://github.com/adap/flower/pull/1723), " -"[#1735](https://github.com/adap/flower/pull/1735), " -"[#1678](https://github.com/adap/flower/pull/1678), " -"[#1750](https://github.com/adap/flower/pull/1750), " -"[#1753](https://github.com/adap/flower/pull/1753), " -"[#1736](https://github.com/adap/flower/pull/1736), " -"[#1766](https://github.com/adap/flower/pull/1766), " -"[#1760](https://github.com/adap/flower/pull/1760), " -"[#1775](https://github.com/adap/flower/pull/1775), " -"[#1776](https://github.com/adap/flower/pull/1776), " -"[#1777](https://github.com/adap/flower/pull/1777), " -"[#1779](https://github.com/adap/flower/pull/1779), " -"[#1784](https://github.com/adap/flower/pull/1784), " -"[#1773](https://github.com/adap/flower/pull/1773), " -"[#1755](https://github.com/adap/flower/pull/1755), " -"[#1789](https://github.com/adap/flower/pull/1789), " -"[#1788](https://github.com/adap/flower/pull/1788), " -"[#1798](https://github.com/adap/flower/pull/1798), " -"[#1799](https://github.com/adap/flower/pull/1799), " -"[#1739](https://github.com/adap/flower/pull/1739), " -"[#1800](https://github.com/adap/flower/pull/1800), " -"[#1804](https://github.com/adap/flower/pull/1804), " -"[#1805](https://github.com/adap/flower/pull/1805))" +"**General improvements** ([#1659](https://github.com/adap/flower/pull/1659), " +"[#1646](https://github.com/adap/flower/pull/1646), [#1647](https://github." +"com/adap/flower/pull/1647), [#1471](https://github.com/adap/flower/" +"pull/1471), [#1648](https://github.com/adap/flower/pull/1648), [#1651]" +"(https://github.com/adap/flower/pull/1651), [#1652](https://github.com/adap/" +"flower/pull/1652), [#1653](https://github.com/adap/flower/pull/1653), [#1659]" +"(https://github.com/adap/flower/pull/1659), [#1665](https://github.com/adap/" +"flower/pull/1665), [#1670](https://github.com/adap/flower/pull/1670), [#1672]" +"(https://github.com/adap/flower/pull/1672), [#1677](https://github.com/adap/" +"flower/pull/1677), [#1684](https://github.com/adap/flower/pull/1684), [#1683]" +"(https://github.com/adap/flower/pull/1683), [#1686](https://github.com/adap/" +"flower/pull/1686), [#1682](https://github.com/adap/flower/pull/1682), [#1685]" +"(https://github.com/adap/flower/pull/1685), [#1692](https://github.com/adap/" +"flower/pull/1692), [#1705](https://github.com/adap/flower/pull/1705), [#1708]" +"(https://github.com/adap/flower/pull/1708), [#1711](https://github.com/adap/" +"flower/pull/1711), [#1713](https://github.com/adap/flower/pull/1713), [#1714]" +"(https://github.com/adap/flower/pull/1714), [#1718](https://github.com/adap/" +"flower/pull/1718), [#1716](https://github.com/adap/flower/pull/1716), [#1723]" +"(https://github.com/adap/flower/pull/1723), [#1735](https://github.com/adap/" +"flower/pull/1735), [#1678](https://github.com/adap/flower/pull/1678), [#1750]" +"(https://github.com/adap/flower/pull/1750), [#1753](https://github.com/adap/" +"flower/pull/1753), [#1736](https://github.com/adap/flower/pull/1736), [#1766]" +"(https://github.com/adap/flower/pull/1766), [#1760](https://github.com/adap/" +"flower/pull/1760), [#1775](https://github.com/adap/flower/pull/1775), [#1776]" +"(https://github.com/adap/flower/pull/1776), [#1777](https://github.com/adap/" +"flower/pull/1777), [#1779](https://github.com/adap/flower/pull/1779), [#1784]" +"(https://github.com/adap/flower/pull/1784), [#1773](https://github.com/adap/" +"flower/pull/1773), [#1755](https://github.com/adap/flower/pull/1755), [#1789]" +"(https://github.com/adap/flower/pull/1789), [#1788](https://github.com/adap/" +"flower/pull/1788), [#1798](https://github.com/adap/flower/pull/1798), [#1799]" +"(https://github.com/adap/flower/pull/1799), [#1739](https://github.com/adap/" +"flower/pull/1739), [#1800](https://github.com/adap/flower/pull/1800), [#1804]" +"(https://github.com/adap/flower/pull/1804), [#1805](https://github.com/adap/" +"flower/pull/1805))" msgstr "" #: ../../source/ref-changelog.md:508 @@ -16941,8 +17383,8 @@ msgstr "" #: ../../source/ref-changelog.md:514 msgid "" -"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, " -"`Daniel J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" +"`Adam Narozniak`, `Alexander Viala Bellander`, `Charles Beauville`, `Daniel " +"J. Beutel`, `JDRanpariya`, `Lennart Behme`, `Taner Topal`" msgstr "" #: ../../source/ref-changelog.md:518 @@ -16953,24 +17395,24 @@ msgstr "" #: ../../source/ref-changelog.md:520 msgid "" -"The (experimental) Driver API now supports a `workload_id` that can be " -"used to identify which workload a task belongs to. It also supports a new" -" `group_id` that can be used, for example, to indicate the current " -"training round. Both the `workload_id` and `group_id` enable client nodes" -" to decide whether they want to handle a task or not." +"The (experimental) Driver API now supports a `workload_id` that can be used " +"to identify which workload a task belongs to. It also supports a new " +"`group_id` that can be used, for example, to indicate the current training " +"round. Both the `workload_id` and `group_id` enable client nodes to decide " +"whether they want to handle a task or not." msgstr "" #: ../../source/ref-changelog.md:522 msgid "" -"**Make Driver API and Fleet API address configurable** " -"([#1637](https://github.com/adap/flower/pull/1637))" +"**Make Driver API and Fleet API address configurable** ([#1637](https://" +"github.com/adap/flower/pull/1637))" msgstr "" #: ../../source/ref-changelog.md:524 msgid "" -"The (experimental) long-running Flower server (Driver API and Fleet API) " -"can now configure the server address of both Driver API (via `--driver-" -"api-address`) and Fleet API (via `--fleet-api-address`) when starting:" +"The (experimental) long-running Flower server (Driver API and Fleet API) can " +"now configure the server address of both Driver API (via `--driver-api-" +"address`) and Fleet API (via `--fleet-api-address`) when starting:" msgstr "" #: ../../source/ref-changelog.md:526 @@ -16985,55 +17427,51 @@ msgstr "" #: ../../source/ref-changelog.md:530 msgid "" -"**Add new example of Federated Learning using fastai and Flower** " -"([#1598](https://github.com/adap/flower/pull/1598))" +"**Add new example of Federated Learning using fastai and Flower** ([#1598]" +"(https://github.com/adap/flower/pull/1598))" msgstr "" #: ../../source/ref-changelog.md:532 msgid "" "A new code example (`quickstart-fastai`) demonstrates federated learning " "with [fastai](https://www.fast.ai/) and Flower. You can find it here: " -"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples" -"/quickstart-fastai)." +"[quickstart-fastai](https://github.com/adap/flower/tree/main/examples/" +"quickstart-fastai)." msgstr "" #: ../../source/ref-changelog.md:534 msgid "" -"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest" -" versions of Android** " -"([#1603](https://github.com/adap/flower/pull/1603))" +"**Make Android example compatible with** `flwr >= 1.0.0` **and the latest " +"versions of Android** ([#1603](https://github.com/adap/flower/pull/1603))" msgstr "" #: ../../source/ref-changelog.md:536 msgid "" -"The Android code example has received a substantial update: the project " -"is compatible with Flower 1.0 (and later), the UI received a full " -"refresh, and the project is updated to be compatible with newer Android " -"tooling." +"The Android code example has received a substantial update: the project is " +"compatible with Flower 1.0 (and later), the UI received a full refresh, and " +"the project is updated to be compatible with newer Android tooling." msgstr "" #: ../../source/ref-changelog.md:538 msgid "" -"**Add new `FedProx` strategy** " -"([#1619](https://github.com/adap/flower/pull/1619))" +"**Add new `FedProx` strategy** ([#1619](https://github.com/adap/flower/" +"pull/1619))" msgstr "" #: ../../source/ref-changelog.md:540 msgid "" -"This " -"[strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedprox.py)" -" is almost identical to " -"[`FedAvg`](https://github.com/adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py)," -" but helps users replicate what is described in this " -"[paper](https://arxiv.org/abs/1812.06127). It essentially adds a " -"parameter called `proximal_mu` to regularize the local models with " -"respect to the global models." +"This [strategy](https://github.com/adap/flower/blob/main/src/py/flwr/server/" +"strategy/fedprox.py) is almost identical to [`FedAvg`](https://github.com/" +"adap/flower/blob/main/src/py/flwr/server/strategy/fedavg.py), but helps " +"users replicate what is described in this [paper](https://arxiv.org/" +"abs/1812.06127). It essentially adds a parameter called `proximal_mu` to " +"regularize the local models with respect to the global models." msgstr "" #: ../../source/ref-changelog.md:542 msgid "" -"**Add new metrics to telemetry events** " -"([#1640](https://github.com/adap/flower/pull/1640))" +"**Add new metrics to telemetry events** ([#1640](https://github.com/adap/" +"flower/pull/1640))" msgstr "" #: ../../source/ref-changelog.md:544 @@ -17044,87 +17482,73 @@ msgstr "" #: ../../source/ref-changelog.md:546 msgid "" -"**Add new custom strategy tutorial section** " -"[#1623](https://github.com/adap/flower/pull/1623)" +"**Add new custom strategy tutorial section** [#1623](https://github.com/adap/" +"flower/pull/1623)" msgstr "" #: ../../source/ref-changelog.md:548 msgid "" -"The Flower tutorial now has a new section that covers implementing a " -"custom strategy from scratch: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-build-a-strategy-from-scratch-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers implementing a custom " +"strategy from scratch: [Open in Colab](https://colab.research.google.com/" +"github/adap/flower/blob/main/doc/source/tutorial-build-a-strategy-from-" +"scratch-pytorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:550 msgid "" -"**Add new custom serialization tutorial section** " -"([#1622](https://github.com/adap/flower/pull/1622))" +"**Add new custom serialization tutorial section** ([#1622](https://github." +"com/adap/flower/pull/1622))" msgstr "" #: ../../source/ref-changelog.md:552 msgid "" -"The Flower tutorial now has a new section that covers custom " -"serialization: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/doc/source" -"/tutorial-customize-the-client-pytorch.ipynb)" +"The Flower tutorial now has a new section that covers custom serialization: " +"[Open in Colab](https://colab.research.google.com/github/adap/flower/blob/" +"main/doc/source/tutorial-customize-the-client-pytorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:554 msgid "" -"**General improvements** " -"([#1638](https://github.com/adap/flower/pull/1638), " -"[#1634](https://github.com/adap/flower/pull/1634), " -"[#1636](https://github.com/adap/flower/pull/1636), " -"[#1635](https://github.com/adap/flower/pull/1635), " -"[#1633](https://github.com/adap/flower/pull/1633), " -"[#1632](https://github.com/adap/flower/pull/1632), " -"[#1631](https://github.com/adap/flower/pull/1631), " -"[#1630](https://github.com/adap/flower/pull/1630), " -"[#1627](https://github.com/adap/flower/pull/1627), " -"[#1593](https://github.com/adap/flower/pull/1593), " -"[#1616](https://github.com/adap/flower/pull/1616), " -"[#1615](https://github.com/adap/flower/pull/1615), " -"[#1607](https://github.com/adap/flower/pull/1607), " -"[#1609](https://github.com/adap/flower/pull/1609), " -"[#1608](https://github.com/adap/flower/pull/1608), " -"[#1603](https://github.com/adap/flower/pull/1603), " -"[#1590](https://github.com/adap/flower/pull/1590), " -"[#1580](https://github.com/adap/flower/pull/1580), " -"[#1599](https://github.com/adap/flower/pull/1599), " -"[#1600](https://github.com/adap/flower/pull/1600), " -"[#1601](https://github.com/adap/flower/pull/1601), " -"[#1597](https://github.com/adap/flower/pull/1597), " -"[#1595](https://github.com/adap/flower/pull/1595), " -"[#1591](https://github.com/adap/flower/pull/1591), " -"[#1588](https://github.com/adap/flower/pull/1588), " -"[#1589](https://github.com/adap/flower/pull/1589), " -"[#1587](https://github.com/adap/flower/pull/1587), " -"[#1573](https://github.com/adap/flower/pull/1573), " -"[#1581](https://github.com/adap/flower/pull/1581), " -"[#1578](https://github.com/adap/flower/pull/1578), " -"[#1574](https://github.com/adap/flower/pull/1574), " -"[#1572](https://github.com/adap/flower/pull/1572), " -"[#1586](https://github.com/adap/flower/pull/1586))" +"**General improvements** ([#1638](https://github.com/adap/flower/pull/1638), " +"[#1634](https://github.com/adap/flower/pull/1634), [#1636](https://github." +"com/adap/flower/pull/1636), [#1635](https://github.com/adap/flower/" +"pull/1635), [#1633](https://github.com/adap/flower/pull/1633), [#1632]" +"(https://github.com/adap/flower/pull/1632), [#1631](https://github.com/adap/" +"flower/pull/1631), [#1630](https://github.com/adap/flower/pull/1630), [#1627]" +"(https://github.com/adap/flower/pull/1627), [#1593](https://github.com/adap/" +"flower/pull/1593), [#1616](https://github.com/adap/flower/pull/1616), [#1615]" +"(https://github.com/adap/flower/pull/1615), [#1607](https://github.com/adap/" +"flower/pull/1607), [#1609](https://github.com/adap/flower/pull/1609), [#1608]" +"(https://github.com/adap/flower/pull/1608), [#1603](https://github.com/adap/" +"flower/pull/1603), [#1590](https://github.com/adap/flower/pull/1590), [#1580]" +"(https://github.com/adap/flower/pull/1580), [#1599](https://github.com/adap/" +"flower/pull/1599), [#1600](https://github.com/adap/flower/pull/1600), [#1601]" +"(https://github.com/adap/flower/pull/1601), [#1597](https://github.com/adap/" +"flower/pull/1597), [#1595](https://github.com/adap/flower/pull/1595), [#1591]" +"(https://github.com/adap/flower/pull/1591), [#1588](https://github.com/adap/" +"flower/pull/1588), [#1589](https://github.com/adap/flower/pull/1589), [#1587]" +"(https://github.com/adap/flower/pull/1587), [#1573](https://github.com/adap/" +"flower/pull/1573), [#1581](https://github.com/adap/flower/pull/1581), [#1578]" +"(https://github.com/adap/flower/pull/1578), [#1574](https://github.com/adap/" +"flower/pull/1574), [#1572](https://github.com/adap/flower/pull/1572), [#1586]" +"(https://github.com/adap/flower/pull/1586))" msgstr "" #: ../../source/ref-changelog.md:558 msgid "" -"**Updated documentation** " -"([#1629](https://github.com/adap/flower/pull/1629), " -"[#1628](https://github.com/adap/flower/pull/1628), " -"[#1620](https://github.com/adap/flower/pull/1620), " -"[#1618](https://github.com/adap/flower/pull/1618), " -"[#1617](https://github.com/adap/flower/pull/1617), " -"[#1613](https://github.com/adap/flower/pull/1613), " -"[#1614](https://github.com/adap/flower/pull/1614))" +"**Updated documentation** ([#1629](https://github.com/adap/flower/" +"pull/1629), [#1628](https://github.com/adap/flower/pull/1628), [#1620]" +"(https://github.com/adap/flower/pull/1620), [#1618](https://github.com/adap/" +"flower/pull/1618), [#1617](https://github.com/adap/flower/pull/1617), [#1613]" +"(https://github.com/adap/flower/pull/1613), [#1614](https://github.com/adap/" +"flower/pull/1614))" msgstr "" #: ../../source/ref-changelog.md:560 ../../source/ref-changelog.md:627 msgid "" -"As usual, the documentation has improved quite a bit. It is another step " -"in our effort to make the Flower documentation the best documentation of " -"any project. Stay tuned and as always, feel free to provide feedback!" +"As usual, the documentation has improved quite a bit. It is another step in " +"our effort to make the Flower documentation the best documentation of any " +"project. Stay tuned and as always, feel free to provide feedback!" msgstr "" #: ../../source/ref-changelog.md:566 @@ -17133,15 +17557,14 @@ msgstr "" #: ../../source/ref-changelog.md:572 msgid "" -"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L." -" Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" +"`Adam Narozniak`, `Charles Beauville`, `Daniel J. Beutel`, `Edoardo`, `L. " +"Jiang`, `Ragy`, `Taner Topal`, `dannymcy`" msgstr "" #: ../../source/ref-changelog.md:576 msgid "" -"**Introduce new Flower Baseline: FedAvg MNIST** " -"([#1497](https://github.com/adap/flower/pull/1497), " -"[#1552](https://github.com/adap/flower/pull/1552))" +"**Introduce new Flower Baseline: FedAvg MNIST** ([#1497](https://github.com/" +"adap/flower/pull/1497), [#1552](https://github.com/adap/flower/pull/1552))" msgstr "" #: ../../source/ref-changelog.md:578 @@ -17150,207 +17573,195 @@ msgid "" "implementations useful especially to FL newcomers. They will typically " "revisit well known papers from the literature, and be suitable for " "integration in your own application or for experimentation, in order to " -"deepen your knowledge of FL in general. Today's release is the first in " -"this series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-" -"pack-fedavg-mnist-cnn/)" +"deepen your knowledge of FL in general. Today's release is the first in this " +"series. [Read more.](https://flower.ai/blog/2023-01-12-fl-starter-pack-" +"fedavg-mnist-cnn/)" msgstr "" #: ../../source/ref-changelog.md:580 msgid "" -"**Improve GPU support in simulations** " -"([#1555](https://github.com/adap/flower/pull/1555))" +"**Improve GPU support in simulations** ([#1555](https://github.com/adap/" +"flower/pull/1555))" msgstr "" #: ../../source/ref-changelog.md:582 msgid "" -"The Ray-based Virtual Client Engine (`start_simulation`) has been updated" -" to improve GPU support. The update includes some of the hard-earned " -"lessons from scaling simulations in GPU cluster environments. New " -"defaults make running GPU-based simulations substantially more robust." +"The Ray-based Virtual Client Engine (`start_simulation`) has been updated to " +"improve GPU support. The update includes some of the hard-earned lessons " +"from scaling simulations in GPU cluster environments. New defaults make " +"running GPU-based simulations substantially more robust." msgstr "" #: ../../source/ref-changelog.md:584 msgid "" -"**Improve GPU support in Jupyter Notebook tutorials** " -"([#1527](https://github.com/adap/flower/pull/1527), " -"[#1558](https://github.com/adap/flower/pull/1558))" +"**Improve GPU support in Jupyter Notebook tutorials** ([#1527](https://" +"github.com/adap/flower/pull/1527), [#1558](https://github.com/adap/flower/" +"pull/1558))" msgstr "" #: ../../source/ref-changelog.md:586 msgid "" -"Some users reported that Jupyter Notebooks have not always been easy to " -"use on GPU instances. We listened and made improvements to all of our " -"Jupyter notebooks! Check out the updated notebooks here:" +"Some users reported that Jupyter Notebooks have not always been easy to use " +"on GPU instances. We listened and made improvements to all of our Jupyter " +"notebooks! Check out the updated notebooks here:" msgstr "" #: ../../source/ref-changelog.md:588 msgid "" -"[An Introduction to Federated Learning](https://flower.ai/docs/framework" -"/tutorial-get-started-with-flower-pytorch.html)" +"[An Introduction to Federated Learning](https://flower.ai/docs/framework/" +"tutorial-get-started-with-flower-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:589 msgid "" -"[Strategies in Federated Learning](https://flower.ai/docs/framework" -"/tutorial-use-a-federated-learning-strategy-pytorch.html)" +"[Strategies in Federated Learning](https://flower.ai/docs/framework/tutorial-" +"use-a-federated-learning-strategy-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:590 msgid "" -"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a" -"-strategy-from-scratch-pytorch.html)" +"[Building a Strategy](https://flower.ai/docs/framework/tutorial-build-a-" +"strategy-from-scratch-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:591 msgid "" -"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-" -"customize-the-client-pytorch.html)" +"[Client and NumPyClient](https://flower.ai/docs/framework/tutorial-customize-" +"the-client-pytorch.html)" msgstr "" #: ../../source/ref-changelog.md:593 msgid "" -"**Introduce optional telemetry** " -"([#1533](https://github.com/adap/flower/pull/1533), " -"[#1544](https://github.com/adap/flower/pull/1544), " -"[#1584](https://github.com/adap/flower/pull/1584))" +"**Introduce optional telemetry** ([#1533](https://github.com/adap/flower/" +"pull/1533), [#1544](https://github.com/adap/flower/pull/1544), [#1584]" +"(https://github.com/adap/flower/pull/1584))" msgstr "" #: ../../source/ref-changelog.md:595 msgid "" -"After a [request for " -"feedback](https://github.com/adap/flower/issues/1534) from the community," -" the Flower open-source project introduces optional collection of " -"*anonymous* usage metrics to make well-informed decisions to improve " -"Flower. Doing this enables the Flower team to understand how Flower is " -"used and what challenges users might face." +"After a [request for feedback](https://github.com/adap/flower/issues/1534) " +"from the community, the Flower open-source project introduces optional " +"collection of *anonymous* usage metrics to make well-informed decisions to " +"improve Flower. Doing this enables the Flower team to understand how Flower " +"is used and what challenges users might face." msgstr "" #: ../../source/ref-changelog.md:597 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users who do not want to share anonymous usage metrics. " -"[Read more.](https://flower.ai/docs/telemetry.html)." +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users who do not want to share anonymous usage metrics. [Read more.]" +"(https://flower.ai/docs/telemetry.html)." msgstr "" #: ../../source/ref-changelog.md:599 msgid "" -"**Introduce (experimental) Driver API** " -"([#1520](https://github.com/adap/flower/pull/1520), " -"[#1525](https://github.com/adap/flower/pull/1525), " -"[#1545](https://github.com/adap/flower/pull/1545), " -"[#1546](https://github.com/adap/flower/pull/1546), " -"[#1550](https://github.com/adap/flower/pull/1550), " -"[#1551](https://github.com/adap/flower/pull/1551), " -"[#1567](https://github.com/adap/flower/pull/1567))" +"**Introduce (experimental) Driver API** ([#1520](https://github.com/adap/" +"flower/pull/1520), [#1525](https://github.com/adap/flower/pull/1525), [#1545]" +"(https://github.com/adap/flower/pull/1545), [#1546](https://github.com/adap/" +"flower/pull/1546), [#1550](https://github.com/adap/flower/pull/1550), [#1551]" +"(https://github.com/adap/flower/pull/1551), [#1567](https://github.com/adap/" +"flower/pull/1567))" msgstr "" #: ../../source/ref-changelog.md:601 msgid "" "Flower now has a new (experimental) Driver API which will enable fully " "programmable, async, and multi-tenant Federated Learning and Federated " -"Analytics applications. Phew, that's a lot! Going forward, the Driver API" -" will be the abstraction that many upcoming features will be built on - " -"and you can start building those things now, too." +"Analytics applications. Phew, that's a lot! Going forward, the Driver API " +"will be the abstraction that many upcoming features will be built on - and " +"you can start building those things now, too." msgstr "" #: ../../source/ref-changelog.md:603 msgid "" -"The Driver API also enables a new execution mode in which the server runs" -" indefinitely. Multiple individual workloads can run concurrently and " -"start and stop their execution independent of the server. This is " -"especially useful for users who want to deploy Flower in production." +"The Driver API also enables a new execution mode in which the server runs " +"indefinitely. Multiple individual workloads can run concurrently and start " +"and stop their execution independent of the server. This is especially " +"useful for users who want to deploy Flower in production." msgstr "" #: ../../source/ref-changelog.md:605 msgid "" -"To learn more, check out the `mt-pytorch` code example. We look forward " -"to you feedback!" +"To learn more, check out the `mt-pytorch` code example. We look forward to " +"you feedback!" msgstr "" #: ../../source/ref-changelog.md:607 msgid "" -"Please note: *The Driver API is still experimental and will likely change" -" significantly over time.*" +"Please note: *The Driver API is still experimental and will likely change " +"significantly over time.*" msgstr "" #: ../../source/ref-changelog.md:609 msgid "" -"**Add new Federated Analytics with Pandas example** " -"([#1469](https://github.com/adap/flower/pull/1469), " -"[#1535](https://github.com/adap/flower/pull/1535))" +"**Add new Federated Analytics with Pandas example** ([#1469](https://github." +"com/adap/flower/pull/1469), [#1535](https://github.com/adap/flower/" +"pull/1535))" msgstr "" #: ../../source/ref-changelog.md:611 msgid "" -"A new code example (`quickstart-pandas`) demonstrates federated analytics" -" with Pandas and Flower. You can find it here: [quickstart-" -"pandas](https://github.com/adap/flower/tree/main/examples/quickstart-" -"pandas)." +"A new code example (`quickstart-pandas`) demonstrates federated analytics " +"with Pandas and Flower. You can find it here: [quickstart-pandas](https://" +"github.com/adap/flower/tree/main/examples/quickstart-pandas)." msgstr "" #: ../../source/ref-changelog.md:613 msgid "" -"**Add new strategies: Krum and MultiKrum** " -"([#1481](https://github.com/adap/flower/pull/1481))" +"**Add new strategies: Krum and MultiKrum** ([#1481](https://github.com/adap/" +"flower/pull/1481))" msgstr "" #: ../../source/ref-changelog.md:615 msgid "" "Edoardo, a computer science student at the Sapienza University of Rome, " -"contributed a new `Krum` strategy that enables users to easily use Krum " -"and MultiKrum in their workloads." +"contributed a new `Krum` strategy that enables users to easily use Krum and " +"MultiKrum in their workloads." msgstr "" #: ../../source/ref-changelog.md:617 msgid "" -"**Update C++ example to be compatible with Flower v1.2.0** " -"([#1495](https://github.com/adap/flower/pull/1495))" +"**Update C++ example to be compatible with Flower v1.2.0** ([#1495](https://" +"github.com/adap/flower/pull/1495))" msgstr "" #: ../../source/ref-changelog.md:619 msgid "" -"The C++ code example has received a substantial update to make it " -"compatible with the latest version of Flower." +"The C++ code example has received a substantial update to make it compatible " +"with the latest version of Flower." msgstr "" #: ../../source/ref-changelog.md:621 msgid "" -"**General improvements** " -"([#1491](https://github.com/adap/flower/pull/1491), " -"[#1504](https://github.com/adap/flower/pull/1504), " -"[#1506](https://github.com/adap/flower/pull/1506), " -"[#1514](https://github.com/adap/flower/pull/1514), " -"[#1522](https://github.com/adap/flower/pull/1522), " -"[#1523](https://github.com/adap/flower/pull/1523), " -"[#1526](https://github.com/adap/flower/pull/1526), " -"[#1528](https://github.com/adap/flower/pull/1528), " -"[#1547](https://github.com/adap/flower/pull/1547), " -"[#1549](https://github.com/adap/flower/pull/1549), " -"[#1560](https://github.com/adap/flower/pull/1560), " -"[#1564](https://github.com/adap/flower/pull/1564), " -"[#1566](https://github.com/adap/flower/pull/1566))" +"**General improvements** ([#1491](https://github.com/adap/flower/pull/1491), " +"[#1504](https://github.com/adap/flower/pull/1504), [#1506](https://github." +"com/adap/flower/pull/1506), [#1514](https://github.com/adap/flower/" +"pull/1514), [#1522](https://github.com/adap/flower/pull/1522), [#1523]" +"(https://github.com/adap/flower/pull/1523), [#1526](https://github.com/adap/" +"flower/pull/1526), [#1528](https://github.com/adap/flower/pull/1528), [#1547]" +"(https://github.com/adap/flower/pull/1547), [#1549](https://github.com/adap/" +"flower/pull/1549), [#1560](https://github.com/adap/flower/pull/1560), [#1564]" +"(https://github.com/adap/flower/pull/1564), [#1566](https://github.com/adap/" +"flower/pull/1566))" msgstr "" #: ../../source/ref-changelog.md:625 msgid "" -"**Updated documentation** " -"([#1494](https://github.com/adap/flower/pull/1494), " -"[#1496](https://github.com/adap/flower/pull/1496), " -"[#1500](https://github.com/adap/flower/pull/1500), " -"[#1503](https://github.com/adap/flower/pull/1503), " -"[#1505](https://github.com/adap/flower/pull/1505), " -"[#1524](https://github.com/adap/flower/pull/1524), " -"[#1518](https://github.com/adap/flower/pull/1518), " -"[#1519](https://github.com/adap/flower/pull/1519), " -"[#1515](https://github.com/adap/flower/pull/1515))" +"**Updated documentation** ([#1494](https://github.com/adap/flower/" +"pull/1494), [#1496](https://github.com/adap/flower/pull/1496), [#1500]" +"(https://github.com/adap/flower/pull/1500), [#1503](https://github.com/adap/" +"flower/pull/1503), [#1505](https://github.com/adap/flower/pull/1505), [#1524]" +"(https://github.com/adap/flower/pull/1524), [#1518](https://github.com/adap/" +"flower/pull/1518), [#1519](https://github.com/adap/flower/pull/1519), [#1515]" +"(https://github.com/adap/flower/pull/1515))" msgstr "" #: ../../source/ref-changelog.md:629 msgid "" -"One highlight is the new [first time contributor " -"guide](https://flower.ai/docs/first-time-contributors.html): if you've " -"never contributed on GitHub before, this is the perfect place to start!" +"One highlight is the new [first time contributor guide](https://flower.ai/" +"docs/first-time-contributors.html): if you've never contributed on GitHub " +"before, this is the perfect place to start!" msgstr "" #: ../../source/ref-changelog.md:635 @@ -17367,110 +17778,106 @@ msgstr "" msgid "" "`Akis Linardos`, `Christopher S`, `Daniel J. Beutel`, `George`, `Jan " "Schlicht`, `Mohammad Fares`, `Pedro Porto Buarque de Gusmão`, `Philipp " -"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, " -"`danielnugraha`, `edogab33`" +"Wiesner`, `Rob Luke`, `Taner Topal`, `VasundharaAgarwal`, `danielnugraha`, " +"`edogab33`" msgstr "" #: ../../source/ref-changelog.md:645 msgid "" -"**Introduce Differential Privacy wrappers (preview)** " -"([#1357](https://github.com/adap/flower/pull/1357), " -"[#1460](https://github.com/adap/flower/pull/1460))" +"**Introduce Differential Privacy wrappers (preview)** ([#1357](https://" +"github.com/adap/flower/pull/1357), [#1460](https://github.com/adap/flower/" +"pull/1460))" msgstr "" #: ../../source/ref-changelog.md:647 msgid "" -"The first (experimental) preview of pluggable Differential Privacy " -"wrappers enables easy configuration and usage of differential privacy " -"(DP). The pluggable DP wrappers enable framework-agnostic **and** " -"strategy-agnostic usage of both client-side DP and server-side DP. Head " -"over to the Flower docs, a new explainer goes into more detail." +"The first (experimental) preview of pluggable Differential Privacy wrappers " +"enables easy configuration and usage of differential privacy (DP). The " +"pluggable DP wrappers enable framework-agnostic **and** strategy-agnostic " +"usage of both client-side DP and server-side DP. Head over to the Flower " +"docs, a new explainer goes into more detail." msgstr "" #: ../../source/ref-changelog.md:649 msgid "" -"**New iOS CoreML code example** " -"([#1289](https://github.com/adap/flower/pull/1289))" +"**New iOS CoreML code example** ([#1289](https://github.com/adap/flower/" +"pull/1289))" msgstr "" #: ../../source/ref-changelog.md:651 msgid "" -"Flower goes iOS! A massive new code example shows how Flower clients can " -"be built for iOS. The code example contains both Flower iOS SDK " -"components that can be used for many tasks, and one task example running " -"on CoreML." +"Flower goes iOS! A massive new code example shows how Flower clients can be " +"built for iOS. The code example contains both Flower iOS SDK components that " +"can be used for many tasks, and one task example running on CoreML." msgstr "" #: ../../source/ref-changelog.md:653 msgid "" -"**New FedMedian strategy** " -"([#1461](https://github.com/adap/flower/pull/1461))" +"**New FedMedian strategy** ([#1461](https://github.com/adap/flower/" +"pull/1461))" msgstr "" #: ../../source/ref-changelog.md:655 msgid "" -"The new `FedMedian` strategy implements Federated Median (FedMedian) by " -"[Yin et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." +"The new `FedMedian` strategy implements Federated Median (FedMedian) by [Yin " +"et al., 2018](https://arxiv.org/pdf/1803.01498v1.pdf)." msgstr "" #: ../../source/ref-changelog.md:657 msgid "" -"**Log** `Client` **exceptions in Virtual Client Engine** " -"([#1493](https://github.com/adap/flower/pull/1493))" +"**Log** `Client` **exceptions in Virtual Client Engine** ([#1493](https://" +"github.com/adap/flower/pull/1493))" msgstr "" #: ../../source/ref-changelog.md:659 msgid "" -"All `Client` exceptions happening in the VCE are now logged by default " -"and not just exposed to the configured `Strategy` (via the `failures` " -"argument)." +"All `Client` exceptions happening in the VCE are now logged by default and " +"not just exposed to the configured `Strategy` (via the `failures` argument)." msgstr "" #: ../../source/ref-changelog.md:661 msgid "" -"**Improve Virtual Client Engine internals** " -"([#1401](https://github.com/adap/flower/pull/1401), " -"[#1453](https://github.com/adap/flower/pull/1453))" +"**Improve Virtual Client Engine internals** ([#1401](https://github.com/adap/" +"flower/pull/1401), [#1453](https://github.com/adap/flower/pull/1453))" msgstr "" #: ../../source/ref-changelog.md:663 msgid "" -"Some internals of the Virtual Client Engine have been revamped. The VCE " -"now uses Ray 2.0 under the hood, the value type of the `client_resources`" -" dictionary changed to `float` to allow fractions of resources to be " +"Some internals of the Virtual Client Engine have been revamped. The VCE now " +"uses Ray 2.0 under the hood, the value type of the `client_resources` " +"dictionary changed to `float` to allow fractions of resources to be " "allocated." msgstr "" #: ../../source/ref-changelog.md:665 msgid "" -"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual " -"Client Engine**" +"**Support optional** `Client`**/**`NumPyClient` **methods in Virtual Client " +"Engine**" msgstr "" #: ../../source/ref-changelog.md:667 msgid "" -"The Virtual Client Engine now has full support for optional `Client` (and" -" `NumPyClient`) methods." +"The Virtual Client Engine now has full support for optional `Client` (and " +"`NumPyClient`) methods." msgstr "" #: ../../source/ref-changelog.md:669 msgid "" -"**Provide type information to packages using** `flwr` " -"([#1377](https://github.com/adap/flower/pull/1377))" +"**Provide type information to packages using** `flwr` ([#1377](https://" +"github.com/adap/flower/pull/1377))" msgstr "" #: ../../source/ref-changelog.md:671 msgid "" -"The package `flwr` is now bundled with a `py.typed` file indicating that " -"the package is typed. This enables typing support for projects or " -"packages that use `flwr` by enabling them to improve their code using " -"static type checkers like `mypy`." +"The package `flwr` is now bundled with a `py.typed` file indicating that the " +"package is typed. This enables typing support for projects or packages that " +"use `flwr` by enabling them to improve their code using static type checkers " +"like `mypy`." msgstr "" #: ../../source/ref-changelog.md:673 msgid "" -"**Updated code example** " -"([#1344](https://github.com/adap/flower/pull/1344), " +"**Updated code example** ([#1344](https://github.com/adap/flower/pull/1344), " "[#1347](https://github.com/adap/flower/pull/1347))" msgstr "" @@ -17482,24 +17889,18 @@ msgstr "" #: ../../source/ref-changelog.md:677 msgid "" -"**Updated documentation** " -"([#1355](https://github.com/adap/flower/pull/1355), " -"[#1558](https://github.com/adap/flower/pull/1558), " -"[#1379](https://github.com/adap/flower/pull/1379), " -"[#1380](https://github.com/adap/flower/pull/1380), " -"[#1381](https://github.com/adap/flower/pull/1381), " -"[#1332](https://github.com/adap/flower/pull/1332), " -"[#1391](https://github.com/adap/flower/pull/1391), " -"[#1403](https://github.com/adap/flower/pull/1403), " -"[#1364](https://github.com/adap/flower/pull/1364), " -"[#1409](https://github.com/adap/flower/pull/1409), " -"[#1419](https://github.com/adap/flower/pull/1419), " -"[#1444](https://github.com/adap/flower/pull/1444), " -"[#1448](https://github.com/adap/flower/pull/1448), " -"[#1417](https://github.com/adap/flower/pull/1417), " -"[#1449](https://github.com/adap/flower/pull/1449), " -"[#1465](https://github.com/adap/flower/pull/1465), " -"[#1467](https://github.com/adap/flower/pull/1467))" +"**Updated documentation** ([#1355](https://github.com/adap/flower/" +"pull/1355), [#1558](https://github.com/adap/flower/pull/1558), [#1379]" +"(https://github.com/adap/flower/pull/1379), [#1380](https://github.com/adap/" +"flower/pull/1380), [#1381](https://github.com/adap/flower/pull/1381), [#1332]" +"(https://github.com/adap/flower/pull/1332), [#1391](https://github.com/adap/" +"flower/pull/1391), [#1403](https://github.com/adap/flower/pull/1403), [#1364]" +"(https://github.com/adap/flower/pull/1364), [#1409](https://github.com/adap/" +"flower/pull/1409), [#1419](https://github.com/adap/flower/pull/1419), [#1444]" +"(https://github.com/adap/flower/pull/1444), [#1448](https://github.com/adap/" +"flower/pull/1448), [#1417](https://github.com/adap/flower/pull/1417), [#1449]" +"(https://github.com/adap/flower/pull/1449), [#1465](https://github.com/adap/" +"flower/pull/1465), [#1467](https://github.com/adap/flower/pull/1467))" msgstr "" #: ../../source/ref-changelog.md:679 @@ -17510,47 +17911,45 @@ msgstr "" #: ../../source/ref-changelog.md:681 msgid "" -"**Restructured documentation** " -"([#1387](https://github.com/adap/flower/pull/1387))" +"**Restructured documentation** ([#1387](https://github.com/adap/flower/" +"pull/1387))" msgstr "" #: ../../source/ref-changelog.md:683 msgid "" -"The documentation has been restructured to make it easier to navigate. " -"This is just the first step in a larger effort to make the Flower " -"documentation the best documentation of any project ever. Stay tuned!" +"The documentation has been restructured to make it easier to navigate. This " +"is just the first step in a larger effort to make the Flower documentation " +"the best documentation of any project ever. Stay tuned!" msgstr "" #: ../../source/ref-changelog.md:685 msgid "" -"**Open in Colab button** " -"([#1389](https://github.com/adap/flower/pull/1389))" +"**Open in Colab button** ([#1389](https://github.com/adap/flower/pull/1389))" msgstr "" #: ../../source/ref-changelog.md:687 msgid "" -"The four parts of the Flower Federated Learning Tutorial now come with a " -"new `Open in Colab` button. No need to install anything on your local " -"machine, you can now use and learn about Flower in your browser, it's " -"only a single click away." +"The four parts of the Flower Federated Learning Tutorial now come with a new " +"`Open in Colab` button. No need to install anything on your local machine, " +"you can now use and learn about Flower in your browser, it's only a single " +"click away." msgstr "" #: ../../source/ref-changelog.md:689 msgid "" -"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468)," -" [#1470](https://github.com/adap/flower/pull/1470), " -"[#1472](https://github.com/adap/flower/pull/1472), " -"[#1473](https://github.com/adap/flower/pull/1473), " -"[#1474](https://github.com/adap/flower/pull/1474), " -"[#1475](https://github.com/adap/flower/pull/1475))" +"**Improved tutorial** ([#1468](https://github.com/adap/flower/pull/1468), " +"[#1470](https://github.com/adap/flower/pull/1470), [#1472](https://github." +"com/adap/flower/pull/1472), [#1473](https://github.com/adap/flower/" +"pull/1473), [#1474](https://github.com/adap/flower/pull/1474), [#1475]" +"(https://github.com/adap/flower/pull/1475))" msgstr "" #: ../../source/ref-changelog.md:691 msgid "" "The Flower Federated Learning Tutorial has two brand-new parts covering " "custom strategies (still WIP) and the distinction between `Client` and " -"`NumPyClient`. The existing parts one and two have also been improved " -"(many small changes and fixes)." +"`NumPyClient`. The existing parts one and two have also been improved (many " +"small changes and fixes)." msgstr "" #: ../../source/ref-changelog.md:697 @@ -17575,93 +17974,79 @@ msgstr "" #: ../../source/ref-changelog.md:704 msgid "" -"Tons of small API cleanups resulting in a more coherent developer " -"experience" +"Tons of small API cleanups resulting in a more coherent developer experience" msgstr "" #: ../../source/ref-changelog.md:708 msgid "" "We would like to give our **special thanks** to all the contributors who " -"made Flower 1.0 possible (in reverse [GitHub " -"Contributors](https://github.com/adap/flower/graphs/contributors) order):" +"made Flower 1.0 possible (in reverse [GitHub Contributors](https://github." +"com/adap/flower/graphs/contributors) order):" msgstr "" #: ../../source/ref-changelog.md:710 msgid "" -"[@rtaiello](https://github.com/rtaiello), " -"[@g-pichler](https://github.com/g-pichler), [@rob-" -"luke](https://github.com/rob-luke), [@andreea-zaharia](https://github.com" -"/andreea-zaharia), [@kinshukdua](https://github.com/kinshukdua), " -"[@nfnt](https://github.com/nfnt), " -"[@tatiana-s](https://github.com/tatiana-s), " -"[@TParcollet](https://github.com/TParcollet), " -"[@vballoli](https://github.com/vballoli), " -"[@negedng](https://github.com/negedng), " -"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), " -"[@hei411](https://github.com/hei411), " -"[@SebastianSpeitel](https://github.com/SebastianSpeitel), " -"[@AmitChaulwar](https://github.com/AmitChaulwar), " -"[@Rubiel1](https://github.com/Rubiel1), [@FANTOME-PAN](https://github.com" -"/FANTOME-PAN), [@Rono-BC](https://github.com/Rono-BC), " -"[@lbhm](https://github.com/lbhm), " -"[@sishtiaq](https://github.com/sishtiaq), " -"[@remde](https://github.com/remde), [@Jueun-Park](https://github.com" -"/Jueun-Park), [@architjen](https://github.com/architjen), " -"[@PratikGarai](https://github.com/PratikGarai), " -"[@mrinaald](https://github.com/mrinaald), " -"[@zliel](https://github.com/zliel), " -"[@MeiruiJiang](https://github.com/MeiruiJiang), " -"[@sancarlim](https://github.com/sancarlim), " -"[@gubertoli](https://github.com/gubertoli), " -"[@Vingt100](https://github.com/Vingt100), " -"[@MakGulati](https://github.com/MakGulati), " -"[@cozek](https://github.com/cozek), " -"[@jafermarq](https://github.com/jafermarq), " -"[@sisco0](https://github.com/sisco0), " -"[@akhilmathurs](https://github.com/akhilmathurs), " -"[@CanTuerk](https://github.com/CanTuerk), " -"[@mariaboerner1987](https://github.com/mariaboerner1987), " -"[@pedropgusmao](https://github.com/pedropgusmao), " -"[@tanertopal](https://github.com/tanertopal), " -"[@danieljanes](https://github.com/danieljanes)." +"[@rtaiello](https://github.com/rtaiello), [@g-pichler](https://github.com/g-" +"pichler), [@rob-luke](https://github.com/rob-luke), [@andreea-zaharia]" +"(https://github.com/andreea-zaharia), [@kinshukdua](https://github.com/" +"kinshukdua), [@nfnt](https://github.com/nfnt), [@tatiana-s](https://github." +"com/tatiana-s), [@TParcollet](https://github.com/TParcollet), [@vballoli]" +"(https://github.com/vballoli), [@negedng](https://github.com/negedng), " +"[@RISHIKESHAVAN](https://github.com/RISHIKESHAVAN), [@hei411](https://github." +"com/hei411), [@SebastianSpeitel](https://github.com/SebastianSpeitel), " +"[@AmitChaulwar](https://github.com/AmitChaulwar), [@Rubiel1](https://github." +"com/Rubiel1), [@FANTOME-PAN](https://github.com/FANTOME-PAN), [@Rono-BC]" +"(https://github.com/Rono-BC), [@lbhm](https://github.com/lbhm), [@sishtiaq]" +"(https://github.com/sishtiaq), [@remde](https://github.com/remde), [@Jueun-" +"Park](https://github.com/Jueun-Park), [@architjen](https://github.com/" +"architjen), [@PratikGarai](https://github.com/PratikGarai), [@mrinaald]" +"(https://github.com/mrinaald), [@zliel](https://github.com/zliel), " +"[@MeiruiJiang](https://github.com/MeiruiJiang), [@sancarlim](https://github." +"com/sancarlim), [@gubertoli](https://github.com/gubertoli), [@Vingt100]" +"(https://github.com/Vingt100), [@MakGulati](https://github.com/MakGulati), " +"[@cozek](https://github.com/cozek), [@jafermarq](https://github.com/" +"jafermarq), [@sisco0](https://github.com/sisco0), [@akhilmathurs](https://" +"github.com/akhilmathurs), [@CanTuerk](https://github.com/CanTuerk), " +"[@mariaboerner1987](https://github.com/mariaboerner1987), [@pedropgusmao]" +"(https://github.com/pedropgusmao), [@tanertopal](https://github.com/" +"tanertopal), [@danieljanes](https://github.com/danieljanes)." msgstr "" #: ../../source/ref-changelog.md:714 msgid "" -"**All arguments must be passed as keyword arguments** " -"([#1338](https://github.com/adap/flower/pull/1338))" +"**All arguments must be passed as keyword arguments** ([#1338](https://" +"github.com/adap/flower/pull/1338))" msgstr "" #: ../../source/ref-changelog.md:716 msgid "" -"Pass all arguments as keyword arguments, positional arguments are not " -"longer supported. Code that uses positional arguments (e.g., " -"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword " -"for each positional argument (e.g., " -"`start_client(server_address=\"127.0.0.1:8080\", " -"client=FlowerClient())`)." +"Pass all arguments as keyword arguments, positional arguments are not longer " +"supported. Code that uses positional arguments (e.g., " +"`start_client(\"127.0.0.1:8080\", FlowerClient())`) must add the keyword for " +"each positional argument (e.g., " +"`start_client(server_address=\"127.0.0.1:8080\", client=FlowerClient())`)." msgstr "" #: ../../source/ref-changelog.md:718 msgid "" "**Introduce configuration object** `ServerConfig` **in** `start_server` " -"**and** `start_simulation` " -"([#1317](https://github.com/adap/flower/pull/1317))" +"**and** `start_simulation` ([#1317](https://github.com/adap/flower/" +"pull/1317))" msgstr "" #: ../../source/ref-changelog.md:720 msgid "" -"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": " -"600.0}`, `start_server` and `start_simulation` now expect a configuration" -" object of type `flwr.server.ServerConfig`. `ServerConfig` takes the same" -" arguments that as the previous config dict, but it makes writing type-" -"safe code easier and the default parameters values more transparent." +"Instead of a config dictionary `{\"num_rounds\": 3, \"round_timeout\": 600.0}" +"`, `start_server` and `start_simulation` now expect a configuration object " +"of type `flwr.server.ServerConfig`. `ServerConfig` takes the same arguments " +"that as the previous config dict, but it makes writing type-safe code easier " +"and the default parameters values more transparent." msgstr "" #: ../../source/ref-changelog.md:722 msgid "" -"**Rename built-in strategy parameters for clarity** " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Rename built-in strategy parameters for clarity** ([#1334](https://github." +"com/adap/flower/pull/1334))" msgstr "" #: ../../source/ref-changelog.md:724 @@ -17684,17 +18069,17 @@ msgstr "" #: ../../source/ref-changelog.md:730 msgid "" -"**Update default arguments of built-in strategies** " -"([#1278](https://github.com/adap/flower/pull/1278))" +"**Update default arguments of built-in strategies** ([#1278](https://github." +"com/adap/flower/pull/1278))" msgstr "" #: ../../source/ref-changelog.md:732 msgid "" "All built-in strategies now use `fraction_fit=1.0` and " -"`fraction_evaluate=1.0`, which means they select *all* currently " -"available clients for training and evaluation. Projects that relied on " -"the previous default values can get the previous behaviour by " -"initializing the strategy in the following way:" +"`fraction_evaluate=1.0`, which means they select *all* currently available " +"clients for training and evaluation. Projects that relied on the previous " +"default values can get the previous behaviour by initializing the strategy " +"in the following way:" msgstr "" #: ../../source/ref-changelog.md:734 @@ -17703,14 +18088,14 @@ msgstr "" #: ../../source/ref-changelog.md:736 msgid "" -"**Add** `server_round` **to** `Strategy.evaluate` " -"([#1334](https://github.com/adap/flower/pull/1334))" +"**Add** `server_round` **to** `Strategy.evaluate` ([#1334](https://github." +"com/adap/flower/pull/1334))" msgstr "" #: ../../source/ref-changelog.md:738 msgid "" -"The `Strategy` method `evaluate` now receives the current round of " -"federated learning/evaluation as the first parameter." +"The `Strategy` method `evaluate` now receives the current round of federated " +"learning/evaluation as the first parameter." msgstr "" #: ../../source/ref-changelog.md:740 @@ -17723,39 +18108,40 @@ msgstr "" msgid "" "The `evaluate_fn` passed to built-in strategies like `FedAvg` now takes " "three parameters: (1) The current round of federated learning/evaluation " -"(`server_round`), (2) the model parameters to evaluate (`parameters`), " -"and (3) a config dictionary (`config`)." +"(`server_round`), (2) the model parameters to evaluate (`parameters`), and " +"(3) a config dictionary (`config`)." msgstr "" #: ../../source/ref-changelog.md:744 msgid "" -"**Rename** `rnd` **to** `server_round` " -"([#1321](https://github.com/adap/flower/pull/1321))" +"**Rename** `rnd` **to** `server_round` ([#1321](https://github.com/adap/" +"flower/pull/1321))" msgstr "" #: ../../source/ref-changelog.md:746 msgid "" "Several Flower methods and functions (`evaluate_fn`, `configure_fit`, " "`aggregate_fit`, `configure_evaluate`, `aggregate_evaluate`) receive the " -"current round of federated learning/evaluation as their first parameter. " -"To improve reaability and avoid confusion with *random*, this parameter " -"has been renamed from `rnd` to `server_round`." +"current round of federated learning/evaluation as their first parameter. To " +"improve reaability and avoid confusion with *random*, this parameter has " +"been renamed from `rnd` to `server_round`." msgstr "" #: ../../source/ref-changelog.md:748 msgid "" -"**Move** `flwr.dataset` **to** `flwr_baselines` " -"([#1273](https://github.com/adap/flower/pull/1273))" +"**Move** `flwr.dataset` **to** `flwr_baselines` ([#1273](https://github.com/" +"adap/flower/pull/1273))" msgstr "" #: ../../source/ref-changelog.md:750 -msgid "The experimental package `flwr.dataset` was migrated to Flower Baselines." +msgid "" +"The experimental package `flwr.dataset` was migrated to Flower Baselines." msgstr "" #: ../../source/ref-changelog.md:752 msgid "" -"**Remove experimental strategies** " -"([#1280](https://github.com/adap/flower/pull/1280))" +"**Remove experimental strategies** ([#1280](https://github.com/adap/flower/" +"pull/1280))" msgstr "" #: ../../source/ref-changelog.md:754 @@ -17766,9 +18152,8 @@ msgstr "" #: ../../source/ref-changelog.md:756 msgid "" -"**Rename** `Weights` **to** `NDArrays` " -"([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Rename** `Weights` **to** `NDArrays` ([#1258](https://github.com/adap/" +"flower/pull/1258), [#1259](https://github.com/adap/flower/pull/1259))" msgstr "" #: ../../source/ref-changelog.md:758 @@ -17779,21 +18164,21 @@ msgstr "" #: ../../source/ref-changelog.md:760 msgid "" -"**Remove antiquated** `force_final_distributed_eval` **from** " -"`start_server` ([#1258](https://github.com/adap/flower/pull/1258), " -"[#1259](https://github.com/adap/flower/pull/1259))" +"**Remove antiquated** `force_final_distributed_eval` **from** `start_server` " +"([#1258](https://github.com/adap/flower/pull/1258), [#1259](https://github." +"com/adap/flower/pull/1259))" msgstr "" #: ../../source/ref-changelog.md:762 msgid "" -"The `start_server` parameter `force_final_distributed_eval` has long been" -" a historic artefact, in this release it is finally gone for good." +"The `start_server` parameter `force_final_distributed_eval` has long been a " +"historic artefact, in this release it is finally gone for good." msgstr "" #: ../../source/ref-changelog.md:764 msgid "" -"**Make** `get_parameters` **configurable** " -"([#1242](https://github.com/adap/flower/pull/1242))" +"**Make** `get_parameters` **configurable** ([#1242](https://github.com/adap/" +"flower/pull/1242))" msgstr "" #: ../../source/ref-changelog.md:766 @@ -17811,64 +18196,62 @@ msgstr "" #: ../../source/ref-changelog.md:770 msgid "" "The `start_simulation` function now accepts a configuration dictionary " -"`config` instead of the `num_rounds` integer. This improves the " -"consistency between `start_simulation` and `start_server` and makes " -"transitioning between the two easier." +"`config` instead of the `num_rounds` integer. This improves the consistency " +"between `start_simulation` and `start_server` and makes transitioning " +"between the two easier." msgstr "" #: ../../source/ref-changelog.md:774 msgid "" -"**Support Python 3.10** " -"([#1320](https://github.com/adap/flower/pull/1320))" +"**Support Python 3.10** ([#1320](https://github.com/adap/flower/pull/1320))" msgstr "" #: ../../source/ref-changelog.md:776 msgid "" -"The previous Flower release introduced experimental support for Python " -"3.10, this release declares Python 3.10 support as stable." +"The previous Flower release introduced experimental support for Python 3.10, " +"this release declares Python 3.10 support as stable." msgstr "" #: ../../source/ref-changelog.md:778 msgid "" -"**Make all** `Client` **and** `NumPyClient` **methods optional** " -"([#1260](https://github.com/adap/flower/pull/1260), " -"[#1277](https://github.com/adap/flower/pull/1277))" +"**Make all** `Client` **and** `NumPyClient` **methods optional** ([#1260]" +"(https://github.com/adap/flower/pull/1260), [#1277](https://github.com/adap/" +"flower/pull/1277))" msgstr "" #: ../../source/ref-changelog.md:780 msgid "" "The `Client`/`NumPyClient` methods `get_properties`, `get_parameters`, " -"`fit`, and `evaluate` are all optional. This enables writing clients that" -" implement, for example, only `fit`, but no other method. No need to " +"`fit`, and `evaluate` are all optional. This enables writing clients that " +"implement, for example, only `fit`, but no other method. No need to " "implement `evaluate` when using centralized evaluation!" msgstr "" #: ../../source/ref-changelog.md:782 msgid "" -"**Enable passing a** `Server` **instance to** `start_simulation` " -"([#1281](https://github.com/adap/flower/pull/1281))" +"**Enable passing a** `Server` **instance to** `start_simulation` ([#1281]" +"(https://github.com/adap/flower/pull/1281))" msgstr "" #: ../../source/ref-changelog.md:784 msgid "" -"Similar to `start_server`, `start_simulation` now accepts a full `Server`" -" instance. This enables users to heavily customize the execution of " -"eperiments and opens the door to running, for example, async FL using the" -" Virtual Client Engine." +"Similar to `start_server`, `start_simulation` now accepts a full `Server` " +"instance. This enables users to heavily customize the execution of " +"eperiments and opens the door to running, for example, async FL using the " +"Virtual Client Engine." msgstr "" #: ../../source/ref-changelog.md:786 msgid "" -"**Update code examples** " -"([#1291](https://github.com/adap/flower/pull/1291), " -"[#1286](https://github.com/adap/flower/pull/1286), " -"[#1282](https://github.com/adap/flower/pull/1282))" +"**Update code examples** ([#1291](https://github.com/adap/flower/pull/1291), " +"[#1286](https://github.com/adap/flower/pull/1286), [#1282](https://github." +"com/adap/flower/pull/1282))" msgstr "" #: ../../source/ref-changelog.md:788 msgid "" -"Many code examples received small or even large maintenance updates, " -"among them are" +"Many code examples received small or even large maintenance updates, among " +"them are" msgstr "" #: ../../source/ref-changelog.md:790 @@ -17897,8 +18280,8 @@ msgstr "" #: ../../source/ref-changelog.md:797 msgid "" -"**Remove the obsolete simulation example** " -"([#1328](https://github.com/adap/flower/pull/1328))" +"**Remove the obsolete simulation example** ([#1328](https://github.com/adap/" +"flower/pull/1328))" msgstr "" #: ../../source/ref-changelog.md:799 @@ -17910,27 +18293,24 @@ msgstr "" #: ../../source/ref-changelog.md:801 msgid "" -"**Update documentation** " -"([#1223](https://github.com/adap/flower/pull/1223), " -"[#1209](https://github.com/adap/flower/pull/1209), " -"[#1251](https://github.com/adap/flower/pull/1251), " -"[#1257](https://github.com/adap/flower/pull/1257), " -"[#1267](https://github.com/adap/flower/pull/1267), " -"[#1268](https://github.com/adap/flower/pull/1268), " -"[#1300](https://github.com/adap/flower/pull/1300), " -"[#1304](https://github.com/adap/flower/pull/1304), " -"[#1305](https://github.com/adap/flower/pull/1305), " -"[#1307](https://github.com/adap/flower/pull/1307))" +"**Update documentation** ([#1223](https://github.com/adap/flower/pull/1223), " +"[#1209](https://github.com/adap/flower/pull/1209), [#1251](https://github." +"com/adap/flower/pull/1251), [#1257](https://github.com/adap/flower/" +"pull/1257), [#1267](https://github.com/adap/flower/pull/1267), [#1268]" +"(https://github.com/adap/flower/pull/1268), [#1300](https://github.com/adap/" +"flower/pull/1300), [#1304](https://github.com/adap/flower/pull/1304), [#1305]" +"(https://github.com/adap/flower/pull/1305), [#1307](https://github.com/adap/" +"flower/pull/1307))" msgstr "" #: ../../source/ref-changelog.md:803 msgid "" "One substantial documentation update fixes multiple smaller rendering " "issues, makes titles more succinct to improve navigation, removes a " -"deprecated library, updates documentation dependencies, includes the " -"`flwr.common` module in the API reference, includes support for markdown-" -"based documentation, migrates the changelog from `.rst` to `.md`, and " -"fixes a number of smaller details!" +"deprecated library, updates documentation dependencies, includes the `flwr." +"common` module in the API reference, includes support for markdown-based " +"documentation, migrates the changelog from `.rst` to `.md`, and fixes a " +"number of smaller details!" msgstr "" #: ../../source/ref-changelog.md:805 ../../source/ref-changelog.md:860 @@ -17940,30 +18320,28 @@ msgstr "" #: ../../source/ref-changelog.md:807 msgid "" -"Add round number to fit and evaluate log messages " -"([#1266](https://github.com/adap/flower/pull/1266))" +"Add round number to fit and evaluate log messages ([#1266](https://github." +"com/adap/flower/pull/1266))" msgstr "" #: ../../source/ref-changelog.md:808 msgid "" -"Add secure gRPC connection to the `advanced_tensorflow` code example " -"([#847](https://github.com/adap/flower/pull/847))" +"Add secure gRPC connection to the `advanced_tensorflow` code example ([#847]" +"(https://github.com/adap/flower/pull/847))" msgstr "" #: ../../source/ref-changelog.md:809 msgid "" -"Update developer tooling " -"([#1231](https://github.com/adap/flower/pull/1231), " -"[#1276](https://github.com/adap/flower/pull/1276), " -"[#1301](https://github.com/adap/flower/pull/1301), " -"[#1310](https://github.com/adap/flower/pull/1310))" +"Update developer tooling ([#1231](https://github.com/adap/flower/pull/1231), " +"[#1276](https://github.com/adap/flower/pull/1276), [#1301](https://github." +"com/adap/flower/pull/1301), [#1310](https://github.com/adap/flower/" +"pull/1310))" msgstr "" #: ../../source/ref-changelog.md:810 msgid "" -"Rename ProtoBuf messages to improve consistency " -"([#1214](https://github.com/adap/flower/pull/1214), " -"[#1258](https://github.com/adap/flower/pull/1258), " +"Rename ProtoBuf messages to improve consistency ([#1214](https://github.com/" +"adap/flower/pull/1214), [#1258](https://github.com/adap/flower/pull/1258), " "[#1259](https://github.com/adap/flower/pull/1259))" msgstr "" @@ -17973,123 +18351,120 @@ msgstr "" #: ../../source/ref-changelog.md:816 msgid "" -"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** " -"([#919](https://github.com/adap/flower/pull/919), " -"[#1127](https://github.com/adap/flower/pull/1127), " -"[#914](https://github.com/adap/flower/pull/914))" +"**Flower Baselines (preview): FedOpt, FedBN, FedAvgM** ([#919](https://" +"github.com/adap/flower/pull/919), [#1127](https://github.com/adap/flower/" +"pull/1127), [#914](https://github.com/adap/flower/pull/914))" msgstr "" #: ../../source/ref-changelog.md:818 msgid "" "The first preview release of Flower Baselines has arrived! We're " "kickstarting Flower Baselines with implementations of FedOpt (FedYogi, " -"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how " -"to use [Flower Baselines](https://flower.ai/docs/using-baselines.html). " -"With this first preview release we're also inviting the community to " -"[contribute their own baselines](https://flower.ai/docs/baselines/how-to-" -"contribute-baselines.html)." +"FedAdam, FedAdagrad), FedBN, and FedAvgM. Check the documentation on how to " +"use [Flower Baselines](https://flower.ai/docs/using-baselines.html). With " +"this first preview release we're also inviting the community to [contribute " +"their own baselines](https://flower.ai/docs/baselines/how-to-contribute-" +"baselines.html)." msgstr "" #: ../../source/ref-changelog.md:820 msgid "" -"**C++ client SDK (preview) and code example** " -"([#1111](https://github.com/adap/flower/pull/1111))" +"**C++ client SDK (preview) and code example** ([#1111](https://github.com/" +"adap/flower/pull/1111))" msgstr "" #: ../../source/ref-changelog.md:822 msgid "" -"Preview support for Flower clients written in C++. The C++ preview " -"includes a Flower client SDK and a quickstart code example that " -"demonstrates a simple C++ client using the SDK." +"Preview support for Flower clients written in C++. The C++ preview includes " +"a Flower client SDK and a quickstart code example that demonstrates a simple " +"C++ client using the SDK." msgstr "" #: ../../source/ref-changelog.md:824 msgid "" -"**Add experimental support for Python 3.10 and Python 3.11** " -"([#1135](https://github.com/adap/flower/pull/1135))" +"**Add experimental support for Python 3.10 and Python 3.11** ([#1135]" +"(https://github.com/adap/flower/pull/1135))" msgstr "" #: ../../source/ref-changelog.md:826 msgid "" -"Python 3.10 is the latest stable release of Python and Python 3.11 is due" -" to be released in October. This Flower release adds experimental support" -" for both Python versions." +"Python 3.10 is the latest stable release of Python and Python 3.11 is due to " +"be released in October. This Flower release adds experimental support for " +"both Python versions." msgstr "" #: ../../source/ref-changelog.md:828 msgid "" -"**Aggregate custom metrics through user-provided functions** " -"([#1144](https://github.com/adap/flower/pull/1144))" +"**Aggregate custom metrics through user-provided functions** ([#1144]" +"(https://github.com/adap/flower/pull/1144))" msgstr "" #: ../../source/ref-changelog.md:830 msgid "" -"Custom metrics (e.g., `accuracy`) can now be aggregated without having to" -" customize the strategy. Built-in strategies support two new arguments, " +"Custom metrics (e.g., `accuracy`) can now be aggregated without having to " +"customize the strategy. Built-in strategies support two new arguments, " "`fit_metrics_aggregation_fn` and `evaluate_metrics_aggregation_fn`, that " "allow passing custom metric aggregation functions." msgstr "" #: ../../source/ref-changelog.md:832 msgid "" -"**User-configurable round timeout** " -"([#1162](https://github.com/adap/flower/pull/1162))" +"**User-configurable round timeout** ([#1162](https://github.com/adap/flower/" +"pull/1162))" msgstr "" #: ../../source/ref-changelog.md:834 msgid "" "A new configuration value allows the round timeout to be set for " -"`start_server` and `start_simulation`. If the `config` dictionary " -"contains a `round_timeout` key (with a `float` value in seconds), the " -"server will wait *at least* `round_timeout` seconds before it closes the " -"connection." +"`start_server` and `start_simulation`. If the `config` dictionary contains a " +"`round_timeout` key (with a `float` value in seconds), the server will wait " +"*at least* `round_timeout` seconds before it closes the connection." msgstr "" #: ../../source/ref-changelog.md:836 msgid "" -"**Enable both federated evaluation and centralized evaluation to be used " -"at the same time in all built-in strategies** " -"([#1091](https://github.com/adap/flower/pull/1091))" +"**Enable both federated evaluation and centralized evaluation to be used at " +"the same time in all built-in strategies** ([#1091](https://github.com/adap/" +"flower/pull/1091))" msgstr "" #: ../../source/ref-changelog.md:838 msgid "" -"Built-in strategies can now perform both federated evaluation (i.e., " -"client-side) and centralized evaluation (i.e., server-side) in the same " -"round. Federated evaluation can be disabled by setting `fraction_eval` to" -" `0.0`." +"Built-in strategies can now perform both federated evaluation (i.e., client-" +"side) and centralized evaluation (i.e., server-side) in the same round. " +"Federated evaluation can be disabled by setting `fraction_eval` to `0.0`." msgstr "" #: ../../source/ref-changelog.md:840 msgid "" -"**Two new Jupyter Notebook tutorials** " -"([#1141](https://github.com/adap/flower/pull/1141))" +"**Two new Jupyter Notebook tutorials** ([#1141](https://github.com/adap/" +"flower/pull/1141))" msgstr "" #: ../../source/ref-changelog.md:842 msgid "" -"Two Jupyter Notebook tutorials (compatible with Google Colab) explain " -"basic and intermediate Flower features:" +"Two Jupyter Notebook tutorials (compatible with Google Colab) explain basic " +"and intermediate Flower features:" msgstr "" #: ../../source/ref-changelog.md:844 msgid "" -"*An Introduction to Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-1" -"-Intro-to-FL-PyTorch.ipynb)" +"*An Introduction to Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-1-Intro-to-" +"FL-PyTorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:846 msgid "" -"*Using Strategies in Federated Learning*: [Open in " -"Colab](https://colab.research.google.com/github/adap/flower/blob/main/tutorials/Flower-2" -"-Strategies-in-FL-PyTorch.ipynb)" +"*Using Strategies in Federated Learning*: [Open in Colab](https://colab." +"research.google.com/github/adap/flower/blob/main/tutorials/Flower-2-" +"Strategies-in-FL-PyTorch.ipynb)" msgstr "" #: ../../source/ref-changelog.md:848 msgid "" -"**New FedAvgM strategy (Federated Averaging with Server Momentum)** " -"([#1076](https://github.com/adap/flower/pull/1076))" +"**New FedAvgM strategy (Federated Averaging with Server Momentum)** ([#1076]" +"(https://github.com/adap/flower/pull/1076))" msgstr "" #: ../../source/ref-changelog.md:850 @@ -18100,8 +18475,8 @@ msgstr "" #: ../../source/ref-changelog.md:852 msgid "" -"**New advanced PyTorch code example** " -"([#1007](https://github.com/adap/flower/pull/1007))" +"**New advanced PyTorch code example** ([#1007](https://github.com/adap/" +"flower/pull/1007))" msgstr "" #: ../../source/ref-changelog.md:854 @@ -18112,8 +18487,7 @@ msgstr "" #: ../../source/ref-changelog.md:856 msgid "" -"**New JAX code example** " -"([#906](https://github.com/adap/flower/pull/906), " +"**New JAX code example** ([#906](https://github.com/adap/flower/pull/906), " "[#1143](https://github.com/adap/flower/pull/1143))" msgstr "" @@ -18137,41 +18511,40 @@ msgstr "" #: ../../source/ref-changelog.md:864 msgid "" -"New documentation for [implementing " -"strategies](https://flower.ai/docs/framework/how-to-implement-" -"strategies.html) ([#1097](https://github.com/adap/flower/pull/1097), " -"[#1175](https://github.com/adap/flower/pull/1175))" +"New documentation for [implementing strategies](https://flower.ai/docs/" +"framework/how-to-implement-strategies.html) ([#1097](https://github.com/adap/" +"flower/pull/1097), [#1175](https://github.com/adap/flower/pull/1175))" msgstr "" #: ../../source/ref-changelog.md:865 msgid "" -"New mobile-friendly documentation theme " -"([#1174](https://github.com/adap/flower/pull/1174))" +"New mobile-friendly documentation theme ([#1174](https://github.com/adap/" +"flower/pull/1174))" msgstr "" #: ../../source/ref-changelog.md:866 msgid "" "Limit version range for (optional) `ray` dependency to include only " -"compatible releases (`>=1.9.2,<1.12.0`) " -"([#1205](https://github.com/adap/flower/pull/1205))" +"compatible releases (`>=1.9.2,<1.12.0`) ([#1205](https://github.com/adap/" +"flower/pull/1205))" msgstr "" #: ../../source/ref-changelog.md:870 msgid "" -"**Remove deprecated support for Python 3.6** " -"([#871](https://github.com/adap/flower/pull/871))" +"**Remove deprecated support for Python 3.6** ([#871](https://github.com/adap/" +"flower/pull/871))" msgstr "" #: ../../source/ref-changelog.md:871 msgid "" -"**Remove deprecated KerasClient** " -"([#857](https://github.com/adap/flower/pull/857))" +"**Remove deprecated KerasClient** ([#857](https://github.com/adap/flower/" +"pull/857))" msgstr "" #: ../../source/ref-changelog.md:872 msgid "" -"**Remove deprecated no-op extra installs** " -"([#973](https://github.com/adap/flower/pull/973))" +"**Remove deprecated no-op extra installs** ([#973](https://github.com/adap/" +"flower/pull/973))" msgstr "" #: ../../source/ref-changelog.md:873 @@ -18182,20 +18555,20 @@ msgstr "" #: ../../source/ref-changelog.md:874 msgid "" -"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** " -"([#1107](https://github.com/adap/flower/pull/1107))" +"**Remove deprecated QffedAvg strategy (replaced by QFedAvg)** ([#1107]" +"(https://github.com/adap/flower/pull/1107))" msgstr "" #: ../../source/ref-changelog.md:875 msgid "" -"**Remove deprecated DefaultStrategy strategy** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated DefaultStrategy strategy** ([#1142](https://github.com/" +"adap/flower/pull/1142))" msgstr "" #: ../../source/ref-changelog.md:876 msgid "" -"**Remove deprecated support for eval_fn accuracy return value** " -"([#1142](https://github.com/adap/flower/pull/1142))" +"**Remove deprecated support for eval_fn accuracy return value** ([#1142]" +"(https://github.com/adap/flower/pull/1142))" msgstr "" #: ../../source/ref-changelog.md:877 @@ -18211,156 +18584,152 @@ msgstr "" #: ../../source/ref-changelog.md:883 msgid "" "**Improved Virtual Client Engine compatibility with Jupyter Notebook / " -"Google Colab** ([#866](https://github.com/adap/flower/pull/866), " -"[#872](https://github.com/adap/flower/pull/872), " -"[#833](https://github.com/adap/flower/pull/833), " -"[#1036](https://github.com/adap/flower/pull/1036))" +"Google Colab** ([#866](https://github.com/adap/flower/pull/866), [#872]" +"(https://github.com/adap/flower/pull/872), [#833](https://github.com/adap/" +"flower/pull/833), [#1036](https://github.com/adap/flower/pull/1036))" msgstr "" #: ../../source/ref-changelog.md:885 msgid "" -"Simulations (using the Virtual Client Engine through `start_simulation`) " -"now work more smoothly on Jupyter Notebooks (incl. Google Colab) after " +"Simulations (using the Virtual Client Engine through `start_simulation`) now " +"work more smoothly on Jupyter Notebooks (incl. Google Colab) after " "installing Flower with the `simulation` extra (`pip install " "flwr[simulation]`)." msgstr "" #: ../../source/ref-changelog.md:887 msgid "" -"**New Jupyter Notebook code example** " -"([#833](https://github.com/adap/flower/pull/833))" +"**New Jupyter Notebook code example** ([#833](https://github.com/adap/flower/" +"pull/833))" msgstr "" #: ../../source/ref-changelog.md:889 msgid "" -"A new code example (`quickstart_simulation`) demonstrates Flower " -"simulations using the Virtual Client Engine through Jupyter Notebook " -"(incl. Google Colab)." +"A new code example (`quickstart_simulation`) demonstrates Flower simulations " +"using the Virtual Client Engine through Jupyter Notebook (incl. Google " +"Colab)." msgstr "" #: ../../source/ref-changelog.md:891 msgid "" -"**Client properties (feature preview)** " -"([#795](https://github.com/adap/flower/pull/795))" +"**Client properties (feature preview)** ([#795](https://github.com/adap/" +"flower/pull/795))" msgstr "" #: ../../source/ref-changelog.md:893 msgid "" -"Clients can implement a new method `get_properties` to enable server-side" -" strategies to query client properties." +"Clients can implement a new method `get_properties` to enable server-side " +"strategies to query client properties." msgstr "" #: ../../source/ref-changelog.md:895 msgid "" -"**Experimental Android support with TFLite** " -"([#865](https://github.com/adap/flower/pull/865))" +"**Experimental Android support with TFLite** ([#865](https://github.com/adap/" +"flower/pull/865))" msgstr "" #: ../../source/ref-changelog.md:897 msgid "" "Android support has finally arrived in `main`! Flower is both client-" "agnostic and framework-agnostic by design. One can integrate arbitrary " -"client platforms and with this release, using Flower on Android has " -"become a lot easier." +"client platforms and with this release, using Flower on Android has become a " +"lot easier." msgstr "" #: ../../source/ref-changelog.md:899 msgid "" -"The example uses TFLite on the client side, along with a new " -"`FedAvgAndroid` strategy. The Android client and `FedAvgAndroid` are " -"still experimental, but they are a first step towards a fully-fledged " -"Android SDK and a unified `FedAvg` implementation that integrated the new" -" functionality from `FedAvgAndroid`." +"The example uses TFLite on the client side, along with a new `FedAvgAndroid` " +"strategy. The Android client and `FedAvgAndroid` are still experimental, but " +"they are a first step towards a fully-fledged Android SDK and a unified " +"`FedAvg` implementation that integrated the new functionality from " +"`FedAvgAndroid`." msgstr "" #: ../../source/ref-changelog.md:901 msgid "" -"**Make gRPC keepalive time user-configurable and decrease default " -"keepalive time** ([#1069](https://github.com/adap/flower/pull/1069))" +"**Make gRPC keepalive time user-configurable and decrease default keepalive " +"time** ([#1069](https://github.com/adap/flower/pull/1069))" msgstr "" #: ../../source/ref-changelog.md:903 msgid "" "The default gRPC keepalive time has been reduced to increase the " -"compatibility of Flower with more cloud environments (for example, " -"Microsoft Azure). Users can configure the keepalive time to customize the" -" gRPC stack based on specific requirements." +"compatibility of Flower with more cloud environments (for example, Microsoft " +"Azure). Users can configure the keepalive time to customize the gRPC stack " +"based on specific requirements." msgstr "" #: ../../source/ref-changelog.md:905 msgid "" -"**New differential privacy example using Opacus and PyTorch** " -"([#805](https://github.com/adap/flower/pull/805))" +"**New differential privacy example using Opacus and PyTorch** ([#805]" +"(https://github.com/adap/flower/pull/805))" msgstr "" #: ../../source/ref-changelog.md:907 msgid "" -"A new code example (`opacus`) demonstrates differentially-private " -"federated learning with Opacus, PyTorch, and Flower." +"A new code example (`opacus`) demonstrates differentially-private federated " +"learning with Opacus, PyTorch, and Flower." msgstr "" #: ../../source/ref-changelog.md:909 msgid "" -"**New Hugging Face Transformers code example** " -"([#863](https://github.com/adap/flower/pull/863))" +"**New Hugging Face Transformers code example** ([#863](https://github.com/" +"adap/flower/pull/863))" msgstr "" #: ../../source/ref-changelog.md:911 msgid "" -"A new code example (`quickstart_huggingface`) demonstrates usage of " -"Hugging Face Transformers with Flower." +"A new code example (`quickstart_huggingface`) demonstrates usage of Hugging " +"Face Transformers with Flower." msgstr "" #: ../../source/ref-changelog.md:913 msgid "" -"**New MLCube code example** " -"([#779](https://github.com/adap/flower/pull/779), " -"[#1034](https://github.com/adap/flower/pull/1034), " -"[#1065](https://github.com/adap/flower/pull/1065), " -"[#1090](https://github.com/adap/flower/pull/1090))" +"**New MLCube code example** ([#779](https://github.com/adap/flower/" +"pull/779), [#1034](https://github.com/adap/flower/pull/1034), [#1065]" +"(https://github.com/adap/flower/pull/1065), [#1090](https://github.com/adap/" +"flower/pull/1090))" msgstr "" #: ../../source/ref-changelog.md:915 msgid "" -"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube " -"with Flower." +"A new code example (`quickstart_mlcube`) demonstrates usage of MLCube with " +"Flower." msgstr "" #: ../../source/ref-changelog.md:917 msgid "" -"**SSL-enabled server and client** " -"([#842](https://github.com/adap/flower/pull/842), " -"[#844](https://github.com/adap/flower/pull/844), " -"[#845](https://github.com/adap/flower/pull/845), " -"[#847](https://github.com/adap/flower/pull/847), " -"[#993](https://github.com/adap/flower/pull/993), " -"[#994](https://github.com/adap/flower/pull/994))" +"**SSL-enabled server and client** ([#842](https://github.com/adap/flower/" +"pull/842), [#844](https://github.com/adap/flower/pull/844), [#845](https://" +"github.com/adap/flower/pull/845), [#847](https://github.com/adap/flower/" +"pull/847), [#993](https://github.com/adap/flower/pull/993), [#994](https://" +"github.com/adap/flower/pull/994))" msgstr "" #: ../../source/ref-changelog.md:919 msgid "" -"SSL enables secure encrypted connections between clients and servers. " -"This release open-sources the Flower secure gRPC implementation to make " -"encrypted communication channels accessible to all Flower users." +"SSL enables secure encrypted connections between clients and servers. This " +"release open-sources the Flower secure gRPC implementation to make encrypted " +"communication channels accessible to all Flower users." msgstr "" #: ../../source/ref-changelog.md:921 msgid "" -"**Updated** `FedAdam` **and** `FedYogi` **strategies** " -"([#885](https://github.com/adap/flower/pull/885), " -"[#895](https://github.com/adap/flower/pull/895))" +"**Updated** `FedAdam` **and** `FedYogi` **strategies** ([#885](https://" +"github.com/adap/flower/pull/885), [#895](https://github.com/adap/flower/" +"pull/895))" msgstr "" #: ../../source/ref-changelog.md:923 msgid "" -"`FedAdam` and `FedAdam` match the latest version of the Adaptive " -"Federated Optimization paper." +"`FedAdam` and `FedAdam` match the latest version of the Adaptive Federated " +"Optimization paper." msgstr "" #: ../../source/ref-changelog.md:925 msgid "" -"**Initialize** `start_simulation` **with a list of client IDs** " -"([#860](https://github.com/adap/flower/pull/860))" +"**Initialize** `start_simulation` **with a list of client IDs** ([#860]" +"(https://github.com/adap/flower/pull/860))" msgstr "" #: ../../source/ref-changelog.md:927 @@ -18374,38 +18743,38 @@ msgstr "" #: ../../source/ref-changelog.md:931 msgid "" -"Update `num_examples` calculation in PyTorch code examples in " -"([#909](https://github.com/adap/flower/pull/909))" +"Update `num_examples` calculation in PyTorch code examples in ([#909]" +"(https://github.com/adap/flower/pull/909))" msgstr "" #: ../../source/ref-changelog.md:932 msgid "" -"Expose Flower version through `flwr.__version__` " -"([#952](https://github.com/adap/flower/pull/952))" +"Expose Flower version through `flwr.__version__` ([#952](https://github.com/" +"adap/flower/pull/952))" msgstr "" #: ../../source/ref-changelog.md:933 msgid "" -"`start_server` in `app.py` now returns a `History` object containing " -"metrics from training ([#974](https://github.com/adap/flower/pull/974))" +"`start_server` in `app.py` now returns a `History` object containing metrics " +"from training ([#974](https://github.com/adap/flower/pull/974))" msgstr "" #: ../../source/ref-changelog.md:934 msgid "" -"Make `max_workers` (used by `ThreadPoolExecutor`) configurable " -"([#978](https://github.com/adap/flower/pull/978))" +"Make `max_workers` (used by `ThreadPoolExecutor`) configurable ([#978]" +"(https://github.com/adap/flower/pull/978))" msgstr "" #: ../../source/ref-changelog.md:935 msgid "" -"Increase sleep time after server start to three seconds in all code " -"examples ([#1086](https://github.com/adap/flower/pull/1086))" +"Increase sleep time after server start to three seconds in all code examples " +"([#1086](https://github.com/adap/flower/pull/1086))" msgstr "" #: ../../source/ref-changelog.md:936 msgid "" -"Added a new FAQ section to the documentation " -"([#948](https://github.com/adap/flower/pull/948))" +"Added a new FAQ section to the documentation ([#948](https://github.com/adap/" +"flower/pull/948))" msgstr "" #: ../../source/ref-changelog.md:937 @@ -18425,8 +18794,8 @@ msgid "" "The packages `flwr_example` and `flwr_experimental` have been deprecated " "since Flower 0.12.0 and they are not longer included in Flower release " "builds. The associated extras (`baseline`, `examples-pytorch`, `examples-" -"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in " -"an upcoming release." +"tensorflow`, `http-logger`, `ops`) are now no-op and will be removed in an " +"upcoming release." msgstr "" #: ../../source/ref-changelog.md:945 @@ -18435,34 +18804,32 @@ msgstr "" #: ../../source/ref-changelog.md:949 msgid "" -"**Experimental virtual client engine** " -"([#781](https://github.com/adap/flower/pull/781) " -"[#790](https://github.com/adap/flower/pull/790) " -"[#791](https://github.com/adap/flower/pull/791))" +"**Experimental virtual client engine** ([#781](https://github.com/adap/" +"flower/pull/781) [#790](https://github.com/adap/flower/pull/790) [#791]" +"(https://github.com/adap/flower/pull/791))" msgstr "" #: ../../source/ref-changelog.md:951 msgid "" -"One of Flower's goals is to enable research at scale. This release " -"enables a first (experimental) peek at a major new feature, codenamed the" -" virtual client engine. Virtual clients enable simulations that scale to " -"a (very) large number of clients on a single machine or compute cluster. " -"The easiest way to test the new functionality is to look at the two new " -"code examples called `quickstart_simulation` and `simulation_pytorch`." +"One of Flower's goals is to enable research at scale. This release enables a " +"first (experimental) peek at a major new feature, codenamed the virtual " +"client engine. Virtual clients enable simulations that scale to a (very) " +"large number of clients on a single machine or compute cluster. The easiest " +"way to test the new functionality is to look at the two new code examples " +"called `quickstart_simulation` and `simulation_pytorch`." msgstr "" #: ../../source/ref-changelog.md:953 msgid "" -"The feature is still experimental, so there's no stability guarantee for " -"the API. It's also not quite ready for prime time and comes with a few " -"known caveats. However, those who are curious are encouraged to try it " -"out and share their thoughts." +"The feature is still experimental, so there's no stability guarantee for the " +"API. It's also not quite ready for prime time and comes with a few known " +"caveats. However, those who are curious are encouraged to try it out and " +"share their thoughts." msgstr "" #: ../../source/ref-changelog.md:955 msgid "" -"**New built-in strategies** " -"([#828](https://github.com/adap/flower/pull/828) " +"**New built-in strategies** ([#828](https://github.com/adap/flower/pull/828) " "[#822](https://github.com/adap/flower/pull/822))" msgstr "" @@ -18480,101 +18847,99 @@ msgstr "" #: ../../source/ref-changelog.md:960 msgid "" -"**New PyTorch Lightning code example** " -"([#617](https://github.com/adap/flower/pull/617))" +"**New PyTorch Lightning code example** ([#617](https://github.com/adap/" +"flower/pull/617))" msgstr "" #: ../../source/ref-changelog.md:962 msgid "" -"**New Variational Auto-Encoder code example** " -"([#752](https://github.com/adap/flower/pull/752))" +"**New Variational Auto-Encoder code example** ([#752](https://github.com/" +"adap/flower/pull/752))" msgstr "" #: ../../source/ref-changelog.md:964 msgid "" -"**New scikit-learn code example** " -"([#748](https://github.com/adap/flower/pull/748))" +"**New scikit-learn code example** ([#748](https://github.com/adap/flower/" +"pull/748))" msgstr "" #: ../../source/ref-changelog.md:966 msgid "" -"**New experimental TensorBoard strategy** " -"([#789](https://github.com/adap/flower/pull/789))" +"**New experimental TensorBoard strategy** ([#789](https://github.com/adap/" +"flower/pull/789))" msgstr "" #: ../../source/ref-changelog.md:970 msgid "" -"Improved advanced TensorFlow code example " -"([#769](https://github.com/adap/flower/pull/769))" +"Improved advanced TensorFlow code example ([#769](https://github.com/adap/" +"flower/pull/769))" msgstr "" #: ../../source/ref-changelog.md:971 msgid "" -"Warning when `min_available_clients` is misconfigured " -"([#830](https://github.com/adap/flower/pull/830))" +"Warning when `min_available_clients` is misconfigured ([#830](https://github." +"com/adap/flower/pull/830))" msgstr "" #: ../../source/ref-changelog.md:972 msgid "" -"Improved gRPC server docs " -"([#841](https://github.com/adap/flower/pull/841))" +"Improved gRPC server docs ([#841](https://github.com/adap/flower/pull/841))" msgstr "" #: ../../source/ref-changelog.md:973 msgid "" -"Improved error message in `NumPyClient` " -"([#851](https://github.com/adap/flower/pull/851))" +"Improved error message in `NumPyClient` ([#851](https://github.com/adap/" +"flower/pull/851))" msgstr "" #: ../../source/ref-changelog.md:974 msgid "" -"Improved PyTorch quickstart code example " -"([#852](https://github.com/adap/flower/pull/852))" +"Improved PyTorch quickstart code example ([#852](https://github.com/adap/" +"flower/pull/852))" msgstr "" #: ../../source/ref-changelog.md:978 msgid "" -"**Disabled final distributed evaluation** " -"([#800](https://github.com/adap/flower/pull/800))" +"**Disabled final distributed evaluation** ([#800](https://github.com/adap/" +"flower/pull/800))" msgstr "" #: ../../source/ref-changelog.md:980 msgid "" -"Prior behaviour was to perform a final round of distributed evaluation on" -" all connected clients, which is often not required (e.g., when using " -"server-side evaluation). The prior behaviour can be enabled by passing " +"Prior behaviour was to perform a final round of distributed evaluation on " +"all connected clients, which is often not required (e.g., when using server-" +"side evaluation). The prior behaviour can be enabled by passing " "`force_final_distributed_eval=True` to `start_server`." msgstr "" #: ../../source/ref-changelog.md:982 msgid "" -"**Renamed q-FedAvg strategy** " -"([#802](https://github.com/adap/flower/pull/802))" +"**Renamed q-FedAvg strategy** ([#802](https://github.com/adap/flower/" +"pull/802))" msgstr "" #: ../../source/ref-changelog.md:984 msgid "" -"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect " -"the notation given in the original paper (q-FFL is the optimization " -"objective, q-FedAvg is the proposed solver). Note the original (now " -"deprecated) `QffedAvg` class is still available for compatibility reasons" -" (it will be removed in a future release)." +"The strategy named `QffedAvg` was renamed to `QFedAvg` to better reflect the " +"notation given in the original paper (q-FFL is the optimization objective, q-" +"FedAvg is the proposed solver). Note the original (now deprecated) " +"`QffedAvg` class is still available for compatibility reasons (it will be " +"removed in a future release)." msgstr "" #: ../../source/ref-changelog.md:986 msgid "" "**Deprecated and renamed code example** `simulation_pytorch` **to** " -"`simulation_pytorch_legacy` " -"([#791](https://github.com/adap/flower/pull/791))" +"`simulation_pytorch_legacy` ([#791](https://github.com/adap/flower/pull/791))" msgstr "" #: ../../source/ref-changelog.md:988 msgid "" -"This example has been replaced by a new example. The new example is based" -" on the experimental virtual client engine, which will become the new " -"default way of doing most types of large-scale simulations in Flower. The" -" existing example was kept for reference purposes, but it might be " -"removed in the future." +"This example has been replaced by a new example. The new example is based on " +"the experimental virtual client engine, which will become the new default " +"way of doing most types of large-scale simulations in Flower. The existing " +"example was kept for reference purposes, but it might be removed in the " +"future." msgstr "" #: ../../source/ref-changelog.md:990 @@ -18583,8 +18948,7 @@ msgstr "" #: ../../source/ref-changelog.md:994 msgid "" -"**New built-in strategies** " -"([#549](https://github.com/adap/flower/pull/549))" +"**New built-in strategies** ([#549](https://github.com/adap/flower/pull/549))" msgstr "" #: ../../source/ref-changelog.md:996 @@ -18593,8 +18957,8 @@ msgstr "" #: ../../source/ref-changelog.md:999 msgid "" -"**Custom metrics for server and strategies** " -"([#717](https://github.com/adap/flower/pull/717))" +"**Custom metrics for server and strategies** ([#717](https://github.com/adap/" +"flower/pull/717))" msgstr "" #: ../../source/ref-changelog.md:1001 @@ -18608,20 +18972,19 @@ msgstr "" #: ../../source/ref-changelog.md:1003 msgid "" -"Custom metric dictionaries are now used in two user-facing APIs: they are" -" returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and " -"they enable evaluation functions passed to built-in strategies (via " -"`eval_fn`) to return more than two evaluation metrics. Strategies can " -"even return *aggregated* metrics dictionaries for the server to keep " -"track of." +"Custom metric dictionaries are now used in two user-facing APIs: they are " +"returned from Strategy methods `aggregate_fit`/`aggregate_evaluate` and they " +"enable evaluation functions passed to built-in strategies (via `eval_fn`) to " +"return more than two evaluation metrics. Strategies can even return " +"*aggregated* metrics dictionaries for the server to keep track of." msgstr "" #: ../../source/ref-changelog.md:1005 msgid "" "Strategy implementations should migrate their `aggregate_fit` and " "`aggregate_evaluate` methods to the new return type (e.g., by simply " -"returning an empty `{}`), server-side evaluation functions should migrate" -" from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." +"returning an empty `{}`), server-side evaluation functions should migrate " +"from `return loss, accuracy` to `return loss, {\"accuracy\": accuracy}`." msgstr "" #: ../../source/ref-changelog.md:1007 @@ -18632,25 +18995,24 @@ msgstr "" #: ../../source/ref-changelog.md:1009 msgid "" -"**Migration warnings for deprecated functionality** " -"([#690](https://github.com/adap/flower/pull/690))" +"**Migration warnings for deprecated functionality** ([#690](https://github." +"com/adap/flower/pull/690))" msgstr "" #: ../../source/ref-changelog.md:1011 msgid "" "Earlier versions of Flower were often migrated to new APIs, while " -"maintaining compatibility with legacy APIs. This release introduces " -"detailed warning messages if usage of deprecated APIs is detected. The " -"new warning messages often provide details on how to migrate to more " -"recent APIs, thus easing the transition from one release to another." +"maintaining compatibility with legacy APIs. This release introduces detailed " +"warning messages if usage of deprecated APIs is detected. The new warning " +"messages often provide details on how to migrate to more recent APIs, thus " +"easing the transition from one release to another." msgstr "" #: ../../source/ref-changelog.md:1013 msgid "" -"Improved docs and docstrings " -"([#691](https://github.com/adap/flower/pull/691) " -"[#692](https://github.com/adap/flower/pull/692) " -"[#713](https://github.com/adap/flower/pull/713))" +"Improved docs and docstrings ([#691](https://github.com/adap/flower/" +"pull/691) [#692](https://github.com/adap/flower/pull/692) [#713](https://" +"github.com/adap/flower/pull/713))" msgstr "" #: ../../source/ref-changelog.md:1015 @@ -18660,43 +19022,39 @@ msgstr "" #: ../../source/ref-changelog.md:1017 msgid "" "FedBN implementation in example PyTorch: From Centralized To Federated " -"([#696](https://github.com/adap/flower/pull/696) " -"[#702](https://github.com/adap/flower/pull/702) " -"[#705](https://github.com/adap/flower/pull/705))" +"([#696](https://github.com/adap/flower/pull/696) [#702](https://github.com/" +"adap/flower/pull/702) [#705](https://github.com/adap/flower/pull/705))" msgstr "" #: ../../source/ref-changelog.md:1021 msgid "" -"**Serialization-agnostic server** " -"([#721](https://github.com/adap/flower/pull/721))" +"**Serialization-agnostic server** ([#721](https://github.com/adap/flower/" +"pull/721))" msgstr "" #: ../../source/ref-changelog.md:1023 msgid "" -"The Flower server is now fully serialization-agnostic. Prior usage of " -"class `Weights` (which represents parameters as deserialized NumPy " -"ndarrays) was replaced by class `Parameters` (e.g., in `Strategy`). " -"`Parameters` objects are fully serialization-agnostic and represents " -"parameters as byte arrays, the `tensor_type` attributes indicates how " -"these byte arrays should be interpreted (e.g., for " -"serialization/deserialization)." +"The Flower server is now fully serialization-agnostic. Prior usage of class " +"`Weights` (which represents parameters as deserialized NumPy ndarrays) was " +"replaced by class `Parameters` (e.g., in `Strategy`). `Parameters` objects " +"are fully serialization-agnostic and represents parameters as byte arrays, " +"the `tensor_type` attributes indicates how these byte arrays should be " +"interpreted (e.g., for serialization/deserialization)." msgstr "" #: ../../source/ref-changelog.md:1025 msgid "" -"Built-in strategies implement this approach by handling serialization and" -" deserialization to/from `Weights` internally. Custom/3rd-party Strategy " +"Built-in strategies implement this approach by handling serialization and " +"deserialization to/from `Weights` internally. Custom/3rd-party Strategy " "implementations should update to the slightly changed Strategy method " -"definitions. Strategy authors can consult PR " -"[#721](https://github.com/adap/flower/pull/721) to see how strategies can" -" easily migrate to the new format." +"definitions. Strategy authors can consult PR [#721](https://github.com/adap/" +"flower/pull/721) to see how strategies can easily migrate to the new format." msgstr "" #: ../../source/ref-changelog.md:1027 msgid "" -"Deprecated `flwr.server.Server.evaluate`, use " -"`flwr.server.Server.evaluate_round` instead " -"([#717](https://github.com/adap/flower/pull/717))" +"Deprecated `flwr.server.Server.evaluate`, use `flwr.server.Server." +"evaluate_round` instead ([#717](https://github.com/adap/flower/pull/717))" msgstr "" #: ../../source/ref-changelog.md:1029 @@ -18705,8 +19063,8 @@ msgstr "" #: ../../source/ref-changelog.md:1033 msgid "" -"**Server-side parameter initialization** " -"([#658](https://github.com/adap/flower/pull/658))" +"**Server-side parameter initialization** ([#658](https://github.com/adap/" +"flower/pull/658))" msgstr "" #: ../../source/ref-changelog.md:1035 @@ -18719,9 +19077,9 @@ msgstr "" #: ../../source/ref-changelog.md:1037 msgid "" "Built-in strategies support a new constructor argument called " -"`initial_parameters` to set the initial parameters. Built-in strategies " -"will provide these initial parameters to the server on startup and then " -"delete them to free the memory afterwards." +"`initial_parameters` to set the initial parameters. Built-in strategies will " +"provide these initial parameters to the server on startup and then delete " +"them to free the memory afterwards." msgstr "" #: ../../source/ref-changelog.md:1056 @@ -18734,8 +19092,8 @@ msgstr "" #: ../../source/ref-changelog.md:1060 msgid "" -"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to " -"`flwr.server.strategy.FedAvg`, which is equivalent)" +"Deprecate `flwr.server.strategy.DefaultStrategy` (migrate to `flwr.server." +"strategy.FedAvg`, which is equivalent)" msgstr "" #: ../../source/ref-changelog.md:1062 @@ -18745,35 +19103,33 @@ msgstr "" #: ../../source/ref-changelog.md:1066 msgid "" "**Generalized** `Client.fit` **and** `Client.evaluate` **return values** " -"([#610](https://github.com/adap/flower/pull/610) " -"[#572](https://github.com/adap/flower/pull/572) " -"[#633](https://github.com/adap/flower/pull/633))" +"([#610](https://github.com/adap/flower/pull/610) [#572](https://github.com/" +"adap/flower/pull/572) [#633](https://github.com/adap/flower/pull/633))" msgstr "" #: ../../source/ref-changelog.md:1068 msgid "" -"Clients can now return an additional dictionary mapping `str` keys to " -"values of the following types: `bool`, `bytes`, `float`, `int`, `str`. " -"This means one can return almost arbitrary values from `fit`/`evaluate` " -"and make use of them on the server side!" +"Clients can now return an additional dictionary mapping `str` keys to values " +"of the following types: `bool`, `bytes`, `float`, `int`, `str`. This means " +"one can return almost arbitrary values from `fit`/`evaluate` and make use of " +"them on the server side!" msgstr "" #: ../../source/ref-changelog.md:1070 msgid "" -"This improvement also allowed for more consistent return types between " -"`fit` and `evaluate`: `evaluate` should now return a tuple `(float, int, " -"dict)` representing the loss, number of examples, and a dictionary " -"holding arbitrary problem-specific values like accuracy." +"This improvement also allowed for more consistent return types between `fit` " +"and `evaluate`: `evaluate` should now return a tuple `(float, int, dict)` " +"representing the loss, number of examples, and a dictionary holding " +"arbitrary problem-specific values like accuracy." msgstr "" #: ../../source/ref-changelog.md:1072 msgid "" -"In case you wondered: this feature is compatible with existing projects, " -"the additional dictionary return value is optional. New code should " -"however migrate to the new return types to be compatible with upcoming " -"Flower releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, " -"`evaluate`: `float, int, Dict[str, Scalar]`). See the example below for " -"details." +"In case you wondered: this feature is compatible with existing projects, the " +"additional dictionary return value is optional. New code should however " +"migrate to the new return types to be compatible with upcoming Flower " +"releases (`fit`: `List[np.ndarray], int, Dict[str, Scalar]`, `evaluate`: " +"`float, int, Dict[str, Scalar]`). See the example below for details." msgstr "" #: ../../source/ref-changelog.md:1074 @@ -18784,23 +19140,23 @@ msgstr "" #: ../../source/ref-changelog.md:1089 msgid "" -"**Generalized** `config` **argument in** `Client.fit` **and** " -"`Client.evaluate` ([#595](https://github.com/adap/flower/pull/595))" +"**Generalized** `config` **argument in** `Client.fit` **and** `Client." +"evaluate` ([#595](https://github.com/adap/flower/pull/595))" msgstr "" #: ../../source/ref-changelog.md:1091 msgid "" -"The `config` argument used to be of type `Dict[str, str]`, which means " -"that dictionary values were expected to be strings. The new release " -"generalizes this to enable values of the following types: `bool`, " -"`bytes`, `float`, `int`, `str`." +"The `config` argument used to be of type `Dict[str, str]`, which means that " +"dictionary values were expected to be strings. The new release generalizes " +"this to enable values of the following types: `bool`, `bytes`, `float`, " +"`int`, `str`." msgstr "" #: ../../source/ref-changelog.md:1093 msgid "" "This means one can now pass almost arbitrary values to `fit`/`evaluate` " -"using the `config` dictionary. Yay, no more `str(epochs)` on the server-" -"side and `int(config[\"epochs\"])` on the client side!" +"using the `config` dictionary. Yay, no more `str(epochs)` on the server-side " +"and `int(config[\"epochs\"])` on the client side!" msgstr "" #: ../../source/ref-changelog.md:1095 @@ -18815,8 +19171,8 @@ msgstr "" #: ../../source/ref-changelog.md:1116 msgid "" -"New example: PyTorch From Centralized To Federated " -"([#549](https://github.com/adap/flower/pull/549))" +"New example: PyTorch From Centralized To Federated ([#549](https://github." +"com/adap/flower/pull/549))" msgstr "" #: ../../source/ref-changelog.md:1117 @@ -18824,7 +19180,8 @@ msgid "Improved documentation" msgstr "" #: ../../source/ref-changelog.md:1118 -msgid "New documentation theme ([#551](https://github.com/adap/flower/pull/551))" +msgid "" +"New documentation theme ([#551](https://github.com/adap/flower/pull/551))" msgstr "" #: ../../source/ref-changelog.md:1119 @@ -18833,14 +19190,14 @@ msgstr "" #: ../../source/ref-changelog.md:1120 msgid "" -"Updated examples documentation " -"([#549](https://github.com/adap/flower/pull/549))" +"Updated examples documentation ([#549](https://github.com/adap/flower/" +"pull/549))" msgstr "" #: ../../source/ref-changelog.md:1121 msgid "" -"Removed obsolete documentation " -"([#548](https://github.com/adap/flower/pull/548))" +"Removed obsolete documentation ([#548](https://github.com/adap/flower/" +"pull/548))" msgstr "" #: ../../source/ref-changelog.md:1123 @@ -18849,10 +19206,9 @@ msgstr "" #: ../../source/ref-changelog.md:1125 msgid "" -"`Server.fit` does not disconnect clients when finished, disconnecting the" -" clients is now handled in `flwr.server.start_server` " -"([#553](https://github.com/adap/flower/pull/553) " -"[#540](https://github.com/adap/flower/issues/540))." +"`Server.fit` does not disconnect clients when finished, disconnecting the " +"clients is now handled in `flwr.server.start_server` ([#553](https://github." +"com/adap/flower/pull/553) [#540](https://github.com/adap/flower/issues/540))." msgstr "" #: ../../source/ref-changelog.md:1127 @@ -18865,23 +19221,22 @@ msgstr "" #: ../../source/ref-changelog.md:1131 msgid "" -"Added an example for embedded devices " -"([#507](https://github.com/adap/flower/pull/507))" +"Added an example for embedded devices ([#507](https://github.com/adap/flower/" +"pull/507))" msgstr "" #: ../../source/ref-changelog.md:1132 msgid "" -"Added a new NumPyClient (in addition to the existing KerasClient) " -"([#504](https://github.com/adap/flower/pull/504) " -"[#508](https://github.com/adap/flower/pull/508))" +"Added a new NumPyClient (in addition to the existing KerasClient) ([#504]" +"(https://github.com/adap/flower/pull/504) [#508](https://github.com/adap/" +"flower/pull/508))" msgstr "" #: ../../source/ref-changelog.md:1133 msgid "" -"Deprecated `flwr_example` package and started to migrate examples into " -"the top-level `examples` directory " -"([#494](https://github.com/adap/flower/pull/494) " -"[#512](https://github.com/adap/flower/pull/512))" +"Deprecated `flwr_example` package and started to migrate examples into the " +"top-level `examples` directory ([#494](https://github.com/adap/flower/" +"pull/494) [#512](https://github.com/adap/flower/pull/512))" msgstr "" #: ../../source/ref-changelog.md:1135 @@ -18894,12 +19249,11 @@ msgstr "" #: ../../source/ref-changelog.md:1139 msgid "" -"Renamed strategy methods " -"([#486](https://github.com/adap/flower/pull/486)) to unify the naming of " -"Flower's public APIs. Other public methods/functions (e.g., every method " -"in `Client`, but also `Strategy.evaluate`) do not use the `on_` prefix, " -"which is why we're removing it from the four methods in Strategy. To " -"migrate rename the following `Strategy` methods accordingly:" +"Renamed strategy methods ([#486](https://github.com/adap/flower/pull/486)) " +"to unify the naming of Flower's public APIs. Other public methods/functions " +"(e.g., every method in `Client`, but also `Strategy.evaluate`) do not use " +"the `on_` prefix, which is why we're removing it from the four methods in " +"Strategy. To migrate rename the following `Strategy` methods accordingly:" msgstr "" #: ../../source/ref-changelog.md:1140 @@ -18920,33 +19274,32 @@ msgstr "" #: ../../source/ref-changelog.md:1147 msgid "" -"Deprecated `DefaultStrategy` " -"([#479](https://github.com/adap/flower/pull/479)). To migrate use " -"`FedAvg` instead." +"Deprecated `DefaultStrategy` ([#479](https://github.com/adap/flower/" +"pull/479)). To migrate use `FedAvg` instead." msgstr "" #: ../../source/ref-changelog.md:1148 msgid "" -"Simplified examples and baselines " -"([#484](https://github.com/adap/flower/pull/484))." +"Simplified examples and baselines ([#484](https://github.com/adap/flower/" +"pull/484))." msgstr "" #: ../../source/ref-changelog.md:1149 msgid "" -"Removed presently unused `on_conclude_round` from strategy interface " -"([#483](https://github.com/adap/flower/pull/483))." +"Removed presently unused `on_conclude_round` from strategy interface ([#483]" +"(https://github.com/adap/flower/pull/483))." msgstr "" #: ../../source/ref-changelog.md:1150 msgid "" -"Set minimal Python version to 3.6.1 instead of 3.6.9 " -"([#471](https://github.com/adap/flower/pull/471))." +"Set minimal Python version to 3.6.1 instead of 3.6.9 ([#471](https://github." +"com/adap/flower/pull/471))." msgstr "" #: ../../source/ref-changelog.md:1151 msgid "" -"Improved `Strategy` docstrings " -"([#470](https://github.com/adap/flower/pull/470))." +"Improved `Strategy` docstrings ([#470](https://github.com/adap/flower/" +"pull/470))." msgstr "" #: ../../source/ref-example-projects.rst:2 @@ -18955,11 +19308,11 @@ msgstr "" #: ../../source/ref-example-projects.rst:4 msgid "" -"Flower comes with a number of usage examples. The examples demonstrate " -"how Flower can be used to federate different kinds of existing machine " -"learning pipelines, usually leveraging popular machine learning " -"frameworks such as `PyTorch `_ or `TensorFlow " -"`_." +"Flower comes with a number of usage examples. The examples demonstrate how " +"Flower can be used to federate different kinds of existing machine learning " +"pipelines, usually leveraging popular machine learning frameworks such as " +"`PyTorch `_ or `TensorFlow `_." msgstr "" #: ../../source/ref-example-projects.rst:10 @@ -18970,25 +19323,25 @@ msgstr "" #: ../../source/ref-example-projects.rst:14 msgid "" -"The TensorFlow/Keras quickstart example shows CIFAR-10 image " -"classification with MobileNetV2:" +"The TensorFlow/Keras quickstart example shows CIFAR-10 image classification " +"with MobileNetV2:" msgstr "" #: ../../source/ref-example-projects.rst:17 msgid "" -"`Quickstart TensorFlow (Code) " -"`_" +"`Quickstart TensorFlow (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:18 -msgid ":doc:`Quickstart TensorFlow (Tutorial) `" +msgid "" +":doc:`Quickstart TensorFlow (Tutorial) `" msgstr "" #: ../../source/ref-example-projects.rst:19 msgid "" -"`Quickstart TensorFlow (Blog Post) `_" +"`Quickstart TensorFlow (Blog Post) `_" msgstr "" #: ../../source/ref-example-projects.rst:23 @@ -18998,14 +19351,14 @@ msgstr "" #: ../../source/ref-example-projects.rst:25 msgid "" -"The PyTorch quickstart example shows CIFAR-10 image classification with a" -" simple Convolutional Neural Network:" +"The PyTorch quickstart example shows CIFAR-10 image classification with a " +"simple Convolutional Neural Network:" msgstr "" #: ../../source/ref-example-projects.rst:28 msgid "" -"`Quickstart PyTorch (Code) " -"`_" +"`Quickstart PyTorch (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:29 @@ -19024,9 +19377,8 @@ msgstr "" #: ../../source/ref-example-projects.rst:37 msgid "" -"`PyTorch: From Centralized To Federated (Code) " -"`_" +"`PyTorch: From Centralized To Federated (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:38 @@ -19047,14 +19399,15 @@ msgstr "" #: ../../source/ref-example-projects.rst:46 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Code) `_" msgstr "" #: ../../source/ref-example-projects.rst:47 msgid "" -"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) " -"`_" +"`Federated Learning on Raspberry Pi and Nvidia Jetson (Blog Post) `_" msgstr "" #: ../../source/ref-faq.rst:4 @@ -19069,22 +19422,20 @@ msgstr "" #: ../../source/ref-faq.rst:8 msgid "" -"Yes, it can! Flower even comes with a few under-the-hood optimizations to" -" make it work even better on Colab. Here's a quickstart example:" +"Yes, it can! Flower even comes with a few under-the-hood optimizations to " +"make it work even better on Colab. Here's a quickstart example:" msgstr "" #: ../../source/ref-faq.rst:10 msgid "" -"`Flower simulation PyTorch " -"`_" +"`Flower simulation PyTorch `_" msgstr "" #: ../../source/ref-faq.rst:11 msgid "" -"`Flower simulation TensorFlow/Keras " -"`_" +"`Flower simulation TensorFlow/Keras `_" msgstr "" #: ../../source/ref-faq.rst @@ -19094,26 +19445,28 @@ msgstr "" #: ../../source/ref-faq.rst:15 msgid "" "Find the `blog post about federated learning on embedded device here " -"`_" -" and the corresponding `GitHub code example " -"`_." +"`_ " +"and the corresponding `GitHub code example `_." msgstr "" #: ../../source/ref-faq.rst -msgid ":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" +msgid "" +":fa:`eye,mr-1` Does Flower support federated learning on Android devices?" msgstr "" #: ../../source/ref-faq.rst:19 msgid "" -"Yes, it does. Please take a look at our `blog post " -"`_ or check out the code examples:" +"Yes, it does. Please take a look at our `blog post `_ or " +"check out the code examples:" msgstr "" #: ../../source/ref-faq.rst:21 msgid "" -"`Android Kotlin example `_" +"`Android Kotlin example `_" msgstr "" #: ../../source/ref-faq.rst:22 @@ -19132,33 +19485,33 @@ msgstr "" #: ../../source/ref-faq.rst:28 msgid "" -"`Flower meets Nevermined GitHub Repository `_." +"`Flower meets Nevermined GitHub Repository `_." msgstr "" #: ../../source/ref-faq.rst:29 msgid "" -"`Flower meets Nevermined YouTube video " -"`_." +"`Flower meets Nevermined YouTube video `_." msgstr "" #: ../../source/ref-faq.rst:30 msgid "" -"`Flower meets KOSMoS `_." +"`Flower meets KOSMoS `_." msgstr "" #: ../../source/ref-faq.rst:31 msgid "" "`Flower meets Talan blog post `_ ." +"learning-same-mask-different-faces-imen-ayari/?" +"trackingId=971oIlxLQ9%2BA9RB0IQ73XQ%3D%3D>`_ ." msgstr "" #: ../../source/ref-faq.rst:32 msgid "" -"`Flower meets Talan GitHub Repository " -"`_ ." +"`Flower meets Talan GitHub Repository `_ ." msgstr "" #: ../../source/ref-telemetry.md:1 @@ -19167,17 +19520,16 @@ msgstr "" #: ../../source/ref-telemetry.md:3 msgid "" -"The Flower open-source project collects **anonymous** usage metrics to " -"make well-informed decisions to improve Flower. Doing this enables the " -"Flower team to understand how Flower is used and what challenges users " -"might face." +"The Flower open-source project collects **anonymous** usage metrics to make " +"well-informed decisions to improve Flower. Doing this enables the Flower " +"team to understand how Flower is used and what challenges users might face." msgstr "" #: ../../source/ref-telemetry.md:5 msgid "" -"**Flower is a friendly framework for collaborative AI and data science.**" -" Staying true to this statement, Flower makes it easy to disable " -"telemetry for users that do not want to share anonymous usage metrics." +"**Flower is a friendly framework for collaborative AI and data science.** " +"Staying true to this statement, Flower makes it easy to disable telemetry " +"for users that do not want to share anonymous usage metrics." msgstr "" #: ../../source/ref-telemetry.md:7 @@ -19185,35 +19537,34 @@ msgid "Principles" msgstr "" #: ../../source/ref-telemetry.md:9 -msgid "We follow strong principles guarding anonymous usage metrics collection:" +msgid "" +"We follow strong principles guarding anonymous usage metrics collection:" msgstr "" #: ../../source/ref-telemetry.md:11 msgid "" -"**Optional:** You will always be able to disable telemetry; read on to " -"learn “[How to opt-out](#how-to-opt-out)”." +"**Optional:** You will always be able to disable telemetry; read on to learn " +"“[How to opt-out](#how-to-opt-out)”." msgstr "" #: ../../source/ref-telemetry.md:12 msgid "" -"**Anonymous:** The reported usage metrics are anonymous and do not " -"contain any personally identifiable information (PII). See “[Collected " -"metrics](#collected-metrics)” to understand what metrics are being " -"reported." +"**Anonymous:** The reported usage metrics are anonymous and do not contain " +"any personally identifiable information (PII). See “[Collected metrics]" +"(#collected-metrics)” to understand what metrics are being reported." msgstr "" #: ../../source/ref-telemetry.md:13 msgid "" "**Transparent:** You can easily inspect what anonymous metrics are being " -"reported; see the section “[How to inspect what is being reported](#how-" -"to-inspect-what-is-being-reported)”" +"reported; see the section “[How to inspect what is being reported](#how-to-" +"inspect-what-is-being-reported)”" msgstr "" #: ../../source/ref-telemetry.md:14 msgid "" -"**Open for feedback:** You can always reach out to us if you have " -"feedback; see the section “[How to contact us](#how-to-contact-us)” for " -"details." +"**Open for feedback:** You can always reach out to us if you have feedback; " +"see the section “[How to contact us](#how-to-contact-us)” for details." msgstr "" #: ../../source/ref-telemetry.md:16 @@ -19230,9 +19581,9 @@ msgstr "" #: ../../source/ref-telemetry.md:24 msgid "" -"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example," -" `.bashrc` (or whatever configuration file applies to your environment) " -"to disable Flower telemetry permanently." +"Alternatively, you can export `FLWR_TELEMETRY_ENABLED=0` in, for example, `." +"bashrc` (or whatever configuration file applies to your environment) to " +"disable Flower telemetry permanently." msgstr "" #: ../../source/ref-telemetry.md:26 @@ -19245,10 +19596,10 @@ msgstr "" #: ../../source/ref-telemetry.md:30 msgid "" -"**Flower version.** Understand which versions of Flower are currently " -"being used. This helps us to decide whether we should invest effort into " -"releasing a patch version for an older version of Flower or instead use " -"the bandwidth to build new features." +"**Flower version.** Understand which versions of Flower are currently being " +"used. This helps us to decide whether we should invest effort into releasing " +"a patch version for an older version of Flower or instead use the bandwidth " +"to build new features." msgstr "" #: ../../source/ref-telemetry.md:32 @@ -19267,15 +19618,15 @@ msgstr "" #: ../../source/ref-telemetry.md:36 msgid "" -"**Hardware properties.** Understanding the hardware environment that " -"Flower is being used in helps to decide whether we should, for example, " -"put more effort into supporting low-resource environments." +"**Hardware properties.** Understanding the hardware environment that Flower " +"is being used in helps to decide whether we should, for example, put more " +"effort into supporting low-resource environments." msgstr "" #: ../../source/ref-telemetry.md:38 msgid "" -"**Execution mode.** Knowing what execution mode Flower starts in enables " -"us to understand how heavily certain features are being used and better " +"**Execution mode.** Knowing what execution mode Flower starts in enables us " +"to understand how heavily certain features are being used and better " "prioritize based on that." msgstr "" @@ -19283,37 +19634,34 @@ msgstr "" msgid "" "**Cluster.** Flower telemetry assigns a random in-memory cluster ID each " "time a Flower workload starts. This allows us to understand which device " -"types not only start Flower workloads but also successfully complete " -"them." +"types not only start Flower workloads but also successfully complete them." msgstr "" #: ../../source/ref-telemetry.md:42 msgid "" -"**Source.** Flower telemetry tries to store a random source ID in " -"`~/.flwr/source` the first time a telemetry event is generated. The " -"source ID is important to identify whether an issue is recurring or " -"whether an issue is triggered by multiple clusters running concurrently " -"(which often happens in simulation). For example, if a device runs " -"multiple workloads at the same time, and this results in an issue, then, " -"in order to reproduce the issue, multiple workloads must be started at " -"the same time." +"**Source.** Flower telemetry tries to store a random source ID in `~/.flwr/" +"source` the first time a telemetry event is generated. The source ID is " +"important to identify whether an issue is recurring or whether an issue is " +"triggered by multiple clusters running concurrently (which often happens in " +"simulation). For example, if a device runs multiple workloads at the same " +"time, and this results in an issue, then, in order to reproduce the issue, " +"multiple workloads must be started at the same time." msgstr "" #: ../../source/ref-telemetry.md:44 msgid "" -"You may delete the source ID at any time. If you wish for all events " -"logged under a specific source ID to be deleted, you can send a deletion " -"request mentioning the source ID to `telemetry@flower.ai`. All events " -"related to that source ID will then be permanently deleted." +"You may delete the source ID at any time. If you wish for all events logged " +"under a specific source ID to be deleted, you can send a deletion request " +"mentioning the source ID to `telemetry@flower.ai`. All events related to " +"that source ID will then be permanently deleted." msgstr "" #: ../../source/ref-telemetry.md:46 msgid "" -"We will not collect any personally identifiable information. If you think" -" any of the metrics collected could be misused in any way, please [get in" -" touch with us](#how-to-contact-us). We will update this page to reflect " -"any changes to the metrics collected and publish changes in the " -"changelog." +"We will not collect any personally identifiable information. If you think " +"any of the metrics collected could be misused in any way, please [get in " +"touch with us](#how-to-contact-us). We will update this page to reflect any " +"changes to the metrics collected and publish changes in the changelog." msgstr "" #: ../../source/ref-telemetry.md:48 @@ -19330,17 +19678,17 @@ msgstr "" #: ../../source/ref-telemetry.md:52 msgid "" "We wanted to make it very easy for you to inspect what anonymous usage " -"metrics are reported. You can view all the reported telemetry information" -" by setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging " -"is disabled by default. You may use logging independently from " +"metrics are reported. You can view all the reported telemetry information by " +"setting the environment variable `FLWR_TELEMETRY_LOGGING=1`. Logging is " +"disabled by default. You may use logging independently from " "`FLWR_TELEMETRY_ENABLED` so that you can inspect the telemetry feature " "without sending any metrics." msgstr "" #: ../../source/ref-telemetry.md:58 msgid "" -"The inspect Flower telemetry without sending any anonymous usage metrics," -" use both environment variables:" +"The inspect Flower telemetry without sending any anonymous usage metrics, " +"use both environment variables:" msgstr "" #: ../../source/ref-telemetry.md:64 @@ -19357,8 +19705,8 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:-1 msgid "" -"Read this Federated Learning quickstart tutorial for creating an Android " -"app using Flower." +"Read this Federated Learning quickstart tutorial for creating an Android app " +"using Flower." msgstr "" #: ../../source/tutorial-quickstart-android.rst:5 @@ -19367,21 +19715,19 @@ msgstr "" #: ../../source/tutorial-quickstart-android.rst:10 msgid "" -"Let's build a federated learning system using TFLite and Flower on " -"Android!" +"Let's build a federated learning system using TFLite and Flower on Android!" msgstr "" #: ../../source/tutorial-quickstart-android.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn " -"more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with FastAI to train a vision model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"FastAI to train a vision model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:5 @@ -19394,15 +19740,14 @@ msgstr "" #: ../../source/tutorial-quickstart-fastai.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:-1 msgid "" -"Check out this Federating Learning quickstart tutorial for using Flower " -"with HuggingFace Transformers in order to fine-tune an LLM." +"Check out this Federating Learning quickstart tutorial for using Flower with " +"HuggingFace Transformers in order to fine-tune an LLM." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:5 @@ -19411,17 +19756,17 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:10 msgid "" -"Let's build a federated learning system using Hugging Face Transformers " -"and Flower!" +"Let's build a federated learning system using Hugging Face Transformers and " +"Flower!" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:12 msgid "" -"We will leverage Hugging Face to federate the training of language models" -" over multiple clients using Flower. More specifically, we will fine-tune" -" a pre-trained Transformer model (distilBERT) for sequence classification" -" over a dataset of IMDB ratings. The end goal is to detect if a movie " -"rating is positive or negative." +"We will leverage Hugging Face to federate the training of language models " +"over multiple clients using Flower. More specifically, we will fine-tune a " +"pre-trained Transformer model (distilBERT) for sequence classification over " +"a dataset of IMDB ratings. The end goal is to detect if a movie rating is " +"positive or negative." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:18 @@ -19431,9 +19776,8 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:20 msgid "" "To follow along this tutorial you will need to install the following " -"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, " -":code:`torch`, and :code:`transformers`. This can be done using " -":code:`pip`:" +"packages: :code:`datasets`, :code:`evaluate`, :code:`flwr`, :code:`torch`, " +"and :code:`transformers`. This can be done using :code:`pip`:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:30 @@ -19457,9 +19801,9 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:83 msgid "" -"Once we have a way of creating our trainloader and testloader, we can " -"take care of the training and testing. This is very similar to any " -":code:`PyTorch` training or testing loop:" +"Once we have a way of creating our trainloader and testloader, we can take " +"care of the training and testing. This is very similar to any :code:" +"`PyTorch` training or testing loop:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:121 @@ -19468,8 +19812,8 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:123 msgid "" -"To create the model itself, we will just load the pre-trained distillBERT" -" model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" +"To create the model itself, we will just load the pre-trained distillBERT " +"model using Hugging Face’s :code:`AutoModelForSequenceClassification` :" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:136 @@ -19483,18 +19827,17 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:141 msgid "" "To federate our example to multiple clients, we first need to write our " -"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). " -"This is very easy, as our model is a standard :code:`PyTorch` model:" +"Flower client class (inheriting from :code:`flwr.client.NumPyClient`). This " +"is very easy, as our model is a standard :code:`PyTorch` model:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:169 msgid "" "The :code:`get_parameters` function lets the server get the client's " -"parameters. Inversely, the :code:`set_parameters` function allows the " -"server to send its parameters to the client. Finally, the :code:`fit` " -"function trains the model locally for the client, and the " -":code:`evaluate` function tests the model locally and returns the " -"relevant metrics." +"parameters. Inversely, the :code:`set_parameters` function allows the server " +"to send its parameters to the client. Finally, the :code:`fit` function " +"trains the model locally for the client, and the :code:`evaluate` function " +"tests the model locally and returns the relevant metrics." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:175 @@ -19503,19 +19846,19 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:177 msgid "" -"Now that we have a way to instantiate clients, we need to create our " -"server in order to aggregate the results. Using Flower, this can be done " -"very easily by first choosing a strategy (here, we are using " -":code:`FedAvg`, which will define the global weights as the average of " -"all the clients' weights at each round) and then using the " -":code:`flwr.server.start_server` function:" +"Now that we have a way to instantiate clients, we need to create our server " +"in order to aggregate the results. Using Flower, this can be done very " +"easily by first choosing a strategy (here, we are using :code:`FedAvg`, " +"which will define the global weights as the average of all the clients' " +"weights at each round) and then using the :code:`flwr.server.start_server` " +"function:" msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:205 msgid "" -"The :code:`weighted_average` function is there to provide a way to " -"aggregate the metrics distributed amongst the clients (basically this " -"allows us to display a nice average accuracy and loss for every round)." +"The :code:`weighted_average` function is there to provide a way to aggregate " +"the metrics distributed amongst the clients (basically this allows us to " +"display a nice average accuracy and loss for every round)." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:209 @@ -19534,22 +19877,22 @@ msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:223 msgid "" -"If you want to check out everything put together, you should check out " -"the `full code example `_ ." +"If you want to check out everything put together, you should check out the " +"`full code example `_ ." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:226 msgid "" -"Of course, this is a very basic example, and a lot can be added or " -"modified, it was just to showcase how simply we could federate a Hugging " -"Face workflow using Flower." +"Of course, this is a very basic example, and a lot can be added or modified, " +"it was just to showcase how simply we could federate a Hugging Face workflow " +"using Flower." msgstr "" #: ../../source/tutorial-quickstart-huggingface.rst:229 msgid "" -"Note that in this example we used :code:`PyTorch`, but we could have very" -" well used :code:`TensorFlow`." +"Note that in this example we used :code:`PyTorch`, but we could have very " +"well used :code:`TensorFlow`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:-1 @@ -19564,38 +19907,38 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:10 msgid "" -"In this tutorial we will learn how to train a Neural Network on MNIST " -"using Flower and CoreML on iOS devices." +"In this tutorial we will learn how to train a Neural Network on MNIST using " +"Flower and CoreML on iOS devices." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:12 msgid "" "First of all, for running the Flower Python server, it is recommended to " -"create a virtual environment and run everything within a :doc:`virtualenv" -" `. For the Flower client " +"create a virtual environment and run everything within a :doc:`virtualenv " +"`. For the Flower client " "implementation in iOS, it is recommended to use Xcode as our IDE." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:15 msgid "" -"Our example consists of one Python *server* and two iPhone *clients* that" -" all have the same model." +"Our example consists of one Python *server* and two iPhone *clients* that " +"all have the same model." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:17 msgid "" -"*Clients* are responsible for generating individual weight updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:21 msgid "" "Now that we have a rough idea of what is going on, let's get started to " -"setup our Flower server environment. We first need to install Flower. You" -" can do this by using pip:" +"setup our Flower server environment. We first need to install Flower. You " +"can do this by using pip:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:27 @@ -19613,21 +19956,20 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:36 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training using CoreML as our local training pipeline and " -"MNIST as our dataset. For simplicity reasons we will use the complete " -"Flower client with CoreML, that has been implemented and stored inside " -"the Swift SDK. The client implementation can be seen below:" +"distributed training using CoreML as our local training pipeline and MNIST " +"as our dataset. For simplicity reasons we will use the complete Flower " +"client with CoreML, that has been implemented and stored inside the Swift " +"SDK. The client implementation can be seen below:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:72 msgid "" -"Let's create a new application project in Xcode and add :code:`flwr` as a" -" dependency in your project. For our application, we will store the logic" -" of our app in :code:`FLiOSModel.swift` and the UI elements in " -":code:`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift`" -" in this quickstart. Please refer to the `full code example " -"`_ to learn more " -"about the app." +"Let's create a new application project in Xcode and add :code:`flwr` as a " +"dependency in your project. For our application, we will store the logic of " +"our app in :code:`FLiOSModel.swift` and the UI elements in :code:" +"`ContentView.swift`. We will focus more on :code:`FLiOSModel.swift` in this " +"quickstart. Please refer to the `full code example `_ to learn more about the app." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:75 @@ -19637,22 +19979,21 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:83 msgid "" "Then add the mlmodel to the project simply by drag-and-drop, the mlmodel " -"will be bundled inside the application during deployment to your iOS " -"device. We need to pass the url to access mlmodel and run CoreML machine " -"learning processes, it can be retrieved by calling the function " -":code:`Bundle.main.url`. For the MNIST dataset, we need to preprocess it " -"into :code:`MLBatchProvider` object. The preprocessing is done inside " -":code:`DataLoader.swift`." +"will be bundled inside the application during deployment to your iOS device. " +"We need to pass the url to access mlmodel and run CoreML machine learning " +"processes, it can be retrieved by calling the function :code:`Bundle.main." +"url`. For the MNIST dataset, we need to preprocess it into :code:" +"`MLBatchProvider` object. The preprocessing is done inside :code:`DataLoader." +"swift`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:99 msgid "" -"Since CoreML does not allow the model parameters to be seen before " -"training, and accessing the model parameters during or after the training" -" can only be done by specifying the layer name, we need to know this " -"information beforehand, through looking at the model specification, which" -" are written as proto files. The implementation can be seen in " -":code:`MLModelInspect`." +"Since CoreML does not allow the model parameters to be seen before training, " +"and accessing the model parameters during or after the training can only be " +"done by specifying the layer name, we need to know this information " +"beforehand, through looking at the model specification, which are written as " +"proto files. The implementation can be seen in :code:`MLModelInspect`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:102 @@ -19663,18 +20004,18 @@ msgstr "" #: ../../source/tutorial-quickstart-ios.rst:117 msgid "" -"Then start the Flower gRPC client and start communicating to the server " -"by passing our Flower client to the function :code:`startFlwrGRPC`." +"Then start the Flower gRPC client and start communicating to the server by " +"passing our Flower client to the function :code:`startFlwrGRPC`." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:124 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -"call the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. " -"The attribute :code:`hostname` and :code:`port` tells the client which " -"server to connect to. This can be done by entering the hostname and port " -"in the application before clicking the start button to start the " -"federated learning process." +"That's it for the client. We only have to implement :code:`Client` or call " +"the provided :code:`MLFlwrClient` and call :code:`startFlwrGRPC()`. The " +"attribute :code:`hostname` and :code:`port` tells the client which server to " +"connect to. This can be done by entering the hostname and port in the " +"application before clicking the start button to start the federated learning " +"process." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:129 @@ -19690,8 +20031,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:100 msgid "" "For simple workloads we can start a Flower server and leave all the " -"configuration possibilities at their default values. In a file named " -":code:`server.py`, import Flower and start the server:" +"configuration possibilities at their default values. In a file named :code:" +"`server.py`, import Flower and start the server:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:142 @@ -19707,32 +20048,31 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:525 msgid "" "With both client and server ready, we can now run everything and see " -"federated learning in action. FL systems usually have a server and " -"multiple clients. We therefore have to start the server first:" +"federated learning in action. FL systems usually have a server and multiple " +"clients. We therefore have to start the server first:" msgstr "" #: ../../source/tutorial-quickstart-ios.rst:152 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Build and run the client through your Xcode, one through Xcode" -" Simulator and the other by deploying it to your iPhone. To see more " -"about how to deploy your app to iPhone or Simulator visit `here " -"`_." +"Once the server is running we can start the clients in different terminals. " +"Build and run the client through your Xcode, one through Xcode Simulator and " +"the other by deploying it to your iPhone. To see more about how to deploy " +"your app to iPhone or Simulator visit `here `_." msgstr "" #: ../../source/tutorial-quickstart-ios.rst:156 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system in your ios device. The full `source code " -"`_ for this " -"example can be found in :code:`examples/ios`." +"learning system in your ios device. The full `source code `_ for this example can be found in :" +"code:`examples/ios`." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Jax to train a linear regression model on a scikit-learn dataset." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Jax to train a linear regression model on a scikit-learn dataset." msgstr "" #: ../../source/tutorial-quickstart-jax.rst:5 @@ -19741,8 +20081,8 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with Pandas to perform Federated Analytics." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"Pandas to perform Federated Analytics." msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:5 @@ -19755,45 +20095,44 @@ msgstr "" #: ../../source/tutorial-quickstart-pandas.rst:12 msgid "" -"Please refer to the `full code example " -"`_ " -"to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch to train a CNN model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch to train a CNN model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:13 msgid "" -"In this tutorial we will learn how to train a Convolutional Neural " -"Network on CIFAR10 using Flower and PyTorch." +"In this tutorial we will learn how to train a Convolutional Neural Network " +"on CIFAR10 using Flower and PyTorch." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:15 #: ../../source/tutorial-quickstart-xgboost.rst:39 msgid "" "First of all, it is recommended to create a virtual environment and run " -"everything within a :doc:`virtualenv `." +"everything within a :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:17 #: ../../source/tutorial-quickstart-scikitlearn.rst:14 msgid "" -"Our example consists of one *server* and two *clients* all having the " -"same model." +"Our example consists of one *server* and two *clients* all having the same " +"model." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:19 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. These updates are then sent to " -"the *server* which will aggregate them to produce a better model. " -"Finally, the *server* sends this improved version of the model back to " -"each *client*. A complete cycle of weight updates is called a *round*." +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. These updates are then sent to the " +"*server* which will aggregate them to produce a better model. Finally, the " +"*server* sends this improved version of the model back to each *client*. A " +"complete cycle of weight updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:23 @@ -19804,16 +20143,15 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:29 msgid "" -"Since we want to use PyTorch to solve a computer vision task, let's go " -"ahead and install PyTorch and the **torchvision** library:" +"Since we want to use PyTorch to solve a computer vision task, let's go ahead " +"and install PyTorch and the **torchvision** library:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:39 msgid "" "Now that we have all our dependencies installed, let's run a simple " -"distributed training with two clients and one server. Our training " -"procedure and network architecture are based on PyTorch's `Deep Learning " -"with PyTorch " +"distributed training with two clients and one server. Our training procedure " +"and network architecture are based on PyTorch's `Deep Learning with PyTorch " "`_." msgstr "" @@ -19830,33 +20168,33 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:62 msgid "" "We use PyTorch to load CIFAR10, a popular colored image classification " -"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads " -"the training and test data that are then normalized." +"dataset for machine learning. The PyTorch :code:`DataLoader()` downloads the " +"training and test data that are then normalized." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:78 msgid "" -"Define the loss and optimizer with PyTorch. The training of the dataset " -"is done by looping over the dataset, measure the corresponding loss and " +"Define the loss and optimizer with PyTorch. The training of the dataset is " +"done by looping over the dataset, measure the corresponding loss and " "optimize it." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:94 msgid "" -"Define then the validation of the machine learning network. We loop over" -" the test set and measure the loss and accuracy of the test set." +"Define then the validation of the machine learning network. We loop over " +"the test set and measure the loss and accuracy of the test set." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:113 msgid "" -"After defining the training and testing of a PyTorch machine learning " -"model, we use the functions for the Flower clients." +"After defining the training and testing of a PyTorch machine learning model, " +"we use the functions for the Flower clients." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:115 msgid "" -"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 " -"Minute Blitz':" +"The Flower clients will use a simple CNN adapted from 'PyTorch: A 60 Minute " +"Blitz':" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:142 @@ -19868,20 +20206,19 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:144 #: ../../source/tutorial-quickstart-tensorflow.rst:54 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to train the neural network we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to train the neural network we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:150 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses PyTorch. Implementing :code:`NumPyClient` usually means " -"defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"PyTorch. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:156 @@ -19897,8 +20234,7 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:158 #: ../../source/tutorial-quickstart-scikitlearn.rst:121 msgid "" -"update the local model weights with the parameters received from the " -"server" +"update the local model weights with the parameters received from the server" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:160 @@ -19928,22 +20264,22 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:189 #: ../../source/tutorial-quickstart-tensorflow.rst:82 msgid "" -"We can now create an instance of our class :code:`CifarClient` and add " -"one line to actually run this client:" +"We can now create an instance of our class :code:`CifarClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:196 #: ../../source/tutorial-quickstart-tensorflow.rst:90 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"[::]:8080\"` tells " -"the client which server to connect to. In our case we can run the server " -"and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"[::]:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"[::]:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we point " +"the client at." msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:226 @@ -19951,8 +20287,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:122 #: ../../source/tutorial-quickstart-xgboost.rst:533 msgid "" -"Once the server is running we can start the clients in different " -"terminals. Open a new terminal and start the first client:" +"Once the server is running we can start the clients in different terminals. " +"Open a new terminal and start the first client:" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:233 @@ -19966,24 +20302,22 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:252 #: ../../source/tutorial-quickstart-xgboost.rst:546 msgid "" -"Each client will have its own dataset. You should now see how the " -"training does in the very first terminal (the one that started the " -"server):" +"Each client will have its own dataset. You should now see how the training " +"does in the very first terminal (the one that started the server):" msgstr "" #: ../../source/tutorial-quickstart-pytorch.rst:271 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples" -"/quickstart-pytorch`." +"learning system. The full `source code `_ for this example can be found " +"in :code:`examples/quickstart-pytorch`." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with PyTorch Lightning to train an Auto Encoder model on MNIST." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"PyTorch Lightning to train an Auto Encoder model on MNIST." msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:5 @@ -19992,21 +20326,20 @@ msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:10 msgid "" -"Let's build a horizontal federated learning system using PyTorch " -"Lightning and Flower!" +"Let's build a horizontal federated learning system using PyTorch Lightning " +"and Flower!" msgstr "" #: ../../source/tutorial-quickstart-pytorch-lightning.rst:12 msgid "" -"Please refer to the `full code example " -"`_ to learn more." +"Please refer to the `full code example `_ to learn more." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with scikit-learn to train a linear regression model." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"scikit-learn to train a linear regression model." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:5 @@ -20015,24 +20348,23 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:10 msgid "" -"In this tutorial, we will learn how to train a :code:`Logistic " -"Regression` model on MNIST using Flower and scikit-learn." +"In this tutorial, we will learn how to train a :code:`Logistic Regression` " +"model on MNIST using Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:12 msgid "" -"It is recommended to create a virtual environment and run everything " -"within this :doc:`virtualenv `." +"It is recommended to create a virtual environment and run everything within " +"this :doc:`virtualenv `." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:16 msgid "" -"*Clients* are responsible for generating individual model parameter " -"updates for the model based on their local datasets. These updates are " -"then sent to the *server* which will aggregate them to produce an updated" -" global model. Finally, the *server* sends this improved version of the " -"model back to each *client*. A complete cycle of parameters updates is " -"called a *round*." +"*Clients* are responsible for generating individual model parameter updates " +"for the model based on their local datasets. These updates are then sent to " +"the *server* which will aggregate them to produce an updated global model. " +"Finally, the *server* sends this improved version of the model back to each " +"*client*. A complete cycle of parameters updates is called a *round*." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:20 @@ -20053,10 +20385,10 @@ msgstr "" msgid "" "Now that we have all our dependencies installed, let's run a simple " "distributed training with two clients and one server. However, before " -"setting up the client and server, we will define all functionalities that" -" we need for our federated learning setup within :code:`utils.py`. The " -":code:`utils.py` contains different functions defining all the machine " -"learning basics:" +"setting up the client and server, we will define all functionalities that we " +"need for our federated learning setup within :code:`utils.py`. The :code:" +"`utils.py` contains different functions defining all the machine learning " +"basics:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:45 @@ -20085,46 +20417,44 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:52 msgid "" -"Please check out :code:`utils.py` `here " -"`_ for more details. The pre-defined functions are used in" -" the :code:`client.py` and imported. The :code:`client.py` also requires " -"to import several packages such as Flower and scikit-learn:" +"Please check out :code:`utils.py` `here `_ for more details. The pre-" +"defined functions are used in the :code:`client.py` and imported. The :code:" +"`client.py` also requires to import several packages such as Flower and " +"scikit-learn:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:67 msgid "" -"Prior to local training, we need to load the MNIST dataset, a popular " -"image classification dataset of handwritten digits for machine learning, " -"and partition the dataset for FL. This can be conveniently achieved using" -" `Flower Datasets `_. The " -":code:`FederatedDataset.load_partition()` method loads the partitioned " -"training set for each partition ID defined in the :code:`--partition-id` " -"argument." +"Prior to local training, we need to load the MNIST dataset, a popular image " +"classification dataset of handwritten digits for machine learning, and " +"partition the dataset for FL. This can be conveniently achieved using " +"`Flower Datasets `_. The :code:" +"`FederatedDataset.load_partition()` method loads the partitioned training " +"set for each partition ID defined in the :code:`--partition-id` argument." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:95 msgid "" -"Next, the logistic regression model is defined and initialized with " -":code:`utils.set_initial_params()`." +"Next, the logistic regression model is defined and initialized with :code:" +"`utils.set_initial_params()`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:107 msgid "" -"The Flower server interacts with clients through an interface called " -":code:`Client`. When the server selects a particular client for training," -" it sends training instructions over the network. The client receives " -"those instructions and calls one of the :code:`Client` methods to run " -"your code (i.e., to fit the logistic regression we defined earlier)." +"The Flower server interacts with clients through an interface called :code:" +"`Client`. When the server selects a particular client for training, it sends " +"training instructions over the network. The client receives those " +"instructions and calls one of the :code:`Client` methods to run your code (i." +"e., to fit the logistic regression we defined earlier)." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:113 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses scikit-learn. Implementing :code:`NumPyClient` usually " -"means defining the following methods (:code:`set_parameters` is optional " -"though):" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"scikit-learn. Implementing :code:`NumPyClient` usually means defining the " +"following methods (:code:`set_parameters` is optional though):" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:122 @@ -20137,28 +20467,28 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:153 msgid "" -"We can now create an instance of our class :code:`MnistClient` and add " -"one line to actually run this client:" +"We can now create an instance of our class :code:`MnistClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:160 msgid "" -"That's it for the client. We only have to implement :code:`Client` or " -":code:`NumPyClient` and call :code:`fl.client.start_client()`. If you " -"implement a client of type :code:`NumPyClient` you'll need to first call " -"its :code:`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells" -" the client which server to connect to. In our case we can run the server" -" and the client on the same machine, therefore we use " -":code:`\"0.0.0.0:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we pass to the client." +"That's it for the client. We only have to implement :code:`Client` or :code:" +"`NumPyClient` and call :code:`fl.client.start_client()`. If you implement a " +"client of type :code:`NumPyClient` you'll need to first call its :code:" +"`to_client()` method. The string :code:`\"0.0.0.0:8080\"` tells the client " +"which server to connect to. In our case we can run the server and the client " +"on the same machine, therefore we use :code:`\"0.0.0.0:8080\"`. If we run a " +"truly federated workload with the server and clients running on different " +"machines, all that needs to change is the :code:`server_address` we pass to " +"the client." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:169 msgid "" "The following Flower server is a little bit more advanced and returns an " -"evaluation function for the server-side evaluation. First, we import " -"again all required libraries such as Flower and scikit-learn." +"evaluation function for the server-side evaluation. First, we import again " +"all required libraries such as Flower and scikit-learn." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:172 @@ -20167,46 +20497,44 @@ msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:185 msgid "" -"The number of federated learning rounds is set in :code:`fit_round()` and" -" the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " +"The number of federated learning rounds is set in :code:`fit_round()` and " +"the evaluation is defined in :code:`get_evaluate_fn()`. The evaluation " "function is called after each federated learning round and gives you " -"information about loss and accuracy. Note that we also make use of Flower" -" Datasets here to load the test split of the MNIST dataset for server-" -"side evaluation." +"information about loss and accuracy. Note that we also make use of Flower " +"Datasets here to load the test split of the MNIST dataset for server-side " +"evaluation." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:213 msgid "" -"The :code:`main` contains the server-side parameter initialization " -":code:`utils.set_initial_params()` as well as the aggregation strategy " -":code:`fl.server.strategy:FedAvg()`. The strategy is the default one, " -"federated averaging (or FedAvg), with two clients and evaluation after " -"each federated learning round. The server can be started with the command" -" :code:`fl.server.start_server(server_address=\"0.0.0.0:8080\", " -"strategy=strategy, config=fl.server.ServerConfig(num_rounds=3))`." +"The :code:`main` contains the server-side parameter initialization :code:" +"`utils.set_initial_params()` as well as the aggregation strategy :code:`fl." +"server.strategy:FedAvg()`. The strategy is the default one, federated " +"averaging (or FedAvg), with two clients and evaluation after each federated " +"learning round. The server can be started with the command :code:`fl.server." +"start_server(server_address=\"0.0.0.0:8080\", strategy=strategy, config=fl." +"server.ServerConfig(num_rounds=3))`." msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:232 msgid "" "With both client and server ready, we can now run everything and see " "federated learning in action. Federated learning systems usually have a " -"server and multiple clients. We, therefore, have to start the server " -"first:" +"server and multiple clients. We, therefore, have to start the server first:" msgstr "" #: ../../source/tutorial-quickstart-scikitlearn.rst:286 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this example can be found in :code:`examples/sklearn-logreg-" -"mnist`." +"learning system. The full `source code `_ for this example can be found in :code:" +"`examples/sklearn-logreg-mnist`." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with TensorFlow to train a MobilNetV2 model on CIFAR-10." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"TensorFlow to train a MobilNetV2 model on CIFAR-10." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:5 @@ -20223,8 +20551,8 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:21 msgid "" -"Since we want to use the Keras API of TensorFlow (TF), we have to install" -" TF as well:" +"Since we want to use the Keras API of TensorFlow (TF), we have to install TF " +"as well:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:31 @@ -20233,25 +20561,24 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:38 msgid "" -"We use the Keras utilities of TF to load CIFAR10, a popular colored image" -" classification dataset for machine learning. The call to " -":code:`tf.keras.datasets.cifar10.load_data()` downloads CIFAR10, caches " -"it locally, and then returns the entire training and test set as NumPy " -"ndarrays." +"We use the Keras utilities of TF to load CIFAR10, a popular colored image " +"classification dataset for machine learning. The call to :code:`tf.keras." +"datasets.cifar10.load_data()` downloads CIFAR10, caches it locally, and then " +"returns the entire training and test set as NumPy ndarrays." msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:47 msgid "" -"Next, we need a model. For the purpose of this tutorial, we use " -"MobilNetV2 with 10 output classes:" +"Next, we need a model. For the purpose of this tutorial, we use MobilNetV2 " +"with 10 output classes:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:60 msgid "" -"Flower provides a convenience class called :code:`NumPyClient` which " -"makes it easier to implement the :code:`Client` interface when your " -"workload uses Keras. The :code:`NumPyClient` interface defines three " -"methods which can be implemented in the following way:" +"Flower provides a convenience class called :code:`NumPyClient` which makes " +"it easier to implement the :code:`Client` interface when your workload uses " +"Keras. The :code:`NumPyClient` interface defines three methods which can be " +"implemented in the following way:" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:135 @@ -20260,23 +20587,22 @@ msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:137 msgid "" -"You should now see how the training does in the very first terminal (the " -"one that started the server):" +"You should now see how the training does in the very first terminal (the one " +"that started the server):" msgstr "" #: ../../source/tutorial-quickstart-tensorflow.rst:169 msgid "" "Congratulations! You've successfully built and run your first federated " -"learning system. The full `source code " -"`_ for this can be found in :code:`examples" -"/quickstart-tensorflow/client.py`." +"learning system. The full `source code `_ for this can be found in :" +"code:`examples/quickstart-tensorflow/client.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:-1 msgid "" -"Check out this Federated Learning quickstart tutorial for using Flower " -"with XGBoost to train classification models on trees." +"Check out this Federated Learning quickstart tutorial for using Flower with " +"XGBoost to train classification models on trees." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:5 @@ -20290,18 +20616,17 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:16 msgid "" "EXtreme Gradient Boosting (**XGBoost**) is a robust and efficient " -"implementation of gradient-boosted decision tree (**GBDT**), that " -"maximises the computational boundaries for boosted tree methods. It's " -"primarily designed to enhance both the performance and computational " -"speed of machine learning models. In XGBoost, trees are constructed " -"concurrently, unlike the sequential approach taken by GBDT." +"implementation of gradient-boosted decision tree (**GBDT**), that maximises " +"the computational boundaries for boosted tree methods. It's primarily " +"designed to enhance both the performance and computational speed of machine " +"learning models. In XGBoost, trees are constructed concurrently, unlike the " +"sequential approach taken by GBDT." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:20 msgid "" "Often, for tabular data on medium-sized datasets with fewer than 10k " -"training examples, XGBoost surpasses the results of deep learning " -"techniques." +"training examples, XGBoost surpasses the results of deep learning techniques." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:23 @@ -20311,30 +20636,30 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:25 msgid "" "Indeed, as the demand for data privacy and decentralized learning grows, " -"there's an increasing requirement to implement federated XGBoost systems " -"for specialised applications, like survival analysis and financial fraud " +"there's an increasing requirement to implement federated XGBoost systems for " +"specialised applications, like survival analysis and financial fraud " "detection." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:27 msgid "" -"Federated learning ensures that raw data remains on the local device, " -"making it an attractive approach for sensitive domains where data " -"security and privacy are paramount. Given the robustness and efficiency " -"of XGBoost, combining it with federated learning offers a promising " -"solution for these specific challenges." +"Federated learning ensures that raw data remains on the local device, making " +"it an attractive approach for sensitive domains where data security and " +"privacy are paramount. Given the robustness and efficiency of XGBoost, " +"combining it with federated learning offers a promising solution for these " +"specific challenges." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:30 msgid "" "In this tutorial we will learn how to train a federated XGBoost model on " "HIGGS dataset using Flower and :code:`xgboost` package. We use a simple " -"example (`full code xgboost-quickstart " -"`_)" -" with two *clients* and one *server* to demonstrate how federated XGBoost" -" works, and then we dive into a more complex example (`full code xgboost-" -"comprehensive `_) to run various experiments." +"example (`full code xgboost-quickstart `_) with two *clients* and one *server* to " +"demonstrate how federated XGBoost works, and then we dive into a more " +"complex example (`full code xgboost-comprehensive `_) to run various " +"experiments." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:37 @@ -20355,16 +20680,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:57 msgid "" -"*Clients* are responsible for generating individual weight-updates for " -"the model based on their local datasets. Now that we have all our " -"dependencies installed, let's run a simple distributed training with two " -"clients and one server." +"*Clients* are responsible for generating individual weight-updates for the " +"model based on their local datasets. Now that we have all our dependencies " +"installed, let's run a simple distributed training with two clients and one " +"server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:60 msgid "" -"In a file called :code:`client.py`, import xgboost, Flower, Flower " -"Datasets and other related functions:" +"In a file called :code:`client.py`, import xgboost, Flower, Flower Datasets " +"and other related functions:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:87 @@ -20373,15 +20698,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:89 msgid "" -"Prior to local training, we require loading the HIGGS dataset from Flower" -" Datasets and conduct data partitioning for FL:" +"Prior to local training, we require loading the HIGGS dataset from Flower " +"Datasets and conduct data partitioning for FL:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:102 msgid "" "In this example, we split the dataset into two partitions with uniform " -"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load " -"the partition for the given client based on :code:`node_id`:" +"distribution (:code:`IidPartitioner(num_partitions=2)`). Then, we load the " +"partition for the given client based on :code:`node_id`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:121 @@ -20392,8 +20717,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:134 msgid "" -"The functions of :code:`train_test_split` and " -":code:`transform_dataset_to_dmatrix` are defined as below:" +"The functions of :code:`train_test_split` and :code:" +"`transform_dataset_to_dmatrix` are defined as below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:158 @@ -20402,10 +20727,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:174 msgid "" -"The :code:`num_local_round` represents the number of iterations for local" -" tree boost. We use CPU for the training in default. One can shift it to " -"GPU by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as " -"evaluation metric." +"The :code:`num_local_round` represents the number of iterations for local " +"tree boost. We use CPU for the training in default. One can shift it to GPU " +"by setting :code:`tree_method` to :code:`gpu_hist`. We use AUC as evaluation " +"metric." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:181 @@ -20414,86 +20739,85 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:183 msgid "" -"After loading the dataset we define the Flower client. We follow the " -"general rule to define :code:`XgbClient` class inherited from " -":code:`fl.client.Client`." +"After loading the dataset we define the Flower client. We follow the general " +"rule to define :code:`XgbClient` class inherited from :code:`fl.client." +"Client`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:193 msgid "" "The :code:`self.bst` is used to keep the Booster objects that remain " "consistent across rounds, allowing them to store predictions from trees " -"integrated in earlier rounds and maintain other essential data structures" -" for training." +"integrated in earlier rounds and maintain other essential data structures " +"for training." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:196 msgid "" -"Then, we override :code:`get_parameters`, :code:`fit` and " -":code:`evaluate` methods insides :code:`XgbClient` class as follows." +"Then, we override :code:`get_parameters`, :code:`fit` and :code:`evaluate` " +"methods insides :code:`XgbClient` class as follows." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:210 msgid "" "Unlike neural network training, XGBoost trees are not started from a " -"specified random weights. In this case, we do not use " -":code:`get_parameters` and :code:`set_parameters` to initialise model " -"parameters for XGBoost. As a result, let's return an empty tensor in " -":code:`get_parameters` when it is called by the server at the first " -"round." +"specified random weights. In this case, we do not use :code:`get_parameters` " +"and :code:`set_parameters` to initialise model parameters for XGBoost. As a " +"result, let's return an empty tensor in :code:`get_parameters` when it is " +"called by the server at the first round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:251 msgid "" -"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build " -"up the first set of trees. the returned Booster object and config are " -"stored in :code:`self.bst` and :code:`self.config`, respectively. From " -"the second round, we load the global model sent from server to " -":code:`self.bst`, and then update model weights on local training data " -"with function :code:`local_boost` as follows:" +"In :code:`fit`, at the first round, we call :code:`xgb.train()` to build up " +"the first set of trees. the returned Booster object and config are stored " +"in :code:`self.bst` and :code:`self.config`, respectively. From the second " +"round, we load the global model sent from server to :code:`self.bst`, and " +"then update model weights on local training data with function :code:" +"`local_boost` as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:269 msgid "" -"Given :code:`num_local_round`, we update trees by calling " -":code:`self.bst.update` method. After training, the last " -":code:`N=num_local_round` trees will be extracted to send to the server." +"Given :code:`num_local_round`, we update trees by calling :code:`self.bst." +"update` method. After training, the last :code:`N=num_local_round` trees " +"will be extracted to send to the server." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:291 msgid "" -"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to " -"conduct evaluation on valid set. The AUC value will be returned." +"In :code:`evaluate`, we call :code:`self.bst.eval_set` function to conduct " +"evaluation on valid set. The AUC value will be returned." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:294 msgid "" -"Now, we can create an instance of our class :code:`XgbClient` and add one" -" line to actually run this client:" +"Now, we can create an instance of our class :code:`XgbClient` and add one " +"line to actually run this client:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:300 msgid "" -"That's it for the client. We only have to implement :code:`Client`and " -"call :code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` " -"tells the client which server to connect to. In our case we can run the " -"server and the client on the same machine, therefore we use " -":code:`\"[::]:8080\"`. If we run a truly federated workload with the " -"server and clients running on different machines, all that needs to " -"change is the :code:`server_address` we point the client at." +"That's it for the client. We only have to implement :code:`Client`and call :" +"code:`fl.client.start_client()`. The string :code:`\"[::]:8080\"` tells the " +"client which server to connect to. In our case we can run the server and the " +"client on the same machine, therefore we use :code:`\"[::]:8080\"`. If we " +"run a truly federated workload with the server and clients running on " +"different machines, all that needs to change is the :code:`server_address` " +"we point the client at." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:311 msgid "" "These updates are then sent to the *server* which will aggregate them to " -"produce a better model. Finally, the *server* sends this improved version" -" of the model back to each *client* to finish a complete FL round." +"produce a better model. Finally, the *server* sends this improved version of " +"the model back to each *client* to finish a complete FL round." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:314 msgid "" -"In a file named :code:`server.py`, import Flower and FedXgbBagging from " -":code:`flwr.server.strategy`." +"In a file named :code:`server.py`, import Flower and FedXgbBagging from :" +"code:`flwr.server.strategy`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:316 @@ -20502,9 +20826,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:339 msgid "" -"We use two clients for this example. An " -":code:`evaluate_metrics_aggregation` function is defined to collect and " -"wighted average the AUC values from clients." +"We use two clients for this example. An :code:`evaluate_metrics_aggregation` " +"function is defined to collect and wighted average the AUC values from " +"clients." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:342 @@ -20517,16 +20841,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:356 msgid "" -"You must be curious about how bagging aggregation works. Let's look into " -"the details." +"You must be curious about how bagging aggregation works. Let's look into the " +"details." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:358 msgid "" -"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define " -":code:`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`." -" Then, we override the :code:`aggregate_fit`, :code:`aggregate_evaluate` " -"and :code:`evaluate` methods as follows:" +"In file :code:`flwr.server.strategy.fedxgb_bagging.py`, we define :code:" +"`FedXgbBagging` inherited from :code:`flwr.server.strategy.FedAvg`. Then, we " +"override the :code:`aggregate_fit`, :code:`aggregate_evaluate` and :code:" +"`evaluate` methods as follows:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:454 @@ -20538,10 +20862,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:513 msgid "" "In this function, we first fetch the number of trees and the number of " -"parallel trees for the current and previous model by calling " -":code:`_get_tree_nums`. Then, the fetched information will be aggregated." -" After that, the trees (containing model weights) are aggregated to " -"generate a new tree model." +"parallel trees for the current and previous model by calling :code:" +"`_get_tree_nums`. Then, the fetched information will be aggregated. After " +"that, the trees (containing model weights) are aggregated to generate a new " +"tree model." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:518 @@ -20557,16 +20881,16 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:585 msgid "" "Congratulations! You've successfully built and run your first federated " -"XGBoost system. The AUC values can be checked in " -":code:`metrics_distributed`. One can see that the average AUC increases " -"over FL rounds." +"XGBoost system. The AUC values can be checked in :code:" +"`metrics_distributed`. One can see that the average AUC increases over FL " +"rounds." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:590 msgid "" -"The full `source code `_ for this example can be found in :code:`examples" -"/xgboost-quickstart`." +"The full `source code `_ for this example can be found in :code:`examples/" +"xgboost-quickstart`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:594 @@ -20575,15 +20899,15 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:596 msgid "" -"Now that you have known how federated XGBoost work with Flower, it's time" -" to run some more comprehensive experiments by customising the " -"experimental settings. In the xgboost-comprehensive example (`full code " -"`_), we provide more options to define various experimental" -" setups, including aggregation strategies, data partitioning and " -"centralised/distributed evaluation. We also support :doc:`Flower " -"simulation ` making it easy to simulate large " -"client cohorts in a resource-aware manner. Let's take a look!" +"Now that you have known how federated XGBoost work with Flower, it's time to " +"run some more comprehensive experiments by customising the experimental " +"settings. In the xgboost-comprehensive example (`full code `_), we provide " +"more options to define various experimental setups, including aggregation " +"strategies, data partitioning and centralised/distributed evaluation. We " +"also support :doc:`Flower simulation ` making it " +"easy to simulate large client cohorts in a resource-aware manner. Let's take " +"a look!" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:603 @@ -20592,41 +20916,40 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:605 msgid "" -"In addition to bagging aggregation, we offer a cyclic training scheme, " -"which performs FL in a client-by-client fashion. Instead of aggregating " -"multiple clients, there is only one single client participating in the " -"training per round in the cyclic training scenario. The trained local " -"XGBoost trees will be passed to the next client as an initialised model " -"for next round's boosting." +"In addition to bagging aggregation, we offer a cyclic training scheme, which " +"performs FL in a client-by-client fashion. Instead of aggregating multiple " +"clients, there is only one single client participating in the training per " +"round in the cyclic training scenario. The trained local XGBoost trees will " +"be passed to the next client as an initialised model for next round's " +"boosting." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:609 msgid "" -"To do this, we first customise a :code:`ClientManager` in " -":code:`server_utils.py`:" +"To do this, we first customise a :code:`ClientManager` in :code:" +"`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:649 msgid "" -"The customised :code:`ClientManager` samples all available clients in " -"each FL round based on the order of connection to the server. Then, we " -"define a new strategy :code:`FedXgbCyclic` in " -":code:`flwr.server.strategy.fedxgb_cyclic.py`, in order to sequentially " -"select only one client in given round and pass the received model to next" -" client." +"The customised :code:`ClientManager` samples all available clients in each " +"FL round based on the order of connection to the server. Then, we define a " +"new strategy :code:`FedXgbCyclic` in :code:`flwr.server.strategy." +"fedxgb_cyclic.py`, in order to sequentially select only one client in given " +"round and pass the received model to next client." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:690 msgid "" "Unlike the original :code:`FedAvg`, we don't perform aggregation here. " -"Instead, we just make a copy of the received client model as global model" -" by overriding :code:`aggregate_fit`." +"Instead, we just make a copy of the received client model as global model by " +"overriding :code:`aggregate_fit`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:693 msgid "" -"Also, the customised :code:`configure_fit` and :code:`configure_evaluate`" -" methods ensure the clients to be sequentially selected given FL round:" +"Also, the customised :code:`configure_fit` and :code:`configure_evaluate` " +"methods ensure the clients to be sequentially selected given FL round:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:757 @@ -20635,11 +20958,11 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:759 msgid "" -"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner`" -" to instantiate the data partitioner based on the given " -":code:`num_partitions` and :code:`partitioner_type`. Currently, we " -"provide four supported partitioner type to simulate the uniformity/non-" -"uniformity in data quantity (uniform, linear, square, exponential)." +"In :code:`dataset.py`, we have a function :code:`instantiate_partitioner` to " +"instantiate the data partitioner based on the given :code:`num_partitions` " +"and :code:`partitioner_type`. Currently, we provide four supported " +"partitioner type to simulate the uniformity/non-uniformity in data quantity " +"(uniform, linear, square, exponential)." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:790 @@ -20648,23 +20971,23 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:792 msgid "" -"To facilitate centralised evaluation, we define a function in " -":code:`server_utils.py`:" +"To facilitate centralised evaluation, we define a function in :code:" +"`server_utils.py`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:824 msgid "" -"This function returns a evaluation function which instantiates a " -":code:`Booster` object and loads the global model weights to it. The " -"evaluation is conducted by calling :code:`eval_set()` method, and the " -"tested AUC value is reported." +"This function returns a evaluation function which instantiates a :code:" +"`Booster` object and loads the global model weights to it. The evaluation is " +"conducted by calling :code:`eval_set()` method, and the tested AUC value is " +"reported." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:827 msgid "" -"As for distributed evaluation on the clients, it's same as the quick-" -"start example by overriding the :code:`evaluate()` method insides the " -":code:`XgbClient` class in :code:`client_utils.py`." +"As for distributed evaluation on the clients, it's same as the quick-start " +"example by overriding the :code:`evaluate()` method insides the :code:" +"`XgbClient` class in :code:`client_utils.py`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:831 @@ -20674,21 +20997,21 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:832 msgid "" "We also provide an example code (:code:`sim.py`) to use the simulation " -"capabilities of Flower to simulate federated XGBoost training on either a" -" single machine or a cluster of machines." +"capabilities of Flower to simulate federated XGBoost training on either a " +"single machine or a cluster of machines." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:866 msgid "" -"After importing all required packages, we define a :code:`main()` " -"function to perform the simulation process:" +"After importing all required packages, we define a :code:`main()` function " +"to perform the simulation process:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:921 msgid "" "We first load the dataset and perform data partitioning, and the pre-" -"processed data is stored in a :code:`list`. After the simulation begins, " -"the clients won't need to pre-process their partitions again." +"processed data is stored in a :code:`list`. After the simulation begins, the " +"clients won't need to pre-process their partitions again." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:924 @@ -20697,8 +21020,8 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:975 msgid "" -"After that, we start the simulation by calling " -":code:`fl.simulation.start_simulation`:" +"After that, we start the simulation by calling :code:`fl.simulation." +"start_simulation`:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:995 @@ -20713,18 +21036,18 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1040 msgid "" -"In :code:`utils.py`, we define the arguments parsers for clients, server " -"and simulation, allowing users to specify different experimental " -"settings. Let's first see the sever side:" +"In :code:`utils.py`, we define the arguments parsers for clients, server and " +"simulation, allowing users to specify different experimental settings. Let's " +"first see the sever side:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1086 msgid "" "This allows user to specify training strategies / the number of total " -"clients / FL rounds / participating clients / clients for evaluation, and" -" evaluation fashion. Note that with :code:`--centralised-eval`, the sever" -" will do centralised evaluation and all functionalities for client " -"evaluation will be disabled." +"clients / FL rounds / participating clients / clients for evaluation, and " +"evaluation fashion. Note that with :code:`--centralised-eval`, the sever " +"will do centralised evaluation and all functionalities for client evaluation " +"will be disabled." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1090 @@ -20733,11 +21056,10 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1144 msgid "" -"This defines various options for client data partitioning. Besides, " -"clients also have an option to conduct evaluation on centralised test set" -" by setting :code:`--centralised-eval`, as well as an option to perform " -"scaled learning rate based on the number of clients by setting :code" -":`--scaled-lr`." +"This defines various options for client data partitioning. Besides, clients " +"also have an option to conduct evaluation on centralised test set by " +"setting :code:`--centralised-eval`, as well as an option to perform scaled " +"learning rate based on the number of clients by setting :code:`--scaled-lr`." msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1148 @@ -20754,9 +21076,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1231 msgid "" -"To run a centralised evaluated experiment with bagging strategy on 5 " -"clients with exponential distribution for 50 rounds, we first start the " -"server as below:" +"To run a centralised evaluated experiment with bagging strategy on 5 clients " +"with exponential distribution for 50 rounds, we first start the server as " +"below:" msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1238 @@ -20769,9 +21091,9 @@ msgstr "" #: ../../source/tutorial-quickstart-xgboost.rst:1250 msgid "" -"The full `code `_ for this comprehensive example can be found in" -" :code:`examples/xgboost-comprehensive`." +"The full `code `_ for this comprehensive example can be found in :code:" +"`examples/xgboost-comprehensive`." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:9 @@ -20782,19 +21104,18 @@ msgstr "" msgid "" "Welcome to the third part of the Flower federated learning tutorial. In " "previous parts of this tutorial, we introduced federated learning with " -"PyTorch and Flower (`part 1 `__) and we learned how strategies " -"can be used to customize the execution on both the server and the clients" -" (`part 2 `__)." +"PyTorch and Flower (`part 1 `__) and we learned how strategies can be " +"used to customize the execution on both the server and the clients (`part 2 " +"`__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:13 msgid "" -"In this notebook, we'll continue to customize the federated learning " -"system we built previously by creating a custom version of FedAvg (again," -" using `Flower `__ and `PyTorch " -"`__)." +"In this notebook, we'll continue to customize the federated learning system " +"we built previously by creating a custom version of FedAvg (again, using " +"`Flower `__ and `PyTorch `__)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:15 @@ -20802,11 +21123,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:15 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:15 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the Flower community on Slack to connect, ask questions, and get help: " -"`Join Slack `__ 🌼 We'd love to hear from " -"you in the ``#introductions`` channel! And if anything is unclear, head " -"over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"Flower community on Slack to connect, ask questions, and get help: `Join " +"Slack `__ 🌼 We'd love to hear from you in the " +"``#introductions`` channel! And if anything is unclear, head over to the " +"``#questions`` channel." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:17 @@ -20852,14 +21173,14 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:102 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:101 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware acclerator: " -"GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware acclerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:114 @@ -20871,11 +21192,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:116 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:116 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``. We introduce a new parameter" -" ``num_clients`` which allows us to call ``load_datasets`` with different" -" numbers of clients." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``. We introduce a new parameter " +"``num_clients`` which allows us to call ``load_datasets`` with different " +"numbers of clients." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:167 @@ -20888,8 +21209,8 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:170 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:169 msgid "" -"Let's continue with the usual model definition (including " -"``set_parameters`` and ``get_parameters``), training and test functions:" +"Let's continue with the usual model definition (including ``set_parameters`` " +"and ``get_parameters``), training and test functions:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:258 @@ -20900,10 +21221,10 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:260 #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:260 msgid "" -"To implement the Flower client, we (again) create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``. Here, we also pass the " -"``cid`` to the client and use it log additional details:" +"To implement the Flower client, we (again) create a subclass of ``flwr." +"client.NumPyClient`` and implement the three methods ``get_parameters``, " +"``fit``, and ``evaluate``. Here, we also pass the ``cid`` to the client and " +"use it log additional details:" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:308 @@ -20916,11 +21237,11 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:341 msgid "" -"Let’s overwrite the ``configure_fit`` method such that it passes a higher" -" learning rate (potentially also other hyperparameters) to the optimizer " -"of a fraction of the clients. We will keep the sampling of the clients as" -" it is in ``FedAvg`` and then change the configuration dictionary (one of" -" the ``FitIns`` attributes)." +"Let’s overwrite the ``configure_fit`` method such that it passes a higher " +"learning rate (potentially also other hyperparameters) to the optimizer of a " +"fraction of the clients. We will keep the sampling of the clients as it is " +"in ``FedAvg`` and then change the configuration dictionary (one of the " +"``FitIns`` attributes)." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:507 @@ -20937,13 +21258,13 @@ msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:536 msgid "" -"In this notebook, we’ve seen how to implement a custom strategy. A custom" -" strategy enables granular control over client node configuration, result" -" aggregation, and more. To define a custom strategy, you only have to " -"overwrite the abstract methods of the (abstract) base class ``Strategy``." -" To make custom strategies even more powerful, you can pass custom " -"functions to the constructor of your new class (``__init__``) and then " -"call these functions whenever needed." +"In this notebook, we’ve seen how to implement a custom strategy. A custom " +"strategy enables granular control over client node configuration, result " +"aggregation, and more. To define a custom strategy, you only have to " +"overwrite the abstract methods of the (abstract) base class ``Strategy``. To " +"make custom strategies even more powerful, you can pass custom functions to " +"the constructor of your new class (``__init__``) and then call these " +"functions whenever needed." msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:550 @@ -20952,8 +21273,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:715 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:369 msgid "" -"Before you continue, make sure to join the Flower community on Slack: " -"`Join Slack `__" +"Before you continue, make sure to join the Flower community on Slack: `Join " +"Slack `__" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:552 @@ -20962,16 +21283,15 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:717 #: ../../source/tutorial-series-what-is-federated-learning.ipynb:371 msgid "" -"There's a dedicated ``#questions`` channel if you need help, but we'd " -"also love to hear who you are in ``#introductions``!" +"There's a dedicated ``#questions`` channel if you need help, but we'd also " +"love to hear who you are in ``#introductions``!" msgstr "" #: ../../source/tutorial-series-build-a-strategy-from-scratch-pytorch.ipynb:554 msgid "" -"The `Flower Federated Learning Tutorial - Part 4 " -"`__ introduces ``Client``, the flexible API underlying " -"``NumPyClient``." +"The `Flower Federated Learning Tutorial - Part 4 `__ introduces " +"``Client``, the flexible API underlying ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:9 @@ -20980,26 +21300,26 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:11 msgid "" -"Welcome to the fourth part of the Flower federated learning tutorial. In " -"the previous parts of this tutorial, we introduced federated learning " -"with PyTorch and Flower (`part 1 `__), we learned how " -"strategies can be used to customize the execution on both the server and " -"the clients (`part 2 `__), and we built our own " -"custom strategy from scratch (`part 3 `__)." +"Welcome to the fourth part of the Flower federated learning tutorial. In the " +"previous parts of this tutorial, we introduced federated learning with " +"PyTorch and Flower (`part 1 `__), we learned how strategies can be used " +"to customize the execution on both the server and the clients (`part 2 " +"`__), and we built our own custom strategy from scratch (`part " +"3 `__)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:14 msgid "" -"In this notebook, we revisit ``NumPyClient`` and introduce a new " -"baseclass for building clients, simply named ``Client``. In previous " -"parts of this tutorial, we've based our client on ``NumPyClient``, a " -"convenience class which makes it easy to work with machine learning " -"libraries that have good NumPy interoperability. With ``Client``, we gain" -" a lot of flexibility that we didn't have before, but we'll also have to " -"do a few things the we didn't have to do before." +"In this notebook, we revisit ``NumPyClient`` and introduce a new baseclass " +"for building clients, simply named ``Client``. In previous parts of this " +"tutorial, we've based our client on ``NumPyClient``, a convenience class " +"which makes it easy to work with machine learning libraries that have good " +"NumPy interoperability. With ``Client``, we gain a lot of flexibility that " +"we didn't have before, but we'll also have to do a few things the we didn't " +"have to do before." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:18 @@ -21015,9 +21335,9 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:117 msgid "" -"Let's now load the CIFAR-10 training and test set, partition them into " -"ten smaller datasets (each split into training and validation set), and " -"wrap everything in their own ``DataLoader``." +"Let's now load the CIFAR-10 training and test set, partition them into ten " +"smaller datasets (each split into training and validation set), and wrap " +"everything in their own ``DataLoader``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:259 @@ -21026,10 +21346,10 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:261 msgid "" -"So far, we've implemented our client by subclassing " -"``flwr.client.NumPyClient``. The three methods we implemented are " -"``get_parameters``, ``fit``, and ``evaluate``. Finally, we wrap the " -"creation of instances of this class in a function called ``client_fn``:" +"So far, we've implemented our client by subclassing ``flwr.client." +"NumPyClient``. The three methods we implemented are ``get_parameters``, " +"``fit``, and ``evaluate``. Finally, we wrap the creation of instances of " +"this class in a function called ``client_fn``:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:309 @@ -21051,25 +21371,24 @@ msgid "" "Let's dive a little bit deeper and discuss how Flower executes this " "simulation. Whenever a client is selected to do some work, " "``start_simulation`` calls the function ``numpyclient_fn`` to create an " -"instance of our ``FlowerNumPyClient`` (along with loading the model and " -"the data)." +"instance of our ``FlowerNumPyClient`` (along with loading the model and the " +"data)." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:343 msgid "" "But here's the perhaps surprising part: Flower doesn't actually use the " -"``FlowerNumPyClient`` object directly. Instead, it wraps the object to " -"makes it look like a subclass of ``flwr.client.Client``, not " -"``flwr.client.NumPyClient``. In fact, the Flower core framework doesn't " -"know how to handle ``NumPyClient``'s, it only knows how to handle " -"``Client``'s. ``NumPyClient`` is just a convenience abstraction built on " -"top of ``Client``." +"``FlowerNumPyClient`` object directly. Instead, it wraps the object to makes " +"it look like a subclass of ``flwr.client.Client``, not ``flwr.client." +"NumPyClient``. In fact, the Flower core framework doesn't know how to handle " +"``NumPyClient``'s, it only knows how to handle ``Client``'s. ``NumPyClient`` " +"is just a convenience abstraction built on top of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:345 msgid "" -"Instead of building on top of ``NumPyClient``, we can directly build on " -"top of ``Client``." +"Instead of building on top of ``NumPyClient``, we can directly build on top " +"of ``Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:357 @@ -21078,14 +21397,13 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:359 msgid "" -"Let's try to do the same thing using ``Client`` instead of " -"``NumPyClient``." +"Let's try to do the same thing using ``Client`` instead of ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:465 msgid "" -"Before we discuss the code in more detail, let's try to run it! Gotta " -"make sure our new ``Client``-based client works, right?" +"Before we discuss the code in more detail, let's try to run it! Gotta make " +"sure our new ``Client``-based client works, right?" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:490 @@ -21096,40 +21414,40 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:492 msgid "" -"First of all, it's more code. But why? The difference comes from the fact" -" that ``Client`` expects us to take care of parameter serialization and " -"deserialization. For Flower to be able to send parameters over the " -"network, it eventually needs to turn these parameters into ``bytes``. " -"Turning parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " +"First of all, it's more code. But why? The difference comes from the fact " +"that ``Client`` expects us to take care of parameter serialization and " +"deserialization. For Flower to be able to send parameters over the network, " +"it eventually needs to turn these parameters into ``bytes``. Turning " +"parameters (e.g., NumPy ``ndarray``'s) into raw bytes is called " "serialization. Turning raw bytes into something more useful (like NumPy " -"``ndarray``'s) is called deserialization. Flower needs to do both: it " -"needs to serialize parameters on the server-side and send them to the " -"client, the client needs to deserialize them to use them for local " -"training, and then serialize the updated parameters again to send them " -"back to the server, which (finally!) deserializes them again in order to " -"aggregate them with the updates received from other clients." +"``ndarray``'s) is called deserialization. Flower needs to do both: it needs " +"to serialize parameters on the server-side and send them to the client, the " +"client needs to deserialize them to use them for local training, and then " +"serialize the updated parameters again to send them back to the server, " +"which (finally!) deserializes them again in order to aggregate them with the " +"updates received from other clients." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:495 msgid "" "The only *real* difference between Client and NumPyClient is that " -"NumPyClient takes care of serialization and deserialization for you. It " -"can do so because it expects you to return parameters as NumPy ndarray's," -" and it knows how to handle these. This makes working with machine " -"learning libraries that have good NumPy support (most of them) a breeze." +"NumPyClient takes care of serialization and deserialization for you. It can " +"do so because it expects you to return parameters as NumPy ndarray's, and it " +"knows how to handle these. This makes working with machine learning " +"libraries that have good NumPy support (most of them) a breeze." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:497 msgid "" -"In terms of API, there's one major difference: all methods in Client take" -" exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return " -"exactly one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " +"In terms of API, there's one major difference: all methods in Client take " +"exactly one argument (e.g., ``FitIns`` in ``Client.fit``) and return exactly " +"one value (e.g., ``FitRes`` in ``Client.fit``). The methods in " "``NumPyClient`` on the other hand have multiple arguments (e.g., " -"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return" -" values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " -"``NumPyClient.fit``) if there are multiple things to handle. These " -"``*Ins`` and ``*Res`` objects in ``Client`` wrap all the individual " -"values you're used to from ``NumPyClient``." +"``parameters`` and ``config`` in ``NumPyClient.fit``) and multiple return " +"values (e.g., ``parameters``, ``num_example``, and ``metrics`` in " +"``NumPyClient.fit``) if there are multiple things to handle. These ``*Ins`` " +"and ``*Res`` objects in ``Client`` wrap all the individual values you're " +"used to from ``NumPyClient``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:510 @@ -21146,17 +21464,16 @@ msgstr "" msgid "" "But first what is serialization? Serialization is just the process of " "converting an object into raw bytes, and equally as important, " -"deserialization is the process of converting raw bytes back into an " -"object. This is very useful for network communication. Indeed, without " +"deserialization is the process of converting raw bytes back into an object. " +"This is very useful for network communication. Indeed, without " "serialization, you could not just a Python object through the internet." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:516 msgid "" -"Federated Learning relies heavily on internet communication for training " -"by sending Python objects back and forth between the clients and the " -"server. This means that serialization is an essential part of Federated " -"Learning." +"Federated Learning relies heavily on internet communication for training by " +"sending Python objects back and forth between the clients and the server. " +"This means that serialization is an essential part of Federated Learning." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:518 @@ -21176,15 +21493,15 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:523 msgid "" -"This is where the real serialization/deserialization will happen, " -"especially in ``ndarray_to_sparse_bytes`` for serialization and " +"This is where the real serialization/deserialization will happen, especially " +"in ``ndarray_to_sparse_bytes`` for serialization and " "``sparse_bytes_to_ndarray`` for deserialization." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:525 msgid "" -"Note that we imported the ``scipy.sparse`` library in order to convert " -"our arrays." +"Note that we imported the ``scipy.sparse`` library in order to convert our " +"arrays." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:613 @@ -21193,30 +21510,28 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:615 msgid "" -"To be able to serialize our ``ndarray``\\ s into sparse parameters, we " -"will just have to call our custom functions in our " -"``flwr.client.Client``." +"To be able to serialize our ``ndarray``\\ s into sparse parameters, we will " +"just have to call our custom functions in our ``flwr.client.Client``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:617 msgid "" "Indeed, in ``get_parameters`` we need to serialize the parameters we got " -"from our network using our custom ``ndarrays_to_sparse_parameters`` " -"defined above." +"from our network using our custom ``ndarrays_to_sparse_parameters`` defined " +"above." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:619 msgid "" "In ``fit``, we first need to deserialize the parameters coming from the " -"server using our custom ``sparse_parameters_to_ndarrays`` and then we " -"need to serialize our local results with " -"``ndarrays_to_sparse_parameters``." +"server using our custom ``sparse_parameters_to_ndarrays`` and then we need " +"to serialize our local results with ``ndarrays_to_sparse_parameters``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:621 msgid "" -"In ``evaluate``, we will only need to deserialize the global parameters " -"with our custom function." +"In ``evaluate``, we will only need to deserialize the global parameters with " +"our custom function." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:725 @@ -21225,11 +21540,10 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:727 msgid "" -"For this example, we will just use ``FedAvg`` as a strategy. To change " -"the serialization and deserialization here, we only need to reimplement " -"the ``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other" -" functions of the strategy will be inherited from the super class " -"``FedAvg``." +"For this example, we will just use ``FedAvg`` as a strategy. To change the " +"serialization and deserialization here, we only need to reimplement the " +"``evaluate`` and ``aggregate_fit`` functions of ``FedAvg``. The other " +"functions of the strategy will be inherited from the super class ``FedAvg``." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:729 @@ -21254,19 +21568,19 @@ msgstr "" msgid "" "In this part of the tutorial, we've seen how we can build clients by " "subclassing either ``NumPyClient`` or ``Client``. ``NumPyClient`` is a " -"convenience abstraction that makes it easier to work with machine " -"learning libraries that have good NumPy interoperability. ``Client`` is a" -" more flexible abstraction that allows us to do things that are not " -"possible in ``NumPyClient``. In order to do so, it requires us to handle " -"parameter serialization and deserialization ourselves." +"convenience abstraction that makes it easier to work with machine learning " +"libraries that have good NumPy interoperability. ``Client`` is a more " +"flexible abstraction that allows us to do things that are not possible in " +"``NumPyClient``. In order to do so, it requires us to handle parameter " +"serialization and deserialization ourselves." msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:952 msgid "" -"This is the final part of the Flower tutorial (for now!), " -"congratulations! You're now well equipped to understand the rest of the " -"documentation. There are many topics we didn't cover in the tutorial, we " -"recommend the following resources:" +"This is the final part of the Flower tutorial (for now!), congratulations! " +"You're now well equipped to understand the rest of the documentation. There " +"are many topics we didn't cover in the tutorial, we recommend the following " +"resources:" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:954 @@ -21275,20 +21589,20 @@ msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:955 msgid "" -"`Check out Flower Code Examples " -"`__" +"`Check out Flower Code Examples `__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:956 msgid "" -"`Use Flower Baselines for your research " -"`__" +"`Use Flower Baselines for your research `__" msgstr "" #: ../../source/tutorial-series-customize-the-client-pytorch.ipynb:957 msgid "" -"`Watch Flower Summit 2023 videos `__" +"`Watch Flower Summit 2023 videos `__" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:9 @@ -21303,10 +21617,9 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:13 msgid "" "In this notebook, we'll build a federated learning system using Flower, " -"`Flower Datasets `__ and PyTorch. In " -"part 1, we use PyTorch for the model training pipeline and data loading. " -"In part 2, we continue to federate the PyTorch-based pipeline using " -"Flower." +"`Flower Datasets `__ and PyTorch. In part " +"1, we use PyTorch for the model training pipeline and data loading. In part " +"2, we continue to federate the PyTorch-based pipeline using Flower." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:17 @@ -21323,20 +21636,19 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:45 msgid "" "Next, we install the necessary packages for PyTorch (``torch`` and " -"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower " -"(``flwr``):" +"``torchvision``), Flower Datasets (``flwr-datasets``) and Flower (``flwr``):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:105 msgid "" -"It is possible to switch to a runtime that has GPU acceleration enabled " -"(on Google Colab: ``Runtime > Change runtime type > Hardware accelerator:" -" GPU > Save``). Note, however, that Google Colab is not always able to " -"offer GPU acceleration. If you see an error related to GPU availability " -"in one of the following sections, consider switching back to CPU-based " -"execution by setting ``DEVICE = torch.device(\"cpu\")``. If the runtime " -"has GPU acceleration enabled, you should see the output ``Training on " -"cuda``, otherwise it'll say ``Training on cpu``." +"It is possible to switch to a runtime that has GPU acceleration enabled (on " +"Google Colab: ``Runtime > Change runtime type > Hardware accelerator: GPU > " +"Save``). Note, however, that Google Colab is not always able to offer GPU " +"acceleration. If you see an error related to GPU availability in one of the " +"following sections, consider switching back to CPU-based execution by " +"setting ``DEVICE = torch.device(\"cpu\")``. If the runtime has GPU " +"acceleration enabled, you should see the output ``Training on cuda``, " +"otherwise it'll say ``Training on cpu``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:118 @@ -21345,51 +21657,50 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:120 msgid "" -"Federated learning can be applied to many different types of tasks across" -" different domains. In this tutorial, we introduce federated learning by " -"training a simple convolutional neural network (CNN) on the popular " -"CIFAR-10 dataset. CIFAR-10 can be used to train image classifiers that " -"distinguish between images from ten different classes: 'airplane', " -"'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and " -"'truck'." +"Federated learning can be applied to many different types of tasks across " +"different domains. In this tutorial, we introduce federated learning by " +"training a simple convolutional neural network (CNN) on the popular CIFAR-10 " +"dataset. CIFAR-10 can be used to train image classifiers that distinguish " +"between images from ten different classes: 'airplane', 'automobile', 'bird', " +"'cat', 'deer', 'dog', 'frog', 'horse', 'ship', and 'truck'." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:131 msgid "" "We simulate having multiple datasets from multiple organizations (also " -"called the \"cross-silo\" setting in federated learning) by splitting the" -" original CIFAR-10 dataset into multiple partitions. Each partition will " -"represent the data from a single organization. We're doing this purely " -"for experimentation purposes, in the real world there's no need for data " -"splitting because each organization already has their own data (so the " -"data is naturally partitioned)." +"called the \"cross-silo\" setting in federated learning) by splitting the " +"original CIFAR-10 dataset into multiple partitions. Each partition will " +"represent the data from a single organization. We're doing this purely for " +"experimentation purposes, in the real world there's no need for data " +"splitting because each organization already has their own data (so the data " +"is naturally partitioned)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:133 msgid "" -"Each organization will act as a client in the federated learning system. " -"So having ten organizations participate in a federation means having ten " +"Each organization will act as a client in the federated learning system. So " +"having ten organizations participate in a federation means having ten " "clients connected to the federated learning server." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:144 msgid "" "Let's now create the Federated Dataset abstraction that from ``flwr-" -"datasets`` that partitions the CIFAR-10. We will create small training " -"and test set for each edge device and wrap each of them into a PyTorch " +"datasets`` that partitions the CIFAR-10. We will create small training and " +"test set for each edge device and wrap each of them into a PyTorch " "``DataLoader``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:198 msgid "" "We now have a list of ten training sets and ten validation sets " -"(``trainloaders`` and ``valloaders``) representing the data of ten " -"different organizations. Each ``trainloader``/``valloader`` pair contains" -" 4000 training examples and 1000 validation examples. There's also a " -"single ``testloader`` (we did not split the test set). Again, this is " -"only necessary for building research or educational systems, actual " -"federated learning systems have their data naturally distributed across " -"multiple partitions." +"(``trainloaders`` and ``valloaders``) representing the data of ten different " +"organizations. Each ``trainloader``/``valloader`` pair contains 4000 " +"training examples and 1000 validation examples. There's also a single " +"``testloader`` (we did not split the test set). Again, this is only " +"necessary for building research or educational systems, actual federated " +"learning systems have their data naturally distributed across multiple " +"partitions." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:201 @@ -21403,8 +21714,8 @@ msgid "" "The output above shows a random batch of images from the first " "``trainloader`` in our list of ten ``trainloaders``. It also prints the " "labels associated with each image (i.e., one of the ten possible labels " -"we've seen above). If you run the cell again, you should see another " -"batch of images." +"we've seen above). If you run the cell again, you should see another batch " +"of images." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:252 @@ -21417,8 +21728,8 @@ msgid "" "network. This introduction assumes basic familiarity with PyTorch, so it " "doesn't cover the PyTorch-related aspects in full detail. If you want to " "dive deeper into PyTorch, we recommend `DEEP LEARNING WITH PYTORCH: A 60 " -"MINUTE BLITZ " -"`__." +"MINUTE BLITZ `__." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:275 @@ -21427,9 +21738,9 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:277 msgid "" -"We use the simple CNN described in the `PyTorch tutorial " -"`__:" +"We use the simple CNN described in the `PyTorch tutorial `__:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:314 @@ -21443,20 +21754,19 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:376 msgid "" "We now have all the basic building blocks we need: a dataset, a model, a " -"training function, and a test function. Let's put them together to train " -"the model on the dataset of one of our organizations " -"(``trainloaders[0]``). This simulates the reality of most machine " -"learning projects today: each organization has their own data and trains " -"models only on this internal data:" +"training function, and a test function. Let's put them together to train the " +"model on the dataset of one of our organizations (``trainloaders[0]``). This " +"simulates the reality of most machine learning projects today: each " +"organization has their own data and trains models only on this internal data:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:406 msgid "" -"Training the simple CNN on our CIFAR-10 split for 5 epochs should result " -"in a test set accuracy of about 41%, which is not good, but at the same " -"time, it doesn't really matter for the purposes of this tutorial. The " -"intent was just to show a simplistic centralized training pipeline that " -"sets the stage for what comes next - federated learning!" +"Training the simple CNN on our CIFAR-10 split for 5 epochs should result in " +"a test set accuracy of about 41%, which is not good, but at the same time, " +"it doesn't really matter for the purposes of this tutorial. The intent was " +"just to show a simplistic centralized training pipeline that sets the stage " +"for what comes next - federated learning!" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:418 @@ -21465,11 +21775,11 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:420 msgid "" -"Step 1 demonstrated a simple centralized training pipeline. All data was " -"in one place (i.e., a single ``trainloader`` and a single ``valloader``)." -" Next, we'll simulate a situation where we have multiple datasets in " -"multiple organizations and where we train a model over these " -"organizations using federated learning." +"Step 1 demonstrated a simple centralized training pipeline. All data was in " +"one place (i.e., a single ``trainloader`` and a single ``valloader``). Next, " +"we'll simulate a situation where we have multiple datasets in multiple " +"organizations and where we train a model over these organizations using " +"federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:432 @@ -21478,30 +21788,29 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:434 msgid "" -"In federated learning, the server sends the global model parameters to " -"the client, and the client updates the local model with the parameters " -"received from the server. It then trains the model on the local data " -"(which changes the model parameters locally) and sends the " -"updated/changed model parameters back to the server (or, alternatively, " -"it sends just the gradients back to the server, not the full model " -"parameters)." +"In federated learning, the server sends the global model parameters to the " +"client, and the client updates the local model with the parameters received " +"from the server. It then trains the model on the local data (which changes " +"the model parameters locally) and sends the updated/changed model parameters " +"back to the server (or, alternatively, it sends just the gradients back to " +"the server, not the full model parameters)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:436 msgid "" "We need two helper functions to update the local model with parameters " -"received from the server and to get the updated model parameters from the" -" local model: ``set_parameters`` and ``get_parameters``. The following " -"two functions do just that for the PyTorch model above." +"received from the server and to get the updated model parameters from the " +"local model: ``set_parameters`` and ``get_parameters``. The following two " +"functions do just that for the PyTorch model above." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:438 msgid "" -"The details of how this works are not really important here (feel free to" -" consult the PyTorch documentation if you want to learn more). In " -"essence, we use ``state_dict`` to access PyTorch model parameter tensors." -" The parameter tensors are then converted to/from a list of NumPy " -"ndarray's (which Flower knows how to serialize/deserialize):" +"The details of how this works are not really important here (feel free to " +"consult the PyTorch documentation if you want to learn more). In essence, we " +"use ``state_dict`` to access PyTorch model parameter tensors. The parameter " +"tensors are then converted to/from a list of NumPy ndarray's (which Flower " +"knows how to serialize/deserialize):" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:466 @@ -21510,19 +21819,18 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:468 msgid "" -"With that out of the way, let's move on to the interesting part. " -"Federated learning systems consist of a server and multiple clients. In " -"Flower, we create clients by implementing subclasses of " -"``flwr.client.Client`` or ``flwr.client.NumPyClient``. We use " -"``NumPyClient`` in this tutorial because it is easier to implement and " -"requires us to write less boilerplate." +"With that out of the way, let's move on to the interesting part. Federated " +"learning systems consist of a server and multiple clients. In Flower, we " +"create clients by implementing subclasses of ``flwr.client.Client`` or " +"``flwr.client.NumPyClient``. We use ``NumPyClient`` in this tutorial because " +"it is easier to implement and requires us to write less boilerplate." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:470 msgid "" -"To implement the Flower client, we create a subclass of " -"``flwr.client.NumPyClient`` and implement the three methods " -"``get_parameters``, ``fit``, and ``evaluate``:" +"To implement the Flower client, we create a subclass of ``flwr.client." +"NumPyClient`` and implement the three methods ``get_parameters``, ``fit``, " +"and ``evaluate``:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:472 @@ -21532,15 +21840,14 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:473 msgid "" "``fit``: Receive model parameters from the server, train the model " -"parameters on the local data, and return the (updated) model parameters " -"to the server" +"parameters on the local data, and return the (updated) model parameters to " +"the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:474 msgid "" -"``evaluate``: Receive model parameters from the server, evaluate the " -"model parameters on the local data, and return the evaluation result to " -"the server" +"``evaluate``: Receive model parameters from the server, evaluate the model " +"parameters on the local data, and return the evaluation result to the server" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:476 @@ -21553,16 +21860,15 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:513 msgid "" "Our class ``FlowerClient`` defines how local training/evaluation will be " -"performed and allows Flower to call the local training/evaluation through" -" ``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a" -" *single client* in our federated learning system. Federated learning " -"systems have multiple clients (otherwise, there's not much to federate), " -"so each client will be represented by its own instance of " -"``FlowerClient``. If we have, for example, three clients in our workload," -" then we'd have three instances of ``FlowerClient``. Flower calls " -"``FlowerClient.fit`` on the respective instance when the server selects a" -" particular client for training (and ``FlowerClient.evaluate`` for " -"evaluation)." +"performed and allows Flower to call the local training/evaluation through " +"``fit`` and ``evaluate``. Each instance of ``FlowerClient`` represents a " +"*single client* in our federated learning system. Federated learning systems " +"have multiple clients (otherwise, there's not much to federate), so each " +"client will be represented by its own instance of ``FlowerClient``. If we " +"have, for example, three clients in our workload, then we'd have three " +"instances of ``FlowerClient``. Flower calls ``FlowerClient.fit`` on the " +"respective instance when the server selects a particular client for training " +"(and ``FlowerClient.evaluate`` for evaluation)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:517 @@ -21571,13 +21877,13 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:519 msgid "" -"In this notebook, we want to simulate a federated learning system with 10" -" clients on a single machine. This means that the server and all 10 " -"clients will live on a single machine and share resources such as CPU, " -"GPU, and memory. Having 10 clients would mean having 10 instances of " -"``FlowerClient`` in memory. Doing this on a single machine can quickly " -"exhaust the available memory resources, even if only a subset of these " -"clients participates in a single round of federated learning." +"In this notebook, we want to simulate a federated learning system with 10 " +"clients on a single machine. This means that the server and all 10 clients " +"will live on a single machine and share resources such as CPU, GPU, and " +"memory. Having 10 clients would mean having 10 instances of ``FlowerClient`` " +"in memory. Doing this on a single machine can quickly exhaust the available " +"memory resources, even if only a subset of these clients participates in a " +"single round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:521 @@ -21586,14 +21892,14 @@ msgid "" "multiple machines, Flower, therefore, provides special simulation " "capabilities that create ``FlowerClient`` instances only when they are " "actually necessary for training or evaluation. To enable the Flower " -"framework to create clients when necessary, we need to implement a " -"function called ``client_fn`` that creates a ``FlowerClient`` instance on" -" demand. Flower calls ``client_fn`` whenever it needs an instance of one " -"particular client to call ``fit`` or ``evaluate`` (those instances are " -"usually discarded after use, so they should not keep any local state). " -"Clients are identified by a client ID, or short ``cid``. The ``cid`` can " -"be used, for example, to load different local data partitions for " -"different clients, as can be seen below:" +"framework to create clients when necessary, we need to implement a function " +"called ``client_fn`` that creates a ``FlowerClient`` instance on demand. " +"Flower calls ``client_fn`` whenever it needs an instance of one particular " +"client to call ``fit`` or ``evaluate`` (those instances are usually " +"discarded after use, so they should not keep any local state). Clients are " +"identified by a client ID, or short ``cid``. The ``cid`` can be used, for " +"example, to load different local data partitions for different clients, as " +"can be seen below:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:556 @@ -21602,31 +21908,31 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:558 msgid "" -"We now have the class ``FlowerClient`` which defines client-side " -"training/evaluation and ``client_fn`` which allows Flower to create " -"``FlowerClient`` instances whenever it needs to call ``fit`` or " -"``evaluate`` on one particular client. The last step is to start the " -"actual simulation using ``flwr.simulation.start_simulation``." +"We now have the class ``FlowerClient`` which defines client-side training/" +"evaluation and ``client_fn`` which allows Flower to create ``FlowerClient`` " +"instances whenever it needs to call ``fit`` or ``evaluate`` on one " +"particular client. The last step is to start the actual simulation using " +"``flwr.simulation.start_simulation``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:560 msgid "" "The function ``start_simulation`` accepts a number of arguments, amongst " -"them the ``client_fn`` used to create ``FlowerClient`` instances, the " -"number of clients to simulate (``num_clients``), the number of federated " -"learning rounds (``num_rounds``), and the strategy. The strategy " -"encapsulates the federated learning approach/algorithm, for example, " -"*Federated Averaging* (FedAvg)." +"them the ``client_fn`` used to create ``FlowerClient`` instances, the number " +"of clients to simulate (``num_clients``), the number of federated learning " +"rounds (``num_rounds``), and the strategy. The strategy encapsulates the " +"federated learning approach/algorithm, for example, *Federated Averaging* " +"(FedAvg)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:562 msgid "" "Flower has a number of built-in strategies, but we can also use our own " -"strategy implementations to customize nearly all aspects of the federated" -" learning approach. For this example, we use the built-in ``FedAvg`` " -"implementation and customize it using a few basic parameters. The last " -"step is the actual call to ``start_simulation`` which - you guessed it - " -"starts the simulation:" +"strategy implementations to customize nearly all aspects of the federated " +"learning approach. For this example, we use the built-in ``FedAvg`` " +"implementation and customize it using a few basic parameters. The last step " +"is the actual call to ``start_simulation`` which - you guessed it - starts " +"the simulation:" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:608 @@ -21640,20 +21946,20 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:612 #, python-format msgid "" -"When we call ``start_simulation``, we tell Flower that there are 10 " -"clients (``num_clients=10``). Flower then goes ahead an asks the " -"``FedAvg`` strategy to select clients. ``FedAvg`` knows that it should " -"select 100% of the available clients (``fraction_fit=1.0``), so it goes " -"ahead and selects 10 random clients (i.e., 100% of 10)." +"When we call ``start_simulation``, we tell Flower that there are 10 clients " +"(``num_clients=10``). Flower then goes ahead an asks the ``FedAvg`` strategy " +"to select clients. ``FedAvg`` knows that it should select 100% of the " +"available clients (``fraction_fit=1.0``), so it goes ahead and selects 10 " +"random clients (i.e., 100% of 10)." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:614 msgid "" -"Flower then asks the selected 10 clients to train the model. When the " -"server receives the model parameter updates from the clients, it hands " -"those updates over to the strategy (*FedAvg*) for aggregation. The " -"strategy aggregates those updates and returns the new global model, which" -" then gets used in the next round of federated learning." +"Flower then asks the selected 10 clients to train the model. When the server " +"receives the model parameter updates from the clients, it hands those " +"updates over to the strategy (*FedAvg*) for aggregation. The strategy " +"aggregates those updates and returns the new global model, which then gets " +"used in the next round of federated learning." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:626 @@ -21662,28 +21968,27 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:628 msgid "" -"You may have noticed that all metrics except for ``losses_distributed`` " -"are empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" +"You may have noticed that all metrics except for ``losses_distributed`` are " +"empty. Where did the ``{\"accuracy\": float(accuracy)}`` go?" msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:630 msgid "" -"Flower can automatically aggregate losses returned by individual clients," -" but it cannot do the same for metrics in the generic metrics dictionary " -"(the one with the ``accuracy`` key). Metrics dictionaries can contain " -"very different kinds of metrics and even key/value pairs that are not " -"metrics at all, so the framework does not (and can not) know how to " -"handle these automatically." +"Flower can automatically aggregate losses returned by individual clients, " +"but it cannot do the same for metrics in the generic metrics dictionary (the " +"one with the ``accuracy`` key). Metrics dictionaries can contain very " +"different kinds of metrics and even key/value pairs that are not metrics at " +"all, so the framework does not (and can not) know how to handle these " +"automatically." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:632 msgid "" -"As users, we need to tell the framework how to handle/aggregate these " -"custom metrics, and we do so by passing metric aggregation functions to " -"the strategy. The strategy will then call these functions whenever it " -"receives fit or evaluate metrics from clients. The two possible functions" -" are ``fit_metrics_aggregation_fn`` and " -"``evaluate_metrics_aggregation_fn``." +"As users, we need to tell the framework how to handle/aggregate these custom " +"metrics, and we do so by passing metric aggregation functions to the " +"strategy. The strategy will then call these functions whenever it receives " +"fit or evaluate metrics from clients. The two possible functions are " +"``fit_metrics_aggregation_fn`` and ``evaluate_metrics_aggregation_fn``." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:634 @@ -21701,17 +22006,17 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:697 msgid "" "We now have a full system that performs federated training and federated " -"evaluation. It uses the ``weighted_average`` function to aggregate custom" -" evaluation metrics and calculates a single ``accuracy`` metric across " -"all clients on the server side." +"evaluation. It uses the ``weighted_average`` function to aggregate custom " +"evaluation metrics and calculates a single ``accuracy`` metric across all " +"clients on the server side." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:699 msgid "" "The other two categories of metrics (``losses_centralized`` and " "``metrics_centralized``) are still empty because they only apply when " -"centralized evaluation is being used. Part two of the Flower tutorial " -"will cover centralized evaluation." +"centralized evaluation is being used. Part two of the Flower tutorial will " +"cover centralized evaluation." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:711 @@ -21721,28 +22026,28 @@ msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:713 msgid "" -"Congratulations, you just trained a convolutional neural network, " -"federated over 10 clients! With that, you understand the basics of " -"federated learning with Flower. The same approach you've seen can be used" -" with other machine learning frameworks (not just PyTorch) and tasks (not" -" just CIFAR-10 images classification), for example NLP with Hugging Face " -"Transformers or speech with SpeechBrain." +"Congratulations, you just trained a convolutional neural network, federated " +"over 10 clients! With that, you understand the basics of federated learning " +"with Flower. The same approach you've seen can be used with other machine " +"learning frameworks (not just PyTorch) and tasks (not just CIFAR-10 images " +"classification), for example NLP with Hugging Face Transformers or speech " +"with SpeechBrain." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:715 msgid "" -"In the next notebook, we're going to cover some more advanced concepts. " -"Want to customize your strategy? Initialize parameters on the server " -"side? Or evaluate the aggregated model on the server side? We'll cover " -"all this and more in the next tutorial." +"In the next notebook, we're going to cover some more advanced concepts. Want " +"to customize your strategy? Initialize parameters on the server side? Or " +"evaluate the aggregated model on the server side? We'll cover all this and " +"more in the next tutorial." msgstr "" #: ../../source/tutorial-series-get-started-with-flower-pytorch.ipynb:733 msgid "" -"The `Flower Federated Learning Tutorial - Part 2 " -"`__ goes into more depth about strategies and all " -"the advanced things you can build with them." +"The `Flower Federated Learning Tutorial - Part 2 `__ goes " +"into more depth about strategies and all the advanced things you can build " +"with them." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:9 @@ -21752,16 +22057,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:11 msgid "" "Welcome to the next part of the federated learning tutorial. In previous " -"parts of this tutorial, we introduced federated learning with PyTorch and" -" Flower (`part 1 `__)." +"parts of this tutorial, we introduced federated learning with PyTorch and " +"Flower (`part 1 `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:13 msgid "" -"In this notebook, we'll begin to customize the federated learning system " -"we built in the introductory notebook (again, using `Flower " -"`__ and `PyTorch `__)." +"In this notebook, we'll begin to customize the federated learning system we " +"built in the introductory notebook (again, using `Flower `__ and `PyTorch `__)." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:17 @@ -21775,8 +22080,8 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:311 msgid "" "So far, everything should look familiar if you've worked through the " -"introductory notebook. With that, we're ready to introduce a number of " -"new features." +"introductory notebook. With that, we're ready to introduce a number of new " +"features." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:323 @@ -21785,16 +22090,16 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:325 msgid "" -"Flower, by default, initializes the global model by asking one random " -"client for the initial parameters. In many cases, we want more control " -"over parameter initialization though. Flower therefore allows you to " -"directly pass the initial parameters to the Strategy:" +"Flower, by default, initializes the global model by asking one random client " +"for the initial parameters. In many cases, we want more control over " +"parameter initialization though. Flower therefore allows you to directly " +"pass the initial parameters to the Strategy:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:370 msgid "" -"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower" -" from asking one of the clients for the initial parameters. If we look " +"Passing ``initial_parameters`` to the ``FedAvg`` strategy prevents Flower " +"from asking one of the clients for the initial parameters. If we look " "closely, we can see that the logs do not show any calls to the " "``FlowerClient.get_parameters`` method." msgstr "" @@ -21805,17 +22110,17 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:384 msgid "" -"We've seen the function ``start_simulation`` before. It accepts a number " -"of arguments, amongst them the ``client_fn`` used to create " -"``FlowerClient`` instances, the number of clients to simulate " -"``num_clients``, the number of rounds ``num_rounds``, and the strategy." +"We've seen the function ``start_simulation`` before. It accepts a number of " +"arguments, amongst them the ``client_fn`` used to create ``FlowerClient`` " +"instances, the number of clients to simulate ``num_clients``, the number of " +"rounds ``num_rounds``, and the strategy." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:386 msgid "" "The strategy encapsulates the federated learning approach/algorithm, for " -"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different " -"strategy this time:" +"example, ``FedAvg`` or ``FedAdagrad``. Let's try to use a different strategy " +"this time:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:424 @@ -21824,9 +22129,9 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:426 msgid "" -"Flower can evaluate the aggregated model on the server-side or on the " -"client-side. Client-side and server-side evaluation are similar in some " -"ways, but different in others." +"Flower can evaluate the aggregated model on the server-side or on the client-" +"side. Client-side and server-side evaluation are similar in some ways, but " +"different in others." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:428 @@ -21834,33 +22139,33 @@ msgid "" "**Centralized Evaluation** (or *server-side evaluation*) is conceptually " "simple: it works the same way that evaluation in centralized machine " "learning does. If there is a server-side dataset that can be used for " -"evaluation purposes, then that's great. We can evaluate the newly " -"aggregated model after each round of training without having to send the " -"model to clients. We're also fortunate in the sense that our entire " -"evaluation dataset is available at all times." +"evaluation purposes, then that's great. We can evaluate the newly aggregated " +"model after each round of training without having to send the model to " +"clients. We're also fortunate in the sense that our entire evaluation " +"dataset is available at all times." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:430 msgid "" -"**Federated Evaluation** (or *client-side evaluation*) is more complex, " -"but also more powerful: it doesn't require a centralized dataset and " -"allows us to evaluate models over a larger set of data, which often " -"yields more realistic evaluation results. In fact, many scenarios require" -" us to use **Federated Evaluation** if we want to get representative " -"evaluation results at all. But this power comes at a cost: once we start " -"to evaluate on the client side, we should be aware that our evaluation " -"dataset can change over consecutive rounds of learning if those clients " -"are not always available. Moreover, the dataset held by each client can " -"also change over consecutive rounds. This can lead to evaluation results " -"that are not stable, so even if we would not change the model, we'd see " -"our evaluation results fluctuate over consecutive rounds." +"**Federated Evaluation** (or *client-side evaluation*) is more complex, but " +"also more powerful: it doesn't require a centralized dataset and allows us " +"to evaluate models over a larger set of data, which often yields more " +"realistic evaluation results. In fact, many scenarios require us to use " +"**Federated Evaluation** if we want to get representative evaluation results " +"at all. But this power comes at a cost: once we start to evaluate on the " +"client side, we should be aware that our evaluation dataset can change over " +"consecutive rounds of learning if those clients are not always available. " +"Moreover, the dataset held by each client can also change over consecutive " +"rounds. This can lead to evaluation results that are not stable, so even if " +"we would not change the model, we'd see our evaluation results fluctuate " +"over consecutive rounds." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:433 msgid "" "We've seen how federated evaluation works on the client side (i.e., by " -"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see " -"how we can evaluate aggregated model parameters on the server-side:" +"implementing the ``evaluate`` method in ``FlowerClient``). Now let's see how " +"we can evaluate aggregated model parameters on the server-side:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:490 @@ -21869,50 +22174,48 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:492 msgid "" -"In some situations, we want to configure client-side execution (training," -" evaluation) from the server-side. One example for that is the server " -"asking the clients to train for a certain number of local epochs. Flower " -"provides a way to send configuration values from the server to the " -"clients using a dictionary. Let's look at an example where the clients " -"receive values from the server through the ``config`` parameter in " -"``fit`` (``config`` is also available in ``evaluate``). The ``fit`` " -"method receives the configuration dictionary through the ``config`` " -"parameter and can then read values from this dictionary. In this example," -" it reads ``server_round`` and ``local_epochs`` and uses those values to " -"improve the logging and configure the number of local training epochs:" +"In some situations, we want to configure client-side execution (training, " +"evaluation) from the server-side. One example for that is the server asking " +"the clients to train for a certain number of local epochs. Flower provides a " +"way to send configuration values from the server to the clients using a " +"dictionary. Let's look at an example where the clients receive values from " +"the server through the ``config`` parameter in ``fit`` (``config`` is also " +"available in ``evaluate``). The ``fit`` method receives the configuration " +"dictionary through the ``config`` parameter and can then read values from " +"this dictionary. In this example, it reads ``server_round`` and " +"``local_epochs`` and uses those values to improve the logging and configure " +"the number of local training epochs:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:546 msgid "" -"So how can we send this config dictionary from server to clients? The " -"built-in Flower Strategies provide way to do this, and it works similarly" -" to the way server-side evaluation works. We provide a function to the " -"strategy, and the strategy calls this function for every round of " -"federated learning:" +"So how can we send this config dictionary from server to clients? The built-" +"in Flower Strategies provide way to do this, and it works similarly to the " +"way server-side evaluation works. We provide a function to the strategy, and " +"the strategy calls this function for every round of federated learning:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:576 msgid "" -"Next, we'll just pass this function to the FedAvg strategy before " -"starting the simulation:" +"Next, we'll just pass this function to the FedAvg strategy before starting " +"the simulation:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:613 msgid "" -"As we can see, the client logs now include the current round of federated" -" learning (which they read from the ``config`` dictionary). We can also " -"configure local training to run for one epoch during the first and second" -" round of federated learning, and then for two epochs during the third " -"round." +"As we can see, the client logs now include the current round of federated " +"learning (which they read from the ``config`` dictionary). We can also " +"configure local training to run for one epoch during the first and second " +"round of federated learning, and then for two epochs during the third round." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:615 msgid "" "Clients can also return arbitrary values to the server. To do so, they " -"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and " -"used this concept throughout this notebook without mentioning it " -"explicitly: our ``FlowerClient`` returns a dictionary containing a custom" -" key/value pair as the third return value in ``evaluate``." +"return a dictionary from ``fit`` and/or ``evaluate``. We have seen and used " +"this concept throughout this notebook without mentioning it explicitly: our " +"``FlowerClient`` returns a dictionary containing a custom key/value pair as " +"the third return value in ``evaluate``." msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:627 @@ -21929,14 +22232,13 @@ msgstr "" #, python-format msgid "" "We now have 1000 partitions, each holding 45 training and 5 validation " -"examples. Given that the number of training examples on each client is " -"quite small, we should probably train the model a bit longer, so we " -"configure the clients to perform 3 local training epochs. We should also " -"adjust the fraction of clients selected for training during each round " -"(we don't want all 1000 clients participating in every round), so we " -"adjust ``fraction_fit`` to ``0.05``, which means that only 5% of " -"available clients (so 50 clients) will be selected for training each " -"round:" +"examples. Given that the number of training examples on each client is quite " +"small, we should probably train the model a bit longer, so we configure the " +"clients to perform 3 local training epochs. We should also adjust the " +"fraction of clients selected for training during each round (we don't want " +"all 1000 clients participating in every round), so we adjust " +"``fraction_fit`` to ``0.05``, which means that only 5% of available clients " +"(so 50 clients) will be selected for training each round:" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:699 @@ -21949,94 +22251,111 @@ msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:701 msgid "" -"In the later sections, we've seen how we can communicate arbitrary values" -" between server and clients to fully customize client-side execution. " -"With that capability, we built a large-scale Federated Learning " -"simulation using the Flower Virtual Client Engine and ran an experiment " -"involving 1000 clients in the same workload - all in a Jupyter Notebook!" +"In the later sections, we've seen how we can communicate arbitrary values " +"between server and clients to fully customize client-side execution. With " +"that capability, we built a large-scale Federated Learning simulation using " +"the Flower Virtual Client Engine and ran an experiment involving 1000 " +"clients in the same workload - all in a Jupyter Notebook!" msgstr "" #: ../../source/tutorial-series-use-a-federated-learning-strategy-pytorch.ipynb:719 msgid "" -"The `Flower Federated Learning Tutorial - Part 3 " -"`__ shows how to build a fully custom ``Strategy`` from " -"scratch." +"The `Flower Federated Learning Tutorial - Part 3 `__ shows how " +"to build a fully custom ``Strategy`` from scratch." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:9 msgid "What is Federated Learning?" -msgstr "" +msgstr "연합 학습이란 무엇입니까?" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:13 msgid "" "In this tutorial, you will learn what federated learning is, build your " "first system in Flower, and gradually extend it. If you work through all " -"parts of the tutorial, you will be able to build advanced federated " -"learning systems that approach the current state of the art in the field." +"parts of the tutorial, you will be able to build advanced federated learning " +"systems that approach the current state of the art in the field." msgstr "" +"이 튜토리얼에서 연합 학습이 무엇인지 배우고 Flower로 첫 번째 시스템을 " +"구축하고 점진적으로 확장해 나갈 것입니다. 본 튜토리얼의 모든 부분을 완성할 " +"수 있다면, 당신은 고급 연방 학습 시스템을 구축하여 그 분야의 현재 기술 " +"수준에 접근할 수 있을 것입니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:15 msgid "" -"🧑‍🏫 This tutorial starts at zero and expects no familiarity with " -"federated learning. Only a basic understanding of data science and Python" -" programming is assumed." +"🧑‍🏫 This tutorial starts at zero and expects no familiarity with federated " +"learning. Only a basic understanding of data science and Python programming " +"is assumed." msgstr "" +"🧑‍🏫이 튜토리얼은 제로베이부터 시작되며 연방 학습에 상세히 아는 필요가 " +"없습니다. 데이터 과학과 파이썬 프로그래밍에 대한 기본적인 이해만 가정합니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:17 msgid "" -"`Star Flower on GitHub `__ ⭐️ and join " -"the open-source Flower community on Slack to connect, ask questions, and " -"get help: `Join Slack `__ 🌼 We'd love to " -"hear from you in the ``#introductions`` channel! And if anything is " -"unclear, head over to the ``#questions`` channel." +"`Star Flower on GitHub `__ ⭐️ and join the " +"open-source Flower community on Slack to connect, ask questions, and get " +"help: `Join Slack `__ 🌼 We'd love to hear " +"from you in the ``#introductions`` channel! And if anything is unclear, head " +"over to the ``#questions`` channel." msgstr "" +"`Star Flower on GitHub `__ ⭐️ Slack의 " +"오픈소스 Flower 커뮤니티에 가입하여 소통하고 질문하고 도움을 받을 수 " +"있습니다: `Slack 가입`__ 🌼 ``#introductions``" +"채널에서 당신의 목소리를 듣고 싶습니다! 궁금한 점이 있으시면``#questions`` " +"채널로 방문해 주시기 바랍니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:31 msgid "Classic machine learning" -msgstr "" +msgstr "클래식 머신러닝" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:33 msgid "" -"Before we begin to discuss federated learning, let us quickly recap how " -"most machine learning works today." -msgstr "" +"Before we begin to discuss federated learning, let us quickly recap how most " +"machine learning works today." +msgstr "연방 학습에 대해 논의하기 전에 현재 대부분의 머신러닝이 어떻게 작동하는지 " +"간략히 요약하겠습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:35 msgid "" -"In machine learning, we have a model, and we have data. The model could " -"be a neural network (as depicted here), or something else, like classical" -" linear regression." +"In machine learning, we have a model, and we have data. The model could be a " +"neural network (as depicted here), or something else, like classical linear " +"regression." msgstr "" +"기계 학습에서 우리는 모델과 데이터를 가지고 있습니다.모델은 신경망((그림과 " +"같이))일 수도 있고 고전적인 선형 회귀와 같은 다른 것일 수도 있습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:41 msgid "|93b02017c78049bbbd5ae456dcb2c91b|" -msgstr "" +msgstr "|93b02017c78049bbbd5ae456dcb2c91b|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:109 msgid "Model and data" -msgstr "" +msgstr "모델과 데이터" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:47 msgid "" -"We train the model using the data to perform a useful task. A task could " -"be to detect objects in images, transcribe an audio recording, or play a " -"game like Go." +"We train the model using the data to perform a useful task. A task could be " +"to detect objects in images, transcribe an audio recording, or play a game " +"like Go." msgstr "" +"우리는 유용한 작업을 수행하기 위해 데이터를 사용하여 모델을 훈련합니다. " +"작업은 이미지 속 물체를 감지하거나 음성 녹음을 기록하거나 바둑과 같은 게임을 " +"하는 것일 수 있습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:53 msgid "|01471150fd5144c080a176b43e92a3ff|" -msgstr "" +msgstr "|01471150fd5144c080a176b43e92a3ff|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:111 msgid "Train model using data" -msgstr "" +msgstr "데이터를 이용한 모델 훈련" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:59 msgid "" -"Now, in practice, the training data we work with doesn't originate on the" -" machine we train the model on. It gets created somewhere else." -msgstr "" +"Now, in practice, the training data we work with doesn't originate on the " +"machine we train the model on. It gets created somewhere else." +msgstr "실제로 우리가 사용하는 훈련 데이터는 모델을 훈련시키는 기계에서 비롯된 것이 " +"아닙니다. 그 데이터는 다른 곳에서 만들어졌습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:61 msgid "" @@ -22044,46 +22363,54 @@ msgid "" "collecting sensor data, a laptop receiving input via the keyboard, or a " "smart speaker listening to someone trying to sing a song." msgstr "" +"스마트폰에서 사용자와 앱의 상호 작용, 센서 데이터를 수집하는 자동차, " +"키보드를 통해 입력을 받는 노트북 또는 누군가 노래를 부르리는 것을 듣는 " +"스마트 스피커에서 비롯됩니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:67 msgid "|9bc21c7dbd17444a8f070c60786e3484|" -msgstr "" +msgstr "|9bc21c7dbd17444a8f070c60786e3484|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:113 msgid "Data on a phone" -msgstr "" +msgstr "핸드푼에 있는 데이터" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:73 msgid "" "What's also important to mention, this \"somewhere else\" is usually not " -"just one place, it's many places. It could be several devices all running" -" the same app. But it could also be several organizations, all generating" -" data for the same task." +"just one place, it's many places. It could be several devices all running " +"the same app. But it could also be several organizations, all generating " +"data for the same task." msgstr "" +"또한 중요한 것은 이 \"다른 곳\"이 보통 한 곳만 아니라 여러 곳이라는 " +"것입니다. 같은 앱을 실행하는 여러 기기일 수도 있습니다. 하지만 여러 조직이 " +"모두 같은 작업을 위해 데이터를 생성하는 것일 수도 있습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:79 msgid "|3047bbce54b34099ae559963d0420d79|" -msgstr "" +msgstr "|3047bbce54b34099ae559963d0420d79|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:115 msgid "Data is on many devices" -msgstr "" +msgstr "데이터가 여러 장치에 있습니다" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:85 msgid "" -"So to use machine learning, or any kind of data analysis, the approach " -"that has been used in the past was to collect all data on a central " -"server. This server can be somewhere in a data center, or somewhere in " -"the cloud." +"So to use machine learning, or any kind of data analysis, the approach that " +"has been used in the past was to collect all data on a central server. This " +"server can be somewhere in a data center, or somewhere in the cloud." msgstr "" +"따라서 머신러닝이나 어떤 종류의 데이터 분석을 이용하려면 과거에는 중앙 " +"서버에서 모든 데이터를 수집하는 방법이 사용되었습니다.이 서버는 데이터 센터 " +"어딘가에 있을 수도 있고 클라우드 어딘가에 있을 수도 있습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:91 msgid "|e9f8ce948593444fb838d2f354c7ec5d|" -msgstr "" +msgstr "|e9f8ce948593444fb838d2f354c7ec5d|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:117 msgid "Central data collection" -msgstr "" +msgstr "중앙 데이터 수집" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:97 msgid "" @@ -22091,56 +22418,68 @@ msgid "" "learning algorithms to train our model on the data. This is the machine " "learning approach that we've basically always relied on." msgstr "" +"모든 데이터가 한 곳에 모이면, 우리는 궁극적으로 머신러닝 알고리즘을 사용하여 " +"데이터에서 모델을 훈련시킬 수 있습니다.이것이 바로 우리가 기본적으로 " +"의지해왔던 머신러닝 방법입니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:103 msgid "|c24c1478b30e4f74839208628a842d1e|" -msgstr "" +msgstr "|c24c1478b30e4f74839208628a842d1e|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:119 msgid "Central model training" -msgstr "" +msgstr "중앙 데이터 훈련" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:130 msgid "Challenges of classical machine learning" -msgstr "" +msgstr "클래식 머신러닝이 만난 도전" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:132 msgid "" -"The classic machine learning approach we've just seen can be used in some" -" cases. Great examples include categorizing holiday photos, or analyzing " -"web traffic. Cases, where all the data is naturally available on a " -"centralized server." +"The classic machine learning approach we've just seen can be used in some " +"cases. Great examples include categorizing holiday photos, or analyzing web " +"traffic. Cases, where all the data is naturally available on a centralized " +"server." msgstr "" +"우리가 방금 본 클래식 머신러닝 접근 방식은 경우에 따라 사용될 수 있습니다. " +"좋은 예로는 휴일 사진을 분류하거나 웹 트래픽을 분석하는 것이 있습니다. " +"이러한 사례에서 모든 데이터는 자연스럽게 중앙 서버에서 사용할 수 있습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:138 msgid "|1b3613d7a58847b59e1d3180802dbc09|" -msgstr "" +msgstr "|1b3613d7a58847b59e1d3180802dbc09|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:173 msgid "Centralized possible" -msgstr "" +msgstr "집중화 가능" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:144 msgid "" -"But the approach can not be used in many other cases. Cases, where the " -"data is not available on a centralized server, or cases where the data " -"available on one server is not enough to train a good model." +"But the approach can not be used in many other cases. Cases, where the data " +"is not available on a centralized server, or cases where the data available " +"on one server is not enough to train a good model." msgstr "" +"그러나 이 방법은 다른 많은 경우에 적용되지 않습니다.예를 들어, 중앙 집중식 " +"서버에 데이터가 없거나 서버의 데이터가 좋은 모델을 훈련하기에 충분하지 " +"않습니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:150 msgid "|9980b5213db547d0b8024a50992b9e3f|" -msgstr "" +msgstr "|9980b5213db547d0b8024a50992b9e3f|" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:175 msgid "Centralized impossible" -msgstr "" +msgstr "집중화 가능" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:156 msgid "" -"There are many reasons why the classic centralized machine learning " -"approach does not work for a large number of highly important real-world " -"use cases. Those reasons include:" +"There are many reasons why the classic centralized machine learning approach " +"does not work for a large number of highly important real-world use cases. " +"Those reasons include:" msgstr "" +"클래식 중앙 집중식 머신러닝 방법이 현실 세계에서 매우 중요한 수많은 사용 " +"사례를 충족시킬 수 없는 이유가 있습니다.이유는 다음과 같은 여러 가지가 " +"있습니다:" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:158 msgid "" @@ -22149,32 +22488,39 @@ msgid "" "(Russia), CDPR (China), PDPB (India), PIPA (Korea), APPI (Japan), PDP " "(Indonesia), PDPA (Singapore), APP (Australia), and other regulations " "protect sensitive data from being moved. In fact, those regulations " -"sometimes even prevent single organizations from combining their own " -"users' data for artificial intelligence training because those users live" -" in different parts of the world, and their data is governed by different" -" data protection regulations." -msgstr "" +"sometimes even prevent single organizations from combining their own users' " +"data for artificial intelligence training because those users live in " +"different parts of the world, and their data is governed by different data " +"protection regulations." +msgstr "" +"**규정**: GDPR (유럽), CCPA (캘리포니아), PIPEDA (캐나다), LGPD (브라질), " +"PDPL (아르헨티나), KVKK (터키), POPI (남아프리카공화국), FSS (러시아), CDPR " +"(중국), PDPB (인도), PIPA (한국), APPI (일본), PDP (인도네시아), PDPA " +"(싱가포르), APP (호주)등의 법규로 민감한 데이터가 이동하지 않도록 보호하고 " +"있습니 다. 실제 로이러한 규정은 사용자가 세계의 다른 지역에 살고 데이터가 " +"다른 데이터 보호 규정에 의해 통제되기 때문에 단일 조직이 자체 사용자 " +"데이터를 인공 지능 교육에 사용하는 것을 방지하기도 합니다." #: ../../source/tutorial-series-what-is-federated-learning.ipynb:160 msgid "" -"**User preference**: In addition to regulation, there are use cases where" -" users just expect that no data leaves their device, ever. If you type " -"your passwords and credit card info into the digital keyboard of your " -"phone, you don't expect those passwords to end up on the server of the " -"company that developed that keyboard, do you? In fact, that use case was " -"the reason federated learning was invented in the first place." +"**User preference**: In addition to regulation, there are use cases where " +"users just expect that no data leaves their device, ever. If you type your " +"passwords and credit card info into the digital keyboard of your phone, you " +"don't expect those passwords to end up on the server of the company that " +"developed that keyboard, do you? In fact, that use case was the reason " +"federated learning was invented in the first place." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:161 msgid "" -"**Data volume**: Some sensors, like cameras, produce such a high data " -"volume that it is neither feasible nor economic to collect all the data " -"(due to, for example, bandwidth or communication efficiency). Think about" -" a national rail service with hundreds of train stations across the " -"country. If each of these train stations is outfitted with a number of " -"security cameras, the volume of raw on-device data they produce requires " -"incredibly powerful and exceedingly expensive infrastructure to process " -"and store. And most of the data isn't even useful." +"**Data volume**: Some sensors, like cameras, produce such a high data volume " +"that it is neither feasible nor economic to collect all the data (due to, " +"for example, bandwidth or communication efficiency). Think about a national " +"rail service with hundreds of train stations across the country. If each of " +"these train stations is outfitted with a number of security cameras, the " +"volume of raw on-device data they produce requires incredibly powerful and " +"exceedingly expensive infrastructure to process and store. And most of the " +"data isn't even useful." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:164 @@ -22189,8 +22535,7 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:167 msgid "" -"Financial information from different organizations to detect financial " -"fraud" +"Financial information from different organizations to detect financial fraud" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:168 @@ -22203,13 +22548,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:171 msgid "" -"The popularity of privacy-enhancing systems like the `Brave " -"`__ browser or the `Signal `__ " -"messenger shows that users care about privacy. In fact, they choose the " -"privacy-enhancing version over other alternatives, if such an alternative" -" exists. But what can we do to apply machine learning and data science to" -" these cases to utilize private data? After all, these are all areas that" -" would benefit significantly from recent advances in AI." +"The popularity of privacy-enhancing systems like the `Brave `__ browser or the `Signal `__ messenger shows " +"that users care about privacy. In fact, they choose the privacy-enhancing " +"version over other alternatives, if such an alternative exists. But what can " +"we do to apply machine learning and data science to these cases to utilize " +"private data? After all, these are all areas that would benefit " +"significantly from recent advances in AI." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:186 @@ -22219,9 +22564,8 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:188 msgid "" "Federated learning simply reverses this approach. It enables machine " -"learning on distributed data by moving the training to the data, instead " -"of moving the data to the training. Here's the single-sentence " -"explanation:" +"learning on distributed data by moving the training to the data, instead of " +"moving the data to the training. Here's the single-sentence explanation:" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:190 @@ -22234,22 +22578,22 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:193 msgid "" -"By doing so, it enables us to use machine learning (and other data " -"science approaches) in areas where it wasn't possible before. We can now " -"train excellent medical AI models by enabling different hospitals to work" -" together. We can solve financial fraud by training AI models on the data" -" of different financial institutions. We can build novel privacy-" -"enhancing applications (such as secure messaging) that have better built-" -"in AI than their non-privacy-enhancing alternatives. And those are just a" -" few of the examples that come to mind. As we deploy federated learning, " -"we discover more and more areas that can suddenly be reinvented because " -"they now have access to vast amounts of previously inaccessible data." +"By doing so, it enables us to use machine learning (and other data science " +"approaches) in areas where it wasn't possible before. We can now train " +"excellent medical AI models by enabling different hospitals to work " +"together. We can solve financial fraud by training AI models on the data of " +"different financial institutions. We can build novel privacy-enhancing " +"applications (such as secure messaging) that have better built-in AI than " +"their non-privacy-enhancing alternatives. And those are just a few of the " +"examples that come to mind. As we deploy federated learning, we discover " +"more and more areas that can suddenly be reinvented because they now have " +"access to vast amounts of previously inaccessible data." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:196 msgid "" -"So how does federated learning work, exactly? Let's start with an " -"intuitive explanation." +"So how does federated learning work, exactly? Let's start with an intuitive " +"explanation." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:199 @@ -22262,9 +22606,9 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:204 msgid "" -"We start by initializing the model on the server. This is exactly the " -"same in classic centralized learning: we initialize the model parameters," -" either randomly or from a previously saved checkpoint." +"We start by initializing the model on the server. This is exactly the same " +"in classic centralized learning: we initialize the model parameters, either " +"randomly or from a previously saved checkpoint." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:210 @@ -22277,18 +22621,18 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:217 msgid "" -"Step 1: Send model to a number of connected organizations/devices (client" -" nodes)" +"Step 1: Send model to a number of connected organizations/devices (client " +"nodes)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:219 msgid "" "Next, we send the parameters of the global model to the connected client " "nodes (think: edge devices like smartphones or servers belonging to " -"organizations). This is to ensure that each participating node starts " -"their local training using the same model parameters. We often use only a" -" few of the connected nodes instead of all nodes. The reason for this is " -"that selecting more and more client nodes has diminishing returns." +"organizations). This is to ensure that each participating node starts their " +"local training using the same model parameters. We often use only a few of " +"the connected nodes instead of all nodes. The reason for this is that " +"selecting more and more client nodes has diminishing returns." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:225 @@ -22301,18 +22645,18 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:232 msgid "" -"Step 2: Train model locally on the data of each organization/device " -"(client node)" +"Step 2: Train model locally on the data of each organization/device (client " +"node)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:234 msgid "" -"Now that all (selected) client nodes have the latest version of the " -"global model parameters, they start the local training. They use their " -"own local dataset to train their own local model. They don't train the " -"model until full convergence, but they only train for a little while. " -"This could be as little as one epoch on the local data, or even just a " -"few steps (mini-batches)." +"Now that all (selected) client nodes have the latest version of the global " +"model parameters, they start the local training. They use their own local " +"dataset to train their own local model. They don't train the model until " +"full convergence, but they only train for a little while. This could be as " +"little as one epoch on the local data, or even just a few steps (mini-" +"batches)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:240 @@ -22329,13 +22673,12 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:249 msgid "" -"After local training, each client node has a slightly different version " -"of the model parameters they originally received. The parameters are all " +"After local training, each client node has a slightly different version of " +"the model parameters they originally received. The parameters are all " "different because each client node has different examples in its local " -"dataset. The client nodes then send those model updates back to the " -"server. The model updates they send can either be the full model " -"parameters or just the gradients that were accumulated during local " -"training." +"dataset. The client nodes then send those model updates back to the server. " +"The model updates they send can either be the full model parameters or just " +"the gradients that were accumulated during local training." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:255 @@ -22353,27 +22696,26 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:264 msgid "" "The server receives model updates from the selected client nodes. If it " -"selected 100 client nodes, it now has 100 slightly different versions of " -"the original global model, each trained on the local data of one client. " -"But didn't we want to have one model that contains the learnings from the" -" data of all 100 client nodes?" +"selected 100 client nodes, it now has 100 slightly different versions of the " +"original global model, each trained on the local data of one client. But " +"didn't we want to have one model that contains the learnings from the data " +"of all 100 client nodes?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:266 msgid "" -"In order to get one single model, we have to combine all the model " -"updates we received from the client nodes. This process is called " -"*aggregation*, and there are many different ways to do it. The most basic" -" way to do it is called *Federated Averaging* (`McMahan et al., 2016 " -"`__), often abbreviated as *FedAvg*. " -"*FedAvg* takes the 100 model updates and, as the name suggests, averages " -"them. To be more precise, it takes the *weighted average* of the model " -"updates, weighted by the number of examples each client used for " -"training. The weighting is important to make sure that each data example " -"has the same \"influence\" on the resulting global model. If one client " -"has 10 examples, and another client has 100 examples, then - without " -"weighting - each of the 10 examples would influence the global model ten " -"times as much as each of the 100 examples." +"In order to get one single model, we have to combine all the model updates " +"we received from the client nodes. This process is called *aggregation*, and " +"there are many different ways to do it. The most basic way to do it is " +"called *Federated Averaging* (`McMahan et al., 2016 `__), often abbreviated as *FedAvg*. *FedAvg* takes the 100 " +"model updates and, as the name suggests, averages them. To be more precise, " +"it takes the *weighted average* of the model updates, weighted by the number " +"of examples each client used for training. The weighting is important to " +"make sure that each data example has the same \"influence\" on the resulting " +"global model. If one client has 10 examples, and another client has 100 " +"examples, then - without weighting - each of the 10 examples would influence " +"the global model ten times as much as each of the 100 examples." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:273 @@ -22391,41 +22733,39 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:282 msgid "" "Steps 1 to 4 are what we call a single round of federated learning. The " -"global model parameters get sent to the participating client nodes (step " -"1), the client nodes train on their local data (step 2), they send their " -"updated models to the server (step 3), and the server then aggregates the" -" model updates to get a new version of the global model (step 4)." +"global model parameters get sent to the participating client nodes (step 1), " +"the client nodes train on their local data (step 2), they send their updated " +"models to the server (step 3), and the server then aggregates the model " +"updates to get a new version of the global model (step 4)." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:284 msgid "" -"During a single round, each client node that participates in that " -"iteration only trains for a little while. This means that after the " -"aggregation step (step 4), we have a model that has been trained on all " -"the data of all participating client nodes, but only for a little while. " -"We then have to repeat this training process over and over again to " -"eventually arrive at a fully trained model that performs well across the " -"data of all client nodes." +"During a single round, each client node that participates in that iteration " +"only trains for a little while. This means that after the aggregation step " +"(step 4), we have a model that has been trained on all the data of all " +"participating client nodes, but only for a little while. We then have to " +"repeat this training process over and over again to eventually arrive at a " +"fully trained model that performs well across the data of all client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:289 msgid "" "Congratulations, you now understand the basics of federated learning. " -"There's a lot more to discuss, of course, but that was federated learning" -" in a nutshell. In later parts of this tutorial, we will go into more " -"detail. Interesting questions include: How can we select the best client " -"nodes that should participate in the next round? What's the best way to " -"aggregate model updates? How can we handle failing client nodes " -"(stragglers)?" +"There's a lot more to discuss, of course, but that was federated learning in " +"a nutshell. In later parts of this tutorial, we will go into more detail. " +"Interesting questions include: How can we select the best client nodes that " +"should participate in the next round? What's the best way to aggregate model " +"updates? How can we handle failing client nodes (stragglers)?" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:294 msgid "" -"Just like we can train a model on the decentralized data of different " -"client nodes, we can also evaluate the model on that data to receive " -"valuable metrics. This is called federated evaluation, sometimes " -"abbreviated as FE. In fact, federated evaluation is an integral part of " -"most federated learning systems." +"Just like we can train a model on the decentralized data of different client " +"nodes, we can also evaluate the model on that data to receive valuable " +"metrics. This is called federated evaluation, sometimes abbreviated as FE. " +"In fact, federated evaluation is an integral part of most federated learning " +"systems." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:297 @@ -22434,25 +22774,24 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:299 msgid "" -"In many cases, machine learning isn't necessary to derive value from " -"data. Data analysis can yield valuable insights, but again, there's often" -" not enough data to get a clear answer. What's the average age at which " -"people develop a certain type of health condition? Federated analytics " -"enables such queries over multiple client nodes. It is usually used in " -"conjunction with other privacy-enhancing technologies like secure " -"aggregation to prevent the server from seeing the results submitted by " -"individual client nodes." +"In many cases, machine learning isn't necessary to derive value from data. " +"Data analysis can yield valuable insights, but again, there's often not " +"enough data to get a clear answer. What's the average age at which people " +"develop a certain type of health condition? Federated analytics enables such " +"queries over multiple client nodes. It is usually used in conjunction with " +"other privacy-enhancing technologies like secure aggregation to prevent the " +"server from seeing the results submitted by individual client nodes." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:305 msgid "" "Differential privacy (DP) is often mentioned in the context of Federated " -"Learning. It is a privacy-preserving method used when analyzing and " -"sharing statistical data, ensuring the privacy of individual " -"participants. DP achieves this by adding statistical noise to the model " -"updates, ensuring any individual participants’ information cannot be " -"distinguished or re-identified. This technique can be considered an " -"optimization that provides a quantifiable privacy protection measure." +"Learning. It is a privacy-preserving method used when analyzing and sharing " +"statistical data, ensuring the privacy of individual participants. DP " +"achieves this by adding statistical noise to the model updates, ensuring any " +"individual participants’ information cannot be distinguished or re-" +"identified. This technique can be considered an optimization that provides a " +"quantifiable privacy protection measure." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:326 @@ -22461,13 +22800,13 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:328 msgid "" -"Federated learning, federated evaluation, and federated analytics require" -" infrastructure to move machine learning models back and forth, train and" -" evaluate them on local data, and then aggregate the updated models. " -"Flower provides the infrastructure to do exactly that in an easy, " -"scalable, and secure way. In short, Flower presents a unified approach to" -" federated learning, analytics, and evaluation. It allows the user to " -"federate any workload, any ML framework, and any programming language." +"Federated learning, federated evaluation, and federated analytics require " +"infrastructure to move machine learning models back and forth, train and " +"evaluate them on local data, and then aggregate the updated models. Flower " +"provides the infrastructure to do exactly that in an easy, scalable, and " +"secure way. In short, Flower presents a unified approach to federated " +"learning, analytics, and evaluation. It allows the user to federate any " +"workload, any ML framework, and any programming language." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:334 @@ -22476,49 +22815,41 @@ msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:340 msgid "" -"Flower federated learning server and client nodes (car, scooter, personal" -" computer, roomba, and phone)" +"Flower federated learning server and client nodes (car, scooter, personal " +"computer, roomba, and phone)" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:353 msgid "" -"Congratulations, you just learned the basics of federated learning and " -"how it relates to the classic (centralized) machine learning!" +"Congratulations, you just learned the basics of federated learning and how " +"it relates to the classic (centralized) machine learning!" msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:355 msgid "" -"In the next part of this tutorial, we are going to build a first " -"federated learning system with Flower." +"In the next part of this tutorial, we are going to build a first federated " +"learning system with Flower." msgstr "" #: ../../source/tutorial-series-what-is-federated-learning.ipynb:373 msgid "" -"The `Flower Federated Learning Tutorial - Part 1 " -"`__ shows how to build a simple federated learning system " -"with PyTorch and Flower." +"The `Flower Federated Learning Tutorial - Part 1 `__ shows how to " +"build a simple federated learning system with PyTorch and Flower." msgstr "" #~ msgid "" -#~ "Currently, Flower provides two images, a" -#~ " ``base`` image and a ``superlink`` " -#~ "image. The base image, as the name" -#~ " suggests, contains basic dependencies that" -#~ " the SuperLink needs. This includes " -#~ "system dependencies, Python and Python " -#~ "tools. The SuperLink image is based " -#~ "on the base image, but it " -#~ "additionally installs the SuperLink using " -#~ "``pip``." +#~ "Currently, Flower provides two images, a ``base`` image and a " +#~ "``superlink`` image. The base image, as the name suggests, contains basic " +#~ "dependencies that the SuperLink needs. This includes system dependencies, " +#~ "Python and Python tools. The SuperLink image is based on the base image, " +#~ "but it additionally installs the SuperLink using ``pip``." #~ msgstr "" -#~ "현재, Flower는 \"base\" 이미지 그리고 " -#~ "\"superlink\" 이미지를 제공합니다. base 이미지는 이름에서" -#~ " 알 수 있듯이 SuperLink가 필요로 하는 기본" -#~ " dependencies를 포함하고 있습니다. 여기에는 시스템 " -#~ "dependencies, Python 및 Python 도구가 포함됩니다." -#~ " SuperLink 이미지는 base 이미지를 기반으로 하지만" -#~ " \"pip\"을 사용하여 SuperLink를 추가로 설치합니다." +#~ "현재, Flower는 \"base\" 이미지 그리고 \"superlink\" 이미지를 제공합니다. " +#~ "base 이미지는 이름에서 알 수 있듯이 SuperLink가 필요로 하는 기본 " +#~ "dependencies를 포함하고 있습니다. 여기에는 시스템 dependencies, Python 및 " +#~ "Python 도구가 포함됩니다. SuperLink 이미지는 base 이미지를 기반으로 하지" +#~ "만 \"pip\"을 사용하여 SuperLink를 추가로 설치합니다." #~ msgid "``3.11``" #~ msgstr "``3.11``" @@ -22542,278 +22873,10 @@ msgstr "" #~ msgstr "``flwr``이 기본값." #~ msgid "" -#~ "The name of image is ``flwr_superlink``" -#~ " and the tag ``0.1.0``. Remember that" -#~ " the build arguments as well as " -#~ "the name and tag can be adapted" -#~ " to your needs. These values serve" -#~ " as examples only." -#~ msgstr "" -#~ "이미지의 이름은 ``flwr_superlink``이고 태그는 " -#~ "``0.1.0``입니다. 필요에 따라 빌드 argument들 뿐만 " -#~ "아니라 이름과 태그도 정할 수 있습니다. 이 값들은" -#~ " 예시일 뿐입니다." - -#~ msgid "Creating New Messages" -#~ msgstr "" - -#~ msgid "" -#~ "This is a simple guide for " -#~ "creating a new type of message " -#~ "between the server and clients in " -#~ "Flower." -#~ msgstr "" - -#~ msgid "" -#~ "Let's suppose we have the following " -#~ "example functions in :code:`server.py` and " -#~ ":code:`numpy_client.py`..." -#~ msgstr "" - -#~ msgid "Server's side:" -#~ msgstr "" - -#~ msgid "Client's side:" -#~ msgstr "" - -#~ msgid "" -#~ "Let's now see what we need to " -#~ "implement in order to get this " -#~ "simple function between the server and" -#~ " client to work!" -#~ msgstr "" - -#~ msgid "Message Types for Protocol Buffers" -#~ msgstr "" - -#~ msgid "" -#~ "The first thing we need to do " -#~ "is to define a message type for" -#~ " the RPC system in :code:`transport.proto`." -#~ " Note that we have to do it " -#~ "for both the request and response " -#~ "messages. For more details on the " -#~ "syntax of proto3, please see the " -#~ "`official documentation `_." -#~ msgstr "" - -#~ msgid "Within the :code:`ServerMessage` block:" -#~ msgstr "" - -#~ msgid "Within the ClientMessage block:" -#~ msgstr "" - -#~ msgid "" -#~ "Make sure to also add a field " -#~ "of the newly created message type " -#~ "in :code:`oneof msg`." -#~ msgstr "" - -#~ msgid "Once that is done, we will compile the file with:" -#~ msgstr "" - -#~ msgid "If it compiles successfully, you should see the following message:" -#~ msgstr "" - -#~ msgid "Serialization and Deserialization Functions" -#~ msgstr "" - -#~ msgid "" -#~ "Our next step is to add functions" -#~ " to serialize and deserialize Python " -#~ "datatypes to or from our defined " -#~ "RPC message types. You should add " -#~ "these functions in :code:`serde.py`." -#~ msgstr "" - -#~ msgid "The four functions:" -#~ msgstr "" - -#~ msgid "Sending the Message from the Server" -#~ msgstr "" - -#~ msgid "" -#~ "Now write the request function in " -#~ "your Client Proxy class (e.g., " -#~ ":code:`grpc_client_proxy.py`) using the serde " -#~ "functions you just created:" -#~ msgstr "" - -#~ msgid "Receiving the Message by the Client" -#~ msgstr "" - -#~ msgid "" -#~ "Last step! Modify the code in " -#~ ":code:`message_handler.py` to check the field" -#~ " of your message and call the " -#~ ":code:`example_response` function. Remember to " -#~ "use the serde functions!" -#~ msgstr "" - -#~ msgid "Within the handle function:" -#~ msgstr "" - -#~ msgid "And add a new function:" -#~ msgstr "" - -#~ msgid "Hopefully, when you run your program you will get the intended result!" -#~ msgstr "" - -#~ msgid "" -#~ "The simplest way to get started " -#~ "with Flower is by using the " -#~ "pre-made Docker images, which you can" -#~ " find on `Docker Hub " -#~ "`__." -#~ msgstr "" - -#~ msgid "" -#~ "If you want to persist the state" -#~ " of the SuperLink on your host " -#~ "system, all you need to do is " -#~ "specify a path where you want to" -#~ " save the file on your host " -#~ "system and a name for the database" -#~ " file. In the example below, we " -#~ "tell Docker via the flag ``--volume``" -#~ " to mount the user's home directory" -#~ " (``~/`` on your host) into the " -#~ "``/app/`` directory of the container. " -#~ "Furthermore, we use the flag " -#~ "``--database`` to specify the name of" -#~ " the database file." -#~ msgstr "" - -#~ msgid "" -#~ "As soon as the SuperLink starts, " -#~ "the file ``state.db`` is created in " -#~ "the user's home directory on your " -#~ "host system. If the file already " -#~ "exists, the SuperLink tries to restore" -#~ " the state from the file. To " -#~ "start the SuperLink with an empty " -#~ "database, simply remove the ``state.db`` " -#~ "file." -#~ msgstr "" - -#~ msgid "" -#~ "Assuming all files we need are in" -#~ " the local ``certificates`` directory, we" -#~ " can use the flag ``--volume`` to " -#~ "mount the local directory into the " -#~ "``/app/`` directory of the container. " -#~ "This allows the SuperLink to access " -#~ "the files within the container. Finally," -#~ " we pass the names of the " -#~ "certificates to the SuperLink with the" -#~ " ``--certificates`` flag." -#~ msgstr "" - -#~ msgid "" -#~ "``--server 192.168.1.100:9092``: This option " -#~ "specifies the address of the SuperLinks" -#~ " Fleet" -#~ msgstr "" - -#~ msgid "" -#~ "Assuming the certificate already exists " -#~ "locally, we can use the flag " -#~ "``--volume`` to mount the local " -#~ "certificate into the container's ``/app/`` " -#~ "directory. This allows the SuperNode to" -#~ " access the certificate within the " -#~ "container. Use the ``--certificates`` flag " -#~ "when starting the container." -#~ msgstr "" - -#~ msgid "" -#~ "``--server 192.168.1.100:9091``: This option " -#~ "specifies the address of the SuperLinks" -#~ " Driver" -#~ msgstr "" - -#~ msgid "" -#~ "Assuming the certificate already exists " -#~ "locally, we can use the flag " -#~ "``--volume`` to mount the local " -#~ "certificate into the container's ``/app/`` " -#~ "directory. This allows the ServerApp to" -#~ " access the certificate within the " -#~ "container. Use the ``--certificates`` flag " -#~ "when starting the container." -#~ msgstr "" - -#~ msgid "" -#~ "If you want to use a different " -#~ "version of Flower, for example Flower" -#~ " nightly, you can do so by " -#~ "changing the tag. All available versions" -#~ " are on `Docker Hub " -#~ "`__." -#~ msgstr "" - -#~ msgid "" -#~ "Here's another example to start with " -#~ "HTTPS. Use the ``--certificates`` command " -#~ "line argument to pass paths to (CA" -#~ " certificate, server certificate, and " -#~ "server private key)." -#~ msgstr "" - -#~ msgid ":py:obj:`run_driver_api `\\ \\(\\)" -#~ msgstr "" - -#~ msgid "Run Flower server (Driver API)." -#~ msgstr "" - -#~ msgid ":py:obj:`run_fleet_api `\\ \\(\\)" -#~ msgstr "" - -#~ msgid "Run Flower server (Fleet API)." -#~ msgstr "" - -#~ msgid "Unreleased" -#~ msgstr "" - -#~ msgid "|d8bf04f23d9b46d8a23cc6f4887d7873|" -#~ msgstr "" - -#~ msgid "|5aa1711387d74d0f8b9c499e1a51627e|" -#~ msgstr "" - -#~ msgid "|2bc8e069228d4873804061ff4a95048c|" -#~ msgstr "" - -#~ msgid "|c258488766324dc9a6807f0e7c4fd5f4|" -#~ msgstr "" - -#~ msgid "|d5f962c3f4ec48529efda980868c14b0|" -#~ msgstr "" - -#~ msgid "|a5eccea18d4c43a68b54b65043cabef8|" -#~ msgstr "" - -#~ msgid "|f17662f7df2d42f68cac70a1fdeda8a7|" -#~ msgstr "" - -#~ msgid "|241fc906441a4f038c625a19d30d01b2|" -#~ msgstr "" - -#~ msgid "|0aa5aa05810b44b6a835cecce28f3137|" -#~ msgstr "" - -#~ msgid "|c742940dd4bf4de09d8d0d5e8d179638|" -#~ msgstr "" - -#~ msgid "|1f169ab4601a47e1a226f1628f4ebddb|" -#~ msgstr "" - -#~ msgid "|12cfa9cde14440ecb8c8f6c1d7185bec|" -#~ msgstr "" - -#~ msgid "|72939caf6e294b0986fee6dde96614d7|" -#~ msgstr "" - -#~ msgid "|83a8daee45da4a98b8d6f24ae098fc50|" +#~ "The name of image is ``flwr_superlink`` and the tag ``0.1.0``. Remember " +#~ "that the build arguments as well as the name and tag can be adapted to " +#~ "your needs. These values serve as examples only." #~ msgstr "" +#~ "이미지의 이름은 ``flwr_superlink``이고 태그는 ``0.1.0``입니다. 필요에 따" +#~ "라 빌드 argument들 뿐만 아니라 이름과 태그도 정할 수 있습니다. 이 값들은 " +#~ "예시일 뿐입니다." From 68d46ca2a96361fae1dea226bab333b239dfb523 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Mon, 24 Jun 2024 10:08:42 +0200 Subject: [PATCH 120/124] docs(datasets) Update Flower Datasets docs (#3585) Co-authored-by: jafermarq --- datasets/README.md | 32 +++++++---- .../comparison_of_partitioning_schemes.png | Bin 0 -> 36019 bytes datasets/doc/source/index.rst | 51 ++++++++++-------- datasets/flwr_datasets/federated_dataset.py | 41 ++++++++++---- 4 files changed, 82 insertions(+), 42 deletions(-) create mode 100644 datasets/doc/source/_static/readme/comparison_of_partitioning_schemes.png diff --git a/datasets/README.md b/datasets/README.md index cf5caac3e1cd..883fb69d607e 100644 --- a/datasets/README.md +++ b/datasets/README.md @@ -7,6 +7,9 @@ [![Slack](https://img.shields.io/badge/Chat-Slack-red)](https://flower.ai/join-slack) Flower Datasets (`flwr-datasets`) is a library to quickly and easily create datasets for federated learning, federated evaluation, and federated analytics. It was created by the `Flower Labs` team that also created Flower: A Friendly Federated Learning Framework. +For complete documentation that includes API docs, how-to guides and tutorials please visit https://flower.ai/docs/datasets/ and for full FL example see https://github.com/adap/flower/tree/main/examples. +Below you'll find a brief overview of the library. + Flower Datasets library supports: * **downloading datasets** - choose the dataset from Hugging Face's `datasets`, * **partitioning datasets** - customize the partitioning scheme, @@ -21,15 +24,24 @@ Thanks to using Hugging Face's `datasets` used under the hood, Flower Datasets i * Jax, * Arrow. -Create **custom partitioning schemes** or choose from the **implemented partitioning schemes**: +Create **custom partitioning schemes** or choose from the **implemented [partitioning schemes](https://flower.ai/docs/datasets/ref-api/flwr_datasets.partitioner.html#module-flwr_datasets.partitioner)**: + * Partitioner (the abstract base class) `Partitioner` * IID partitioning `IidPartitioner(num_partitions)` -* Natural ID partitioner `NaturalIdPartitioner` +* Dirichlet partitioning `DirichletPartitioner(num_partitions, partition_by, alpha)` +* InnerDirichlet partitioning `InnerDirichletPartitioner(partition_sizes, partition_by, alpha)` +* Natural ID partitioner `NaturalIdPartitioner(partition_by)` * Size partitioner (the abstract base class for the partitioners dictating the division based the number of samples) `SizePartitioner` -* Linear partitioner `LinearPartitioner` -* Square partitioner `SquarePartitioner` -* Exponential partitioner `ExponentialPartitioner` -* more to come in future releases. +* Linear partitioner `LinearPartitioner(num_partitions)` +* Square partitioner `SquarePartitioner(num_partitions)` +* Exponential partitioner `ExponentialPartitioner(num_partitions)` +* more to come in the future releases (contributions are welcome). +

    + Comparison of partitioning schemes. +
    + Comparison of Partitioning Schemes on CIFAR10 +

    +PS: This plot was generated using a library function (see [flwr_datasets.visualization](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.html) package for more). # Installation @@ -67,11 +79,11 @@ Here's a basic quickstart example of how to partition the MNIST dataset: from flwr_datasets import FederatedDataset # The train split of the MNIST dataset will be partitioned into 100 partitions -mnist_fds = FederatedDataset("mnist", partitioners={"train": 100} +fds = FederatedDataset("mnist", partitioners={"train": 100}) -mnist_partition_0 = mnist_fds.load_partition(0, "train") +partition = fds.load_partition(0) -centralized_data = mnist_fds.load_split("test") +centralized_data = fds.load_split("test") ``` For more details, please refer to the specific how-to guides or tutorial. They showcase customization and more advanced features. @@ -85,6 +97,6 @@ Here are a few of the things that we will work on in future releases: * ✅ More out-of-the-box `Partitioner`s. * ✅ Passing `Partitioner`s via `FederatedDataset`'s `partitioners` argument. * ✅ Customization of the dataset splitting before the partitioning. -* Simplification of the dataset transformation to the popular frameworks/types. +* ✅ Simplification of the dataset transformation to the popular frameworks/types. * Creation of the synthetic data, * Support for Vertical FL. diff --git a/datasets/doc/source/_static/readme/comparison_of_partitioning_schemes.png b/datasets/doc/source/_static/readme/comparison_of_partitioning_schemes.png new file mode 100644 index 0000000000000000000000000000000000000000..ed2e323ef649ae1f4c72b2390b71a817ae16ce28 GIT binary patch literal 36019 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 EKdp(oGynhq literal 0 HcmV?d00001 diff --git a/datasets/doc/source/index.rst b/datasets/doc/source/index.rst index df248969a849..263aa4908d6d 100644 --- a/datasets/doc/source/index.rst +++ b/datasets/doc/source/index.rst @@ -7,6 +7,15 @@ learning/analytics/evaluation. It is created by the ``Flower Labs`` team that al Flower Datasets Framework ------------------------- +Install +~~~~~~~ + +.. code-block:: bash + + python -m pip install "flwr-datasets[vision]" + +Check out all the details on how to install Flower Datasets in :doc:`how-to-install-flwr-datasets`. + Tutorials ~~~~~~~~~ @@ -57,9 +66,16 @@ Main features ------------- Flower Datasets library supports: -- **downloading datasets** - choose the dataset from Hugging Face's ``dataset`` -- **partitioning datasets** - customize the partitioning scheme +- **downloading datasets** - choose the dataset from Hugging Face's ``dataset`` (`link `_) +- **partitioning datasets** - choose one of the implemented partitioning scheme or create your own. - **creating centralized datasets** - leave parts of the dataset unpartitioned (e.g. for centralized evaluation) +- **visualization of the partitioned datasets** - visualize the label distribution of the partitioned dataset (and compare the results on different parameters of the same partitioning schemes, different datasets, different partitioning schemes, or any mix of them) + + +.. image:: ./_static/readme/comparison_of_partitioning_schemes.png + :align: center + :alt: Comparison of Partitioning Schemes on CIFAR10 + Thanks to using Hugging Face's ``datasets`` used under the hood, Flower Datasets integrates with the following popular formats/frameworks: @@ -71,28 +87,19 @@ Thanks to using Hugging Face's ``datasets`` used under the hood, Flower Datasets - Jax - Arrow -Install -------- - -The simplest install is - -.. code-block:: bash - - python -m pip install flwr-datasets - -If you plan to use the image datasets - -.. code-block:: bash - - python -m pip install flwr-datasets[vision] - -If you plan to use the audio datasets - -.. code-block:: bash +Here are a few of the ``Partitioner`` s that are available: (for a full list see `link `_ ) - python -m pip install flwr-datasets[audio] +* Partitioner (the abstract base class) ``Partitioner`` +* IID partitioning ``IidPartitioner(num_partitions)`` +* Dirichlet partitioning ``DirichletPartitioner(num_partitions, partition_by, alpha)`` +* InnerDirichlet partitioning ``InnerDirichletPartitioner(partition_sizes, partition_by, alpha)`` +* Natural ID partitioner ``NaturalIdPartitioner(partition_by)`` +* Size partitioner (the abstract base class for the partitioners dictating the division based the number of samples) ``SizePartitioner`` +* Linear partitioner ``LinearPartitioner(num_partitions)`` +* Square partitioner ``SquarePartitioner(num_partitions)`` +* Exponential partitioner ``ExponentialPartitioner(num_partitions)`` +* more to come in the future releases (contributions are welcome). -Check out the full details on the download in :doc:`how-to-install-flwr-datasets`. How To Use the library ---------------------- diff --git a/datasets/flwr_datasets/federated_dataset.py b/datasets/flwr_datasets/federated_dataset.py index bbc6e99b651e..accfb783f368 100644 --- a/datasets/flwr_datasets/federated_dataset.py +++ b/datasets/flwr_datasets/federated_dataset.py @@ -36,8 +36,9 @@ class FederatedDataset: Download, partition data among clients (edge devices), or load full dataset. - Partitions are created using IidPartitioner. Support for different partitioners - specification and types will come in future releases. + Partitions are created per-split-basis using Partitioners from + `flwr_datasets.partitioner` specified in `partitioners` (see `partitioners` + parameter for more information). Parameters ---------- @@ -57,23 +58,43 @@ class FederatedDataset: into). One or multiple `Partitioner` objects can be specified in that manner, but at most, one per split. shuffle : bool - Whether to randomize the order of samples. Applied prior to resplitting, - speratelly to each of the present splits in the dataset. It uses the `seed` - argument. Defaults to True. + Whether to randomize the order of samples. Applied prior to preprocessing + operations, speratelly to each of the present splits in the dataset. It uses + the `seed` argument. Defaults to True. seed : Optional[int] Seed used for dataset shuffling. It has no effect if `shuffle` is False. The - seed cannot be set in the later stages. If `None`, then fresh, unpredictable entropy - will be pulled from the OS. Defaults to 42. + seed cannot be set in the later stages. If `None`, then fresh, unpredictable + entropy will be pulled from the OS. Defaults to 42. Examples -------- Use MNIST dataset for Federated Learning with 100 clients (edge devices): - >>> mnist_fds = FederatedDataset(dataset="mnist", partitioners={"train": 100}) + >>> from flwr_datasets import FederatedDataset + >>> + >>> fds = FederatedDataset(dataset="mnist", partitioners={"train": 100}) >>> # Load partition for client with ID 10. - >>> partition = mnist_fds.load_partition(10, "train") + >>> partition = fds.load_partition(10) >>> # Use test split for centralized evaluation. - >>> centralized = mnist_fds.load_split("test") + >>> centralized = fds.load_split("test") + + Use CIFAR10 dataset for Federated Laerning with 100 clients: + >>> from flwr_datasets import FederatedDataset + >>> from flwr_datasets.partitioner import DirichletPartitioner + >>> + >>> partitioner = DirichletPartitioner(num_partitions=10, partition_by="label", + >>> alpha=0.5, min_partition_size=10) + >>> fds = FederatedDataset(dataset="cifar10", partitioners={"train": partitioner}) + >>> partition = fds.load_partition(partition_id=0) + + Visualize the partitioned datasets + >>> from flwr_datasets.visualization import plot_label_distributions + >>> + >>> _ = plot_label_distributions( + >>> partitioner=fds.partitioners["train"], + >>> label_name="label", + >>> legend=True, + >>> ) """ # pylint: disable=too-many-instance-attributes From 7fa6fb7b32b82199cf7f5e4b0ade769f53876785 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Mon, 24 Jun 2024 10:56:31 +0200 Subject: [PATCH 121/124] feat(datasets) Add notebooks formatting (#3673) --- datasets/dev/format.sh | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/datasets/dev/format.sh b/datasets/dev/format.sh index 8292e0b3ed79..c6977982dd6c 100755 --- a/datasets/dev/format.sh +++ b/datasets/dev/format.sh @@ -3,9 +3,16 @@ set -e cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"/../ # Python -echo "Formatting started" +echo "Formatting started: Python" python -m isort flwr_datasets/ python -m black -q flwr_datasets/ python -m docformatter -i -r flwr_datasets/ python -m ruff check --fix flwr_datasets/ -echo "Formatting done" +echo "Formatting done: Python" + +# Notebooks +echo "Formatting started: Notebooks" +python -m black --ipynb -q doc/source/*.ipynb +KEYS="metadata.celltoolbar metadata.language_info metadata.toc metadata.notify_time metadata.varInspector metadata.accelerator metadata.vscode cell.metadata.id cell.metadata.heading_collapsed cell.metadata.hidden cell.metadata.code_folding cell.metadata.tags cell.metadata.init_cell cell.metadata.vscode cell.metadata.pycharm" +python -m nbstripout --keep-output doc/source/*.ipynb --extra-keys "$KEYS" +echo "Formatting done: Notebooks" From 90d7aba648e055685d0e034154f79fbfa83d44ad Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Mon, 24 Jun 2024 12:56:27 +0200 Subject: [PATCH 122/124] docs(datasets) Update readme proposal (#3677) Co-authored-by: jafermarq --- datasets/README.md | 46 +++++++++++++++++----------------------------- 1 file changed, 17 insertions(+), 29 deletions(-) diff --git a/datasets/README.md b/datasets/README.md index 883fb69d607e..1d8014d57ea3 100644 --- a/datasets/README.md +++ b/datasets/README.md @@ -7,8 +7,20 @@ [![Slack](https://img.shields.io/badge/Chat-Slack-red)](https://flower.ai/join-slack) Flower Datasets (`flwr-datasets`) is a library to quickly and easily create datasets for federated learning, federated evaluation, and federated analytics. It was created by the `Flower Labs` team that also created Flower: A Friendly Federated Learning Framework. -For complete documentation that includes API docs, how-to guides and tutorials please visit https://flower.ai/docs/datasets/ and for full FL example see https://github.com/adap/flower/tree/main/examples. -Below you'll find a brief overview of the library. + + +> [!TIP] +> For complete documentation that includes API docs, how-to guides and tutorials please visit the [Flower Datasets Documentation](https://flower.ai/docs/datasets/) and for full FL example see the [Flower Examples page](https://github.com/adap/flower/tree/main/examples). + +## Installation + +For a complete installation guide visit the [Flower Datasets Documenation](https://flower.ai/docs/datasets/) + +```bash +pip install flwr-datasets[vision] +``` + +## Overview Flower Datasets library supports: * **downloading datasets** - choose the dataset from Hugging Face's `datasets`, @@ -41,35 +53,11 @@ Create **custom partitioning schemes** or choose from the **implemented [partiti
    Comparison of Partitioning Schemes on CIFAR10

    -PS: This plot was generated using a library function (see [flwr_datasets.visualization](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.html) package for more). - -# Installation - -## With pip - -Flower Datasets can be installed from PyPi -```bash -pip install flwr-datasets -``` - -Install with an extension: - -* for image datasets: - -```bash -pip install flwr-datasets[vision] -``` - -* for audio datasets: - -```bash -pip install flwr-datasets[audio] -``` +PS: This plot was generated using a library function (see [flwr_datasets.visualization](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.html) package for more). -If you plan to change the type of the dataset to run the code with your ML framework, make sure to have it installed too. -# Usage +## Usage Flower Datasets exposes the `FederatedDataset` abstraction to represent the dataset needed for federated learning/evaluation/analytics. It has two powerful methods that let you handle the dataset preprocessing: `load_partition(partition_id, split)` and `load_split(split)`. @@ -88,7 +76,7 @@ centralized_data = fds.load_split("test") For more details, please refer to the specific how-to guides or tutorial. They showcase customization and more advanced features. -# Future release +## Future release Here are a few of the things that we will work on in future releases: From d42cc2e84a5835ccac33911fc12b973857c97089 Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Mon, 24 Jun 2024 13:19:52 +0200 Subject: [PATCH 123/124] docs(datasets) Update Flower Datasets version to 0.2.0 (#3678) --- datasets/doc/source/conf.py | 2 +- datasets/doc/source/how-to-install-flwr-datasets.rst | 2 +- datasets/pyproject.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/datasets/doc/source/conf.py b/datasets/doc/source/conf.py index 755147bc9e1d..11285c375f96 100644 --- a/datasets/doc/source/conf.py +++ b/datasets/doc/source/conf.py @@ -38,7 +38,7 @@ author = "The Flower Authors" # The full version, including alpha/beta/rc tags -release = "0.1.0" +release = "0.2.0" # -- General configuration --------------------------------------------------- diff --git a/datasets/doc/source/how-to-install-flwr-datasets.rst b/datasets/doc/source/how-to-install-flwr-datasets.rst index d2fd7923a817..c690ffb1b09c 100644 --- a/datasets/doc/source/how-to-install-flwr-datasets.rst +++ b/datasets/doc/source/how-to-install-flwr-datasets.rst @@ -42,5 +42,5 @@ If everything worked, it should print the version of Flower Datasets to the comm .. code-block:: none - 0.0.1 + 0.2.0 diff --git a/datasets/pyproject.toml b/datasets/pyproject.toml index 56cf3038f4ef..017374181f59 100644 --- a/datasets/pyproject.toml +++ b/datasets/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "flwr-datasets" -version = "0.1.0" +version = "0.2.0" description = "Flower Datasets" license = "Apache-2.0" authors = ["The Flower Authors "] From febaccc20d276f505cb4fea635a5bef3567e870f Mon Sep 17 00:00:00 2001 From: Adam Narozniak <51029327+adam-narozniak@users.noreply.github.com> Date: Mon, 24 Jun 2024 17:22:37 +0200 Subject: [PATCH 124/124] docs(datasets) Add how to visualization guide (#3672) Co-authored-by: jafermarq --- .../how-to-visualize-label-distribution.ipynb | 1122 +++++++++++++++++ datasets/doc/source/index.rst | 1 + 2 files changed, 1123 insertions(+) create mode 100644 datasets/doc/source/how-to-visualize-label-distribution.ipynb diff --git a/datasets/doc/source/how-to-visualize-label-distribution.ipynb b/datasets/doc/source/how-to-visualize-label-distribution.ipynb new file mode 100644 index 000000000000..26db72047cff --- /dev/null +++ b/datasets/doc/source/how-to-visualize-label-distribution.ipynb @@ -0,0 +1,1122 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fb7e89caa9e6d772", + "metadata": {}, + "source": [ + "# Visualize Label Distribution" + ] + }, + { + "cell_type": "markdown", + "id": "67c54a8d7c872547", + "metadata": {}, + "source": [ + "If you partition datasets to simulate heterogeneity through label skew and/or size skew, you can now effortlessly visualize the partitioned dataset using `flwr-datasets`.\n", + "\n", + "In this how-to guide, you'll learn how to visualize and compare partitioned datasets when applying different methods or parameters.\n", + "\n", + "All the described visualization functions are compatible with all ``Partitioner`` you can find in\n", + "[flwr_datasets.partitioner](https://flower.ai/docs/datasets/ref-api/flwr_datasets.partitioner.html#module-flwr_datasets.partitioner)\n" + ] + }, + { + "cell_type": "markdown", + "id": "7220467f2c6ba432", + "metadata": {}, + "source": [ + "## Common Setup" + ] + }, + { + "cell_type": "markdown", + "id": "4e2ad2f0a0f7174d", + "metadata": {}, + "source": [ + "Install Flower Datasets library:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c46514b679f394ce", + "metadata": {}, + "outputs": [], + "source": [ + "! pip install -q \"flwr-datasets[vision]\"" + ] + }, + { + "cell_type": "markdown", + "id": "d7ffd5b6836a5ee0", + "metadata": {}, + "source": [ + "## Plot Label Distribution" + ] + }, + { + "cell_type": "markdown", + "id": "38fbbdfe6b930916", + "metadata": {}, + "source": [ + "### Bar plot" + ] + }, + { + "cell_type": "markdown", + "id": "a5778edf97a7ee04", + "metadata": {}, + "source": [ + "Let's visualize the result of `DirichletPartitioner`.\n", + "We will create a `FederatedDataset` and assign `DirichletPartitioner` to the `train` split:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42397afaaf50529e", + "metadata": {}, + "outputs": [], + "source": [ + "from flwr_datasets import FederatedDataset\n", + "from flwr_datasets.partitioner import DirichletPartitioner\n", + "from flwr_datasets.visualization import plot_label_distributions\n", + "\n", + "\n", + "fds = FederatedDataset(\n", + " dataset=\"cifar10\",\n", + " partitioners={\n", + " \"train\": DirichletPartitioner(\n", + " num_partitions=10,\n", + " partition_by=\"label\",\n", + " alpha=0.3,\n", + " seed=42,\n", + " min_partition_size=0,\n", + " ),\n", + " },\n", + ")\n", + "\n", + "partitioner = fds.partitioners[\"train\"]" + ] + }, + { + "cell_type": "markdown", + "id": "c4d5855ee8a605d3", + "metadata": {}, + "source": [ + "Once we have the partitioner with the dataset assigned, we are ready to pass it to the plotting function:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f75b48256ed68897", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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ACBkZGSU7kkgIiIileHvb5ISyexjXtVxH1QiIqKqh7+/SUoku8aciIiIiOh9wsSciIiIiEgCmJgTEREREUkAE3MiIiIiIglgYk5EREREJAFMzImIiIiIJEBD1QEQEREpW50N/ZTex59+vyq9DyKq3jhjTkREREQkAUzMiYiIiIgkgIk5EREREZEEMDEnIiIiIpIAJuZERERERBLAxJyIiIiISAKYmBMRERERSQATcyIiIiIiCWBiTkREREQkAUzMiYiIiIgkgIk5EREREZEEMDEnIiIiIpIAJuZERERERBLAxJyIiIiISAKYmBMRERERSQATcyIiIiIiCWBiTkREREQkAUzMiYiIiIgkQEPVARARESlb33pmqg6BiOhfccaciIiIiEgCmJgTEREREUkAE3MiIiIiIglgYk5EREREJAFMzImIiIiIJICJORERERGRBDAxJyIiIiKSACbmREREREQSwMSciIiIiEgCmJgTEREREUkAE3MiIiIiIglgYk5EREREJAFMzImIiIiIJICJORERERGRBDAxJyIiIiKSACbmREREREQSwMSciIiIiEgCmJgTEREREUkAE3MiIiIiIglgYk5EREREJAFMzImIiIiIJICJORERERGRBDAxJyIiIiKSAA1VB0BERKRsk9w7qDoEIqJ/xRlzIiIiIiIJYGJORERERCQBXMpCREREVAnkcjlyc3NVHQZVIk1NTairq5e4PhNzIiIiIiXLzc1FcnIy5HK5qkOhSmZiYgJra2vIZLJ/rcvEnIiIiEiJBEHAgwcPoK6uDjs7O6ipcSXx+0AQBDx//hxpaWkAABsbm3+9hok5ERERkRLl5+fj+fPnsLW1hZ6enqrDoUqkq6sLAEhLS4OlpeW/LmvhRzYiIiIiJSooKAAAaGlpqTgSUoXCD2N5eXn/WpeJOREREVElKMkaY6p+SvO6MzEnIiIiIpIAJuZEREREVCE2btwIExOTcrcjk8mwZ8+ecrdT1TAxJyIiIiKRr68vevfureow3ktMzImIiIiIJEDSiXlBQQGmT58OR0dH6OrqwsnJCbNnz4YgCGIdQRAwY8YM2NjYQFdXF15eXrh165ZCO0+ePMGgQYNgZGQEExMT+Pn5ISsrS6HO5cuX0aFDB+jo6MDOzg7z58+vlDESERERVRWLFy9Go0aNoK+vDzs7O3z99ddFcioA2LNn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i4uLg76+fqX2WdUxMSciIiKiCmdhYaHqEKocLmUhIiIiomLt3LkTjRo1gq6uLszNzeHl5YXs7Gzx/MKFC2FjYwNzc3P4+/sjLy9PPPfmUhaZTIY1a9agW7du0NXVRZ06dbBz587KHI7kMTEnIiIioiIePHiAgQMHYujQoUhMTER0dDT69u0LQRAAACdOnMCdO3dw4sQJREREYOPGjdi4ceM725w+fTr69euHS5cuYdCgQRgwYAASExMrYTRVA5eyEBEREVERDx48QH5+Pvr27Qt7e3sAQKNGjcTzpqamWLlyJdTV1VG/fn306NEDUVFRGD58+Fvb/PTTTzFs2DAAwOzZsxEZGYkVK1Zg9erVyh1MFcEZcyIiIiIqokmTJujcuTMaNWqETz/9FOvXr8fTp0/F8w0aNIC6urp4bGNjg7S0tHe26eHhUeSYM+b/j4k5ERERERWhrq6OyMhIHDp0CG5ublixYgVcXFyQnJwMANDU1FSoL5PJIJfLVRFqtcHEnIiIiIiKJZPJ0K5dOwQHB+PixYvQ0tLC7t27y9ze2bNnixy7urqWN8xqg2vMiYiIiKiI2NhYREVFoUuXLrC0tERsbCwePXoEV1dXXL58uUxt/vLLL3B3d0f79u2xZcsWnDt3Dhs2bKjgyKsuJuZEREREVISRkRFOnTqFpUuXIjMzE/b29li0aBG6deuG7du3l6nN4OBgbNu2DV9//TVsbGzw888/w83NrYIjr7qYmBMRUbVn8aISOtGthD6oWqnsO3GWlqurKw4fPlzsueK2RXx9z3IASElJKVLH1tYWR48erYDoqieuMSciIiIikgAm5kREREREEsClLERERESkdIV3DKW344w5EREREZEEMDEnIiIiIpIAJuZERERERBLAxJyIiIiISAKYmBMRERERSQB3ZVGxCb8PV2r7CzusV2r7RERERFQxOGNOREREREV4enoiMDBQ1WG8VzhjTkRERKQCyv6r+Zv4V3Tp44w5ERERESldbm6uqkOQPCbmRERERFQsuVyOSZMmwczMDNbW1ggKChLP3b17F7169YKBgQGMjIzw2WefITU1VTwfFBSEpk2b4ocffoCjoyN0dHQAADt37kSjRo2gq6sLc3NzeHl5ITs7W7zuhx9+gKurK3R0dFC/fn2sXr260saralzKQkRERETFioiIwPjx4xEbG4uYmBj4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", + "text/plain": [ + "
    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax, df = plot_label_distributions(\n", + " partitioner,\n", + " label_name=\"label\",\n", + " plot_type=\"bar\",\n", + " size_unit=\"absolute\",\n", + " partition_id_axis=\"x\",\n", + " legend=True,\n", + " verbose_labels=True,\n", + " title=\"Per Partition Labels Distribution\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "be05badab744d9f7", + "metadata": {}, + "source": [ + "You can configure many details directly using the function parameters. The ones that can interest you the most are:\n", + "\n", + "* `size_unit` to have the sizes normalized such that they sum up to 1 and express the fraction of the data in each partition,\n", + "* `legend` and `verbose_labels` in case the dataset has more descriptive names and not numbers,\n", + "* `cmap` to change the values of the bars (for an overview of the available colors, have a look at [link](https://matplotlib.org/stable/users/explain/colors/colormaps.html); check out `cmap=\"tab20b\"`) \n", + "\n", + " And for even greater control, you can specify `plot_kwargs` and `legend_kwargs` as `Dict`, which will be further passed to the `plot` and `legend` functions." + ] + }, + { + "cell_type": "markdown", + "id": "3dbf6dc4ede79f05", + "metadata": {}, + "source": [ + "You can also inspect the exact numbers that were used to create this plot. Three objects are returned (see reference [here](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.plot_label_distributions.html#flwr_datasets.visualization.plot_label_distributions)). Let's inspect the returned DataFrame." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f6edd14d8b260e9e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    \n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
    airplaneautomobilebirdcatdeerdogfroghorseshiptruck
    Partition ID
    08177941462212343225456384149
    11416697530340903868
    2041124543511158421
    37621591100511201662198213512175
    424371421924004251151477
    5677917025255247727445900
    6422244863809290380506
    7122281159721741038172716825154
    825629342751848151122401417
    91136107350357126711223
    \n", + "
    " + ], + "text/plain": [ + " airplane automobile bird cat deer dog frog horse ship \\\n", + "Partition ID \n", + "0 817 794 1462 2123 432 25 456 384 14 \n", + "1 1416 6 97 5 3 0 3409 0 3 \n", + "2 0 4 11 2 454 3 511 15 84 \n", + "3 762 159 1100 51 120 166 2 1982 1351 \n", + "4 2 43 714 2 19 2400 425 1 151 \n", + "5 67 79 170 25 2552 477 27 44 590 \n", + "6 422 2 4 486 380 92 90 380 50 \n", + "7 122 2811 597 2174 1038 1727 1 682 515 \n", + "8 256 29 342 75 1 84 8 1511 2240 \n", + "9 1136 1073 503 57 1 26 71 1 2 \n", + "\n", + " truck \n", + "Partition ID \n", + "0 9 \n", + "1 868 \n", + "2 21 \n", + "3 2175 \n", + "4 477 \n", + "5 0 \n", + "6 6 \n", + "7 4 \n", + "8 1417 \n", + "9 23 " + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df" + ] + }, + { + "cell_type": "markdown", + "id": "2902213a", + "metadata": {}, + "source": [ + "Each row represents a unique partition ID, and the columns represent unique labels (either in the verbose version if `verbose_labels=True` or typically `int` values otherwise, representing the partition IDs).\n", + "That you can index the DataFrame `df[partition_id, label_id]` to get the number of samples in `partition_id` for the specified `label_id.`" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ffe4039", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "714" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.loc[4, \"bird\"]" + ] + }, + { + "cell_type": "markdown", + "id": "2e6c17af529a668f", + "metadata": {}, + "source": [ + "Let's see a plot with `size_unit=\"percent\"`, which is another excellent way to understand the partitions. In this mode, the number of datapoints for each class in a given partition are normalized, so they sum up to 100." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a241894a47f3cc9f", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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SgAAAPsKCwuTu7u7Nm/enGnf999/r5CQEI0ePVr169dXWFiYfv/9d4tjXFxclJ6enl/lFgmFYslHUlKSevToocWLF2vSpEnm9itXrujtt9/We++9p4ceekjSzdv7hYeH64cfftD9999vr5IBAADsws3NTSNHjtSIESPk4uKiJk2a6MKFC/rll18UFhamU6dO6YMPPlCDBg30+eefa82aNRbnlytXTidOnFBCQoLKlCkjb29viwf7IbNCEahjYmLUtm1bRUZGWgTqvXv36saNG4qMjDS3ValSRWXLltXOnTvvGKhTUlKUkpJi3k5MTLRd8QAAoMjJzwet5MaYMWPk5OSksWPH6s8//1RgYKCee+459e7dWy+88IJiY2OVkpKitm3basyYMRo/frz53M6dO2v16tV68MEHdfnyZS1ZskTR0dF2u5bCoMAH6g8++ED79u3T7t27M+07e/asXFxc5Ovra9Hu7++vs2fP3rHPqVOnKi4uLq9LBQAAKBAcHBw0evRojR49OtO+6dOna/r06RZt//58mqurqz7++GNbl1ikFOg11KdPn9agQYO0cuVKubm55Vm/L774oq5cuWJ+nT59Os/6BgAAwL2lQAfqvXv36vz586pbt66cnJzk5OSkbdu2ae7cuXJycpK/v79SU1N1+fJli/POnTt313snurq6ysfHx+IFAAAA5EaBXvLRsmVLHThwwKLtmWeeUZUqVTRy5EgFBwfL2dlZmzdvVufOnSVJhw8f1qlTpxQREWGPkgEAKJL27V2VD6PUzocxgLxXoAO1t7e3qlevbtHm6ekpPz8/c3vv3r01ZMgQlShRQj4+PhowYIAiIiK4wwcAAADyRYEO1Nnx2muvycHBQZ07d1ZKSopatWqlBQsW2LssAADMHvpf3n0OCEDBU+gC9datWy223dzc9Prrr+v111+3T0EAAAC4pxXoDyUCAAAABR2BGgAAALACgRoAAACwAoEaAACgiGnRooXF0w9vV65cOc2ePTvH/Y4fP161a9fOdV1FVaH7UCIAAIC99Xmpcb6O99aU7/O0v927d8vT0zNP+7yXEagBAAXW6lX7bD5Gm9o2HwIocEqWLHnX/Tdu3JCzs3M+VVP4seQDAACgCEpLS1NsbKyKFSum++67T2PGjJFhGJIyL/kwmUxauHChHnvsMXl6emry5MmSpFdeeUX+/v7y9vZW7969df36dXtcSoFHoAYAACiCli1bJicnJ+3atUtz5szRrFmz9NZbb93x+PHjx6tjx446cOCAevXqpVWrVmn8+PGaMmWK9uzZo8DAQB6edwcs+QAAACiCgoOD9dprr8lkMqly5co6cOCAXnvtNfXt2zfL45988kk988wz5u1u3bqpd+/e6t27tyRp0qRJ+vrrr5mlzgIz1AAAAEXQ/fffL5PJZN6OiIjQ0aNHlZ6enuXx9evXt9g+dOiQGjVqZNEWERGR94UWAQRqAAAAcNcPKxCoAQAAiqD4+HiL7R9++EFhYWFydHTM1vnh4eFZ9oHMCNQAAABF0KlTpzRkyBAdPnxY77//vubNm6dBgwZl+/xBgwbpnXfe0ZIlS3TkyBGNGzdOv/zyiw0rLrz4UCIAAEAO5fWDVmyhZ8+e+ueff9SwYUM5Ojpq0KBB6tevX7bP79q1q44fP64RI0bo+vXr6ty5s/r376+NGzfasOrCiUANAABQxGzdutX89cKFCzPtP3nypMX2rftT3+6ll17SSy+9ZNE2bdo0q+sraljyAQAAAFiBQA0AAABYgUANAAAAWIFADQAAAFiBQA0AAABYgUANAAAAWIFADQAAAFiBQA0AAABYgUANAAAAWIFADQAAgAJv6dKl8vX1vesx48ePV+3atc3b0dHR6tChg03rknj0OAAAQI7FDkrI1/Hmz6mdr+NJNwPs4MGDdfny5XwfO7eGDRumAQMG5Pu4BGoAAAAUCV5eXvLy8sr3cVnyAQAosNySF9j8BRRVGzZsUNOmTeXr6ys/Pz+1a9dOx48flyRt3bpVJpPJYvY5ISFBJpNJJ0+e1NatW/XMM8/oypUrMplMMplMGj9+vCTp0qVL6tmzp4oXLy4PDw+1bt1aR48eNfdza2nGZ599psqVK8vDw0NdunTRtWvXtGzZMpUrV07FixfXwIEDlZ6ebj7vv/q9Ze3atQoLC5Obm5tatWql06dPm/fdvuTjdhkZGZo6dapCQ0Pl7u6uWrVq6eOPP87ld/j/YYYaKCgaXLd3BQCAIiQ5OVlDhgxRzZo1lZSUpLFjx6pjx45KSEj4z3MbN26s2bNna+zYsTp8+LAkmWd+o6OjdfToUa1fv14+Pj4aOXKk2rRpo4MHD8rZ2VmSdO3aNc2dO1cffPCBrl69qk6dOqljx47y9fXVF198od9++02dO3dWkyZN1LVr1xz1O3nyZC1fvlwuLi56/vnn1a1bN+3YsSNb35OpU6fq3Xff1aJFixQWFqZvv/1WTz31lEqWLKnmzZvn9FtsRqAGAAAogjp37myx/c4776hkyZI6ePDgf57r4uKiYsWKyWQyKSAgwNx+K/Du2LFDjRs3liStXLlSwcHBWrt2rR5//HFJ0o0bN7Rw4UJVqFBBktSlSxetWLFC586dk5eXl6pWraoHH3xQ33zzjbp27ZqjfufPn69GjRpJkpYtW6bw8HDt2rVLDRs2vOs1paSkaMqUKfr6668VEREhSSpfvry2b9+uN954g0ANAAAAS0ePHtXYsWMVHx+vv/76SxkZGZKkU6dOycPDI1d9Hjp0SE5OTuZAK0l+fn6qXLmyDh06ZG7z8PAwh2lJ8vf3V7ly5SzWN/v7++v8+fM56tfJyUkNGjQwb1epUkW+vr46dOjQfwbqY8eO6dq1a/rf//5n0Z6amqo6depk91uQJQI1AABAEfToo48qJCREixcvVlBQkDIyMlS9enWlpqaag61hGObjb9y4kWdj31qicYvJZMqy7VbIzw9JSUmSpM8//1ylS5e22Ofq6mpV33woEQAAoIi5ePGiDh8+rJdfflktW7ZUeHi4Ll26ZN5fsmRJSdKZM2fMbbevrXZxcbH40KAkhYeHKy0tTfHx8ZnGqlq1aq7rzW6/aWlp2rNnj3n78OHDunz5ssLDw/9zjKpVq8rV1VWnTp1SxYoVLV7BwcG5rl1ihhoAAKDIKV68uPz8/PTmm28qMDBQp06d0qhRo8z7b4XI8ePHa/LkyTpy5Ihmzpxp0Ue5cuWUlJSkzZs3q1atWvLw8FBYWJjat2+vvn376o033pC3t7dGjRql0qVLq3379rmuN7v9Ojs7a8CAAZo7d66cnJwUGxur+++//z+Xe0iSt7e3hg0bphdeeEEZGRlq2rSprly5oh07dsjHx0dRUVG5rp9ADQAAkEP2eNBKTjg4OOiDDz7QwIEDVb16dVWuXFlz585VixYtJN0Mpu+//7769++vmjVrqkGDBpo0aZL5w3/SzTt9PPfcc+ratasuXryocePGafz48VqyZIkGDRqkdu3aKTU1VQ888IC++OKLTEs6cio7/Xp4eGjkyJF68skn9ccff6hZs2Z6++23sz3GxIkTVbJkSU2dOlW//fabfH19VbduXb300ktW1W4y/r145h6VmJioYsWK6cqVK/Lx8cnWOX1eamzjqqS3pnxv8zFWt2lr0/47ffG5TfuXpJkD69p8jKFz99l8jLN7Xrf5GAH1Y2zaf1G4BqnovKe+SIi1af9tas+3af9S/jyNLj+C0dmF2f8HP7cC+ve2af+Nm1oXOLLj++1TcnR8bv79zonr16/rxIkTCg0NlZubW573j4Ivu+8BZqiBAmLlctv/gzs0H8IoAAD3Gj6UCAAAAFiBQA0AAABYgUANAAAAWIFADQAAAFiBDyXe49ymhNq7BPz/wnvZ/s4xAAAg7xGo73GrV9n21l1tatu0ewAAALsjUAMFhK1/uZH4BQcAAFtgDTUAAMA95uTJkzKZTEpISLC6r+joaHXo0MHqfgozZqgBAADuMcHBwTpz5ozuu+8+e5dSJBCoAQAAcig/HsX+bzl9LPt/cXR0VEBAwB33G4ah9PR0OTkRFbODJR+55Ja8wOYvAACA3NqwYYOaNm0qX19f+fn5qV27djp+/LikzEs+tm7dKpPJpC+//FL16tWTq6urtm/frvHjx6t27dp64403FBwcLA8PDz3xxBO6cuVKrsb999irV6/Wgw8+KA8PD9WqVUs7d+606Gf79u1q1qyZ3N3dFRwcrIEDByo5OTnvv1F5gF877nEHv21h7xIAAIANJCcna8iQIapZs6aSkpI0duxYdezY8a7rpkeNGqUZM2aofPnyKl68uLZu3apjx45p1apV+vTTT5WYmKjevXvr+eef18qVK3M8roPD/5vLHT16tGbMmKGwsDCNHj1a3bt317Fjx+Tk5KTjx4/rkUce0aRJk/TOO+/owoULio2NVWxsrJYsWZLX3yqrEagBAACKoM6dO1tsv/POOypZsqQOHjwoLy+vLM+ZMGGC/ve//1m0Xb9+XcuXL1fp0qUlSfPmzVPbtm01c+bMLJeN3G3c6tWrm9uHDRumtm3bSpLi4uJUrVo1HTt2TFWqVNHUqVPVo0cPDR48WJIUFhamuXPnqnnz5lq4cKHc3Nxy9s2wMZZ8AAAAFEFHjx5V9+7dVb58efn4+KhcuXKSpFOnTt3xnPr162dqK1u2rDlMS1JERIQyMjJ0+PBhq8atWbOm+evAwEBJ0vnz5yVJ+/fv19KlS+Xl5WV+tWrVShkZGTpx4sR/X3w+Y4YaAACgCHr00UcVEhKixYsXKygoSBkZGapevbpSU1PveI6np2e+jevs7Gz+2mQySZIyMjIkSUlJSXr22Wc1cODATP2XLVvW6hrzGoEaAACgiLl48aIOHz6sxYsXq1mzZpJufsgvN06dOqU///xTQUFBkqQffvhBDg4Oqly5ss3GrVu3rg4ePKiKFSvmqub8RqAGAAAoYooXLy4/Pz+9+eabCgwM1KlTpzRq1Khc9eXm5qaoqCjNmDFDiYmJGjhwoJ544oks10/n1bgjR47U/fffr9jYWPXp00eenp46ePCgNm3apPnz5+fqOmyJNdQAAABFjIODgz744APt3btX1atX1wsvvKBXX301V31VrFhRnTp1Ups2bfTwww+rZs2aWrAg69v75tW4NWvW1LZt23TkyBE1a9ZMderU0dixY82z5AUNM9QAUEStXrXPpv23qW3T7oECLa8ftGILkZGROnjwoEWbYRhZft2iRQuL7dv1799f/fv3z3Lf0qVLczRuuXLlMo3l6+ubqa1Bgwb66quv7lhTQUKgBoAiivvMA0D+YMkHAAAAYAUCNQAAALI0fvz4uz5ZETcV6EA9depUNWjQQN7e3ipVqpQ6dOiQ6Sbi169fV0xMjPz8/OTl5aXOnTvr3LlzdqoYAAAA95oCHai3bdummJgY/fDDD9q0aZNu3Lihhx9+WMnJyeZjXnjhBX366af66KOPtG3bNv3555/q1KmTHasGAADAvaRAfyhxw4YNFttLly5VqVKltHfvXj3wwAO6cuWK3n77bb333nt66KGHJElLlixReHi4fvjhB91///32KBsAABQhd7v7BYq27P7sC/QM9e2uXLkiSSpRooQkae/evbpx44YiIyPNx1SpUkVly5bVzp0779hPSkqKEhMTLV4AAAD/duvR2NeuXbNzJbCXWz/7fz8mPSsFeob63zIyMjR48GA1adJE1atXlySdPXtWLi4u8vX1tTjW399fZ8+evWNfU6dOVVxcnC3LBQAAhZyjo6N8fX11/vx5SZKHh4dMJpOdq0J+MAxD165d0/nz5+Xr6ytHR8e7Hl9oAnVMTIx+/vnnXD+H/t9efPFFDRkyxLydmJio4OBgq/sFAABFy63Ha98K1bi3+Pr6ZvmI9dsVikAdGxurzz77TN9++63KlCljbg8ICFBqaqouX75sMUt97ty5u168q6urXF1dbVkyAAAoAkwmkwIDA1WqVCnd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", + "text/plain": [ + "
    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax, df = plot_label_distributions(\n", + " partitioner,\n", + " label_name=\"label\",\n", + " plot_type=\"bar\",\n", + " size_unit=\"percent\",\n", + " partition_id_axis=\"x\",\n", + " legend=True,\n", + " verbose_labels=True,\n", + " cmap=\"tab20b\",\n", + " title=\"Per Partition Labels Distribution\",\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "e7d1fe2e1c0f14c", + "metadata": {}, + "source": [ + "### Heatmap" + ] + }, + { + "cell_type": "markdown", + "id": "ad6a2e53de3cc084", + "metadata": {}, + "source": [ + "You might want to visualize the results of partitioning as a heatmap, which can be especially useful for binary labels. Here's how:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "14a4b4e574866120", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig, ax, df = plot_label_distributions(\n", + " partitioner,\n", + " label_name=\"label\",\n", + " plot_type=\"heatmap\",\n", + " size_unit=\"absolute\",\n", + " partition_id_axis=\"x\",\n", + " legend=True,\n", + " verbose_labels=True,\n", + " title=\"Per Partition Labels Distribution\",\n", + " plot_kwargs={\"annot\": True},\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "5167593e67fa3dbb", + "metadata": {}, + "source": [ + "Note: we used the `plot_kwargs={\"annot\": True}` to add the number directly to the plot." + ] + }, + { + "cell_type": "markdown", + "id": "e2e41273551ac32a", + "metadata": {}, + "source": [ + "If you are a `pandas` fan, then you might be interested that a similar heatmap can be created with the DataFrame object for visualization in jupyter notebook:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fcc90b52bfd650cf", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
     airplaneautomobilebirdcatdeerdogfroghorseshiptruck
    Partition ID          
    08177941462212343225456384149
    11416697530340903868
    2041124543511158421
    37621591100511201662198213512175
    424371421924004251151477
    5677917025255247727445900
    6422244863809290380506
    7122281159721741038172716825154
    825629342751848151122401417
    91136107350357126711223
    \n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": null, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df.style.background_gradient(axis=None, cmap=\"Greens\", vmin=0)" + ] + }, + { + "cell_type": "markdown", + "id": "37d85e1b40d54918", + "metadata": {}, + "source": [ + "## Plot Comparison of Label Distributions" + ] + }, + { + "cell_type": "markdown", + "id": "4f49259a3de7dd17", + "metadata": {}, + "source": [ + "Now, once you know how to visualize a single partitioned dataset, you'll learn how to compare a few of them on a single plot.\n", + "\n", + "Let's compare:\n", + "\n", + "- IidPartitioner,\n", + "- DirichletPartitioner,\n", + "- ShardPartitioner\n", + "still using the `cifar10` dataset.\n", + "\n", + "We need to create a list of partitioners. Each partitioner needs to have a dataset assigned to it (it does not have to be the same dataset so you can also compare the same partitioning on different datasets)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9e84a9192a266f3e", + "metadata": {}, + "outputs": [], + "source": [ + "from flwr_datasets import FederatedDataset\n", + "from flwr_datasets.partitioner import (\n", + " IidPartitioner,\n", + " DirichletPartitioner,\n", + " ShardPartitioner,\n", + ")\n", + "\n", + "partitioner_list = []\n", + "title_list = [\"IidPartitioner\", \"DirichletPartitioner\", \"ShardPartitioner\"]\n", + "\n", + "## IidPartitioner\n", + "fds = FederatedDataset(\n", + " dataset=\"cifar10\",\n", + " partitioners={\n", + " \"train\": IidPartitioner(num_partitions=10),\n", + " },\n", + ")\n", + "partitioner_list.append(fds.partitioners[\"train\"])\n", + "\n", + "## DirichletPartitioner\n", + "fds = FederatedDataset(\n", + " dataset=\"cifar10\",\n", + " partitioners={\n", + " \"train\": DirichletPartitioner(\n", + " num_partitions=10,\n", + " partition_by=\"label\",\n", + " alpha=1.0,\n", + " min_partition_size=0,\n", + " ),\n", + " },\n", + ")\n", + "partitioner_list.append(fds.partitioners[\"train\"])\n", + "\n", + "## ShardPartitioner\n", + "fds = FederatedDataset(\n", + " dataset=\"cifar10\",\n", + " partitioners={\n", + " \"train\": ShardPartitioner(\n", + " num_partitions=10, partition_by=\"label\", num_shards_per_partition=2\n", + " )\n", + " },\n", + ")\n", + "partitioner_list.append(fds.partitioners[\"train\"])" + ] + }, + { + "cell_type": "markdown", + "id": "d18bae80", + "metadata": {}, + "source": [ + "Now let's visualize them side by side" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f2ee2864", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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+7wm9ml10URu6LKSlNfiv58hsjTwS4HU5vALzf1+JfVp5zRf2yFQKcczlURERERERKQyFpVERERERESkMhaVREREREREpDKdKypfvHiB4OBgODk5wcTEBM2aNcPFixe1HRYREREREVGZpHNF5dChQ3H06FFs3LgRN27cQNu2beHn54fHj/mgBSIiIiIiouKmU0Vleno6du7cifnz56Nly5Zwd3dHSEgI3N3dER4eru3wiIiIiIiIyhydeqVIVlYWsrOzYWxsrDDexMQEp0+fznOejIwMZGRkyIdTUlI0GiMREREREVFZolNnKi0sLNC0aVPMnj0bT548QXZ2NjZt2oRz587h6dOnec4TFhYGKysr+cfR0bGYoyYiIiIiIiq9dKqoBICNGzdCCIHKlStDKpVi+fLl6Nu3L/T08l6VqVOnIjk5Wf559OhRMUdMRERERERUeunU5a8A4ObmhlOnTiEtLQ0pKSmwt7dH79694erqmmd7qVQKqVRazFESERERERGVDTp3pjKHmZkZ7O3tkZiYiMOHD6Nz587aDomIiIiIiKjM0bkzlYcPH4YQAtWrV8eDBw8wadIkeHp6YtCgQdoOjYiIiIiIqMzRuTOVycnJGDNmDDw9PTFgwAC0aNEChw8fhqGhobZDIyIiIiIiKnN07kxlr1690KtXL22HQURERERERNDBM5VERERERERUckiEEELbQRSnlJQUWFlZITk5GZaWltoOh6hM0HTeMa+Jip8m8445TVT8mHf0PnimkoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFRmoO0AtGWbVQOYQl+tfTb2Vv/XWcXPSe19AoC0TTW19iep00Ct/SWYqLU7uSvxN9XaX2Rcolr7A4Bd9/5Te585Yi49Vmt/Ivy8Wvt7X9EfecNcX7m8Liy31J0j2qZKjiaYqD9nNEETeahp6s5zdeZ2ScprTfyuJvX66nsvbYdASvhryE5th0ClHM9UEhERERERkcpYVBIREREREZHKWFQSERERERGRylhUEhERERERkcp0qqjMzs7G9OnT4eLiAhMTE7i5uWH27NkQQmg7NCIiIiIiojJJp57+Om/ePISHh2PDhg2oVasWLl26hEGDBsHKygrjxo3TdnhERERERERljk4VlWfPnkXnzp3Rvn17AICzszN+/vln/PHHH1qOjIiIiIiIqGzSqctfmzVrhmPHjuHevXsAgOvXr+P06dMICAjId56MjAykpKQofIiIiIiIiEg9dOpM5RdffIGUlBR4enpCX18f2dnZmDt3Lvr375/vPGFhYQgNDS3GKImIiIiIiMoOnSoqt23bhs2bN+Onn35CrVq1cO3aNQQHB8PBwQEDBw7Mc56pU6diwoQJ8uGUlBQ4OjoWV8hERERERDotOzsbr1+/1nYYVIz09fVhYGAAiUSiVHudKionTZqEL774An369AEA1K5dGw8fPkRYWFi+RaVUKoVUKi3OMImIiIiISoXU1FT8/ffffNtCGWRqagp7e3sYGRkV2lanisqXL19CT0/xNlB9fX3IZDItRUREREREVDplZ2fj77//hqmpKWxtbZU+a0W6TQiBzMxMJCQkICYmBh4eHrlqsHfpVFHZsWNHzJ07F1WrVkWtWrVw9epVLF68GIMHD9Z2aEREREREpcrr168hhICtrS1MTEy0HQ4VIxMTExgaGuLhw4fIzMyEsbFxge11qqhcsWIFpk+fjtGjRyM+Ph4ODg4YMWIEZsyYoe3QiIiIiIhKJZ6hLJsKOzv5Np0qKi0sLLB06VIsXbpU26EQERERERERdOw9lURERERERFSySEQZe5RTSkoKrKyskJycDEtLS22HQ1QmaDrvmNdExU+TececJip+eeXdq1evEBMTAxcXl0LvqdN169evR3BwMJKSkt6rH4lEgt27d6NLly5qiUubirL9eaaSiIiIiIh0XmBgYKko5nQRi0oiIiIiIiJSGYtKIiIiIiIq1RYvXozatWvDzMwMjo6OGD16NFJTU3O127NnDzw8PGBsbAx/f388evRIYfrevXvRoEEDGBsbw9XVFaGhocjKyspzmZmZmQgKCoK9vT2MjY3h5OSEsLAwjayftrGoJCIiIiKiUk1PTw/Lly/HrVu3sGHDBhw/fhyTJ09WaPPy5UvMnTsXP/74I86cOYOkpCT06dNHPv3333/HgAED8Nlnn+H27dtYs2YN1q9fj7lz5+a5zOXLl+OXX37Btm3bEBUVhc2bN8PZ2VmTq6k1OvVKESIiIiIioqIKDg6W/+zs7Iw5c+Zg5MiRWLVqlXz869evsXLlSjRp0gQAsGHDBtSoUQN//PEHvL29ERoaii+++AIDBw4EALi6umL27NmYPHkyZs6cmWuZcXFx8PDwQIsWLSCRSODk5KTZldQinqkkIiIiIqJSLTIyEq1bt0blypVhYWGBTz/9FM+fP8fLly/lbQwMDNC4cWP5sKenJ6ytrXHnzh0AwPXr1zFr1iyYm5vLP8OGDcPTp08V+skRGBiIa9euoXr16hg3bhyOHDmi+RXVEhaVRERERERUasXGxqJDhw6oU6cOdu7cicuXL+Pbb78F8Oa+R2WlpqYiNDQU165dk39u3LiB+/fv5/nKjQYNGiAmJgazZ89Geno6evXqhR49eqhtvUoSXv5KRERERESl1uXLlyGTybBo0SLo6b05p7Zt27Zc7bKysnDp0iV4e3sDAKKiopCUlIQaNWoAeFMkRkVFwd3dXellW1paonfv3ujduzd69OiBdu3a4b///kP58uXVsGYlB4tKIiIiIiIqFZKTk3Ht2jWFcRUqVMDr16+xYsUKdOzYEWfOnMHq1atzzWtoaIixY8di+fLlMDAwQFBQED744AN5kTljxgx06NABVatWRY8ePaCnp4fr16/j5s2bmDNnTq7+Fi9eDHt7e9SvXx96enrYvn07KlWqBGtra02sulbx8lciIiIiIioVTp48ifr16yt8Nm7ciMWLF2PevHnw8vLC5s2b83y1h6mpKaZMmYJ+/fqhefPmMDc3x9atW+XT/f39sW/fPhw5cgSNGzfGBx98gCVLluT7AB4LCwvMnz8fjRo1QuPGjREbG4sDBw7Iz5aWJhIhhNB2EMUpJSUFVlZWSE5OhqWlpbbDISoTNJ13zGui4qfJvGNOExW/vPLu1atXiImJgYuLS573DFLpVpTtX/rKZCIiIiIiIio2LCqJiIiIiIhIZSwqiYiIiIiISGUsKomIiIiIiEhlLCqJiIiIiIhIZWX2PZXbrBrAFPpq66+xt2a+yip+eT+iWFXSNtXU2h8ASOo0UHufAJBgov4+r8TfVHufkXGJau1v173/1NofAMRceqz2PgFAhJ/XSL+qUndelzZFOU69e+zRxLHjbeo6jqhy3FDHcUEXjgMFefsYUZLyOvojb5jrM6dLMnX/nUKaYTL3gLZDoFKOZyqJiIiIiIhIZSwqiYiIiIiISGUsKomIiIiIiEhlZfaeSiIiIiIiKjrJqA+KdXkl6V7vt8XGxsLFxQVXr15FvXr1tB2OVunUmUpnZ2dIJJJcnzFjxmg7NCIiIiIiKgFatWqF4OBgbYdRpujUmcqLFy8iOztbPnzz5k20adMGPXv21GJURERERESkK4QQyM7OhoGBTpVCJZpOnam0tbVFpUqV5J99+/bBzc0Nvr6+2g6NiIiIiIi0LDAwEKdOncKyZcvkVzWuX78eEokEBw8eRMOGDSGVSnH69GkEBgaiS5cuCvMHBwejVatW8mGZTIb58+fD3d0dUqkUVatWxdy5c/NcdnZ2NgYPHgxPT0/ExcVpcC1LHp0tzzMzM7Fp0yZMmDABEokk33YZGRnIyMiQD6ekpBRHeEREREREVMyWLVuGe/fuwcvLC7NmzQIA3Lp1CwDwxRdfYOHChXB1dUW5cuWU6m/q1KlYu3YtlixZghYtWuDp06e4e/durnYZGRno27cvYmNj8fvvv8PW1lZ9K6UDdLao3LNnD5KSkhAYGFhgu7CwMISGhhZPUEREREREpDVWVlYwMjKCqakpKlWqBADyInDWrFlo06aN0n29ePECy5Ytw8qVKzFw4EAAgJubG1q0aKHQLjU1Fe3bt0dGRgZOnDgBKysrNa2N7tCpy1/ftm7dOgQEBMDBwaHAdlOnTkVycrL88+jRo2KKkIiIiIiISopGjRoVqf2dO3eQkZGB1q1bF9iub9++SEtLw5EjR8pkQQnoaFH58OFDREZGYujQoYW2lUqlsLS0VPgQEREREVHZYmZmpjCsp6cHIYTCuNevX8t/NjExUarfjz/+GH/++SfOnTv3/kHqKJ0sKiMiImBnZ4f27dtrOxQiIiIiIipBjIyMFN4YkR9bW1s8ffpUYdy1a9fkP3t4eMDExATHjh0rsJ9Ro0bhm2++QadOnXDq1CmVYtZ1OndPpUwmQ0REBAYOHMjHABMRERERkQJnZ2dcuHABsbGxMDc3h0wmy7PdRx99hAULFuDHH39E06ZNsWnTJty8eRP169cHABgbG2PKlCmYPHkyjIyM0Lx5cyQkJODWrVsYMmSIQl9jx45FdnY2OnTogIMHD+a677K007mqLDIyEnFxcRg8eLC2QyEiIiIiKnNE+Hlth1CgiRMnYuDAgahZsybS09MRERGRZzt/f39Mnz4dkydPxqtXrzB48GAMGDAAN27ckLeZPn06DAwMMGPGDDx58gT29vYYOXJknv0FBwdDJpPh448/xqFDh9CsWTONrF9JpHNFZdu2bXNd+0xERERERAQA1apVy3V/Y35vjAgNDS3wTRF6enqYNm0apk2blmuas7NzrrpkwoQJmDBhQtGD1nE6eU8lERERERERlQwSUcZO+6WkpMDKygrJycl8EixRMdF03jGviYqfJvOOOU1U/PLKu1evXiEmJgYuLi4wNjbWcoRU3Iqy/XmmkoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFRmoO0AiIiIiIhId7iu616sy/tryE619RUYGIikpCTs2bMn3zbOzs4IDg5GcHCw2pZb2rGoJCIiIiIi+n8XL16EmZmZtsPQKSwqiYiIiIiI/p+tra22Q9A5vKeSiIiIiIhKlR07dqB27dowMTGBjY0N/Pz8kJaWJp++cOFC2Nvbw8bGBmPGjMHr16/l05ydnbF06VL5sEQiQXh4OAICAmBiYgJXV1fs2LGjOFenxGNRSUREREREpcbTp0/Rt29fDB48GHfu3MHJkyfRrVs3CCEAACdOnEB0dDROnDiBDRs2YP369Vi/fn2BfU6fPh3du3fH9evX0b9/f/Tp0wd37twphrXRDbz8lYiIiIiISo2nT58iKysL3bp1g5OTEwCgdu3a8unlypXDypUroa+vD09PT7Rv3x7Hjh3DsGHD8u2zZ8+eGDp0KABg9uzZOHr0KFasWIFVq1ZpdmV0BM9UEhERERFRqVG3bl20bt0atWvXRs+ePbF27VokJibKp9eqVQv6+vryYXt7e8THxxfYZ9OmTXMN80zl/7CoJCIiIiKiUkNfXx9Hjx7FwYMHUbNmTaxYsQLVq1dHTEwMAMDQ0FChvUQigUwm00aopQaLSiIiIiIiKlUkEgmaN2+O0NBQXL16FUZGRti9e7fK/Z0/fz7XcI0aNd43zFKjzN5Tuc2qAUyhX3hDJTT2Vv/XWMXPSe19AoC0TTWN9Cup00Aj/SaYqL/PK/E31d5nZFxi4Y2KaNe9/9TeZ8ylx2rtT4SfL7xRMVJXXmsip/Ojaq5rKpc1paBjhKp5/nYuFzUHNZFfuqKw40BJyuuE9J/xylADvwhIbSpO4P1kuqAk5XVxuHDhAo4dO4a2bdvCzs4OFy5cQEJCAmrUqIE///xTpT63b9+ORo0aoUWLFti8eTP++OMPrFu3Ts2R664yW1QSEREREVHR/TVkp7ZDKJClpSV+++03LF26FCkpKXBycsKiRYsQEBCArVu3qtRnaGgotmzZgtGjR8Pe3h4///wzatasqebIdReLSiIiIiIiKjVq1KiBQ4cO5Tktr1eHvP1OSgCIjY3N1cbBwQFHjhxRQ3SlE++pJCIiIiIiIpWxqCQiIiIiIiKV6VxR+fjxY3zyySewsbGBiYkJateujUuXLmk7LCIiIiIiKoWEEOjSpYu2wyjRdOqeysTERDRv3hwffvghDh48CFtbW9y/fx/lypXTdmhERERERERlkk4VlfPmzYOjoyMiIiLk41xcXAqcJyMjAxkZGfLhlJQUjcVHRERERERU1ujU5a+//PILGjVqhJ49e8LOzg7169fH2rVrC5wnLCwMVlZW8o+jo2MxRUtERERERFT66VRR+ddffyE8PBweHh44fPgwRo0ahXHjxmHDhg35zjN16lQkJyfLP48ePSrGiImIiIiIiEo3nbr8VSaToVGjRvj6668BAPXr18fNmzexevVqDBw4MM95pFIppFJpcYZJRERERERUZujUmUp7e3vUrFlTYVyNGjUQFxenpYiIiIiIiIjKNp06U9m8eXNERUUpjLt37x6cnJy0FBERERERUdky8fdhxbq8hT4FP0PlXa1atUK9evWwdOlSzQREuejUmcrx48fj/Pnz+Prrr/HgwQP89NNP+O677zBmzBhth0ZERERERFQm6VRR2bhxY+zevRs///wzvLy8MHv2bCxduhT9+/fXdmhERERERFQKZWZmajuEEk+nikoA6NChA27cuIFXr17hzp07GDaseE+/ExERERFRySaTyTB58mSUL18elSpVQkhIiHxaXFwcOnfuDHNzc1haWqJXr1549uyZfHpISAjq1auH77//Hi4uLjA2NgYA7NixA7Vr14aJiQlsbGzg5+eHtLQ0+Xzff/89atSoAWNjY3h6emLVqlXFtr7apvI9lampqYiNjcWLFy9gYWEBFxcXmJmZqTM2IiIiIiKiItuwYQMmTJiACxcu4Ny5cwgMDETz5s3RunVreUF56tQpZGVlYcyYMejduzdO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VBIREREREZHKWFQSERERERGRylhUEhERERERkcpYVBIREREREZHKWFQSERERERGRylhUEhERERERkcpYVBIREREREZHKWFQSERERERGRylhUEhERERERkcpYVBIREREREZHKWFQSERERERGRylhUEhERERERkcpYVBIREREREZHKWFQSERERERGRylhUEhERERERkcpYVBIREREREZHKDLQdgLZss2oAU+irpa/G3ur/Gqv4Oam1P2mbamrpR1KngVr6eVeCiUa6xZX4mxrpNzIuUSP9AsCue/+pvc+YS4/V3icAiPDzGulXVerMa1Vp4nhQVOo+fqhDUY9Byhxr3ue4kXNsUDWXNZGn2pDXsaEk5bX472eILA39giC1mHTrd22HQEpY6LNW2yFQKcczlURERERERKQyFpVERERERESkMhaVREREREREpDKdLCq//fZbODs7w9jYGE2aNMEff/yh7ZCIiIiIiIjKJJ0rKrdu3YoJEyZg5syZuHLlCurWrQt/f3/Ex8drOzQiIiIiIqIyR+eKysWLF2PYsGEYNGgQatasidWrV8PU1BQ//PCDtkMjIiIiIiIqc3SqqMzMzMTly5fh5+cnH6enpwc/Pz+cO3cuz3kyMjKQkpKi8CEiIiIiIiL10Kmi8t9//0V2djYqVqyoML5ixYr4559/8pwnLCwMVlZW8o+jo2NxhEpERERERFQm6FRRqYqpU6ciOTlZ/nn06JG2QyIiIiIiIio1DLQdQFFUqFAB+vr6ePbsmcL4Z8+eoVKlSnnOI5VKIZVKiyM8IiIiIiKiMkenzlQaGRmhYcOGOHbsmHycTCbDsWPH0LRpUy1GRkREREREVDbp1JlKAJgwYQIGDhyIRo0awdvbG0uXLkVaWhoGDRqk7dCIiIiIiIjKHJ0rKnv37o2EhATMmDED//zzD+rVq4dDhw7lengPERERERERaZ7OFZUAEBQUhKCgIG2HQUREREREVObp1D2VREREREREVLKwqCQiIiIiIiKVSYQQQttBFKeUlBRYWVkhOTkZlpaW2g6HqEzQdN4xr4mKnybzjjlNVPyYd/Q+eKaSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUxqKSiIiIiIiIVMaikoiIiIiIiFTGopKIiIiIiIhUZqDtAIpbzhtUUlJStBwJUdmRk2+aeoMR85qo+Gkyr5nTRMVP07+rqXQrc0Xl8+fPAQCOjo5ajoSo7Hnx4gWsrKzU3i/zmkh7NJHXzGki7dHU72oq3cpcUVm+fHkAQFxcXKlImJSUFDg6OuLRo0el5kW1XCfdUJR1EkLgxYsXcHBw0EgszOuSj+ukG0pKXpe2nAa4v+iKsrxOmv5dTaVbmSsq9fTe3EZqZWVVag4WAGBpaVmq1gfgOukKZddJk38YMq91B9dJN2g7r0trTgNle3/RJWV1nUrLP3Go+PFBPURERERERKQyFpVERERERESksjJXVEqlUsycORNSqVTboahFaVsfgOukK0rSOpWkWNShtK0PwHXSFSVlnUpKHOrEddINXCci1UgEnxtMREREREREKipzZyqJiIiIiIhIfVhUEhERERERkcpYVBIREREREZHKWFQSERERERGRyspUUfntt9/C2dkZxsbGaNKkCf744w9th6S0sLAwNG7cGBYWFrCzs0OXLl0QFRWl0KZVq1aQSCQKn5EjR2op4sKFhITkitfT01M+/dWrVxgzZgxsbGxgbm6O7t2749mzZ1qMuHDOzs651kkikWDMmDEASv42+u2339CxY0c4ODhAIpFgz549CtOFEJgxYwbs7e1hYmICPz8/3L9/X6HNf//9h/79+8PS0hLW1tYYMmQIUlNTNRYz87pkYV6XvG3EvC5epS2vmdMlc/voYl5T6VZmisqtW7diwoQJmDlzJq5cuYK6devC398f8fHx2g5NKadOncKYMWNw/vx5HD16FK9fv0bbtm2Rlpam0G7YsGF4+vSp/DN//nwtRaycWrVqKcR7+vRp+bTx48fj119/xfbt23Hq1Ck8efIE3bp102K0hbt48aLC+hw9ehQA0LNnT3mbkryN0tLSULduXXz77bd5Tp8/fz6WL1+O1atX48KFCzAzM4O/vz9evXolb9O/f3/cunULR48exb59+/Dbb79h+PDhGomXeV0yMa9L1jZiXhev0pjXzOmSt310La+pDBBlhLe3txgzZox8ODs7Wzg4OIiwsDAtRqW6+Ph4AUCcOnVKPs7X11d89tln2guqiGbOnCnq1q2b57SkpCRhaGgotm/fLh93584dAUCcO3eumCJ8f5999plwc3MTMplMCKFb2wiA2L17t3xYJpOJSpUqiQULFsjHJSUlCalUKn7++WchhBC3b98WAMTFixflbQ4ePCgkEol4/Pix2mNkXpc8zOuSjXld/HQ9r5nTJZ8u5DWVfmXiTGVmZiYuX74MPz8/+Tg9PT34+fnh3LlzWoxMdcnJyQCA8uXLK4zfvHkzKlSoAC8vL0ydOhUvX77URnhKu3//PhwcHODq6or+/fsjLi4OAHD58mW8fv1aYZt5enqiatWqOrPNMjMzsWnTJgwePBgSiUQ+Xte2UY6YmBj8888/CtvEysoKTZo0kW+Tc+fOwdraGo0aNZK38fPzg56eHi5cuKDWeJjXJRfzuuRvoxzMa80rDXnNnC7Z2+ddJS2vqWww0HYAxeHff/9FdnY2KlasqDC+YsWKuHv3rpaiUp1MJkNwcDCaN28OLy8v+fh+/frByckJDg4O+PPPPzFlyhRERUVh165dWow2f02aNMH69etRvXp1PH36FKGhofDx8cHNmzfxzz//wMjICNbW1grzVKxYEf/88492Ai6iPXv2ICkpCYGBgfJxuraN3pbzveeVRznT/vnnH9jZ2SlMNzAwQPny5dW+3ZjXJXOfYV6X/G30Nua1ZpWGvGZOl+ztk5eSltdUNpSJorK0GTNmDG7evKlwTwMAhevga9euDXt7e7Ru3RrR0dFwc3Mr7jALFRAQIP+5Tp06aNKkCZycnLBt2zaYmJhoMTL1WLduHQICAuDg4CAfp2vbiIoP81o3MK+pKEpDXjOnS/b2ISopysTlrxUqVIC+vn6up5E9e/YMlSpV0lJUqgkKCsK+fftw4sQJVKlSpcC2TZo0AQA8ePCgOEJ7b9bW1qhWrRoePHiASpUqITMzE0lJSQptdGWbPXz4EJGRkRg6dGiB7XRpG+V87wXlUaVKlXI9TCMrKwv//fef2rcb87rk7zMA87qkY15rTmnNa+Z0yVfS8prKhjJRVBoZGaFhw4Y4duyYfJxMJsOxY8fQtGlTLUamPCEEgoKCsHv3bhw/fhwuLi6FznPt2jUAgL29vYajU4/U1FRER0fD3t4eDRs2hKGhocI2i4qKQlxcnE5ss4iICNjZ2aF9+/YFttOlbeTi4oJKlSopbJOUlBRcuHBBvk2aNm2KpKQkXL58Wd7m+PHjkMlk8l/K6sK8Lvn7DMC8LumY1+pX2vOaOV3ylbS8pjJCyw8KKjZbtmwRUqlUrF+/Xty+fVsMHz5cWFtbi3/++UfboSll1KhRwsrKSpw8eVI8ffpU/nn58qUQQogHDx6IWbNmiUuXLomYmBixd+9e4erqKlq2bKnlyPP3+eefi5MnT4qYmBhx5swZ4efnJypUqCDi4+OFEEKMHDlSVK1aVRw/flxcunRJNG3aVDRt2lTLURcuOztbVK1aVUyZMkVhvC5soxcvXoirV6+Kq1evCgBi8eLF4urVq+Lhw4dCCCG++eYbYW1tLfbu3Sv+/PNP0blzZ+Hi4iLS09PlfbRr107Ur19fXLhwQZw+fVp4eHiIvn37aiRe5nXJw7wueduIeV28SlteM6dL5vbRtbym0q/MFJVCCLFixQpRtWpVYWRkJLy9vcX58+e1HZLSAOT5iYiIEEIIERcXJ1q2bCnKly8vpFKpcHd3F5MmTRLJycnaDbwAvXv3Fvb29sLIyEhUrlxZ9O7dWzx48EA+PT09XYwePVqUK1dOmJqaiq5du4qnT59qMWLlHD58WAAQUVFRCuN1YRudOHEiz/1s4MCBQog3jymfPn26qFixopBKpaJ169a51vP58+eib9++wtzcXFhaWopBgwaJFy9eaCxm5nXJwrwueduIeV28SlteM6dL5vbRxbym0k0ihBAaPBFKREREREREpViZuKeSiIiIiIiININFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJREREREREamMRSURERERERGpjEUlERERERERqYxFJRGRCpydnREYGKjtMJQSEhICiUSiMK644o+NjYVEIsH69evl4wIDA2Fubq7xZeeQSCQICQkptuURERGVNSwqiYjeEh0djREjRsDV1RXGxsawtLRE8+bNsWzZMqSnp2s7PK06cOBAiS3OSnJsREREpZ2BtgMgIiop9u/fj549e0IqlWLAgAHw8vJCZmYmTp8+jUmTJuHWrVv47rvvtB2mWkRFRUFPr2j/Vzxw4AC+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", + "text/plain": [ + "
    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from flwr_datasets.visualization import plot_comparison_label_distribution\n", + "\n", + "fig, axes, df_list = plot_comparison_label_distribution(\n", + " partitioner_list=partitioner_list,\n", + " label_name=\"label\",\n", + " subtitle=\"Comparison of Partitioning Schemes on CIFAR10\",\n", + " titles=title_list,\n", + " legend=True,\n", + " verbose_labels=True,\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "862899eb04695380", + "metadata": {}, + "source": [ + "## Bonus: Natural Id Dataset" + ] + }, + { + "cell_type": "markdown", + "id": "4f3f8aaf", + "metadata": {}, + "source": [ + "Nothing stops you from using the `NaturalIdPartitioner` to visualize a dataset with the `id` in it and does not need the artificial partitioning but has the pre-existing partitions. For that dataset, we use `NaturalIdPartitioner`. Let's look at the `speech-commands` dataset that has `speaker_id`, and there are quite a few speakers; therefore, we will show only the first 20 partitions. And since we have quite a few different labels, let's specify `legend_kwargs={\"ncols\": 2}` to display them in two columns (we will also shift the legend slightly to the right)." + ] + }, + { + "cell_type": "markdown", + "id": "f016d21a", + "metadata": {}, + "source": [ + "You'll be using the [Google SpeechCommands](https://huggingface.co/datasets/google/speech_commands) dataset, which is a speech-based dataset. For this, you'll need to install the `\"audio\"` extension for Flower Datasets. It can be easily done like this:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fd5ca8f4", + "metadata": {}, + "outputs": [], + "source": [ + "! pip install -q \"flwr-datasets[audio]\"" + ] + }, + { + "cell_type": "markdown", + "id": "90ea3642", + "metadata": {}, + "source": [ + "With everything ready, let's visualize the partitions for a naturally partitioned dataset." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "4fe70116", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "text/plain": [ + "
    " + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from flwr_datasets import FederatedDataset\n", + "from flwr_datasets.partitioner import NaturalIdPartitioner\n", + "from flwr_datasets.visualization import plot_label_distributions\n", + "\n", + "\n", + "fds = FederatedDataset(\n", + " dataset=\"google/speech_commands\",\n", + " subset=\"v0.01\",\n", + " partitioners={\n", + " \"train\": NaturalIdPartitioner(\n", + " partition_by=\"speaker_id\",\n", + " ),\n", + " },\n", + ")\n", + "\n", + "partitioner = fds.partitioners[\"train\"]\n", + "\n", + "fix, ax, df = plot_label_distributions(\n", + " partitioner=partitioner,\n", + " label_name=\"label\",\n", + " max_num_partitions=20,\n", + " plot_type=\"bar\",\n", + " size_unit=\"percent\",\n", + " partition_id_axis=\"x\",\n", + " legend=True,\n", + " title=\"Per Partition Labels Distribution\",\n", + " verbose_labels=True,\n", + " legend_kwargs={\"ncols\": 2, \"bbox_to_anchor\": (1.25, 0.5)},\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "4442c99c", + "metadata": {}, + "source": [ + "## More resources\n", + "\n", + "If you are looking for more resorces, feel free to check:\n", + "\n", + "* `flwr-dataset` documentation\n", + " * [plot_label_distributions](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.plot_label_distributions.html#flwr_datasets.visualization.plot_label_distributions)\n", + " * [plot_comparison_label_distribution](https://flower.ai/docs/datasets/ref-api/flwr_datasets.visualization.plot_comparison_label_distribution.html#flwr_datasets.visualization.plot_comparison_label_distribution)\n", + "* if you want to do any custom modification of the returned plots\n", + " * [matplotlib](https://matplotlib.org/)\n", + " * [seaborn](https://seaborn.pydata.org/)\n", + " * or plot directly using pandas object [pd.DataFrame.plot](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html)" + ] + }, + { + "cell_type": "markdown", + "id": "52655972", + "metadata": {}, + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "flwr", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/datasets/doc/source/index.rst b/datasets/doc/source/index.rst index 263aa4908d6d..bdcea7650bbc 100644 --- a/datasets/doc/source/index.rst +++ b/datasets/doc/source/index.rst @@ -41,6 +41,7 @@ Problem-oriented how-to guides show step-by-step how to achieve a specific goal. how-to-use-with-tensorflow how-to-use-with-numpy how-to-use-with-local-data + how-to-visualize-label-distribution how-to-disable-enable-progress-bar References